[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