[PATCH v2] PE/COFF: auto-promote oversized objects to bigobj

Oleg Tolmatcev oleg.tolmatcev@gmail.com
Tue Jun 23 21:39:01 GMT 2026


PE/COFF object files use 16-bit section numbers in normal symbols.
When an object grows past that limit, current BFD already rejects it with
a "too many sections" / "file too big" error.

BFD already has PE bigobj targets for the backends that support them, but
oversized PE/COFF output still requires selecting bigobj explicitly.

Teach coff_compute_section_file_positions to switch PE/COFF output to the
corresponding bigobj target when the normal section-number limit is
exceeded. This preserves the existing hard error for targets without
bigobj support, but lets supported PE targets transparently emit a valid
bigobj object instead of requiring manual selection.

bfd/
	* coffcode.h (coff_compute_section_file_positions): Auto-promote
	oversized PE/COFF objects to the bigobj target.

gas/
	* testsuite/gas/pe/big-obj-auto.d: New test.
	* testsuite/gas/pe/big-obj-auto.s: New test.
	* testsuite/gas/pe/pe.exp: Run big-obj-auto.

Signed-off-by: Oleg Tolmatcev <oleg.tolmatcev@gmail.com>
---
 bfd/coffcode.h                      | 14 ++++++++++++++
 gas/testsuite/gas/pe/big-obj-auto.d |  9 +++++++++
 gas/testsuite/gas/pe/big-obj-auto.s | 16 ++++++++++++++++
 gas/testsuite/gas/pe/pe.exp         |  4 +++-
 4 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/pe/big-obj-auto.d
 create mode 100644 gas/testsuite/gas/pe/big-obj-auto.s

diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 7439fca676..5c9722a15e 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -360,6 +360,10 @@ CODE_FRAGMENT
 #include "coffswap.h"
 #endif
 
+#ifdef COFF_WITH_PE_BIGOBJ
+extern const bfd_target TARGET_SYM_BIG;
+#endif
+
 #define STRING_SIZE_SIZE 4
 
 #define DOT_DEBUG	".debug"
@@ -3154,6 +3158,16 @@ coff_compute_section_file_positions (bfd * abfd)
 
   if (target_index >= bfd_coff_max_nscns (abfd))
     {
+#ifdef COFF_WITH_PE_BIGOBJ
+      if (abfd->xvec != &TARGET_SYM_BIG)
+	{
+	  /* Regular PE/COFF uses 16-bit section numbers in symbols.
+	     Promote oversized objects to the matching bigobj target
+	     before any headers or symbols are finalized.  */
+	  abfd->xvec = &TARGET_SYM_BIG;
+	  return coff_compute_section_file_positions (abfd);
+	}
+#endif
       bfd_set_error (bfd_error_file_too_big);
       _bfd_error_handler
 	/* xgettext:c-format */
diff --git a/gas/testsuite/gas/pe/big-obj-auto.d b/gas/testsuite/gas/pe/big-obj-auto.d
new file mode 100644
index 0000000000..985c1270e2
--- /dev/null
+++ b/gas/testsuite/gas/pe/big-obj-auto.d
@@ -0,0 +1,9 @@
+#objdump: -h
+#name: PE big obj auto-promotion
+
+.*: *file format pe-bigobj-.*
+
+Sections:
+#...
+80002 +\.data\$a79999  .*
+                  CONTENTS, ALLOC, LOAD, DATA
diff --git a/gas/testsuite/gas/pe/big-obj-auto.s b/gas/testsuite/gas/pe/big-obj-auto.s
new file mode 100644
index 0000000000..8c010716c6
--- /dev/null
+++ b/gas/testsuite/gas/pe/big-obj-auto.s
@@ -0,0 +1,16 @@
+	.file "big-obj-auto.s"
+
+	.irp n,0,1,2,3,4,5,6,7
+	.irp m,0,1,2,3,4,5,6,7,8,9
+	.irp c,0,1,2,3,4,5,6,7,8,9
+	.irp d,0,1,2,3,4,5,6,7,8,9
+	.irp u,0,1,2,3,4,5,6,7,8,9
+	.globl a\n\m\c\d\u
+	.section .data$a\n\m\c\d\u,"w"
+a\n\m\c\d\u :
+	.byte 1
+	.endr
+	.endr
+	.endr
+	.endr
+	.endr
diff --git a/gas/testsuite/gas/pe/pe.exp b/gas/testsuite/gas/pe/pe.exp
index e25de3cfa9..2aba5ecb3d 100644
--- a/gas/testsuite/gas/pe/pe.exp
+++ b/gas/testsuite/gas/pe/pe.exp
@@ -68,6 +68,8 @@ if {[istarget "aarch64-*-pe*"] || [istarget "aarch64-*-mingw*"]} {
 # Big obj
 
 
-if ([istarget "*-*-mingw*"]) then {
+if { [istarget "aarch64-*-*"] || [istarget "i*86-*-*"]
+    || [istarget "x86_64-*-*"] } then {
 	run_dump_test "big-obj"
+	run_dump_test "big-obj-auto"
 }
-- 
2.54.0.windows.1



More information about the Binutils mailing list