AArch64: Add gdbserver MTE support
[deliverable/binutils-gdb.git] / bfd / dwarf2.c
index 3ee753d0aa4cda8a0c1d6748c5d4ae298a245bed..dbaec4016c194f4f1a21b6365787bc658b1a846b 100644 (file)
@@ -1,5 +1,5 @@
 /* DWARF 2 support.
-   Copyright (C) 1994-2020 Free Software Foundation, Inc.
+   Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
    Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions
    (gavin@cygnus.com).
@@ -130,6 +130,12 @@ struct dwarf2_debug_file
   /* Length of the loaded .debug_ranges section.  */
   bfd_size_type dwarf_ranges_size;
 
+  /* Pointer to the .debug_rnglists section loaded into memory.  */
+  bfd_byte *dwarf_rnglists_buffer;
+
+  /* Length of the loaded .debug_rnglists section.  */
+  bfd_size_type dwarf_rnglists_size;
+
   /* A list of all previously read comp_units.  */
   struct comp_unit *all_comp_units;
 
@@ -327,6 +333,7 @@ const struct dwarf_debug_section dwarf_debug_sections[] =
   { ".debug_pubnames",         ".zdebug_pubnames" },
   { ".debug_pubtypes",         ".zdebug_pubtypes" },
   { ".debug_ranges",           ".zdebug_ranges" },
+  { ".debug_rnglists",         ".zdebug_rnglist" },
   { ".debug_static_func",      ".zdebug_static_func" },
   { ".debug_static_vars",      ".zdebug_static_vars" },
   { ".debug_str",              ".zdebug_str", },
@@ -360,6 +367,7 @@ enum dwarf_debug_section_enum
   debug_pubnames,
   debug_pubtypes,
   debug_ranges,
+  debug_rnglists,
   debug_static_func,
   debug_static_vars,
   debug_str,
@@ -523,22 +531,24 @@ read_section (bfd *             abfd,
              bfd_byte **     section_buffer,
              bfd_size_type * section_size)
 {
-  asection *msec;
   const char *section_name = sec->uncompressed_name;
   bfd_byte *contents = *section_buffer;
-  bfd_size_type amt;
 
   /* The section may have already been read.  */
   if (contents == NULL)
     {
+      bfd_size_type amt;
+      asection *msec;
+      ufile_ptr filesize;
+
       msec = bfd_get_section_by_name (abfd, section_name);
-      if (! msec)
+      if (msec == NULL)
        {
          section_name = sec->compressed_name;
          if (section_name != NULL)
            msec = bfd_get_section_by_name (abfd, section_name);
        }
-      if (! msec)
+      if (msec == NULL)
        {
          _bfd_error_handler (_("DWARF error: can't find %s section."),
                              sec->uncompressed_name);
@@ -546,12 +556,23 @@ read_section (bfd *             abfd,
          return FALSE;
        }
 
-      *section_size = msec->rawsize ? msec->rawsize : msec->size;
+      amt = bfd_get_section_limit_octets (abfd, msec);
+      filesize = bfd_get_file_size (abfd);
+      if (amt >= filesize)
+       {
+         /* PR 26946 */
+         _bfd_error_handler (_("DWARF error: section %s is larger than its filesize! (0x%lx vs 0x%lx)"),
+                             section_name, (long) amt, (long) filesize);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+      *section_size = amt;
       /* Paranoia - alloc one extra so that we can make sure a string
         section is NUL terminated.  */
-      amt = *section_size + 1;
+      amt += 1;
       if (amt == 0)
        {
+         /* Paranoia - this should never happen.  */
          bfd_set_error (bfd_error_no_memory);
          return FALSE;
        }
@@ -1139,8 +1160,23 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash,
 static inline bfd_boolean
 is_str_attr (enum dwarf_form form)
 {
-  return (form == DW_FORM_string || form == DW_FORM_strp
-         || form == DW_FORM_line_strp || form == DW_FORM_GNU_strp_alt);
+  return (form == DW_FORM_string
+         || form == DW_FORM_strp
+         || form == DW_FORM_strx
+         || form == DW_FORM_strx1
+         || form == DW_FORM_strx2
+         || form == DW_FORM_strx3
+         || form == DW_FORM_strx4
+         || form == DW_FORM_line_strp
+         || form == DW_FORM_GNU_strp_alt);
+}
+
+static const char *
+read_indexed_string (bfd_uint64_t idx ATTRIBUTE_UNUSED,
+                    struct comp_unit * unit ATTRIBUTE_UNUSED)
+{
+  /* FIXME: Add support for indexed strings.  */
+  return "<indexed strings not yet supported>";
 }
 
 /* Read and fill in the value of attribute ATTR as described by FORM.
@@ -1171,10 +1207,13 @@ read_attribute_value (struct attribute *  attr,
 
   switch (form)
     {
+    case DW_FORM_flag_present:
+      attr->u.val = 1;
+      break;
     case DW_FORM_ref_addr:
       /* DW_FORM_ref_addr is an address in DWARF2, and an offset in
         DWARF3.  */
-      if (unit->version == 3 || unit->version == 4)
+      if (unit->version >= 3)
        {
          if (unit->offset_size == 4)
            attr->u.val = read_4_bytes (unit->abfd, info_ptr, info_ptr_end);
@@ -1216,15 +1255,32 @@ read_attribute_value (struct attribute *  attr,
       info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
+    case DW_FORM_ref1:
+    case DW_FORM_flag:
+    case DW_FORM_data1:
+    case DW_FORM_addrx1:
+      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
+      info_ptr += 1;
+      break;
     case DW_FORM_data2:
+    case DW_FORM_ref2:
       attr->u.val = read_2_bytes (abfd, info_ptr, info_ptr_end);
       info_ptr += 2;
       break;
+    case DW_FORM_addrx3:
+      attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
+      attr->u.val &= 0xffffff;
+      info_ptr += 3;
+      break;
+    case DW_FORM_ref4:
     case DW_FORM_data4:
+    case DW_FORM_addrx4:
       attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
       info_ptr += 4;
       break;
     case DW_FORM_data8:
+    case DW_FORM_ref8:
+    case DW_FORM_ref_sig8:
       attr->u.val = read_8_bytes (abfd, info_ptr, info_ptr_end);
       info_ptr += 8;
       break;
@@ -1244,6 +1300,33 @@ read_attribute_value (struct attribute *  attr,
       attr->u.str = read_alt_indirect_string (unit, info_ptr, info_ptr_end, &bytes_read);
       info_ptr += bytes_read;
       break;
+    case DW_FORM_strx1:
+      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
+      info_ptr += 1;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
+    case DW_FORM_strx2:
+      attr->u.val = read_2_bytes (abfd, info_ptr, info_ptr_end);
+      info_ptr += 2;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
+    case DW_FORM_strx3:
+      attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
+      info_ptr += 3;
+      attr->u.val &= 0xffffff;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
+    case DW_FORM_strx4:
+      attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
+      info_ptr += 4;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
+    case DW_FORM_strx:
+      attr->u.val = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                        FALSE, info_ptr_end);
+      info_ptr += bytes_read;
+      attr->u.str = (char *) read_indexed_string (attr->u.val, unit);
+      break;
     case DW_FORM_exprloc:
     case DW_FORM_block:
       amt = sizeof (struct dwarf_block);
@@ -1266,48 +1349,14 @@ read_attribute_value (struct attribute *  attr,
       info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
-    case DW_FORM_data1:
-      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
-      info_ptr += 1;
-      break;
-    case DW_FORM_flag:
-      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
-      info_ptr += 1;
-      break;
-    case DW_FORM_flag_present:
-      attr->u.val = 1;
-      break;
     case DW_FORM_sdata:
       attr->u.sval = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
                                            TRUE, info_ptr_end);
       info_ptr += bytes_read;
       break;
-    case DW_FORM_udata:
-      attr->u.val = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
-                                          FALSE, info_ptr_end);
-      info_ptr += bytes_read;
-      break;
-    case DW_FORM_ref1:
-      attr->u.val = read_1_byte (abfd, info_ptr, info_ptr_end);
-      info_ptr += 1;
-      break;
-    case DW_FORM_ref2:
-      attr->u.val = read_2_bytes (abfd, info_ptr, info_ptr_end);
-      info_ptr += 2;
-      break;
-    case DW_FORM_ref4:
-      attr->u.val = read_4_bytes (abfd, info_ptr, info_ptr_end);
-      info_ptr += 4;
-      break;
-    case DW_FORM_ref8:
-      attr->u.val = read_8_bytes (abfd, info_ptr, info_ptr_end);
-      info_ptr += 8;
-      break;
-    case DW_FORM_ref_sig8:
-      attr->u.val = read_8_bytes (abfd, info_ptr, info_ptr_end);
-      info_ptr += 8;
-      break;
     case DW_FORM_ref_udata:
+    case DW_FORM_udata:
+    case DW_FORM_addrx:
       attr->u.val = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
                                           FALSE, info_ptr_end);
       info_ptr += bytes_read;
@@ -1329,6 +1378,18 @@ read_attribute_value (struct attribute *  attr,
       attr->form = DW_FORM_sdata;
       attr->u.sval = implicit_const;
       break;
+    case DW_FORM_data16:
+      /* This is really a "constant", but there is no way to store that
+         so pretend it is a 16 byte block instead.  */
+      amt = sizeof (struct dwarf_block);
+      blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
+      if (blk == NULL)
+       return NULL;
+      blk->size = 16;
+      info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
+      attr->u.blk = blk;
+      break;
+
     default:
       _bfd_error_handler (_("DWARF error: invalid or unhandled FORM value: %#x"),
                          form);
@@ -1452,6 +1513,8 @@ struct funcinfo
   struct arange                arange;
   /* Where the symbol is defined.  */
   asection *           sec;
+  /* The offset of the funcinfo from the start of the unit.  */
+  bfd_uint64_t          unit_offset;
 };
 
 struct lookup_funcinfo
@@ -2069,11 +2132,17 @@ read_formatted_entries (struct comp_unit *unit, bfd_byte **bufp,
            case DW_FORM_udata:
              *uintp = attr.u.val;
              break;
+
+           case DW_FORM_data16:
+             /* MD5 data is in the attr.blk, but we are ignoring those.  */
+             break;
            }
        }
 
-      if (!callback (table, fe.name, fe.dir, fe.time, fe.size))
-       return FALSE;
+      /* Skip the first "zero entry", which is the compilation dir/file.  */
+      if (datai != 0)
+       if (!callback (table, fe.name, fe.dir, fe.time, fe.size))
+         return FALSE;
     }
 
   *bufp = buf;
@@ -2420,8 +2489,7 @@ decode_line_info (struct comp_unit *unit)
                    (_("DWARF error: mangled line number section"));
                  bfd_set_error (bfd_error_bad_value);
                line_fail:
-                 if (filename != NULL)
-                   free (filename);
+                 free (filename);
                  goto fail;
                }
              break;
@@ -2466,8 +2534,7 @@ decode_line_info (struct comp_unit *unit)
                filenum = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
                                                 FALSE, line_end);
                line_ptr += bytes_read;
