Add -ws switch to display contents of .debug_str sections

This commit is contained in:
Nick Clifton 2001-11-19 14:35:57 +00:00
parent b8908f93e2
commit 261a45adff
3 changed files with 174 additions and 54 deletions

View file

@ -1,3 +1,24 @@
2001-11-19 Nick Clifton <nickc@cambridge.redhat.com>
* readelf.c (do_debug_str): New variable.
(display_debug_str): New function: Display the contents of a
.debug_str section.
(load_debug_str): New function: Load in the contents of a
.debug_str section.
(free_debug_str): New function: Free the memory used by
load_debug_str().
(fetch_indirect_string): Retrieve a string from the .debug_str
section.
(usage): Add -ws.
(parse_args): Accept -ws.
(process_section_headers): Allow the display of the .debug_str
section.
(read_and_display_attr_value): Use fetch_indirect_string. Show
offset into .debug_str section.
(display_debug_info): Use load_debug_str and free_debug_str.
(debug_displays): Add .debug_str.
* doc/binutils.texi: Document -ws.
2001-11-19 Andreas Jaeger <aj@suse.de>
* testsuite/binutils-all/objdump.exp: Add x86-64.

View file

@ -2851,7 +2851,7 @@ readelf [@option{-a}|@option{--all}]
[@option{-V}|@option{--version-info}]
[@option{-D}|@option{--use-dynamic}]
[@option{-x} <number>|@option{--hex-dump=}<number>]
[@option{-w[liaprmf]}|@option{--debug-dump}[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames]]
[@option{-w[liaprmfs]}|@option{--debug-dump}[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str]]
[@option{-histogram}]
[@option{-v}|@option{--version}]
[@option{-W}|@option{--wide}]
@ -2953,8 +2953,8 @@ symbols section.
@itemx --hex-dump=<number>
Displays the contents of the indicated section as a hexadecimal dump.
@item -w[liaprmf]
@itemx --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames]
@item -w[liaprmfs]
@itemx --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str]
Displays the contents of the debug sections in the file, if any are
present. If one of the optional letters or words follows the switch
then only data found in those specific sections will be dumped.

View file

