aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-12-02 15:46:48 +1030
committerAlan Modra <amodra@gmail.com>2015-12-02 23:55:51 +1030
commit923b198a8426f02866f33362b26ed8bbf7a5c5cd (patch)
treed88697dfaa76f5c49207fe729990fa938a2a12e8 /bfd
parent26e3a0c9ba4a8376fdf9f898637919d144d8b1d8 (diff)
downloadfsf-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')
-rw-r--r--bfd/ChangeLog8
-rw-r--r--bfd/dwarf2.c35
-rw-r--r--bfd/elf-bfd.h2
3 files changed, 31 insertions, 14 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index fbbea1d..cc3cc2b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,13 @@
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
symbol section or output section.
(ppc64_elf_edit_toc): Similarly for ld -R objects.
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;
}
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 2b05089..70e3327 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