PATCH: Move some STT_GNU_IFUNC support to generic ELF linker
H.J. Lu
hjl.tools@gmail.com
Tue Jun 16 16:15:00 GMT 2009
On Tue, Jun 16, 2009 at 4:56 AM, Nick Clifton<nickc@redhat.com> wrote:
> Hi H.J.
>
>> Here is the first patch. OK for trunk?
>
>> 2009-06-15 H.J. Lu <hongjiu.lu@intel.com>
>>
>> * configure.in (elf): Add elf-ifunc.lo.
>>
>> * configure: Regenerated.
>> * Makefile.in: Likewise.
>>
>> * elf-bfd.h (elf_link_hash_table): Add sgot, sgotplt,
>> srelgot, splt, srelplt, igotplt, iplt, irelplt and irelifunc.
>>
>> * elf32-i386.c (elf_i386_link_hash_table): Remove sgot,
>> sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and
>> irelifunc.
>> (elf_i386_link_hash_table_create): Likewise.
>> (elf_i386_create_dynamic_sections): Likewise.
>> (elf_i386_check_relocs): Likewise.
>> (elf_i386_allocate_dynrelocs): Likewise.
>> (elf_i386_size_dynamic_sections): Likewise.
>> (elf_i386_relocate_section): Likewise.
>> (elf_i386_finish_dynamic_symbol): Likewise.
>> (elf_i386_finish_dynamic_sections): Likewise.
>> (elf_i386_create_got_section): Removed.
>>
>> * elf64-x86-64.c (elf64_x86_64_link_hash_table): Remove sgot,
>> sgotplt, srelgot, splt, srelplt, igotplt, iplt, irelplt and
>> irelifunc.
>> (elf64_x86_64_compute_jump_table_size): Updated.
>> (elf64_x86_64_link_hash_table_create): Likewise.
>> (elf64_x86_64_create_dynamic_sections): Likewise.
>> (elf64_x86_64_check_relocs): Likewise.
>> (elf64_x86_64_allocate_dynrelocs): Likewise.
>> (elf64_x86_64_size_dynamic_sections): Likewise.
>> (elf64_x86_64_relocate_section): Likewise.
>> (elf64_x86_64_finish_dynamic_symbol): Likewise.
>> (elf64_x86_64_finish_dynamic_sections): Likewise.
>> (elf64_x86_64_create_got_section): Removed.
>>
>> * elflink.c (_bfd_elf_create_got_section): Use log_file_align
>> for pointer alignment. Set up section pointers.
>> (_bfd_elf_create_dynamic_sections): Likewise.
>> (_bfd_elf_create_ifunc_sections): Moved to ...
>> * elf-ifunc.c: Here. New.
>>
>> * Makefile.am (BFD32_BACKENDS): Add elf-ifunc.lo.
>> (BFD32_BACKENDS_CFILES): Add elf-ifunc.c.
>> Run "make dep-am".
>
> Approved - please apply.
>
> Cheers
> Nick
>
IA64 needs this patch to fix linker failures. I will check it in as an
obvious fix. Please let me know if other backends need similar
patches.
Thanks.
H.J.
---
2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
* elfxx-ia64.c (elfNN_ia64_link_hash_table): Remove got_sec,
rel_got_sec and plt_sec.
(elfNN_ia64_relax_section): Updated.
(elfNN_ia64_create_dynamic_sections): Likewise.
(get_got): Likewise.
(allocate_dynrel_entries): Likewise.
(elfNN_ia64_size_dynamic_sections): Likewise.
(set_got_entry): Likewise.
(elfNN_ia64_choose_gp): Likewise.
(elfNN_ia64_relocate_section): Likewise.
(elfNN_ia64_finish_dynamic_symbol): Likewise.
(elfNN_ia64_finish_dynamic_sections): Likewise.
-------------- next part --------------
Index: elfxx-ia64.c
===================================================================
--- elfxx-ia64.c (revision 6145)
+++ elfxx-ia64.c (working copy)
@@ -163,11 +163,8 @@ struct elfNN_ia64_link_hash_table
/* The main hash table. */
struct elf_link_hash_table root;
- asection *got_sec; /* the linkage table section (or NULL) */
- asection *rel_got_sec; /* dynamic relocation section for same */
asection *fptr_sec; /* function descriptor table (or NULL) */
asection *rel_fptr_sec; /* dynamic relocation section for same */
- asection *plt_sec; /* the primary plt section (or NULL) */
asection *pltoff_sec; /* private descriptors for plt (or NULL) */
asection *rel_pltoff_sec; /* dynamic relocation section for same */
@@ -932,7 +929,7 @@ elfNN_ia64_relax_section (bfd *abfd, ase
if (r_type != R_IA64_PCREL21B)
continue;
- tsec = ia64_info->plt_sec;
+ tsec = ia64_info->root.splt;
toff = dyn_i->plt2_offset;
BFD_ASSERT (irel->r_addend == 0);
}
@@ -1005,7 +1002,7 @@ elfNN_ia64_relax_section (bfd *abfd, ase
to 32byte. We assume linker will always insert 32byte
between the .plt and .text sections after the the first
relaxation pass. */
- if (tsec == ia64_info->plt_sec)
+ if (tsec == ia64_info->root.splt)
offset = -0x1000000 + 32;
else
offset = -0x1000000;
@@ -1076,7 +1073,7 @@ elfNN_ia64_relax_section (bfd *abfd, ase
size_t size;
- if (tsec == ia64_info->plt_sec)
+ if (tsec == ia64_info->root.splt)
size = sizeof (plt_full_entry);
else
size = oor_branch_size;
@@ -1096,7 +1093,7 @@ elfNN_ia64_relax_section (bfd *abfd, ase
goto error_return;
sec->size = amt;
- if (tsec == ia64_info->plt_sec)
+ if (tsec == ia64_info->root.splt)
{
memcpy (contents + trampoff, plt_full_entry, size);
@@ -1250,16 +1247,16 @@ elfNN_ia64_relax_section (bfd *abfd, ase
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
- ia64_info->got_sec->size = data.ofs;
+ ia64_info->root.sgot->size = data.ofs;
if (ia64_info->root.dynamic_sections_created
- && ia64_info->rel_got_sec != NULL)
+ && ia64_info->root.srelgot != NULL)
{
/* Resize .rela.got. */
- ia64_info->rel_got_sec->size = 0;
+ ia64_info->root.srelgot->size = 0;
if (link_info->shared
&& ia64_info->self_dtpmod_offset != (bfd_vma) -1)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
data.only_got = TRUE;
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
&data);
@@ -2003,14 +2000,12 @@ elfNN_ia64_create_dynamic_sections (bfd
ia64_info = elfNN_ia64_hash_table (info);
- ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
- ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
-
{
- flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
- bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
+ flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
+ bfd_set_section_flags (abfd, ia64_info->root.sgot,
+ SEC_SMALL_DATA | flags);
/* The .got section is always aligned at 8 bytes. */
- bfd_set_section_alignment (abfd, ia64_info->got_sec, 3);
+ bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3);
}
if (!get_pltoff (abfd, info, ia64_info))
@@ -2027,17 +2022,6 @@ elfNN_ia64_create_dynamic_sections (bfd
return FALSE;
ia64_info->rel_pltoff_sec = s;
- s = bfd_make_section_with_flags (abfd, ".rela.got",
- (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
- if (s == NULL
- || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
- return FALSE;
- ia64_info->rel_got_sec = s;
-
return TRUE;
}
@@ -2418,7 +2402,7 @@ get_got (bfd *abfd, struct bfd_link_info
asection *got;
bfd *dynobj;
- got = ia64_info->got_sec;
+ got = ia64_info->root.sgot;
if (!got)
{
flagword flags;
@@ -2429,9 +2413,7 @@ get_got (bfd *abfd, struct bfd_link_info
if (!_bfd_elf_create_got_section (dynobj, info))
return 0;
- got = bfd_get_section_by_name (dynobj, ".got");
- BFD_ASSERT (got);
- ia64_info->got_sec = got;
+ got = ia64_info->root.sgot;
/* The .got section is always aligned at 8 bytes. */
if (!bfd_set_section_alignment (abfd, got, 3))
@@ -3330,14 +3312,14 @@ allocate_dynrel_entries (struct elfNN_ia
|| !x->info->pie
|| dyn_i->h == NULL
|| dyn_i->h->root.type != bfd_link_hash_undefweak)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
}
if ((dynamic_symbol || shared) && dyn_i->want_tprel)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
if (dynamic_symbol && dyn_i->want_dtpmod)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
if (dynamic_symbol && dyn_i->want_dtprel)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
if (x->only_got)
return TRUE;
@@ -3471,13 +3453,13 @@ elfNN_ia64_size_dynamic_sections (bfd *o
/* Allocate the GOT entries. */
- if (ia64_info->got_sec)
+ if (ia64_info->root.sgot)
{
data.ofs = 0;
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
- ia64_info->got_sec->size = data.ofs;
+ ia64_info->root.sgot->size = data.ofs;
}
/* Allocate the FPTR entries. */
@@ -3516,7 +3498,7 @@ elfNN_ia64_size_dynamic_sections (bfd *o
BFD_ASSERT (ia64_info->root.dynamic_sections_created);
- ia64_info->plt_sec->size = data.ofs;
+ ia64_info->root.splt->size = data.ofs;
/* If we've got a .plt, we need some extra memory for the dynamic
linker. We stuff these in .got.plt. */
@@ -3539,7 +3521,7 @@ elfNN_ia64_size_dynamic_sections (bfd *o
required. */
if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
data.only_got = FALSE;
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
}
@@ -3563,12 +3545,12 @@ elfNN_ia64_size_dynamic_sections (bfd *o
strip = (sec->size == 0);
- if (sec == ia64_info->got_sec)
+ if (sec == ia64_info->root.sgot)
strip = FALSE;
- else if (sec == ia64_info->rel_got_sec)
+ else if (sec == ia64_info->root.srelgot)
{
if (strip)
- ia64_info->rel_got_sec = NULL;
+ ia64_info->root.srelgot = NULL;
else
/* We use the reloc_count field as a counter if we need to
copy relocs into the output file. */
@@ -3588,10 +3570,10 @@ elfNN_ia64_size_dynamic_sections (bfd *o
copy relocs into the output file. */
sec->reloc_count = 0;
}
- else if (sec == ia64_info->plt_sec)
+ else if (sec == ia64_info->root.splt)
{
if (strip)
- ia64_info->plt_sec = NULL;
+ ia64_info->root.splt = NULL;
}
else if (sec == ia64_info->pltoff_sec)
{
@@ -3960,7 +3942,7 @@ set_got_entry (bfd *abfd, struct bfd_lin
bfd_vma got_offset;
ia64_info = elfNN_ia64_hash_table (info);
- got_sec = ia64_info->got_sec;
+ got_sec = ia64_info->root.sgot;
switch (dyn_r_type)
{
@@ -4071,7 +4053,7 @@ set_got_entry (bfd *abfd, struct bfd_lin
}
elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
- ia64_info->rel_got_sec,
+ ia64_info->root.srelgot,
got_offset, dyn_r_type,
dynindx, addend);
}
@@ -4292,7 +4274,7 @@ elfNN_ia64_choose_gp (bfd *abfd, struct
{
/* Pick a sensible value. */
- asection *got_sec = ia64_info->got_sec;
+ asection *got_sec = ia64_info->root.sgot;
/* Start with just the address of the .got. */
if (got_sec)
@@ -4845,8 +4827,8 @@ elfNN_ia64_relocate_section (bfd *output
/* Should have caught this earlier. */
BFD_ASSERT (rel->r_addend == 0);
- value = (ia64_info->plt_sec->output_section->vma
- + ia64_info->plt_sec->output_offset
+ value = (ia64_info->root.splt->output_section->vma
+ + ia64_info->root.splt->output_offset
+ dyn_i->plt2_offset);
}
else
@@ -5184,7 +5166,7 @@ elfNN_ia64_finish_dynamic_symbol (bfd *o
/* Initialize the minimal PLT entry. */
index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
- plt_sec = ia64_info->plt_sec;
+ plt_sec = ia64_info->root.splt;
loc = plt_sec->contents + dyn_i->plt_offset;
memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
@@ -5313,9 +5295,9 @@ elfNN_ia64_finish_dynamic_sections (bfd
}
/* Initialize the PLT0 entry. */
- if (ia64_info->plt_sec)
+ if (ia64_info->root.splt)
{
- bfd_byte *loc = ia64_info->plt_sec->contents;
+ bfd_byte *loc = ia64_info->root.splt->contents;
bfd_vma pltres;
memcpy (loc, plt_header, PLT_HEADER_SIZE);
Index: ChangeLog
===================================================================
--- ChangeLog (revision 6150)
+++ ChangeLog (working copy)
@@ -1,5 +1,20 @@
2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
+ * elfxx-ia64.c (elfNN_ia64_link_hash_table): Remove got_sec,
+ rel_got_sec and plt_sec.
+ (elfNN_ia64_relax_section): Updated.
+ (elfNN_ia64_create_dynamic_sections): Likewise.
+ (get_got): Likewise.
+ (allocate_dynrel_entries): Likewise.
+ (elfNN_ia64_size_dynamic_sections): Likewise.
+ (set_got_entry): Likewise.
+ (elfNN_ia64_choose_gp): Likewise.
+ (elfNN_ia64_relocate_section): Likewise.
+ (elfNN_ia64_finish_dynamic_symbol): Likewise.
+ (elfNN_ia64_finish_dynamic_sections): Likewise.
+
+2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
+
* configure.in (elf): Add elf-ifunc.lo.
* configure: Regenerated.
More information about the Binutils
mailing list