From 9f296da34f6b4357ce7528eeb2b29d9f8e50c71e Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 23 Jan 2012 06:16:38 +0000 Subject: [PATCH] * elf-bfd.h: Formatting. (struct elf_backend_data): Add "maybe_function_sym". (_bfd_elf_maybe_function_sym): Declare. * elfxx-target.h (elf_backend_maybe_function_sym): Define. (elfNN_bed): Init new field. * elf.c (elf_find_function): Use maybe_function_sym. (_bfd_elf_maybe_function_sym): New function. * elf64-ppc.c (elf_backend_maybe_function_sym): Define. (ppc64_elf_maybe_function_sym): New function. --- bfd/ChangeLog | 12 ++++++++++++ bfd/elf-bfd.h | 24 ++++++++++++++++-------- bfd/elf.c | 35 +++++++++++++++++++++++++++-------- bfd/elf64-ppc.c | 21 ++++++++++++++++++++- bfd/elfxx-target.h | 7 ++++++- 5 files changed, 81 insertions(+), 18 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 994a1ce2df0..23c33a137ad 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2012-01-23 Alan Modra + + * elf-bfd.h: Formatting. + (struct elf_backend_data): Add "maybe_function_sym". + (_bfd_elf_maybe_function_sym): Declare. + * elfxx-target.h (elf_backend_maybe_function_sym): Define. + (elfNN_bed): Init new field. + * elf.c (elf_find_function): Use maybe_function_sym. + (_bfd_elf_maybe_function_sym): New function. + * elf64-ppc.c (elf_backend_maybe_function_sym): Define. + (ppc64_elf_maybe_function_sym): New function. + 2012-01-20 Francois Gouget PR binutils/13534 diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index c7846e118f0..98948a99c32 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1,6 +1,6 @@ /* BFD back-end data structures for ELF files. Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Written by Cygnus Support. @@ -1221,6 +1221,11 @@ struct elf_backend_data /* Return TRUE if type is a function symbol type. */ bfd_boolean (*is_function_type) (unsigned int type); + /* Return TRUE if symbol may be a function. Set *CODE_SEC and *CODE_VAL + to the function's entry point. */ + bfd_boolean (*maybe_function_sym) (const elf_symbol_type *sym, + asection **code_sec, bfd_vma *code_off); + /* Used to handle bad SHF_LINK_ORDER input. */ bfd_error_handler_type link_order_error_handler; @@ -1413,14 +1418,14 @@ struct bfd_elf_section_data void *sec_info; }; -#define elf_section_data(sec) ((struct bfd_elf_section_data*)(sec)->used_by_bfd) +#define elf_section_data(sec) ((struct bfd_elf_section_data*)(sec)->used_by_bfd) #define elf_linked_to_section(sec) (elf_section_data(sec)->linked_to) -#define elf_section_type(sec) (elf_section_data(sec)->this_hdr.sh_type) -#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags) -#define elf_group_name(sec) (elf_section_data(sec)->group.name) -#define elf_group_id(sec) (elf_section_data(sec)->group.id) -#define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group) -#define elf_fde_list(sec) (elf_section_data(sec)->fde_list) +#define elf_section_type(sec) (elf_section_data(sec)->this_hdr.sh_type) +#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags) +#define elf_group_name(sec) (elf_section_data(sec)->group.name) +#define elf_group_id(sec) (elf_section_data(sec)->group.id) +#define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group) +#define elf_fde_list(sec) (elf_section_data(sec)->fde_list) #define elf_sec_group(sec) (elf_section_data(sec)->sec_group) #define xvec_get_elf_backend_data(xvec) \ @@ -2197,6 +2202,9 @@ extern bfd_boolean _bfd_elf_map_sections_to_segments extern bfd_boolean _bfd_elf_is_function_type (unsigned int); +extern bfd_boolean _bfd_elf_maybe_function_sym (const elf_symbol_type *, + asection **, bfd_vma *); + extern int bfd_elf_get_default_section_type (flagword); extern void bfd_elf_lookup_section_flags diff --git a/bfd/elf.c b/bfd/elf.c index 35007cd4d49..9c9ba754022 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1,7 +1,7 @@ /* ELF executable support for BFD. Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -7406,6 +7406,8 @@ elf_find_function (bfd *abfd, { elf_symbol_type *q; unsigned int type; + asection *code_sec; + bfd_vma code_off; q = (elf_symbol_type *) *p; @@ -7418,15 +7420,13 @@ elf_find_function (bfd *abfd, state = file_after_symbol_seen; continue; default: - if (!bed->is_function_type (type)) - break; - case STT_NOTYPE: - if (bfd_get_section (&q->symbol) == section - && q->symbol.value >= low_func - && q->symbol.value <= offset) + if (bed->maybe_function_sym (q, &code_sec, &code_off) + && code_sec == section + && code_off >= low_func + && code_off <= offset) { func = (asymbol *) q; - low_func = q->symbol.value; + low_func = code_off; filename = NULL; if (file != NULL && (ELF_ST_BIND (q->internal_elf_sym.st_info) == STB_LOCAL @@ -9690,3 +9690,22 @@ _bfd_elf_is_function_type (unsigned int type) return (type == STT_FUNC || type == STT_GNU_IFUNC); } + +/* Return TRUE iff the ELF symbol SYM might be a function. Set *CODE_SEC + and *CODE_OFF to the function's entry point. */ + +bfd_boolean +_bfd_elf_maybe_function_sym (const elf_symbol_type *sym, + asection **code_sec, bfd_vma *code_off) +{ + unsigned int type = ELF_ST_TYPE (sym->internal_elf_sym.st_info); + if (type == STT_NOTYPE + || type == STT_FUNC + || type == STT_GNU_IFUNC) + { + *code_sec = sym->symbol.section; + *code_off = sym->symbol.value; + return TRUE; + } + return FALSE; +} diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 7ffbe0e42ce..a51115e01a7 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -105,6 +105,7 @@ static bfd_vma opd_entry_value #define elf_backend_gc_sweep_hook ppc64_elf_gc_sweep_hook #define elf_backend_adjust_dynamic_symbol ppc64_elf_adjust_dynamic_symbol #define elf_backend_hide_symbol ppc64_elf_hide_symbol +#define elf_backend_maybe_function_sym ppc64_elf_maybe_function_sym #define elf_backend_always_size_sections ppc64_elf_func_desc_adjust #define elf_backend_size_dynamic_sections ppc64_elf_size_dynamic_sections #define elf_backend_init_index_section _bfd_elf_init_2_index_sections @@ -5528,7 +5529,8 @@ opd_entry_value (asection *opd_sec, Elf_Internal_Rela *lo, *hi, *look; bfd_vma val; - /* No relocs implies we are linking a --just-symbols object. */ + /* No relocs implies we are linking a --just-symbols object, or looking + at a final linked executable with addr2line or somesuch. */ if (opd_sec->reloc_count == 0) { char buf[8]; @@ -5631,6 +5633,23 @@ opd_entry_value (asection *opd_sec, return val; } +/* Return TRUE iff the ELF symbol SYM might be a function. Set *CODE_SEC + and *CODE_OFF to the function's entry point. */ + +static bfd_boolean +ppc64_elf_maybe_function_sym (const elf_symbol_type *sym, + asection **code_sec, bfd_vma *code_off) +{ + if (_bfd_elf_maybe_function_sym (sym, code_sec, code_off)) + { + if (strcmp (sym->symbol.section->name, ".opd") == 0) + opd_entry_value (sym->symbol.section, sym->symbol.value, + code_sec, code_off); + return TRUE; + } + return FALSE; +} + /* Return true if symbol is defined in a regular object file. */ static bfd_boolean diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 96ecce308d2..5a6cae02ee3 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -1,6 +1,6 @@ /* Target definitions for NN-bit ELF Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -655,6 +655,10 @@ #define elf_backend_is_function_type _bfd_elf_is_function_type #endif +#ifndef elf_backend_maybe_function_sym +#define elf_backend_maybe_function_sym _bfd_elf_maybe_function_sym +#endif + #ifndef elf_match_priority #define elf_match_priority \ (ELF_ARCH == bfd_arch_unknown ? 2 : ELF_OSABI == ELFOSABI_NONE ? 1 : 0) @@ -750,6 +754,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_merge_symbol, elf_backend_hash_symbol, elf_backend_is_function_type, + elf_backend_maybe_function_sym, elf_backend_link_order_error_handler, elf_backend_relplt_name, ELF_MACHINE_ALT1, -- 2.30.2