[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Display contents of .debug_str section
From: |
Nick Clifton |
Subject: |
Display contents of .debug_str section |
Date: |
19 Nov 2001 14:31:37 +0000 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/21.1 |
Hi Guys,
I am applying the patch below to allow readelf to display the
contents of a .debug_str section (command line switch: -ws). I also
extended the display of the DW_FORM_strp attribute so that it shows
the offset into the .debug_str section, in case this offset is
buggy.
Cheers
Nick
2001-11-19 Nick Clifton <address@hidden>
* 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.
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.134
diff -p -w -r1.134 readelf.c
*** readelf.c 2001/11/15 13:14:09 1.134
--- readelf.c 2001/11/19 14:22:34
*************** int do_debug_aranges
*** 123,128 ****
--- 123,129 ----
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;
*************** static int display_debug_
*** 220,226 ****
--- 221,231 ----
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));
*************** usage ()
*** 2072,2078 ****
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, _(" Display the contents of
DWARF2 debug sections\n"));
#ifdef SUPPORT_DISASSEMBLY
fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
--- 2077,2083 ----
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[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"));
*************** parse_args (argc, argv)
*** 2252,2257 ****
--- 2257,2267 ----
do_debug_macinfo = 1;
break;
+ case 's':
+ case 'S':
+ do_debug_str = 1;
+ break;
+
default:
warn (_("Unrecognised debug option '%s'\n"), optarg);
break;
*************** process_section_headers (file)
*** 3046,3052 ****
}
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)
&& strncmp (name, ".debug_", 7) == 0)
{
name += 7;
--- 3056,3062 ----
}
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_str)
&& strncmp (name, ".debug_", 7) == 0)
{
name += 7;
*************** process_section_headers (file)
*** 3059,3064 ****
--- 3069,3075 ----
|| (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);
}
*************** get_FORM_name (form)
*** 6307,6315 ****
}
}
- 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. */
--- 6317,6322 ----
*************** decode_location_expression (data, pointe
*** 6933,6938 ****
--- 6940,7062 ----
}
+ 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;
*************** read_and_display_attr_value (attribute,
*** 7061,7073 ****
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);
break;
case DW_FORM_indirect:
--- 7185,7192 ----
break;
case DW_FORM_strp:
! printf (_(" (indirect string, offset: 0x%lx): "), uvalue);
! printf (fetch_indirect_string (uvalue));
break;
case DW_FORM_indirect:
*************** display_debug_info (section, start, file
*** 7259,7282 ****
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;
- }
- }
-
while (start < end)
{
DWARF2_External_CompUnit * external;
--- 7378,7385 ----
printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
! load_debug_str (file);
while (start < end)
{
DWARF2_External_CompUnit * external;
*************** display_debug_info (section, start, file
*** 7378,7384 ****
continue;
}
- if (first_abbrev != NULL)
free_abbrevs ();
/* Read in the abbrevs used by this compilation unit. */
--- 7481,7486 ----
*************** display_debug_info (section, start, file
*** 7461,7471 ****
}
}
! if (debug_str != NULL)
! {
! free ((char *) debug_str);
! debug_str = NULL;
! }
printf ("\n");
--- 7563,7569 ----
}
}
! free_debug_str ();
printf ("\n");
*************** prescan_debug_info (section, start, file
*** 8262,8283 ****
sections. */
struct
{
! char * 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 },
{ ".eh_frame", display_debug_frames, NULL },
{ ".debug_macinfo", display_debug_macinfo, NULL },
{ ".debug_pubtypes", display_debug_not_supported, NULL },
! { ".debug_str", 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 },
--- 8360,8383 ----
sections. */
struct
{
! 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_abbrev", display_debug_abbrev, NULL },
{ ".debug_aranges", display_debug_aranges, 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_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 },
*************** display_debug_section (section, file)
*** 8324,8330 ****
/* If we loaded in the abbrev section at some point,
we must release it here. */
- if (first_abbrev != NULL)
free_abbrevs ();
return 1;
--- 8424,8429 ----
Index: binutils/doc/binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/doc/binutils.texi,v
retrieving revision 1.11
diff -p -w -r1.11 binutils.texi
*** binutils.texi 2001/11/15 01:08:50 1.11
--- binutils.texi 2001/11/19 14:22:35
*************** readelf address@hidden|@option{--all}]
*** 2851,2857 ****
address@hidden|@option{--version-info}]
address@hidden|@option{--use-dynamic}]
address@hidden <number>|@option{--hex-dump=}<number>]
!
address@hidden|@option{--debug-dump}[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames]]
address@hidden
address@hidden|@option{--version}]
address@hidden|@option{--wide}]
--- 2851,2857 ----
address@hidden|@option{--version-info}]
address@hidden|@option{--use-dynamic}]
address@hidden <number>|@option{--hex-dump=}<number>]
!
address@hidden|@option{--debug-dump}[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str]]
address@hidden
address@hidden|@option{--version}]
address@hidden|@option{--wide}]
*************** symbols section.
*** 2953,2960 ****
@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]
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.
--- 2953,2960 ----
@itemx --hex-dump=<number>
Displays the contents of the indicated section as a hexadecimal dump.
! @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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Display contents of .debug_str section,
Nick Clifton <=