PR23652, Use symbols from debug bfd for _bfd_elf_find_function

Alan Modra amodra@gmail.com
Wed Nov 27 08:41:00 GMT 2019


On Wed, Nov 27, 2019 at 12:05:53PM +1030, Alan Modra wrote:
> Sometimes DWARF info for a function is incomplete, and the function
> can be retrieved by examining symbols.  However, when separate debug
> files are used it may be that the original file is completely
> stripped of symbols.  This patch teaches BFD to look at symbols from
> the debug file in that case.

Well, it does look at symbols, but not ideally.  There were a number
of problems with the patch.  Firstly, _bfd_dwarf2_stash_syms didn't do
anything when the original file had dynamic symbols, and secondly,
info found by the symbol search didn't make it out of
_bfd_elf_find_nearest_line except in the case of DWARF functions
without external linkage.

	PR 23652
	* dwarf2.c (_bfd_dwarf2_stash_syms): Break out of loop on finding
	matching section.
	(_bfd_dwarf2_find_nearest_line): Return an int, with value 2 when
	returning info from the symbol table.  Do the _bfd_elf_find_function
	search also when !found.  Call _bfd_dwarf2_stash_syms regardless of
	symbols.
	* elf64-alpha.c (elf64_alpha_find_nearest_line): Accept dwarf2
	result of 1 only.
	* elfxx-mips.c (_bfd_mips_elf_find_nearest_line): Likewise.
	* libbfd-in.h (_bfd_dwarf2_find_nearest_line): Update prototype.
	* libbfd.h: Regenerate.

diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index e42483a535..a25f76ac2b 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -3923,6 +3923,7 @@ _bfd_dwarf2_stash_syms (struct dwarf2_debug *stash, bfd *abfd,
 	    {
 	      *sec = d;
 	      *syms = stash->syms;
+	      break;
 	    }
 	}
     }
@@ -4692,15 +4693,19 @@ _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.  */
 
-bfd_boolean
+int
 _bfd_dwarf2_find_nearest_line (bfd *abfd,
 			       asymbol **symbols,
 			       asymbol *symbol,
@@ -4726,7 +4731,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 +4930,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;
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index d4ac0c1469..f312a6e03d 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -1468,7 +1468,8 @@ elf64_alpha_find_nearest_line (bfd *abfd, asymbol **symbols,
 				     filename_ptr, functionname_ptr,
 				     line_ptr, discriminator_ptr,
 				     dwarf_debug_sections,
-				     &elf_tdata (abfd)->dwarf2_find_line_info))
+				     &elf_tdata (abfd)->dwarf2_find_line_info)
+      == 1)
     return TRUE;
 
   msec = bfd_get_section_by_name (abfd, ".mdebug");
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index e9af7abd4b..b1f83a0545 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -13078,7 +13078,8 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols,
 				     filename_ptr, functionname_ptr,
 				     line_ptr, discriminator_ptr,
 				     dwarf_debug_sections,
-				     &elf_tdata (abfd)->dwarf2_find_line_info))
+				     &elf_tdata (abfd)->dwarf2_find_line_info)
+      == 1)
     return TRUE;
 
   if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index f498ffd5e7..64ae6c6e91 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -596,7 +596,7 @@ struct dwarf_debug_section
 extern const struct dwarf_debug_section dwarf_debug_sections[] ATTRIBUTE_HIDDEN;
 
 /* Find the nearest line using DWARF 2 debugging information.  */
-extern bfd_boolean _bfd_dwarf2_find_nearest_line
+extern int _bfd_dwarf2_find_nearest_line
   (bfd *, asymbol **, asymbol *, asection *, bfd_vma,
    const char **, const char **, unsigned int *, unsigned int *,
    const struct dwarf_debug_section *, void **) ATTRIBUTE_HIDDEN;

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list