diff options
author | Richard Henderson <rth@redhat.com> | 2008-09-24 23:21:04 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 2008-09-24 23:21:04 +0000 |
commit | f1c4cc7516582b6fdb474d43c1b8e1b74dd73f52 (patch) | |
tree | 6f14d634455a6dc54e1db050f103bea47095686d /binutils | |
parent | 6fbd21a1cee8c0f55252cd0f0c06423aaddaf70f (diff) | |
download | binutils-f1c4cc7516582b6fdb474d43c1b8e1b74dd73f52.zip binutils-f1c4cc7516582b6fdb474d43c1b8e1b74dd73f52.tar.gz binutils-f1c4cc7516582b6fdb474d43c1b8e1b74dd73f52.tar.bz2 |
include/
* elf/dwarf2.h (DW_OP_GNU_encoded_addr): New.
binutils/
* dwarf.c (size_of_encoded_value, get_encoded_value): Move up.
(decode_location_expression): Add section parameter. Handle
DW_OP_GNU_encoded_addr.
(read_and_display_attr_value): Update decode_location_expression call.
(display_debug_loc, display_debug_frames): Likewise.
gas/
* dw2gencfi.c (DWARF2_ADDR_SIZE): Provide default.
(struct cfi_insn_data): Add ea member.
(CFI_val_encoded_addr, dot_cfi_val_encoded_addr): New.
(output_cfi_insn): Handle CFI_val_encoded_addr.
(select_cie_for_fde): Don't match CFI_val_encoded_addr.
* doc/as.texinfo (.cfi_val_encoded_addr): Document.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 8 | ||||
-rw-r--r-- | binutils/dwarf.c | 78 |
2 files changed, 56 insertions, 30 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index e909e77..ab1d8f3 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,11 @@ +2008-09-24 Richard Henderson <rth@redhat.com> + + * dwarf.c (size_of_encoded_value, get_encoded_value): Move up. + (decode_location_expression): Add section parameter. Handle + DW_OP_GNU_encoded_addr. + (read_and_display_attr_value): Update decode_location_expression call. + (display_debug_loc, display_debug_frames): Likewise. + 2008-09-25 Alan Modra <amodra@bigpond.net.au> PR 6913 diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 42ddd94..983a3c7 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -164,6 +164,30 @@ byte_get_signed (unsigned char *field, int size) } } +static int +size_of_encoded_value (int encoding) +{ + switch (encoding & 0x7) + { + default: /* ??? */ + case 0: return eh_addr_size; + case 2: return 2; + case 3: return 4; + case 4: return 8; + } +} + +static dwarf_vma +get_encoded_value (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); +} + /* Print a dwarf_vma value (typically an address, offset or length) in hexadecimal format, followed by a space. The length of the value (and hence the precision displayed) is determined by the byte_size parameter. */ @@ -651,7 +675,8 @@ static int decode_location_expression (unsigned char * data, unsigned int pointer_size, unsigned long length, - unsigned long cu_offset) + unsigned long cu_offset, + struct dwarf_section * section) { unsigned op; unsigned int bytes_read; @@ -989,6 +1014,21 @@ decode_location_expression (unsigned char * data, printf ("DW_OP_GNU_uninit"); /* FIXME: Is there data associated with this OP ? */ break; + case DW_OP_GNU_encoded_addr: + { + int encoding; + dwarf_vma addr; + + encoding = *data++; + addr = get_encoded_value (data, encoding); + if ((encoding & 0x70) == DW_EH_PE_pcrel) + addr += section->address + (data - section->start); + data += size_of_encoded_value (encoding); + + printf ("DW_OP_GNU_encoded_addr: fmt:%02x addr:", encoding); + print_dwarf_vma (addr, pointer_size); + } + break; /* HP extensions. */ case DW_OP_HP_is_value: @@ -1508,7 +1548,7 @@ read_and_display_attr_value (unsigned long attribute, need_frame_base = decode_location_expression (block_start, pointer_size, uvalue, - cu_offset); + cu_offset, section); printf (")"); if (need_frame_base && !have_frame_base) printf (_(" [without DW_AT_frame_base]")); @@ -3186,7 +3226,7 @@ display_debug_loc (struct dwarf_section *section, void *file) need_frame_base = decode_location_expression (start, pointer_size, length, - cu_offset); + cu_offset, section); putchar (')'); if (need_frame_base && !has_frame_base) @@ -3756,30 +3796,6 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs) printf ("\n"); } -static int -size_of_encoded_value (int encoding) -{ - switch (encoding & 0x7) - { - default: /* ??? */ - case 0: return eh_addr_size; - case 2: return 2; - case 3: return 4; - case 4: return 8; - } -} - -static dwarf_vma -get_encoded_value (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 @@ -4379,7 +4395,8 @@ display_debug_frames (struct dwarf_section *section, if (! do_debug_frames_interp) { printf (" DW_CFA_def_cfa_expression ("); - decode_location_expression (start, eh_addr_size, ul, 0); + decode_location_expression (start, eh_addr_size, ul, 0, + section); printf (")\n"); } fc->cfa_exp = 1; @@ -4394,7 +4411,7 @@ display_debug_frames (struct dwarf_section *section, printf (" DW_CFA_expression: %s (", regname (reg, 0)); decode_location_expression (start, eh_addr_size, - ul, 0); + ul, 0, section); printf (")\n"); } fc->col_type[reg] = DW_CFA_expression; @@ -4408,7 +4425,8 @@ display_debug_frames (struct dwarf_section *section, { printf (" DW_CFA_val_expression: %s (", regname (reg, 0)); - decode_location_expression (start, eh_addr_size, ul, 0); + decode_location_expression (start, eh_addr_size, ul, 0, + section); printf (")\n"); } fc->col_type[reg] = DW_CFA_val_expression; |