diff options
author | Richard Henderson <rth@redhat.com> | 2003-05-31 19:29:19 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 2003-05-31 19:29:19 +0000 |
commit | 38fafa6d088439f82e140d2f60f76fa0d15def57 (patch) | |
tree | 32c455550fd7f31ca3eab178d5f1f7cbc18e313f | |
parent | cfc14b3aa68dffce6c9db5070f8346841c9bc8a4 (diff) | |
download | gdb-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/ChangeLog | 6 | ||||
-rw-r--r-- | binutils/readelf.c | 50 |
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; |