aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-12-10 09:51:56 +1030
committerAlan Modra <amodra@gmail.com>2014-12-10 23:00:51 +1030
commite00e81980c70659d0efe686b31a55db5faaa91f9 (patch)
tree95c316a165c37f3d3cc8cc03995b089ad8e66b21 /bfd/elf.c
parentfa15f18deaf6f48e0b415ad3e8864de0b1cf6a39 (diff)
downloadbinutils-e00e81980c70659d0efe686b31a55db5faaa91f9.zip
binutils-e00e81980c70659d0efe686b31a55db5faaa91f9.tar.gz
binutils-e00e81980c70659d0efe686b31a55db5faaa91f9.tar.bz2
Don't return DW_AT_name for function name in C++
DW_AT_name for functions typically just contains the base function name, so lacks namespace, class and parameter information. It would be possible to extract all these from the DWARF, but at a considerable complication of the parser in dwarf2.c, and then you'd need to mangle it all together. Much simpler is to look up the actual symbol. This patch does that, avoiding the extra symbol lookup when the language doesn't do name mangling. PR 17541 * dwarf2.c (struct comp_unit): Add "lang". (non_mangled): New function. (struct funcinfo): Add "is_linkage". Reorder for better packing. Make "name" a const char*. (lookup_address_in_function_table): Delete functionname_ptr param. (find_abstract_instance_name): Add is_linkage param. Set if we have DW_AT_linkage_name or non_mangled DW_AT_name. (scan_unit_for_symbols): Similarly set func->is_linkage. (parse_comp_unit): Stash DW_AT_language. (comp_unit_find_nearest_line): Replace functionname_ptr param with function_ptr param. (_bfd_dwarf2_find_nearest_line): Adjust above calls. Set functionname_ptr from function->name. Call _bfd_elf_find_function to retrieve symbol for function if not linkage name. (_bfd_elf_find_function): Add bfd_target_elf_flavour test, moved from.. * elf.c (elf_find_function): ..here. (_bfd_elf_find_nearest_line): Adjust calls. * elf-bfd.h (_bfd_elf_find_function): Declare.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c130
1 files changed, 9 insertions, 121 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index f6923b4..f7c1b9e 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -7702,109 +7702,6 @@ _bfd_elf_set_arch_mach (bfd *abfd,
return bfd_default_set_arch_mach (abfd, arch, machine);
}
-/* Find the function to a particular section and offset,
- for error reporting. */
-
-static bfd_boolean
-elf_find_function (bfd *abfd,
- asymbol **symbols,
- asection *section,
- bfd_vma offset,
- const char **filename_ptr,
- const char **functionname_ptr)
-{
- struct elf_find_function_cache
- {
- asection *last_section;
- asymbol *func;
- const char *filename;
- bfd_size_type func_size;
- } *cache;
-
- if (symbols == NULL)
- return FALSE;
-
- cache = elf_tdata (abfd)->elf_find_function_cache;
- if (cache == NULL)
- {
- cache = bfd_zalloc (abfd, sizeof (*cache));
- elf_tdata (abfd)->elf_find_function_cache = cache;
- if (cache == NULL)
- return FALSE;
- }
- if (cache->last_section != section
- || cache->func == NULL
- || offset < cache->func->value
- || offset >= cache->func->value + cache->func_size)
- {
- asymbol *file;
- bfd_vma low_func;
- asymbol **p;
- /* ??? Given multiple file symbols, it is impossible to reliably
- choose the right file name for global symbols. File symbols are
- local symbols, and thus all file symbols must sort before any
- global symbols. The ELF spec may be interpreted to say that a
- file symbol must sort before other local symbols, but currently
- ld -r doesn't do this. So, for ld -r output, it is possible to
- make a better choice of file name for local symbols by ignoring
- file symbols appearing after a given local symbol. */
- enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
- const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-
- file = NULL;
- low_func = 0;
- state = nothing_seen;
- cache->filename = NULL;
- cache->func = NULL;
- cache->func_size = 0;
- cache->last_section = section;
-
- for (p = symbols; *p != NULL; p++)
- {
- asymbol *sym = *p;
- bfd_vma code_off;
- bfd_size_type size;
-
- if ((sym->flags & BSF_FILE) != 0)
- {
- file = sym;
- if (state == symbol_seen)
- state = file_after_symbol_seen;
- continue;
- }
-
- size = bed->maybe_function_sym (sym, section, &code_off);
- if (size != 0
- && code_off <= offset
- && (code_off > low_func
- || (code_off == low_func
- && size > cache->func_size)))
- {
- cache->func = sym;
- cache->func_size = size;
- cache->filename = NULL;
- low_func = code_off;
- if (file != NULL
- && ((sym->flags & BSF_LOCAL) != 0
- || state != file_after_symbol_seen))
- cache->filename = bfd_asymbol_name (file);
- }
- if (state == nothing_seen)
- state = symbol_seen;
- }
- }
-
- if (cache->func == NULL)
- return FALSE;
-
- if (filename_ptr)
- *filename_ptr = cache->filename;
- if (functionname_ptr)
- *functionname_ptr = bfd_asymbol_name (cache->func);
-
- return TRUE;
-}
-
/* Find the nearest line to a particular section and offset,
for error reporting. */
@@ -7824,24 +7721,15 @@ _bfd_elf_find_nearest_line (bfd *abfd,
filename_ptr, functionname_ptr,
line_ptr, discriminator_ptr,
dwarf_debug_sections, 0,
- &elf_tdata (abfd)->dwarf2_find_line_info))
- {
- if (!*functionname_ptr)
- elf_find_function (abfd, symbols, section, offset,
- *filename_ptr ? NULL : filename_ptr,
- functionname_ptr);
-
- return TRUE;
- }
-
- if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr, line_ptr))
+ &elf_tdata (abfd)->dwarf2_find_line_info)
+ || _bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr))
{
if (!*functionname_ptr)
- elf_find_function (abfd, symbols, section, offset,
- *filename_ptr ? NULL : filename_ptr,
- functionname_ptr);
-
+ _bfd_elf_find_function (abfd, symbols, section, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_ptr);
return TRUE;
}
@@ -7856,8 +7744,8 @@ _bfd_elf_find_nearest_line (bfd *abfd,
if (symbols == NULL)
return FALSE;
- if (! elf_find_function (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr))
+ if (! _bfd_elf_find_function (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr))
return FALSE;
*line_ptr = 0;