diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 15 | ||||
-rw-r--r-- | bfd/elf-linker-x86.h | 47 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 4 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 16 | ||||
-rw-r--r-- | bfd/elfxx-x86.c | 42 | ||||
-rw-r--r-- | bfd/elfxx-x86.h | 4 |
6 files changed, 109 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7953c84..72156b9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2019-04-06 H.J. Lu <hongjiu.lu@intel.com> + + * elf-linker-x86.h: New file. + * elf32-i386.c (elf_i386_convert_load_reloc): Use htab->params + to get x86-specific linker options. + * elf64-x86-64.c (elf_x86_64_convert_load_reloc): Likewise. + (elf_x86_64_check_relocs): Likewise. + (elf_x86_64_relocate_section): Likewise. + (elf_x86_64_link_setup_gnu_properties): Likewise. + * elfxx-x86.c (_bfd_x86_elf_merge_gnu_properties): Likewise. + (_bfd_x86_elf_link_setup_gnu_properties): Likewise. + (_bfd_elf_linker_x86_set_options): New function. + * elfxx-x86.h: Include "elf-linker-x86.h". + (elf_x86_link_hash_table): Add params. + 2019-04-03 Alan Modra <amodra@gmail.com> * coff-i386.c, * coff-x86_64.c, * coffgen.c, * dwarf2.c, diff --git a/bfd/elf-linker-x86.h b/bfd/elf-linker-x86.h new file mode 100644 index 0000000..bd14b71 --- /dev/null +++ b/bfd/elf-linker-x86.h @@ -0,0 +1,47 @@ +/* x86-specific ELF linker support between ld and bfd. + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* Used to pass x86-specific linker options from ld to bfd. */ +struct elf_linker_x86_params +{ + /* TRUE if BND prefix in PLT entries is always generated. */ + unsigned int bndplt: 1; + + /* TRUE if IBT-enabled PLT entries should be generated. */ + unsigned int ibtplt: 1; + + /* TRUE if GNU_PROPERTY_X86_FEATURE_1_IBT should be generated. */ + unsigned int ibt: 1; + + /* TRUE if GNU_PROPERTY_X86_FEATURE_1_SHSTK should be generated. */ + unsigned int shstk: 1; + + /* TRUE if we shouldn't check relocation overflow. */ + unsigned int no_reloc_overflow_check: 1; + + /* TRUE if generate a 1-byte NOP as suffix for x86 call instruction. */ + unsigned int call_nop_as_suffix : 1; + + /* The 1-byte NOP for x86 call instruction. */ + char call_nop_byte; +}; + +extern void _bfd_elf_linker_x86_set_options + (struct bfd_link_info *, struct elf_linker_x86_params *); diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 79cd8c6..5d3f2eb 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1343,8 +1343,8 @@ convert_branch: } else { - nop = link_info->call_nop_byte; - if (link_info->call_nop_as_suffix) + nop = htab->params->call_nop_byte; + if (htab->params->call_nop_as_suffix) { nop_offset = roff + 3; irel->r_offset -= 1; diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index ecd4c6d..6790228 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1676,8 +1676,8 @@ convert: } else { - nop = link_info->call_nop_byte; - if (link_info->call_nop_as_suffix) + nop = htab->params->call_nop_byte; + if (htab->params->call_nop_as_suffix) { nop_offset = irel->r_offset + 3; disp = bfd_get_32 (abfd, contents + irel->r_offset); @@ -2149,7 +2149,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, run-time relocation overflow. Don't error out for sections we don't care about, such as debug sections or when relocation overflow check is disabled. */ - if (!info->no_reloc_overflow_check + if (!htab->params->no_reloc_overflow_check && !converted_reloc && (bfd_link_pic (info) || (bfd_link_executable (info) @@ -3206,7 +3206,7 @@ direct: convert R_X86_64_32 to dynamic R_X86_64_RELATIVE. */ if (r_type == htab->pointer_r_type || (r_type == R_X86_64_32 - && info->no_reloc_overflow_check)) + && htab->params->no_reloc_overflow_check)) { relocate = TRUE; outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); @@ -5048,7 +5048,13 @@ elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info) if (get_elf_x86_backend_data (info->output_bfd)->target_os != is_nacl) { - if (info->bndplt) + const struct elf_backend_data *bed + = get_elf_backend_data (info->output_bfd); + struct elf_x86_link_hash_table *htab + = elf_x86_hash_table (info, bed->target_id); + if (!htab) + abort (); + if (htab->params->bndplt) { init_table.lazy_plt = &elf_x86_64_lazy_bnd_plt; init_table.non_lazy_plt = &elf_x86_64_non_lazy_bnd_plt; diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 5703b5f..8d08a69 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -2479,12 +2479,18 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, 2. If APROP is NULL, remove x86 feature. 3. Otherwise, do nothing. */ + const struct elf_backend_data *bed + = get_elf_backend_data (info->output_bfd); + struct elf_x86_link_hash_table *htab + = elf_x86_hash_table (info, bed->target_id); + if (!htab) + abort (); if (aprop != NULL && bprop != NULL) { features = 0; - if (info->ibt) + if (htab->params->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; - if (info->shstk) + if (htab->params->shstk) features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; number = aprop->u.number; /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and @@ -2501,9 +2507,9 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info, have them. Set IBT and SHSTK properties for -z ibt and -z shstk if needed. */ features = 0; - if (info->ibt) + if (htab->params->ibt) features = GNU_PROPERTY_X86_FEATURE_1_IBT; - if (info->shstk) + if (htab->params->shstk) features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; if (features) { @@ -2556,12 +2562,6 @@ _bfd_x86_elf_link_setup_gnu_properties unsigned int class_align = ABI_64_P (info->output_bfd) ? 3 : 2; unsigned int got_align; - features = 0; - if (info->ibt) - features = GNU_PROPERTY_X86_FEATURE_1_IBT; - if (info->shstk) - features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; - /* Find a normal input file with GNU property note. */ for (pbfd = info->input_bfds; pbfd != NULL; @@ -2581,6 +2581,12 @@ _bfd_x86_elf_link_setup_gnu_properties if (htab == NULL) return pbfd; + features = 0; + if (htab->params->ibt) + features = GNU_PROPERTY_X86_FEATURE_1_IBT; + if (htab->params->shstk) + features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK; + if (ebfd != NULL) { prop = NULL; @@ -2630,7 +2636,7 @@ error_alignment: htab->plt0_pad_byte = init_table->plt0_pad_byte; - use_ibt_plt = info->ibtplt || info->ibt; + use_ibt_plt = htab->params->ibtplt || htab->params->ibt; if (!use_ibt_plt && pbfd != NULL) { /* Check if GNU_PROPERTY_X86_FEATURE_1_IBT is on. */ @@ -2853,7 +2859,7 @@ error_alignment: plt_alignment)) goto error_alignment; } - else if (info->bndplt && ABI_64_P (dynobj)) + else if (htab->params->bndplt && ABI_64_P (dynobj)) { /* Create the second PLT for Intel MPX support. MPX PLT is supported only for non-NaCl target in 64-bit @@ -2984,3 +2990,15 @@ _bfd_x86_elf_link_fixup_gnu_properties } } } + +void +_bfd_elf_linker_x86_set_options (struct bfd_link_info * info, + struct elf_linker_x86_params *params) +{ + const struct elf_backend_data *bed + = get_elf_backend_data (info->output_bfd); + struct elf_x86_link_hash_table *htab + = elf_x86_hash_table (info, bed->target_id); + if (htab != NULL) + htab->params = params; +} diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 4df2173..013ac4b 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -24,6 +24,7 @@ #include "libbfd.h" #include "elf-bfd.h" #include "hashtab.h" +#include "elf-linker-x86.h" #define PLT_CIE_LENGTH 20 #define PLT_FDE_LENGTH 36 @@ -530,6 +531,9 @@ struct elf_x86_link_hash_table int dynamic_interpreter_size; const char *dynamic_interpreter; const char *tls_get_addr; + + /* Options passed from the linker. */ + struct elf_linker_x86_params *params; }; /* Architecture-specific backend data for x86. */ |