dwarf2.c: read_abbrevs fail cleanup, and offset checking
[deliverable/binutils-gdb.git] / bfd / dwarf2.c
index e42483a535ab334dca2bbf50e35f191536b26953..0d5d84ea4c7342bc683a219447c0c9795b13ad37 100644 (file)
@@ -107,12 +107,9 @@ struct dwarf2_debug
      time.  */
   bfd *orig_bfd;
 
-  /* Pointer to the bfd, section and address of the beginning of the
-     section.  The bfd might be different than expected because of
-     gnu_debuglink sections.  */
+  /* Pointer to the bfd.  The bfd might be different than expected
+     because of gnu_debuglink sections.  */
   bfd *bfd_ptr;
-  asection *sec;
-  bfd_byte *sec_info_ptr;
 
   /* Support for alternate debug info sections created by the DWZ utility:
      This includes a pointer to an alternate bfd which contains *extra*,
@@ -124,9 +121,7 @@ struct dwarf2_debug
   bfd_byte *    alt_dwarf_info_buffer;
   bfd_size_type         alt_dwarf_info_size;
 
-  /* 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.  */
+  /* A pointer to the memory block allocated for .debug_info sections.  */
   bfd_byte *info_ptr_memory;
 
   /* Pointer to the symbol table.  */
@@ -726,8 +721,6 @@ read_indirect_string (struct comp_unit * unit,
                      &stash->dwarf_str_buffer, &stash->dwarf_str_size))
     return NULL;
 
-  if (offset >= stash->dwarf_str_size)
-    return NULL;
   str = (char *) stash->dwarf_str_buffer + offset;
   if (*str == '\0')
     return NULL;
@@ -765,8 +758,6 @@ read_indirect_line_string (struct comp_unit * unit,
                      &stash->dwarf_line_str_size))
     return NULL;
 
-  if (offset >= stash->dwarf_line_str_size)
-    return NULL;
   str = (char *) stash->dwarf_line_str_buffer + offset;
   if (*str == '\0')
     return NULL;
@@ -830,8 +821,6 @@ read_alt_indirect_string (struct comp_unit * unit,
                      &stash->alt_dwarf_str_size))
     return NULL;
 
-  if (offset >= stash->alt_dwarf_str_size)
-    return NULL;
   str = (char *) stash->alt_dwarf_str_buffer + offset;
   if (*str == '\0')
     return NULL;
@@ -855,7 +844,7 @@ read_alt_indirect_ref (struct comp_unit * unit,
       char *debug_filename = bfd_follow_gnu_debugaltlink (unit->abfd, DEBUGDIR);
 
       if (debug_filename == NULL)
-       return FALSE;
+       return NULL;
 
       debug_bfd = bfd_openr (debug_filename, NULL);
       free (debug_filename);
@@ -879,8 +868,6 @@ read_alt_indirect_ref (struct comp_unit * unit,
                      &stash->alt_dwarf_info_size))
     return NULL;
 
-  if (offset >= stash->alt_dwarf_info_size)
-    return NULL;
   return stash->alt_dwarf_info_buffer + offset;
 }
 
@@ -968,9 +955,6 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
                      &stash->dwarf_abbrev_buffer, &stash->dwarf_abbrev_size))
     return NULL;
 
-  if (offset >= stash->dwarf_abbrev_size)
-    return NULL;
-
   amt = sizeof (struct abbrev_info*) * ABBREV_HASH_SIZE;
   abbrevs = (struct abbrev_info **) bfd_zalloc (abfd, amt);
   if (abbrevs == NULL)
@@ -988,7 +972,7 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
       amt = sizeof (struct abbrev_info);
       cur_abbrev = (struct abbrev_info *) bfd_zalloc (abfd, amt);
       if (cur_abbrev == NULL)
-       return NULL;
+       goto fail;
 
       /* Read in abbrev header.  */
       cur_abbrev->number = abbrev_number;
@@ -1030,21 +1014,7 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
              amt *= sizeof (struct attr_abbrev);
              tmp = (struct attr_abbrev *) bfd_realloc (cur_abbrev->attrs, amt);
              if (tmp == NULL)
-               {
-                 size_t i;
-
-                 for (i = 0; i < ABBREV_HASH_SIZE; i++)
-                   {
-                     struct abbrev_info *abbrev = abbrevs[i];
-
-                     while (abbrev)
-                       {
-                         free (abbrev->attrs);
-                         abbrev = abbrev->next;
-                       }
-                   }
-                 return NULL;
-               }
+               goto fail;
              cur_abbrev->attrs = tmp;
            }
 
@@ -1068,7 +1038,7 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
         already read (which means we are about to read the abbreviations
         for the next compile unit) or if the end of the abbreviation
         table is reached.  */
