[binutils-gdb] elflink.c: input object compatibility checks

Alan Modra amodra@sourceware.org
Mon Aug 17 01:24:24 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d77630b6d6e9fae8cf74e32816cb52e7b2ffcbcb

commit d77630b6d6e9fae8cf74e32816cb52e7b2ffcbcb
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Aug 6 11:15:12 2026 +0930

    elflink.c: input object compatibility checks
    
    A number of places in elflink.c need to check that the input object
    relocs are compatible with the output.  Extract those checks into a
    new function.  Note that the seeming extra condition on sec_info_type
    in _bfd_elf_link_iterate_on_relocs is just an early out, as
    --just-symbols objects will have all section's output_section set to
    the absolute section, and that is checked in the loop.
    
            * elflink.c (compatible_format): New function.
            (_bfd_elf_link_create_dynstrtab): Use compatible_format.
            (_bfd_elf_link_iterate_on_relocs, bfd_elf_gc_sections): Likewise.
            (elf_gc_sweep): Likewise.  Lose unused obfd param.

Diff:
---
 bfd/elflink.c | 73 ++++++++++++++++++++++++-----------------------------------
 1 file changed, 30 insertions(+), 43 deletions(-)

diff --git a/bfd/elflink.c b/bfd/elflink.c
index cc29b99ba56..bee57bcdff4 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -282,7 +282,24 @@ _bfd_elf_create_got_section (bfd *dynobj, struct bfd_link_info *info)
 
   return true;
 }
-

+
+/* Return true if IBFD is compatible with the output.  Used for example
+   to decide whether an object file can hold linker generated dynamic
+   sections, and whether object file relocations can be examined by
+   check_relocs (for plt/got/dyn reloc generation).  */
+
+static bool
+compatible_format (struct bfd_link_info *info, bfd *ibfd)
+{
+  return (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
+	  && is_elf_hash_table (info->hash)
+	  && elf_object_id (ibfd) == elf_hash_table_id (elf_hash_table (info))
+	  && !(ibfd->sections != NULL
+	       && ibfd->sections->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+	  && (get_elf_backend_data (ibfd)
+	      ->relocs_compatible (ibfd->xvec, info->output_bfd->xvec)));
+}
+
 /* Create a strtab to hold the dynamic symbol names.  */
 static bool
 _bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
@@ -299,14 +316,10 @@ _bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
       if ((abfd->flags & (DYNAMIC | BFD_PLUGIN)) != 0)
 	{
 	  bfd *ibfd;
-	  asection *s;
 	  for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
 	    if ((ibfd->flags
 		 & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0
-		&& bfd_get_flavour (ibfd) == bfd_target_elf_flavour
-		&& elf_object_id (ibfd) == elf_hash_table_id (hash_table)
-		&& !((s = ibfd->sections) != NULL
-		     && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS))
+		&& compatible_format (info, ibfd))
 	      {
 		abfd = ibfd;
 		break;
@@ -4270,9 +4283,6 @@ _bfd_elf_link_iterate_on_relocs
    bool (*action) (bfd *, struct bfd_link_info *, asection *,
 		   const Elf_Internal_Rela *))
 {
-  elf_backend_data *bed = get_elf_backend_data (abfd);
-  struct elf_link_hash_table *htab = elf_hash_table (info);
-
   /* If this object is the same format as the output object, and it is
      not a shared library, then let the backend look through the
      relocs.
@@ -4291,13 +4301,9 @@ _bfd_elf_link_iterate_on_relocs
      I have no idea how to handle linking PIC code into a file of a
      different format.  It probably can't be done.  */
   if ((abfd->flags & DYNAMIC) == 0
-      && is_elf_hash_table (&htab->root)
-      && elf_object_id (abfd) == elf_hash_table_id (htab)
-      && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec))
+      && compatible_format (info, abfd))
     {
-      asection *o;
-
-      for (o = abfd->sections; o != NULL; o = o->next)
+      for (asection *o = abfd->sections; o != NULL; o = o->next)
 	{
 	  Elf_Internal_Rela *internal_relocs;
 	  bool ok;
@@ -14384,24 +14390,14 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
 }
 
 static bool
-elf_gc_sweep (bfd *obfd, struct bfd_link_info *info)
+elf_gc_sweep (struct bfd_link_info *info)
 {
-  bfd *sub;
-  elf_backend_data *obed = get_elf_backend_data (obfd);
-
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+  for (bfd *sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     {
-      asection *o;
-
-      if (bfd_get_flavour (sub) != bfd_target_elf_flavour
-	  || elf_object_id (sub) != elf_hash_table_id (elf_hash_table (info))
-	  || !obed->relocs_compatible (sub->xvec, obfd->xvec))
-	continue;
-      o = sub->sections;
-      if (o == NULL || o->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+      if (!compatible_format (info, sub))
 	continue;
 
-      for (o = sub->sections; o != NULL; o = o->next)
+      for (asection *o = sub->sections; o != NULL; o = o->next)
 	{
 	  /* When any section in a section group is kept, we keep all
 	     sections in the section group.  If the first member of
@@ -14648,7 +14644,6 @@ bool
 bfd_elf_gc_sections (bfd *obfd, struct bfd_link_info *info)
 {
   bool ok = true;
-  bfd *sub;
   elf_gc_mark_hook_fn gc_mark_hook;
   elf_backend_data *obed = get_elf_backend_data (obfd);
   struct elf_link_hash_table *htab;
@@ -14666,7 +14661,7 @@ bfd_elf_gc_sections (bfd *obfd, struct bfd_link_info *info)
 
   /* Try to parse each bfd's .eh_frame section.  Point elf_eh_frame_section
      at the .eh_frame section if we can mark the FDEs individually.  */
-  for (sub = info->input_bfds;
+  for (bfd *sub = info->input_bfds;
        info->eh_frame_hdr_type != COMPACT_EH_HDR && sub != NULL;
        sub = sub->link.next)
     {
@@ -14724,24 +14719,16 @@ bfd_elf_gc_sections (bfd *obfd, struct bfd_link_info *info)
 
   /* Grovel through relocs to find out who stays ...  */
   gc_mark_hook = obed->gc_mark_hook;
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+  for (bfd *sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     {
-      asection *o;
-
-      if (bfd_get_flavour (sub) != bfd_target_elf_flavour
-	  || elf_object_id (sub) != elf_hash_table_id (htab)
-	  || !obed->relocs_compatible (sub->xvec, obfd->xvec))
-	continue;
-
-      o = sub->sections;
-      if (o == NULL || o->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+      if (!compatible_format (info, sub))
 	continue;
 
       /* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep).
 	 Also treat note sections as a root, if the section is not part
 	 of a group.  We must keep all PREINIT_ARRAY, INIT_ARRAY as
 	 well as FINI_ARRAY sections for ld -r.  */
-      for (o = sub->sections; o != NULL; o = o->next)
+      for (asection *o = sub->sections; o != NULL; o = o->next)
 	if (!o->gc_mark
 	    && (o->flags & SEC_EXCLUDE) == 0
 	    && ((o->flags & SEC_KEEP) != 0
@@ -14768,7 +14755,7 @@ bfd_elf_gc_sections (bfd *obfd, struct bfd_link_info *info)
     return false;
 
   /* ... and mark SEC_EXCLUDE for those that go.  */
-  return elf_gc_sweep (obfd, info);
+  return elf_gc_sweep (info);
 }
 

 /* Called from check_relocs to record the existence of a VTINHERIT reloc.  */


More information about the Binutils-cvs mailing list