* elf64-hppa.c (elf64_hppa_new_dyn_hash_entry): Don't clear everything,
[deliverable/binutils-gdb.git] / binutils / readelf.c
index c12e970817dc75846413a207f326015ebfd7db42..a4650b47036ac58b0588eefb3cb2ba3308a976b9 100644 (file)
@@ -170,7 +170,7 @@ int do_notes;
 int is_32bit_elf;
 int have_frame_base;
 int need_base_address;
-unsigned long saved_base_address;
+bfd_vma eh_addr_size;
 
 struct group_list
 {
@@ -644,6 +644,20 @@ byte_put_big_endian (unsigned char *field, bfd_vma value, int size)
     }
 }
 
+/* Return a pointer to section NAME, or NULL if no such section exists.  */
+
+static Elf_Internal_Shdr *
+find_section (const char *name)
+{
+  unsigned int i;
+
+  for (i = 0; i < elf_header.e_shnum; i++)
+    if (streq (SECTION_NAME (section_headers + i), name))
+      return section_headers + i;
+
+  return NULL;
+}
+
 /* Guess the relocation size commonly used by the specific machines.  */
 
 static int
@@ -3285,15 +3299,9 @@ process_program_headers (FILE *file)
          if (section_headers != NULL)
            {
              Elf_Internal_Shdr *sec;
-             unsigned int j;
-
-             for (j = 0, sec = section_headers;
-                  j < elf_header.e_shnum;
-                  j++, sec++)
-               if (streq (SECTION_NAME (sec), ".dynamic"))
-                 break;
 
-             if (j == elf_header.e_shnum || sec->sh_size == 0)
+             sec = find_section (".dynamic");
+             if (sec == NULL || sec->sh_size == 0)
                {
                  error (_("no .dynamic section in the dynamic segment"));
                  break;
@@ -3717,6 +3725,26 @@ process_section_headers (FILE *file)
   dynamic_syminfo = NULL;
   symtab_shndx_hdr = NULL;
 
+  eh_addr_size = is_32bit_elf ? 4 : 8;
+  switch (elf_header.e_machine)
+    {
+    case EM_MIPS:
+    case EM_MIPS_RS3_LE:
+      /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
+        FDE addresses.  However, the ABI also has a semi-official ILP32
+        variant for which the normal FDE address size rules apply.
+
+        GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
+        section, where XX is the size of longs in bits.  Unfortunately,
+        earlier compilers provided no way of distinguishing ILP32 objects
+        from LP64 objects, so if there's any doubt, we should assume that
+        the official LP64 form is being used.  */
+      if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
+         && find_section (".gcc_compiled_long32") == NULL)
+       eh_addr_size = 8;
+      break;
+    }
+
   for (i = 0, section = section_headers;
        i < elf_header.e_shnum;
        i++, section++)
@@ -4302,12 +4330,9 @@ find_symbol_for_address (Elf_Internal_Sym *symtab,
 static void
 dump_ia64_unwind (struct ia64_unw_aux_info *aux)
 {
-  bfd_vma addr_size;
   struct ia64_unw_table_entry *tp;
   int in_body;
 
-  addr_size = is_32bit_elf ? 4 : 8;
-
   for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
     {
       bfd_vma stamp;
@@ -4344,7 +4369,7 @@ dump_ia64_unwind (struct ia64_unw_aux_info *aux)
              (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
              UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
              UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
-             (unsigned long) (addr_size * UNW_LENGTH (stamp)));
+             (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
 
       if (UNW_VER (stamp) != 1)
        {
@@ -4353,7 +4378,7 @@ dump_ia64_unwind (struct ia64_unw_aux_info *aux)
        }
 
       in_body = 0;
-      for (dp = head + 8; dp < head + 8 + addr_size * UNW_LENGTH (stamp);)
+      for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
        dp = unw_decode (dp, in_body, & in_body);
     }
 }
@@ -4363,7 +4388,7 @@ slurp_ia64_unwind_table (FILE *file,
                         struct ia64_unw_aux_info *aux,
                         Elf_Internal_Shdr *sec)
 {
-  unsigned long size, addr_size, nrelas, i;
+  unsigned long size, nrelas, i;
   Elf_Internal_Phdr *seg;
   struct ia64_unw_table_entry *tep;
   Elf_Internal_Shdr *relsec;
@@ -4372,8 +4397,6 @@ slurp_ia64_unwind_table (FILE *file,
   Elf_Internal_Sym *sym;
   const char *relname;
 
-  addr_size = is_32bit_elf ? 4 : 8;
-
   /* First, find the starting address of the segment that includes
      this section: */
 
@@ -4404,8 +4427,9 @@ slurp_ia64_unwind_table (FILE *file,
   if (!table)
     return 0;
 
-  tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
-  for (tp = table; tp < table + size; tp += 3 * addr_size, ++tep)
+  aux->table = xmalloc (size / (3 * eh_addr_size) * sizeof (aux->table[0]));
+  tep = aux->table;
+  for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
     {
       tep->start.section = SHN_UNDEF;
       tep->end.section   = SHN_UNDEF;
@@ -4461,9 +4485,9 @@ slurp_ia64_unwind_table (FILE *file,
              continue;
            }
 
-         i = rp->r_offset / (3 * addr_size);
+         i = rp->r_offset / (3 * eh_addr_size);
 
-         switch (rp->r_offset/addr_size % 3)
+         switch (rp->r_offset/eh_addr_size % 3)
            {
            case 0:
              aux->table[i].start.section = sym->st_shndx;
@@ -4485,7 +4509,7 @@ slurp_ia64_unwind_table (FILE *file,
       free (rela);
     }
 
-  aux->table_len = size / (3 * addr_size);
+  aux->table_len = size / (3 * eh_addr_size);
   return 1;
 }
 
@@ -4493,13 +4517,11 @@ static int
 ia64_process_unwind (FILE *file)
 {
   Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
-  unsigned long i, addr_size, unwcount = 0, unwstart = 0;
+  unsigned long i, unwcount = 0, unwstart = 0;
   struct ia64_unw_aux_info aux;
 
   memset (& aux, 0, sizeof (aux));
 
-  addr_size = is_32bit_elf ? 4 : 8;
-
   for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
     {
       if (sec->sh_type == SHT_SYMTAB)
@@ -4603,7 +4625,7 @@ ia64_process_unwind (FILE *file)
 
          printf (_(" at offset 0x%lx contains %lu entries:\n"),
                  (unsigned long) unwsec->sh_offset,
-                 (unsigned long) (unwsec->sh_size / (3 * addr_size)));
+                 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
 
          (void) slurp_ia64_unwind_table (file, & aux, unwsec);
 
@@ -4677,10 +4699,8 @@ struct hppa_unw_aux_info
 static void
 dump_hppa_unwind (struct hppa_unw_aux_info *aux)
 {
-  bfd_vma addr_size;
   struct hppa_unw_table_entry *tp;
 
-  addr_size = is_32bit_elf ? 4 : 8;
   for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
     {
       bfd_vma offset;
@@ -4747,7 +4767,7 @@ slurp_hppa_unwind_table (FILE *file,
                         struct hppa_unw_aux_info *aux,
                         Elf_Internal_Shdr *sec)
 {
-  unsigned long size, unw_ent_size, addr_size, nrelas, i;
+  unsigned long size, unw_ent_size, nrelas, i;
   Elf_Internal_Phdr *seg;
   struct hppa_unw_table_entry *tep;
   Elf_Internal_Shdr *relsec;
@@ -4756,8 +4776,6 @@ slurp_hppa_unwind_table (FILE *file,
   Elf_Internal_Sym *sym;
   const char *relname;
 
-  addr_size = is_32bit_elf ? 4 : 8;
-
   /* First, find the starting address of the segment that includes
      this section.  */
 
@@ -4789,11 +4807,11 @@ slurp_hppa_unwind_table (FILE *file,
   if (!table)
     return 0;
 
-  unw_ent_size = 2 * addr_size + 8;
+  unw_ent_size = 2 * eh_addr_size + 8;
 
   tep = aux->table = xmalloc (size / unw_ent_size * sizeof (aux->table[0]));
 
-  for (tp = table; tp < table + size; tp += (2 * addr_size + 8), ++tep)
+  for (tp = table; tp < table + size; tp += (2 * eh_addr_size + 8), ++tep)
     {
       unsigned int tmp1, tmp2;
 
@@ -4888,7 +4906,7 @@ slurp_hppa_unwind_table (FILE *file,
 
          i = rp->r_offset / unw_ent_size;
 
-         switch ((rp->r_offset % unw_ent_size) / addr_size)
+         switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
            {
            case 0:
              aux->table[i].start.section = sym->st_shndx;
@@ -4918,13 +4936,11 @@ hppa_process_unwind (FILE *file)
   Elf_Internal_Shdr *unwsec = NULL;
   Elf_Internal_Shdr *strsec;
   Elf_Internal_Shdr *sec;
-  unsigned long addr_size;
   unsigned long i;
 
   memset (& aux, 0, sizeof (aux));
 
   assert (string_table != NULL);
-  addr_size = is_32bit_elf ? 4 : 8;
 
   for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
     {
@@ -4954,7 +4970,7 @@ hppa_process_unwind (FILE *file)
 
          printf (_(" at offset 0x%lx contains %lu entries:\n"),
                  (unsigned long) sec->sh_offset,
-                 (unsigned long) (sec->sh_size / (2 * addr_size + 8)));
+                 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
 
           slurp_hppa_unwind_table (file, &aux, sec);
          if (aux.table_len > 0)
@@ -7051,26 +7067,6 @@ 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 (streq (SECTION_NAME (sec), name))
-      break;
-
-  if (i && sec && sec->sh_size != 0)
-    return sec;
-
-  return NULL;
-}
-
 static const char *debug_str_contents;
 static bfd_vma debug_str_size;
 
@@ -7895,120 +7891,6 @@ decode_location_expression (unsigned char * data,
   return need_frame_base;
 }
 
-/* Decode a DW_AT_ranges attribute for 64bit DWARF3 .  */
-
-static void
-decode_64bit_range (unsigned long offset, bfd_vma base_address)
-{
-  const char * start = debug_range_contents + offset;
-  const char * end   = debug_range_contents + debug_range_size;
-
-  do
-    {
-      bfd_vma a;
-      bfd_vma b;
-
-      a = byte_get ((unsigned char *) start, 8);
-      b = byte_get ((unsigned char *) start + 8, 8);
-
-      if (a == 0xffffffff)
-       {
-         base_address = b;
-       }
-      else if (a == 0 && b == 0)
-       break;
-      else if (a > b)
-       printf (_(" [corrupt: start > end]"));
-      else
-       {
-         printf (" ");
-         print_vma (base_address + a, PREFIX_HEX);
-         printf (" - ");
-         print_vma (base_address + b, PREFIX_HEX);
-         printf (", ");
-       }
-
-      start += 16;
-    }
-  while (start < end);
-}
-
-/* Decode a DW_AT_ranges attribute.  */
-
-static void
-decode_range (unsigned long offset, bfd_vma base_address)
-{
-  const char * start;
-  const char * end;
-
-  if (offset >= (debug_range_size - 8))
-    {
-      printf (_("[corrupt: offset is outside the .debug_ranges section]"));
-      return;
-    }
-
-  /* Since all entries in the .debug_ranges section are pairs of either
-     4-byte integers (32-bit DWARF3) or 8-byte integers (64-bit DWARF3)
-     the offset should always be a multiple of 8 bytes.  */
-  if (offset % 8)
-    {
-      printf (_("[corrupt: offset is not a multiple of 8]"));
-      return;
-    }  
-
-  start = debug_range_contents + offset;
-
-  if (offset > 0
-      /* Be paranoid - check to see if the previous
-        two words were and end-of-range marker.  */
-      && (byte_get ((unsigned char *) start - 4, 4) != 0
-         || byte_get ((unsigned char *) start - 8, 4) != 0))
-    {
-      printf (_("[corrupt: offset is not at the start of a range]"));
-      return;
-    }  
-
-  end = debug_range_contents + debug_range_size;
-
-  printf ("(");
-  do
-    {
-      unsigned long a;
-      unsigned long b;
-
-      a = byte_get ((unsigned char *) start, 4);
-      b = byte_get ((unsigned char *) start + 4, 4);
-
-      if (a == 0xffffffff)
-       {
-         if (b == 0xffffffff)
-           {
-             decode_64bit_range (offset, base_address);
-             return;
-           }
-
-         base_address = b;
-       }
-      else if (a == 0 && b == 0)
-       break;
-      else if (a > b)
-       printf (_("[corrupt: start > end]"));
-      else
-       {
-         if (start > debug_range_contents + offset)
-           printf (", ");
-
-         printf (_("0x%lx - 0x%lx"),
-                 (unsigned long) base_address + a,
-                 (unsigned long) base_address + b);
-       }
-
-      start += 8;
-    }
-  while (start < end);
-  printf (")");
-}
-
 /* This structure records the information that
    we extract from the.debug_info section.  */
 typedef struct
@@ -8021,6 +7903,9 @@ typedef struct
   int          *have_frame_base;
   unsigned int   num_loc_offsets;
   unsigned int   max_loc_offsets;
+  unsigned long *range_lists;
+  unsigned int   num_range_lists;
+  unsigned int   max_range_lists;
 }
 debug_info;
 
@@ -8154,7 +8039,7 @@ read_and_display_attr_value (unsigned long attribute,
          printf (" %lx", uvalue);
          printf (" %lx", (unsigned long) byte_get (data + 4, 4));
        }
-      if ((do_loc || do_debug_loc)
+      if ((do_loc || do_debug_loc || do_debug_ranges)
          && num_debug_info_entries == 0)
        {
          if (sizeof (uvalue) == 8)
@@ -8223,7 +8108,7 @@ read_and_display_attr_value (unsigned long attribute,
     }
 
   /* For some attributes we can display further information.  */
-  if ((do_loc || do_debug_loc)
+  if ((do_loc || do_debug_loc || do_debug_ranges)
       && num_debug_info_entries == 0)
     {
       switch (attribute)
@@ -8267,6 +8152,26 @@ read_and_display_attr_value (unsigned long attribute,
            debug_info_p->base_address = uvalue;
          break;
 
+       case DW_AT_ranges:
+         if (form == DW_FORM_data4 || form == DW_FORM_data8)
+           {
+             /* Process range list.  */
+             unsigned int max = debug_info_p->max_range_lists;
+             unsigned int num = debug_info_p->num_range_lists;
+
+             if (max == 0 || num >= max)
+               {
+                 max += 1024;
+                 debug_info_p->range_lists
+                   = xrealloc (debug_info_p->range_lists,
+                               max * sizeof (*debug_info_p->range_lists));
+                 debug_info_p->max_range_lists = max;
+               }
+             debug_info_p->range_lists [num] = uvalue;
+             debug_info_p->num_range_lists++;
+           }
+         break;
+
        default:
          break;
        }
@@ -8447,15 +8352,6 @@ read_and_display_attr_value (unsigned long attribute,
 
       break;
 
-    case DW_AT_low_pc:
-      if (need_base_address)
-       saved_base_address = uvalue;
-      break;
-
-    case DW_AT_ranges:
-      decode_range (uvalue, saved_base_address);
-      break;
-
     default:
       break;
     }
@@ -8612,7 +8508,7 @@ process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
   unsigned int unit;
   unsigned int num_units = 0;
 
-  if ((do_loc || do_debug_loc)
+  if ((do_loc || do_debug_loc || do_debug_ranges)
       && num_debug_info_entries == 0)
     {
       unsigned long length;
@@ -8708,7 +8604,7 @@ process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
 
       compunit.cu_pointer_size = byte_get (hdrptr, 1);
       hdrptr += 1;
-      if ((do_loc || do_debug_loc)
+      if ((do_loc || do_debug_loc || do_debug_ranges)
          && num_debug_info_entries == 0)
        {
          debug_information [unit].cu_offset = cu_offset;
@@ -8719,6 +8615,9 @@ process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
          debug_information [unit].have_frame_base = NULL;
          debug_information [unit].max_loc_offsets = 0;
          debug_information [unit].num_loc_offsets = 0;
+         debug_information [unit].range_lists = NULL;
+         debug_information [unit].max_range_lists= 0;
+         debug_information [unit].num_range_lists = 0;
        }
 
       tags = hdrptr;
@@ -8811,7 +8710,6 @@ process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
              break;
            case DW_TAG_compile_unit:
              need_base_address = 1;
-             saved_base_address = 0;
              break;
            case DW_TAG_entry_point:
            case DW_TAG_inlined_subroutine:
@@ -8837,9 +8735,9 @@ process_debug_info (Elf_Internal_Shdr *section, unsigned char *start,
        }
     }
  
-  /* Set num_debug_info_entries here so that it can be used
-     to check if we need to proecess .debug_loc section.  */
-  if ((do_loc || do_debug_loc)
+  /* Set num_debug_info_entries here so that it can be used to check if
+     we need to proecess .debug_loc and .debug_ranges sections.  */
+  if ((do_loc || do_debug_loc || do_debug_ranges)
       && num_debug_info_entries == 0)
     num_debug_info_entries = num_units;
       
@@ -9550,6 +9448,8 @@ display_debug_loc (Elf_Internal_Shdr *section,
              if (begin == -1UL && end != -1UL)
                {
                  base_address = end;
+                 printf ("    %8.8lx %8.8lx %8.8lx (base address)\n",
+                         offset, begin, end);
                  continue;
                }
 
@@ -9577,9 +9477,7 @@ display_debug_loc (Elf_Internal_Shdr *section,
              start += length;
            }
 
-         if (j < debug_information [i].num_loc_offsets -1)
-           printf (_("  <End of list>"));
-         printf ("\n");
+         fputs (_("  <End of list>\n"), stdout);
        }
     }
   return 1;
@@ -9752,91 +9650,147 @@ display_debug_aranges (Elf_Internal_Shdr *section,
 }
 
 static int
-display_64bit_debug_ranges (unsigned char * start, unsigned char * end)
+display_debug_ranges (Elf_Internal_Shdr *section,
+                     unsigned char *start,
+                     FILE *file ATTRIBUTE_UNUSED)
 {
-  bfd_vma base_address = 0;
+  unsigned char *section_end;
+  unsigned long bytes;
+  unsigned char *section_begin = start;
+  unsigned int num_range_list = 0;
+  unsigned long last_offset = 0;
+  unsigned int first = 0;
+  unsigned int i;
+  unsigned int j;
+  int seen_first_offset = 0;
+  int use_debug_info = 1;
+  unsigned char *next;
 
-  while (start < end)
+  bytes = section->sh_size;
+  section_end = start + bytes;
+
+  if (bytes == 0)
     {
-      bfd_vma a, b;
+      printf (_("\nThe .debug_ranges section is empty.\n"));
+      return 0;
+    }
 
-      a = byte_get (start, 8);
-      b = byte_get (start + 8, 8);
+  get_debug_info (file);
 
-      if (a == 0xffffffffffffffffLL)
-       {
-         printf (_(" set base address to "));
-         print_vma (b, PREFIX_HEX);
-         base_address = b;
-       }
-      else if (a == 0 && b == 0)
-       printf ( _("end of range"));
-      else if (a > b)
-       printf (_(" <corrupt range entry, start is greater than end>"));
-      else if (base_address == 0)
-       {
-         printf ("range from base address + ");
-         print_vma (a, PREFIX_HEX);
-         printf (" to base address + ");
-         print_vma (b, PREFIX_HEX);
-       }
-      else
+  /* Check the order of range list in .debug_info section. If
+     offsets of range lists are in the ascending order, we can
+     use `debug_information' directly.  */
+  for (i = 0; i < num_debug_info_entries; i++)
+    {
+      unsigned int num;
+
+      num = debug_information [i].num_range_lists;
+      num_range_list += num;
+
+      /* Check if we can use `debug_information' directly.  */
+      if (use_debug_info && num != 0)
        {
-         printf ("range from ");
-         print_vma (base_address + a, PREFIX_HEX);
-         printf (" to ");
-         print_vma (base_address + b, PREFIX_HEX);
-       }
+         if (!seen_first_offset)
+           {
+             /* This is the first range list.  */
+             last_offset = debug_information [i].range_lists [0];
+             first = i;
+             seen_first_offset = 1;
+             j = 1;
+           }
+         else
+           j = 0;
 
-      start += 16;
-      printf ("\n");
+         for (; j < num; j++)
+           {
+             if (last_offset >
+                 debug_information [i].range_lists [j])
+               {
+                 use_debug_info = 0;
+                 break;
+               }
+             last_offset = debug_information [i].range_lists [j];
+           }
+       }
     }
 
-  return 1;
-}
+  if (!use_debug_info)
+    /* FIXME: Should we handle this case?  */
+    error (_("Range lists in .debug_info section aren't in ascending order!\n"));
 
-static int
-display_debug_ranges (Elf_Internal_Shdr *section,
-                     unsigned char *start,
-                     FILE *file ATTRIBUTE_UNUSED)
-{
-  unsigned long base_address = 0;
-  unsigned char *end = start + section->sh_size;
+  if (!seen_first_offset)
+    error (_("No range lists in .debug_info section!\n"));
 
-  printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
+  if (debug_information [first].range_lists [0] != 0)
+    warn (_("Range lists in .debug_ranges section start at 0x%lx\n"),
+         debug_information [first].range_lists [0]);
 
-  while (start < end)
+  printf (_("Contents of the .debug_ranges section:\n\n"));
+  printf (_("    Offset   Begin    End\n"));
+
+  seen_first_offset = 0;
+  for (i = first; i < num_debug_info_entries; i++)
     {
-      unsigned long a;
-      unsigned long b;
+      unsigned long begin;
+      unsigned long end;
+      unsigned long offset;
+      unsigned int pointer_size;
+      unsigned long base_address;
 
-      a = byte_get (start, 4);
-      b = byte_get (start + 4, 4);
+      pointer_size = debug_information [i].pointer_size;
 
-      if (a == 0xffffffff)
+      for (j = 0; j < debug_information [i].num_range_lists; j++)
        {
-         /* Attempt to handle 64-bit DWARF3 format.  This assumes
-            that in a 32-bit DWARF3 file the base address will
-            never be 0xffffffff, and that the .debug_ranges section
-            will never contain a mixture of 32-bit and 64-bit entries.  */
-         if (b == 0xffffffff)
-           return display_64bit_debug_ranges (start, end);
-      
-         printf (_(" set base address to 0x%lx\n"), b);
-         base_address = b;
-       }
-      else if (a == 0 && b == 0)
-       printf (_(" end of range\n"));
-      else if (a > b)
-       printf (_(" <corrupt range entry, start is greater than end>\n"));
-      else if (base_address == 0)
-       printf (_(" range from base address + 0x%lx to base address + 0x%lx\n"), a, b);
-      else
-       printf (_(" range from 0x%lx to 0x%lx\n"), base_address + a, base_address + b);
+         offset = debug_information [i].range_lists [j];
+         next = section_begin + offset;
+         base_address = debug_information [i].base_address;
 
-      start += 8;
-    }
+         if (!seen_first_offset)
+           seen_first_offset = 1;
+         else
+           {
+             if (start < next)
+               warn (_("There is a hole [0x%lx - 0x%lx] in .debug_ranges section.\n"),
+                     start - section_begin, next - section_begin);
+             else if (start > next)
+               warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_ranges section.\n"),
+                     start - section_begin, next - section_begin);
+           }
+         start = next;
+
+         while (1)
+           {
+             begin = byte_get (start, pointer_size);
+             start += pointer_size;
+             end = byte_get (start, pointer_size);
+             start += pointer_size;
 
+             if (begin == 0 && end == 0)
+               break;
+
+             /* Check base address specifiers.  */
+             if (begin == -1UL && end != -1UL)
+               {
+                 base_address = end;
+                 printf ("    %8.8lx %8.8lx %8.8lx (base address)\n",
+                         offset, begin, end);
+                 continue;
+               }
+
+             printf ("    %8.8lx %8.8lx %8.8lx",
+                     offset, begin + base_address, end + base_address);
+
+             if (begin == end)
+               fputs (_(" (start == end)"), stdout);
+             else if (begin > end)
+               fputs (_(" (start > end)"), stdout);
+
+             putchar ('\n');
+           }
+         fputs (_("  <End of list>\n"), stdout);
+       }
+    }
+  putchar ('\n');
   return 1;
 }
 
@@ -9956,7 +9910,7 @@ size_of_encoded_value (int encoding)
   switch (encoding & 0x7)
     {
     default:   /* ??? */
-    case 0:    return is_32bit_elf ? 4 : 8;
+    case 0:    return eh_addr_size;
     case 2:    return 2;
     case 3:    return 4;
     case 4:    return 8;
@@ -9990,7 +9944,6 @@ display_debug_frames (Elf_Internal_Shdr *section,
   int is_eh = streq (SECTION_NAME (section), ".eh_frame");
   int length_return;
   int max_regs = 0;
-  int addr_size = is_32bit_elf ? 4 : 8;
 
   printf (_("The section %s contains:\n"), SECTION_NAME (section));
 
@@ -10005,7 +9958,7 @@ display_debug_frames (Elf_Internal_Shdr *section,
       int need_col_headers = 1;
       unsigned char *augmentation_data = NULL;
       unsigned long augmentation_data_len = 0;
-      int encoded_ptr_size = addr_size;
+      int encoded_ptr_size = eh_addr_size;
       int offset_size;
       int initial_length_size;
 
@@ -10078,7 +10031,7 @@ display_debug_frames (Elf_Internal_Shdr *section,
            }
          else if (streq (fc->augmentation, "eh"))
            {
-             start += addr_size;
+             start += eh_addr_size;
              fc->code_factor = LEB ();
              fc->data_factor = SLEB ();
              if (version == 1)
@@ -10558,7 +10511,7 @@ display_debug_frames (Elf_Internal_Shdr *section,
              if (! do_debug_frames_interp)
                {
                  printf ("  DW_CFA_def_cfa_expression (");
-                 decode_location_expression (start, addr_size, ul, 0);
+                 decode_location_expression (start, eh_addr_size, ul, 0);
                  printf (")\n");
                }
              fc->cfa_exp = 1;
@@ -10571,7 +10524,7 @@ display_debug_frames (Elf_Internal_Shdr *section,
              if (! do_debug_frames_interp)
                {
                  printf ("  DW_CFA_expression: r%ld (", reg);
-                 decode_location_expression (start, addr_size, ul, 0);
+                 decode_location_expression (start, eh_addr_size, ul, 0);
                  printf (")\n");
                }
              fc->col_type[reg] = DW_CFA_expression;
@@ -11804,11 +11757,15 @@ process_object (char *file_name, FILE *file)
   if (debug_information)
     {
       for (i = 0; i < num_debug_info_entries; i++)
-       if (!debug_information [i].max_loc_offsets)
-         {
-           free (debug_information [i].loc_offsets);
-           free (debug_information [i].have_frame_base);
-         }
+       {
+         if (!debug_information [i].max_loc_offsets)
+           {
+             free (debug_information [i].loc_offsets);
+             free (debug_information [i].have_frame_base);
+           }
+         if (!debug_information [i].max_range_lists)
+           free (debug_information [i].range_lists);
+       }
       free (debug_information);
       debug_information = NULL;
       num_debug_info_entries = 0;
This page took 0.033215 seconds and 4 git commands to generate.