-               if (filename)
-                 free (filename);
+               free (filename);
                filename = concat_filename (table, filenum);
                break;
              }
@@ -2513,8 +2580,7 @@ decode_line_info (struct comp_unit *unit)
            }
        }
 
-      if (filename)
-       free (filename);
+      free (filename);
     }
 
   if (unit->line_offset == 0)
@@ -2529,10 +2595,8 @@ decode_line_info (struct comp_unit *unit)
       table->sequences = table->sequences->prev_sequence;
       free (seq);
     }
-  if (table->files != NULL)
-    free (table->files);
-  if (table->dirs != NULL)
-    free (table->dirs);
+  free (table->files);
+  free (table->dirs);
   return NULL;
 }
 
@@ -2622,6 +2686,19 @@ read_debug_ranges (struct comp_unit * unit)
                       &file->dwarf_ranges_buffer, &file->dwarf_ranges_size);
 }
 
+/* Read in the .debug_rnglists section for future reference.  */
+
+static bfd_boolean
+read_debug_rnglists (struct comp_unit * unit)
+{
+  struct dwarf2_debug *stash = unit->stash;
+  struct dwarf2_debug_file *file = unit->file;
+
+  return read_section (unit->abfd, &stash->debug_sections[debug_rnglists],
+                      file->syms, 0,
+                      &file->dwarf_rnglists_buffer, &file->dwarf_rnglists_size);
+}
+
 /* Function table functions.  */
 
 static int
