aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-01-12 10:30:56 -0800
committerH.J. Lu <hjl.tools@gmail.com>2017-01-12 10:32:17 -0800
commit8361ed4d6b7049264153434e8dc15e6dc2200ebf (patch)
tree12ec4f05453db4b68a7136a96375ee2b96dacf4a /bfd
parent2425a30e406a0523020b7e70abb864a06a45bb97 (diff)
downloadgdb-8361ed4d6b7049264153434e8dc15e6dc2200ebf.zip
gdb-8361ed4d6b7049264153434e8dc15e6dc2200ebf.tar.gz
gdb-8361ed4d6b7049264153434e8dc15e6dc2200ebf.tar.bz2
x86-64: Also generate unwind info for .plt.bnd
Also generate unwind info for the .plt.bnd section. Sine it is the same as unwind info for the .plt.got section, we use unwind info for the .plt.got section to cover the the .plt.bnd section. bfd/ PR ld/21038 * elf64-x86-64.c (elf_x86_64_link_hash_table): Add plt_bnd_eh_frame. (elf_x86_64_check_relocs): Create .eh_frame section for the .plt.bnd section. (elf_x86_64_size_dynamic_sections): Allocate and initialize .eh_frame section for the .plt.bnd section. (elf_x86_64_finish_dynamic_sections): Adjust .eh_frame section for the .plt.bnd section. ld/ PR ld/21038 * testsuite/ld-x86-64/pr21038b.d: Updated. * testsuite/ld-x86-64/pr21038c.d: New file. * testsuite/ld-x86-64/pr21038c.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run pr21038c.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/elf64-x86-64.c106
2 files changed, 88 insertions, 30 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 6705ae4..ef7d68c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2017-01-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/21038
+ * elf64-x86-64.c (elf_x86_64_link_hash_table): Add
+ plt_bnd_eh_frame.
+ (elf_x86_64_check_relocs): Create .eh_frame section for the
+ .plt.bnd section.
+ (elf_x86_64_size_dynamic_sections): Allocate and initialize
+ .eh_frame section for the .plt.bnd section.
+ (elf_x86_64_finish_dynamic_sections): Adjust .eh_frame section
+ for the .plt.bnd section.
+
2017-01-12 Nick Clifton <nickc@redhat.com>
PR binutils/20876
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 1fb865c..a058eca 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -934,6 +934,7 @@ struct elf_x86_64_link_hash_table
asection *interp;
asection *plt_eh_frame;
asection *plt_bnd;
+ asection *plt_bnd_eh_frame;
asection *plt_got;
asection *plt_got_eh_frame;
@@ -2343,23 +2344,21 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
/* 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;
@@ -2374,7 +2373,24 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
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;
}
}
@@ -3687,6 +3703,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
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)
@@ -3878,30 +3895,31 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
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.
@@ -3921,6 +3939,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|| 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)
{
@@ -3975,13 +3994,6 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
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,
@@ -3991,10 +4003,6 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
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);
@@ -4003,6 +4011,17 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
+ 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
@@ -6495,6 +6514,33 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
}
}
+ /* 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;