bug-gnu-utils
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]