[binutils-gdb] arm: delay setting of plt header and entry size

Alan Modra via Binutils-cvs <[email protected]>
Newsgroups gmane.comp.gnu.binutils.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bd8942a0e049a466f9b649364bf53445fb47dd0c

commit bd8942a0e049a466f9b649364bf53445fb47dd0c
Author: Alan Modra <[email protected]>
Date:   Mon May 11 09:17:42 2026 +0930

    arm: delay setting of plt header and entry size
    
    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.

Diff:
---
 bfd/elf32-arm.c        | 126 ++++++++++++++++++++++---------------------------
 bfd/elf32-arm.h        |   8 +---
 ld/emultempl/armelf.em |   8 +---
 3 files changed, 59 insertions(+), 83 deletions(-)

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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.