arm: delay setting of plt header and entry size

Message ID b55f8cf89d4c95eff688661be7c3f9fb99396d89.1778457849.git.amodra@gmail.com
State New
Headers
Series arm: delay setting of plt header and entry size |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed

Commit Message

Alan Modra May 11, 2026, 5:11 a.m. UTC
  elf32_arm_create_dynamic_sections was used to set plt_header_size and
plt_entry_size.  This necessitated a hack for using_thumb_only() as
the output file attributes used by that function are not set until
lang_check calls bfd_merge_private_bfd_data.  Now the earliest use of
plt_header_size and plt_entry_size is in elf32_arm_late_size_sections,
called from bfd_elf_size_dynamic_sections.  So this patch moves the
initialisation of these variables to elf32_arm_late_size_sections.
Initialising them there is after lang_check runs, and also guarantees
they are initialised for all later uses too.

The patch also moves initialisation of htab->stub_bfd earlier, and
calls to add_glue_sections_to_bfd and get_bfd_for_interworking from
ld/armelf.em to bfd/elf32-arm.c.  I removed an abort in
elf32_arm_create_dynamic_sections too.  It really doesn't improve
confidence that much to check that a function you have just called to
create dynamic sections has done its job.

	PR 16017
bfd/
	* elf32-arm.c (elf32_arm_plt_needs_thumb_stub_p): Formatting.
	(elf32_arm_create_dynamic_sections): Remove abort.  Move
	initialisation of plt_header_size and plt_entry_size to..
	(elf32_arm_late_size_sections): ..here.
	(bfd_elf32_arm_add_glue_sections_to_bfd),
	(bfd_elf32_arm_get_bfd_for_interworking): Make static.
	(bfd_elf32_arm_set_target_params): Add stub_bfd param.  Remove
	output_bfd param.  Make params const.  Init globals->stub_bfd.
	Set flags and EI_CLASS for stub_bfd.  Call
	add_glue_sections_to_bfd and get_bfd_for_interworking.
	* elf32-arm.h (bfd_elf32_arm_add_glue_sections_to_bfd),
	(bfd_elf32_arm_get_bfd_for_interworking): Delete declarations.
	(bfd_elf32_arm_set_target_params): Update prototype.
ld/
	* emultempl/armelf.em (arm_elf_create_output_section_statements):
	Don't set stub bfd flags here, or call
	add_glue_sections_to_bfd and get_bfd_for_interworking.  Pass
	stub bfd to set_target_params.
  

Patch

diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index aeef471cb06..bb0a24127ab 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -3672,8 +3672,9 @@  elf32_arm_plt_needs_thumb_stub_p (struct bfd_link_info *info,
 
   htab = elf32_arm_hash_table (info);
 
-  return (!using_thumb_only (htab) && (arm_plt->thumb_refcount != 0
-	  || (!htab->use_blx && arm_plt->maybe_thumb_refcount != 0)));
+  return (!using_thumb_only (htab)
+	  && (arm_plt->thumb_refcount != 0
+	      || (!htab->use_blx && arm_plt->maybe_thumb_refcount != 0)));
 }
 
 /* Return a pointer to the head of the dynamic reloc list that should
@@ -3917,59 +3918,10 @@  elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
     return false;
 
 #ifdef OBJ_MAYBE_ELF_VXWORKS
-  if (htab->root.target_os == is_vxworks)
-    {
-      if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
-	return false;
-
-      if (bfd_link_pic (info))
-	{
-	  htab->plt_header_size = 0;
-	  htab->plt_entry_size
-	    = 4 * ARRAY_SIZE (elf32_arm_vxworks_shared_plt_entry);
-	}
-      else
-	{
-	  htab->plt_header_size
-	    = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt0_entry);
-	  htab->plt_entry_size
-	    = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
-	}
-
-      if (elf_elfheader (dynobj))
-	elf_elfheader (dynobj)->e_ident[EI_CLASS] = ELFCLASS32;
-    }
-  else
-#endif /* OBJ_MAYBE_ELF_VXWORKS */
-    {
-      /* PR ld/16017
-	 Test for thumb only architectures.  Note - we cannot just call
-	 using_thumb_only() as the attributes in the output bfd have not been
-	 initialised at this point, so instead we use the input bfd.  */
-      bfd * saved_obfd = htab->obfd;
-
-      htab->obfd = dynobj;
-      if (using_thumb_only (htab))
-	{
-	  htab->plt_header_size = 4 * ARRAY_SIZE (elf32_thumb2_plt0_entry);
-	  htab->plt_entry_size  = 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
-	}
-      htab->obfd = saved_obfd;
-    }
-
-  if (htab->fdpic_p) {
-    htab->plt_header_size = 0;
-    if (info->flags & DF_BIND_NOW)
-      htab->plt_entry_size = 4 * (ARRAY_SIZE (elf32_arm_fdpic_plt_entry) - 5);
-    else
-      htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_fdpic_plt_entry);
-  }
-
-  if (!htab->root.splt
-      || !htab->root.srelplt
-      || !htab->root.sdynbss
-      || (!bfd_link_pic (info) && !htab->root.srelbss))
-    abort ();
+  if (htab->root.target_os == is_vxworks
+      && !elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
+    return false;
+#endif
 
   return true;
 }