@@ -3112,8 +3189,8 @@ find_abstract_instance (struct comp_unit *unit,
 }
 
 static bfd_boolean
-read_rangelist (struct comp_unit *unit, struct arange *arange,
-               bfd_uint64_t offset)
+read_ranges (struct comp_unit *unit, struct arange *arange,
+            bfd_uint64_t offset)
 {
   bfd_byte *ranges_ptr;
   bfd_byte *ranges_end;
@@ -3158,6 +3235,115 @@ read_rangelist (struct comp_unit *unit, struct arange *arange,
   return TRUE;
 }
 
+static bfd_boolean
+read_rnglists (struct comp_unit *unit, struct arange *arange,
+              bfd_uint64_t offset)
+{
+  bfd_byte *rngs_ptr;
+  bfd_byte *rngs_end;
+  bfd_vma base_address = unit->base_address;
+  bfd_vma low_pc;
+  bfd_vma high_pc;
+  bfd *abfd = unit->abfd;
+
+  if (! unit->file->dwarf_rnglists_buffer)
+    {
+      if (! read_debug_rnglists (unit))
+       return FALSE;
+    }
+
+  rngs_ptr = unit->file->dwarf_rnglists_buffer + offset;
+  if (rngs_ptr < unit->file->dwarf_rnglists_buffer)
+    return FALSE;
+  rngs_end = unit->file->dwarf_rnglists_buffer;
+  rngs_end +=  unit->file->dwarf_rnglists_size;
+
+  for (;;)
+    {
+      enum dwarf_range_list_entry rlet;
+      unsigned int bytes_read;
+
+      if (rngs_ptr + 1 > rngs_end)
+       return FALSE;
+
+      rlet = read_1_byte (abfd, rngs_ptr, rngs_end);
+      rngs_ptr++;
+
+      switch (rlet)
+       {
+       case DW_RLE_end_of_list:
+         return TRUE;
+
+       case DW_RLE_base_address:
+         if (rngs_ptr + unit->addr_size > rngs_end)
+           return FALSE;
+         base_address = read_address (unit, rngs_ptr, rngs_end);
+         rngs_ptr += unit->addr_size;
+         continue;
+
+       case DW_RLE_start_length:
+         if (rngs_ptr + unit->addr_size > rngs_end)
+           return FALSE;
+         low_pc = read_address (unit, rngs_ptr, rngs_end);
+         rngs_ptr += unit->addr_size;
+         high_pc = low_pc;
+         high_pc += _bfd_safe_read_leb128 (abfd, rngs_ptr, &bytes_read,
+                                           FALSE, rngs_end);
+         rngs_ptr += bytes_read;
+         break;
+
+       case DW_RLE_offset_pair:
+         low_pc = base_address;
+         low_pc += _bfd_safe_read_leb128 (abfd, rngs_ptr, &bytes_read,
+                                          FALSE, rngs_end);
+         rngs_ptr += bytes_read;
+         high_pc = base_address;
+         high_pc += _bfd_safe_read_leb128 (abfd, rngs_ptr, &bytes_read,
+                                           FALSE, rngs_end);
+         rngs_ptr += bytes_read;
+         break;
+
+       case DW_RLE_start_end:
+         if (rngs_ptr + 2 * unit->addr_size > rngs_end)
+           return FALSE;
+         low_pc = read_address (unit, rngs_ptr, rngs_end);
+         rngs_ptr += unit->addr_size;
+         high_pc = read_address (unit, rngs_ptr, rngs_end);
+         rngs_ptr += unit->addr_size;
+         break;
+
+       /* TODO x-variants need .debug_addr support used for split-dwarf.  */
+       case DW_RLE_base_addressx:
+       case DW_RLE_startx_endx:
+       case DW_RLE_startx_length:
+       default:
+         return FALSE;
+       }
+
+      if (!arange_add (unit, arange, low_pc, high_pc))
+       return FALSE;
+    }
+}
+
+static bfd_boolean
+read_rangelist (struct comp_unit *unit, struct arange *arange,
+               bfd_uint64_t offset)
+{
+  if (unit->version <= 4)
+    return read_ranges (unit, arange, offset);
+  else
+    return read_rnglists (unit, arange, offset);
+}
+
+static struct funcinfo *
+lookup_func_by_offset (bfd_uint64_t offset, struct funcinfo * table)
+{
+  for (; table != NULL; table = table->prev_func)
+    if (table->unit_offset == offset)
+      return table;
+  return NULL;
+}
+
 static struct varinfo *
 lookup_var_by_offset (bfd_uint64_t offset, struct varinfo * table)
 {
@@ -3184,7 +3370,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
   bfd_byte *info_ptr = unit->first_child_die_ptr;
   bfd_byte *info_ptr_end = unit->end_ptr;
   int nesting_level = 0;
-  struct nest_funcinfo {
+  struct nest_funcinfo
+  {
     struct funcinfo *func;
   } *nested_funcs;
   int nested_funcs_size;
@@ -3198,16 +3385,16 @@ scan_unit_for_symbols (struct comp_unit *unit)
     return FALSE;
   nested_funcs[nesting_level].func = 0;
 
+  /* PR 27484: We must scan the DIEs twice.  The first time we look for
+     function and variable tags and accumulate them into their respective
+     tables.  The second time through we process the attributes of the
+     functions/variables and augment the table entries.  */
   while (nesting_level >= 0)
     {
       unsigned int abbrev_number, bytes_read, i;
       struct abbrev_info *abbrev;
-      struct attribute attr;
       struct funcinfo *func;
       struct varinfo *var;
-      bfd_vma low_pc = 0;
-      bfd_vma high_pc = 0;
-      bfd_boolean high_pc_relative = FALSE;
       bfd_uint64_t current_offset;
 
       /* PR 17512: file: 9f405d9d.  */
@@ -3219,7 +3406,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
                                             FALSE, info_ptr_end);
       info_ptr += bytes_read;
 
-      if (! abbrev_number)
+      if (abbrev_number == 0)
        {
          nesting_level--;
          continue;
@@ -3254,6 +3441,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
            goto fail;
          func->tag = abbrev->tag;
          func->prev_func = unit->function_table;
+         func->unit_offset = current_offset;
          unit->function_table = func;
          unit->number_of_functions++;
          BFD_ASSERT (!unit->cached);
@@ -3270,9 +3458,11 @@ scan_unit_for_symbols (struct comp_unit *unit)
       else
        {
          func = NULL;
-         if (abbrev->tag == DW_TAG_variable)
+         if (abbrev->tag == DW_TAG_variable
+             || abbrev->tag == DW_TAG_member)
            {
              size_t amt = sizeof (struct varinfo);
+
              var = (struct varinfo *) bfd_zalloc (abfd, amt);
              if (var == NULL)
                goto fail;
@@ -3291,6 +3481,89 @@ scan_unit_for_symbols (struct comp_unit *unit)
          nested_funcs[nesting_level].func = 0;
        }
 
+      for (i = 0; i < abbrev->num_attrs; ++i)
+       {
+         struct attribute attr;
+
+         info_ptr = read_attribute (&attr, &abbrev->attrs[i],
+                                    unit, info_ptr, info_ptr_end);
+         if (info_ptr == NULL)
+           goto fail;
+       }
+
+      if (abbrev->has_children)
+       {
+         nesting_level++;
+
+         if (nesting_level >= nested_funcs_size)
+           {
+             struct nest_funcinfo *tmp;
+
+             nested_funcs_size *= 2;
+             tmp = (struct nest_funcinfo *)
+               bfd_realloc (nested_funcs,
+                            nested_funcs_size * sizeof (*nested_funcs));
+             if (tmp == NULL)
+               goto fail;
+             nested_funcs = tmp;
+           }
+         nested_funcs[nesting_level].func = 0;
+       }
+    }
+
+  /* This is the second pass over the abbrevs.  */      
+  info_ptr = unit->first_child_die_ptr;
+  nesting_level = 0;
+  
+  while (nesting_level >= 0)
+    {
+      unsigned int abbrev_number, bytes_read, i;
+      struct abbrev_info *abbrev;
+      struct attribute attr;
+      struct funcinfo *func;
+      struct varinfo *var;
+      bfd_vma low_pc = 0;
+      bfd_vma high_pc = 0;
+      bfd_boolean high_pc_relative = FALSE;
+      bfd_uint64_t current_offset;
+
+      /* PR 17512: file: 9f405d9d.  */
+      if (info_ptr >= info_ptr_end)
+       goto fail;
+
+      current_offset = info_ptr - unit->info_ptr_unit;
+      abbrev_number = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                            FALSE, info_ptr_end);
+      info_ptr += bytes_read;
+
+      if (! abbrev_number)
+       {
+         nesting_level--;
+         continue;
+       }
+
+      abbrev = lookup_abbrev (abbrev_number, unit->abbrevs);
+      /* This should have been handled above.  */
+      BFD_ASSERT (abbrev != NULL);
+
+      func = NULL;
+      var = NULL;
+      if (abbrev->tag == DW_TAG_subprogram
+         || abbrev->tag == DW_TAG_entry_point
+         || abbrev->tag == DW_TAG_inlined_subroutine)
+       {
+         func = lookup_func_by_offset (current_offset, unit->function_table);
+         if (func == NULL)
+           goto fail;
+       }
+      else if (abbrev->tag == DW_TAG_variable
+              || abbrev->tag == DW_TAG_member)
+       {
+         var = lookup_var_by_offset (current_offset, unit->variable_table);
+         if (var == NULL)
+           goto fail;
+       }
+
       for (i = 0; i < abbrev->num_attrs; ++i)
        {
          info_ptr = read_attribute (&attr, &abbrev->attrs[i],
@@ -3379,18 +3652,20 @@ scan_unit_for_symbols (struct comp_unit *unit)
                    {
                      struct varinfo * spec_var;
 
-                     spec_var = lookup_var_by_offset (attr.u.val, unit->variable_table);
+                     spec_var = lookup_var_by_offset (attr.u.val,
+                                                      unit->variable_table);
                      if (spec_var == NULL)
-                       {       
-                         _bfd_error_handler
-                           (_("DWARF error: could not find variable specification at offset %lx"),
-                            (unsigned long) attr.u.val);
+                       {
+                         _bfd_error_handler (_("DWARF error: could not find "
+                                               "variable specification "
+                                               "at offset 0x%lx"),
+                                             (unsigned long) attr.u.val);
                          break;
                        }
 
                      if (var->name == NULL)
                        var->name = spec_var->name;
-                     if (var->file == NULL)
+                     if (var->file == NULL && spec_var->file != NULL)
                        var->file = strdup (spec_var->file);
                      if (var->line == 0)
                        var->line = spec_var->line;
@@ -3455,6 +3730,9 @@ scan_unit_for_symbols (struct comp_unit *unit)
            }
        }
 
+      if (abbrev->has_children)
+       nesting_level++;
+
       if (high_pc_relative)
        high_pc += low_pc;
 
@@ -3463,25 +3741,6 @@ scan_unit_for_symbols (struct comp_unit *unit)
          if (!arange_add (unit, &func->arange, low_pc, high_pc))
            goto fail;
        }
-
-      if (abbrev->has_children)
-       {
-         nesting_level++;
-
-         if (nesting_level >= nested_funcs_size)
-           {
-             struct nest_funcinfo *tmp;
-
-             nested_funcs_size *= 2;
-             tmp = (struct nest_funcinfo *)
-               bfd_realloc (nested_funcs,
-                            nested_funcs_size * sizeof (*nested_funcs));
-             if (tmp == NULL)
-               goto fail;
-             nested_funcs = tmp;
-           }
-         nested_funcs[nesting_level].func = 0;
-       }
     }
 
   free (nested_funcs);
@@ -3975,7 +4234,7 @@ find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
        }
 
       for (msec = abfd->sections; msec != NULL; msec = msec->next)
-       if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
+       if (startswith (msec->name, GNU_LINKONCE_INFO))
          return msec;
 
       return NULL;
@@ -3991,7 +4250,7 @@ find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
       if (look != NULL && strcmp (msec->name, look) == 0)
        return msec;
 
-      if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
+      if (startswith (msec->name, GNU_LINKONCE_INFO))
        return msec;
     }
 
@@ -4116,7 +4375,7 @@ place_sections (bfd *orig_bfd, struct dwarf2_debug *stash)
            continue;
 
          is_debug_info = (strcmp (sect->name, debug_info_name) == 0
-                          || CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO));
+                          || startswith (sect->name, GNU_LINKONCE_INFO));
 
          if (!((sect->flags & SEC_ALLOC) != 0 && abfd == orig_bfd)
              && !is_debug_info)