-      if ((unsigned int) (abbrev_ptr - stash->dwarf_abbrev_buffer)
+      if ((size_t) (abbrev_ptr - stash->dwarf_abbrev_buffer)
          >= stash->dwarf_abbrev_size)
        break;
       abbrev_number = _bfd_safe_read_leb128 (abfd, abbrev_ptr,
@@ -1077,8 +1047,26 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
       if (lookup_abbrev (abbrev_number, abbrevs) != NULL)
        break;
     }
-
   return abbrevs;
+
+ fail:
+  if (abbrevs != NULL)
+    {
+      size_t i;
+
+      for (i = 0; i < ABBREV_HASH_SIZE; i++)
+       {
+         struct abbrev_info *abbrev = abbrevs[i];
+
+         while (abbrev)
+           {
+             free (abbrev->attrs);
+             abbrev = abbrev->next;
+           }
+       }
+      free (abbrevs);
+    }
+  return NULL;
 }
 
 /* Returns true if the form is one which has a string value.  */
@@ -3923,6 +3911,7 @@ _bfd_dwarf2_stash_syms (struct dwarf2_debug *stash, bfd *abfd,
            {
              *sec = d;
              *syms = stash->syms;
+             break;
            }
        }
     }
@@ -4520,8 +4509,6 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
 
   stash->info_ptr = stash->info_ptr_memory;
   stash->info_ptr_end = stash->info_ptr + total_size;
-  stash->sec = find_debug_info (debug_bfd, debug_sections, NULL);
-  stash->sec_info_ptr = stash->info_ptr;
   return TRUE;
 }
 
@@ -4590,15 +4577,6 @@ stash_comp_unit (struct dwarf2_debug *stash)
          stash->all_comp_units = each;
 
          stash->info_ptr += length;
-
-         if ((bfd_size_type) (stash->info_ptr - stash->sec_info_ptr)
-             == stash->sec->size)
-           {
-             stash->sec = find_debug_info (stash->bfd_ptr,
-                                           stash->debug_sections,
-                                           stash->sec);
-             stash->sec_info_ptr = stash->info_ptr;
-           }
          return each;
        }
     }
@@ -4692,15 +4670,17 @@ _bfd_dwarf2_find_symbol_bias (asymbol ** symbols, void ** pinfo)
 /* Find the source code location of SYMBOL.  If SYMBOL is NULL
    then find the nearest source code location corresponding to
    the address SECTION + OFFSET.
-   Returns TRUE if the line is found without error and fills in
+   Returns 1 if the line is found without error and fills in
    FILENAME_PTR and LINENUMBER_PTR.  In the case where SYMBOL was
    NULL the FUNCTIONNAME_PTR is also filled in.
+   Returns 2 if partial information from _bfd_elf_find_function is
+   returned (function and maybe file) by looking at symbols.  DWARF2
+   info is present but not regarding the requested code location.
+   Returns 0 otherwise.
    SYMBOLS contains the symbol table for ABFD.
-   DEBUG_SECTIONS contains the name of the dwarf debug sections.
-   field and in the abbreviation offset, or zero to indicate that the
-   default value should be used.  */
+   DEBUG_SECTIONS contains the name of the dwarf debug sections.  */
 
-bfd_boolean
+int
 _bfd_dwarf2_find_nearest_line (bfd *abfd,
                               asymbol **symbols,
                               asymbol *symbol,
@@ -4726,7 +4706,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
   bfd_vma addr;
   struct comp_unit* each;
   struct funcinfo *function = NULL;
-  bfd_boolean found = FALSE;
+  int found = FALSE;
   bfd_boolean do_line;
 
   *filename_ptr = NULL;
@@ -4925,19 +4905,21 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
   if (functionname_ptr && function && function->is_linkage)
     *functionname_ptr = function->name;
   else if (functionname_ptr
-          && ((found && !*functionname_ptr)
+          && (!*functionname_ptr
               || (function && !function->is_linkage)))
     {
       asymbol *fun;
       asymbol **syms = symbols;
       asection *sec = section;
 
-      if (symbols == NULL || *symbols == NULL)
-       _bfd_dwarf2_stash_syms (stash, abfd, &sec, &syms);
+      _bfd_dwarf2_stash_syms (stash, abfd, &sec, &syms);
       fun = _bfd_elf_find_function (abfd, syms, sec, offset,
                                    *filename_ptr ? NULL : filename_ptr,
                                    functionname_ptr);
 
+      if (!found && fun != NULL)
+       found = 2;
+
       if (function && !function->is_linkage)
        {
          bfd_vma sec_vma;
This page took 0.027337 seconds and 4 git commands to generate.