X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Felfxx-x86.h;h=db11327e96f403bed1d4f582117fc04493c9735d;hb=5f47741bf633596475bb8fbb0ed304be318362cd;hp=fb57d4377a80ade85982007d9d39b25d866b1cc9;hpb=79b0c981b8f0c912208ec305d48e775bcb6d2624;p=binutils-gdb.git diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index fb57d4377a8..db11327e96f 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -1,5 +1,5 @@ /* x86 specific support for ELF - Copyright (C) 2017 Free Software Foundation, Inc. + Copyright (C) 2017-2021 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -18,13 +18,16 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ +/* Don't generate unused section symbols. */ +#define TARGET_KEEP_UNUSED_SECTION_SYMBOLS false + #include "sysdep.h" #include "bfd.h" #include "bfdlink.h" #include "libbfd.h" #include "elf-bfd.h" -#include "bfd_stdint.h" #include "hashtab.h" +#include "elf-linker-x86.h" #define PLT_CIE_LENGTH 20 #define PLT_FDE_LENGTH 36 @@ -76,14 +79,11 @@ into the shared library. However, if we are linking with -Bsymbolic, we do not need to copy a reloc against a global symbol which is defined in an object we are including in the link (i.e., DEF_REGULAR - is set). At this point we have not seen all the input files, so it - is possible that DEF_REGULAR is not set now but will be set later (it - is never cleared). In case of a weak definition, DEF_REGULAR may be - cleared later by a strong definition in a shared library. We account - for that possibility below by storing information in the relocs_copied - field of the hash table entry. A similar situation occurs when - creating shared libraries and symbol visibility changes render the - symbol local. + is set). + + If PCREL_PLT is true, don't generate dynamic relocation in PIE for + PC-relative relocation against a dynamic function definition in data + section when PLT address can be used. If on the other hand, we are creating an executable, we may need to keep relocations for symbols satisfied by a dynamic library if we @@ -91,23 +91,30 @@ We also need to generate dynamic pointer relocation against STT_GNU_IFUNC symbol in the non-code section. */ -#define NEED_DYNAMIC_RELOCATION_P(INFO, H, SEC, R_TYPE, POINTER_TYPE) \ +#define NEED_DYNAMIC_RELOCATION_P(INFO, PCREL_PLT, H, SEC, R_TYPE, \ + POINTER_TYPE) \ ((bfd_link_pic (INFO) \ && (! X86_PCREL_TYPE_P (R_TYPE) \ || ((H) != NULL \ && (! (bfd_link_pie (INFO) \ || SYMBOLIC_BIND ((INFO), (H))) \ || (H)->root.type == bfd_link_hash_defweak \ - || !(H)->def_regular)))) \ - || ((H) != NULL \ - && (H)->type == STT_GNU_IFUNC \ - && (R_TYPE) == POINTER_TYPE \ - && ((SEC)->flags & SEC_CODE) == 0) \ - || (ELIMINATE_COPY_RELOCS \ - && !bfd_link_pic (INFO) \ - && (H) != NULL \ - && ((H)->root.type == bfd_link_hash_defweak \ - || !(H)->def_regular))) + || (!(bfd_link_pie (INFO) \ + && (PCREL_PLT) \ + && (H)->plt.refcount > 0 \ + && ((SEC)->flags & SEC_CODE) == 0 \ + && (H)->type == STT_FUNC \ + && (H)->def_dynamic) \ + && !(H)->def_regular))))) \ + || ((H) != NULL \ + && (H)->type == STT_GNU_IFUNC \ + && (R_TYPE) == POINTER_TYPE \ + && ((SEC)->flags & SEC_CODE) == 0) \ + || (ELIMINATE_COPY_RELOCS \ + && !bfd_link_pic (INFO) \ + && (H) != NULL \ + && ((H)->root.type == bfd_link_hash_defweak \ + || !(H)->def_regular))) /* TRUE if dynamic relocation should be generated. Don't copy a pc-relative relocation into the output file if the symbol needs @@ -115,19 +122,23 @@ Copy dynamic function pointer relocations. Don't generate dynamic relocations against resolved undefined weak symbols in PIE, except when PC32_RELOC is TRUE. Undefined weak symbol is bound locally - when PIC is false. */ -#define GENERATE_DYNAMIC_RELOCATION_P(INFO, EH, R_TYPE, \ + when PIC is false. Don't generate dynamic relocations against + non-preemptible absolute symbol. */ +#define GENERATE_DYNAMIC_RELOCATION_P(INFO, EH, R_TYPE, SEC, \ NEED_COPY_RELOC_IN_PIE, \ RESOLVED_TO_ZERO, PC32_RELOC) \ ((bfd_link_pic (INFO) \ + && !(bfd_is_abs_section (SEC) \ + && ((EH) == NULL \ + || SYMBOL_REFERENCES_LOCAL (INFO, &(EH)->elf))) \ && !(NEED_COPY_RELOC_IN_PIE) \ && ((EH) == NULL \ || ((ELF_ST_VISIBILITY ((EH)->elf.other) == STV_DEFAULT \ && (!(RESOLVED_TO_ZERO) || PC32_RELOC)) \ || (EH)->elf.root.type != bfd_link_hash_undefweak)) \ - && ((!X86_PCREL_TYPE_P (R_TYPE) \ - && !X86_SIZE_TYPE_P (R_TYPE)) \ - || ! SYMBOL_CALLS_LOCAL ((INFO), &(EH)->elf))) \ + && ((!X86_PCREL_TYPE_P (R_TYPE) && !X86_SIZE_TYPE_P (R_TYPE)) \ + || ! SYMBOL_CALLS_LOCAL ((INFO), \ + (struct elf_link_hash_entry *) (EH)))) \ || (ELIMINATE_COPY_RELOCS \ && !bfd_link_pic (INFO) \ && (EH) != NULL \ @@ -158,17 +169,33 @@ || (ELF_ST_VISIBILITY ((H)->other) \ && (H)->root.type == bfd_link_hash_undefweak)) +/* TRUE if this symbol isn't defined by a shared object. */ +#define SYMBOL_DEFINED_NON_SHARED_P(H) \ + ((H)->def_regular \ + || (H)->root.linker_def \ + || (H)->root.ldscript_def \ + || ((struct elf_x86_link_hash_entry *) (H))->linker_def \ + || ELF_COMMON_DEF_P (H)) + +/* Return TRUE if the symbol described by a linker hash entry H is + going to be absolute. Similar to bfd_is_abs_symbol, but excluding + all linker-script defined symbols. */ +#define ABS_SYMBOL_P(H) \ + (bfd_is_abs_symbol (&(H)->root) && !(H)->root.ldscript_def) + /* TRUE if relative relocation should be generated. GOT reference to global symbol in PIC will lead to dynamic symbol. It becomes a problem when "time" or "times" is defined as a variable in an executable, clashing with functions of the same name in libc. If a symbol isn't undefined weak symbol, don't make it dynamic in PIC and - generate relative relocation. */ + generate relative relocation. Don't generate relative relocation + against non-preemptible absolute symbol. */ #define GENERATE_RELATIVE_RELOC_P(INFO, H) \ ((H)->dynindx == -1 \ && !(H)->forced_local \ && (H)->root.type != bfd_link_hash_undefweak \ - && bfd_link_pic (INFO)) + && bfd_link_pic (INFO) \ + && !ABS_SYMBOL_P (H)) /* TRUE if this is a pointer reference to a local IFUNC. */ #define POINTER_LOCAL_IFUNC_P(INFO, H) \ @@ -226,9 +253,6 @@ struct elf_x86_link_hash_entry { struct elf_link_hash_entry elf; - /* Track dynamic relocs copied for this symbol. */ - struct elf_dyn_relocs *dyn_relocs; - unsigned char tls_type; /* Bit 0: Symbol has no GOT nor PLT relocations. @@ -281,15 +305,29 @@ struct elf_x86_link_hash_entry struct elf_x86_lazy_plt_layout { - /* The first entry in an absolute lazy procedure linkage table looks - like this. */ + /* The first entry in a lazy procedure linkage table looks like this. */ const bfd_byte *plt0_entry; - unsigned int plt0_entry_size; /* Size of PLT0 entry. */ + unsigned int plt0_entry_size; /* Size of PLT0 entry. */ - /* Later entries in an absolute lazy procedure linkage table look - like this. */ + /* Later entries in a lazy procedure linkage table look like this. */ const bfd_byte *plt_entry; - unsigned int plt_entry_size; /* Size of each PLT entry. */ + unsigned int plt_entry_size; /* Size of each PLT entry. */ + + /* The TLSDESC entry in a lazy procedure linkage table looks like + this. This is for x86-64 only. */ + const bfd_byte *plt_tlsdesc_entry; + unsigned int plt_tlsdesc_entry_size; /* Size of TLSDESC entry. */ + + /* Offsets into the TLSDESC entry that are to be replaced with + GOT+8 and GOT+TDG. These are for x86-64 only. */ + unsigned int plt_tlsdesc_got1_offset; + unsigned int plt_tlsdesc_got2_offset; + + /* Offset of the end of the PC-relative instructions containing + plt_tlsdesc_got1_offset and plt_tlsdesc_got2_offset. These + are for x86-64 only. */ + unsigned int plt_tlsdesc_got1_insn_end; + unsigned int plt_tlsdesc_got2_insn_end; /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2]. */ @@ -332,13 +370,14 @@ struct elf_x86_lazy_plt_layout struct elf_x86_non_lazy_plt_layout { - /* Entries in an absolute non-lazy procedure linkage table look like - this. */ + /* Entries in a non-lazy procedure linkage table look like this. */ const bfd_byte *plt_entry; - /* Entries in a PIC non-lazy procedure linkage table look like this. */ + /* Entries in a PIC non-lazy procedure linkage table look like this. + This is only used for i386 where absolute PLT and PIC PLT are + different. */ const bfd_byte *pic_plt_entry; - unsigned int plt_entry_size; /* Size of each PLT entry. */ + unsigned int plt_entry_size; /* Size of each PLT entry. */ /* Offsets into plt_entry that are to be replaced with... */ unsigned int plt_got_offset; /* ... address of this symbol in .got. */ @@ -354,13 +393,11 @@ struct elf_x86_non_lazy_plt_layout struct elf_x86_plt_layout { - /* The first entry in a lazy procedure linkage table looks like this. - This is only used for i386 where absolute PLT0 and PIC PLT0 are - different. */ + /* The first entry in a lazy procedure linkage table looks like this. */ const bfd_byte *plt0_entry; /* Entries in a procedure linkage table look like this. */ const bfd_byte *plt_entry; - unsigned int plt_entry_size; /* Size of each PLT entry. */ + unsigned int plt_entry_size; /* Size of each PLT entry. */ /* 1 has PLT0. */ unsigned int has_plt0; @@ -372,6 +409,9 @@ struct elf_x86_plt_layout This is only used for x86-64. */ unsigned int plt_got_insn_size; + /* Alignment of the .iplt section. */ + unsigned int iplt_alignment; + /* .eh_frame covering the .plt section. */ const bfd_byte *eh_frame_plt; unsigned int eh_frame_plt_size; @@ -386,6 +426,7 @@ struct elf_x86_plt_layout #define GOT_TLS_IE_NEG 6 #define GOT_TLS_IE_BOTH 7 #define GOT_TLS_GDESC 8 +#define GOT_ABS 9 #define GOT_TLS_GD_BOTH_P(type) \ ((type) == (GOT_TLS_GD | GOT_TLS_GDESC)) #define GOT_TLS_GD_P(type) \ @@ -398,13 +439,6 @@ struct elf_x86_plt_layout #define elf_x86_hash_entry(ent) \ ((struct elf_x86_link_hash_entry *)(ent)) -enum elf_x86_target_os -{ - is_normal, - is_vxworks, - is_nacl -}; - /* x86 ELF linker hash table. */ struct elf_x86_link_hash_table @@ -437,9 +471,6 @@ struct elf_x86_link_hash_table /* The amount of space used by the jump slots in the GOT. */ bfd_vma sgotplt_jump_table_size; - /* Small local sym cache. */ - struct sym_cache sym_cache; - /* _TLS_MODULE_BASE_ symbol. */ struct bfd_link_hash_entry *tls_module_base; @@ -447,19 +478,11 @@ struct elf_x86_link_hash_table htab_t loc_hash_table; void * loc_hash_memory; - /* The offset into sgot of the GOT entry used by the PLT entry - above. */ - bfd_vma tlsdesc_got; - /* The index of the next R_X86_64_JUMP_SLOT entry in .rela.plt. */ bfd_vma next_jump_slot_index; /* The index of the next R_X86_64_IRELATIVE entry in .rela.plt. */ bfd_vma next_irelative_index; - /* TRUE if there are dynamic relocs against IFUNC symbols that apply - to read-only sections. */ - bfd_boolean readonly_dynrelocs_against_ifunc; - /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. This is used for i386 only. */ asection *srelplt2; @@ -468,44 +491,35 @@ struct elf_x86_link_hash_table is only used for i386. */ bfd_vma next_tls_desc_index; - /* The offset into splt of the PLT entry for the TLS descriptor - resolver. Special values are 0, if not necessary (or not found - to be necessary yet), and -1 if needed but not determined - yet. This is only used for x86-64. */ - bfd_vma tlsdesc_plt; - /* Value used to fill the unused bytes of the first PLT entry. This is only used for i386. */ bfd_byte plt0_pad_byte; + /* TRUE if GOT is referenced. */ + unsigned int got_referenced : 1; + + /* TRUE if PLT is PC-relative. PLT in PDE and PC-relative PLT in PIE + can be used as function address. + + NB: i386 has non-PIC PLT and PIC PLT. Only non-PIC PLT in PDE can + be used as function address. PIC PLT in PIE can't be used as + function address. */ + unsigned int pcrel_plt : 1; + bfd_vma (*r_info) (bfd_vma, bfd_vma); bfd_vma (*r_sym) (bfd_vma); - bfd_boolean (*is_reloc_section) (const char *); - enum elf_target_id target_id; - enum elf_x86_target_os target_os; + bool (*is_reloc_section) (const char *); unsigned int sizeof_reloc; - unsigned int dt_reloc; - unsigned int dt_reloc_sz; - unsigned int dt_reloc_ent; unsigned int got_entry_size; unsigned int pointer_r_type; int dynamic_interpreter_size; const char *dynamic_interpreter; const char *tls_get_addr; -}; - -/* Architecture-specific backend data for x86. */ -struct elf_x86_backend_data -{ - /* Target system. */ - enum elf_x86_target_os target_os; + /* Options passed from the linker. */ + struct elf_linker_x86_params *params; }; -#define get_elf_x86_backend_data(abfd) \ - ((const struct elf_x86_backend_data *) \ - get_elf_backend_data (abfd)->arch_data) - struct elf_x86_init_table { /* The lazy PLT layout. */ @@ -558,6 +572,9 @@ struct elf_x86_plt long count; }; +/* Set if a relocation is converted from a GOTPCREL relocation. */ +#define R_X86_64_converted_reloc_bit (1 << 7) + #define elf_x86_tdata(abfd) \ ((struct elf_x86_obj_tdata *) (abfd)->tdata.any) @@ -573,9 +590,9 @@ struct elf_x86_plt #define is_x86_elf(bfd, htab) \ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ && elf_tdata (bfd) != NULL \ - && elf_object_id (bfd) == (htab)->target_id) + && elf_object_id (bfd) == (htab)->elf.hash_table_id) -extern bfd_boolean _bfd_x86_elf_mkobject +extern bool _bfd_x86_elf_mkobject (bfd *); extern void _bfd_x86_elf_set_tls_module_base @@ -584,12 +601,12 @@ extern void _bfd_x86_elf_set_tls_module_base extern bfd_vma _bfd_x86_elf_dtpoff_base (struct bfd_link_info *); -extern bfd_boolean _bfd_x86_elf_readonly_dynrelocs +extern bool _bfd_x86_elf_readonly_dynrelocs (struct elf_link_hash_entry *, void *); extern struct elf_link_hash_entry * _bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *, bfd *, const Elf_Internal_Rela *, - bfd_boolean); + bool); extern hashval_t _bfd_x86_elf_local_htab_hash (const void *); @@ -606,39 +623,43 @@ extern struct bfd_link_hash_table * _bfd_x86_elf_link_hash_table_create extern int _bfd_x86_elf_compare_relocs (const void *, const void *); -extern bfd_boolean _bfd_x86_elf_link_check_relocs +extern bool _bfd_x86_elf_link_check_relocs (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_x86_elf_size_dynamic_sections +extern bool _bfd_elf_x86_valid_reloc_p + (asection *, struct bfd_link_info *, struct elf_x86_link_hash_table *, + const Elf_Internal_Rela *, struct elf_link_hash_entry *, + Elf_Internal_Sym *, Elf_Internal_Shdr *, bool *); + +extern bool _bfd_x86_elf_size_dynamic_sections (bfd *, struct bfd_link_info *); extern struct elf_x86_link_hash_table *_bfd_x86_elf_finish_dynamic_sections (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_x86_elf_always_size_sections +extern bool _bfd_x86_elf_always_size_sections (bfd *, struct bfd_link_info *); extern void _bfd_x86_elf_merge_symbol_attribute - (struct elf_link_hash_entry *, const Elf_Internal_Sym *, - bfd_boolean, bfd_boolean); + (struct elf_link_hash_entry *, unsigned int, bool, bool); extern void _bfd_x86_elf_copy_indirect_symbol (struct bfd_link_info *, struct elf_link_hash_entry *, struct elf_link_hash_entry *); -extern bfd_boolean _bfd_x86_elf_fixup_symbol +extern bool _bfd_x86_elf_fixup_symbol (struct bfd_link_info *, struct elf_link_hash_entry *); -extern bfd_boolean _bfd_x86_elf_hash_symbol +extern bool _bfd_x86_elf_hash_symbol (struct elf_link_hash_entry *); -extern bfd_boolean _bfd_x86_elf_adjust_dynamic_symbol +extern bool _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *, struct elf_link_hash_entry *); extern void _bfd_x86_elf_hide_symbol - (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean); + (struct bfd_link_info *, struct elf_link_hash_entry *, bool); -extern bfd_boolean _bfd_x86_elf_link_symbol_references_local +extern bool _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *, struct elf_link_hash_entry *); extern asection * _bfd_x86_elf_gc_mark_hook @@ -652,12 +673,23 @@ extern long _bfd_x86_elf_get_synthetic_symtab extern enum elf_property_kind _bfd_x86_elf_parse_gnu_properties (bfd *, unsigned int, bfd_byte *, unsigned int); -extern bfd_boolean _bfd_x86_elf_merge_gnu_properties - (struct bfd_link_info *, bfd *, elf_property *, elf_property *); +extern bool _bfd_x86_elf_merge_gnu_properties + (struct bfd_link_info *, bfd *, bfd *, elf_property *, elf_property *); + +extern void _bfd_x86_elf_link_fixup_gnu_properties + (struct bfd_link_info *, elf_property_list **); extern bfd * _bfd_x86_elf_link_setup_gnu_properties (struct bfd_link_info *, struct elf_x86_init_table *); +extern void _bfd_x86_elf_link_fixup_ifunc_symbol + (struct bfd_link_info *, struct elf_x86_link_hash_table *, + struct elf_link_hash_entry *, Elf_Internal_Sym *sym); + +extern void _bfd_x86_elf_link_report_relative_reloc + (struct bfd_link_info *, asection *, struct elf_link_hash_entry *, + Elf_Internal_Sym *, const char *, const void *); + #define bfd_elf64_mkobject \ _bfd_x86_elf_mkobject #define bfd_elf32_mkobject \ @@ -688,8 +720,10 @@ extern bfd * _bfd_x86_elf_link_setup_gnu_properties #define elf_backend_gc_mark_hook \ _bfd_x86_elf_gc_mark_hook #define elf_backend_omit_section_dynsym \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) + _bfd_elf_omit_section_dynsym_all #define elf_backend_parse_gnu_properties \ _bfd_x86_elf_parse_gnu_properties #define elf_backend_merge_gnu_properties \ _bfd_x86_elf_merge_gnu_properties +#define elf_backend_fixup_gnu_properties \ + _bfd_x86_elf_link_fixup_gnu_properties