diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-09-01 08:00:36 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-09-01 08:00:51 -0700 |
commit | a6798baba212170e427d2f9bd99af12f1078b162 (patch) | |
tree | 5dfcb207d647aff488599dccbac51f25241e4d8b /bfd/elf32-i386.c | |
parent | 376dc015f275575e0aa7be9c46476db5506ff836 (diff) | |
download | gdb-a6798baba212170e427d2f9bd99af12f1078b162.zip gdb-a6798baba212170e427d2f9bd99af12f1078b162.tar.gz gdb-a6798baba212170e427d2f9bd99af12f1078b162.tar.bz2 |
x86: Add _bfd_x86_elf_link_setup_gnu_properties
Extract the common parts of elf_i386_link_setup_gnu_properties and
elf_x86_64_link_setup_gnu_properties into a new function.
For x86-64, since PIC PLT layouts are the same as non-PIC PLT layouts,
initialize pic_plt0_entry and pic_plt_entry fields in PLT layouts with
the non-PIC PLT entries.
* elf32-i386.c (elf_i386_link_setup_gnu_properties): Updated.
Call _bfd_x86_elf_link_setup_gnu_properties.
* elf64-x86-64.c (elf_x86_lazy_plt_layout): Initialize
pic_plt0_entry and pic_plt_entry fields with the non-PIC PLT
entries.
(elf_x86_64_non_lazy_plt): Likewise.
(elf_x86_64_lazy_bnd_plt): Likewise.
(elf_x86_64_non_lazy_bnd_plt): Likewise.
(elf_x86_64_lazy_ibt_plt): Likewise.
(elf_x32_lazy_ibt_plt): Likewise.
(elf_x86_64_non_lazy_ibt_plt): Likewise.
(elf_x32_non_lazy_ibt_plt): Likewise.
(elf_x86_64_nacl_plt): Likewise.
(elf_x86_64_link_setup_gnu_properties): Updated. Call
_bfd_x86_elf_link_setup_gnu_properties.
* elfxx-x86.c: Include elf-vxworks.h".
(_bfd_x86_elf_link_setup_gnu_properties): New function.
* elfxx-x86.h (elf_x86_lazy_plt_layout): Remove "for i386 only"
comments for pic_plt0_entry and pic_plt_entry.
(elf_x86_non_lazy_plt_layout): Likewise.
(elf_x86_plt_layout_table): New.
(_bfd_x86_elf_link_setup_gnu_properties): Likewise.
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 355 |
1 files changed, 18 insertions, 337 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index a983301..a0d4285 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -5825,354 +5825,35 @@ elf_i386_get_synthetic_symtab (bfd *abfd, static bfd * elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) { - bfd_boolean normal_target; - bfd_boolean lazy_plt; - asection *sec, *pltsec; - bfd *dynobj; - bfd_boolean use_ibt_plt; - unsigned int plt_alignment, features; - struct elf_x86_link_hash_table *htab; - bfd *pbfd; - bfd *ebfd = NULL; - elf_property *prop; - - 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; - pbfd = pbfd->link.next) - if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour - && bfd_count_sections (pbfd) != 0) - { - ebfd = pbfd; - - if (elf_properties (pbfd) != NULL) - break; - } - - if (ebfd != NULL && features) - { - /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and - GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ - prop = _bfd_elf_get_property (ebfd, - GNU_PROPERTY_X86_FEATURE_1_AND, - 4); - prop->u.number |= features; - prop->pr_kind = property_number; - - /* Create the GNU property note section if needed. */ - if (pbfd == NULL) - { - sec = bfd_make_section_with_flags (ebfd, - NOTE_GNU_PROPERTY_SECTION_NAME, - (SEC_ALLOC - | SEC_LOAD - | SEC_IN_MEMORY - | SEC_READONLY - | SEC_HAS_CONTENTS - | SEC_DATA)); - if (sec == NULL) - info->callbacks->einfo (_("%F: failed to create GNU property section\n")); - - if (!bfd_set_section_alignment (ebfd, sec, 2)) - { -error_alignment: - info->callbacks->einfo (_("%F%A: failed to align section\n"), - sec); - } - - elf_section_type (sec) = SHT_NOTE; - } - } - - pbfd = _bfd_elf_link_setup_gnu_properties (info); - - if (bfd_link_relocatable (info)) - return pbfd; - - htab = elf_x86_hash_table (info, I386_ELF_DATA); - if (htab == NULL) - return pbfd; - - use_ibt_plt = info->ibtplt || info->ibt; - if (!use_ibt_plt && pbfd != NULL) - { - /* Check if GNU_PROPERTY_X86_FEATURE_1_IBT is on. */ - elf_property_list *p; - - /* The property list is sorted in order of type. */ - for (p = elf_properties (pbfd); p; p = p->next) - { - if (GNU_PROPERTY_X86_FEATURE_1_AND == p->property.pr_type) - { - use_ibt_plt = !!(p->property.u.number - & GNU_PROPERTY_X86_FEATURE_1_IBT); - break; - } - else if (GNU_PROPERTY_X86_FEATURE_1_AND < p->property.pr_type) - break; - } - } - - dynobj = htab->elf.dynobj; - - /* Set htab->elf.dynobj here so that there is no need to check and - set it in check_relocs. */ - if (dynobj == NULL) - { - if (pbfd != NULL) - { - htab->elf.dynobj = pbfd; - dynobj = pbfd; - } - else - { - bfd *abfd; - - /* Find a normal input file to hold linker created - sections. */ - for (abfd = info->input_bfds; - abfd != NULL; - abfd = abfd->link.next) - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour - && (abfd->flags - & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0) - { - htab->elf.dynobj = abfd; - dynobj = abfd; - break; - } - } - } - - /* Even when lazy binding is disabled by "-z now", the PLT0 entry may - still be used with LD_AUDIT or LD_PROFILE if PLT entry is used for - canonical function address. */ - htab->plt.has_plt0 = 1; - normal_target = FALSE; + struct elf_x86_plt_layout_table plt_layout; + plt_layout.normal_target = FALSE; + plt_layout.is_vxworks = FALSE; switch (get_elf_i386_backend_data (info->output_bfd)->os) { case is_normal: - if (use_ibt_plt) - { - htab->lazy_plt = &elf_i386_lazy_ibt_plt; - htab->non_lazy_plt = &elf_i386_non_lazy_ibt_plt; - } - else - { - htab->lazy_plt = &elf_i386_lazy_plt; - htab->non_lazy_plt = &elf_i386_non_lazy_plt; - } - normal_target = TRUE; + plt_layout.lazy_plt = &elf_i386_lazy_plt; + plt_layout.non_lazy_plt = &elf_i386_non_lazy_plt; + plt_layout.lazy_ibt_plt = &elf_i386_lazy_ibt_plt; + plt_layout.non_lazy_ibt_plt = &elf_i386_non_lazy_ibt_plt; + plt_layout.normal_target = TRUE; break; case is_vxworks: - htab->lazy_plt = &elf_i386_lazy_plt; - htab->non_lazy_plt = NULL; - if (!elf_vxworks_create_dynamic_sections (dynobj, info, - &htab->srelplt2)) - info->callbacks->einfo (_("%F: failed to create VxWorks dynamic sections\n")); + plt_layout.lazy_plt = &elf_i386_lazy_plt; + plt_layout.non_lazy_plt = NULL; + plt_layout.lazy_ibt_plt = NULL; + plt_layout.non_lazy_ibt_plt = NULL; + plt_layout.is_vxworks = TRUE; break; case is_nacl: - htab->lazy_plt = &elf_i386_nacl_plt; - htab->non_lazy_plt = NULL; + plt_layout.lazy_plt = &elf_i386_nacl_plt; + plt_layout.non_lazy_plt = NULL; + plt_layout.lazy_ibt_plt = NULL; + plt_layout.non_lazy_ibt_plt = NULL; break; } - pltsec = htab->elf.splt; - - /* If the non-lazy PLT is available, use it for all PLT entries if - there are no PLT0 or no .plt section. */ - if (htab->non_lazy_plt != NULL - && (!htab->plt.has_plt0 || pltsec == NULL)) - { - lazy_plt = FALSE; - if (bfd_link_pic (info)) - htab->plt.plt_entry = htab->non_lazy_plt->pic_plt_entry; - else - htab->plt.plt_entry = htab->non_lazy_plt->plt_entry; - htab->plt.plt_entry_size = htab->non_lazy_plt->plt_entry_size; - htab->plt.plt_got_offset = htab->non_lazy_plt->plt_got_offset; - htab->plt.eh_frame_plt_size - = htab->non_lazy_plt->eh_frame_plt_size; - htab->plt.eh_frame_plt = htab->non_lazy_plt->eh_frame_plt; - } - else - { - lazy_plt = TRUE; - if (bfd_link_pic (info)) - { - htab->plt.plt0_entry = htab->lazy_plt->pic_plt0_entry; - htab->plt.plt_entry = htab->lazy_plt->pic_plt_entry; - } - else - { - htab->plt.plt0_entry = htab->lazy_plt->plt0_entry; - htab->plt.plt_entry = htab->lazy_plt->plt_entry; - } - - htab->plt.plt_entry_size = htab->lazy_plt->plt_entry_size; - htab->plt.plt_got_offset = htab->lazy_plt->plt_got_offset; - htab->plt.eh_frame_plt_size = htab->lazy_plt->eh_frame_plt_size; - htab->plt.eh_frame_plt = htab->lazy_plt->eh_frame_plt; - } - - /* This is unused for i386. */ - htab->plt.plt_got_insn_size = 0; - - /* Return if there are no normal input files. */ - if (dynobj == NULL) - return pbfd; - - /* Since create_dynamic_sections isn't always called, but GOT - relocations need GOT sections, create them here so that we - don't need to do it in check_relocs. */ - if (htab->elf.sgot == NULL - && !_bfd_elf_create_got_section (dynobj, info)) - info->callbacks->einfo (_("%F: failed to create GOT sections\n")); - - /* Create the ifunc sections here so that check_relocs can be - simplified. */ - if (!_bfd_elf_create_ifunc_sections (dynobj, info)) - info->callbacks->einfo (_("%F: failed to create ifunc sections\n")); - - plt_alignment = bfd_log2 (htab->plt.plt_entry_size); - - if (pltsec != NULL) - { - /* Whe creating executable, set the contents of the .interp - section to the interpreter. */ - if (bfd_link_executable (info) && !info->nointerp) - { - asection *s = bfd_get_linker_section (dynobj, ".interp"); - if (s == NULL) - abort (); - s->size = htab->dynamic_interpreter_size; - s->contents = (unsigned char *) htab->dynamic_interpreter; - htab->interp = s; - } - - /* Don't change PLT section alignment for NaCl since it uses - 64-byte PLT entry and sets PLT section alignment to 32 - bytes. */ - if (normal_target) - { - const struct elf_backend_data *bed - = get_elf_backend_data (dynobj); - flagword pltflags = (bed->dynamic_sec_flags - | SEC_ALLOC - | SEC_CODE - | SEC_LOAD - | SEC_READONLY); - unsigned int non_lazy_plt_alignment - = bfd_log2 (htab->non_lazy_plt->plt_entry_size); - - sec = pltsec; - if (!bfd_set_section_alignment (sec->owner, sec, - plt_alignment)) - goto error_alignment; - - /* Create the GOT procedure linkage table. */ - sec = bfd_make_section_anyway_with_flags (dynobj, - ".plt.got", - pltflags); - if (sec == NULL) - info->callbacks->einfo (_("%F: failed to create GOT PLT section\n")); - - if (!bfd_set_section_alignment (dynobj, sec, - non_lazy_plt_alignment)) - goto error_alignment; - - htab->plt_got = sec; - - if (lazy_plt) - { - sec = NULL; - - if (use_ibt_plt) - { - /* Create the second PLT for Intel IBT support. IBT - PLT is supported only for non-NaCl target and is - is needed only for lazy binding. */ - sec = bfd_make_section_anyway_with_flags (dynobj, - ".plt.sec", - pltflags); - if (sec == NULL) - info->callbacks->einfo (_("%F: failed to create IBT-enabled PLT section\n")); - - if (!bfd_set_section_alignment (dynobj, sec, - plt_alignment)) - goto error_alignment; - } - - htab->plt_second = sec; - } - } - - if (!info->no_ld_generated_unwind_info) - { - flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY - | SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_LINKER_CREATED); - - sec = bfd_make_section_anyway_with_flags (dynobj, - ".eh_frame", - flags); - if (sec == NULL) - info->callbacks->einfo (_("%F: failed to create PLT .eh_frame section\n")); - - if (!bfd_set_section_alignment (dynobj, sec, 2)) - goto error_alignment; - - htab->plt_eh_frame = sec; - - if (htab->plt_got != NULL) - { - sec = bfd_make_section_anyway_with_flags (dynobj, - ".eh_frame", - flags); - if (sec == NULL) - info->callbacks->einfo (_("%F: failed to create GOT PLT .eh_frame section\n")); - - if (!bfd_set_section_alignment (dynobj, sec, 2)) - goto error_alignment; - - htab->plt_got_eh_frame = sec; - } - - if (htab->plt_second != NULL) - { - sec = bfd_make_section_anyway_with_flags (dynobj, - ".eh_frame", - flags); - if (sec == NULL) - info->callbacks->einfo (_("%F: failed to create the second PLT .eh_frame section\n")); - - if (!bfd_set_section_alignment (dynobj, sec, 2)) - goto error_alignment; - - htab->plt_second_eh_frame = sec; - } - } - } - - if (normal_target) - { - /* The .iplt section is used for IFUNC symbols in static - executables. */ - sec = htab->elf.iplt; - if (sec != NULL - && !bfd_set_section_alignment (sec->owner, sec, - plt_alignment)) - goto error_alignment; - } - - return pbfd; + return _bfd_x86_elf_link_setup_gnu_properties (info, &plt_layout); } #define TARGET_LITTLE_SYM i386_elf32_vec |