x86: Create dynamic sections in create_dynamic_sections

This patch creates dynamic sections in i386/x86-64 create_dynamic_sections
instead of creating them on demend.  Linker will strip them if they are
empty.  It changes order in x86-64 .eh_frame section.  The extra DW_CFA_nop
paddings is due to

https://sourceware.org/bugzilla/show_bug.cgi?id=21441

bfd/

	* elf32-i386.c (elf_i386_create_dynamic_sections): Create the
	.plt.got section here.
	(elf_i386_check_relocs): Don't create the .plt.got section.
	* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Create
	the .plt.got and .plt.bnd sections here.
	(elf_x86_64_check_relocs): Don't create the .plt.got nor
	.plt.bnd sections.

ld/

	* testsuite/ld-x86-64/pr21038a.d: Update DW_CFA_nop paddings
	in .eh_frame section.
	* testsuite/ld-x86-64/pr21038c.d: Update .eh_frame order.
This commit is contained in:
H.J. Lu 2017-04-27 13:55:31 -07:00
parent da3d25afa2
commit de9a3c4285
6 changed files with 185 additions and 191 deletions

View file

@ -1,3 +1,13 @@
2017-04-27 H.J. Lu <hongjiu.lu@intel.com>
* elf32-i386.c (elf_i386_create_dynamic_sections): Create the
.plt.got section here.
(elf_i386_check_relocs): Don't create the .plt.got section.
* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Create
the .plt.got and .plt.bnd sections here.
(elf_x86_64_check_relocs): Don't create the .plt.got nor
.plt.bnd sections.
2017-04-27 H.J. Lu <hongjiu.lu@intel.com>
* elf64-x86-64.c (elf_x86_64_link_hash_entry): Remove

View file

@ -1124,18 +1124,70 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
&htab->srelplt2))
return FALSE;
if (!info->no_ld_generated_unwind_info
&& htab->plt_eh_frame == NULL
&& htab->elf.splt != NULL)
if (htab->elf.splt != NULL)
{
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
htab->plt_eh_frame
= bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
if (htab->plt_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2))
return FALSE;
if (htab->plt_got == NULL
&& !get_elf_i386_backend_data (dynobj)->is_vxworks
&& get_elf_i386_backend_data (dynobj) == &elf_i386_arch_bed)
{
/* Create the GOT procedure linkage table. */
unsigned int plt_got_align;
const struct elf_backend_data *bed;
bed = get_elf_backend_data (dynobj);
BFD_ASSERT (sizeof (elf_i386_got_plt_entry) == 8
&& (sizeof (elf_i386_got_plt_entry)
== sizeof (elf_i386_pic_got_plt_entry)));
plt_got_align = 3;
htab->plt_got
= bfd_make_section_anyway_with_flags (dynobj,
".plt.got",
(bed->dynamic_sec_flags
| SEC_ALLOC
| SEC_CODE
| SEC_LOAD
| SEC_READONLY));
if (htab->plt_got == NULL
|| !bfd_set_section_alignment (dynobj,
htab->plt_got,
plt_got_align))
return FALSE;
}
if (!info->no_ld_generated_unwind_info)
{
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
if (htab->plt_eh_frame == NULL)
{
htab->plt_eh_frame
= bfd_make_section_anyway_with_flags (dynobj,
".eh_frame",
flags);
if (htab->plt_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj,
htab->plt_eh_frame,
2))
return FALSE;
}
if (htab->plt_got_eh_frame == NULL
&& htab->plt_got != NULL)
{
htab->plt_got_eh_frame
= bfd_make_section_anyway_with_flags (dynobj,
".eh_frame",
flags);
if (htab->plt_got_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj,
htab->plt_got_eh_frame,
2))
return FALSE;
}
}
}
return TRUE;
@ -1858,7 +1910,6 @@ elf_i386_check_relocs (bfd *abfd,
const Elf_Internal_Rela *rel_end;
asection *sreloc;
bfd_byte *contents;
bfd_boolean use_plt_got;
if (bfd_link_relocatable (info))
return TRUE;
@ -1890,10 +1941,6 @@ elf_i386_check_relocs (bfd *abfd,
return FALSE;
}
use_plt_got = (!get_elf_i386_backend_data (abfd)->is_vxworks
&& (get_elf_i386_backend_data (abfd)
== &elf_i386_arch_bed));
symtab_hdr = &elf_symtab_hdr (abfd);
sym_hashes = elf_sym_hashes (abfd);
@ -2353,58 +2400,6 @@ do_size:
break;
}
if (use_plt_got
&& h != NULL
&& h->plt.refcount > 0
&& (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed)
|| h->got.refcount > 0)
&& htab->plt_got == NULL)
{
/* Create the GOT procedure linkage table. */
unsigned int plt_got_align;
const struct elf_backend_data *bed;
bed = get_elf_backend_data (info->output_bfd);
BFD_ASSERT (sizeof (elf_i386_got_plt_entry) == 8
&& (sizeof (elf_i386_got_plt_entry)
== sizeof (elf_i386_pic_got_plt_entry)));
plt_got_align = 3;
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
htab->plt_got
= bfd_make_section_anyway_with_flags (htab->elf.dynobj,
".plt.got",
(bed->dynamic_sec_flags
| SEC_ALLOC
| SEC_CODE
| SEC_LOAD
| SEC_READONLY));
if (htab->plt_got == NULL
|| !bfd_set_section_alignment (htab->elf.dynobj,
htab->plt_got,
plt_got_align))
goto error_return;
if (!info->no_ld_generated_unwind_info
&& htab->plt_got_eh_frame == NULL
&& get_elf_i386_backend_data (abfd)->plt->eh_frame_plt_got != NULL)
{
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
htab->plt_got_eh_frame
= bfd_make_section_anyway_with_flags (htab->elf.dynobj,
".eh_frame",
flags);
if (htab->plt_got_eh_frame == NULL
|| !bfd_set_section_alignment (htab->elf.dynobj,
htab->plt_got_eh_frame,
2))
goto error_return;
}
}
if (r_type == R_386_GOT32X
&& (h == NULL || h->type != STT_GNU_IFUNC))
sec->need_convert_load = 1;

