[binutils-gdb] BFD: Make `bfd_finalize_section_relocs' return status

Maciej W. Rozycki macro@sourceware.org
Wed Jan 14 22:31:11 GMT 2026


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

commit ca2186f9ca89e4d0602e67d2ecca997c8a097aa6
Author: Maciej W. Rozycki <macro@orcam.me.uk>
Date:   Wed Jan 14 22:28:43 2026 +0000

    BFD: Make `bfd_finalize_section_relocs' return status
    
    Update `bfd_finalize_section_relocs' to return status so that backends
    can fail in this interface and propagate that to the respective callers.
    Add suitable error reporting there.  No failure cases in the existing
    handlers though.

Diff:
---
 bfd/bfd-in2.h          |  4 ++--
 bfd/bfd.c              |  2 +-
 bfd/elf64-sparc.c      |  3 ++-
 bfd/libbfd-in.h        |  2 +-
 bfd/libbfd.c           |  4 ++--
 bfd/libbfd.h           |  4 ++--
 bfd/reloc.c            |  5 +++--
 bfd/targets.c          |  2 +-
 binutils/objcopy.c     | 11 ++++++++---
 binutils/rescoff.c     |  8 +++++++-
 gas/config/obj-coff.c  |  6 ++++--
 gas/config/obj-coff.h  |  2 +-
 gas/config/obj-macho.c |  4 ++--
 gas/config/obj-macho.h |  2 +-
 gas/write.c            |  3 ++-
 ld/ldlang.c            | 18 +++++++++++++++---
 16 files changed, 54 insertions(+), 26 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 131e969a083..d4e4f8e4375 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2613,7 +2613,7 @@ long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect);
 long bfd_canonicalize_reloc
    (bfd *abfd, asection *sec, arelent **loc, asymbol **syms);
 
-void bfd_finalize_section_relocs
+bool bfd_finalize_section_relocs
    (bfd *abfd, asection *sec, arelent **rel, unsigned int count);
 
 #define bfd_finalize_section_relocs(abfd, asect, location, count) \
@@ -7664,7 +7664,7 @@ typedef struct bfd_target
   long (*_get_reloc_upper_bound) (bfd *, sec_ptr);
   long (*_bfd_canonicalize_reloc) (bfd *, sec_ptr, arelent **,
 				   struct bfd_symbol **);
-  void (*_bfd_finalize_section_relocs) (bfd *, sec_ptr, arelent **,
+  bool (*_bfd_finalize_section_relocs) (bfd *, sec_ptr, arelent **,
 					unsigned int);
   /* See documentation on reloc types.  */
   reloc_howto_type *
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 0c97a495e2f..35669075da2 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2202,7 +2202,7 @@ FUNCTION
 	bfd_finalize_section_relocs
 
 SYNOPSIS
-	void bfd_finalize_section_relocs
+	bool bfd_finalize_section_relocs
 	  (bfd *abfd, asection *sec, arelent **rel, unsigned int count);
 
 DESCRIPTION
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
index 2a192ddabc9..c73f2934edf 100644
--- a/bfd/elf64-sparc.c
+++ b/bfd/elf64-sparc.c
@@ -314,7 +314,7 @@ elf64_sparc_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
 
 /* Install a new set of internal relocs.  */
 
-static void
+static bool
 elf64_sparc_finalize_section_relocs (bfd *abfd ATTRIBUTE_UNUSED,
 				     asection *asect,
 				     arelent **location,
@@ -326,6 +326,7 @@ elf64_sparc_finalize_section_relocs (bfd *abfd ATTRIBUTE_UNUSED,
     asect->flags |= SEC_RELOC;
   else
     asect->flags &= ~SEC_RELOC;
+  return true;
 }
 
 /* Write out the relocs.  */
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index b9a1ca44224..a5186b5e6f0 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -447,7 +447,7 @@ extern long _bfd_norelocs_get_reloc_upper_bound
   (bfd *, asection *) ATTRIBUTE_HIDDEN;
 extern long _bfd_norelocs_canonicalize_reloc
   (bfd *, asection *, arelent **, asymbol **) ATTRIBUTE_HIDDEN;
-extern void _bfd_norelocs_finalize_section_relocs
+extern bool _bfd_norelocs_finalize_section_relocs
   (bfd *, asection *, arelent **, unsigned int) ATTRIBUTE_HIDDEN;
 extern reloc_howto_type *_bfd_norelocs_bfd_reloc_type_lookup
   (bfd *, bfd_reloc_code_real_type) ATTRIBUTE_HIDDEN;
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
index 8be82665342..6311ef49f6e 100644
--- a/bfd/libbfd.c
+++ b/bfd/libbfd.c
@@ -199,13 +199,13 @@ _bfd_norelocs_canonicalize_reloc (bfd *abfd ATTRIBUTE_UNUSED,
   return 0;
 }
 
-void
+bool
 _bfd_norelocs_finalize_section_relocs (bfd *abfd ATTRIBUTE_UNUSED,
 				       asection *sec ATTRIBUTE_UNUSED,
 				       arelent **relptr ATTRIBUTE_UNUSED,
 				       unsigned int count ATTRIBUTE_UNUSED)
 {
-  /* Do nothing.  */
+  return true;
 }
 
 bool
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 5d394785236..a27134dcd78 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -453,7 +453,7 @@ extern long _bfd_norelocs_get_reloc_upper_bound
   (bfd *, asection *) ATTRIBUTE_HIDDEN;
 extern long _bfd_norelocs_canonicalize_reloc
   (bfd *, asection *, arelent **, asymbol **) ATTRIBUTE_HIDDEN;
-extern void _bfd_norelocs_finalize_section_relocs
+extern bool _bfd_norelocs_finalize_section_relocs
   (bfd *, asection *, arelent **, unsigned int) ATTRIBUTE_HIDDEN;
 extern reloc_howto_type *_bfd_norelocs_bfd_reloc_type_lookup
   (bfd *, bfd_reloc_code_real_type) ATTRIBUTE_HIDDEN;
@@ -3530,7 +3530,7 @@ bfd_byte *bfd_generic_get_relocated_section_contents
     bool relocatable,
     asymbol **symbols) ATTRIBUTE_HIDDEN;
 
-void _bfd_generic_finalize_section_relocs
+bool _bfd_generic_finalize_section_relocs
    (bfd *abfd,
     sec_ptr section,
     arelent **relptr,
diff --git a/bfd/reloc.c b/bfd/reloc.c
index aea90fbc327..98343696a33 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8365,7 +8365,7 @@ INTERNAL_FUNCTION
 	_bfd_generic_finalize_section_relocs
 
 SYNOPSIS
-	void _bfd_generic_finalize_section_relocs
+	bool _bfd_generic_finalize_section_relocs
 	  (bfd *abfd,
 	   sec_ptr section,
 	   arelent **relptr,
@@ -8375,7 +8375,7 @@ DESCRIPTION
 	Installs a new set of internal relocations in SECTION.
 */
 
-void
+bool
 _bfd_generic_finalize_section_relocs (bfd *abfd ATTRIBUTE_UNUSED,
 				      sec_ptr section,
 				      arelent **relptr,
@@ -8387,6 +8387,7 @@ _bfd_generic_finalize_section_relocs (bfd *abfd ATTRIBUTE_UNUSED,
     section->flags |= SEC_RELOC;
   else
     section->flags &= ~SEC_RELOC;
+  return true;
 }
 
 /*
diff --git a/bfd/targets.c b/bfd/targets.c
index 864ff625f55..dce4b88a20c 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -438,7 +438,7 @@ BFD_JUMP_TABLE macros.
 .  long	(*_get_reloc_upper_bound) (bfd *, sec_ptr);
 .  long	(*_bfd_canonicalize_reloc) (bfd *, sec_ptr, arelent **,
 .				    struct bfd_symbol **);
-.  void	(*_bfd_finalize_section_relocs) (bfd *, sec_ptr, arelent **,
+.  bool (*_bfd_finalize_section_relocs) (bfd *, sec_ptr, arelent **,
 .					 unsigned int);
 .  {* See documentation on reloc types.  *}
 .  reloc_howto_type *
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index aea69ba886a..5f44c6295f2 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -4555,7 +4555,10 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, bfd *obfd)
     }
 
   if (relsize == 0)
-    bfd_finalize_section_relocs (obfd, osection, NULL, 0);
+    {
+      if (!bfd_finalize_section_relocs (obfd, osection, NULL, 0))
+	return false;
+    }
   else
     {
       if (isection->orelocation != NULL)
@@ -4596,8 +4599,10 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, bfd *obfd)
 	  *w_relpp = 0;
 	}
 
-      bfd_finalize_section_relocs (obfd, osection,
-				   relcount == 0 ? NULL : relpp, relcount);
+      if (!bfd_finalize_section_relocs (obfd, osection,
+					relcount == 0 ? NULL : relpp,
+					relcount))
+	return false;
     }
   return true;
 }
diff --git a/binutils/rescoff.c b/binutils/rescoff.c
index afeadf161c1..6b07ddd2bcb 100644
--- a/binutils/rescoff.c
+++ b/binutils/rescoff.c
@@ -685,7 +685,13 @@ write_coff_file (const char *filename, const char *target,
       return false;
     }
 
-  bfd_finalize_section_relocs (abfd, sec, cwi.relocs, cwi.reloc_count);
+  if (!bfd_finalize_section_relocs (abfd, sec, cwi.relocs, cwi.reloc_count))
+    {
+      bfd_nonfatal ("bfd_finalize_section_relocs");
+      bfd_close_all_done (abfd);
+      free (cwi.relocs);
+      return false;
+    }
 
   offset = 0;
   for (d = cwi.dirs.d; d != NULL; d = d->next)
diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c
index b01ef975763..30e3ca2e2c8 100644
--- a/gas/config/obj-coff.c
+++ b/gas/config/obj-coff.c
@@ -1517,13 +1517,14 @@ coff_frob_file_after_relocs (void)
 /* Set relocations for the section and then store the number of relocations
    in its aux entry.  */
 
-void
+bool
 obj_coff_finalize_section_relocs (asection *sec, arelent **relocs,
 				  unsigned int n)
 {
   symbolS *sect_sym;
 
-  bfd_finalize_section_relocs (stdoutput, sec, n ? relocs : NULL, n);
+  if (!bfd_finalize_section_relocs (stdoutput, sec, n ? relocs : NULL, n))
+    return false;
   sect_sym = section_symbol (sec);
 #ifdef OBJ_XCOFF
   if (S_GET_STORAGE_CLASS (sect_sym) == C_DWARF)
@@ -1531,6 +1532,7 @@ obj_coff_finalize_section_relocs (asection *sec, arelent **relocs,
   else
 #endif
     SA_SET_SCN_NRELOC (sect_sym, n);
+  return true;
 }
 
 /* Implement the .section pseudo op:
diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h
index 8fb39dbfcd2..0b933f467b2 100644
--- a/gas/config/obj-coff.h
+++ b/gas/config/obj-coff.h
@@ -296,7 +296,7 @@ extern void coff_pop_insert (void);
 /* We need to store the number of relocations in the section aux entry.  */
 #define FINALIZE_SECTION_RELOCS(sec, relocs, n) \
   obj_coff_finalize_section_relocs (sec, relocs, n)
-extern void obj_coff_finalize_section_relocs (asection *, arelent **,
+extern bool obj_coff_finalize_section_relocs (asection *, arelent **,
 					      unsigned int);
 
 extern int  S_SET_DATA_TYPE              (symbolS *, int);
diff --git a/gas/config/obj-macho.c b/gas/config/obj-macho.c
index 06ace7a0756..5b16e7512b4 100644
--- a/gas/config/obj-macho.c
+++ b/gas/config/obj-macho.c
@@ -1879,7 +1879,7 @@ obj_mach_o_frob_file_after_relocs (void)
 
 /* Reverse relocations order to make ld happy.  */
 
-void
+bool
 obj_mach_o_reorder_section_relocs (asection *sec, arelent **rels, unsigned int n)
 {
   unsigned int i;
@@ -1891,7 +1891,7 @@ obj_mach_o_reorder_section_relocs (asection *sec, arelent **rels, unsigned int n
       rels[i] = rels[n - i - 1];
       rels[n - i - 1] = r;
     }
-  bfd_finalize_section_relocs (stdoutput, sec, rels, n);
+  return bfd_finalize_section_relocs (stdoutput, sec, rels, n);
 }
 
 /* Relocation rules are different in frame sections.  */
diff --git a/gas/config/obj-macho.h b/gas/config/obj-macho.h
index 40dd9fb0c15..6e4b7b6d178 100644
--- a/gas/config/obj-macho.h
+++ b/gas/config/obj-macho.h
@@ -101,7 +101,7 @@ extern void obj_mach_o_frob_file_after_relocs (void);
 
 #define FINALIZE_SECTION_RELOCS(sec, relocs, n) \
   obj_mach_o_reorder_section_relocs (sec, relocs, n)
-extern void obj_mach_o_reorder_section_relocs (asection *, arelent **,
+extern bool obj_mach_o_reorder_section_relocs (asection *, arelent **,
 					       unsigned int);
 
 /* Emit relocs for local subtracts, to cater for subsections-via-symbols.  */
diff --git a/gas/write.c b/gas/write.c
index b3427145571..3494871270a 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -1419,7 +1419,8 @@ write_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
   }
 #endif
 
-  FINALIZE_SECTION_RELOCS (sec, relocs, n);
+  if (!FINALIZE_SECTION_RELOCS (sec, relocs, n))
+    as_bad (_("%s: unable to finalize relocations"), sec->name);
 
 #ifdef DEBUG3
   {
diff --git a/ld/ldlang.c b/ld/ldlang.c
index c5a128072ed..a0368ecbe42 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -10640,7 +10640,13 @@ copy_section (bfd *ibfd, sec_ptr isection, void *p)
     }
 
   if (relsize == 0)
-    bfd_finalize_section_relocs (obfd, osection, NULL, 0);
+    {
+      if (!bfd_finalize_section_relocs (obfd, osection, NULL, 0))
+	{
+	  err = _("unable to finalize relocations");
+	  goto loser;
+	}
+    }
   else
     {
       relpp = (arelent **) xmalloc (relsize);
@@ -10651,8 +10657,14 @@ copy_section (bfd *ibfd, sec_ptr isection, void *p)
 	  goto loser;
 	}
 
-      bfd_finalize_section_relocs (obfd, osection,
-				   relcount == 0 ? NULL : relpp, relcount);
+      if (!bfd_finalize_section_relocs (obfd, osection,
+					relcount == 0 ? NULL : relpp,
+					relcount))
+	{
+	  free (relpp);
+	  err = _("unable to finalize relocations");
+	  goto loser;
+	}
       if (relcount == 0)
 	free (relpp);
     }


More information about the Binutils-cvs mailing list