+2019-11-27 Alan Modra <amodra@gmail.com>
+
+ PR 23652
+ * dwarf2.c (_bfd_dwarf2_stash_syms): New function.
+ (_bfd_dwarf2_find_nearest_line): Use it here, passing syms to
+ _bfd_elf_find_function. Call _bfd_elf_find_function in cases
+ where _bfd_elf_find_nearest_line would do so.
+ * elf.c (_bfd_elf_find_nearest_line): Omit _bfd_elf_find_function
+ for dwarf2.
+ * elfxx-mips.c (_bfd_mips_elf_find_nearest_line): Similarly. Tidy.
+ * elf32-arm.c (elf32_arm_maybe_function_sym): New function.
+ (elf_backend_maybe_function_sym): Define.
+ (arm_elf_find_function, elf32_arm_find_nearest_line): Delete.
+ (bfd_elf32_find_nearest_line): Don't define.
+ * elfnn-aarch64.c (elfNN_aarch64_maybe_function_sym): New function.
+ (elf_backend_maybe_function_sym): Define.
+ (aarch64_elf_find_function, elfNN_aarch64_find_nearest_line): Delete.
+ (bfd_elfNN_find_nearest_line): Don't define.
+
2019-11-27 Alan Modra <amodra@gmail.com>
* elf32-sh.c (sh_reloc): Use a bfd_vma insn.
}
}
+/* If the dwarf2 info was found in a separate debug file, return the
+ debug file section corresponding to the section in the original file
+ and the debug file symbols. */
+
+static void
+_bfd_dwarf2_stash_syms (struct dwarf2_debug *stash, bfd *abfd,
+ asection **sec, asymbol ***syms)
+{
+ if (stash->bfd_ptr != abfd)
+ {
+ asection *s, *d;
+
+ if (*sec == NULL)
+ {
+ *syms = stash->syms;
+ return;
+ }
+
+ for (s = abfd->sections, d = stash->bfd_ptr->sections;
+ s != NULL && d != NULL;
+ s = s->next, d = d->next)
+ {
+ if ((d->flags & SEC_DEBUGGING) != 0)
+ break;
+ if (s == *sec
+ && strcmp (s->name, d->name) == 0)
+ {
+ *sec = d;
+ *syms = stash->syms;
+ }
+ }
+ }
+}
+
/* Unset vmas for adjusted sections in STASH. */
static void
}
done:
- if (function)
+ if (functionname_ptr && function && function->is_linkage)
+ *functionname_ptr = function->name;
+ else if (functionname_ptr
+ && ((found && !*functionname_ptr)
+ || (function && !function->is_linkage)))
{
- if (!function->is_linkage)
+ asymbol *fun;
+ asymbol **syms = symbols;
+ asection *sec = section;
+
+ if (symbols == NULL || *symbols == NULL)
+ _bfd_dwarf2_stash_syms (stash, abfd, &sec, &syms);
+ fun = _bfd_elf_find_function (abfd, syms, sec, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_ptr);
+
+ if (function && !function->is_linkage)
{
- 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;
to stop a repeated search of symbols. */
function->is_linkage = TRUE;
}
- *functionname_ptr = function->name;
}
+
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
unset_sections (stash);
filename_ptr, functionname_ptr,
line_ptr, discriminator_ptr,
dwarf_debug_sections,
- &elf_tdata (abfd)->dwarf2_find_line_info)
- || _bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr,
- line_ptr))
+ &elf_tdata (abfd)->dwarf2_find_line_info))
+ return TRUE;
+
+ if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr, line_ptr))
{
if (!*functionname_ptr)
_bfd_elf_find_function (abfd, symbols, section, offset,
BFD_ARM_SPECIAL_SYM_TYPE_ANY);
}
-/* This is a version of _bfd_elf_find_function() from dwarf2.c except that
- ARM mapping symbols are ignored when looking for function names
- and STT_ARM_TFUNC is considered to a function type. */
+/* If the ELF symbol SYM might be a function in SEC, return the
+ function size and set *CODE_OFF to the function's entry point,
+ otherwise return zero. */
-static bfd_boolean
-arm_elf_find_function (bfd * abfd,
- asymbol ** symbols,
- asection * section,
- bfd_vma offset,
- const char ** filename_ptr,
- const char ** functionname_ptr)
-{
- const char * filename = NULL;
- asymbol * func = NULL;
- bfd_vma low_func = 0;
- asymbol ** p;
-
- if (symbols == NULL)
- return FALSE;
-
- if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
- return FALSE;
-
- for (p = symbols; *p != NULL; p++)
- {
- elf_symbol_type *q;
+static bfd_size_type
+elf32_arm_maybe_function_sym (const asymbol *sym, asection *sec,
+ bfd_vma *code_off)
+{
+ bfd_size_type size;
- q = (elf_symbol_type *) *p;
+ if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
+ || sym->section != sec)
+ return 0;
- switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
- {
- default:
- break;
- case STT_FILE:
- filename = bfd_asymbol_name (&q->symbol);
- break;
+ if (!(sym->flags & BSF_SYNTHETIC))
+ switch (ELF_ST_TYPE (((elf_symbol_type *) sym)->internal_elf_sym.st_info))
+ {
case STT_FUNC:
case STT_ARM_TFUNC:
case STT_NOTYPE:
- /* Skip mapping symbols. */
- if ((q->symbol.flags & BSF_LOCAL)
- && bfd_is_arm_special_symbol_name (q->symbol.name,
- BFD_ARM_SPECIAL_SYM_TYPE_ANY))
- continue;
- /* Fall through. */
- if (bfd_asymbol_section (&q->symbol) == section
- && q->symbol.value >= low_func
- && q->symbol.value <= offset)
- {
- func = (asymbol *) q;
- low_func = q->symbol.value;
- }
break;
- }
- }
-
- if (func == NULL)
- return FALSE;
-
- if (filename_ptr)
- *filename_ptr = filename;
- if (functionname_ptr)
- *functionname_ptr = bfd_asymbol_name (func);
-
- return TRUE;
-}
-
-
-/* Find the nearest line to a particular section and offset, for error
- reporting. This code is a duplicate of the code in elf.c, except
- that it uses arm_elf_find_function. */
-
-static bfd_boolean
-elf32_arm_find_nearest_line (bfd * abfd,
- asymbol ** symbols,
- asection * section,
- bfd_vma offset,
- const char ** filename_ptr,
- const char ** functionname_ptr,
- unsigned int * line_ptr,
- unsigned int * discriminator_ptr)
-{
- bfd_boolean found = FALSE;
-
- if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
- filename_ptr, functionname_ptr,
- line_ptr, discriminator_ptr,
- dwarf_debug_sections,
- & elf_tdata (abfd)->dwarf2_find_line_info))
- {
- if (!*functionname_ptr)
- arm_elf_find_function (abfd, symbols, section, offset,
- *filename_ptr ? NULL : filename_ptr,
- functionname_ptr);
-
- return TRUE;
- }
-
- /* Skip _bfd_dwarf1_find_nearest_line since no known ARM toolchain
- uses DWARF1. */
-
- if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
- & found, filename_ptr,
- functionname_ptr, line_ptr,
- & elf_tdata (abfd)->line_info))
- return FALSE;
-
- if (found && (*functionname_ptr || *line_ptr))
- return TRUE;
-
- if (symbols == NULL)
- return FALSE;
+ default:
+ return 0;
+ }
- if (! arm_elf_find_function (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr))
- return FALSE;
+ if ((sym->flags & BSF_LOCAL)
+ && bfd_is_arm_special_symbol_name (sym->name,
+ BFD_ARM_SPECIAL_SYM_TYPE_ANY))
+ return 0;
- *line_ptr = 0;
- return TRUE;
+ *code_off = sym->value;
+ size = 0;
+ if (!(sym->flags & BSF_SYNTHETIC))
+ size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+ if (size == 0)
+ size = 1;
+ return size;
}
static bfd_boolean
#define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create
#define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup elf32_arm_reloc_name_lookup
-#define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line
#define bfd_elf32_find_inliner_info elf32_arm_find_inliner_info
#define bfd_elf32_new_section_hook elf32_arm_new_section_hook
#define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symbol
#define bfd_elf32_get_synthetic_symtab elf32_arm_get_synthetic_symtab
#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
+#define elf_backend_maybe_function_sym elf32_arm_maybe_function_sym
#define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
#define elf_backend_gc_mark_extra_sections elf32_arm_gc_mark_extra_sections
#define elf_backend_check_relocs elf32_arm_check_relocs
BFD_AARCH64_SPECIAL_SYM_TYPE_ANY);
}
-/* This is a version of _bfd_elf_find_function() from dwarf2.c except that
- AArch64 mapping symbols are ignored when looking for function names. */
+/* If the ELF symbol SYM might be a function in SEC, return the
+ function size and set *CODE_OFF to the function's entry point,
+ otherwise return zero. */
-static bfd_boolean
-aarch64_elf_find_function (bfd * abfd,
- asymbol ** symbols,
- asection * section,
- bfd_vma offset,
- const char ** filename_ptr,
- const char ** functionname_ptr)
-{
- const char *filename = NULL;
- asymbol *func = NULL;
- bfd_vma low_func = 0;
- asymbol **p;
-
- if (symbols == NULL)
- return FALSE;
-
- if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
- return FALSE;
-
- for (p = symbols; *p != NULL; p++)
- {
- elf_symbol_type *q;
+static bfd_size_type
+elfNN_aarch64_maybe_function_sym (const asymbol *sym, asection *sec,
+ bfd_vma *code_off)
+{
+ bfd_size_type size;
- q = (elf_symbol_type *) * p;
+ if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
+ || sym->section != sec)
+ return 0;
- switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
- {
- default:
- break;
- case STT_FILE:
- filename = bfd_asymbol_name (&q->symbol);
- break;
+ if (!(sym->flags & BSF_SYNTHETIC))
+ switch (ELF_ST_TYPE (((elf_symbol_type *) sym)->internal_elf_sym.st_info))
+ {
case STT_FUNC:
case STT_NOTYPE:
- /* Skip mapping symbols. */
- if ((q->symbol.flags & BSF_LOCAL)
- && (bfd_is_aarch64_special_symbol_name
- (q->symbol.name, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY)))
- continue;
- /* Fall through. */
- if (bfd_asymbol_section (&q->symbol) == section
- && q->symbol.value >= low_func && q->symbol.value <= offset)
- {
- func = (asymbol *) q;
- low_func = q->symbol.value;
- }
break;
- }
- }
-
- if (func == NULL)
- return FALSE;
-
- if (filename_ptr)
- *filename_ptr = filename;
- if (functionname_ptr)
- *functionname_ptr = bfd_asymbol_name (func);
-
- return TRUE;
-}
-
-
-/* Find the nearest line to a particular section and offset, for error
- reporting. This code is a duplicate of the code in elf.c, except
- that it uses aarch64_elf_find_function. */
-
-static bfd_boolean
-elfNN_aarch64_find_nearest_line (bfd *abfd,
- asymbol **symbols,
- asection *section,
- bfd_vma offset,
- const char **filename_ptr,
- const char **functionname_ptr,
- unsigned int *line_ptr,
- unsigned int *discriminator_ptr)
-{
- bfd_boolean found = FALSE;
-
- if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
- filename_ptr, functionname_ptr,
- line_ptr, discriminator_ptr,
- dwarf_debug_sections,
- &elf_tdata (abfd)->dwarf2_find_line_info))
- {
- if (!*functionname_ptr)
- aarch64_elf_find_function (abfd, symbols, section, offset,
- *filename_ptr ? NULL : filename_ptr,
- functionname_ptr);
-
- return TRUE;
- }
-
- /* Skip _bfd_dwarf1_find_nearest_line since no known AArch64
- toolchain uses DWARF1. */
-
- if (!_bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
- &found, filename_ptr,
- functionname_ptr, line_ptr,
- &elf_tdata (abfd)->line_info))
- return FALSE;
-
- if (found && (*functionname_ptr || *line_ptr))
- return TRUE;
-
- if (symbols == NULL)
- return FALSE;
+ default:
+ return 0;
+ }
- if (!aarch64_elf_find_function (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr))
- return FALSE;
+ if ((sym->flags & BSF_LOCAL)
+ && bfd_is_aarch64_special_symbol_name (sym->name,
+ BFD_AARCH64_SPECIAL_SYM_TYPE_ANY))
+ return 0;
- *line_ptr = 0;
- return TRUE;
+ *code_off = sym->value;
+ size = 0;
+ if (!(sym->flags & BSF_SYNTHETIC))
+ size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+ if (size == 0)
+ size = 1;
+ return size;
}
static bfd_boolean
#define bfd_elfNN_find_inliner_info \
elfNN_aarch64_find_inliner_info
-#define bfd_elfNN_find_nearest_line \
- elfNN_aarch64_find_nearest_line
-
#define bfd_elfNN_get_synthetic_symtab \
elfNN_aarch64_get_synthetic_symtab
#define elf_backend_output_arch_local_syms \
elfNN_aarch64_output_arch_local_syms
+#define elf_backend_maybe_function_sym \
+ elfNN_aarch64_maybe_function_sym
+
#define elf_backend_plt_sym_val \
elfNN_aarch64_plt_sym_val
filename_ptr, functionname_ptr,
line_ptr, discriminator_ptr,
dwarf_debug_sections,
- &elf_tdata (abfd)->dwarf2_find_line_info)
- || _bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr,
- line_ptr))
- {
- /* PR 22789: If the function name or filename was not found through
- the debug information, then try an ordinary lookup instead. */
- if ((functionname_ptr != NULL && *functionname_ptr == NULL)
- || (filename_ptr != NULL && *filename_ptr == NULL))
- {
- /* Do not override already discovered names. */
- if (functionname_ptr != NULL && *functionname_ptr != NULL)
- functionname_ptr = NULL;
-
- if (filename_ptr != NULL && *filename_ptr != NULL)
- filename_ptr = NULL;
-
- _bfd_elf_find_function (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr);
- }
+ &elf_tdata (abfd)->dwarf2_find_line_info))
+ return TRUE;
+ if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr))
+ {
+ if (!*functionname_ptr)
+ _bfd_elf_find_function (abfd, symbols, section, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_ptr);
return TRUE;
}