diff options
author | Alan Modra <amodra@gmail.com> | 2015-12-02 15:46:48 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2015-12-02 23:55:51 +1030 |
commit | 923b198a8426f02866f33362b26ed8bbf7a5c5cd (patch) | |
tree | d88697dfaa76f5c49207fe729990fa938a2a12e8 /bfd/dwarf2.c | |
parent | 26e3a0c9ba4a8376fdf9f898637919d144d8b1d8 (diff) | |
download | fsf-binutils-gdb-923b198a8426f02866f33362b26ed8bbf7a5c5cd.zip fsf-binutils-gdb-923b198a8426f02866f33362b26ed8bbf7a5c5cd.tar.gz fsf-binutils-gdb-923b198a8426f02866f33362b26ed8bbf7a5c5cd.tar.bz2 |
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.
Diffstat (limited to 'bfd/dwarf2.c')
-rw-r--r-- | bfd/dwarf2.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 401ec43..176f018 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -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; } |