asection *interp;
asection *plt_eh_frame;
asection *plt_bnd;
+ asection *plt_bnd_eh_frame;
asection *plt_got;
asection *plt_got_eh_frame;
/* MPX PLT is supported only if elf_x86_64_arch_bed
is used in 64-bit mode. */
if (ABI_64_P (abfd)
- && info->bndplt
- && (get_elf_x86_64_backend_data (abfd)
- == &elf_x86_64_arch_bed))
+ && info->bndplt
+ && (get_elf_x86_64_backend_data (abfd)
+ == &elf_x86_64_arch_bed))
{
elf_x86_64_hash_entry (h)->has_bnd_reloc = 1;
/* Create the second PLT for Intel MPX support. */
if (htab->plt_bnd == NULL)
{
- unsigned int plt_bnd_align;
const struct elf_backend_data *bed;
bed = get_elf_backend_data (info->output_bfd);
BFD_ASSERT (sizeof (elf_x86_64_bnd_plt2_entry) == 8
&& (sizeof (elf_x86_64_bnd_plt2_entry)
== sizeof (elf_x86_64_legacy_plt2_entry)));
- plt_bnd_align = 3;
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
if (htab->plt_bnd == NULL
|| !bfd_set_section_alignment (htab->elf.dynobj,
htab->plt_bnd,
- plt_bnd_align))
+ 3))
+ goto error_return;
+ }
+
+ if (!info->no_ld_generated_unwind_info
+ && htab->plt_bnd_eh_frame == NULL)
+ {
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ htab->plt_bnd_eh_frame
+ = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
+ ".eh_frame",
+ flags);
+ if (htab->plt_bnd_eh_frame == NULL
+ || !bfd_set_section_alignment (htab->elf.dynobj,
+ htab->plt_bnd_eh_frame,
+ 3))
goto error_return;
}
}
bfd_boolean relocs;
bfd *ibfd;
const struct elf_backend_data *bed;
+ const struct elf_x86_64_backend_data *arch_data;
htab = elf_x86_64_hash_table (info);
if (htab == NULL)
htab->elf.sgotplt->size = 0;
}
+ arch_data = (htab->plt_bnd != NULL
+ ? &elf_x86_64_bnd_arch_bed
+ : get_elf_x86_64_arch_data (bed));
+
if (_bfd_elf_eh_frame_present (info))
{
if (htab->plt_eh_frame != NULL
&& htab->elf.splt != NULL
&& htab->elf.splt->size != 0
&& !bfd_is_abs_section (htab->elf.splt->output_section))
- {
- /* Unwind info for the BND PLT and the normal PLT have the
- same time. */
- const struct elf_x86_64_backend_data *arch_data
- = get_elf_x86_64_arch_data (bed);
- htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
- }
+ htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
if (htab->plt_got_eh_frame != NULL
&& htab->plt_got != NULL
&& htab->plt_got->size != 0
&& !bfd_is_abs_section (htab->plt_got->output_section))
- {
- const struct elf_x86_64_backend_data *arch_data
- = get_elf_x86_64_arch_data (bed);
- htab->plt_got_eh_frame->size
- = arch_data->eh_frame_plt_got_size;
- }
+ htab->plt_got_eh_frame->size = arch_data->eh_frame_plt_got_size;
+
+ /* Unwind info for .plt.bnd and .plt.got sections are
+ identical. */
+ if (htab->plt_bnd_eh_frame != NULL
+ && htab->plt_bnd != NULL
+ && htab->plt_bnd->size != 0
+ && !bfd_is_abs_section (htab->plt_bnd->output_section))
+ htab->plt_bnd_eh_frame->size = arch_data->eh_frame_plt_got_size;
}
/* We now have determined the sizes of the various dynamic sections.
|| s == htab->plt_got
|| s == htab->plt_eh_frame
|| s == htab->plt_got_eh_frame
+ || s == htab->plt_bnd_eh_frame
|| s == htab->elf.sdynbss
|| s == htab->elf.sdynrelro)
{
if (htab->plt_eh_frame != NULL
&& htab->plt_eh_frame->contents != NULL)
{
- /* Unwind info for the BND PLT and the normal PLT have the same
- size, but different contents. */
- const struct elf_x86_64_backend_data *arch_data
- = (htab->plt_bnd != NULL
- ? &elf_x86_64_bnd_arch_bed
- : get_elf_x86_64_arch_data (bed));
-
memcpy (htab->plt_eh_frame->contents,
arch_data->eh_frame_plt, htab->plt_eh_frame->size);
bfd_put_32 (dynobj, htab->elf.splt->size,
if (htab->plt_got_eh_frame != NULL
&& htab->plt_got_eh_frame->contents != NULL)
{
- /* Unwind info for .plt.bnd and .plt.got sections are identical. */
- const struct elf_x86_64_backend_data *arch_data
- = get_elf_x86_64_arch_data (bed);
-
memcpy (htab->plt_got_eh_frame->contents,
arch_data->eh_frame_plt_got,
htab->plt_got_eh_frame->size);
+ PLT_FDE_LEN_OFFSET));
}
+ if (htab->plt_bnd_eh_frame != NULL
+ && htab->plt_bnd_eh_frame->contents != NULL)
+ {
+ memcpy (htab->plt_bnd_eh_frame->contents,
+ arch_data->eh_frame_plt_got,
+ htab->plt_bnd_eh_frame->size);
+ bfd_put_32 (dynobj, htab->plt_bnd->size,
+ (htab->plt_bnd_eh_frame->contents
+ + PLT_FDE_LEN_OFFSET));
+ }
+
if (htab->elf.dynamic_sections_created)
{
/* Add some entries to the .dynamic section. We fill in the
+ h->root.u.def.section->output_offset);
rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY);
rela.r_addend = 0;
- if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+ if (h->root.u.def.section == htab->elf.sdynrelro)
s = htab->elf.sreldynrelro;
else
s = htab->elf.srelbss;
}
}
+ /* Adjust .eh_frame for .plt.bnd section. */
+ if (htab->plt_bnd_eh_frame != NULL
+ && htab->plt_bnd_eh_frame->contents != NULL)
+ {
+ if (htab->plt_bnd != NULL
+ && htab->plt_bnd->size != 0
+ && (htab->plt_bnd->flags & SEC_EXCLUDE) == 0
+ && htab->plt_bnd->output_section != NULL
+ && htab->plt_bnd_eh_frame->output_section != NULL)
+ {
+ bfd_vma plt_start = htab->plt_bnd->output_section->vma;
+ bfd_vma eh_frame_start = htab->plt_bnd_eh_frame->output_section->vma
+ + htab->plt_bnd_eh_frame->output_offset
+ + PLT_FDE_START_OFFSET;
+ bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
+ htab->plt_bnd_eh_frame->contents
+ + PLT_FDE_START_OFFSET);
+ }
+ if (htab->plt_bnd_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
+ {
+ if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
+ htab->plt_bnd_eh_frame,
+ htab->plt_bnd_eh_frame->contents))
+ return FALSE;
+ }
+ }
+
if (htab->elf.sgot && htab->elf.sgot->size > 0)
elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
= GOT_ENTRY_SIZE;