Fix up changelog entry of previous delta
[binutils-gdb.git] / binutils / dwarf.c
index 5cfa528594ffc1a4f386df6831ec202c3fea0458..c454d058b22a190930caeab892c5b0d0e32e9b43 100644 (file)
@@ -702,7 +702,7 @@ fetch_indirect_string (dwarf_vma offset)
     ret = (const unsigned char *)
       _("<no NUL byte at end of .debug_str section>");
 
-  return ret; 
+  return ret;
 }
 
 static const unsigned char *
@@ -795,7 +795,7 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set,
     }
 
   index_offset = idx * offset_size;
-      
+
   if (this_set != NULL)
     index_offset += this_set->section_offsets [DW_SECT_STR_OFFSETS];
 
@@ -876,6 +876,7 @@ typedef struct abbrev_list
 {
   abbrev_entry *        first_abbrev;
   abbrev_entry *        last_abbrev;
+  dwarf_vma             abbrev_base;
   dwarf_vma             abbrev_offset;
   struct abbrev_list *  next;
   unsigned char *       start_of_next_abbrevs;
@@ -955,10 +956,11 @@ free_all_abbrevs (void)
 }
 
 static abbrev_list *
-new_abbrev_list (dwarf_vma abbrev_offset)
+new_abbrev_list (dwarf_vma abbrev_base, dwarf_vma abbrev_offset)
 {
   abbrev_list * list = (abbrev_list *) xcalloc (sizeof * list, 1);
 
+  list->abbrev_base = abbrev_base;
   list->abbrev_offset = abbrev_offset;
 
   list->next = abbrev_lists;
@@ -968,12 +970,14 @@ new_abbrev_list (dwarf_vma abbrev_offset)
 }
 
 static abbrev_list *
-find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_offset)
+find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_base,
+                                  dwarf_vma abbrev_offset)
 {
   abbrev_list * list;
 
   for (list = abbrev_lists; list != NULL; list = list->next)
-    if (list->abbrev_offset == abbrev_offset)
+    if (list->abbrev_base == abbrev_base
+       && list->abbrev_offset == abbrev_offset)
       return list;
 
   return NULL;
@@ -1855,7 +1859,7 @@ fetch_alt_indirect_string (dwarf_vma offset)
 
       return ret;
     }
-  
+
   warn (_("DW_FORM_GNU_strp_alt offset (%s) too big or no string sections available\n"),
        dwarf_vmatoa ("x", offset));
   return _("<offset is too big>");