@@ -6408,7 +6360,6 @@  elf32_arm_size_stubs (bfd *output_bfd,
 		     bfd_get_mach (output_bfd));
 
   /* Stash our params away.  */
-  htab->stub_bfd = stub_bfd;
   htab->add_stub_section = add_stub_section;
   htab->layout_sections_again = layout_sections_again;
   stubs_always_after_branch = group_size < 0;
@@ -7680,10 +7631,9 @@  bfd_elf32_arm_use_long_plt (void)
   elf32_arm_use_long_plt_entry = true;
 }
 
-/* Add the glue sections to ABFD.  This function is called from the
-   linker scripts in ld/emultempl/{armelf}.em.  */
+/* Add the glue sections to the stub bfd.  */
 
-bool
+static bool
 bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
 					struct bfd_link_info *info)
 {
@@ -7740,11 +7690,9 @@  bfd_elf32_arm_keep_private_stub_output_sections (struct bfd_link_info *info)
     }
 }
 
-/* Select a BFD to be used to hold the sections used by the glue code.
-   This function is called from the linker scripts in ld/emultempl/
-   {armelf/pe}.em.  */
+/* Select a BFD to be used to hold the sections used by the glue code.  */
 
-bool
+static bool
 bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
 {
   struct elf32_arm_link_hash_table *globals;
@@ -8996,9 +8944,9 @@  bfd_elf32_arm_stm32l4xx_erratum_scan (bfd *abfd,
 /* Set target relocation values needed during linking.  */
 
 void
-bfd_elf32_arm_set_target_params (struct bfd *output_bfd,
-				 struct bfd_link_info *link_info,
-				 struct elf32_arm_params *params)
+bfd_elf32_arm_set_target_params (struct bfd_link_info *link_info,
+				 const struct elf32_arm_params *params,
+				 struct bfd *stub_bfd)
 {
   struct elf32_arm_link_hash_table *globals;
 
@@ -9033,11 +8981,19 @@  bfd_elf32_arm_set_target_params (struct bfd *output_bfd,
   globals->cmse_implib = params->cmse_implib;
   globals->in_implib_bfd = params->in_implib_bfd;
 
-  BFD_ASSERT (is_arm_elf (output_bfd));
-  elf_arm_tdata (output_bfd)->no_enum_size_warning
+  BFD_ASSERT (is_arm_elf (link_info->output_bfd));
+  elf_arm_tdata (link_info->output_bfd)->no_enum_size_warning
     = params->no_enum_size_warning;
-  elf_arm_tdata (output_bfd)->no_wchar_size_warning
+  elf_arm_tdata (link_info->output_bfd)->no_wchar_size_warning
     = params->no_wchar_size_warning;
+
+  globals->stub_bfd = stub_bfd;
+  stub_bfd->flags |= BFD_LINKER_CREATED;
+  elf_elfheader (stub_bfd)->e_ident[EI_CLASS] = ELFCLASS32;
+
+  /* Also use the stub file for stubs placed in a single output section.  */
+  bfd_elf32_arm_add_glue_sections_to_bfd (stub_bfd, link_info);
+  bfd_elf32_arm_get_bfd_for_interworking (stub_bfd, link_info);
 }
 
 /* Replace the target offset of a Thumb bl or b.w instruction.  */
@@ -16699,6 +16655,38 @@  elf32_arm_late_size_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
 	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
 	  s->alloced = 1;
 	}
+
+#ifdef OBJ_MAYBE_ELF_VXWORKS
+      if (htab->root.target_os == is_vxworks)
+	{
+	  if (bfd_link_pic (info))
+	    {
+	      htab->plt_header_size = 0;
+	      htab->plt_entry_size
+		= 4 * ARRAY_SIZE (elf32_arm_vxworks_shared_plt_entry);
+	    }
+	  else
+	    {
+	      htab->plt_header_size
+		= 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt0_entry);
+	      htab->plt_entry_size
+		= 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
+	    }
+	}
+      else
+#endif /* OBJ_MAYBE_ELF_VXWORKS */
+      if (htab->fdpic_p)
+	{
+	  htab->plt_header_size = 0;
+	  htab->plt_entry_size = 4 * ARRAY_SIZE (elf32_arm_fdpic_plt_entry);
+	  if (info->flags & DF_BIND_NOW)
+	    htab->plt_entry_size -= 4 * 5;
+	}
+      else if (using_thumb_only (htab))
+	{
+	  htab->plt_header_size = 4 * ARRAY_SIZE (elf32_thumb2_plt0_entry);
+	  htab->plt_entry_size  = 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
+	}
     }
 
   /* Set up .got offsets for local syms, and space for local dynamic
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
index 84f3c80c94b..11d479d3e8c 100644
--- a/bfd/elf32-arm.h
+++ b/bfd/elf32-arm.h
@@ -87,13 +87,7 @@  struct elf32_arm_params {
 };
 
 void bfd_elf32_arm_set_target_params
-  (bfd *, struct bfd_link_info *, struct elf32_arm_params *);
-
-extern bool bfd_elf32_arm_get_bfd_for_interworking
-  (bfd *, struct bfd_link_info *);
-
-extern bool bfd_elf32_arm_add_glue_sections_to_bfd
-  (bfd *, struct bfd_link_info *);
+  (struct bfd_link_info *, const struct elf32_arm_params *, bfd *);
 
 extern void bfd_elf32_arm_keep_private_stub_output_sections
   (struct bfd_link_info *);
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index c743c6f80d4..265b77816f4 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -538,8 +538,6 @@  arm_elf_create_output_section_statements (void)
 	fatal (_("%P: %s: not a relocatable file: %E\n"), in_implib_filename);
     }
 
-  bfd_elf32_arm_set_target_params (link_info.output_bfd, &link_info, &params);
-
   stub_file = lang_add_input_file ("linker stubs",
 				   lang_input_file_is_fake_enum,
 				   NULL);
@@ -552,13 +550,9 @@  arm_elf_create_output_section_statements (void)
       fatal (_("%P: can not create BFD: %E\n"));
       return;
     }
-
-  stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
   ldlang_add_file (stub_file);
 
-  /* Also use the stub file for stubs placed in a single output section.  */
-  bfd_elf32_arm_add_glue_sections_to_bfd (stub_file->the_bfd, &link_info);
-  bfd_elf32_arm_get_bfd_for_interworking (stub_file->the_bfd, &link_info);
+  bfd_elf32_arm_set_target_params (&link_info, &params, stub_file->the_bfd);
 }
 
 EOF