x86-64: Don't pass output_bfd to info->callbacks->minfo
[binutils-gdb.git] / bfd / dwarf2.c
index 856c963985cdf03568b2736dd6a3fd30d86e19f4..be415e394a36e3659bec6195c50f1c9b551d0d83 100644 (file)
@@ -125,8 +125,7 @@ struct dwarf2_debug
 
   /* A pointer to the memory block allocated for info_ptr.  Neither
      info_ptr nor sec_info_ptr are guaranteed to stay pointing to the
-     beginning of the malloc block.  This is used only to free the
-     memory later.  */
+     beginning of the malloc block.  */
   bfd_byte *info_ptr_memory;
 
   /* Pointer to the symbol table.  */
@@ -250,9 +249,6 @@ struct comp_unit
      by its reference.  */
   bfd_byte *info_ptr_unit;
 
-  /* Pointer to the start of the debug section, for DW_FORM_ref_addr.  */
-  bfd_byte *sec_info_ptr;
-
   /* The offset into .debug_line of the line number table.  */
   unsigned long line_offset;
 
@@ -1597,6 +1593,8 @@ concat_filename (struct line_info_table *table, unsigned int file)
     }
 
   filename = table->files[file - 1].name;
+  if (filename == NULL)
+    return strdup ("<unknown>");
 
   if (!IS_ABSOLUTE_PATH (filename))
     {
@@ -1933,17 +1931,36 @@ read_formatted_entries (struct comp_unit *unit, bfd_byte **bufp,
 
   data_count = _bfd_safe_read_leb128 (abfd, buf, &bytes_read, FALSE, buf_end);
   buf += bytes_read;
+  if (format_count == 0 && data_count != 0)
+    {
+      _bfd_error_handler (_("Dwarf Error: Zero format count."));
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
+  /* PR 22210.  Paranoia check.  Don't bother running the loop
+     if we know that we are going to run out of buffer.  */
+  if (data_count > (bfd_vma) (buf_end - buf))
+    {
+      _bfd_error_handler (_("Dwarf Error: data count (%Lx) larger than buffer size."),
+                         data_count);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
   for (datai = 0; datai < data_count; datai++)
     {
       bfd_byte *format = format_header_data;
       struct fileinfo fe;
 
+      memset (&fe, 0, sizeof fe);
       for (formati = 0; formati < format_count; formati++)
        {
          bfd_vma content_type, form;
          char *string_trash;
          char **stringp = &string_trash;
          unsigned int uint_trash, *uintp = &uint_trash;
+         struct attribute attr;
 
          content_type = _bfd_safe_read_leb128 (abfd, format, &bytes_read,
                                                FALSE, buf_end);
@@ -1975,47 +1992,23 @@ read_formatted_entries (struct comp_unit *unit, bfd_byte **bufp,
          form = _bfd_safe_read_leb128 (abfd, format, &bytes_read, FALSE,
                                        buf_end);
          format += bytes_read;
+
+         buf = read_attribute_value (&attr, form, 0, unit, buf, buf_end);
+         if (buf == NULL)
+           return FALSE;
          switch (form)
            {
            case DW_FORM_string:
-             *stringp = read_string (abfd, buf, buf_end, &bytes_read);
-             buf += bytes_read;
-             break;
-
            case DW_FORM_line_strp:
-             *stringp = read_indirect_line_string (unit, buf, buf_end, &bytes_read);
-             buf += bytes_read;
+             *stringp = attr.u.str;
              break;
 
            case DW_FORM_data1:
-             *uintp = read_1_byte (abfd, buf, buf_end);
-             buf += 1;
-             break;
-
            case DW_FORM_data2:
-             *uintp = read_2_bytes (abfd, buf, buf_end);
-             buf += 2;
-             break;
-
            case DW_FORM_data4:
-             *uintp = read_4_bytes (abfd, buf, buf_end);
-             buf += 4;
-             break;
-
            case DW_FORM_data8:
-             *uintp = read_8_bytes (abfd, buf, buf_end);
-             buf += 8;
-             break;
-
            case DW_FORM_udata:
-             *uintp = _bfd_safe_read_leb128 (abfd, buf, &bytes_read, FALSE,
-                                             buf_end);
-             buf += bytes_read;
-             break;
-
-           case DW_FORM_block:
-             /* It is valid only for DW_LNCT_timestamp which is ignored by
-                current GDB.  */
+             *uintp = attr.u.val;
              break;
            }
        }
@@ -2096,12 +2089,13 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
       offset_size = 8;
     }
 
-  if (unit->line_offset + lh.total_length > stash->dwarf_line_size)
+  if (lh.total_length > (size_t) (line_end - line_ptr))
     {
       _bfd_error_handler
        /* xgettext: c-format */
-       (_("Dwarf Error: Line info data is bigger (%#Lx) than the space remaining in the section (%#Lx)"),
-        lh.total_length, stash->dwarf_line_size - unit->line_offset);
+       (_("Dwarf Error: Line info data is bigger (%#Lx)"
+          " than the space remaining in the section (%#lx)"),
+        lh.total_length, (unsigned long) (line_end - line_ptr));
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
@@ -2260,6 +2254,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
       unsigned int discriminator = 0;
       int is_stmt = lh.default_is_stmt;
       int end_sequence = 0;
+      unsigned int dir, xtime, size;
       /* eraxxon@alumni.rice.edu: Against the DWARF2 specs, some
         compilers generate address sequences that are wildly out of
         order using DW_LNE_set_address (e.g. Intel C++ 6.0 compiler
@@ -2269,7 +2264,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
       bfd_vma high_pc = 0;
 
       /* Decode the table.  */
-      while (! end_sequence)
+      while (!end_sequence && line_ptr < line_end)
        {
          op_code = read_1_byte (abfd, line_ptr, line_end);
          line_ptr += 1;
@@ -2334,31 +2329,18 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
                case DW_LNE_define_file:
                  cur_file = read_string (abfd, line_ptr, line_end, &bytes_read);
                  line_ptr += bytes_read;
-                 if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
-                   {
-                     struct fileinfo *tmp;
-
-                     amt = table->num_files + FILE_ALLOC_CHUNK;
-                     amt *= sizeof (struct fileinfo);
-                     tmp = (struct fileinfo *) bfd_realloc (table->files, amt);
-                     if (tmp == NULL)
-                       goto line_fail;
-                     table->files = tmp;
-                   }
-                 table->files[table->num_files].name = cur_file;
-                 table->files[table->num_files].dir =
-                   _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
-                                          FALSE, line_end);
+                 dir = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                              FALSE, line_end);
                  line_ptr += bytes_read;
-                 table->files[table->num_files].time =
-                   _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
-                                          FALSE, line_end);
+                 xtime = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                                FALSE, line_end);
                  line_ptr += bytes_read;
-                 table->files[table->num_files].size =
-                   _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
-                                          FALSE, line_end);
+                 size = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                               FALSE, line_end);
                  line_ptr += bytes_read;
-                 table->num_files++;
+                 if (!line_info_add_file_name (table, cur_file, dir,
+                                               xtime, size))
+                   goto line_fail;
                  break;
                case DW_LNE_set_discriminator:
                  discriminator =
@@ -2436,6 +2418,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
            case DW_LNS_set_basic_block:
              break;
            case DW_LNS_const_add_pc:
+             if (lh.line_range == 0)
+               goto line_fail;
              if (lh.maximum_ops_per_insn == 1)
                address += (lh.minimum_instruction_length
                            * ((255 - lh.opcode_base) / lh.line_range));
@@ -2473,8 +2457,12 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
     return table;
 
  fail:
-  if (table->sequences != NULL)
-    free (table->sequences);
+  while (table->sequences != NULL)
+    {
+      struct line_sequence* seq = table->sequences;
+      table->sequences = table->sequences->prev_sequence;
+      free (seq);
+    }
   if (table->files != NULL)
     free (table->files);
   if (table->dirs != NULL)
@@ -2823,9 +2811,11 @@ lookup_symbol_in_variable_table (struct comp_unit *unit,
   return FALSE;
 }
 
-static char *
+static bfd_boolean
 find_abstract_instance_name (struct comp_unit *unit,
+                            bfd_byte *orig_info_ptr,
                             struct attribute *attr_ptr,
+                            const char **pname,
                             bfd_boolean *is_linkage)
 {
   bfd *abfd = unit->abfd;
@@ -2835,23 +2825,44 @@ find_abstract_instance_name (struct comp_unit *unit,
   struct abbrev_info *abbrev;
   bfd_uint64_t die_ref = attr_ptr->u.val;
   struct attribute attr;
-  char *name = NULL;
+  const char *name = NULL;
 
   /* DW_FORM_ref_addr can reference an entry in a different CU. It
      is an offset from the .debug_info section, not the current CU.  */
   if (attr_ptr->form == DW_FORM_ref_addr)
     {
       /* We only support DW_FORM_ref_addr within the same file, so
-        any relocations should be resolved already.  */
-      if (!die_ref)
-       abort ();
-
-      info_ptr = unit->sec_info_ptr + die_ref;
-      info_ptr_end = unit->end_ptr;
+        any relocations should be resolved already.  Check this by
+        testing for a zero die_ref;  There can't be a valid reference
+        to the header of a .debug_info section.
+        DW_FORM_ref_addr is an offset relative to .debug_info.
+        Normally when using the GNU linker this is accomplished by
+        emitting a symbolic reference to a label, because .debug_info
+        sections are linked at zero.  When there are multiple section
+        groups containing .debug_info, as there might be in a
+        relocatable object file, it would be reasonable to assume that
+        a symbolic reference to a label in any .debug_info section
+        might be used.  Since we lay out multiple .debug_info
+        sections at non-zero VMAs (see place_sections), and read
+        them contiguously into stash->info_ptr_memory, that means
+        the reference is relative to stash->info_ptr_memory.  */
+      size_t total;
+
+      info_ptr = unit->stash->info_ptr_memory;
+      info_ptr_end = unit->stash->info_ptr_end;
+      total = info_ptr_end - info_ptr;
+      if (!die_ref || die_ref >= total)
+       {
+         _bfd_error_handler
+           (_("Dwarf Error: Invalid abstract instance DIE ref."));
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+      info_ptr += die_ref;
 
       /* Now find the CU containing this pointer.  */
       if (info_ptr >= unit->info_ptr_unit && info_ptr < unit->end_ptr)
-       ;
+       info_ptr_end = unit->end_ptr;
       else
        {
          /* Check other CUs to see if they contain the abbrev.  */
@@ -2867,7 +2878,10 @@ find_abstract_instance_name (struct comp_unit *unit,
                break;
 
          if (u)
-           unit = u;
+           {
+             unit = u;
+             info_ptr_end = unit->end_ptr;
+           }
          /* else FIXME: What do we do now ?  */
        }
     }
@@ -2880,17 +2894,32 @@ find_abstract_instance_name (struct comp_unit *unit,
            (_("Dwarf Error: Unable to read alt ref %llu."),
             (long long) die_ref);
          bfd_set_error (bfd_error_bad_value);
-         return NULL;
+         return FALSE;
        }
-      info_ptr_end = unit->stash->alt_dwarf_info_buffer + unit->stash->alt_dwarf_info_size;
+      info_ptr_end = (unit->stash->alt_dwarf_info_buffer
+                     + unit->stash->alt_dwarf_info_size);
 
       /* FIXME: Do we need to locate the correct CU, in a similar
         fashion to the code in the DW_FORM_ref_addr case above ?  */
     }
   else
     {
-      info_ptr = unit->info_ptr_unit + die_ref;
+      /* DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8 or
+        DW_FORM_ref_udata.  These are all references relative to the
+        start of the current CU.  */
+      size_t total;
+
+      info_ptr = unit->info_ptr_unit;
       info_ptr_end = unit->end_ptr;
+      total = info_ptr_end - info_ptr;
+      if (!die_ref || die_ref >= total)
+       {
+         _bfd_error_handler
+           (_("Dwarf Error: Invalid abstract instance DIE ref."));
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+      info_ptr += die_ref;
     }
 
   abbrev_number = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
@@ -2905,6 +2934,7 @@ find_abstract_instance_name (struct comp_unit *unit,
          _bfd_error_handler
            (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number);
          bfd_set_error (bfd_error_bad_value);
+         return FALSE;
        }
       else
        {
@@ -2914,6 +2944,15 @@ find_abstract_instance_name (struct comp_unit *unit,
                                         info_ptr, info_ptr_end);
              if (info_ptr == NULL)
                break;
+             /* It doesn't ever make sense for DW_AT_specification to
+                refer to the same DIE.  Stop simple recursion.  */
+             if (info_ptr == orig_info_ptr)
+               {
+                 _bfd_error_handler
+                   (_("Dwarf Error: Abstract instance recursion detected."));
+                 bfd_set_error (bfd_error_bad_value);
+                 return FALSE;
+               }
              switch (attr.name)
                {
                case DW_AT_name:
@@ -2927,7 +2966,9 @@ find_abstract_instance_name (struct comp_unit *unit,
                    }
                  break;
                case DW_AT_specification:
-                 name = find_abstract_instance_name (unit, &attr, is_linkage);
+                 if (!find_abstract_instance_name (unit, info_ptr, &attr,
+                                                   pname, is_linkage))
+                   return FALSE;
                  break;
                case DW_AT_linkage_name:
                case DW_AT_MIPS_linkage_name:
@@ -2945,7 +2986,8 @@ find_abstract_instance_name (struct comp_unit *unit,
            }
        }
     }
-  return name;
+  *pname = name;
+  return TRUE;
 }
 
 static bfd_boolean
@@ -3006,20 +3048,22 @@ scan_unit_for_symbols (struct comp_unit *unit)
   bfd *abfd = unit->abfd;
   bfd_byte *info_ptr = unit->first_child_die_ptr;
   bfd_byte *info_ptr_end = unit->stash->info_ptr_end;
-  int nesting_level = 1;
-  struct funcinfo **nested_funcs;
+  int nesting_level = 0;
+  struct nest_funcinfo {
+    struct funcinfo *func;
+  } *nested_funcs;
   int nested_funcs_size;
 
   /* Maintain a stack of in-scope functions and inlined functions, which we
      can use to set the caller_func field.  */
   nested_funcs_size = 32;
-  nested_funcs = (struct funcinfo **)
-    bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
+  nested_funcs = (struct nest_funcinfo *)
+    bfd_malloc (nested_funcs_size * sizeof (*nested_funcs));
   if (nested_funcs == NULL)
     return FALSE;
-  nested_funcs[nesting_level] = 0;
+  nested_funcs[nesting_level].func = 0;
 
-  while (nesting_level)
+  while (nesting_level >= 0)
     {
       unsigned int abbrev_number, bytes_read, i;
       struct abbrev_info *abbrev;
@@ -3077,13 +3121,13 @@ scan_unit_for_symbols (struct comp_unit *unit)
          BFD_ASSERT (!unit->cached);
 
          if (func->tag == DW_TAG_inlined_subroutine)
-           for (i = nesting_level - 1; i >= 1; i--)
-             if (nested_funcs[i])
+           for (i = nesting_level; i-- != 0; )
+             if (nested_funcs[i].func)
                {
-                 func->caller_func = nested_funcs[i];
+                 func->caller_func = nested_funcs[i].func;
                  break;
                }
-         nested_funcs[nesting_level] = func;
+         nested_funcs[nesting_level].func = func;
        }
       else
        {
@@ -3103,12 +3147,13 @@ scan_unit_for_symbols (struct comp_unit *unit)
            }
 
          /* No inline function in scope at this nesting level.  */
-         nested_funcs[nesting_level] = 0;
+         nested_funcs[nesting_level].func = 0;
        }
 
       for (i = 0; i < abbrev->num_attrs; ++i)
        {
-         info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr, info_ptr_end);
+         info_ptr = read_attribute (&attr, &abbrev->attrs[i],
+                                    unit, info_ptr, info_ptr_end);
          if (info_ptr == NULL)
            goto fail;
 
@@ -3127,8 +3172,10 @@ scan_unit_for_symbols (struct comp_unit *unit)
 
                case DW_AT_abstract_origin:
                case DW_AT_specification:
-                 func->name = find_abstract_instance_name (unit, &attr,
-                                                           &func->is_linkage);
+                 if (!find_abstract_instance_name (unit, info_ptr, &attr,
+                                                   &func->name,
+                                                   &func->is_linkage))
+                   goto fail;
                  break;
 
                case DW_AT_name:
@@ -3185,7 +3232,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
              switch (attr.name)
                {
                case DW_AT_name:
-                 var->name = attr.u.str;
+                 if (is_str_attr (attr.form))
+                   var->name = attr.u.str;
                  break;
 
                case DW_AT_decl_file:
@@ -3210,7 +3258,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
                    case DW_FORM_block2:
                    case DW_FORM_block4:
                    case DW_FORM_exprloc:
-                     if (*attr.u.blk->data == DW_OP_addr)
+                     if (attr.u.blk->data != NULL
+                         && *attr.u.blk->data == DW_OP_addr)
                        {
                          var->stack = 0;
 
@@ -3253,17 +3302,17 @@ scan_unit_for_symbols (struct comp_unit *unit)
 
          if (nesting_level >= nested_funcs_size)
            {
-             struct funcinfo **tmp;
+             struct nest_funcinfo *tmp;
 
              nested_funcs_size *= 2;
-             tmp = (struct funcinfo **)
+             tmp = (struct nest_funcinfo *)
                bfd_realloc (nested_funcs,
-                            nested_funcs_size * sizeof (struct funcinfo *));
+                            nested_funcs_size * sizeof (*nested_funcs));
              if (tmp == NULL)
                goto fail;
              nested_funcs = tmp;
            }
-         nested_funcs[nesting_level] = 0;
+         nested_funcs[nesting_level].func = 0;
        }
     }
 
@@ -3418,7 +3467,6 @@ parse_comp_unit (struct dwarf2_debug *stash,
   unit->end_ptr = end_ptr;
   unit->stash = stash;
   unit->info_ptr_unit = info_ptr_unit;
-  unit->sec_info_ptr = stash->sec_info_ptr;
 
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
@@ -3436,7 +3484,8 @@ parse_comp_unit (struct dwarf2_debug *stash,
          break;
 
        case DW_AT_name:
-         unit->name = attr.u.str;
+         if (is_str_attr (attr.form))
+           unit->name = attr.u.str;
          break;
 
        case DW_AT_low_pc: