Fix initialisation of debug_line_pointer_sizes array so that it is done as needed
authorNick Clifton <nickc@redhat.com>
Wed, 7 Jan 2004 18:50:51 +0000 (18:50 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 7 Jan 2004 18:50:51 +0000 (18:50 +0000)
binutils/ChangeLog
binutils/readelf.c
gas/testsuite/ChangeLog
gas/testsuite/gas/cris/rd-dw2-1.d

index d2a65c6dd6965ec8765c894fe44dc40e8c40d2be..f26615da18fb5ef4264ddc8d9a8cb5b464b35cbe 100644 (file)
@@ -1,3 +1,18 @@
+2004-01-07  Nick Clifton  <nickc@redhat.com>
+
+       * readelf.c (find_section): New function.  Locates a named
+       section.
+       (get_debug_line_pointer_sizes): New function:  Initialises the
+       debug_line_pointer_sizes array.
+        (display_debug_lines): Call get_debug_line_pointer_sizes.
+        (display_debug_loc): Likewise.
+        (load_debug_loc): Use find_section.
+        (load_debug_str): Likewise.
+        (display_debug_info): Likewise.
+        (prescan_debug_info): Delete.
+        (debug_displays): Remove prescan field.
+        (process_section_contents): Do not perform prescans.
+
 2004-01-03  Alan Modra  <amodra@bigpond.net.au>
 
        * objcopy.c (filter_bytes): Delete.  Move code to..
index 67c48168b66c5f6652d7afb78d31d09fc533514a..6604cad3eb6931f19f4b61b429809b58c400c120 100644 (file)
@@ -6271,16 +6271,137 @@ process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
   return len;
 }
 
+/* Finds section NAME inside FILE and returns a
+   pointer to it, or NULL upon failure.  */
+
+static Elf_Internal_Shdr *
+find_section (const char * name)
+{
+  Elf_Internal_Shdr *sec;
+  unsigned int i;
+  
+  for (i = elf_header.e_shnum, sec = section_headers + i - 1;
+       i; --i, --sec)
+    if (strcmp (SECTION_NAME (sec), name) == 0)
+      break;
+
+  if (i && sec && sec->sh_size != 0)
+    return sec;
+
+  return NULL;
+}
+
 /* Size of pointers in the .debug_line section.  This information is not
    really present in that section.  It's obtained before dumping the debug
    sections by doing some pre-scan of the .debug_info section.  */
 static unsigned int * debug_line_pointer_sizes = NULL;
 static unsigned int   num_debug_line_pointer_sizes = 0;
 