@ -123,6 +123,7 @@ int do_debug_aranges;
int do_debug_frames;
int do_debug_frames_interp;
int do_debug_macinfo;
int do_debug_str;
int do_arch;
int do_notes;
int is_32bit_elf;
@ -220,7 +221,11 @@ static int display_debug_abbrev PARAMS ((Elf32_Internal_Sh
static int display_debug_aranges 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_str PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
static void load_debug_str PARAMS ((FILE *));
static void free_debug_str PARAMS ((void));
static const char * fetch_indirect_string PARAMS ((unsigned long));
static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
static int process_extended_line_op PARAMS ((unsigned char *, int, int));
static void reset_state_machine PARAMS ((int));
@ -276,7 +281,7 @@ typedef int Elf32_Word;
#define BYTE_GET8(field) byte_get (field, 8)
#endif
#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
#define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
#define GET_ELF_SYMBOLS(file, offset, size) \
(is_32bit_elf ? get_32bit_elf_symbols (file, offset, size) \
@ -2072,7 +2077,7 @@ usage ()
fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
fprintf (stdout, _(" Dump the contents of section <number>\n"));
fprintf (stdout, _(" -w[liaprmf] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames]\n"));
fprintf (stdout, _(" -w[liaprmfs] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str]\n"));
fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
#ifdef SUPPORT_DISASSEMBLY
fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
@ -2252,6 +2257,11 @@ parse_args (argc, argv)
do_debug_macinfo = 1;
break;
case 's':
case 'S':
do_debug_str = 1;
break;
default:
warn (_("Unrecognised debug option '%s'\n"), optarg);
break;
@ -3046,7 +3056,7 @@ process_section_headers (file)
}
else if ((do_debugging || do_debug_info || do_debug_abbrevs
|| do_debug_lines || do_debug_pubnames || do_debug_aranges
|| do_debug_frames || do_debug_macinfo)
|| do_debug_frames || do_debug_macinfo || do_debug_str)
&& strncmp (name, ".debug_", 7) == 0)
{
name += 7;
@ -3059,6 +3069,7 @@ process_section_headers (file)
|| (do_debug_aranges && (strcmp (name, "aranges") == 0))
|| (do_debug_frames && (strcmp (name, "frame") == 0))
|| (do_debug_macinfo && (strcmp (name, "macinfo") == 0))
|| (do_debug_str && (strcmp (name, "str") == 0))
)
request_dump (i, DEBUG_DUMP);
}
@ -4091,7 +4102,6 @@ process_dynamic_segment (file)
dynamic_strings = (char *) get_data (NULL, file, offset, str_tab_len,
_("dynamic string table"));
break;
}
}
@ -4740,12 +4750,12 @@ process_version_sections (file)
case SHT_GNU_versym:
{
Elf32_Internal_Shdr * link_section;
int total;
int cnt;
unsigned char * edata;
unsigned short * data;
char * strtab;
Elf_Internal_Sym * symbols;
int total;
int cnt;
unsigned char * edata;
unsigned short * data;
char * strtab;
Elf_Internal_Sym * symbols;
Elf32_Internal_Shdr * string_sec;
link_section = section_headers + section->sh_link;
@ -6307,9 +6317,6 @@ get_FORM_name (form)
}
}
static const char *debug_str;
static bfd_vma debug_str_size;
/* FIXME: There are better and more effiecint ways to handle
these structures. For now though, I just want something that
is simple to implement. */
@ -6933,6 +6940,123 @@ decode_location_expression (data, pointer_size, length)
}
static const char * debug_str_contents;
static bfd_vma debug_str_size;
static void
load_debug_str (file)
FILE * file;
{
Elf32_Internal_Shdr * sec;
int i;
/* If it is already loaded, do nothing. */
if (debug_str_contents != NULL)
return;
/* Locate the .debug_str section. */
for (i = 0, sec = section_headers;
i < elf_header.e_shnum;
i ++, sec ++)
if (strcmp (SECTION_NAME (sec), ".debug_str") == 0)
break;
if (i == elf_header.e_shnum || sec->sh_size == 0)
return;
debug_str_size = sec->sh_size;
debug_str_contents = ((char *)
get_data (NULL, file, sec->sh_offset, sec->sh_size,
_("debug_str section data")));
}
static void
free_debug_str ()
{
if (debug_str_contents == NULL)
return;
free ((char *) debug_str_contents);
debug_str_contents = NULL;
debug_str_size = 0;
}
static const char *
fetch_indirect_string (offset)
unsigned long offset;
{
if (debug_str_contents == NULL)
return _("<no .debug_str section>");
if (offset > debug_str_size)
return _("<offset is too big>");
return debug_str_contents + offset;
}
static int
display_debug_str (section, start, file)
Elf32_Internal_Shdr * section;
unsigned char * start;
FILE * file ATTRIBUTE_UNUSED;
{
unsigned long bytes;
bfd_vma addr;
addr = section->sh_addr;
bytes = section->sh_size;
if (bytes == 0)
{
printf (_("\nThe .debug_str section is empty.\n"));
return 0;
}
printf (_("Contents of the .debug_str section:\n\n"));
while (bytes)
{
int j;
int k;
int lbytes;
lbytes = (bytes > 16 ? 16 : bytes);
printf (" 0x%8.8lx ", (unsigned long) addr);
for (j = 0; j < 16; j++)
{
if (j < lbytes)
printf ("%2.2x", start [j]);
else
printf (" ");
if ((j & 3) == 3)
printf (" ");
}
for (j = 0; j < lbytes; j++)
{
k = start [j];
if (k >= ' ' && k < 0x80)
printf ("%c", k);
else
printf (".");
}
putchar ('\n');
start += lbytes;
addr += lbytes;
bytes -= lbytes;
}
return 1;
}
static unsigned char *
read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size)
unsigned long attribute;
@ -7061,13 +7185,8 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size)
break;
case DW_FORM_strp:
if (debug_str == NULL)
warn (_("DW_FORM_strp used but no .debug_str section\n"));
else if (uvalue >= debug_str_size)
warn (_("DW_FORM_strp %lx points outside of .debug_str section\n"),
uvalue);
else
printf (" %s", debug_str + uvalue);
printf (_(" (indirect string, offset: 0x%lx): "), uvalue);
printf (fetch_indirect_string (uvalue));
break;
case DW_FORM_indirect:
@ -7259,23 +7378,7 @@ display_debug_info (section, start, file)
printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
{
Elf32_Internal_Shdr * sec;
int i;
/* Locate the .debug_str section and read it. */
for (i = 0, sec = section_headers;
i < elf_header.e_shnum;
i ++, sec ++)
if (strcmp (SECTION_NAME (sec), ".debug_str") == 0 && sec->sh_size != 0)
{
debug_str = (const char *)
get_data (NULL, file, sec->sh_offset, sec->sh_size,
_("debug_str section data"));
debug_str_size = sec->sh_size;
break;
}
}
load_debug_str (file);
while (start < end)
{
@ -7378,8 +7481,7 @@ display_debug_info (section, start, file)
continue;
}
if (first_abbrev != NULL)
free_abbrevs ();
free_abbrevs ();
/* Read in the abbrevs used by this compilation unit. */
@ -7461,11 +7563,7 @@ display_debug_info (section, start, file)
}
}
if (debug_str != NULL)
{
free ((char *) debug_str);
debug_str = NULL;
}
free_debug_str ();
printf ("\n");
@ -8262,22 +8360,24 @@ prescan_debug_info (section, start, file)
sections. */
struct
{
char * name;
const char * const name;
int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
}
debug_displays[] =
{
{ ".debug_info", display_debug_info, prescan_debug_info },
{ ".debug_abbrev", display_debug_abbrev, NULL },
{ ".debug_line", display_debug_lines, NULL },
{ ".debug_aranges", display_debug_aranges, NULL },
{ ".debug_pubnames", display_debug_pubnames, NULL },
{ ".debug_frame", display_debug_frames, NULL },
{ ".debug_info", display_debug_info, prescan_debug_info },
{ ".debug_line", display_debug_lines, NULL },
{ ".debug_pubnames", display_debug_pubnames, NULL },
{ ".eh_frame", display_debug_frames, NULL },
{ ".debug_macinfo", display_debug_macinfo, NULL },
{ ".debug_str", display_debug_str, NULL },
{ ".debug_pubtypes", display_debug_not_supported, NULL },
{ ".debug_str", display_debug_not_supported, NULL },
{ ".debug_ranges", display_debug_not_supported, NULL },
{ ".debug_static_func", display_debug_not_supported, NULL },
{ ".debug_static_vars", display_debug_not_supported, NULL },
{ ".debug_types", display_debug_not_supported, NULL },
@ -8324,8 +8424,7 @@ display_debug_section (section, file)
/* If we loaded in the abbrev section at some point,
we must release it here. */
if (first_abbrev != NULL)
free_abbrevs ();
free_abbrevs ();
return 1;
}