addr2line vs. inlined C functions called from C++

In this case the inlined function doesn't have DW_AT_linkage_name in
.debug_info, but the language is C++ so find_nearest_line goes looking
in the symbol table.  Since the function is inlined the enclosing
non-inline function symbol is returned from _bfd_elf_find_function,
which is wrong.  This patch only uses a symbol if its address matches.

	PR binutils/19315
	* dwarf2.c (_bfd_elf_find_function): Return symbol matched.
	(_bfd_dwarf2_find_nearest_line): Check symbol returned above
	against dwarf range.
	* elf-bfd.h (_bfd_elf_find_function): Update prototype.
This commit is contained in:
Alan Modra 2015-12-02 15:46:48 +10:30
parent 26e3a0c9ba
commit 923b198a84
3 changed files with 31 additions and 14 deletions

View File

@ -1,3 +1,11 @@
2015-12-02 Alan Modra <amodra@gmail.com>
PR binutils/19315
* dwarf2.c (_bfd_elf_find_function): Return symbol matched.
(_bfd_dwarf2_find_nearest_line): Check symbol returned above
against dwarf range.
* elf-bfd.h (_bfd_elf_find_function): Update prototype.
2015-12-02 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (ppc64_elf_tls_optimize): Don't segfault on NULL

View File

@ -4129,16 +4129,25 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
done:
if (function)
{
if (!function->is_linkage
&& _bfd_elf_find_function (abfd, symbols, section, offset,
*filename_ptr ? NULL : filename_ptr,
functionname_ptr))
if (!function->is_linkage)
{
function->name = *functionname_ptr;
asymbol *fun;
bfd_vma sec_vma;
fun = _bfd_elf_find_function (abfd, symbols, section, offset,
*filename_ptr ? NULL : filename_ptr,
functionname_ptr);
sec_vma = section->vma;
if (section->output_section != NULL)
sec_vma = section->output_section->vma + section->output_offset;
if (fun != NULL
&& fun->value + sec_vma == function->arange.low)
function->name = *functionname_ptr;
/* Even if we didn't find a linkage name, say that we have
to stop a repeated search of symbols. */
function->is_linkage = TRUE;
}
else
*functionname_ptr = function->name;
*functionname_ptr = function->name;
}
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
unset_sections (stash);
@ -4261,7 +4270,7 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
/* Find the function to a particular section and offset,
for error reporting. */
bfd_boolean
asymbol *
_bfd_elf_find_function (bfd *abfd,
asymbol **symbols,
asection *section,
@ -4278,10 +4287,10 @@ _bfd_elf_find_function (bfd *abfd,
} *cache;
if (symbols == NULL)
return FALSE;
return NULL;
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
return FALSE;
return NULL;
cache = elf_tdata (abfd)->elf_find_function_cache;
if (cache == NULL)
@ -4289,7 +4298,7 @@ _bfd_elf_find_function (bfd *abfd,
cache = bfd_zalloc (abfd, sizeof (*cache));
elf_tdata (abfd)->elf_find_function_cache = cache;
if (cache == NULL)
return FALSE;
return NULL;
}
if (cache->last_section != section
|| cache->func == NULL
@ -4354,12 +4363,12 @@ _bfd_elf_find_function (bfd *abfd,
}
if (cache->func == NULL)
return FALSE;
return NULL;
if (filename_ptr)
*filename_ptr = cache->filename;
if (functionname_ptr)
*functionname_ptr = bfd_asymbol_name (cache->func);
return TRUE;
return cache->func;
}

View File

@ -1996,7 +1996,7 @@ extern bfd_boolean _bfd_elf_find_line
(bfd *, asymbol **, asymbol *, const char **, unsigned int *);
extern bfd_boolean _bfd_elf_find_inliner_info
(bfd *, const char **, const char **, unsigned int *);
extern bfd_boolean _bfd_elf_find_function
extern asymbol *_bfd_elf_find_function
(bfd *, asymbol **, asection *, bfd_vma, const char **, const char **);
#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol