use linker created stub bfd for dynobj

Alan Modra amodra@gmail.com
Thu Aug 6 04:21:09 GMT 2026


A linker created bfd is a good choice for somewhere to attach linker
created dynamic sections.  It is always the correct format and doesn't
have anything other than linker generated info to potentially confuse
ld.  It is always the first bfd too, if ordering matters.

For those targets that create a stub bfd, this patch makes use of that
bfd for the linker dynobj.  I've done that by allowing the stub bfd
in _bfd_elf_link_dynobj, and using that function wherever dynobj is
assigned in ELF targets that currently support dynamic linking.

For targets that don't create a stub bfd, _bfd_elf_link_dynobj has
fewer conditions on the bfd chosen for dynobj than those for running
check relocs, so _bfd_elf_link_dynobj return in check_relocs is always
non-NULL.  Despite that I thought it good defensive programming
practice to check the return value anyway.

One testcase needs updating for .dynamic being placed earlier if left
as an orphan.  I chose to provide the missing sections in the test
linker script rather than changing expected output.

bfd/
	* elf-bfd.h (struct elf_link_hash_table <dynobj>): Update comment.
	(_bfd_elf_link_dynobj_internal): Declare.
	(_bfd_elf_link_dynobj): Define.
	* elflink.c (_bfd_elf_link_dynobj_internal): Rename from
	_bfd_elf_link_dynobj.  Delete "abfd" param.  Add "report"
	param.  Don't exclude any object satisfying compatible_format
	from being used as dynobj.  Do complain if "report" and no
	suitable object found.
	* elf-m10300.c (mn10300_elf_check_relocs): Replace assignment
	from abfd to dynobj with call to _bfd_elf_link_dynobj.
	* elf32-arc.c (elf_arc_check_relocs): Likewise.
	* elf32-arm.c (elf32_arm_check_relocs): Likewise.
	* elf32-bfin.c (bfin_check_relocs): Likewise.
	(bfinfdpic_check_relocs): Likewise.
	* elf32-cr16.c (cr16_elf_check_relocs): Likewise.
	* elf32-cris.c (cris_elf_check_relocs): Likewise.
	* elf32-csky.c (csky_elf_check_relocs): Likewise.
	* elf32-frv.c (elf32_frv_check_relocs): Likewise.
	* elf32-lm32.c (lm32_elf_check_relocs): Likewise.
	* elf32-m32c.c (m32c_elf_check_relocs): Likewise.
	* elf32-m32r.c (m32r_elf_check_relocs): Likewise.
	* elf32-m68k.c (elf_m68k_check_relocs): Likewise.
	* elf32-metag.c (elf_metag_check_relocs): Likewise.
	* elf32-microblaze.c (microblaze_elf_check_relocs): Likewise.
	* elf32-nds32.c (nds32_elf_check_relocs): Likewise.
	* elf32-or1k.c (or1k_elf_check_relocs): Likewise.
	* elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise.
	(ppc_elf_check_relocs): Likewise.
	* elf32-rl78.c (rl78_elf_check_relocs): Likewise.
	* elf32-s390.c (elf_s390_check_relocs): Likewise.
	* elf32-score.c (s3_bfd_score_elf_check_relocs): Likewise.
	* elf32-score7.c (s7_bfd_score_elf_check_relocs): Likewise.
	* elf32-sh.c (sh_elf_check_relocs): Likewise.
	* elf32-spu.c (spu_elf_create_sections): Likewise.
	* elf32-tic6x.c (elf32_tic6x_check_relocs): Likewise.
	* elf32-tilepro.c (tilepro_elf_check_relocs): Likewise.
	* elf32-vax.c (elf_vax_check_relocs): Likewise.
	* elf32-xstormy16.c (xstormy16_elf_check_relocs): Likewise.
	* elf64-alpha.c (elf64_alpha_check_relocs): Likewise.
	* elf64-ia64-vms.c (elf64_ia64_check_relocs): Likewise.
	* elf64-s390.c (elf_s390_check_relocs): Likewise.
	* elfnn-aarch64.c (elfNN_aarch64_check_relocs): Likewise.
	* elfnn-ia64.c (elfNN_ia64_check_relocs): Likewise.
	* elfnn-kvx.c (elfNN_kvx_check_relocs): Likewise.
	* elfnn-loongarch.c (loongarch_elf_check_relocs): Likewise.
	* elfnn-riscv.c (riscv_elf_check_relocs): Likewise.
	* elfxx-mips.c (_bfd_mips_elf_check_relocs): Likewise.
	* elfxx-sparc.c (_bfd_sparc_elf_check_relocs): Likewise.
	* elfxx-tilegx.c (tilegx_elf_check_relocs): Likewise.
	* elf64-hppa.c (get_reloc_section): Delete forward decl.  Add
	bfd_link_info param.  Replace assignment from abfd to dynobj
	with call to _bfd_elf_link_dynobj.
	(get_opd, get_plt, get_dlt, get_stub): Delete abfd param.
	Replace assignment from abfd to dynobj with call to
	_bfd_elf_link_dynobj.  Update all callers.
	* elf64-ia64-vms.c (get_got, get_fptr, get_pltoff),
	(get_reloc_section): Replace abfd param with bfd_link_info
	param.  Replace assignment from abfd to dynobj with call to
	_bfd_elf_link_dynobj.  Update all callers.
	* elfnn-ia64.c (get_got, get_fptr, get_pltoff): Delete bfd
	param.  Use _bfd_elf_link_dynobj.
	(get_reloc_section): Replace ia64_info with info param.  Use
	_bfd_elf_link_dynobj.
	* elfxx-x86.c (_bfd_x86_elf_link_setup_gnu_properties): Use
	_bfd_elf_link_dynobj_internal.
ld/
	* testsuite/ld-aarch64/relocs.ld: Add .rodata, various .data.*
	and .dynamic.
---
 bfd/elf-bfd.h                     | 10 +++--
 bfd/elf-m10300.c                  |  4 +-
 bfd/elf32-arc.c                   |  6 +--
 bfd/elf32-arm.c                   |  7 ++--
 bfd/elf32-bfin.c                  | 12 +++++-
 bfd/elf32-cr16.c                  |  4 +-
 bfd/elf32-cris.c                  |  6 ++-
 bfd/elf32-csky.c                  | 10 +++--
 bfd/elf32-frv.c                   |  6 ++-
 bfd/elf32-lm32.c                  | 18 +++++++--
 bfd/elf32-m32c.c                  |  6 ++-
 bfd/elf32-m32r.c                  | 12 +++++-
 bfd/elf32-m68k.c                  |  6 ++-
 bfd/elf32-metag.c                 | 20 ++++++----
 bfd/elf32-microblaze.c            | 19 +++++-----
 bfd/elf32-nds32.c                 | 12 +++++-
 bfd/elf32-or1k.c                  | 15 ++++++--
 bfd/elf32-ppc.c                   | 25 ++++++++-----
 bfd/elf32-rl78.c                  |  6 ++-
 bfd/elf32-s390.c                  | 20 ++++++----
 bfd/elf32-score.c                 | 18 +++++++--
 bfd/elf32-score7.c                | 18 +++++++--
 bfd/elf32-sh.c                    | 10 +++--
 bfd/elf32-spu.c                   |  6 +--
 bfd/elf32-tic6x.c                 | 10 +++--
 bfd/elf32-tilepro.c               |  7 ++--
 bfd/elf32-vax.c                   |  6 ++-
 bfd/elf32-xstormy16.c             |  6 ++-
 bfd/elf64-alpha.c                 |  4 +-
 bfd/elf64-hppa.c                  | 62 ++++++++++++++-----------------
 bfd/elf64-ia64-vms.c              | 47 ++++++++++++-----------
 bfd/elf64-s390.c                  | 20 ++++++----
 bfd/elflink.c                     | 16 +++-----
 bfd/elfnn-aarch64.c               | 21 ++++++-----
 bfd/elfnn-ia64.c                  | 43 ++++++++++-----------
 bfd/elfnn-kvx.c                   | 15 +++++---
 bfd/elfnn-loongarch.c             |  7 ++--
 bfd/elfnn-riscv.c                 |  5 ++-
 bfd/elfxx-mips.c                  | 12 +++++-
 bfd/elfxx-sparc.c                 |  5 ++-
 bfd/elfxx-tilegx.c                |  7 ++--
 bfd/elfxx-x86.c                   | 31 +---------------
 ld/testsuite/ld-aarch64/relocs.ld | 15 ++++++++
 43 files changed, 370 insertions(+), 245 deletions(-)

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index f7886a57aa8..421ab6346d3 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -664,9 +664,7 @@ struct elf_link_hash_table
   /* TRUE if there are base symbols.  */
   bool has_base_symbols;
 
