diff options
Diffstat (limited to 'bfd/elfnn-aarch64.c')
-rw-r--r-- | bfd/elfnn-aarch64.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 0a1d7a6..b6f083e 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -8012,34 +8012,42 @@ elfNN_aarch64_maybe_function_sym (const asymbol *sym, asection *sec, bfd_vma *code_off) { bfd_size_type size; + elf_symbol_type * elf_sym = (elf_symbol_type *) sym; if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0 || sym->section != sec) return 0; + size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size; + if (!(sym->flags & BSF_SYNTHETIC)) - switch (ELF_ST_TYPE (((elf_symbol_type *) sym)->internal_elf_sym.st_info)) + switch (ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info)) { - case STT_FUNC: case STT_NOTYPE: + /* Ignore symbols created by the annobin plugin for gcc and clang. + These symbols are hidden, local, notype and have a size of 0. */ + if (size == 0 + && sym->flags & BSF_LOCAL + && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN) + return 0; + /* Fall through. */ + case STT_FUNC: + /* FIXME: Allow STT_GNU_IFUNC as well ? */ break; default: return 0; } - + if ((sym->flags & BSF_LOCAL) && bfd_is_aarch64_special_symbol_name (sym->name, BFD_AARCH64_SPECIAL_SYM_TYPE_ANY)) return 0; *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; + + /* Do not return 0 for the function's size. */ + return size ? size : 1; } static bool |