[PATCH v2 04/10] BFD: Make `bfd_finalize_section_relocs' return status

Maciej W. Rozycki macro@orcam.me.uk
Wed Nov 5 02:46:49 GMT 2025


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.
---
New change in v2.
---
 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(-)

binutils-bfd-finalize-section-relocs-bool.diff
Index: binutils-gdb/bfd/bfd-in2.h
===================================================================
--- binutils-gdb.orig/bfd/bfd-in2.h
+++ binutils-gdb/bfd/bfd-in2.h
@@ -2620,7 +2620,7 @@ long bfd_get_reloc_upper_bound (bfd *abf
 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) \
@@ -7806,7 +7806,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 *
Index: binutils-gdb/bfd/bfd.c
===================================================================
--- binutils-gdb.orig/bfd/bfd.c
+++ binutils-gdb/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
Index: binutils-gdb/bfd/elf64-sparc.c
===================================================================
--- binutils-gdb.orig/bfd/elf64-sparc.c
+++ binutils-gdb/bfd/elf64-sparc.c
@@ -314,7 +314,7 @@ elf64_sparc_canonicalize_dynamic_reloc (
 
 /* 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
     asect->flags |= SEC_RELOC;
   else
     asect->flags &= ~SEC_RELOC;
+  return true;
 }
 
 /* Write out the relocs.  */
Index: binutils-gdb/bfd/libbfd-in.h
===================================================================
--- binutils-gdb.orig/bfd/libbfd-in.h
+++ binutils-gdb/bfd/libbfd-in.h
@@ -454,7 +454,7 @@ extern long _bfd_norelocs_get_reloc_uppe
   (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;
Index: binutils-gdb/bfd/libbfd.c
===================================================================
--- binutils-gdb.orig/bfd/libbfd.c
+++ binutils-gdb/bfd/libbfd.c
@@ -199,13 +199,13 @@ _bfd_norelocs_canonicalize_reloc (bfd *a
   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
Index: binutils-gdb/bfd/libbfd.h
===================================================================
--- binutils-gdb.orig/bfd/libbfd.h
+++ binutils-gdb/bfd/libbfd.h
@@ -460,7 +460,7 @@ extern long _bfd_norelocs_get_reloc_uppe
   (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;
@@ -3633,7 +3633,7 @@ bfd_byte *bfd_generic_get_relocated_sect
     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,
Index: binutils-gdb/bfd/reloc.c
===================================================================
--- binutils-gdb.orig/bfd/reloc.c
+++ binutils-gdb/bfd/reloc.c
@@ -8593,7 +8593,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,
@@ -8603,7 +8603,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,
@@ -8615,6 +8615,7 @@ _bfd_generic_finalize_section_relocs (bf
     section->flags |= SEC_RELOC;
   else
     section->flags &= ~SEC_RELOC;
+  return true;
 }
 
 /*
Index: binutils-gdb/bfd/targets.c
===================================================================
--- binutils-gdb.orig/bfd/targets.c
+++ binutils-gdb/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 *
Index: binutils-gdb/binutils/objcopy.c
===================================================================
--- binutils-gdb.orig/binutils/objcopy.c
+++ binutils-gdb/binutils/objcopy.c
@@ -4555,7 +4555,10 @@ copy_relocations_in_section (bfd *ibfd,
     }
 
   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,
 	  *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;
 }
Index: binutils-gdb/binutils/rescoff.c
===================================================================
--- binutils-gdb.orig/binutils/rescoff.c
+++ binutils-gdb/binutils/rescoff.c
@@ -685,7 +685,13 @@ write_coff_file (const char *filename, c
       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)
Index: binutils-gdb/gas/config/obj-coff.c
===================================================================
--- binutils-gdb.orig/gas/config/obj-coff.c
+++ binutils-gdb/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 (asecti
   else
 #endif
     SA_SET_SCN_NRELOC (sect_sym, n);
+  return true;
 }
 
 /* Implement the .section pseudo op:
Index: binutils-gdb/gas/config/obj-coff.h
===================================================================
--- binutils-gdb.orig/gas/config/obj-coff.h
+++ binutils-gdb/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);
Index: binutils-gdb/gas/config/obj-macho.c
===================================================================
--- binutils-gdb.orig/gas/config/obj-macho.c
+++ binutils-gdb/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 (asect
       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.  */
Index: binutils-gdb/gas/config/obj-macho.h
===================================================================
--- binutils-gdb.orig/gas/config/obj-macho.h
+++ binutils-gdb/gas/config/obj-macho.h
@@ -101,7 +101,7 @@ extern void obj_mach_o_frob_file_after_r
 
 #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.  */
Index: binutils-gdb/gas/write.c
===================================================================
--- binutils-gdb.orig/gas/write.c
+++ binutils-gdb/gas/write.c
@@ -1419,7 +1419,8 @@ write_relocs (bfd *abfd ATTRIBUTE_UNUSED
   }
 #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
   {
Index: binutils-gdb/ld/ldlang.c
===================================================================
--- binutils-gdb.orig/ld/ldlang.c
+++ binutils-gdb/ld/ldlang.c
@@ -10564,7 +10564,13 @@ copy_section (bfd *ibfd, sec_ptr isectio
     }
 
   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);
@@ -10575,8 +10581,14 @@ copy_section (bfd *ibfd, sec_ptr isectio
 	  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 mailing list