From 3084d7a27b8e4d13f0fdd0fac62ffadc9c2223b5 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 23 Jun 2020 05:07:31 -0700 Subject: [PATCH] ELF: Add _bfd_elf_add_dynamic_tags All ELF backends with shared library support need to add dynamic tags. Add dt_pltgot_required and dt_jmprel_required to elf_link_hash_table to indicate that DT_PLTGOT and DT_JMPREL are required dynamic tags. 1. Add _bfd_elf_add_dynamic_tags to add common dynamic tags. 2. Add _bfd_elf_maybe_vxworks_add_dynamic_tags to add common VxWorks dynamic tags. * elf-bfd.h (elf_link_hash_table): Add dt_pltgot_required and dt_jmprel_required. (_bfd_elf_add_dynamic_tags): New. * elf-m10300.c (_bfd_mn10300_elf_size_dynamic_sections): Call _bfd_elf_add_dynamic_tags. * elf32-arc.c (elf_arc_size_dynamic_sections): Likewise. * elf32-bfin.c (elf32_bfinfdpic_size_dynamic_sections): Likewise. * elf32-cr16.c (_bfd_cr16_elf_size_dynamic_sections): Likewise. * elf32-frv.c (elf32_frvfdpic_size_dynamic_sections): Likewise. * elf32-lm32.c (lm32_elf_size_dynamic_sections): Likewise. * elf32-m32r.c (m32r_elf_size_dynamic_sections): Likewise. * elf32-m68k.c (elf_m68k_size_dynamic_sections): Likewise. * elf32-microblaze.c (microblaze_elf_size_dynamic_sections): Likewise. * elf32-nds32.c (nds32_elf_size_dynamic_sections): Likewise. * elf32-nios2.c (nios2_elf32_size_dynamic_sections): Likewise. * elf32-or1k.c (or1k_elf_size_dynamic_sections): Likewise. * elf32-s390.c (elf_s390_size_dynamic_sections): Likewise. * elf32-tilepro.c (tilepro_elf_size_dynamic_sections): Likewise. * elf32-vax.c (elf_vax_size_dynamic_sections): Likewise. * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Likewise. * elf64-s390.c (elf_s390_size_dynamic_sections): Likewise. * elfnn-aarch64.c (elfNN_aarch64_size_dynamic_sections): Likewise. * elfnn-riscv.c (riscv_elf_size_dynamic_sections): Likewise. * elfxx-tilegx.c (tilegx_elf_size_dynamic_sections): Likewise. * elf32-arm.c (elf32_arm_size_dynamic_sections): Call _bfd_elf_maybe_vxworks_add_dynamic_tags. * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise. * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): Likewise. * elfxx-x86.c (_bfd_x86_elf_link_hash_table_create): Likewise. (_bfd_x86_elf_size_dynamic_sections): Likewise. * elfxx-x86.h (elf_x86_link_hash_table): Remove dt_reloc, dt_reloc_sz and dt_reloc_ent. * elf-vxworks.c (_bfd_elf_maybe_vxworks_add_dynamic_tags): New. * elf-vxworks.h (_bfd_elf_maybe_vxworks_add_dynamic_tags): Likewise. * elf32-hppa.c (elf32_hppa_link_hash_table_create): Set etab.dt_pltgot_required. (elf32_hppa_size_dynamic_sections): Call _bfd_elf_add_dynamic_tags. * elf32-metag.c (elf_metag_link_hash_table_create): Set etab.dt_pltgot_required. (elf_metag_size_dynamic_sections): Call _bfd_elf_add_dynamic_tags. * elf32-sh.c (sh_elf_link_hash_table_create): Set root.dt_pltgot_required for FDPIC output. (sh_elf_size_dynamic_sections): Call _bfd_elf_maybe_vxworks_add_dynamic_tags. * elf32-xtensa.c (elf_xtensa_link_hash_table_create): Set elf.dt_pltgot_required. (elf_xtensa_size_dynamic_sections): Call _bfd_elf_add_dynamic_tags. * elf64-hppa.c (elf64_hppa_hash_table_create): Set root.dt_pltgot_required. (elf64_hppa_size_dynamic_sections): Call _bfd_elf_add_dynamic_tags. * elfnn-ia64.c (elfNN_ia64_hash_table_create): Set root.dt_pltgot_required. (elfNN_ia64_size_dynamic_sections): Set root.dt_jmprel_required for rel_pltoff_sec. Call _bfd_elf_add_dynamic_tags. * elflink.c (_bfd_elf_add_dynamic_tags): New. --- bfd/ChangeLog | 65 +++++++++++++++++++++++++++++ bfd/elf-bfd.h | 9 ++++ bfd/elf-m10300.c | 66 ++---------------------------- bfd/elf-vxworks.c | 13 ++++++ bfd/elf-vxworks.h | 3 +- bfd/elf32-arc.c | 53 +----------------------- bfd/elf32-arm.c | 73 ++------------------------------- bfd/elf32-bfin.c | 22 +--------- bfd/elf32-cr16.c | 66 ++---------------------------- bfd/elf32-frv.c | 22 +--------- bfd/elf32-hppa.c | 56 +------------------------ bfd/elf32-lm32.c | 49 +--------------------- bfd/elf32-m32r.c | 50 +---------------------- bfd/elf32-m68k.c | 47 +-------------------- bfd/elf32-metag.c | 52 +---------------------- bfd/elf32-microblaze.c | 42 ++----------------- bfd/elf32-nds32.c | 63 +--------------------------- bfd/elf32-nios2.c | 47 +-------------------- bfd/elf32-or1k.c | 50 +---------------------- bfd/elf32-ppc.c | 41 ++----------------- bfd/elf32-s390.c | 49 +--------------------- bfd/elf32-sh.c | 65 ++++------------------------- bfd/elf32-tilepro.c | 46 +-------------------- bfd/elf32-vax.c | 70 ++----------------------------- bfd/elf32-xtensa.c | 28 +++---------- bfd/elf64-alpha.c | 38 ++++------------- bfd/elf64-hppa.c | 58 +++----------------------- bfd/elf64-s390.c | 49 +--------------------- bfd/elflink.c | 93 ++++++++++++++++++++++++++++++++++++++++++ bfd/elfnn-aarch64.c | 38 +---------------- bfd/elfnn-ia64.c | 34 ++------------- bfd/elfnn-riscv.c | 46 +-------------------- bfd/elfxx-sparc.c | 36 +--------------- bfd/elfxx-tilegx.c | 46 +-------------------- bfd/elfxx-x86.c | 78 +---------------------------------- bfd/elfxx-x86.h | 3 -- 36 files changed, 257 insertions(+), 1409 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f1496779133..5d1075e743d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,68 @@ +2020-06-23 H.J. Lu + + * elf-bfd.h (elf_link_hash_table): Add dt_pltgot_required and + dt_jmprel_required. + (_bfd_elf_add_dynamic_tags): New. + * elf-m10300.c (_bfd_mn10300_elf_size_dynamic_sections): Call + _bfd_elf_add_dynamic_tags. + * elf32-arc.c (elf_arc_size_dynamic_sections): Likewise. + * elf32-bfin.c (elf32_bfinfdpic_size_dynamic_sections): Likewise. + * elf32-cr16.c (_bfd_cr16_elf_size_dynamic_sections): Likewise. + * elf32-frv.c (elf32_frvfdpic_size_dynamic_sections): Likewise. + * elf32-lm32.c (lm32_elf_size_dynamic_sections): Likewise. + * elf32-m32r.c (m32r_elf_size_dynamic_sections): Likewise. + * elf32-m68k.c (elf_m68k_size_dynamic_sections): Likewise. + * elf32-microblaze.c (microblaze_elf_size_dynamic_sections): + Likewise. + * elf32-nds32.c (nds32_elf_size_dynamic_sections): Likewise. + * elf32-nios2.c (nios2_elf32_size_dynamic_sections): Likewise. + * elf32-or1k.c (or1k_elf_size_dynamic_sections): Likewise. + * elf32-s390.c (elf_s390_size_dynamic_sections): Likewise. + * elf32-tilepro.c (tilepro_elf_size_dynamic_sections): Likewise. + * elf32-vax.c (elf_vax_size_dynamic_sections): Likewise. + * elf64-alpha.c (elf64_alpha_size_dynamic_sections): Likewise. + * elf64-s390.c (elf_s390_size_dynamic_sections): Likewise. + * elfnn-aarch64.c (elfNN_aarch64_size_dynamic_sections): + Likewise. + * elfnn-riscv.c (riscv_elf_size_dynamic_sections): Likewise. + * elfxx-tilegx.c (tilegx_elf_size_dynamic_sections): Likewise. + * elf32-arm.c (elf32_arm_size_dynamic_sections): Call + _bfd_elf_maybe_vxworks_add_dynamic_tags. + * elf32-ppc.c (ppc_elf_size_dynamic_sections): Likewise. + * elfxx-sparc.c (_bfd_sparc_elf_size_dynamic_sections): + Likewise. + * elfxx-x86.c (_bfd_x86_elf_link_hash_table_create): Likewise. + (_bfd_x86_elf_size_dynamic_sections): Likewise. + * elfxx-x86.h (elf_x86_link_hash_table): Remove dt_reloc, + dt_reloc_sz and dt_reloc_ent. + * elf-vxworks.c (_bfd_elf_maybe_vxworks_add_dynamic_tags): New. + * elf-vxworks.h (_bfd_elf_maybe_vxworks_add_dynamic_tags): + Likewise. + * elf32-hppa.c (elf32_hppa_link_hash_table_create): Set + etab.dt_pltgot_required. + (elf32_hppa_size_dynamic_sections): Call + _bfd_elf_add_dynamic_tags. + * elf32-metag.c (elf_metag_link_hash_table_create): Set + etab.dt_pltgot_required. + (elf_metag_size_dynamic_sections): Call _bfd_elf_add_dynamic_tags. + * elf32-sh.c (sh_elf_link_hash_table_create): Set + root.dt_pltgot_required for FDPIC output. + (sh_elf_size_dynamic_sections): Call + _bfd_elf_maybe_vxworks_add_dynamic_tags. + * elf32-xtensa.c (elf_xtensa_link_hash_table_create): Set + elf.dt_pltgot_required. + (elf_xtensa_size_dynamic_sections): Call + _bfd_elf_add_dynamic_tags. + * elf64-hppa.c (elf64_hppa_hash_table_create): Set + root.dt_pltgot_required. + (elf64_hppa_size_dynamic_sections): Call + _bfd_elf_add_dynamic_tags. + * elfnn-ia64.c (elfNN_ia64_hash_table_create): Set + root.dt_pltgot_required. + (elfNN_ia64_size_dynamic_sections): Set root.dt_jmprel_required + for rel_pltoff_sec. Call _bfd_elf_add_dynamic_tags. + * elflink.c (_bfd_elf_add_dynamic_tags): New. + 2020-06-22 Saagar Jha * mach-o.c: Support the new load commands by reading a linkedit diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 242750fa581..1576724511d 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -573,6 +573,12 @@ struct elf_link_hash_table /* TRUE if there are IFUNC resolvers. */ bfd_boolean ifunc_resolvers; + /* TRUE if DT_PLTGOT is a required dynamic tag. */ + bfd_boolean dt_pltgot_required; + + /* TRUE if DT_JMPREL is a required dynamic tag. */ + bfd_boolean dt_jmprel_required; + /* 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. */ @@ -2908,6 +2914,9 @@ extern asection *_bfd_elf_readonly_dynrelocs 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/elf-m10300.c b/bfd/elf-m10300.c index 5a0bb9f005a..1c436a78d5c 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -5012,9 +5012,7 @@ _bfd_mn10300_elf_size_dynamic_sections (bfd * output_bfd, struct elf32_mn10300_link_hash_table *htab = elf32_mn10300_hash_table (info); bfd * dynobj; asection * s; - bfd_boolean plt; bfd_boolean relocs; - bfd_boolean reltext; dynobj = htab->root.dynobj; BFD_ASSERT (dynobj != NULL); @@ -5052,9 +5050,7 @@ _bfd_mn10300_elf_size_dynamic_sections (bfd * output_bfd, /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ - plt = FALSE; relocs = FALSE; - reltext = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { const char * name; @@ -5069,34 +5065,16 @@ _bfd_mn10300_elf_size_dynamic_sections (bfd * output_bfd, if (streq (name, ".plt")) { /* Remember whether there is a PLT. */ - plt = s->size != 0; + ; } else if (CONST_STRNEQ (name, ".rela")) { if (s->size != 0) { - asection * target; - /* Remember whether there are any reloc sections other than .rela.plt. */ if (! streq (name, ".rela.plt")) - { - const char * outname; - - relocs = TRUE; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. The entries in the .rela.plt section - really apply to the .got section, which we - created ourselves and so know is not readonly. */ - outname = bfd_section_name (s->output_section); - target = bfd_get_section_by_name (output_bfd, outname + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0 - && (target->flags & SEC_ALLOC) != 0) - reltext = TRUE; - } + relocs = TRUE; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -5136,45 +5114,7 @@ _bfd_mn10300_elf_size_dynamic_sections (bfd * output_bfd, return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in _bfd_mn10300_elf_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. */ - if (! bfd_link_pic (info)) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0)) - return FALSE; - } - - if (plt) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return FALSE; - } - - if (reltext) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0)) - return FALSE; - } - } - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Finish up dynamic symbol handling. We set the contents of various diff --git a/bfd/elf-vxworks.c b/bfd/elf-vxworks.c index 0984cc83e6d..f8a57e1a7dc 100644 --- a/bfd/elf-vxworks.c +++ b/bfd/elf-vxworks.c @@ -295,4 +295,17 @@ elf_vxworks_finish_dynamic_entry (bfd *output_bfd, Elf_Internal_Dyn *dyn) return TRUE; } +/* Add dynamic tags. */ +bfd_boolean +_bfd_elf_maybe_vxworks_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); + return (_bfd_elf_add_dynamic_tags (output_bfd, info, + need_dynamic_reloc) + && (!htab->dynamic_sections_created + || htab->target_os != is_vxworks + || elf_vxworks_add_dynamic_entries (output_bfd, info))); +} diff --git a/bfd/elf-vxworks.h b/bfd/elf-vxworks.h index 3c7a82b9457..47a099fca72 100644 --- a/bfd/elf-vxworks.h +++ b/bfd/elf-vxworks.h @@ -33,4 +33,5 @@ bfd_boolean elf_vxworks_create_dynamic_sections (bfd *, struct bfd_link_info *, asection **); bfd_boolean elf_vxworks_add_dynamic_entries (bfd *, struct bfd_link_info *); bfd_boolean elf_vxworks_finish_dynamic_entry (bfd *, Elf_Internal_Dyn *); - +bfd_boolean _bfd_elf_maybe_vxworks_add_dynamic_tags + (bfd *, struct bfd_link_info *, bfd_boolean); diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c index 06ee60ac409..4d9d6b99928 100644 --- a/bfd/elf32-arc.c +++ b/bfd/elf32-arc.c @@ -2707,7 +2707,6 @@ elf_arc_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *dynobj; asection *s; bfd_boolean relocs_exist = FALSE; - bfd_boolean reltext_exist = FALSE; struct elf_link_hash_table *htab = elf_hash_table (info); dynobj = htab->dynobj; @@ -2762,29 +2761,7 @@ elf_arc_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, else if (strncmp (s->name, ".rela", 5) == 0) { if (s->size != 0 && s != htab->srelplt) - { - if (!reltext_exist) - { - const char *name = s->name + 5; - bfd *ibfd; - for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next) - if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour - && ibfd->flags & DYNAMIC) - { - asection *target = bfd_get_section_by_name (ibfd, name); - if (target != NULL - && elf_section_data (target)->sreloc == s - && ((target->output_section->flags - & (SEC_READONLY | SEC_ALLOC)) - == (SEC_READONLY | SEC_ALLOC))) - { - reltext_exist = TRUE; - break; - } - } - } - relocs_exist = TRUE; - } + relocs_exist = TRUE; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -2811,33 +2788,7 @@ elf_arc_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (htab->dynamic_sections_created) - { - /* TODO: Check if this is needed. */ - if (!bfd_link_pic (info)) - if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0)) - return FALSE; - - if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0) - if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)) - return FALSE; - - if (relocs_exist) - if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return FALSE; - - if (reltext_exist) - if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0)) - return FALSE; - } - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs_exist); } diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 35eee87a6d6..508f4236932 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -16673,7 +16673,6 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, { bfd * dynobj; asection * s; - bfd_boolean plt; bfd_boolean relocs; bfd *ibfd; struct elf32_arm_link_hash_table *htab; @@ -16976,7 +16975,6 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ - plt = FALSE; relocs = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { @@ -16992,7 +16990,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, if (s == htab->root.splt) { /* Remember whether there is a PLT. */ - plt = s->size != 0; + ; } else if (CONST_STRNEQ (name, ".rel")) { @@ -17044,73 +17042,8 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf32_arm_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (plt) - { - if ( !add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, - htab->use_rel ? DT_REL : DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - - if (htab->root.tlsdesc_plt - && (!add_dynamic_entry (DT_TLSDESC_PLT,0) - || !add_dynamic_entry (DT_TLSDESC_GOT,0))) - return FALSE; - } - - if (relocs) - { - if (htab->use_rel) - { - if (!add_dynamic_entry (DT_REL, 0) - || !add_dynamic_entry (DT_RELSZ, 0) - || !add_dynamic_entry (DT_RELENT, RELOC_SIZE (htab))) - return FALSE; - } - else - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab))) - 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->root, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - if (htab->root.target_os == is_vxworks - && !elf_vxworks_add_dynamic_entries (output_bfd, info)) - return FALSE; - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_maybe_vxworks_add_dynamic_tags (output_bfd, info, + relocs); } /* Size sections even though they're not dynamic. We use it to setup diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index 31ae4a68755..eed437f8f43 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -4067,26 +4067,6 @@ elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd, if (!_bfinfdpic_size_got_plt (output_bfd, &gpinfo)) return FALSE; - if (elf_hash_table (info)->dynamic_sections_created) - { - if (bfinfdpic_got_section (info)->size) - if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)) - return FALSE; - - if (bfinfdpic_pltrel_section (info)->size) - if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL) - || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)) - return FALSE; - - if (bfinfdpic_gotrel_section (info)->size) - if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELENT, - sizeof (Elf32_External_Rel))) - return FALSE; - } - s = bfd_get_linker_section (dynobj, ".dynbss"); if (s && s->size == 0) s->flags |= SEC_EXCLUDE; @@ -4095,7 +4075,7 @@ elf32_bfinfdpic_size_dynamic_sections (bfd *output_bfd, if (s && s->size == 0) s->flags |= SEC_EXCLUDE; - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, TRUE); } static bfd_boolean diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c index 62906c83a50..8a3775efc07 100644 --- a/bfd/elf32-cr16.c +++ b/bfd/elf32-cr16.c @@ -2407,9 +2407,7 @@ _bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd, { bfd * dynobj; asection * s; - bfd_boolean plt; bfd_boolean relocs; - bfd_boolean reltext; dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); @@ -2442,9 +2440,7 @@ _bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd, /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ - plt = FALSE; relocs = FALSE; - reltext = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { const char * name; @@ -2459,34 +2455,16 @@ _bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd, if (strcmp (name, ".plt") == 0) { /* Remember whether there is a PLT. */ - plt = s->size != 0; + ; } else if (CONST_STRNEQ (name, ".rela")) { if (s->size != 0) { - asection * target; - /* Remember whether there are any reloc sections other than .rela.plt. */ if (strcmp (name, ".rela.plt") != 0) - { - const char * outname; - - relocs = TRUE; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. The entries in the .rela.plt section - really apply to the .got section, which we - created ourselves and so know is not readonly. */ - outname = bfd_section_name (s->output_section); - target = bfd_get_section_by_name (output_bfd, outname + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0 - && (target->flags & SEC_ALLOC) != 0) - reltext = TRUE; - } + relocs = TRUE; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -2526,45 +2504,7 @@ _bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd, return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in _bfd_cr16_elf_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. */ - if (! bfd_link_executable (info)) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0)) - return FALSE; - } - - if (plt) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return FALSE; - } - - if (reltext) - { - if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0)) - return FALSE; - } - } - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Finish up dynamic symbol handling. We set the contents of various diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c index 83de5e67b5f..96ed5f6bb06 100644 --- a/bfd/elf32-frv.c +++ b/bfd/elf32-frv.c @@ -5466,27 +5466,7 @@ elf32_frvfdpic_size_dynamic_sections (bfd *output_bfd, if (!_frvfdpic_size_got_plt (output_bfd, &gpinfo)) return FALSE; - if (elf_hash_table (info)->dynamic_sections_created) - { - if (frvfdpic_got_section (info)->size) - if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)) - return FALSE; - - if (frvfdpic_pltrel_section (info)->size) - if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL) - || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)) - return FALSE; - - if (frvfdpic_gotrel_section (info)->size) - if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_RELENT, - sizeof (Elf32_External_Rel))) - return FALSE; - } - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, TRUE); } static bfd_boolean diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index d131f1a0794..36582d078f9 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -435,6 +435,7 @@ elf32_hppa_link_hash_table_create (bfd *abfd) return NULL; } htab->etab.root.hash_table_free = elf32_hppa_link_hash_table_free; + htab->etab.dt_pltgot_required = TRUE; htab->text_segment_base = (bfd_vma) -1; htab->data_segment_base = (bfd_vma) -1; @@ -2278,60 +2279,7 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (htab->etab.dynamic_sections_created) - { - /* Like IA-64 and HPPA64, always create a DT_PLTGOT. It - actually has nothing to do with the PLT, it is how we - communicate the LTP value of a load module to the dynamic - linker. */ -#define add_dynamic_entry(TAG, VAL) \ - _bfd_elf_add_dynamic_entry (info, TAG, VAL) - - if (!add_dynamic_entry (DT_PLTGOT, 0)) - return FALSE; - - /* Add some entries to the .dynamic section. We fill in the - values later, in elf32_hppa_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. */ - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->etab.srelplt->size != 0) - { - if (!add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - 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->etab, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* External entry points for sizing and building linker stubs. */ diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c index aba821ffd1a..2be3b926442 100644 --- a/bfd/elf32-lm32.c +++ b/bfd/elf32-lm32.c @@ -2060,53 +2060,8 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd, return FALSE; } - if (htab->root.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in lm32_elf_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) - - if (bfd_link_executable (info)) - { - if (! add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->root.splt->size != 0) - { - if (! add_dynamic_entry (DT_PLTGOT, 0) - || ! add_dynamic_entry (DT_PLTRELSZ, 0) - || ! add_dynamic_entry (DT_PLTREL, DT_RELA) - || ! add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (! add_dynamic_entry (DT_RELA, 0) - || ! add_dynamic_entry (DT_RELASZ, 0) - || ! add_dynamic_entry (DT_RELAENT, - sizeof (Elf32_External_Rela))) - 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->root, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (! add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } -#undef add_dynamic_entry + if (!_bfd_elf_add_dynamic_tags (output_bfd, info, relocs)) + return FALSE; /* Allocate .rofixup section. */ if (IS_FDPIC (output_bfd)) diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index 740be933829..dfdf8f38c77 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -2137,55 +2137,7 @@ m32r_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (htab->root.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in m32r_elf_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) - - if (bfd_link_executable (info)) - { - if (! add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->root.splt->size != 0) - { - if (! add_dynamic_entry (DT_PLTGOT, 0) - || ! add_dynamic_entry (DT_PLTRELSZ, 0) - || ! add_dynamic_entry (DT_PLTREL, DT_RELA) - || ! add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (! add_dynamic_entry (DT_RELA, 0) - || ! add_dynamic_entry (DT_RELASZ, 0) - || ! add_dynamic_entry (DT_RELAENT, - sizeof (Elf32_External_Rela))) - 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->root, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (! add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Relocate an M32R/D ELF section. diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 868435a4442..39c5e1c2cc9 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -3052,7 +3052,6 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, { bfd *dynobj; asection *s; - bfd_boolean plt; bfd_boolean relocs; dynobj = elf_hash_table (info)->dynobj; @@ -3095,7 +3094,6 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ - plt = FALSE; relocs = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { @@ -3111,7 +3109,7 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (strcmp (name, ".plt") == 0) { /* Remember whether there is a PLT. */ - plt = s->size != 0; + ; } else if (CONST_STRNEQ (name, ".rela")) { @@ -3160,48 +3158,7 @@ elf_m68k_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_m68k_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (plt) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - return FALSE; - } - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* This function is called via elf_link_hash_traverse if we are diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c index 7938b24d2a5..fc5f3a99d47 100644 --- a/bfd/elf32-metag.c +++ b/bfd/elf32-metag.c @@ -1039,6 +1039,7 @@ elf_metag_link_hash_table_create (bfd *abfd) return NULL; } htab->etab.root.hash_table_free = elf_metag_link_hash_table_free; + htab->etab.dt_pltgot_required = TRUE; return &htab->etab.root; } @@ -2902,56 +2903,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, } } - if (htab->etab.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_metag_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) - - if (!add_dynamic_entry (DT_PLTGOT, 0)) - return FALSE; - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->etab.srelplt->size != 0) - { - if (!add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - 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->etab, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Finish up dynamic symbol handling. We set the contents of various diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c index caf0f2edcaa..693fc71f730 100644 --- a/bfd/elf32-microblaze.c +++ b/bfd/elf32-microblaze.c @@ -3103,45 +3103,9 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in microblaze_elf_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - return FALSE; - - if (htab->elf.splt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0) - || !add_dynamic_entry (DT_BIND_NOW, 1)) - return FALSE; - } - - if (info->flags & DF_TEXTREL) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } -#undef add_dynamic_entry - return TRUE; + /* ??? Force DF_BIND_NOW? */ + info->flags |= DF_BIND_NOW; + return _bfd_elf_add_dynamic_tags (output_bfd, info, TRUE); } /* Finish up dynamic symbol handling. We set the contents of various diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c index d8726359d56..186ab36e89c 100644 --- a/bfd/elf32-nds32.c +++ b/bfd/elf32-nds32.c @@ -4262,7 +4262,6 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *dynobj; asection *s; bfd_boolean relocs; - bfd_boolean plt; bfd *ibfd; htab = nds32_elf_hash_table (info); @@ -4422,7 +4421,6 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ - plt = FALSE; relocs = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { @@ -4433,7 +4431,7 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, { /* Strip this section if we don't need it; see the comment below. */ - plt = s->size != 0; + ; } else if (s == elf_hash_table (info)->sgot) { @@ -4483,64 +4481,7 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - - if (htab->root.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in nds32_elf_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (elf_hash_table (info)->splt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (htab->tls_desc_trampoline && plt) - { - if (htab->root.tlsdesc_plt - && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) - || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - 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->root, - _bfd_elf_maybe_set_textrel, - (void *) info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } static bfd_reloc_status_type diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c index cdc11f97159..01c2fe5ee54 100644 --- a/bfd/elf32-nios2.c +++ b/bfd/elf32-nios2.c @@ -5877,52 +5877,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (htab->res_n_size) elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info); - if (htab->root.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_nios2_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) - - if (!bfd_link_pic (info) && !add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - - if (htab->root.sgotplt->size != 0 - && !add_dynamic_entry (DT_PLTGOT, 0)) - return FALSE; - - if (htab->root.splt->size != 0 - && (!add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0))) - return FALSE; - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, - sizeof (Elf32_External_Rela))) - return FALSE; - - if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->root, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0 - && !add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - - if (!bfd_link_pic (info) && !add_dynamic_entry (DT_NIOS2_GP, 0)) - return FALSE; - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Free the derived linker hash table. */ diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c index b25f96b42de..7c02d004cc7 100644 --- a/bfd/elf32-or1k.c +++ b/bfd/elf32-or1k.c @@ -3078,55 +3078,7 @@ or1k_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (htab->root.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in or1k_elf_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) - - if (bfd_link_executable (info)) - { - if (! add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->root.splt->size != 0) - { - if (! add_dynamic_entry (DT_PLTGOT, 0) - || ! add_dynamic_entry (DT_PLTRELSZ, 0) - || ! add_dynamic_entry (DT_PLTREL, DT_RELA) - || ! add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (! add_dynamic_entry (DT_RELA, 0) - || ! add_dynamic_entry (DT_RELASZ, 0) - || ! add_dynamic_entry (DT_RELAENT, - sizeof (Elf32_External_Rela))) - 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->root, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (! add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } - -#undef add_dynamic_entry - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Copy the extra info we tack onto an elf_link_hash_entry. */ diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 89c069b3c51..5155dc935f9 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5822,20 +5822,9 @@ ppc_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 != NULL && htab->elf.splt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } + if (!_bfd_elf_maybe_vxworks_add_dynamic_tags (output_bfd, info, + relocs)) + return FALSE; if (htab->plt_type == PLT_NEW && htab->glink != NULL @@ -5849,30 +5838,6 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd, && !add_dynamic_entry (DT_PPC_OPT, PPC_OPT_TLS)) return FALSE; } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - 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 (elf_hash_table (info), - _bfd_elf_maybe_set_textrel, - info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - if (htab->elf.target_os == is_vxworks - && !elf_vxworks_add_dynamic_entries (output_bfd, info)) - return FALSE; } #undef add_dynamic_entry diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 5bd63fe1c94..ceb97879177 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -1965,54 +1965,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (htab->elf.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_s390_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->elf.splt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - 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 (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Return the base VMA address which should be subtracted from real addresses diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 84afe44f430..8c74ef7c778 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -2255,7 +2255,11 @@ sh_elf_link_hash_table_create (bfd *abfd) return NULL; } - ret->fdpic_p = fdpic_object_p (abfd); + if (fdpic_object_p (abfd)) + { + ret->root.dt_pltgot_required = TRUE; + ret->fdpic_p = TRUE; + } return &ret->root.root; } @@ -3196,63 +3200,8 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (htab->root.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in sh_elf_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) - - if (bfd_link_executable (info)) - { - if (! add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->root.splt->size != 0) - { - if (! add_dynamic_entry (DT_PLTGOT, 0) - || ! add_dynamic_entry (DT_PLTRELSZ, 0) - || ! add_dynamic_entry (DT_PLTREL, DT_RELA) - || ! add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - else if ((elf_elfheader (output_bfd)->e_flags & EF_SH_FDPIC)) - { - if (! add_dynamic_entry (DT_PLTGOT, 0)) - return FALSE; - } - - if (relocs) - { - if (! add_dynamic_entry (DT_RELA, 0) - || ! add_dynamic_entry (DT_RELASZ, 0) - || ! add_dynamic_entry (DT_RELAENT, - sizeof (Elf32_External_Rela))) - 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->root, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (! add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - if (htab->root.target_os == is_vxworks - && !elf_vxworks_add_dynamic_entries (output_bfd, info)) - return FALSE; - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_maybe_vxworks_add_dynamic_tags (output_bfd, info, + relocs); } /* Add a dynamic relocation to the SRELOC section. */ diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c index 2d78f3c9c89..5b3e80a5fc9 100644 --- a/bfd/elf32-tilepro.c +++ b/bfd/elf32-tilepro.c @@ -2381,51 +2381,7 @@ tilepro_elf_size_dynamic_sections (bfd *output_bfd, return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in tilepro_elf_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->elf.srelplt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, TILEPRO_ELF_RELA_BYTES)) - 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) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, TRUE); } /* Return the base VMA address which should be subtracted from real addresses diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index b5c3d8943a8..58a4a8bdfbe 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -1029,9 +1029,7 @@ elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { bfd *dynobj; asection *s; - bfd_boolean plt; bfd_boolean relocs; - bfd_boolean reltext; dynobj = elf_hash_table (info)->dynobj; BFD_ASSERT (dynobj != NULL); @@ -1067,9 +1065,7 @@ elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) /* The check_relocs and adjust_dynamic_symbol entry points have determined the sizes of the various dynamic sections. Allocate memory for them. */ - plt = FALSE; relocs = FALSE; - reltext = FALSE; for (s = dynobj->sections; s != NULL; s = s->next) { const char *name; @@ -1084,33 +1080,14 @@ elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) if (strcmp (name, ".plt") == 0) { /* Remember whether there is a PLT. */ - plt = s->size != 0; + ; } else if (CONST_STRNEQ (name, ".rela")) { if (s->size != 0) { - asection *target; - - /* Remember whether there are any reloc sections other - than .rela.plt. */ if (strcmp (name, ".rela.plt") != 0) - { - const char *outname; - - relocs = TRUE; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. .rela.plt is actually associated with - .got.plt, which is never readonly. */ - outname = bfd_section_name (s->output_section); - target = bfd_get_section_by_name (output_bfd, outname + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0 - && (target->flags & SEC_ALLOC) != 0) - reltext = TRUE; - } + relocs = TRUE; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -1148,48 +1125,7 @@ elf_vax_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_vax_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) - - if (!bfd_link_pic (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (plt) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - return FALSE; - } - - if (reltext || (info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* This function is called via elf_vax_link_hash_traverse if we are diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index b223424cce4..45727b3f805 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -766,6 +766,7 @@ elf_xtensa_link_hash_table_create (bfd *abfd) tlsbase->root.type = bfd_link_hash_new; tlsbase->root.u.undef.abfd = NULL; tlsbase->non_elf = 0; + ret->elf.dt_pltgot_required = TRUE; ret->tlsbase = elf_xtensa_hash_entry (tlsbase); ret->tlsbase->tls_type = GOT_UNKNOWN; @@ -1767,30 +1768,11 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, #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 (relplt) - { - if (!add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relgot) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) - return FALSE; - } + if (!_bfd_elf_add_dynamic_tags (output_bfd, info, + relplt || relgot)) + return FALSE; - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0) + if (!add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0) || !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0)) return FALSE; } diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 0b31d450dca..a6b20982609 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -2910,38 +2910,14 @@ elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, #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 (relplt) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - - if (elf64_alpha_use_secureplt - && !add_dynamic_entry (DT_ALPHA_PLTRO, 1)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) - return FALSE; + if (!_bfd_elf_add_dynamic_tags (output_bfd, info, + relocs || relplt)) + return FALSE; - if (info->flags & DF_TEXTREL) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } + if (relplt + && elf64_alpha_use_secureplt + && !add_dynamic_entry (DT_ALPHA_PLTRO, 1)) + return FALSE; } #undef add_dynamic_entry diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index 1088bcc21f0..dd52b351182 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -302,6 +302,7 @@ elf64_hppa_hash_table_create (bfd *abfd) return NULL; } + htab->root.dt_pltgot_required = TRUE; htab->text_segment_base = (bfd_vma) -1; htab->data_segment_base = (bfd_vma) -1; @@ -1526,9 +1527,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) bfd *dynobj; bfd *ibfd; asection *sec; - bfd_boolean plt; bfd_boolean relocs; - bfd_boolean reltext; hppa_info = hppa_link_hash_table (info); if (hppa_info == NULL) @@ -1736,9 +1735,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) allocate_dynrel_entries, &data); /* The sizes of all the sections are set. Allocate memory for them. */ - plt = FALSE; relocs = FALSE; - reltext = FALSE; for (sec = dynobj->sections; sec != NULL; sec = sec->next) { const char *name; @@ -1753,7 +1750,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) if (strcmp (name, ".plt") == 0) { /* Remember whether there is a PLT. */ - plt = sec->size != 0; + ; } else if (strcmp (name, ".opd") == 0 || CONST_STRNEQ (name, ".dlt") @@ -1766,28 +1763,10 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { if (sec->size != 0) { - asection *target; - /* Remember whether there are any reloc sections other than .rela.plt. */ if (strcmp (name, ".rela.plt") != 0) - { - const char *outname; - - relocs = TRUE; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. The entries in the .rela.plt section - really apply to the .got section, which we - created ourselves and so know is not readonly. */ - outname = bfd_section_name (sec->output_section); - target = bfd_get_section_by_name (output_bfd, outname + 4); - if (target != NULL - && (target->flags & SEC_READONLY) != 0 - && (target->flags & SEC_ALLOC) != 0) - reltext = TRUE; - } + relocs = TRUE; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -1840,8 +1819,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) #define add_dynamic_entry(TAG, VAL) \ _bfd_elf_add_dynamic_entry (info, TAG, VAL) - if (!add_dynamic_entry (DT_HP_DLD_FLAGS, 0) - || !add_dynamic_entry (DT_PLTGOT, 0)) + if (!add_dynamic_entry (DT_HP_DLD_FLAGS, 0)) return FALSE; /* Add some entries to the .dynamic section. We fill in the @@ -1851,8 +1829,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) dynamic linker and used by the debugger. */ if (! bfd_link_pic (info)) { - if (!add_dynamic_entry (DT_DEBUG, 0) - || !add_dynamic_entry (DT_HP_DLD_HOOK, 0) + if (!add_dynamic_entry (DT_HP_DLD_HOOK, 0) || !add_dynamic_entry (DT_HP_LOAD_MAP, 0)) return FALSE; } @@ -1861,33 +1838,10 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) Required by HPUX 11.00 patch PHSS_26559. */ if (!add_dynamic_entry (DT_FLAGS, (info)->flags)) return FALSE; - - if (plt) - { - if (!add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) - return FALSE; - } - - if (reltext) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - info->flags |= DF_TEXTREL; - } } #undef add_dynamic_entry - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Called after we have output the symbol into the dynamic symbol diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 5b95b5f814a..da72c78753e 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -1919,54 +1919,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (htab->elf.dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_s390_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->elf.splt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) - 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 (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs); } /* Return the base VMA address which should be subtracted from real addresses diff --git a/bfd/elflink.c b/bfd/elflink.c index 14d8d159da7..998b72f2281 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -14897,3 +14897,96 @@ _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 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->dt_pltgot_required || 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->dt_jmprel_required || 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 (htab->tlsdesc_plt + && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) + || !add_dynamic_entry (DT_TLSDESC_GOT, 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->ifunc_resolvers) + info->callbacks->einfo + (_("%P: warning: GNU indirect functions with DT_TEXTREL " + "may result in a segfault at runtime; recompile with %s\n"), + bfd_link_dll (info) ? "-fPIC" : "-fPIE"); + + if (!add_dynamic_entry (DT_TEXTREL, 0)) + return FALSE; + } + } + } +#undef add_dynamic_entry + + return TRUE; +} diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index eff27f6ae35..8f1e5e1e456 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -9101,29 +9101,15 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, #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 (!_bfd_elf_add_dynamic_tags (output_bfd, info, relocs)) + return FALSE; if (htab->root.splt->size != 0) { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - if (htab->variant_pcs && !add_dynamic_entry (DT_AARCH64_VARIANT_PCS, 0)) return FALSE; - if (htab->root.tlsdesc_plt - && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) - || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) - return FALSE; - if ((elf_aarch64_tdata (output_bfd)->plt_type == PLT_BTI_PAC) && (!add_dynamic_entry (DT_AARCH64_BTI_PLT, 0) || !add_dynamic_entry (DT_AARCH64_PAC_PLT, 0))) @@ -9137,26 +9123,6 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, && !add_dynamic_entry (DT_AARCH64_PAC_PLT, 0)) return FALSE; } - - if (relocs) - { - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab))) - 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->root, - _bfd_elf_maybe_set_textrel, info); - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } } #undef add_dynamic_entry diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c index ba46270f866..4d6a0279e31 100644 --- a/bfd/elfnn-ia64.c +++ b/bfd/elfnn-ia64.c @@ -1473,6 +1473,7 @@ elfNN_ia64_hash_table_create (bfd *abfd) return NULL; } ret->root.root.hash_table_free = elfNN_ia64_link_hash_table_free; + ret->root.dt_pltgot_required = TRUE; return &ret->root.root; } @@ -2994,7 +2995,6 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, struct elfNN_ia64_link_hash_table *ia64_info; asection *sec; bfd *dynobj; - bfd_boolean relplt = FALSE; ia64_info = elfNN_ia64_hash_table (info); if (ia64_info == NULL) @@ -3148,7 +3148,7 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, ia64_info->rel_pltoff_sec = NULL; else { - relplt = TRUE; + ia64_info->root.dt_jmprel_required = TRUE; /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ sec->reloc_count = 0; @@ -3194,40 +3194,14 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, later (in finish_dynamic_sections) but we must add the entries now so that we get the correct size for the .dynamic section. */ - if (bfd_link_executable (info)) - { - /* 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) - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0)) - return FALSE; - if (!add_dynamic_entry (DT_PLTGOT, 0)) + if (!_bfd_elf_add_dynamic_tags (output_bfd, info, TRUE)) return FALSE; - if (relplt) - { - if (!add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela))) + if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0)) return FALSE; - - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } } /* ??? Perhaps force __gp local. */ diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 00553f77464..a5fa415309a 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -1261,51 +1261,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in riscv_elf_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->elf.srelplt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela))) - 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) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, TRUE); } #define TP_OFFSET 0 diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 4dcdd1793eb..bd046aca6c8 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2590,39 +2590,10 @@ _bfd_sparc_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.srelplt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, - SPARC_ELF_RELA_BYTES (htab))) + if (!_bfd_elf_maybe_vxworks_add_dynamic_tags (output_bfd, info, + TRUE)) 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) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - if (ABI_64_P (output_bfd)) { int reg; @@ -2678,9 +2649,6 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, eht->dynsymcount++; } } - if (htab->elf.target_os == is_vxworks - && !elf_vxworks_add_dynamic_entries (output_bfd, info)) - return FALSE; } #undef add_dynamic_entry diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c index 9d8b42e1de0..c0494a4ced5 100644 --- a/bfd/elfxx-tilegx.c +++ b/bfd/elfxx-tilegx.c @@ -2621,51 +2621,7 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return FALSE; } - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in tilegx_elf_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) - - if (bfd_link_executable (info)) - { - if (!add_dynamic_entry (DT_DEBUG, 0)) - return FALSE; - } - - if (htab->elf.srelplt->size != 0) - { - if (!add_dynamic_entry (DT_PLTGOT, 0) - || !add_dynamic_entry (DT_PLTRELSZ, 0) - || !add_dynamic_entry (DT_PLTREL, DT_RELA) - || !add_dynamic_entry (DT_JMPREL, 0)) - return FALSE; - } - - if (!add_dynamic_entry (DT_RELA, 0) - || !add_dynamic_entry (DT_RELASZ, 0) - || !add_dynamic_entry (DT_RELAENT, TILEGX_ELF_RELA_BYTES (htab))) - 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) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_add_dynamic_tags (output_bfd, info, TRUE); } /* Return the base VMA address which should be subtracted from real addresses diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 29b020442f8..5b1793ae807 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -721,9 +721,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"; @@ -748,9 +745,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; @@ -1362,76 +1356,8 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, + PLT_FDE_LEN_OFFSET)); } - if (htab->elf.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) - - 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->elf.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->elf.ifunc_resolvers) - info->callbacks->einfo - (_("%P: warning: GNU indirect functions with DT_TEXTREL " - "may result in a segfault at runtime; recompile with %s\n"), - bfd_link_dll (info) ? "-fPIC" : "-fPIE"); - - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return FALSE; - } - } - if (htab->elf.target_os == is_vxworks - && !elf_vxworks_add_dynamic_entries (output_bfd, info)) - return FALSE; - } -#undef add_dynamic_entry - - return TRUE; + return _bfd_elf_maybe_vxworks_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 915cd4d5d04..7541554bafb 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -510,9 +510,6 @@ struct elf_x86_link_hash_table bfd_vma (*r_sym) (bfd_vma); bfd_boolean (*is_reloc_section) (const char *); 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; -- 2.30.2