aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2003-05-31 19:29:19 +0000
committerRichard Henderson <rth@redhat.com>2003-05-31 19:29:19 +0000
commit38fafa6d088439f82e140d2f60f76fa0d15def57 (patch)
tree32c455550fd7f31ca3eab178d5f1f7cbc18e313f
parentcfc14b3aa68dffce6c9db5070f8346841c9bc8a4 (diff)
downloadgdb-38fafa6d088439f82e140d2f60f76fa0d15def57.zip
gdb-38fafa6d088439f82e140d2f60f76fa0d15def57.tar.gz
gdb-38fafa6d088439f82e140d2f60f76fa0d15def57.tar.bz2
* readelf.c (byte_get_signed): New.
(get_encoded_value): New. (display_debug_frames): Use it. Always pre-process opcodes.
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/readelf.c50
2 files changed, 52 insertions, 4 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 18a7044..85d4f97 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2003-05-31 Richard Henderson <rth@redhat.com>
+
+ * readelf.c (byte_get_signed): New.
+ (get_encoded_value): New.
+ (display_debug_frames): Use it. Always pre-process opcodes.
+
2003-05-20 Michal Ludvig <mludvig@suse.cz>
* readelf.c (display_debug_frames): Print both registers
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 8fcfda4..dbd802a 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -173,6 +173,8 @@ static bfd_vma byte_get_little_endian
PARAMS ((unsigned char *, int));
static bfd_vma byte_get_big_endian
PARAMS ((unsigned char *, int));
+static bfd_vma byte_get_signed
+ PARAMS ((unsigned char *, int));
static void (*byte_put)
PARAMS ((unsigned char *, bfd_vma, int));
static void byte_put_little_endian
@@ -556,6 +558,29 @@ byte_get_little_endian (field, size)
}
}
+static bfd_vma
+byte_get_signed (field, size)
+ unsigned char *field;
+ int size;
+{
+ bfd_vma x = byte_get (field, size);
+
+ switch (size)
+ {
+ case 1:
+ return (x ^ 0x80) - 0x80;
+ case 2:
+ return (x ^ 0x8000) - 0x8000;
+ case 4:
+ return (x ^ 0x80000000) - 0x80000000;
+ case 8:
+ case -8:
+ return x;
+ default:
+ abort ();
+ }
+}
+
static void
byte_put_little_endian (field, value, size)
unsigned char * field;
@@ -8668,6 +8693,7 @@ Frame_Chunk;
static void frame_need_space PARAMS ((Frame_Chunk *, int));
static void frame_display_row PARAMS ((Frame_Chunk *, int *, int *));
static int size_of_encoded_value PARAMS ((int));
+static bfd_vma get_encoded_value PARAMS ((unsigned char *, int));
static void
frame_need_space (fc, reg)
@@ -8775,6 +8801,18 @@ size_of_encoded_value (encoding)
}
}
+static bfd_vma
+get_encoded_value (data, encoding)
+ unsigned char *data;
+ int encoding;
+{
+ int size = size_of_encoded_value (encoding);
+ if (encoding & DW_EH_PE_signed)
+ return byte_get_signed (data, size);
+ else
+ return byte_get (data, size);
+}
+
#define GET(N) byte_get (start, N); start += N
#define LEB() read_leb128 (start, & length_return, 0); start += length_return
#define SLEB() read_leb128 (start, & length_return, 1); start += length_return
@@ -8980,7 +9018,7 @@ display_debug_frames (section, start, file)
if (fc->fde_encoding)
encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
- fc->pc_begin = byte_get (start, encoded_ptr_size);
+ fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
fc->pc_begin += section->sh_addr + (start - section_start);
start += encoded_ptr_size;
@@ -9011,8 +9049,12 @@ display_debug_frames (section, start, file)
/* At this point, fc is the current chunk, cie (if any) is set, and we're
about to interpret instructions for the chunk. */
-
- if (do_debug_frames_interp)
+ /* ??? At present we need to do this always, since this sizes the
+ fc->col_type and fc->col_offset arrays, which we write into always.
+ We should probably split the interpreted and non-interpreted bits
+ into two different routines, since there's so much that doesn't
+ really overlap between them. */
+ if (1 || do_debug_frames_interp)
{
/* Start by making a pass over the chunk, allocating storage
and taking note of what registers are used. */
@@ -9175,7 +9217,7 @@ display_debug_frames (section, start, file)
break;
case DW_CFA_set_loc:
- vma = byte_get (start, encoded_ptr_size);
+ vma = get_encoded_value (start, fc->fde_encoding);
if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
vma += section->sh_addr + (start - section_start);
start += encoded_ptr_size;