aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2008-09-24 23:21:04 +0000
committerRichard Henderson <rth@redhat.com>2008-09-24 23:21:04 +0000
commitf1c4cc7516582b6fdb474d43c1b8e1b74dd73f52 (patch)
tree6f14d634455a6dc54e1db050f103bea47095686d /binutils
parent6fbd21a1cee8c0f55252cd0f0c06423aaddaf70f (diff)
downloadbinutils-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/ChangeLog8
-rw-r--r--binutils/dwarf.c78
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;