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:
parent
da3d25afa2
commit
de9a3c4285
6 changed files with 185 additions and 191 deletions
|
@ -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
|
||||
|
|
131
bfd/elf32-i386.c
131
bfd/elf32-i386.c
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue