From: Alan Modra Date: Wed, 2 Dec 2015 05:16:48 +0000 (+1030) Subject: addr2line vs. inlined C functions called from C++ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=923b198a8426f02866f33362b26ed8bbf7a5c5cd;p=binutils-gdb.git 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index fbbea1dabb7..cc3cc2bbfe2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2015-12-02 Alan Modra + + 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 * elf64-ppc.c (ppc64_elf_tls_optimize): Don't segfault on NULL diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 401ec43a7ce..176f018add2 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; } diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 2b05089a526..70e33275054 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -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