diff options
-rw-r--r-- | bfd/ChangeLog | 19 | ||||
-rw-r--r-- | bfd/dwarf2.c | 58 | ||||
-rw-r--r-- | bfd/elf.c | 9 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 141 | ||||
-rw-r--r-- | bfd/elfnn-aarch64.c | 143 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 30 |
6 files changed, 147 insertions, 253 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3ef8515..4a0852e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,24 @@ 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. (sh_reloc <R_SH_IND12W>): Divide calculated relocation value by two before applying to insn. Correct overflow test. diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index c3d9ffc..e42483a 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -3894,6 +3894,40 @@ set_debug_vma (bfd *orig_bfd, bfd *debug_bfd) } } +/* 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 @@ -4888,16 +4922,26 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd, } 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; @@ -4908,8 +4952,8 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd, 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); @@ -9030,10 +9030,11 @@ _bfd_elf_find_nearest_line (bfd *abfd, 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, diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index dca208f..37b5b64 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -16040,125 +16040,44 @@ elf32_arm_is_target_special_symbol (bfd * abfd ATTRIBUTE_UNUSED, asymbol * sym) 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 @@ -20488,7 +20407,6 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym) #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 @@ -20496,6 +20414,7 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym) #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 diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index a710711..51d7526 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -7999,122 +7999,43 @@ elfNN_aarch64_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED, 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 @@ -10123,9 +10044,6 @@ const struct elf_size_info elfNN_aarch64_size_info = #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 @@ -10170,6 +10088,9 @@ const struct elf_size_info elfNN_aarch64_size_info = #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 diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 3982ed2..e9af7ab 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -13078,27 +13078,17 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols, 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; } |