aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/elf64-x86-64.c106
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/testsuite/ld-x86-64/pr21038b.d9
-rw-r--r--ld/testsuite/ld-x86-64/pr21038c.d90
-rw-r--r--ld/testsuite/ld-x86-64/pr21038c.s9
-rw-r--r--ld/testsuite/ld-x86-64/x86-64.exp1
7 files changed, 205 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;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 79bcc5f..1579442 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2017-01-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ 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.
+
2017-01-11 H.J. Lu <hongjiu.lu@intel.com>
PR ld/21038
diff --git a/ld/testsuite/ld-x86-64/pr21038b.d b/ld/testsuite/ld-x86-64/pr21038b.d
index 1690d1e..053d908 100644
--- a/ld/testsuite/ld-x86-64/pr21038b.d
+++ b/ld/testsuite/ld-x86-64/pr21038b.d
@@ -40,6 +40,15 @@ Contents of the .eh_frame section:
DW_CFA_nop
DW_CFA_nop
+0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000240..0000000000000248
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+
Disassembly of section .plt:
diff --git a/ld/testsuite/ld-x86-64/pr21038c.d b/ld/testsuite/ld-x86-64/pr21038c.d
new file mode 100644
index 0000000..33ff4ed
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr21038c.d
@@ -0,0 +1,90 @@
+#name: PR ld/21038 (.plt.got and .plt.bnd)
+#as: --64
+#ld: -z bndplt -melf_x86_64 -shared -z relro --ld-generated-unwind-info
+#objdump: -dw -Wf
+
+.*: +file format .*
+
+Contents of the .eh_frame section:
+
+0+ 0000000000000014 00000000 CIE
+ Version: 1
+ Augmentation: "zR"
+ Code alignment factor: 1
+ Data alignment factor: -8
+ Return address column: 16
+ Augmentation data: 1b
+
+ DW_CFA_def_cfa: r7 \(rsp\) ofs 8
+ DW_CFA_offset: r16 \(rip\) at cfa-8
+ DW_CFA_nop
+ DW_CFA_nop
+
+0+18 0000000000000014 0000001c FDE cie=00000000 pc=0000000000000290..00000000000002a1
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+
+0+30 0000000000000024 00000034 FDE cie=00000000 pc=0000000000000260..0000000000000280
+ DW_CFA_def_cfa_offset: 16
+ DW_CFA_advance_loc: 6 to 0000000000000266
+ DW_CFA_def_cfa_offset: 24
+ DW_CFA_advance_loc: 10 to 0000000000000270
+ DW_CFA_def_cfa_expression \(DW_OP_breg7 \(rsp\): 8; DW_OP_breg16 \(rip\): 0; DW_OP_lit15; DW_OP_and; DW_OP_lit5; DW_OP_ge; DW_OP_lit3; DW_OP_shl; DW_OP_plus\)
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+
+0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000288..0000000000000290
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+
+0+70 0000000000000014 00000074 FDE cie=00000000 pc=0000000000000280..0000000000000288
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+ DW_CFA_nop
+
+
+Disassembly of section .plt:
+
+0+260 <.plt>:
+ +[a-f0-9]+: ff 35 a2 0d 20 00 pushq 0x200da2\(%rip\) # 201008 <_GLOBAL_OFFSET_TABLE_\+0x8>
+ +[a-f0-9]+: f2 ff 25 a3 0d 20 00 bnd jmpq \*0x200da3\(%rip\) # 201010 <_GLOBAL_OFFSET_TABLE_\+0x10>
+ +[a-f0-9]+: 0f 1f 00 nopl \(%rax\)
+ +[a-f0-9]+: 68 00 00 00 00 pushq \$0x0
+ +[a-f0-9]+: f2 e9 e5 ff ff ff bnd jmpq 260 <.plt>
+ +[a-f0-9]+: 0f 1f 44 00 00 nopl 0x0\(%rax,%rax,1\)
+
+Disassembly of section .plt.got:
+
+0+280 <.plt.got>:
+ +[a-f0-9]+: f2 ff 25 71 0d 20 00 bnd jmpq \*0x200d71\(%rip\) # 200ff8 <func1>
+ +[a-f0-9]+: 90 nop
+
+Disassembly of section .plt.bnd:
+
+0+288 <func2@plt>:
+ +[a-f0-9]+: f2 ff 25 89 0d 20 00 bnd jmpq \*0x200d89\(%rip\) # 201018 <func2>
+ +[a-f0-9]+: 90 nop
+
+Disassembly of section .text:
+
+0+290 <foo>:
+ +[a-f0-9]+: e8 eb ff ff ff callq 280 <.plt.got>
+ +[a-f0-9]+: e8 ee ff ff ff callq 288 <func2@plt>
+ +[a-f0-9]+: 48 8b 05 57 0d 20 00 mov 0x200d57\(%rip\),%rax # 200ff8 <func1>
+#pass
diff --git a/ld/testsuite/ld-x86-64/pr21038c.s b/ld/testsuite/ld-x86-64/pr21038c.s
new file mode 100644
index 0000000..38fc10d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/pr21038c.s
@@ -0,0 +1,9 @@
+ .text
+ .globl foo
+ .type foo, @function
+foo:
+ .cfi_startproc
+ call func1@plt
+ call func2@plt
+ movq func1@GOTPCREL(%rip), %rax
+ .cfi_endproc
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index ff782a0..8e4e422 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -1023,3 +1023,4 @@ run_dump_test "pr20830a"
run_dump_test "pr20830b"
run_dump_test "pr21038a"
run_dump_test "pr21038b"
+run_dump_test "pr21038c"