-  /* 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.  */
+  /* The BFD used to hold special sections created by the linker.  */
   bfd *dynobj;
 
   /* The value to use when initialising got.refcount/offset and
@@ -2731,6 +2729,12 @@ extern unsigned int _bfd_elf_default_action_discarded
 extern struct bfd_section *bfd_elf_tls_setup
   (struct bfd_link_info *);
 
+extern bfd *_bfd_elf_link_dynobj_internal
+  (struct bfd_link_info *, bool) ATTRIBUTE_HIDDEN;
+static inline bfd *
+_bfd_elf_link_dynobj (struct bfd_link_info *info)
+{ return _bfd_elf_link_dynobj_internal (info, true); }
+
 extern bool bfd_elf_link_create_dynamic_sections
   (struct bfd_link_info *);
 extern bool _bfd_elf_omit_section_dynsym_default
diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c
index 04cf702a067..2aef1ddddf7 100644
--- a/bfd/elf-m10300.c
+++ b/bfd/elf-m10300.c
@@ -1115,7 +1115,9 @@ mn10300_elf_check_relocs (bfd *abfd,
 	    case R_MN10300_TLS_LD:
 	    case R_MN10300_TLS_GOTIE:
 	    case R_MN10300_TLS_IE:
-	      elf_hash_table (info)->dynobj = dynobj = abfd;
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		goto fail;
 	      if (! _bfd_mn10300_elf_create_got_section (dynobj, info))
 		goto fail;
 	      break;
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index 19011c416af..29b173cf486 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -1987,10 +1987,10 @@ elf_arc_check_relocs (bfd *			 abfd,
   if (bfd_link_relocatable (info))
     return true;
 
-  if (htab->dynobj == NULL)
-    htab->dynobj = abfd;
+  dynobj = _bfd_elf_link_dynobj (info);
+  if (dynobj == NULL)
+    return false;
 
-  dynobj = (elf_hash_table (info))->dynobj;
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index b280cf5e069..e7c7b5680e4 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -15216,14 +15216,13 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
     return false;
 
   sreloc = NULL;
+  dynobj = _bfd_elf_link_dynobj (info);
+  if (dynobj == NULL)
+    return false;
 
-  if (htab->root.dynobj == NULL)
-    htab->root.dynobj = abfd;
   if (!create_ifunc_sections (info))
     return false;
 
-  dynobj = htab->root.dynobj;
-
   symtab_hdr = & elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
   nsyms = NUM_SHDR_ENTRIES (symtab_hdr);
diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c
index 82025e6b242..38546621864 100644
--- a/bfd/elf32-bfin.c
+++ b/bfd/elf32-bfin.c
@@ -1226,7 +1226,11 @@ bfin_check_relocs (bfd * abfd,
 	  /* Fall through.  */
 
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 
 	  if (!_bfd_elf_create_got_section (dynobj, info))
 	    return false;
@@ -4559,7 +4563,11 @@ bfinfdpic_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  if (IS_FDPIC (abfd))
 	    {
 	      if (dynobj == NULL)
-		elf_hash_table (info)->dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!_bfin_create_got_section (dynobj, info))
 		return false;
 	    }
diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c
index 2aed75aacbe..91ddbefb841 100644
--- a/bfd/elf32-cr16.c
+++ b/bfd/elf32-cr16.c
@@ -744,7 +744,9 @@ cr16_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
 	    {
 	    case R_CR16_GOT_REGREL20:
 	    case R_CR16_GOTC_REGREL20:
-	      elf_hash_table (info)->dynobj = dynobj = abfd;
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		goto fail;
 	      if (! _bfd_cr16_elf_create_got_section (dynobj, info))
 		goto fail;
 	      break;
diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c
index aefd3db10f5..1df98bd55aa 100644
--- a/bfd/elf32-cris.c
+++ b/bfd/elf32-cris.c
@@ -3036,7 +3036,11 @@ cris_elf_check_relocs (bfd *abfd,
 	case R_CRIS_16_GOTPLT:
 	case R_CRIS_32_GOTPLT:
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 
 	  if (sgot == NULL)
 	    {
diff --git a/bfd/elf32-csky.c b/bfd/elf32-csky.c
index 877c6ee86d7..af36392a759 100644
--- a/bfd/elf32-csky.c
+++ b/bfd/elf32-csky.c
@@ -2569,8 +2569,9 @@ csky_elf_check_relocs (bfd * abfd,
 		 this reloc.  */
 	      if (sreloc == NULL)
 		{
-		  if (htab->elf.dynobj == NULL)
-		    htab->elf.dynobj = abfd;
+		  if (htab->elf.dynobj == NULL
+		      && !_bfd_elf_link_dynobj (info))
+		    return false;
 
 		  sreloc = _bfd_elf_make_dynamic_reloc_section
 		    (sec, htab->elf.dynobj, 2, abfd, true);
@@ -2767,8 +2768,9 @@ csky_elf_check_relocs (bfd * abfd,
 	case R_CKCORE_GOTOFF_IMM18:
 	  if (htab->elf.sgot == NULL)
 	    {
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
 		return false;
 	    }
diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c
index d19bb5a1499..42efc672b34 100644
--- a/bfd/elf32-frv.c
+++ b/bfd/elf32-frv.c
@@ -6072,7 +6072,11 @@ elf32_frv_check_relocs (bfd *abfd,
 	case R_FRV_LABEL24:
 	case R_FRV_32:
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 	  if (!_frv_create_got_section (dynobj, info))
 	    return false;
 	  if (! IS_FDPIC (abfd))
diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c
index 7014a522522..72a021b7d12 100644
--- a/bfd/elf32-lm32.c
+++ b/bfd/elf32-lm32.c
@@ -1169,7 +1169,11 @@ lm32_elf_check_relocs (bfd *abfd,
 	    case R_LM32_GOTOFF_HI16:
 	    case R_LM32_GOTOFF_LO16:
 	      if (dynobj == NULL)
-		htab->root.dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!_bfd_elf_create_got_section (dynobj, info))
 		return false;
 	      break;
@@ -1185,7 +1189,11 @@ lm32_elf_check_relocs (bfd *abfd,
 	      /* FDPIC requires a GOT if there is a .rofixup section
 		 (Normal ELF doesn't). */
 	      if (dynobj == NULL)
-		htab->root.dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!_bfd_elf_create_got_section (dynobj, info))
 		return false;
 	      /* Create .rofixup section */
@@ -1202,7 +1210,11 @@ lm32_elf_check_relocs (bfd *abfd,
 	      if (htab->sfixup32 == NULL)
 		{
 		  if (dynobj == NULL)
-		    htab->root.dynobj = dynobj = abfd;
+		    {
+		      dynobj = _bfd_elf_link_dynobj (info);
+		      if (dynobj == NULL)
+			return false;
+		    }
 		  if (! create_rofixup_section (dynobj, info))
 		    return false;
 		}
diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c
index c8c95e89b94..7fcf8216a3f 100644
--- a/bfd/elf32-m32c.c
+++ b/bfd/elf32-m32c.c
@@ -698,7 +698,11 @@ m32c_elf_check_relocs
 	     for it now.  */
 	case R_M32C_16:
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 	  splt = elf_hash_table (info)->splt;
 	  if (splt == NULL)
 	    {
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index 1219d9b04fc..4cdcd9e4db3 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -3458,7 +3458,11 @@ m32r_elf_check_relocs (bfd *abfd,
 	    case R_M32R_GOTPC_LO:
 	    case R_M32R_GOT24:
 	      if (dynobj == NULL)
-		htab->dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!_bfd_elf_create_got_section (dynobj, info))
 		return false;
 	      break;
@@ -3575,7 +3579,11 @@ m32r_elf_check_relocs (bfd *abfd,
 	      struct elf_dyn_relocs **head;
 
 	      if (dynobj == NULL)
-		htab->dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 
 	      /* When creating a shared object, we must copy these
 		 relocs into the output file.  We create a reloc
diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
index 541ff670110..b50a7706a85 100644
--- a/bfd/elf32-m68k.c
+++ b/bfd/elf32-m68k.c
@@ -2637,7 +2637,11 @@ elf_m68k_check_relocs (bfd *abfd,
 	  /* This symbol requires a global offset table entry.  */
 
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 
 	  if (!_bfd_elf_create_got_section (dynobj, info))
 	    return false;
diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c
index 1288c97b385..36e2d0dd0b3 100644
--- a/bfd/elf32-metag.c
+++ b/bfd/elf32-metag.c
@@ -2098,7 +2098,11 @@ elf_metag_check_relocs (bfd *abfd,
 	    case R_METAG_HI16_GOTPC:
 	    case R_METAG_LO16_GOTPC:
 	      if (dynobj == NULL)
-		htab->etab.dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!elf_metag_create_dynamic_sections (dynobj, info))
 		return false;
 	      break;
@@ -2264,17 +2268,19 @@ elf_metag_check_relocs (bfd *abfd,
 	      struct elf_dyn_relocs *hdh_p;
 	      struct elf_dyn_relocs **hdh_head;
 
-	      if (dynobj == NULL)
-		htab->etab.dynobj = dynobj = abfd;
-
 	      /* When creating a shared object, we must copy these
 		 relocs into the output file.  We create a reloc
 		 section in dynobj and make room for the reloc.  */
 	      if (sreloc == NULL)
 		{
-		  sreloc = _bfd_elf_make_dynamic_reloc_section
-		    (sec, htab->etab.dynobj, 2, abfd, /*rela?*/ true);
-
+		  if (dynobj == NULL)
+		    {
+		      dynobj = _bfd_elf_link_dynobj (info);
+		      if (dynobj == NULL)
+			return false;
+		    }
+		  sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj, 2,
+								abfd, true);
 		  if (sreloc == NULL)
 		    {
 		      bfd_set_error (bfd_error_bad_value);
diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
index a52358a9a12..5300f8d4d87 100644
--- a/bfd/elf32-microblaze.c
+++ b/bfd/elf32-microblaze.c
@@ -2512,8 +2512,9 @@ microblaze_elf_check_relocs (bfd * abfd,
 	case R_MICROBLAZE_GOT_64:
 	  if (htab->elf.sgot == NULL)
 	    {
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
 		return false;
 	    }
@@ -2533,8 +2534,9 @@ microblaze_elf_check_relocs (bfd * abfd,
 	case R_MICROBLAZE_GOTOFF_32:
 	  if (htab->elf.sgot == NULL)
 	    {
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
 		return false;
 	    }
@@ -2600,12 +2602,9 @@ microblaze_elf_check_relocs (bfd * abfd,
 
 		if (sreloc == NULL)
 		  {
-		    bfd *dynobj;
-
-		    if (htab->elf.dynobj == NULL)
-		      htab->elf.dynobj = abfd;
-		    dynobj = htab->elf.dynobj;
-
+		    bfd *dynobj = _bfd_elf_link_dynobj (info);
+		    if (dynobj == NULL)
+		      return false;
 		    sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
 								  2, abfd, 1);
 		    if (sreloc == NULL)
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index 937ada25f05..daad1deb85d 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -7169,7 +7169,11 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    case R_NDS32_TLS_DESC_HI20:
 	    case R_NDS32_TLS_DESC_LO12:
 	      if (dynobj == NULL)
-		htab->root.dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!create_got_section (dynobj, info))
 		return false;
 	      break;
@@ -7336,7 +7340,11 @@ nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	      struct elf_dyn_relocs **head;
 
 	      if (dynobj == NULL)
-		htab->root.dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 
 	      /* When creating a shared object, we must copy these
 		 relocs into the output file.  We create a reloc
diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
index ab5b2f495f8..49ce3ce0dad 100644
--- a/bfd/elf32-or1k.c
+++ b/bfd/elf32-or1k.c
@@ -2116,7 +2116,11 @@ or1k_elf_check_relocs (bfd *abfd,
 	  if (htab->root.sgot == NULL)
 	    {
 	      if (dynobj == NULL)
-		htab->root.dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!_bfd_elf_create_got_section (dynobj, info))
 		return false;
 	    }
@@ -2203,9 +2207,12 @@ or1k_elf_check_relocs (bfd *abfd,
 			   abfd, name);
 		      }
 
-		    if (htab->root.dynobj == NULL)
-		      htab->root.dynobj = abfd;
-		    dynobj = htab->root.dynobj;
+		    if (dynobj == NULL)
+		      {
+			dynobj = _bfd_elf_link_dynobj (info);
+			if (dynobj == NULL)
+			  return false;
+		      }
 
 		    sreloc = bfd_get_section_by_name (dynobj, name);
 		    if (sreloc == NULL)
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index e3b54336da5..b2395c1b0a6 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -2620,8 +2620,9 @@ ppc_elf_add_symbol_hook (bfd *abfd,
 	{
 	  flagword flags = SEC_IS_COMMON | SEC_SMALL_DATA | SEC_LINKER_CREATED;
 
-	  if (!htab->elf.dynobj)
-	    htab->elf.dynobj = abfd;
+	  if (htab->elf.dynobj == NULL
+	      && !_bfd_elf_link_dynobj (info))
+	    return false;
 
 	  htab->sbss = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
 							   ".sbss",
@@ -2894,8 +2895,9 @@ ppc_elf_check_relocs (bfd *abfd,
   htab = ppc_elf_hash_table (info);
   if (htab->glink == NULL)
     {
-      if (htab->elf.dynobj == NULL)
-	htab->elf.dynobj = abfd;
+      if (htab->elf.dynobj == NULL
+	  && !_bfd_elf_link_dynobj (info))
+	return false;
       if (!ppc_elf_create_glink (htab->elf.dynobj, info))
 	return false;
     }
@@ -2942,8 +2944,9 @@ ppc_elf_check_relocs (bfd *abfd,
 	  && htab->elf.sgot == NULL
 	  && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
 	{
-	  if (htab->elf.dynobj == NULL)
-	    htab->elf.dynobj = abfd;
+	  if (htab->elf.dynobj == NULL
+	      && !_bfd_elf_link_dynobj (info))
+	    return false;
 	  if (!ppc_elf_create_got (htab->elf.dynobj, info))
 	    return false;
 	  BFD_ASSERT (h == htab->elf.hgot);
@@ -3067,8 +3070,9 @@ ppc_elf_check_relocs (bfd *abfd,
 	  /* This symbol requires a global offset table entry.  */
 	  if (htab->elf.sgot == NULL)
 	    {
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!ppc_elf_create_got (htab->elf.dynobj, info))
 		return false;
 	    }
@@ -3431,8 +3435,9 @@ ppc_elf_check_relocs (bfd *abfd,
 #endif
 	      if (sreloc == NULL)
 		{
-		  if (htab->elf.dynobj == NULL)
-		    htab->elf.dynobj = abfd;
+		  if (htab->elf.dynobj == NULL
+		      && !_bfd_elf_link_dynobj (info))
+		    return false;
 
 		  sreloc = _bfd_elf_make_dynamic_reloc_section
 		    (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ true);
diff --git a/bfd/elf32-rl78.c b/bfd/elf32-rl78.c
index e9e047fcca7..9a3e2f22707 100644
--- a/bfd/elf32-rl78.c
+++ b/bfd/elf32-rl78.c
@@ -1369,7 +1369,11 @@ rl78_elf_check_relocs
 	     for it now.  */
 	case R_RL78_DIR16S:
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 	  splt = elf_hash_table (info)->splt;
 	  if (splt == NULL)
 	    {
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index dd9149a4824..b61c7de1d03 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -936,8 +936,9 @@ elf_s390_check_relocs (bfd *abfd,
 	    {
 	      struct plt_entry *plt;
 
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 
 	      if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info))
 		return false;
@@ -999,8 +1000,9 @@ elf_s390_check_relocs (bfd *abfd,
 	case R_390_GOTPCDBL:
 	  if (htab->elf.sgot == NULL)
 	    {
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
 		return false;
 	    }
@@ -1008,8 +1010,9 @@ elf_s390_check_relocs (bfd *abfd,
 
       if (h != NULL)
 	{
-	  if (htab->elf.dynobj == NULL)
-	    htab->elf.dynobj = abfd;
+	  if (htab->elf.dynobj == NULL
+	      && !_bfd_elf_link_dynobj (info))
+	    return false;
 	  if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info))
 	    return false;
 
@@ -1254,8 +1257,9 @@ elf_s390_check_relocs (bfd *abfd,
 		 this reloc.  */
 	      if (sreloc == NULL)
 		{
-		  if (htab->elf.dynobj == NULL)
-		    htab->elf.dynobj = abfd;
+		  if (htab->elf.dynobj == NULL
+		      && !_bfd_elf_link_dynobj (info))
+		    return false;
 
 		  sreloc = _bfd_elf_make_dynamic_reloc_section
 		    (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ true);
diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c
index 606458722bc..dca6333e710 100644
--- a/bfd/elf32-score.c
+++ b/bfd/elf32-score.c
@@ -2871,7 +2871,11 @@ s3_bfd_score_elf_check_relocs (bfd *abfd,
 	    case R_SCORE_GOT15:
 	    case R_SCORE_CALL15:
 	      if (dynobj == NULL)
-		elf_hash_table (info)->dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!score_elf_create_got_section (dynobj, info, false))
 		return false;
 	      g = score_elf_got_info (dynobj, &sgot);
@@ -2881,7 +2885,11 @@ s3_bfd_score_elf_check_relocs (bfd *abfd,
 	      if (dynobj == NULL
 		  && (bfd_link_pic (info) || h != NULL)
 		  && (sec->flags & SEC_ALLOC) != 0)
-		elf_hash_table (info)->dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      break;
 	    default:
 	      break;
@@ -2967,7 +2975,11 @@ s3_bfd_score_elf_check_relocs (bfd *abfd,
 	      if (h != NULL)
 		{
 		  if (dynobj == NULL)
-		    elf_hash_table (info)->dynobj = dynobj = abfd;
+		    {
+		      dynobj = _bfd_elf_link_dynobj (info);
+		      if (dynobj == NULL)
+			return false;
+		    }
 		  if (! score_elf_create_got_section (dynobj, info, true))
 		    return false;
 		  g = score_elf_got_info (dynobj, &sgot);
diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c
index cf01059013f..16378cddc30 100644
--- a/bfd/elf32-score7.c
+++ b/bfd/elf32-score7.c
@@ -2673,7 +2673,11 @@ s7_bfd_score_elf_check_relocs (bfd *abfd,
 	    case R_SCORE_GOT15:
 	    case R_SCORE_CALL15:
 	      if (dynobj == NULL)
-		elf_hash_table (info)->dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      if (!score_elf_create_got_section (dynobj, info, false))
 		return false;
 	      g = score_elf_got_info (dynobj, &sgot);
@@ -2683,7 +2687,11 @@ s7_bfd_score_elf_check_relocs (bfd *abfd,
 	      if (dynobj == NULL
 		  && (bfd_link_pic (info) || h != NULL)
 		  && (sec->flags & SEC_ALLOC) != 0)
-		elf_hash_table (info)->dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	      break;
 	    default:
 	      break;
@@ -2769,7 +2777,11 @@ s7_bfd_score_elf_check_relocs (bfd *abfd,
 	      if (h != NULL)
 		{
 		  if (dynobj == NULL)
-		    elf_hash_table (info)->dynobj = dynobj = abfd;
+		    {
+		      dynobj = _bfd_elf_link_dynobj (info);
+		      if (dynobj == NULL)
+			return false;
+		    }
 		  if (! score_elf_create_got_section (dynobj, info, true))
 		    return false;
 		  g = score_elf_got_info (dynobj, &sgot);
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index 2107e3f807a..827f617a057 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -5384,8 +5384,9 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
 	    case R_SH_TLS_GD_32:
 	    case R_SH_TLS_LD_32:
 	    case R_SH_TLS_IE_32:
-	      if (htab->root.dynobj == NULL)
-		htab->root.dynobj = abfd;
+	      if (htab->root.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!create_got_section (htab->root.dynobj, info))
 		return false;
 	      break;
@@ -5656,8 +5657,9 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
 	      struct elf_dyn_relocs *p;
 	      struct elf_dyn_relocs **head;
 
-	      if (htab->root.dynobj == NULL)
-		htab->root.dynobj = abfd;
+	      if (htab->root.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 
 	      /* When creating a shared object, we must copy these
 		 reloc types into the output file.  We create a reloc
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
index 5f1183ce7d1..a3f4e6c52f8 100644
--- a/bfd/elf32-spu.c
+++ b/bfd/elf32-spu.c
@@ -619,9 +619,9 @@ spu_elf_create_sections (struct bfd_link_info *info)
       asection *s;
       flagword flags;
 
-      if (htab->elf.dynobj == NULL)
-	htab->elf.dynobj = ibfd;
-      ibfd = htab->elf.dynobj;
+      ibfd = _bfd_elf_link_dynobj (info);
+      if (ibfd == NULL)
+	return false;
       flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY | SEC_HAS_CONTENTS
 	       | SEC_IN_MEMORY | SEC_LINKER_CREATED);
       s = bfd_make_section_anyway_with_flags (ibfd, ".fixup", flags);
diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c
index e8223312b3d..bcd98b2b4dd 100644
--- a/bfd/elf32-tic6x.c
+++ b/bfd/elf32-tic6x.c
@@ -2788,8 +2788,9 @@ elf32_tic6x_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
 	  if (htab->elf.sgot == NULL)
 	    {
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
 		return false;
 	    }
@@ -2843,8 +2844,9 @@ elf32_tic6x_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		 this reloc.  */
 	      if (sreloc == NULL)
 		{
-		  if (htab->elf.dynobj == NULL)
-		    htab->elf.dynobj = abfd;
+		  if (htab->elf.dynobj == NULL
+		      && !_bfd_elf_link_dynobj (info))
+		    return false;
 
 		  sreloc = _bfd_elf_make_dynamic_reloc_section
 		    (sec, htab->elf.dynobj, 2, abfd, /*rela? */ true);
diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c
index df47e3857ef..b41c20920cf 100644
--- a/bfd/elf32-tilepro.c
+++ b/bfd/elf32-tilepro.c
@@ -1404,6 +1404,10 @@ tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
     return true;
 
   htab = tilepro_elf_hash_table (info);
+  if (htab->dynobj == NULL
+      && !_bfd_elf_link_dynobj (info))
+    return false;
+
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
@@ -1413,9 +1417,6 @@ tilepro_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
   BFD_ASSERT (is_tilepro_elf (abfd) || num_relocs == 0);
 
-  if (htab->dynobj == NULL)
-    htab->dynobj = abfd;
-
   rel_end = relocs + num_relocs;
   for (rel = relocs; rel < rel_end; rel++)
     {
diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
index b49a4837c04..8e5a5275428 100644
--- a/bfd/elf32-vax.c
+++ b/bfd/elf32-vax.c
@@ -594,7 +594,11 @@ elf_vax_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
 	  /* This symbol requires a global offset table entry.  */
 
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 
 	  if (!_bfd_elf_create_got_section (dynobj, info))
 	    return false;
diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c
index 04782449b8a..07270b8b66f 100644
--- a/bfd/elf32-xstormy16.c
+++ b/bfd/elf32-xstormy16.c
@@ -460,7 +460,11 @@ xstormy16_elf_check_relocs (bfd *abfd,
 	    }
 
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 	  splt = elf_hash_table (info)->splt;
 	  if (splt == NULL)
 	    {
diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
index 20374c297f0..07e145fc586 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -1768,9 +1768,9 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
   BFD_ASSERT (is_alpha_elf (abfd));
 
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = _bfd_elf_link_dynobj (info);
   if (dynobj == NULL)
-    elf_hash_table (info)->dynobj = dynobj = abfd;
+    return false;
 
   sreloc = NULL;
   symtab_hdr = &elf_symtab_hdr (abfd);
diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
index 230ed4997ec..0a14e2f1adc 100644
--- a/bfd/elf64-hppa.c
+++ b/bfd/elf64-hppa.c
@@ -215,9 +215,6 @@ static bool allocate_global_data_stub
 static bool allocate_global_data_opd
   (struct elf_link_hash_entry *, void *);
 
-static bool get_reloc_section
-  (bfd *, struct elf64_hppa_link_hash_table *, asection *);
-
 static bool count_dyn_reloc
   (bfd *, struct elf64_hppa_link_hash_entry *,
    int, asection *, int, bfd_vma, bfd_vma);
@@ -229,16 +226,16 @@ static bool elf64_hppa_finalize_dynreloc
   (struct elf_link_hash_entry *, void *);
 
 static bool get_opd
-  (bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
+  (struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
 
 static bool get_plt
-  (bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
+  (struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
 
 static bool get_dlt
-  (bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
+  (struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
 
 static bool get_stub
-  (bfd *, struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
+  (struct bfd_link_info *, struct elf64_hppa_link_hash_table *);
 
 static int elf64_hppa_elf_get_symbol_type
   (Elf_Internal_Sym *, int);
@@ -388,6 +385,7 @@ elf64_hppa_section_from_shdr (bfd *abfd,
 
 static bool
 get_reloc_section (bfd *abfd,
+		   struct bfd_link_info *info,
 		   struct elf64_hppa_link_hash_table *hppa_info,
 		   asection *sec)
 {
@@ -401,9 +399,9 @@ get_reloc_section (bfd *abfd,
   if (srel_name == NULL)
     return false;
 
-  dynobj = hppa_info->root.dynobj;
+  dynobj = _bfd_elf_link_dynobj (info);
   if (!dynobj)
-    hppa_info->root.dynobj = dynobj = abfd;
+    return false;
 
   srel = bfd_get_linker_section (dynobj, srel_name);
   if (srel == NULL)
@@ -793,7 +791,7 @@ elf64_hppa_check_relocs (bfd *abfd,
 	  /* Allocate space for a DLT entry, as well as a dynamic
 	     relocation for this entry.  */
 	  if (! hppa_info->dlt_sec
-	      && ! get_dlt (abfd, info, hppa_info))
+	      && ! get_dlt (info, hppa_info))
 	    goto err_out;
 
 	  if (hh != NULL)
@@ -816,7 +814,7 @@ elf64_hppa_check_relocs (bfd *abfd,
       if (need_entry & NEED_PLT)
 	{
 	  if (! hppa_info->root.splt
-	      && ! get_plt (abfd, info, hppa_info))
+	      && ! get_plt (info, hppa_info))
 	    goto err_out;
 
 	  if (hh != NULL)
@@ -842,7 +840,7 @@ elf64_hppa_check_relocs (bfd *abfd,
       if (need_entry & NEED_STUB)
 	{
 	  if (! hppa_info->stub_sec
-	      && ! get_stub (abfd, info, hppa_info))
+	      && ! get_stub (info, hppa_info))
 	    goto err_out;
 	  if (hh)
 	    hh->want_stub = 1;
@@ -851,7 +849,7 @@ elf64_hppa_check_relocs (bfd *abfd,
       if (need_entry & NEED_OPD)
 	{
 	  if (! hppa_info->opd_sec
-	      && ! get_opd (abfd, info, hppa_info))
+	      && ! get_opd (info, hppa_info))
 	    goto err_out;
 
 	  /* FPTRs are not allocated by the dynamic linker for PA64,
@@ -879,7 +877,7 @@ elf64_hppa_check_relocs (bfd *abfd,
       if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
 	{
 	  if (! hppa_info->other_rel_sec
-	      && ! get_reloc_section (abfd, hppa_info, sec))
+	      && ! get_reloc_section (abfd, info, hppa_info, sec))
 	    goto err_out;
 
 	  /* Count dynamic relocations against global symbols.  */
@@ -1166,8 +1164,7 @@ elf64_hppa_init_file_header (bfd *abfd, struct bfd_link_info *info)
    of a procedure, thus ensuring a unique address for each procedure.  */
 
 static bool
-get_opd (bfd *abfd,
-	 struct bfd_link_info *info ATTRIBUTE_UNUSED,
+get_opd (struct bfd_link_info *info,
 	 struct elf64_hppa_link_hash_table *hppa_info)
 {
   asection *opd;
@@ -1176,9 +1173,9 @@ get_opd (bfd *abfd,
   opd = hppa_info->opd_sec;
   if (!opd)
     {
-      dynobj = hppa_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	hppa_info->root.dynobj = dynobj = abfd;
+	return false;
 
       opd = bfd_make_section_anyway_with_flags (dynobj, ".opd",
 						(SEC_ALLOC
@@ -1202,8 +1199,7 @@ get_opd (bfd *abfd,
 /* Create the PLT section.  */
 
 static bool
-get_plt (bfd *abfd,
-	 struct bfd_link_info *info ATTRIBUTE_UNUSED,
+get_plt (struct bfd_link_info *info,
 	 struct elf64_hppa_link_hash_table *hppa_info)
 {
   asection *plt;
@@ -1212,9 +1208,9 @@ get_plt (bfd *abfd,
   plt = hppa_info->root.splt;
   if (!plt)
     {
-      dynobj = hppa_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	hppa_info->root.dynobj = dynobj = abfd;
+	return false;
 
       plt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
 						(SEC_ALLOC
@@ -1238,8 +1234,7 @@ get_plt (bfd *abfd,
 /* Create the DLT section.  */
 
 static bool
-get_dlt (bfd *abfd,
-	 struct bfd_link_info *info ATTRIBUTE_UNUSED,
+get_dlt (struct bfd_link_info *info,
 	 struct elf64_hppa_link_hash_table *hppa_info)
 {
   asection *dlt;
@@ -1248,9 +1243,9 @@ get_dlt (bfd *abfd,
   dlt = hppa_info->dlt_sec;
   if (!dlt)
     {
-      dynobj = hppa_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	hppa_info->root.dynobj = dynobj = abfd;
+	return false;
 
       dlt = bfd_make_section_anyway_with_flags (dynobj, ".dlt",
 						(SEC_ALLOC
@@ -1274,8 +1269,7 @@ get_dlt (bfd *abfd,
 /* Create the stubs section.  */
 
 static bool
-get_stub (bfd *abfd,
-	  struct bfd_link_info *info ATTRIBUTE_UNUSED,
+get_stub (struct bfd_link_info *info,
 	  struct elf64_hppa_link_hash_table *hppa_info)
 {
   asection *stub;
@@ -1284,9 +1278,9 @@ get_stub (bfd *abfd,
   stub = hppa_info->stub_sec;
   if (!stub)
     {
-      dynobj = hppa_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	hppa_info->root.dynobj = dynobj = abfd;
+	return false;
 
       stub = bfd_make_section_anyway_with_flags (dynobj, ".stub",
 						 (SEC_ALLOC | SEC_LOAD
@@ -1368,16 +1362,16 @@ elf64_hppa_create_dynamic_sections (bfd *abfd,
 	return false;
     }
 
-  if (! get_stub (abfd, info, hppa_info))
+  if (! get_stub (info, hppa_info))
     return false;
 
-  if (! get_dlt (abfd, info, hppa_info))
+  if (! get_dlt (info, hppa_info))
     return false;
 
-  if (! get_plt (abfd, info, hppa_info))
+  if (! get_plt (info, hppa_info))
     return false;
 
-  if (! get_opd (abfd, info, hppa_info))
+  if (! get_opd (info, hppa_info))
     return false;
 
   s = bfd_make_section_anyway_with_flags (abfd, ".rela.dlt", flags);
diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c
index 6785ea08a38..420341e91f7 100644
--- a/bfd/elf64-ia64-vms.c
+++ b/bfd/elf64-ia64-vms.c
@@ -234,9 +234,9 @@ static bool allocate_local_got
 static bool allocate_dynrel_entries
   (struct elf64_ia64_dyn_sym_info *, void *);
 static asection *get_pltoff
-  (bfd *, struct elf64_ia64_link_hash_table *);
+  (struct bfd_link_info *, struct elf64_ia64_link_hash_table *);
 static asection *get_got
-  (bfd *, struct elf64_ia64_link_hash_table *);
+  (struct bfd_link_info *, struct elf64_ia64_link_hash_table *);
 
 
 /* Given a ELF reloc, return the matching HOWTO structure.  */
@@ -1289,10 +1289,10 @@ elf64_ia64_create_dynamic_sections (bfd *abfd,
     return false;
   ia64_info->root.splt = s;
 
-  if (!get_got (abfd, ia64_info))
+  if (!get_got (info, ia64_info))
     return false;
 
-  if (!get_pltoff (abfd, ia64_info))
+  if (!get_pltoff (info, ia64_info))
     return false;
 
   s = bfd_make_section_anyway_with_flags (abfd, ".vmsdynstr",
@@ -1713,7 +1713,8 @@ get_dyn_sym_info (struct elf64_ia64_link_hash_table *ia64_info,
 }
 
 static asection *
-get_got (bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info)
+get_got (struct bfd_link_info *info,
+	 struct elf64_ia64_link_hash_table *ia64_info)
 {
   asection *got;
   bfd *dynobj;
@@ -1723,9 +1724,9 @@ get_got (bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info)
     {
       flagword flags;
 
-      dynobj = ia64_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	ia64_info->root.dynobj = dynobj = abfd;
+	return NULL;
 
       /* The .got section is always aligned at 8 bytes.  */
       flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
@@ -1746,7 +1747,7 @@ get_got (bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info)
    of a procedure, thus ensuring a unique address for each procedure.  */
 
 static asection *
-get_fptr (bfd *abfd, struct bfd_link_info *info,
+get_fptr (struct bfd_link_info *info,
 	  struct elf64_ia64_link_hash_table *ia64_info)
 {
   asection *fptr;
@@ -1755,9 +1756,9 @@ get_fptr (bfd *abfd, struct bfd_link_info *info,
   fptr = ia64_info->fptr_sec;
   if (!fptr)
     {
-      dynobj = ia64_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	ia64_info->root.dynobj = dynobj = abfd;
+	return NULL;
 
       fptr = bfd_make_section_anyway_with_flags (dynobj, ".opd",
 						 (SEC_ALLOC
@@ -1800,7 +1801,8 @@ get_fptr (bfd *abfd, struct bfd_link_info *info,
 }
 
 static asection *
-get_pltoff (bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info)
+get_pltoff (struct bfd_link_info *info,
+	    struct elf64_ia64_link_hash_table *ia64_info)
 {
   asection *pltoff;
   bfd *dynobj;
@@ -1808,9 +1810,9 @@ get_pltoff (bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info)
   pltoff = ia64_info->pltoff_sec;
   if (!pltoff)
     {
-      dynobj = ia64_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	ia64_info->root.dynobj = dynobj = abfd;
+	return NULL;
 
       pltoff = bfd_make_section_anyway_with_flags (dynobj,
 						   ELF_STRING_ia64_pltoff,
@@ -1835,7 +1837,7 @@ get_pltoff (bfd *abfd, struct elf64_ia64_link_hash_table *ia64_info)
 
 static asection *
 get_reloc_section (bfd *abfd,
-		   struct elf64_ia64_link_hash_table *ia64_info,
+		   struct bfd_link_info *info,
 		   asection *sec, bool create)
 {
   const char *srel_name;
@@ -1853,9 +1855,9 @@ get_reloc_section (bfd *abfd,
 	      || (startswith (srel_name, ".rel")
 		  && strcmp (bfd_section_name (sec), srel_name+4) == 0));
 
-  dynobj = ia64_info->root.dynobj;
+  dynobj = _bfd_elf_link_dynobj (info);
   if (!dynobj)
-    ia64_info->root.dynobj = dynobj = abfd;
+    return NULL;
 
   srel = bfd_get_linker_section (dynobj, srel_name);
   if (srel == NULL && create)
@@ -2228,7 +2230,7 @@ elf64_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	{
 	  if (!got)
 	    {
-	      got = get_got (abfd, ia64_info);
+	      got = get_got (info, ia64_info);
 	      if (!got)
 		return false;
 	    }
@@ -2242,7 +2244,7 @@ elf64_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  /* Create the .opd section.  */
 	  if (!fptr)
 	    {
-	      fptr = get_fptr (abfd, info, ia64_info);
+	      fptr = get_fptr (info, ia64_info);
 	      if (!fptr)
 		return false;
 	    }
@@ -2252,8 +2254,9 @@ elf64_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	dyn_i->want_ltoff_fptr = 1;
       if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
 	{
-	  if (!ia64_info->root.dynobj)
-	    ia64_info->root.dynobj = abfd;
+	  if (!ia64_info->root.dynobj
+	      && !_bfd_elf_link_dynobj (info))
+	    return false;
 	  h->needs_plt = 1;
 	  dyn_i->want_plt = 1;
 	}
@@ -2265,7 +2268,7 @@ elf64_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	     link.  */
 	  if (!pltoff)
 	    {
-	      pltoff = get_pltoff (abfd, ia64_info);
+	      pltoff = get_pltoff (info, ia64_info);
 	      if (!pltoff)
 		return false;
 	    }
@@ -2276,7 +2279,7 @@ elf64_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	{
 	  if (!srel)
 	    {
-	      srel = get_reloc_section (abfd, ia64_info, sec, true);
+	      srel = get_reloc_section (abfd, info, sec, true);
 	      if (!srel)
 		return false;
 	    }
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index 9150670f0ce..2df8a36f206 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -949,8 +949,9 @@ elf_s390_check_relocs (bfd *abfd,
 	    {
 	      struct plt_entry *plt;
 
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 
 	      if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info))
 		return false;
@@ -1016,8 +1017,9 @@ elf_s390_check_relocs (bfd *abfd,
 	case R_390_GOTPCDBL:
 	  if (htab->elf.sgot == NULL)
 	    {
-	      if (htab->elf.dynobj == NULL)
-		htab->elf.dynobj = abfd;
+	      if (htab->elf.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
 		return false;
 	    }
@@ -1025,8 +1027,9 @@ elf_s390_check_relocs (bfd *abfd,
 
       if (h != NULL)
 	{
-	  if (htab->elf.dynobj == NULL)
-	    htab->elf.dynobj = abfd;
+	  if (htab->elf.dynobj == NULL
+	      && !_bfd_elf_link_dynobj (info))
+	    return false;
 	  if (!s390_elf_create_ifunc_sections (htab->elf.dynobj, info))
 	    return false;
 
@@ -1319,8 +1322,9 @@ elf_s390_check_relocs (bfd *abfd,
 		 this reloc.  */
 	      if (sreloc == NULL)
 		{
-		  if (htab->elf.dynobj == NULL)
-		    htab->elf.dynobj = abfd;
+		  if (htab->elf.dynobj == NULL
+		      && !_bfd_elf_link_dynobj (info))
+		    return false;
 
 		  sreloc = _bfd_elf_make_dynamic_reloc_section
 		    (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ true);
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ecbb4d3b42e..d1edf1bddf7 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -302,24 +302,20 @@ compatible_format (struct bfd_link_info *info, bfd *ibfd)
 
 /* Find a suitable object for attaching dynamic sections.  */
 
-static bfd *
-_bfd_elf_link_dynobj (struct bfd_link_info *info)
+bfd *
+_bfd_elf_link_dynobj_internal (struct bfd_link_info *info, bool report)
 {
   struct elf_link_hash_table *htab = elf_hash_table (info);
 
   if (htab->dynobj == NULL)
     {
       /* We need to find an input file of the same format as the
-	 output to hold linker created sections.  For now, exclude
-	 any stub bfd.  */
-      bfd *ibfd = info->input_bfds;
-      if ((ibfd->flags
-	   & (BFD_PLUGIN | BFD_LINKER_CREATED)) == BFD_LINKER_CREATED)
-	ibfd = ibfd->link.next;
-      for (; ibfd; ibfd = ibfd->link.next)
+	 output to hold linker created sections.  */
+      bfd *ibfd;
+      for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
 	if (compatible_format (info, ibfd))
 	  break;
-      if (ibfd == NULL)
+      if (ibfd == NULL && report)
 	_bfd_error_handler (_("no %s input object found"),
 			    bfd_get_target (info->output_bfd));
       htab->dynobj = ibfd;
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index ca0a4b67321..de0f0a2b3ca 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -8006,8 +8006,9 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	  if (h->root.root.string
 	      && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
 	    {
-	      if (htab->root.dynobj == NULL)
-		htab->root.dynobj = abfd;
+	      if (htab->root.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 
 	      if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
 		return false;
@@ -8038,8 +8039,9 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC:
 	    case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1:
 	    case BFD_RELOC_AARCH64_NN:
-	      if (htab->root.dynobj == NULL)
-		htab->root.dynobj = abfd;
+	      if (htab->root.dynobj == NULL
+		  && !_bfd_elf_link_dynobj (info))
+		return false;
 	      if (!_bfd_elf_create_ifunc_sections (htab->root.dynobj, info))
 		return false;
 	      break;
@@ -8165,9 +8167,9 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	       this reloc.  */
 	    if (sreloc == NULL)
 	      {
-		if (htab->root.dynobj == NULL)
-		  htab->root.dynobj = abfd;
-
+		if (htab->root.dynobj == NULL
+		    && !_bfd_elf_link_dynobj (info))
+		  return false;
 		sreloc = _bfd_elf_make_dynamic_reloc_section (sec,
 							      htab->root.dynobj,
 							      LOG_FILE_ALIGN,
@@ -8314,8 +8316,9 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		  }
 	      }
 
-	    if (htab->root.dynobj == NULL)
-	      htab->root.dynobj = abfd;
+	    if (htab->root.dynobj == NULL
+		&& !_bfd_elf_link_dynobj (info))
+	      return false;
 	    if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
 	      return false;
 	    break;
diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c
index 401327a7c68..4e2d27cfc3f 100644
--- a/bfd/elfnn-ia64.c
+++ b/bfd/elfnn-ia64.c
@@ -193,7 +193,7 @@ static bool elfNN_ia64_hpux_vec
 static bool allocate_dynrel_entries
   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
 static asection *get_pltoff
-  (bfd *abfd, struct bfd_link_info *info,
+  (struct bfd_link_info *info,
    struct elfNN_ia64_link_hash_table *ia64_info);
 
 /* ia64-specific relocation.  */
@@ -1562,7 +1562,7 @@ elfNN_ia64_create_dynamic_sections (bfd *abfd,
       return false;
   }
 
-  if (!get_pltoff (abfd, info, ia64_info))
+  if (!get_pltoff (info, ia64_info))
     return false;
 
   s = bfd_make_section_anyway_with_flags (abfd, ".rela.IA_64.pltoff",
@@ -1952,7 +1952,7 @@ get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
 }
 
 static asection *
-get_got (bfd *abfd, struct bfd_link_info *info,
+get_got (struct bfd_link_info *info,
 	 struct elfNN_ia64_link_hash_table *ia64_info)
 {
   asection *got;
@@ -1963,9 +1963,9 @@ get_got (bfd *abfd, struct bfd_link_info *info,
     {
       flagword flags;
 
-      dynobj = ia64_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	ia64_info->root.dynobj = dynobj = abfd;
+	return NULL;
       if (!_bfd_elf_create_got_section (dynobj, info))
 	return NULL;
 
@@ -1989,7 +1989,7 @@ get_got (bfd *abfd, struct bfd_link_info *info,
    of a procedure, thus ensuring a unique address for each procedure.  */
 
 static asection *
-get_fptr (bfd *abfd, struct bfd_link_info *info,
+get_fptr (struct bfd_link_info *info,
 	  struct elfNN_ia64_link_hash_table *ia64_info)
 {
   asection *fptr;
@@ -1998,9 +1998,9 @@ get_fptr (bfd *abfd, struct bfd_link_info *info,
   fptr = ia64_info->fptr_sec;
   if (!fptr)
     {
-      dynobj = ia64_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	ia64_info->root.dynobj = dynobj = abfd;
+	return NULL;
 
       fptr = bfd_make_section_anyway_with_flags (dynobj, ".opd",
 						 (SEC_ALLOC
@@ -2043,7 +2043,7 @@ get_fptr (bfd *abfd, struct bfd_link_info *info,
 }
 
 static asection *
-get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
+get_pltoff (struct bfd_link_info *info,
 	    struct elfNN_ia64_link_hash_table *ia64_info)
 {
   asection *pltoff;
@@ -2052,9 +2052,9 @@ get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
   pltoff = ia64_info->pltoff_sec;
   if (!pltoff)
     {
-      dynobj = ia64_info->root.dynobj;
+      dynobj = _bfd_elf_link_dynobj (info);
       if (!dynobj)
-	ia64_info->root.dynobj = dynobj = abfd;
+	return NULL;
 
       pltoff = bfd_make_section_anyway_with_flags (dynobj,
 						   ELF_STRING_ia64_pltoff,
@@ -2079,7 +2079,7 @@ get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
 
 static asection *
 get_reloc_section (bfd *abfd,
-		   struct elfNN_ia64_link_hash_table *ia64_info,
+		   struct bfd_link_info *info,
 		   asection *sec, bool create)
 {
   const char *srel_name;
@@ -2092,9 +2092,9 @@ get_reloc_section (bfd *abfd,
   if (srel_name == NULL)
     return NULL;
 
-  dynobj = ia64_info->root.dynobj;
+  dynobj = _bfd_elf_link_dynobj (info);
   if (!dynobj)
-    ia64_info->root.dynobj = dynobj = abfd;
+    return NULL;
 
   srel = bfd_get_linker_section (dynobj, srel_name);
   if (srel == NULL && create)
@@ -2524,7 +2524,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	{
 	  if (!got)
 	    {
-	      got = get_got (abfd, info, ia64_info);
+	      got = get_got (info, ia64_info);
 	      if (!got)
 		return false;
 	    }
@@ -2543,7 +2543,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	{
 	  if (!fptr)
 	    {
-	      fptr = get_fptr (abfd, info, ia64_info);
+	      fptr = get_fptr (info, ia64_info);
 	      if (!fptr)
 		return false;
 	    }
@@ -2564,8 +2564,9 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	dyn_i->want_ltoff_fptr = 1;
       if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
 	{
-	  if (!ia64_info->root.dynobj)
-	    ia64_info->root.dynobj = abfd;
+	  if (!ia64_info->root.dynobj
+	      && !_bfd_elf_link_dynobj (info))
+	    return false;
 	  h->needs_plt = 1;
 	  dyn_i->want_plt = 1;
 	}
@@ -2577,7 +2578,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	     link.  */
 	  if (!pltoff)
 	    {
-	      pltoff = get_pltoff (abfd, info, ia64_info);
+	      pltoff = get_pltoff (info, ia64_info);
 	      if (!pltoff)
 		return false;
 	    }
@@ -2588,7 +2589,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	{
 	  if (!srel)
 	    {
-	      srel = get_reloc_section (abfd, ia64_info, sec, true);
+	      srel = get_reloc_section (abfd, info, sec, true);
 	      if (!srel)
 		return false;
 	    }
@@ -3793,7 +3794,7 @@ elfNN_ia64_relocate_section (struct bfd_link_info *info,
     }
 
   gp_val = _bfd_get_gp_value (info->output_bfd);
-  srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
+  srel = get_reloc_section (input_bfd, info, input_section, false);
 
   rel = relocs;
   relend = relocs + input_section->reloc_count;
diff --git a/bfd/elfnn-kvx.c b/bfd/elfnn-kvx.c
index d3fa7f874b7..595138526a8 100644
--- a/bfd/elfnn-kvx.c
+++ b/bfd/elfnn-kvx.c
@@ -3327,8 +3327,9 @@ elfNN_kvx_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	       this reloc.  */
 	    if (sreloc == NULL)
 	      {
-		if (htab->root.dynobj == NULL)
-		  htab->root.dynobj = abfd;
+		if (htab->root.dynobj == NULL
+		    && !_bfd_elf_link_dynobj (info))
+		  return false;
 
 		sreloc = _bfd_elf_make_dynamic_reloc_section
 		  (sec, htab->root.dynobj, LOG_FILE_ALIGN, abfd, /*rela? */ true);
@@ -3472,8 +3473,9 @@ elfNN_kvx_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		  }
 	      }
 
-	    if (htab->root.dynobj == NULL)
-	      htab->root.dynobj = abfd;
+	    if (htab->root.dynobj == NULL
+		&& !_bfd_elf_link_dynobj (info))
+	      return false;
 	    if (! kvx_elf_create_got_section (htab->root.dynobj, info))
 	      return false;
 	    break;
@@ -3490,8 +3492,9 @@ elfNN_kvx_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	case BFD_RELOC_KVX_S37_GOTADDR_LO10:
 	case BFD_RELOC_KVX_S37_GOTADDR_UP27:
 
-	  if (htab->root.dynobj == NULL)
-	    htab->root.dynobj = abfd;
+	  if (htab->root.dynobj == NULL
+	      && !_bfd_elf_link_dynobj (info))
+	    return false;
 	  if (! kvx_elf_create_got_section (htab->root.dynobj, info))
 	    return false;
 	  break;
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index a66a9d7bec8..7f5bd24977f 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -1133,12 +1133,13 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       return true;
     }
 
+  if (htab->elf.dynobj == NULL
+      && !_bfd_elf_link_dynobj (info))
+    return false;
+
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
-  if (htab->elf.dynobj == NULL)
-    htab->elf.dynobj = abfd;
-
   for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
     {
       unsigned int r_type;
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 1c1c3ea36c5..5cddbb36b4b 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -936,8 +936,9 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
-  if (htab->elf.dynobj == NULL)
-    htab->elf.dynobj = abfd;
+  if (htab->elf.dynobj == NULL
+      && !_bfd_elf_link_dynobj (info))
+    return false;
 
   for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
     {
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 7dc72afa697..1f7da4fdcf6 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -8890,7 +8890,11 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	case R_MICROMIPS_TLS_GD:
 	case R_MICROMIPS_TLS_LDM:
 	  if (dynobj == NULL)
-	    elf_hash_table (info)->dynobj = dynobj = abfd;
+	    {
+	      dynobj = _bfd_elf_link_dynobj (info);
+	      if (dynobj == NULL)
+		return false;
+	    }
 	  if (!mips_elf_create_got_section (dynobj, info))
 	    return false;
 	  if (htab->root.target_os == is_vxworks
@@ -8949,7 +8953,11 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    {
 	      can_make_dynamic_p = true;
 	      if (dynobj == NULL)
-		elf_hash_table (info)->dynobj = dynobj = abfd;
+		{
+		  dynobj = _bfd_elf_link_dynobj (info);
+		  if (dynobj == NULL)
+		    return false;
+		}
 	    }
 	  break;
 
diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
index 641b806f686..7a5093b6de7 100644
--- a/bfd/elfxx-sparc.c
+++ b/bfd/elfxx-sparc.c
@@ -1362,8 +1362,9 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
   BFD_ASSERT (is_sparc_elf (abfd) || num_relocs == 0);
 
-  if (htab->elf.dynobj == NULL)
-    htab->elf.dynobj = abfd;
+  if (htab->elf.dynobj == NULL
+      && !_bfd_elf_link_dynobj (info))
+    return false;
   if (!create_ifunc_sections (htab->elf.dynobj, info))
     return false;
 
diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c
index dcdd7cafe0e..689c400c34c 100644
--- a/bfd/elfxx-tilegx.c
+++ b/bfd/elfxx-tilegx.c
@@ -1602,6 +1602,10 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
     return true;
 
   htab = tilegx_elf_hash_table (info);
+  if (htab->elf.dynobj == NULL
+      && !_bfd_elf_link_dynobj (info))
+    return false;
+
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
@@ -1611,9 +1615,6 @@ tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
   BFD_ASSERT (is_tilegx_elf (abfd) || num_relocs == 0);
 
-  if (htab->elf.dynobj == NULL)
-    htab->elf.dynobj = abfd;
-
   rel_end = relocs + num_relocs;
 
   /* Check whether to do optimization to transform TLS GD/IE
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 8935bfc9c77..6912549446c 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -4634,38 +4634,9 @@ _bfd_x86_elf_link_setup_gnu_properties
 	}
     }
 
-  dynobj = htab->elf.dynobj;
-
   /* Set htab->elf.dynobj here so that there is no need to check and
      set it in check_relocs.  */
-  if (dynobj == NULL)
-    {
-      if (pbfd != NULL)
-	{
-	  htab->elf.dynobj = pbfd;
-	  dynobj = pbfd;
-	}
-      else
-	{
-	  bfd *abfd;
-
-	  /* Find a normal input file to hold linker created
-	     sections.  */
-	  for (abfd = info->input_bfds;
-	       abfd != NULL;
-	       abfd = abfd->link.next)
-	    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
-		&& (abfd->flags
-		    & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0
-		&& bed->relocs_compatible (abfd->xvec,
-					   info->output_bfd->xvec))
-	      {
-		htab->elf.dynobj = abfd;
-		dynobj = abfd;
-		break;
-	      }
-	}
-    }
+  dynobj = _bfd_elf_link_dynobj_internal (info, false);
 
   /* Return if there are no normal input files.  */
   if (dynobj == NULL)
diff --git a/ld/testsuite/ld-aarch64/relocs.ld b/ld/testsuite/ld-aarch64/relocs.ld
index b0e75e0e29a..7d1609bd1d2 100644
--- a/ld/testsuite/ld-aarch64/relocs.ld
+++ b/ld/testsuite/ld-aarch64/relocs.ld
@@ -11,6 +11,10 @@ SECTIONS
     *(.text)
     *(.after)
   } =0
+  .rodata :
+  {
+    *(.rodata)
+  }
   . = 0x20000;
   .got            : { *(.got) *(.got.plt)}
   . = 0x12340000;
@@ -20,4 +24,15 @@ SECTIONS
      generated, which gives somewhere else for the linker to put the TLS
      segment without creating a RWX permissioned one. */
   .data : { *(.data) }
+  .data.unaligned_local : { *(.data.unaligned_local) }
+  .data.unaligned_hidden : { *(.data.unaligned_hidden) }
+  .data.unaligned_global : { *(.data.unaligned_global) }
+  .data.unaligned_DYNAMIC : { *(.data.unaligned_DYNAMIC) }
+  .data.aligned_local : { *(.data.aligned_local) }
+  .data.aligned_hidden : { *(.data.aligned_hidden) }
+  .data.aligned_global : { *(.data.aligned_global) }
+  .data.aligned_global_abs : { *(.data.aligned_global_abs) }
+  .data.aligned_weak_undef : { *(.data.aligned_weak_undef) }
+  .data.aligned_DYNAMIC : { *(.data.aligned_DYNAMIC) }
+  .dynamic : { *(.dynamic) }
 }


More information about the Binutils mailing list