2002-03-20 Daniel Berlin <dan@dberlin.org>
* readelf.c: Add support for displaying dwarf2 location lists. (do_debug_loc, debug_loc_section, debug_loc_size): New. (parse_args): Use 'O' as shorthand for displaying location list section. (process_section_headers): Handle debug_loc as well. (load_debug_loc): New. (free_debug_loc): New. (fetch_location_list): New. (display_debug_loc): New. (display_debug_info): Call load_debug_loc and free_debug_loc. (debug_displays): We can display .debug_loc now, too. (usage): Update usage string. (read_and_display_attr_value): Note location lists, but don't display them inline.
This commit is contained in:
parent
bdbe574731
commit
a2f14207f3
2 changed files with 157 additions and 3 deletions
|
@ -1,3 +1,20 @@
|
||||||
|
2002-03-20 Daniel Berlin <dan@dberlin.org>
|
||||||
|
|
||||||
|
* readelf.c: Add support for displaying dwarf2 location lists.
|
||||||
|
(do_debug_loc, debug_loc_section, debug_loc_size): New.
|
||||||
|
(parse_args): Use 'O' as shorthand for displaying location list
|
||||||
|
section.
|
||||||
|
(process_section_headers): Handle debug_loc as well.
|
||||||
|
(load_debug_loc): New.
|
||||||
|
(free_debug_loc): New.
|
||||||
|
(fetch_location_list): New.
|
||||||
|
(display_debug_loc): New.
|
||||||
|
(display_debug_info): Call load_debug_loc and free_debug_loc.
|
||||||
|
(debug_displays): We can display .debug_loc now, too.
|
||||||
|
(usage): Update usage string.
|
||||||
|
(read_and_display_attr_value): Note location lists, but don't
|
||||||
|
display them inline.
|
||||||
|
|
||||||
2002-03-18 Tom Rix <trix@redhat.com>
|
2002-03-18 Tom Rix <trix@redhat.com>
|
||||||
|
|
||||||
* Makefile.am: Add binutils emulation support.
|
* Makefile.am: Add binutils emulation support.
|
||||||
|
|
|
@ -127,6 +127,7 @@ int do_debug_frames;
|
||||||
int do_debug_frames_interp;
|
int do_debug_frames_interp;
|
||||||
int do_debug_macinfo;
|
int do_debug_macinfo;
|
||||||
int do_debug_str;
|
int do_debug_str;
|
||||||
|
int do_debug_loc;
|
||||||
int do_arch;
|
int do_arch;
|
||||||
int do_notes;
|
int do_notes;
|
||||||
int is_32bit_elf;
|
int is_32bit_elf;
|
||||||
|
@ -227,10 +228,14 @@ static int display_debug_aranges PARAMS ((Elf32_Internal_Sh
|
||||||
static int display_debug_frames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
|
static int display_debug_frames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
|
||||||
static int display_debug_macinfo PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
|
static int display_debug_macinfo PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
|
||||||
static int display_debug_str PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
|
static int display_debug_str PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
|
||||||
|
static int display_debug_loc PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
|
||||||
static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
|
static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
|
||||||
static void load_debug_str PARAMS ((FILE *));
|
static void load_debug_str PARAMS ((FILE *));
|
||||||
static void free_debug_str PARAMS ((void));
|
static void free_debug_str PARAMS ((void));
|
||||||
static const char * fetch_indirect_string PARAMS ((unsigned long));
|
static const char * fetch_indirect_string PARAMS ((unsigned long));
|
||||||
|
static void load_debug_loc PARAMS ((FILE *));
|
||||||
|
static void free_debug_loc PARAMS ((void));
|
||||||
|
static const char * fetch_location_list PARAMS ((unsigned long));
|
||||||
static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
|
static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
|
||||||
static int process_extended_line_op PARAMS ((unsigned char *, int, int));
|
static int process_extended_line_op PARAMS ((unsigned char *, int, int));
|
||||||
static void reset_state_machine PARAMS ((int));
|
static void reset_state_machine PARAMS ((int));
|
||||||
|
@ -2248,7 +2253,7 @@ usage ()
|
||||||
-A --arch-specific Display architecture specific information (if any).\n\
|
-A --arch-specific Display architecture specific information (if any).\n\
|
||||||
-D --use-dynamic Use the dynamic section info when displaying symbols\n\
|
-D --use-dynamic Use the dynamic section info when displaying symbols\n\
|
||||||
-x --hex-dump=<number> Dump the contents of section <number>\n\
|
-x --hex-dump=<number> Dump the contents of section <number>\n\
|
||||||
-w --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str]\n\
|
-w --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str,=loc]\n\
|
||||||
Display the contents of DWARF2 debug sections\n"));
|
Display the contents of DWARF2 debug sections\n"));
|
||||||
#ifdef SUPPORT_DISASSEMBLY
|
#ifdef SUPPORT_DISASSEMBLY
|
||||||
fprintf (stdout, _("\
|
fprintf (stdout, _("\
|
||||||
|
@ -2435,6 +2440,11 @@ parse_args (argc, argv)
|
||||||
do_debug_str = 1;
|
do_debug_str = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
do_debug_loc = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
warn (_("Unrecognized debug option '%s'\n"), optarg);
|
warn (_("Unrecognized debug option '%s'\n"), optarg);
|
||||||
break;
|
break;
|
||||||
|
@ -3301,7 +3311,8 @@ process_section_headers (file)
|
||||||
}
|
}
|
||||||
else if ((do_debugging || do_debug_info || do_debug_abbrevs
|
else if ((do_debugging || do_debug_info || do_debug_abbrevs
|
||||||
|| do_debug_lines || do_debug_pubnames || do_debug_aranges
|
|| do_debug_lines || do_debug_pubnames || do_debug_aranges
|
||||||
|| do_debug_frames || do_debug_macinfo || do_debug_str)
|
|| do_debug_frames || do_debug_macinfo || do_debug_str
|
||||||
|
|| do_debug_loc)
|
||||||
&& strncmp (name, ".debug_", 7) == 0)
|
&& strncmp (name, ".debug_", 7) == 0)
|
||||||
{
|
{
|
||||||
name += 7;
|
name += 7;
|
||||||
|
@ -3315,6 +3326,7 @@ process_section_headers (file)
|
||||||
|| (do_debug_frames && (strcmp (name, "frame") == 0))
|
|| (do_debug_frames && (strcmp (name, "frame") == 0))
|
||||||
|| (do_debug_macinfo && (strcmp (name, "macinfo") == 0))
|
|| (do_debug_macinfo && (strcmp (name, "macinfo") == 0))
|
||||||
|| (do_debug_str && (strcmp (name, "str") == 0))
|
|| (do_debug_str && (strcmp (name, "str") == 0))
|
||||||
|
|| (do_debug_loc && (strcmp (name, "loc") == 0))
|
||||||
)
|
)
|
||||||
request_dump (i, DEBUG_DUMP);
|
request_dump (i, DEBUG_DUMP);
|
||||||
}
|
}
|
||||||
|
@ -7187,6 +7199,123 @@ decode_location_expression (data, pointer_size, length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char * debug_loc_contents;
|
||||||
|
static bfd_vma debug_loc_size;
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_debug_loc (file)
|
||||||
|
FILE * file;
|
||||||
|
{
|
||||||
|
Elf32_Internal_Shdr * sec;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/* If it is already loaded, do nothing. */
|
||||||
|
if (debug_loc_contents != NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Locate the .debug_loc section. */
|
||||||
|
for (i = 0, sec = section_headers;
|
||||||
|
i < elf_header.e_shnum;
|
||||||
|
i ++, sec ++)
|
||||||
|
if (strcmp (SECTION_NAME (sec), ".debug_loc") == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == elf_header.e_shnum || sec->sh_size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
debug_loc_size = sec->sh_size;
|
||||||
|
|
||||||
|
debug_loc_contents = ((char *)
|
||||||
|
get_data (NULL, file, sec->sh_offset, sec->sh_size,
|
||||||
|
_("debug_loc section data")));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_debug_loc ()
|
||||||
|
{
|
||||||
|
if (debug_loc_contents == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free ((char *) debug_loc_contents);
|
||||||
|
debug_loc_contents = NULL;
|
||||||
|
debug_loc_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
fetch_location_list (offset)
|
||||||
|
unsigned long offset;
|
||||||
|
{
|
||||||
|
if (debug_loc_contents == NULL)
|
||||||
|
return _("<no .debug_loc section>");
|
||||||
|
|
||||||
|
if (offset > debug_loc_size)
|
||||||
|
return _("<offset is too big>");
|
||||||
|
|
||||||
|
return debug_loc_contents + offset;
|
||||||
|
}
|
||||||
|
static int
|
||||||
|
display_debug_loc (section, start, file)
|
||||||
|
Elf32_Internal_Shdr * section;
|
||||||
|
unsigned char * start;
|
||||||
|
FILE * file ATTRIBUTE_UNUSED;
|
||||||
|
{
|
||||||
|
unsigned char *section_end;
|
||||||
|
unsigned long bytes;
|
||||||
|
unsigned char *section_begin = start;
|
||||||
|
bfd_vma addr;
|
||||||
|
|
||||||
|
addr = section->sh_addr;
|
||||||
|
bytes = section->sh_size;
|
||||||
|
section_end = start + bytes;
|
||||||
|
if (bytes == 0)
|
||||||
|
{
|
||||||
|
printf (_("\nThe .debug_loc section is empty.\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
printf (_("Contents of the .debug_loc section:\n\n"));
|
||||||
|
printf (_("\n Offset Begin End Expression\n"));
|
||||||
|
while (start < section_end)
|
||||||
|
{
|
||||||
|
unsigned long begin;
|
||||||
|
unsigned long end;
|
||||||
|
unsigned short length;
|
||||||
|
unsigned long offset;
|
||||||
|
|
||||||
|
offset = start - section_begin;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* Normally, the lists in the debug_loc section are related to a
|
||||||
|
given compilation unit, and thus, we would use the
|
||||||
|
pointer size of that compilation unit. However, since we are
|
||||||
|
displaying it seperately here, we either have to store
|
||||||
|
pointer sizes of all compilation units, or assume they don't
|
||||||
|
change. We assume, like the debug_line display, that
|
||||||
|
it doesn't change. */
|
||||||
|
begin = byte_get (start, debug_line_pointer_size);
|
||||||
|
start += debug_line_pointer_size;
|
||||||
|
end = byte_get (start, debug_line_pointer_size);
|
||||||
|
start += debug_line_pointer_size;
|
||||||
|
|
||||||
|
if (begin == 0 && end == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
begin += addr;
|
||||||
|
end += addr;
|
||||||
|
|
||||||
|
length = byte_get (start, 2);
|
||||||
|
start += 2;
|
||||||
|
|
||||||
|
printf (" %8.8lx %8.8lx %8.8lx (", offset, begin, end);
|
||||||
|
decode_location_expression (start, debug_line_pointer_size, length);
|
||||||
|
printf (")\n");
|
||||||
|
|
||||||
|
start += length;
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static const char * debug_str_contents;
|
static const char * debug_str_contents;
|
||||||
static bfd_vma debug_str_size;
|
static bfd_vma debug_str_size;
|
||||||
|
@ -7591,6 +7720,12 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size)
|
||||||
decode_location_expression (block_start, pointer_size, uvalue);
|
decode_location_expression (block_start, pointer_size, uvalue);
|
||||||
printf (")");
|
printf (")");
|
||||||
}
|
}
|
||||||
|
else if (form == DW_FORM_data4)
|
||||||
|
{
|
||||||
|
printf ("(");
|
||||||
|
printf ("location list");
|
||||||
|
printf (")");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -7627,6 +7762,7 @@ display_debug_info (section, start, file)
|
||||||
printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
|
printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
|
||||||
|
|
||||||
load_debug_str (file);
|
load_debug_str (file);
|
||||||
|
load_debug_loc (file);
|
||||||
|
|
||||||
while (start < end)
|
while (start < end)
|
||||||
{
|
{
|
||||||
|
@ -7811,6 +7947,7 @@ display_debug_info (section, start, file)
|
||||||
}
|
}
|
||||||
|
|
||||||
free_debug_str ();
|
free_debug_str ();
|
||||||
|
free_debug_loc ();
|
||||||
|
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
|
||||||
|
@ -8622,7 +8759,7 @@ debug_displays[] =
|
||||||
{ ".eh_frame", display_debug_frames, NULL },
|
{ ".eh_frame", display_debug_frames, NULL },
|
||||||
{ ".debug_macinfo", display_debug_macinfo, NULL },
|
{ ".debug_macinfo", display_debug_macinfo, NULL },
|
||||||
{ ".debug_str", display_debug_str, NULL },
|
{ ".debug_str", display_debug_str, NULL },
|
||||||
|
{ ".debug_loc", display_debug_loc, NULL },
|
||||||
{ ".debug_pubtypes", display_debug_not_supported, NULL },
|
{ ".debug_pubtypes", display_debug_not_supported, NULL },
|
||||||
{ ".debug_ranges", display_debug_not_supported, NULL },
|
{ ".debug_ranges", display_debug_not_supported, NULL },
|
||||||
{ ".debug_static_func", display_debug_not_supported, NULL },
|
{ ".debug_static_func", display_debug_not_supported, NULL },
|
||||||
|
|
Loading…
Add table
Reference in a new issue