+/* Locate and scan the .debug_info section in the file and record the pointer
+   sizes for the compilation units in it.  Usually an executable will have
+   just one pointer size, but this is not guaranteed, and so we try not to
+   make any assumptions.  Returns zero upon failure, or the number of
+   compilation units upon success.  */
+
+static unsigned int
+get_debug_line_pointer_sizes (FILE * file)
+{
+  Elf_Internal_Shdr * section;
+  unsigned char *     start;
+  unsigned char *     end;
+  unsigned char *     begin;
+  unsigned long       length;
+  unsigned int        num_units;
+  unsigned int        unit;
+
+  section = find_section (".debug_info");
+  if (section == NULL)
+    return 0;
+
+  length = section->sh_size;
+  start = get_data (NULL, file, section->sh_offset, section->sh_size,
+                   _("extracting pointer sizes from .debug_info section"));
+  if (start == NULL)
+    return 0;
+
+  end = start + section->sh_size;
+  /* First scan the section to get the number of comp units.  */
+  for (begin = start, num_units = 0; begin < end; num_units++)
+    {
+      /* Read the first 4 bytes.  For a 32-bit DWARF section, this will
+        be the length.  For a 64-bit DWARF section, it'll be the escape
+        code 0xffffffff followed by an 8 byte length.  */
+      length = byte_get (begin, 4);
+
+      if (length == 0xffffffff)
+       {
+         length = byte_get (begin + 4, 8);
+         begin += length + 12;
+       }
+      else
+       begin += length + 4;
+    }
+
+  if (num_units == 0)
+    {
+      error (_("No comp units in .debug_info section ?"));
+      free (start);
+      return 0;
+    }
+
+  /* Then allocate an array to hold the pointer sizes.  */
+  debug_line_pointer_sizes = malloc (num_units * sizeof * debug_line_pointer_sizes);
+  if (debug_line_pointer_sizes == NULL)
+    {
+      error (_("Not enough memory for a pointer size array of %u entries"),
+            num_units);
+      free (start);
+      return 0;
+    }
+
+  /* Populate the array.  */
+  for (begin = start, unit = 0; begin < end; unit++)
+    {
+      length = byte_get (begin, 4);
+      if (length == 0xffffffff)
+       {
+         /* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
+            from the start of the section.  This is computed as follows:
+
+            unit_length:         12 bytes
+            version:              2 bytes
+            debug_abbrev_offset:  8 bytes
+            -----------------------------
+            Total:               22 bytes  */
+
+         debug_line_pointer_sizes [unit] = byte_get (begin + 22, 1);
+         length = byte_get (begin + 4, 8);
+         begin += length + 12;
+       }
+      else
+       {
+         /* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
+            the start of the section:
+            
+            unit_length:          4 bytes
+            version:              2 bytes
+            debug_abbrev_offset:  4 bytes
+            -----------------------------
+            Total:               10 bytes  */
+
+         debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
+         begin += length + 4;
+       }
+    }
+
+  free (start);
+  num_debug_line_pointer_sizes = num_units;
+  return num_units;
+}
+
 static int
 display_debug_lines (Elf_Internal_Shdr *section,
-                    unsigned char * start,
-                    FILE *file ATTRIBUTE_UNUSED)
+                    unsigned char *start, FILE *file)
 {
   unsigned char *hdrptr;
   DWARF2_Internal_LineInfo info;
@@ -6296,6 +6417,9 @@ display_debug_lines (Elf_Internal_Shdr *section,
   printf (_("\nDump of debug contents of section %s:\n\n"),
          SECTION_NAME (section));
 
+  if (num_debug_line_pointer_sizes == 0)
+    get_debug_line_pointer_sizes (file);
+
   while (data < end)
     {
       unsigned int pointer_size;
@@ -7506,20 +7630,14 @@ static void
 load_debug_loc (FILE *file)
 {
   Elf_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)
+  sec = find_section (".debug_loc");
+  if (sec == NULL)
     return;
 
   debug_loc_size = sec->sh_size;
@@ -7542,8 +7660,7 @@ free_debug_loc (void)
 
 static int
 display_debug_loc (Elf_Internal_Shdr *section,
-                  unsigned char *start,
-                  FILE *file ATTRIBUTE_UNUSED)
+                  unsigned char *start, FILE *file)
 {
   unsigned char *section_end;
   unsigned long bytes;
@@ -7561,6 +7678,9 @@ display_debug_loc (Elf_Internal_Shdr *section,
       return 0;
     }
 
+  if (num_debug_line_pointer_sizes == 0)
+    get_debug_line_pointer_sizes (file);
+
   printf (_("Contents of the .debug_loc section:\n\n"));
   printf (_("\n    Offset   Begin    End      Expression\n"));
 
@@ -7625,20 +7745,14 @@ static void
 load_debug_str (FILE *file)
 {
   Elf_Internal_Shdr *sec;
-  unsigned 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)
+  sec = find_section (".debug_str");
+  if (sec == NULL)
     return;
 
   debug_str_size = sec->sh_size;
@@ -8100,7 +8214,6 @@ display_debug_info (Elf_Internal_Shdr *section,
       unsigned char *hdrptr;
       unsigned char *cu_abbrev_offset_ptr;
       unsigned char *tags;
-      unsigned int i;
       int level;
       unsigned long cu_offset;
       int offset_size;
@@ -8224,13 +8337,8 @@ display_debug_info (Elf_Internal_Shdr *section,
        unsigned char *begin;
 
        /* Locate the .debug_abbrev section and process it.  */
-       for (i = 0, sec = section_headers;
-            i < elf_header.e_shnum;
-            i++, sec++)
-         if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
-           break;
-
-       if (i == elf_header.e_shnum || sec->sh_size == 0)
+       sec = find_section (".debug_abbrev");
+       if (sec == NULL)
          {
            warn (_("Unable to locate .debug_abbrev section!\n"));
            return 0;
@@ -9194,121 +9302,31 @@ display_debug_not_supported (Elf_Internal_Shdr *section,
   return 1;
 }
 
-/* Pre-scan the .debug_info section to record the pointer sizes for the
-   compilation units.  Usually an executable will have just one pointer
-   size, but this is not guaranteed, and so we try not to make any
-   assumptions.  Returns zero upon failure, or the number of compilation
-   units upon success.  */
-
-static unsigned int
-prescan_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
-                   FILE *file ATTRIBUTE_UNUSED)
-{
-  unsigned char *begin;
-  unsigned char *end = start + section->sh_size;
-  unsigned long  length;
-  unsigned int   num_units;
-  unsigned int   unit;
-    
-  /* First scan the section to compute the number of comp units.  */
-  for (begin = start, num_units = 0; begin < end; num_units++)
-    {
-      /* Read the first 4 bytes.  For a 32-bit DWARF section, this will
-        be the length.  For a 64-bit DWARF section, it'll be the escape
-        code 0xffffffff followed by an 8 byte length.  */
-      length = byte_get (begin, 4);
-
-      if (length == 0xffffffff)
-       {
-         length = byte_get (begin + 4, 8);
-         begin += length + 12;
-       }
-      else
-       begin += length + 4;
-    }
-
-  if (num_units == 0)
-    {
-      error (_("No comp units in .debug_info section ?"));
-      return 0;
-    }
-
-  /* Then allocate an array to hold the pointer sizes.  */
-  debug_line_pointer_sizes = malloc (num_units * sizeof * debug_line_pointer_sizes);
-  if (debug_line_pointer_sizes == NULL)
-    {
-      error (_("Not enough memory for a pointer size array of %u entries"),
-            num_units);
-      return 0;
-    }
-
-  /* Populate the array.  */
-  for (begin = start, unit = 0; begin < end; unit++)
-    {
-      length = byte_get (begin, 4);
-      if (length == 0xffffffff)
-       {
-         /* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
-            from the start of the section.  This is computed as follows:
-
-            unit_length:         12 bytes
-            version:              2 bytes
-            debug_abbrev_offset:  8 bytes
-            -----------------------------
-            Total:               22 bytes  */
-
-         debug_line_pointer_sizes [unit] = byte_get (begin + 22, 1);
-         length = byte_get (begin + 4, 8);
-         begin += length + 12;
-       }
-      else
-       {
-         /* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
-            the start of the section:
-            
-            unit_length:          4 bytes
-            version:              2 bytes
-            debug_abbrev_offset:  4 bytes
-            -----------------------------
-            Total:               10 bytes  */
-
-         debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
-         begin += length + 4;
-       }
-    }
-
-  num_debug_line_pointer_sizes = num_units;
-  return num_units;
-}
-
-/* A structure containing the name of a debug section and a pointer
-   to a function that can decode it.  The third field is a prescan
-   function to be run over the section before displaying any of the
-   sections.  */
+/* A structure containing the name of a debug section
+   and a pointer to a function that can decode it.  */
 struct
 {
   const char *const name;
   int (*display) (Elf_Internal_Shdr *, unsigned char *, FILE *);
-  int (*prescan) (Elf_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_loc",              display_debug_loc, 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 },
-  { ".debug_weaknames",                display_debug_not_supported, NULL }
+  { ".debug_abbrev",           display_debug_abbrev },
+  { ".debug_aranges",          display_debug_aranges },
+  { ".debug_frame",            display_debug_frames },
+  { ".debug_info",             display_debug_info },
+  { ".debug_line",             display_debug_lines },
+  { ".debug_pubnames",         display_debug_pubnames },
+  { ".eh_frame",               display_debug_frames },
+  { ".debug_macinfo",          display_debug_macinfo },
+  { ".debug_str",              display_debug_str },
+  { ".debug_loc",              display_debug_loc },
+  { ".debug_pubtypes",         display_debug_not_supported },
+  { ".debug_ranges",           display_debug_not_supported },
+  { ".debug_static_func",      display_debug_not_supported },
+  { ".debug_static_vars",      display_debug_not_supported },
+  { ".debug_types",            display_debug_not_supported },
+  { ".debug_weaknames",                display_debug_not_supported }
 };
 
 static int
@@ -9363,42 +9381,6 @@ process_section_contents (FILE *file)
   if (! do_dump)
     return 1;
 
-  /* Pre-scan the debug sections to find some debug information not
-     present in some of them.  For the .debug_line, we must find out the
-     size of address (specified in .debug_info and .debug_aranges).  */
-  for (i = 0, section = section_headers;
-       i < elf_header.e_shnum && i < num_dump_sects;
-       i++, section++)
-    {
-      char *name = SECTION_NAME (section);
-      int j;
-
-      if (section->sh_size == 0)
-       continue;
-
-      /* See if there is some pre-scan operation for this section.  */
-      for (j = NUM_ELEM (debug_displays); j--;)
-       if (strcmp (debug_displays[j].name, name) == 0)
-         {
-           if (debug_displays[j].prescan != NULL)
-             {
-               bfd_size_type length;
-               unsigned char *start;
-
-               length = section->sh_size;
-               start = get_data (NULL, file, section->sh_offset, length,
-                                 _("debug section data"));
-               if (!start)
-                 return 0;
-
-               debug_displays[j].prescan (section, start, file);
-               free (start);
-             }
-
-           break;
-         }
-    }
-
   for (i = 0, section = section_headers;
        i < elf_header.e_shnum && i < num_dump_sects;
        i++, section++)
index c077fdb68c18aa43a6d11e190367ba91f827d3f7..5815de85ad082119626c3aee69d6d66248501a5f 100644 (file)
@@ -1,3 +1,7 @@
+2004-01-07  Nick Clifton  <nickc@redhat.com>
+
+       * gas/cris/rd-dw2-1.d: Expect a pointer size from readelf.
+
 2004-01-06  Alexandre Oliva  <aoliva@redhat.com>
 
        2003-11-05  Alexandre Oliva  <aoliva@redhat.com>
index a487af8b806699836093cf848af343fc0adc4c61..fa9da0c02f8c121c85c271ac96b0aa5a126cfabb 100644 (file)
@@ -14,6 +14,7 @@ Dump of debug contents of section \.debug_line:
   Line Base:                   -5
   Line Range:                  14
   Opcode Base:                 10
+  \(Pointer size:               4\)
 
  Opcodes:
   Opcode 1 has 0 args