aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-i386.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-09-01 08:00:36 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-09-01 08:00:51 -0700
commita6798baba212170e427d2f9bd99af12f1078b162 (patch)
tree5dfcb207d647aff488599dccbac51f25241e4d8b /bfd/elf32-i386.c
parent376dc015f275575e0aa7be9c46476db5506ff836 (diff)
downloadgdb-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.c355
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