[PATCH] ELF: Add _bfd_elf_add_dynamic_tags
H.J. Lu
hjl.tools@gmail.com
Wed Jun 3 22:20:02 GMT 2020
Add _bfd_elf_add_dynamic_tags to add common dynamic tags. Only x86
backends is updated to use it in the initial checkin. Other backends
can be updated one by one.
bfd/
* elf-bfd.h (elf_link_hash_table): Add
readonly_dynrelocs_against_ifunc.
(_bfd_elf_add_dynamic_tags): New.
* elflink.c (_bfd_elf_add_dynamic_tags): New function.
* elfxx-x86.c (elf_x86_allocate_dynrelocs): Updated.
(_bfd_x86_elf_link_hash_table_create): Likewise.
(_bfd_x86_elf_size_dynamic_sections): Call
_bfd_elf_add_dynamic_tags.
* elfxx-x86.h (elf_x86_link_hash_table): Remove
readonly_dynrelocs_against_ifunc, dt_reloc, dt_reloc_sz and
dt_reloc_ent.
ld/
* testsuite/ld-x86-64/tlsdesc-nacl.rd: Updated.
* testsuite/ld-x86-64/tlsdesc.rd: Likewise.
---
bfd/elf-bfd.h | 6 ++
bfd/elflink.c | 92 ++++++++++++++++++++++++++
bfd/elfxx-x86.c | 62 +----------------
bfd/elfxx-x86.h | 7 --
ld/testsuite/ld-x86-64/tlsdesc-nacl.rd | 4 +-
ld/testsuite/ld-x86-64/tlsdesc.rd | 4 +-
6 files changed, 104 insertions(+), 71 deletions(-)
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index fbdd19ba21..a4499cb2f1 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -561,6 +561,10 @@ struct elf_link_hash_table
section symbols. */
bfd_boolean is_relocatable_executable;
+ /* TRUE if there are dynamic relocs against IFUNC symbols that apply
+ to read-only sections. */
+ bfd_boolean readonly_dynrelocs_against_ifunc;
+
/* The BFD used to hold special sections created by the linker.
This will be the first BFD found which requires these sections to
be created. */
@@ -2878,6 +2882,8 @@ extern asection *_bfd_elf_readonly_dynrelocs
(struct elf_link_hash_entry *);
extern bfd_boolean _bfd_elf_maybe_set_textrel
(struct elf_link_hash_entry *, void *);
+extern bfd_boolean _bfd_elf_add_dynamic_tags
+ (bfd *, struct bfd_link_info *, bfd_boolean);
/* Large common section. */
extern asection _bfd_elf_large_com_section;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ce6282a9dc..daa1db3dca 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -14875,3 +14875,95 @@ _bfd_elf_maybe_set_textrel (struct elf_link_hash_entry *h, void *inf)
}
return TRUE;
}
+
+/* Add dynamic tags. */
+
+bfd_boolean
+_bfd_elf_add_dynamic_tags (bfd *output_bfd, struct bfd_link_info *info,
+ bfd_boolean need_dynamic_reloc)
+{
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ if (htab->dynamic_sections_created)
+ {
+ /* Add some entries to the .dynamic section. We fill in the
+ values later, in elf_{i386,x86_64}_finish_dynamic_sections,
+ but we must add the entries now so that we get the correct
+ size for the .dynamic section. The DT_DEBUG entry is filled
+ in by the dynamic linker and used by the debugger. */
+#define add_dynamic_entry(TAG, VAL) \
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
+
+ const struct elf_backend_data *bed
+ = get_elf_backend_data (output_bfd);
+
+ if (bfd_link_executable (info))
+ {
+ if (!add_dynamic_entry (DT_DEBUG, 0))
+ return FALSE;
+ }
+
+ if (htab->splt->size != 0)
+ {
+ /* DT_PLTGOT is used by prelink even if there is no PLT
+ relocation. */
+ if (!add_dynamic_entry (DT_PLTGOT, 0))
+ return FALSE;
+ }
+
+ if (htab->srelplt->size != 0)
+ {
+ if (!add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL,
+ (bed->rela_plts_and_copies_p
+ ? DT_RELA : DT_REL))
+ || !add_dynamic_entry (DT_JMPREL, 0))
+ return FALSE;
+ }
+
+ if (need_dynamic_reloc)
+ {
+ if (bed->rela_plts_and_copies_p)
+ {
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT,
+ bed->s->sizeof_rela))
+ return FALSE;
+ }
+ else
+ {
+ if (!add_dynamic_entry (DT_REL, 0)
+ || !add_dynamic_entry (DT_RELSZ, 0)
+ || !add_dynamic_entry (DT_RELENT,
+ bed->s->sizeof_rel))
+ return FALSE;
+ }
+
+ /* If any dynamic relocs apply to a read-only section,
+ then we need a DT_TEXTREL entry. */
+ if ((info->flags & DF_TEXTREL) == 0)
+ elf_link_hash_traverse (htab, _bfd_elf_maybe_set_textrel,
+ info);
+
+ if ((info->flags & DF_TEXTREL) != 0)
+ {
+ if (htab->readonly_dynrelocs_against_ifunc)
+ {
+ info->callbacks->einfo
+ (_("%P%X: read-only segment has dynamic IFUNC relocations;"
+ " recompile with %s\n"),
+ bfd_link_dll (info) ? "-fPIC" : "-fPIE");
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
+ }
+ }
+#undef add_dynamic_entry
+
+ return TRUE;
+}
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 035b5c5c64..4433ae4233 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -132,7 +132,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
&& h->def_regular)
{
if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &h->dyn_relocs,
- &htab->readonly_dynrelocs_against_ifunc,
+ &htab->elf.readonly_dynrelocs_against_ifunc,
plt_entry_size,
(htab->plt.has_plt0
* plt_entry_size),
@@ -722,9 +722,6 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd)
if (bed->target_id == X86_64_ELF_DATA)
{
ret->is_reloc_section = elf_x86_64_is_reloc_section;
- ret->dt_reloc = DT_RELA;
- ret->dt_reloc_sz = DT_RELASZ;
- ret->dt_reloc_ent = DT_RELAENT;
ret->got_entry_size = 8;
ret->pcrel_plt = TRUE;
ret->tls_get_addr = "__tls_get_addr";
@@ -749,9 +746,6 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd)
else
{
ret->is_reloc_section = elf_i386_is_reloc_section;
- ret->dt_reloc = DT_REL;
- ret->dt_reloc_sz = DT_RELSZ;
- ret->dt_reloc_ent = DT_RELENT;
ret->sizeof_reloc = sizeof (Elf32_External_Rel);
ret->got_entry_size = 4;
ret->pcrel_plt = FALSE;
@@ -1374,70 +1368,18 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
#define add_dynamic_entry(TAG, VAL) \
_bfd_elf_add_dynamic_entry (info, TAG, VAL)
- if (bfd_link_executable (info))
- {
- if (!add_dynamic_entry (DT_DEBUG, 0))
- return FALSE;
- }
-
- if (htab->elf.splt->size != 0)
- {
- /* DT_PLTGOT is used by prelink even if there is no PLT
- relocation. */
- if (!add_dynamic_entry (DT_PLTGOT, 0))
- return FALSE;
- }
-
- if (htab->elf.srelplt->size != 0)
- {
- if (!add_dynamic_entry (DT_PLTRELSZ, 0)
- || !add_dynamic_entry (DT_PLTREL, htab->dt_reloc)
- || !add_dynamic_entry (DT_JMPREL, 0))
- return FALSE;
- }
-
if (htab->tlsdesc_plt
&& (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
|| !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
return FALSE;
- if (relocs)
- {
- if (!add_dynamic_entry (htab->dt_reloc, 0)
- || !add_dynamic_entry (htab->dt_reloc_sz, 0)
- || !add_dynamic_entry (htab->dt_reloc_ent,
- htab->sizeof_reloc))
- return FALSE;
-
- /* If any dynamic relocs apply to a read-only section,
- then we need a DT_TEXTREL entry. */
- if ((info->flags & DF_TEXTREL) == 0)
- elf_link_hash_traverse (&htab->elf,
- _bfd_elf_maybe_set_textrel, info);
-
- if ((info->flags & DF_TEXTREL) != 0)
- {
- if (htab->readonly_dynrelocs_against_ifunc)
- {
- info->callbacks->einfo
- (_("%P%X: read-only segment has dynamic IFUNC relocations;"
- " recompile with %s\n"),
- bfd_link_dll (info) ? "-fPIC" : "-fPIE");
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
-
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- }
- }
if (htab->target_os == is_vxworks
&& !elf_vxworks_add_dynamic_entries (output_bfd, info))
return FALSE;
}
#undef add_dynamic_entry
- return TRUE;
+ return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs);
}
/* Finish up the x86 dynamic sections. */
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index c717cd16e5..f23127bb0c 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -495,10 +495,6 @@ struct elf_x86_link_hash_table
/* The index of the next R_X86_64_IRELATIVE entry in .rela.plt. */
bfd_vma next_irelative_index;
- /* TRUE if there are dynamic relocs against IFUNC symbols that apply
- to read-only sections. */
- bfd_boolean readonly_dynrelocs_against_ifunc;
-
/* The (unloaded but important) .rel.plt.unloaded section on VxWorks.
This is used for i386 only. */
asection *srelplt2;
@@ -534,9 +530,6 @@ struct elf_x86_link_hash_table
enum elf_target_id target_id;
enum elf_x86_target_os target_os;
unsigned int sizeof_reloc;
- unsigned int dt_reloc;
- unsigned int dt_reloc_sz;
- unsigned int dt_reloc_ent;
unsigned int got_entry_size;
unsigned int pointer_r_type;
int dynamic_interpreter_size;
diff --git a/ld/testsuite/ld-x86-64/tlsdesc-nacl.rd b/ld/testsuite/ld-x86-64/tlsdesc-nacl.rd
index 1a7c693cdb..ea4c7ad046 100644
--- a/ld/testsuite/ld-x86-64/tlsdesc-nacl.rd
+++ b/ld/testsuite/ld-x86-64/tlsdesc-nacl.rd
@@ -55,12 +55,12 @@ Dynamic section at offset 0x[0-9a-f]+ contains 16 entries:
0x[0-9a-f]+ +\(SYMTAB\).*
0x[0-9a-f]+ +\(STRSZ\).*
0x[0-9a-f]+ +\(SYMENT\).*
+ 0x[0-9a-f]+ +\(TLSDESC_PLT\) +0x40
+ 0x[0-9a-f]+ +\(TLSDESC_GOT\) +0x100105d8
0x[0-9a-f]+ +\(PLTGOT\).*
0x[0-9a-f]+ +\(PLTRELSZ\).*
0x[0-9a-f]+ +\(PLTREL\).*
0x[0-9a-f]+ +\(JMPREL\).*
- 0x[0-9a-f]+ +\(TLSDESC_PLT\) +0x40
- 0x[0-9a-f]+ +\(TLSDESC_GOT\) +0x100105d8
0x[0-9a-f]+ +\(RELA\).*
0x[0-9a-f]+ +\(RELASZ\).*
0x[0-9a-f]+ +\(RELAENT\).*
diff --git a/ld/testsuite/ld-x86-64/tlsdesc.rd b/ld/testsuite/ld-x86-64/tlsdesc.rd
index 4fcd8826ae..763080a18b 100644
--- a/ld/testsuite/ld-x86-64/tlsdesc.rd
+++ b/ld/testsuite/ld-x86-64/tlsdesc.rd
@@ -53,12 +53,12 @@ Dynamic section at offset 0x[0-9a-f]+ contains 16 entries:
0x[0-9a-f]+ +\(SYMTAB\).*
0x[0-9a-f]+ +\(STRSZ\).*
0x[0-9a-f]+ +\(SYMENT\).*
+ 0x[0-9a-f]+ +\(TLSDESC_PLT\) +0x3c0
+ 0x[0-9a-f]+ +\(TLSDESC_GOT\) +0x201348
0x[0-9a-f]+ +\(PLTGOT\).*
0x[0-9a-f]+ +\(PLTRELSZ\).*
0x[0-9a-f]+ +\(PLTREL\).*
0x[0-9a-f]+ +\(JMPREL\).*
- 0x[0-9a-f]+ +\(TLSDESC_PLT\) +0x3c0
- 0x[0-9a-f]+ +\(TLSDESC_GOT\) +0x201348
0x[0-9a-f]+ +\(RELA\).*
0x[0-9a-f]+ +\(RELASZ\).*
0x[0-9a-f]+ +\(RELAENT\).*
--
2.26.2
More information about the Binutils
mailing list