@@ -4160,7 +4419,7 @@ place_sections (bfd *orig_bfd, struct dwarf2_debug *stash)
                continue;
 
              is_debug_info = (strcmp (sect->name, debug_info_name) == 0
-                              || CONST_STRNEQ (sect->name, GNU_LINKONCE_INFO));
+                              || startswith (sect->name, GNU_LINKONCE_INFO));
 
              if (!((sect->flags & SEC_ALLOC) != 0 && abfd == orig_bfd)
                  && !is_debug_info)
@@ -5144,34 +5403,22 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
              free (each->line_table->dirs);
            }
 
-         if (each->lookup_funcinfo_table)
-           {
-             free (each->lookup_funcinfo_table);
-             each->lookup_funcinfo_table = NULL;
-           }
+         free (each->lookup_funcinfo_table);
+         each->lookup_funcinfo_table = NULL;
 
          while (function_table)
            {
-             if (function_table->file)
-               {
-                 free (function_table->file);
-                 function_table->file = NULL;
-               }
-             if (function_table->caller_file)
-               {
-                 free (function_table->caller_file);
-                 function_table->caller_file = NULL;
-               }
+             free (function_table->file);
+             function_table->file = NULL;
+             free (function_table->caller_file);
+             function_table->caller_file = NULL;
              function_table = function_table->prev_func;
            }
 
          while (variable_table)
            {
-             if (variable_table->file)
-               {
-                 free (variable_table->file);
-                 variable_table->file = NULL;
-               }
+             free (variable_table->file);
+             variable_table->file = NULL;
              variable_table = variable_table->prev_var;
            }
        }
This page took 0.03135 seconds and 4 git commands to generate.