]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Update pointer_size patch
authorNick Clifton <nickc@redhat.com>
Mon, 29 Dec 2003 14:22:07 +0000 (14:22 +0000)
committerNick Clifton <nickc@redhat.com>
Mon, 29 Dec 2003 14:22:07 +0000 (14:22 +0000)
binutils/ChangeLog
binutils/readelf.c

index bf46bce64377e18dd3163a4eb7dca506378b20ce..f1a21c163ed48c05324e954ff1358e5477513b1a 100644 (file)
@@ -1,3 +1,14 @@
+2003-12-29  Nick Clifton  <nickc@redhat.com>
+
+       * readelf.c (debug_line_pointer_size): Replace with an array
+        called 'debug_line_pointer_sizes'.
+        (num_debug_line_pointer_sizes): New variable.
+        (display_debug_lines): Extract pointer size from the
+        debug_line_pointer_sizes array.
+        (display_debug_loc): Likewise.
+        (prescan_debug_info): Fill in the debug_line_pointer_sizes
+        array.
+
 2003-12-23  Ralf Baechle  <ralf@gnu.org>
            Maciej W. Rozycki  <macro@ds2.pg.gda.pl>
 
index 6774088bb864467ffec4c847d9b22a62cd2b702a..67c48168b66c5f6652d7afb78d31d09fc533514a 100644 (file)
@@ -6274,7 +6274,8 @@ process_extended_line_op (unsigned char *data, int is_stmt, int pointer_size)
 /* 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 int debug_line_pointer_size = 4;
+static unsigned int * debug_line_pointer_sizes = NULL;
+static unsigned int   num_debug_line_pointer_sizes = 0;
 
 static int
 display_debug_lines (Elf_Internal_Shdr *section,
@@ -6290,12 +6291,15 @@ display_debug_lines (Elf_Internal_Shdr *section,
   int i;
   int offset_size;
   int initial_length_size;
+  unsigned int comp_unit = 0;
 
   printf (_("\nDump of debug contents of section %s:\n\n"),
          SECTION_NAME (section));
 
   while (data < end)
     {
+      unsigned int pointer_size;
+
       hdrptr = data;
 
       /* Check the length of the block.  */
@@ -6349,6 +6353,19 @@ display_debug_lines (Elf_Internal_Shdr *section,
       info.li_line_base <<= 24;
       info.li_line_base >>= 24;
 
+      /* Get the pointer size from the comp unit associated
+        with this block of line number information.  */
+      if (comp_unit >= num_debug_line_pointer_sizes)
+       {
+         error (_("Not enough comp units for .debug_lines section\n"));
+         return 0;
+       }
+      else
+       {
+         pointer_size = debug_line_pointer_sizes [comp_unit];
+         comp_unit ++;
+       }
+
       printf (_("  Length:                      %ld\n"), info.li_length);
       printf (_("  DWARF Version:               %d\n"), info.li_version);
       printf (_("  Prologue Length:             %d\n"), info.li_prologue_length);
@@ -6357,6 +6374,7 @@ display_debug_lines (Elf_Internal_Shdr *section,
       printf (_("  Line Base:                   %d\n"), info.li_line_base);
       printf (_("  Line Range:                  %d\n"), info.li_line_range);
       printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
+      printf (_("  (Pointer size:               %u)\n"), pointer_size);
 
       end_of_sequence = data + info.li_length + initial_length_size;
 
@@ -6449,7 +6467,7 @@ display_debug_lines (Elf_Internal_Shdr *section,
            {
            case DW_LNS_extended_op:
              data += process_extended_line_op (data, info.li_default_is_stmt,
-                                               debug_line_pointer_size);
+                                               pointer_size);
              break;
 
            case DW_LNS_copy:
@@ -7531,6 +7549,7 @@ display_debug_loc (Elf_Internal_Shdr *section,
   unsigned long bytes;
   unsigned char *section_begin = start;
   bfd_vma addr;
+  unsigned int comp_unit = 0;
 
   addr = section->sh_addr;
   bytes = section->sh_size;
@@ -7551,21 +7570,29 @@ display_debug_loc (Elf_Internal_Shdr *section,
       unsigned long end;
       unsigned short length;
       unsigned long offset;
+      unsigned int pointer_size;
 
       offset = start - section_begin;
 
+      /* Get the pointer size from the comp unit associated
+        with this block of location information.  */
+      if (comp_unit >= num_debug_line_pointer_sizes)
+       {
+         error (_("Not enough comp units for .debug_loc section\n"));
+         return 0;
+       }
+      else
+       {
+         pointer_size = debug_line_pointer_sizes [comp_unit];
+         comp_unit ++;
+       }
+
       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
-            separately 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;
+         begin = byte_get (start, pointer_size);
+         start += pointer_size;
+         end = byte_get (start, pointer_size);
+         start += pointer_size;
 
          if (begin == 0 && end == 0)
            break;
@@ -7581,7 +7608,7 @@ display_debug_loc (Elf_Internal_Shdr *section,
          start += 2;
 
          printf ("    %8.8lx %8.8lx %8.8lx (", offset, begin, end);
-         decode_location_expression (start, debug_line_pointer_size, length);
+         decode_location_expression (start, pointer_size, length);
          printf (")\n");
 
          start += length;
@@ -9167,56 +9194,97 @@ display_debug_not_supported (Elf_Internal_Shdr *section,
   return 1;
 }
 
-/* Pre-scan the .debug_info section to record the size of address.
-   When dumping the .debug_line, we use that size information, assuming
-   that all compilation units have the same address size.  */
-static int
-prescan_debug_info (Elf_Internal_Shdr *section ATTRIBUTE_UNUSED,
-                   unsigned char *start,
+/* 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 long length;
+  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);
 
-  /* 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.  For the purposes
-     of this prescan, we don't care about the actual length, but the
-     presence of the escape bytes does affect the location of the byte
-     which describes the address size.  */
-  length = byte_get (start, 4);
+      if (length == 0xffffffff)
+       {
+         length = byte_get (begin + 4, 8);
+         begin += length + 12;
+       }
+      else
+       begin += length + 4;
+    }
 
-  if (length == 0xffffffff)
+  if (num_units == 0)
     {
-      /* 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  */
+      error (_("No comp units in .debug_info section ?"));
+      return 0;
+    }
 
-      debug_line_pointer_size = byte_get (start + 22, 1);
+  /* 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;
     }
-  else
+
+  /* Populate the array.  */
+  for (begin = start, unit = 0; begin < end; unit++)
     {
-      /* 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  */
+      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_size = byte_get (start + 10, 1);
+         debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
+         begin += length + 4;
+       }
     }
-  return 0;
+
+  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.  The third field is a prescan
+   function to be run over the section before displaying any of the
+   sections.  */
 struct
 {
   const char *const name;