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.
This commit is contained in:
H.J. Lu 2017-01-12 10:30:56 -08:00
parent 2425a30e40
commit 8361ed4d6b
7 changed files with 205 additions and 30 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -1023,3 +1023,4 @@ run_dump_test "pr20830a"
run_dump_test "pr20830b"
run_dump_test "pr21038a"
run_dump_test "pr21038b"
run_dump_test "pr21038c"