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:
parent
26e3a0c9ba
commit
923b198a84
|
@ -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>
|
2015-12-02 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf64-ppc.c (ppc64_elf_tls_optimize): Don't segfault on NULL
|
* elf64-ppc.c (ppc64_elf_tls_optimize): Don't segfault on NULL
|
||||||
|
|
31
bfd/dwarf2.c
31
bfd/dwarf2.c
|
@ -4129,15 +4129,24 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
||||||
done:
|
done:
|
||||||
if (function)
|
if (function)
|
||||||
{
|
{
|
||||||
if (!function->is_linkage
|
if (!function->is_linkage)
|
||||||
&& _bfd_elf_find_function (abfd, symbols, section, offset,
|
|
||||||
*filename_ptr ? NULL : filename_ptr,
|
|
||||||
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;
|
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;
|
function->is_linkage = TRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
*functionname_ptr = function->name;
|
*functionname_ptr = function->name;
|
||||||
}
|
}
|
||||||
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
||||||
|
@ -4261,7 +4270,7 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
|
||||||
/* Find the function to a particular section and offset,
|
/* Find the function to a particular section and offset,
|
||||||
for error reporting. */
|
for error reporting. */
|
||||||
|
|
||||||
bfd_boolean
|
asymbol *
|
||||||
_bfd_elf_find_function (bfd *abfd,
|
_bfd_elf_find_function (bfd *abfd,
|
||||||
asymbol **symbols,
|
asymbol **symbols,
|
||||||
asection *section,
|
asection *section,
|
||||||
|
@ -4278,10 +4287,10 @@ _bfd_elf_find_function (bfd *abfd,
|
||||||
} *cache;
|
} *cache;
|
||||||
|
|
||||||
if (symbols == NULL)
|
if (symbols == NULL)
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
|
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
cache = elf_tdata (abfd)->elf_find_function_cache;
|
cache = elf_tdata (abfd)->elf_find_function_cache;
|
||||||
if (cache == NULL)
|
if (cache == NULL)
|
||||||
|
@ -4289,7 +4298,7 @@ _bfd_elf_find_function (bfd *abfd,
|
||||||
cache = bfd_zalloc (abfd, sizeof (*cache));
|
cache = bfd_zalloc (abfd, sizeof (*cache));
|
||||||
elf_tdata (abfd)->elf_find_function_cache = cache;
|
elf_tdata (abfd)->elf_find_function_cache = cache;
|
||||||
if (cache == NULL)
|
if (cache == NULL)
|
||||||
return FALSE;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (cache->last_section != section
|
if (cache->last_section != section
|
||||||
|| cache->func == NULL
|
|| cache->func == NULL
|
||||||
|
@ -4354,12 +4363,12 @@ _bfd_elf_find_function (bfd *abfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache->func == NULL)
|
if (cache->func == NULL)
|
||||||
return FALSE;
|
return NULL;
|
||||||
|
|
||||||
if (filename_ptr)
|
if (filename_ptr)
|
||||||
*filename_ptr = cache->filename;
|
*filename_ptr = cache->filename;
|
||||||
if (functionname_ptr)
|
if (functionname_ptr)
|
||||||
*functionname_ptr = bfd_asymbol_name (cache->func);
|
*functionname_ptr = bfd_asymbol_name (cache->func);
|
||||||
|
|
||||||
return TRUE;
|
return cache->func;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1996,7 +1996,7 @@ extern bfd_boolean _bfd_elf_find_line
|
||||||
(bfd *, asymbol **, asymbol *, const char **, unsigned int *);
|
(bfd *, asymbol **, asymbol *, const char **, unsigned int *);
|
||||||
extern bfd_boolean _bfd_elf_find_inliner_info
|
extern bfd_boolean _bfd_elf_find_inliner_info
|
||||||
(bfd *, const char **, const char **, unsigned int *);
|
(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 **);
|
(bfd *, asymbol **, asection *, bfd_vma, const char **, const char **);
|
||||||
#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
|
#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
|
||||||
#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
|
#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
|
||||||
|
|
Loading…
Reference in New Issue