* dwarf.h (debug_info): Add offset_info and dwarf_version fields.

* dwarf.c (decode_location_expression): Add offset_size and
	dwarf_version arguments.  Prefix DIE offset with 0x for
	DW_OP_call{2,4,_ref}.  Fix up DW_OP_call_ref operand size,
	complain if in frame info section.  Handle
	DW_OP_GNU_implicit_pointer.
	(read_and_display_attr_value, display_debug_loc,
	display_debug_frames): Adjust decode_location_expression callers.
	(process_debug_info): Save offset_size and dwarf_version values
	into debug_information array.

	* dwarf2.h (DW_OP_GNU_implicit_pointer): New.
This commit is contained in:
Jakub Jelinek
2010-09-09 10:18:12 +00:00
parent 7326c758fd
commit b7807392f0
5 changed files with 82 additions and 10 deletions

View File

@ -1,3 +1,16 @@
2010-09-09 Jakub Jelinek <jakub@redhat.com>
* dwarf.h (debug_info): Add offset_info and dwarf_version fields.
* dwarf.c (decode_location_expression): Add offset_size and
dwarf_version arguments. Prefix DIE offset with 0x for
DW_OP_call{2,4,_ref}. Fix up DW_OP_call_ref operand size,
complain if in frame info section. Handle
DW_OP_GNU_implicit_pointer.
(read_and_display_attr_value, display_debug_loc,
display_debug_frames): Adjust decode_location_expression callers.
(process_debug_info): Save offset_size and dwarf_version values
into debug_information array.
2010-09-07 Nick Clifton <nickc@redhat.com> 2010-09-07 Nick Clifton <nickc@redhat.com>
* readelf.c (process_section_headers): Mention meaning of 'l' * readelf.c (process_section_headers): Mention meaning of 'l'

View File

@ -712,6 +712,8 @@ display_block (unsigned char *data, unsigned long length)
static int static int
decode_location_expression (unsigned char * data, decode_location_expression (unsigned char * data,
unsigned int pointer_size, unsigned int pointer_size,
unsigned int offset_size,
int dwarf_version,
unsigned long length, unsigned long length,
unsigned long cu_offset, unsigned long cu_offset,
struct dwarf_section * section) struct dwarf_section * section)
@ -1018,20 +1020,36 @@ decode_location_expression (unsigned char * data,
case DW_OP_call2: case DW_OP_call2:
/* XXX: Strictly speaking for 64-bit DWARF3 files /* XXX: Strictly speaking for 64-bit DWARF3 files
this ought to be an 8-byte wide computation. */ this ought to be an 8-byte wide computation. */
printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2) + cu_offset); printf ("DW_OP_call2: <0x%lx>", (long) byte_get (data, 2) + cu_offset);
data += 2; data += 2;
break; break;
case DW_OP_call4: case DW_OP_call4:
/* XXX: Strictly speaking for 64-bit DWARF3 files /* XXX: Strictly speaking for 64-bit DWARF3 files
this ought to be an 8-byte wide computation. */ this ought to be an 8-byte wide computation. */
printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4) + cu_offset); printf ("DW_OP_call4: <0x%lx>", (long) byte_get (data, 4) + cu_offset);
data += 4; data += 4;
break; break;
case DW_OP_call_ref: case DW_OP_call_ref:
/* XXX: Strictly speaking for 64-bit DWARF3 files /* XXX: Strictly speaking for 64-bit DWARF3 files
this ought to be an 8-byte wide computation. */ this ought to be an 8-byte wide computation. */
printf ("DW_OP_call_ref: <%lx>", (long) byte_get (data, 4) + cu_offset); if (dwarf_version == -1)
data += 4; {
printf (_("(DW_OP_call_ref in frame info)"));
/* No way to tell where the next op is, so just bail. */
return need_frame_base;
}
if (dwarf_version == 2)
{
printf ("DW_OP_call_ref: <0x%lx>",
(long) byte_get (data, pointer_size));
data += pointer_size;
}
else
{
printf ("DW_OP_call_ref: <0x%lx>",
(long) byte_get (data, offset_size));
data += offset_size;
}
break; break;
case DW_OP_form_tls_address: case DW_OP_form_tls_address:
printf ("DW_OP_form_tls_address"); printf ("DW_OP_form_tls_address");
@ -1083,6 +1101,30 @@ decode_location_expression (unsigned char * data,
print_dwarf_vma (addr, pointer_size); print_dwarf_vma (addr, pointer_size);
} }
break; break;
case DW_OP_GNU_implicit_pointer:
/* XXX: Strictly speaking for 64-bit DWARF3 files
this ought to be an 8-byte wide computation. */
if (dwarf_version == -1)
{
printf (_("(DW_OP_GNU_implicit_pointer in frame info)"));
/* No way to tell where the next op is, so just bail. */
return need_frame_base;
}
if (dwarf_version == 2)
{
printf ("DW_OP_GNU_implicit_pointer: <0x%lx> %ld",
(long) byte_get (data, pointer_size),
read_leb128 (data + pointer_size, &bytes_read, 1));
data += pointer_size + bytes_read;
}
else
{
printf ("DW_OP_GNU_implicit_pointer: <0x%lx> %ld",
(long) byte_get (data, offset_size),
read_leb128 (data + offset_size, &bytes_read, 1));
data += offset_size;
}
break;
/* HP extensions. */ /* HP extensions. */
case DW_OP_HP_is_value: case DW_OP_HP_is_value:
@ -1632,6 +1674,8 @@ read_and_display_attr_value (unsigned long attribute,
printf ("("); printf ("(");
need_frame_base = decode_location_expression (block_start, need_frame_base = decode_location_expression (block_start,
pointer_size, pointer_size,
offset_size,
dwarf_version,
uvalue, uvalue,
cu_offset, section); cu_offset, section);
printf (")"); printf (")");
@ -2023,6 +2067,8 @@ process_debug_info (struct dwarf_section *section,
debug_information [unit].cu_offset = cu_offset; debug_information [unit].cu_offset = cu_offset;
debug_information [unit].pointer_size debug_information [unit].pointer_size
= compunit.cu_pointer_size; = compunit.cu_pointer_size;
debug_information [unit].offset_size = offset_size;
debug_information [unit].dwarf_version = compunit.cu_version;
debug_information [unit].base_address = 0; debug_information [unit].base_address = 0;
debug_information [unit].loc_offsets = NULL; debug_information [unit].loc_offsets = NULL;
debug_information [unit].have_frame_base = NULL; debug_information [unit].have_frame_base = NULL;
@ -3405,6 +3451,8 @@ display_debug_loc (struct dwarf_section *section, void *file)
unsigned short length; unsigned short length;
unsigned long offset; unsigned long offset;
unsigned int pointer_size; unsigned int pointer_size;
unsigned int offset_size;
int dwarf_version;
unsigned long cu_offset; unsigned long cu_offset;
unsigned long base_address; unsigned long base_address;
int need_frame_base; int need_frame_base;
@ -3412,6 +3460,8 @@ display_debug_loc (struct dwarf_section *section, void *file)
pointer_size = debug_information [i].pointer_size; pointer_size = debug_information [i].pointer_size;
cu_offset = debug_information [i].cu_offset; cu_offset = debug_information [i].cu_offset;
offset_size = debug_information [i].offset_size;
dwarf_version = debug_information [i].dwarf_version;
for (j = 0; j < debug_information [i].num_loc_offsets; j++) for (j = 0; j < debug_information [i].num_loc_offsets; j++)
{ {
@ -3503,6 +3553,8 @@ display_debug_loc (struct dwarf_section *section, void *file)
putchar ('('); putchar ('(');
need_frame_base = decode_location_expression (start, need_frame_base = decode_location_expression (start,
pointer_size, pointer_size,
offset_size,
dwarf_version,
length, length,
cu_offset, section); cu_offset, section);
putchar (')'); putchar (')');
@ -4774,8 +4826,8 @@ display_debug_frames (struct dwarf_section *section,
if (! do_debug_frames_interp) if (! do_debug_frames_interp)
{ {
printf (" DW_CFA_def_cfa_expression ("); printf (" DW_CFA_def_cfa_expression (");
decode_location_expression (start, eh_addr_size, ul, 0, decode_location_expression (start, eh_addr_size, 0, -1,
section); ul, 0, section);
printf (")\n"); printf (")\n");
} }
fc->cfa_exp = 1; fc->cfa_exp = 1;
@ -4791,7 +4843,7 @@ display_debug_frames (struct dwarf_section *section,
{ {
printf (" DW_CFA_expression: %s%s (", printf (" DW_CFA_expression: %s%s (",
reg_prefix, regname (reg, 0)); reg_prefix, regname (reg, 0));
decode_location_expression (start, eh_addr_size, decode_location_expression (start, eh_addr_size, 0, -1,
ul, 0, section); ul, 0, section);
printf (")\n"); printf (")\n");
} }
@ -4809,8 +4861,8 @@ display_debug_frames (struct dwarf_section *section,
{ {
printf (" DW_CFA_val_expression: %s%s (", printf (" DW_CFA_val_expression: %s%s (",
reg_prefix, regname (reg, 0)); reg_prefix, regname (reg, 0));
decode_location_expression (start, eh_addr_size, ul, 0, decode_location_expression (start, eh_addr_size, 0, -1,
section); ul, 0, section);
printf (")\n"); printf (")\n");
} }
if (*reg_prefix == '\0') if (*reg_prefix == '\0')

View File

@ -1,5 +1,5 @@
/* dwarf.h - DWARF support header file /* dwarf.h - DWARF support header file
Copyright 2005, 2007, 2008, 2009 Copyright 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of GNU Binutils. This file is part of GNU Binutils.
@ -84,6 +84,8 @@ extern struct dwarf_section_display debug_displays [];
typedef struct typedef struct
{ {
unsigned int pointer_size; unsigned int pointer_size;
unsigned int offset_size;
int dwarf_version;
unsigned long cu_offset; unsigned long cu_offset;
unsigned long base_address; unsigned long base_address;
/* This is an array of offsets to the location list table. */ /* This is an array of offsets to the location list table. */

View File

@ -1,3 +1,7 @@
2010-09-09 Jakub Jelinek <jakub@redhat.com>
* dwarf2.h (DW_OP_GNU_implicit_pointer): New.
2010-07-06 Ken Werner <ken.werner@de.ibm.com> 2010-07-06 Ken Werner <ken.werner@de.ibm.com>
* floatformat.h (floatformat_ieee_half_big): Add declaration. * floatformat.h (floatformat_ieee_half_big): Add declaration.

View File

@ -622,6 +622,7 @@ enum dwarf_location_atom
/* The following is for marking variables that are uninitialized. */ /* The following is for marking variables that are uninitialized. */
DW_OP_GNU_uninit = 0xf0, DW_OP_GNU_uninit = 0xf0,
DW_OP_GNU_encoded_addr = 0xf1, DW_OP_GNU_encoded_addr = 0xf1,
DW_OP_GNU_implicit_pointer = 0xf2,
/* HP extensions. */ /* HP extensions. */
DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */
DW_OP_HP_is_value = 0xe1, DW_OP_HP_is_value = 0xe1,