@@ -2021,6 +2025,21 @@ skip_attr_bytes (unsigned long          form,
       break;
 
     case DW_FORM_ref8:
+      {
+       dwarf_vma high_bits;
+
+       SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
+       data += 8;
+       if (sizeof (uvalue) > 4)
+         uvalue += high_bits << 32;
+       else if (high_bits != 0)
+         {
+           /* FIXME: What to do ?  */
+           return NULL;
+         }
+       break;
+      }
+
     case DW_FORM_data8:
     case DW_FORM_ref_sig8:
       data += 8;
@@ -2111,6 +2130,7 @@ get_type_abbrev_from_form (unsigned long                 form,
     case DW_FORM_ref1:
     case DW_FORM_ref2:
     case DW_FORM_ref4:
+    case DW_FORM_ref8:
     case DW_FORM_ref_udata:
       if (uvalue + cu_offset > section->size)
        {
@@ -2130,7 +2150,7 @@ get_type_abbrev_from_form (unsigned long                 form,
 
   data = (unsigned char *) section->start + uvalue;
   map = find_abbrev_map_by_offset (uvalue);
-  
+
   if (map == NULL)
     {
       warn (_("Unable to find abbreviations for CU offset %#lx\n"), uvalue);
@@ -2155,7 +2175,7 @@ get_type_abbrev_from_form (unsigned long                 form,
   for (entry = map->list->first_abbrev; entry != NULL; entry = entry->next)
     if (entry->number == abbrev_number)
       break;
-  
+
   if (abbrev_num_return != NULL)
     * abbrev_num_return = abbrev_number;
 
@@ -2299,7 +2319,7 @@ display_discr_list (unsigned long          form,
       printf ("[default]");
       return;
     }
-  
+
   switch (form)
     {
     case DW_FORM_block:
@@ -2325,7 +2345,7 @@ display_discr_list (unsigned long          form,
   bfd_boolean is_signed =
     (level > 0 && level <= MAX_CU_NESTING)
     ? level_type_signed [level - 1] : FALSE;
-    
+
   printf ("(");
   while (uvalue)
     {
@@ -2407,6 +2427,17 @@ read_and_display_attr_value (unsigned long           attribute,
       return data;
     }
 
+  if (do_wide && ! do_loc)
+    {
+      /* PR 26847: Display the name of the form.  */
+      const char * name = get_FORM_name (form);
+
+      /* For convenience we skip the DW_FORM_ prefix to the name.  */
+      if (name[0] == 'D')
+       name += 8; /* strlen ("DW_FORM_")  */
+      printf ("%c(%s)", delimiter, name);
+    }
+
   switch (form)
     {
     default:
@@ -2488,7 +2519,13 @@ read_and_display_attr_value (unsigned long           attribute,
 
     case DW_FORM_GNU_ref_alt:
       if (!do_loc)
-       printf ("%c<alt 0x%s>", delimiter, dwarf_vmatoa ("x", uvalue));
+       {
+         if (do_wide)
+           /* We have already printed the form name.  */
+           printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue));
+         else
+           printf ("%c<alt 0x%s>", delimiter, dwarf_vmatoa ("x", uvalue));
+       }
       /* FIXME: Follow the reference...  */
       break;
 
@@ -2616,16 +2653,32 @@ read_and_display_attr_value (unsigned long           attribute,
 
     case DW_FORM_strp:
       if (!do_loc)
-       printf (_("%c(indirect string, offset: 0x%s): %s"), delimiter,
-               dwarf_vmatoa ("x", uvalue),
-               fetch_indirect_string (uvalue));
+       {
+         if (do_wide)
+           /* We have already displayed the form name.  */
+           printf (_("%c(offset: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_indirect_string (uvalue));
+         else
+           printf (_("%c(indirect string, offset: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_indirect_string (uvalue));
+       }
       break;
 
     case DW_FORM_line_strp:
       if (!do_loc)
-       printf (_("%c(indirect line string, offset: 0x%s): %s"), delimiter,
-               dwarf_vmatoa ("x", uvalue),
-               fetch_indirect_line_string (uvalue));
+       {
+         if (do_wide)
+           /* We have already displayed the form name.  */
+           printf (_("%c(offset: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_indirect_line_string (uvalue));
+         else
+           printf (_("%c(indirect line string, offset: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_indirect_line_string (uvalue));
+       }
       break;
 
     case DW_FORM_GNU_str_index:
@@ -2634,18 +2687,30 @@ read_and_display_attr_value (unsigned long           attribute,
          const char * suffix = strrchr (section->name, '.');
          bfd_boolean  dwo = (suffix && strcmp (suffix, ".dwo") == 0) ? TRUE : FALSE;
 
-         printf (_("%c(indexed string: 0x%s): %s"), delimiter,
-                 dwarf_vmatoa ("x", uvalue),
-                 fetch_indexed_string (uvalue, this_set, offset_size, dwo));
+         if (do_wide)
+           /* We have already displayed the form name.  */
+           printf (_("%c(offset: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_indexed_string (uvalue, this_set, offset_size, dwo));
+         else
+           printf (_("%c(indexed string: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_indexed_string (uvalue, this_set, offset_size, dwo));
        }
       break;
 
     case DW_FORM_GNU_strp_alt:
       if (!do_loc)
        {
-         printf (_("%c(alt indirect string, offset: 0x%s) %s"), delimiter,
-                 dwarf_vmatoa ("x", uvalue),
-                 fetch_alt_indirect_string (uvalue));
+         if (do_wide)
+           /* We have already displayed the form name.  */
+           printf (_("%c(offset: 0x%s) %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_alt_indirect_string (uvalue));
+         else
+           printf (_("%c(alt indirect string, offset: 0x%s) %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_alt_indirect_string (uvalue));
        }
       break;
 
@@ -2660,17 +2725,30 @@ read_and_display_attr_value (unsigned long           attribute,
          char buf[64];
 
          SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end);
-         printf ("%csignature: 0x%s", delimiter,
-                 dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
+         if (do_wide)
+           /* We have already displayed the form name.  */
+           printf ("%c: 0x%s", delimiter,
+                   dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
+         else
+           printf ("%csignature: 0x%s", delimiter,
+                   dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
        }
       data += 8;
       break;
 
     case DW_FORM_GNU_addr_index:
       if (!do_loc)
-       printf (_("%c(addr_index: 0x%s): %s"), delimiter,
-               dwarf_vmatoa ("x", uvalue),
-               fetch_indexed_value (uvalue * pointer_size, pointer_size));
+       {
+         if (do_wide)
+           /* We have already displayed the form name.  */
+           printf (_("%c(index: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_indexed_value (uvalue * pointer_size, pointer_size));
+         else
+           printf (_("%c(addr_index: 0x%s): %s"), delimiter,
+                   dwarf_vmatoa ("x", uvalue),
+                   fetch_indexed_value (uvalue * pointer_size, pointer_size));
+       }
       break;
 
     default:
@@ -2815,7 +2893,7 @@ read_and_display_attr_value (unsigned long           attribute,
                break;
              }
          break;
-             
+
        case DW_AT_comp_dir:
          /* FIXME: Also extract a build-id in a CU/TU.  */
          if (need_dwo_info)
@@ -2842,7 +2920,7 @@ read_and_display_attr_value (unsigned long           attribute,
                break;
              }
          break;
-             
+
        case DW_AT_GNU_dwo_id:
          if (need_dwo_info)
            switch (form)
@@ -2857,7 +2935,7 @@ read_and_display_attr_value (unsigned long           attribute,
                break;
              }
          break;
-             
+
        default:
          break;
        }
@@ -2877,7 +2955,7 @@ read_and_display_attr_value (unsigned long           attribute,
          abbrev_entry *  type_abbrev;
          unsigned char * type_data;
          unsigned long   type_cu_offset;
-         
+
          type_abbrev = get_type_abbrev_from_form (form, uvalue, cu_offset,
                                                   section, NULL, & type_data, & type_cu_offset);
          if (type_abbrev != NULL)
@@ -2889,7 +2967,7 @@ read_and_display_attr_value (unsigned long           attribute,
          level_type_signed[level] = is_signed;
        }
       break;
-      
+
     case DW_AT_inline:
       printf ("\t");
       switch (uvalue)
@@ -3141,7 +3219,7 @@ read_and_display_attr_value (unsigned long           attribute,
       printf ("\t");
       display_discr_list (form, uvalue, data, end, level);
       break;
-      
+
     case DW_AT_frame_base:
       have_frame_base = 1;
       /* Fall through.  */
@@ -3330,7 +3408,7 @@ introduce (struct dwarf_section * section, bfd_boolean raw)
        printf (_("Contents of the %s section:\n\n"), section->name);
     }
 }
-  
+
 /* Process the contents of a .debug_info section.
    If do_loc is TRUE then we are scanning for location lists and dwo tags
    and we do not want to display anything to the user.
@@ -3430,7 +3508,7 @@ process_debug_info (struct dwarf_section *           section,
       load_debug_section_with_follow (str_index_dwo, file);
       load_debug_section_with_follow (debug_addr, file);
     }
-  
+
   load_debug_section_with_follow (abbrev_sec, file);
   if (debug_displays [abbrev_sec].section.start == NULL)
     {
@@ -3446,7 +3524,7 @@ process_debug_info (struct dwarf_section *           section,
   free (cu_abbrev_map);
   cu_abbrev_map = NULL;
   next_free_abbrev_map_entry = 0;
-  
+
   /* In order to be able to resolve DW_FORM_ref_attr forms we need
      to load *all* of the abbrevs for all CUs in this .debug_info
      section.  This does effectively mean that we (partially) read
@@ -3455,6 +3533,8 @@ process_debug_info (struct dwarf_section *           section,
     {
       DWARF2_Internal_CompUnit  compunit;
       unsigned char *           hdrptr;
+      dwarf_vma                 abbrev_base;
+      size_t                    abbrev_size;
       dwarf_vma                 cu_offset;
       unsigned int              offset_size;
       unsigned int              initial_length_size;
@@ -3499,25 +3579,25 @@ process_debug_info (struct dwarf_section *           section,
 
       SAFE_BYTE_GET_AND_INC (compunit.cu_abbrev_offset, hdrptr, offset_size, end);
 
-      list = find_abbrev_list_by_abbrev_offset (compunit.cu_abbrev_offset);
+      if (this_set == NULL)
+       {
+         abbrev_base = 0;
+         abbrev_size = debug_displays [abbrev_sec].section.size;
+       }
+      else
+       {
+         abbrev_base = this_set->section_offsets [DW_SECT_ABBREV];
+         abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
+       }
+
+      list = find_abbrev_list_by_abbrev_offset (abbrev_base,
+                                               compunit.cu_abbrev_offset);
       if (list == NULL)
        {
-         dwarf_vma        abbrev_base;
-         size_t           abbrev_size;
          unsigned char *  next;
 
-         if (this_set == NULL)
-           {
-             abbrev_base = 0;
-             abbrev_size = debug_displays [abbrev_sec].section.size;
-           }
-         else
-           {
-             abbrev_base = this_set->section_offsets [DW_SECT_ABBREV];
-             abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
-           }
-
-         list = new_abbrev_list (compunit.cu_abbrev_offset);
+         list = new_abbrev_list (abbrev_base,
+                                 compunit.cu_abbrev_offset);
          next = process_abbrev_set
            (((unsigned char *) debug_displays [abbrev_sec].section.start
              + abbrev_base + compunit.cu_abbrev_offset),
@@ -3526,7 +3606,7 @@ process_debug_info (struct dwarf_section *           section,
             list);
          list->start_of_next_abbrevs = next;
        }
-                      
+
       start = section_begin + cu_offset + compunit.cu_length
        + initial_length_size;
       record_abbrev_list_for_cu (cu_offset, start - section_begin, list);
@@ -3739,12 +3819,14 @@ process_debug_info (struct dwarf_section *           section,
              (unsigned long) debug_displays [abbrev_sec].section.size);
       else
        {
-         list = find_abbrev_list_by_abbrev_offset (compunit.cu_abbrev_offset);
+         list = find_abbrev_list_by_abbrev_offset (abbrev_base,
+                                                   compunit.cu_abbrev_offset);
          if (list == NULL)
            {
              unsigned char * next;
 
-             list = new_abbrev_list (compunit.cu_abbrev_offset);
+             list = new_abbrev_list (abbrev_base,
+                                     compunit.cu_abbrev_offset);
              next = process_abbrev_set
                (((unsigned char *) debug_displays [abbrev_sec].section.start
                  + abbrev_base + compunit.cu_abbrev_offset),
@@ -4115,7 +4197,7 @@ display_formatted_table (unsigned char *                   data,
   dwarf_vma data_count, datai;
   unsigned int namepass, last_entry = 0;
   const char * table_name = is_dir ? N_("Directory Table") : N_("File Name Table");
-  
+
   SAFE_BYTE_GET_AND_INC (format_count, data, 1, end);
   if (do_checks && format_count > 5)
     warn (_("Unexpectedly large number of columns in the %s (%u)\n"),
@@ -4158,7 +4240,7 @@ display_formatted_table (unsigned char *                   data,
          format_count);
 
   printf (_("  Entry"));
-  /* Delay displaying name as the last entry for better screen layout.  */ 
+  /* Delay displaying name as the last entry for better screen layout.  */
   for (namepass = 0; namepass < 2; namepass++)
     {
       format = format_start;
@@ -4199,7 +4281,7 @@ display_formatted_table (unsigned char *                   data,
       unsigned char *datapass = data;
 
       printf ("  %d", last_entry++);
-      /* Delay displaying name as the last entry for better screen layout.  */ 
+      /* Delay displaying name as the last entry for better screen layout.  */
       for (namepass = 0; namepass < 2; namepass++)
        {
          format = format_start;
@@ -6071,10 +6153,10 @@ display_debug_abbrev (struct dwarf_section *section,
       dwarf_vma        offset;
 
       offset = start - section->start;
-      list = find_abbrev_list_by_abbrev_offset (offset);
+      list = find_abbrev_list_by_abbrev_offset (0, offset);
       if (list == NULL)
        {
-         list = new_abbrev_list (offset);
+         list = new_abbrev_list (0, offset);
          start = process_abbrev_set (start, end, list);
          list->start_of_next_abbrevs = start;
        }
@@ -7361,7 +7443,6 @@ display_debug_ranges_list (unsigned char *start, unsigned char *finish,
        break;
       SAFE_SIGNED_BYTE_GET_AND_INC (end, start, pointer_size, finish);
 
-      
       printf ("    %8.8lx ", offset);
 
       if (begin == 0 && end == 0)
@@ -7451,8 +7532,15 @@ display_debug_rnglists_list (unsigned char *start, unsigned char *finish,
       if (rlet == DW_RLE_base_address)
        continue;
 
-      print_dwarf_vma (begin + base_address, pointer_size);
-      print_dwarf_vma (end + base_address, pointer_size);
+      /* Only a DW_RLE_offset_pair needs the base address added.  */
+      if (rlet == DW_RLE_offset_pair)
+       {
+         begin += base_address;
+         end += base_address;
+       }
+
+      print_dwarf_vma (begin, pointer_size);
+      print_dwarf_vma (end, pointer_size);
 
       if (begin == end)
        fputs (_("(start == end)"), stdout);
@@ -9697,7 +9785,7 @@ display_debug_links (struct dwarf_section *  section,
     The .gun_debugaltlink section is formatted as:
       (c-string)  Filename.
       (binary)    Build-ID.  */
-  
+
   filename =  section->start;
   filelen = strnlen ((const char *) filename, section->size);
   if (filelen == section->size)
@@ -10391,7 +10479,7 @@ load_cu_tu_indexes (void *file)
   if (cu_tu_indexes_read == -1)
     {
       cu_tu_indexes_read = TRUE;
-  
+
       if (load_debug_section_with_follow (dwp_cu_index, file))
        if (! process_cu_tu_index (&debug_displays [dwp_cu_index].section, 0))
          cu_tu_indexes_read = FALSE;
@@ -10635,7 +10723,6 @@ parse_gnu_debuglink (struct dwarf_section * section, void * data)
      The CRC value is stored after the filename, aligned up to 4 bytes.  */
   name = (const char *) section->start;
 
-  
   crc_offset = strnlen (name, section->size) + 1;
   crc_offset = (crc_offset + 3) & ~3;
   if (crc_offset + 4 > section->size)
@@ -10793,12 +10880,12 @@ load_separate_debug_info (const char *            main_filename,
            xlink->name ? xlink->name : xlink->uncompressed_name);
       return NULL;
     }
-    
+
   /* Attempt to locate the separate file.
      This should duplicate the logic in bfd/opncls.c:find_separate_debug_file().  */
 
   canon_dir = lrealpath (main_filename);
-  
+
   for (canon_dirlen = strlen (canon_dir); canon_dirlen > 0; canon_dirlen--)
     if (IS_DIR_SEPARATOR (canon_dir[canon_dirlen - 1]))
       break;
@@ -11126,7 +11213,7 @@ load_separate_debug_files (void * file, const char * filename)
 
   do_follow_links = 0;
   return FALSE;
-}  
+}
 
 void
 free_debug_memory (void)
@@ -11138,7 +11225,7 @@ free_debug_memory (void)
   free (cu_abbrev_map);
   cu_abbrev_map = NULL;
   next_free_abbrev_map_entry = 0;
-  
+
   for (i = 0; i < max; i++)
     free_debug_section ((enum dwarf_section_display_enum) i);
 
@@ -11170,7 +11257,7 @@ free_debug_memory (void)
       free ((void *) d);
     }
   first_separate_info = NULL;
-  
+
   free_dwo_info ();
 }