View file

@ -1197,19 +1197,106 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
htab->interp = s;
}
if (!info->no_ld_generated_unwind_info
&& htab->plt_eh_frame == NULL
&& htab->elf.splt != NULL)
if (htab->elf.splt != NULL)
{
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
htab->plt_eh_frame
= bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
if (htab->plt_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj, htab->plt_eh_frame,
ABI_64_P (dynobj) ? 3 : 2))
return FALSE;
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);
if (htab->plt_got == NULL
&& get_elf_x86_64_backend_data (dynobj) == &elf_x86_64_arch_bed)
{
/* Create the GOT procedure linkage table. */
unsigned int plt_got_align;
BFD_ASSERT (sizeof (elf_x86_64_legacy_plt2_entry) == 8
&& (sizeof (elf_x86_64_bnd_plt2_entry)
== sizeof (elf_x86_64_legacy_plt2_entry)));
plt_got_align = 3;
htab->plt_got
= bfd_make_section_anyway_with_flags (dynobj,
".plt.got",
pltflags);
if (htab->plt_got == NULL
|| !bfd_set_section_alignment (dynobj,
htab->plt_got,
plt_got_align))
return FALSE;
}
/* MPX PLT is supported only if elf_x86_64_arch_bed is used in
64-bit mode. */
if (ABI_64_P (dynobj)
&& info->bndplt
&& get_elf_x86_64_backend_data (dynobj) == &elf_x86_64_arch_bed
&& htab->plt_bnd == NULL)
{
/* Create the second PLT for Intel MPX support. */
BFD_ASSERT (sizeof (elf_x86_64_bnd_plt2_entry) == 8
&& (sizeof (elf_x86_64_bnd_plt2_entry)
== sizeof (elf_x86_64_legacy_plt2_entry)));
htab->plt_bnd
= bfd_make_section_anyway_with_flags (dynobj,
".plt.bnd",
pltflags);
if (htab->plt_bnd == NULL
|| !bfd_set_section_alignment (dynobj, htab->plt_bnd, 3))
return FALSE;
}
if (!info->no_ld_generated_unwind_info)
{
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
if (htab->plt_eh_frame == NULL)
{
htab->plt_eh_frame
= bfd_make_section_anyway_with_flags (dynobj,
".eh_frame",
flags);
if (htab->plt_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj,
htab->plt_eh_frame,
ABI_64_P (dynobj) ? 3 : 2))
return FALSE;
}
if (htab->plt_got_eh_frame == NULL
&& htab->plt_got != NULL)
{
htab->plt_got_eh_frame
= bfd_make_section_anyway_with_flags (htab->elf.dynobj,
".eh_frame",
flags);
if (htab->plt_got_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj,
htab->plt_got_eh_frame,
ABI_64_P (dynobj) ? 3 : 2))
return FALSE;
}
if (htab->plt_bnd_eh_frame == NULL
&& htab->plt_bnd != NULL)
{
htab->plt_bnd_eh_frame
= bfd_make_section_anyway_with_flags (dynobj,
".eh_frame",
flags);
if (htab->plt_bnd_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj,
htab->plt_bnd_eh_frame,
3))
return FALSE;
}
}
}
/* Align .got section to its entry size. */
@ -2198,7 +2285,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
const Elf_Internal_Rela *rel_end;
asection *sreloc;
bfd_byte *contents;
bfd_boolean use_plt_got;
if (bfd_link_relocatable (info))
return TRUE;
@ -2230,8 +2316,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
return FALSE;
}
use_plt_got = get_elf_x86_64_backend_data (abfd) == &elf_x86_64_arch_bed;
symtab_hdr = &elf_symtab_hdr (abfd);
sym_hashes = elf_sym_hashes (abfd);
@ -2340,59 +2424,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_X86_64_PLT32:
case R_X86_64_32:
case R_X86_64_64:
/* 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))
{
/* Create the second PLT for Intel MPX support. */
if (htab->plt_bnd == NULL)
{
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)));
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
htab->plt_bnd
= bfd_make_section_anyway_with_flags (htab->elf.dynobj,
".plt.bnd",
(bed->dynamic_sec_flags
| SEC_ALLOC
| SEC_CODE
| SEC_LOAD
| SEC_READONLY));
if (htab->plt_bnd == NULL
|| !bfd_set_section_alignment (htab->elf.dynobj,
htab->plt_bnd,
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;
}
}
/* Fall through. */
case R_X86_64_32S:
case R_X86_64_PC64:
case R_X86_64_GOTPCREL:
@ -2798,58 +2829,6 @@ do_size:
break;
}
if (use_plt_got
&& h != NULL
&& h->plt.refcount > 0
&& (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed)
|| h->got.refcount > 0)
&& htab->plt_got == NULL)
{
/* Create the GOT procedure linkage table. */
unsigned int plt_got_align;
const struct elf_backend_data *bed;
bed = get_elf_backend_data (info->output_bfd);
BFD_ASSERT (sizeof (elf_x86_64_legacy_plt2_entry) == 8
&& (sizeof (elf_x86_64_bnd_plt2_entry)
== sizeof (elf_x86_64_legacy_plt2_entry)));
plt_got_align = 3;
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
htab->plt_got
= bfd_make_section_anyway_with_flags (htab->elf.dynobj,
".plt.got",
(bed->dynamic_sec_flags
| SEC_ALLOC
| SEC_CODE
| SEC_LOAD
| SEC_READONLY));
if (htab->plt_got == NULL
|| !bfd_set_section_alignment (htab->elf.dynobj,
htab->plt_got,
plt_got_align))
goto error_return;
if (!info->no_ld_generated_unwind_info
&& htab->plt_got_eh_frame == NULL
&& get_elf_x86_64_backend_data (abfd)->eh_frame_plt_got != NULL)
{
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
| SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
htab->plt_got_eh_frame
= bfd_make_section_anyway_with_flags (htab->elf.dynobj,
".eh_frame",
flags);
if (htab->plt_got_eh_frame == NULL
|| !bfd_set_section_alignment (htab->elf.dynobj,
htab->plt_got_eh_frame,
ABI_64_P (htab->elf.dynobj) ? 3 : 2))
goto error_return;
}
}
if ((r_type == R_X86_64_GOTPCREL
|| r_type == R_X86_64_GOTPCRELX
|| r_type == R_X86_64_REX_GOTPCRELX)

View file

@ -1,3 +1,9 @@
2017-04-27 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/ld-x86-64/pr21038a.d: Update DW_CFA_nop paddings
in .eh_frame section.
* testsuite/ld-x86-64/pr21038c.d: Update .eh_frame order.
2017-04-26 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/ld-i386/tlsdesc2.d: New test.

View file

@ -40,7 +40,11 @@ Contents of the .eh_frame section:
DW_CFA_nop
DW_CFA_nop
0+58 0000000000000010 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000230..0000000000000238
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop

View file

@ -40,7 +40,7 @@ Contents of the .eh_frame section:
DW_CFA_nop
DW_CFA_nop
0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000288..0000000000000290
0+58 0000000000000014 0000005c FDE cie=00000000 pc=0000000000000280..0000000000000288
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
@ -49,7 +49,7 @@ Contents of the .eh_frame section:
DW_CFA_nop
DW_CFA_nop
0+70 0000000000000010 00000074 FDE cie=00000000 pc=0000000000000280..0000000000000288
0+70 0000000000000010 00000074 FDE cie=00000000 pc=0000000000000288..0000000000000290
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop