]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
aarch64: Add bigobj support to AArch64 COFF
authorEvgeny Karpov <evgeny@kmaps.co>
Wed, 21 Jan 2026 13:44:44 +0000 (14:44 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 21 Jan 2026 13:44:44 +0000 (14:44 +0100)
During Boost library testing on aarch64-w64-mingw32, it appeared that 2^16
sections are not enough. It can be handled by using the bigobj format to extend
the total amount of sections to 2^32. This patch adds bigobj support to
AArch64 COFF in a similar way to how it is done for x86_64.

Co-authored-by: Martin Vejbora <mvejbora@microsoft.com>
Signed-off-by: Evgeny Karpov <evgeny@kmaps.co>
bfd/coff-aarch64.c
bfd/config.bfd
bfd/configure
bfd/configure.ac
bfd/cpu-aarch64.c
bfd/pe-aarch64.c
bfd/targets.c
gas/config/tc-aarch64.c
gas/doc/c-aarch64.texi
ld/pe-dll.c

index fae37bc1e540ebd2ae0450d57776aad739839b8b..c00448efc8296c70e8aefffebec49ec85a8a094e 100644 (file)
@@ -1018,3 +1018,78 @@ const bfd_target
 
   COFF_SWAP_TABLE
 };
+
+#ifdef COFF_WITH_PE_BIGOBJ
+const bfd_target
+  TARGET_SYM_BIG =
+{
+  TARGET_NAME_BIG,
+  bfd_target_coff_flavour,
+  BFD_ENDIAN_LITTLE,           /* Data byte order is little.  */
+  BFD_ENDIAN_LITTLE,           /* Header byte order is little.  */
+
+  (HAS_RELOC | EXEC_P          /* Object flags.  */
+   | HAS_LINENO | HAS_DEBUG
+   | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
+
+  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
+#ifdef COFF_WITH_PE
+   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
+#endif
+   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
+
+#ifdef TARGET_UNDERSCORE
+  TARGET_UNDERSCORE,           /* Leading underscore.  */
+#else
+  0,                           /* Leading underscore.  */
+#endif
+  '/',                         /* Ar_pad_char.  */
+  15,                          /* Ar_max_namelen.  */
+  0,                           /* match priority.  */
+  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
+  TARGET_MERGE_SECTIONS,
+
+  /* Data conversion functions.  */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+  bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
+  /* Header conversion functions.  */
+  bfd_getl64, bfd_getl_signed_64, bfd_putl64,
+  bfd_getl32, bfd_getl_signed_32, bfd_putl32,
+  bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs.  */
+
+  /* Note that we allow an object file to be treated as a core file as well.  */
+  {                            /* bfd_check_format.  */
+    _bfd_dummy_target,
+    coff_object_p,
+    bfd_generic_archive_p,
+    coff_object_p
+  },
+  {                            /* bfd_set_format.  */
+    _bfd_bool_bfd_false_error,
+    coff_mkobject,
+    _bfd_generic_mkarchive,
+    _bfd_bool_bfd_false_error
+  },
+  {                            /* bfd_write_contents.  */
+    _bfd_bool_bfd_false_error,
+    coff_write_object_contents,
+    _bfd_write_archive_contents,
+    _bfd_bool_bfd_false_error
+  },
+
+  BFD_JUMP_TABLE_GENERIC (coff_aarch64),
+  BFD_JUMP_TABLE_COPY (coff),
+  BFD_JUMP_TABLE_CORE (_bfd_nocore),
+  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
+  BFD_JUMP_TABLE_SYMBOLS (coff),
+  BFD_JUMP_TABLE_RELOCS (coff),
+  BFD_JUMP_TABLE_WRITE (coff),
+  BFD_JUMP_TABLE_LINK (coff),
+  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
+
+  NULL,
+
+  &bigobj_swap_table
+};
+#endif
index 0f74fde2accb9ef4c87a25614a271ac06ffd0bf3..4dde5321f2376bf4e71df8c803623a214277b694 100644 (file)
@@ -256,7 +256,7 @@ case "${targ}" in
     ;;
   aarch64-*-pe* | aarch64-*-mingw*)
     targ_defvec=aarch64_pe_le_vec
-    targ_selvecs="aarch64_pe_le_vec aarch64_pei_le_vec aarch64_elf64_le_vec aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec pdb_vec"
+    targ_selvecs="aarch64_pe_le_vec aarch64_pei_le_vec aarch64_pe_bigobj_le_vec aarch64_elf64_le_vec aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec pdb_vec"
     want64=true
     targ_underscore=no
     ;;
index fc36a79f184cc55062d8babc57bb75c6b37e65a1..afa496a7042ef4c4902cd6c3ded4691762bf7816 100755 (executable)
@@ -15850,6 +15850,7 @@ do
     aarch64_mach_o_vec)                 tb="$tb mach-o-aarch64.lo"; target_size=64 ;;
     aarch64_pei_le_vec)                 tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
     aarch64_pe_le_vec)          tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
+    aarch64_pe_bigobj_le_vec)           tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
     alpha_ecoff_le_vec)                 tb="$tb coff-alpha.lo ecoff.lo $ecoff"; target_size=64 ;;
     alpha_elf64_vec)            tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
     alpha_elf64_fbsd_vec)       tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
index c5e24545dc9cfdadf1b98170076f0bc32e97c6ac..f86c9eae754a7ee50bfca9dab6208ca3634ad3b5 100644 (file)
@@ -391,6 +391,7 @@ do
     aarch64_mach_o_vec)                 tb="$tb mach-o-aarch64.lo"; target_size=64 ;;
     aarch64_pei_le_vec)                 tb="$tb pei-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
     aarch64_pe_le_vec)          tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
+    aarch64_pe_bigobj_le_vec)           tb="$tb pe-aarch64.lo pe-aarch64igen.lo $coff"; target_size=64 ;;
     alpha_ecoff_le_vec)                 tb="$tb coff-alpha.lo ecoff.lo $ecoff"; target_size=64 ;;
     alpha_elf64_vec)            tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
     alpha_elf64_fbsd_vec)       tb="$tb elf64-alpha.lo elf64.lo $elf"; target_size=64 ;;
index 5bdccd804284bec84ccffaaaf9c418a3026cdcc1..21afa219cc6c634928db7a1b54023d963c07e3af 100644 (file)
@@ -115,7 +115,7 @@ scan (const struct bfd_arch_info *info, const char *string)
 }
 
 /* Figure out if llp64 is default */
-#if DEFAULT_VECTOR == aarch64_pe_le_vec
+#if DEFAULT_VECTOR == aarch64_pe_le_vec || DEFAULT_VECTOR == aarch64_pe_bigobj_le_vec
 #define LLP64_DEFAULT true
 #define AARCH64_DEFAULT false
 #else
index be6d32c0e93d8cc6ef818fcbf21974fbca404649..5f9f928d4da9bcd0ec24f8af5d0dd9075529795c 100644 (file)
@@ -23,6 +23,8 @@
 
 #define TARGET_SYM             aarch64_pe_le_vec
 #define TARGET_NAME            "pe-aarch64-little"
+#define TARGET_SYM_BIG         aarch64_pe_bigobj_le_vec
+#define TARGET_NAME_BIG        "pe-bigobj-aarch64-little"
 #define TARGET_ARCHITECTURE    bfd_arch_aarch64
 #define TARGET_PAGESIZE        4096
 #define TARGET_BIG_ENDIAN      0
@@ -32,6 +34,7 @@
 /* Rename the above into.. */
 #define COFF_WITH_peAArch64
 #define COFF_WITH_PE
+#define COFF_WITH_PE_BIGOBJ
 #define PCRELOFFSET       true
 
 /* Long section names not allowed in executable images, only object files.  */
index dce4b88a20cc28f41b6ebd12271a08d9dd30bda6..fcf650410dcbba1cf1b36db2b09de7acc5722b57 100644 (file)
@@ -685,6 +685,7 @@ extern const bfd_target aarch64_elf64_le_vec;
 extern const bfd_target aarch64_mach_o_vec;
 extern const bfd_target aarch64_pei_le_vec;
 extern const bfd_target aarch64_pe_le_vec;
+extern const bfd_target aarch64_pe_bigobj_le_vec;
 extern const bfd_target alpha_ecoff_le_vec;
 extern const bfd_target alpha_elf64_vec;
 extern const bfd_target alpha_elf64_fbsd_vec;
@@ -992,6 +993,7 @@ static const bfd_target * const _bfd_target_vector[] =
        &aarch64_elf64_le_vec,
        &aarch64_mach_o_vec,
        &aarch64_pe_le_vec,
+       &aarch64_pe_bigobj_le_vec,
        &aarch64_pei_le_vec,
 #endif
 
index 38c3cfda7f251c627edd969a563bd85f77181e1a..669e9620a78ec091968a34b55dc5cf41845100e6 100644 (file)
@@ -10315,6 +10315,11 @@ aarch64_after_parse_args (void)
 #endif
 }
 
+#ifdef OBJ_COFF
+/* Use big object file format.  */
+static bool use_big_obj = false;
+#endif
+
 #ifdef OBJ_ELF
 const char *
 elf64_aarch64_target_format (void)
@@ -10334,7 +10339,7 @@ aarch64elf_frob_symbol (symbolS * symp, int *puntp)
 const char *
 coff_aarch64_target_format (void)
 {
-  return "pe-aarch64-little";
+  return use_big_obj ? "pe-bigobj-aarch64-little" : "pe-aarch64-little";
 }
 #endif
 
@@ -10708,6 +10713,7 @@ const char md_shortopts[] = "m:";
 #define OPTION_EL (OPTION_MD_BASE + 1)
 #endif
 #endif
+#define OPTION_MBIG_OBJ (OPTION_MD_BASE + 2)
 
 const struct option md_longopts[] = {
 #ifdef OPTION_EB
@@ -10715,6 +10721,9 @@ const struct option md_longopts[] = {
 #endif
 #ifdef OPTION_EL
   {"EL", no_argument, NULL, OPTION_EL},
+#endif
+#ifdef OBJ_COFF
+  {"mbig-obj", no_argument, NULL, OPTION_MBIG_OBJ},
 #endif
   {NULL, no_argument, NULL, 0}
 };
@@ -11356,6 +11365,12 @@ md_parse_option (int c, const char *arg)
       break;
 #endif
 
+#ifdef OBJ_COFF
+    case OPTION_MBIG_OBJ:
+      use_big_obj = true;
+      break;
+#endif
+
     case 'a':
       /* Listing option.  Just ignore these, we don't support additional
          ones.  */
@@ -11428,6 +11443,11 @@ md_show_usage (FILE * fp)
   fprintf (fp, _("\
   -EL                     assemble code for a little-endian cpu\n"));
 #endif
+
+#ifdef OBJ_COFF
+  fprintf (fp, _("\
+  -mbig-obj               generate big object files\n"));
+#endif
 }
 
 /* Parse a .cpu directive.  */
index a56934653d619da4e0a8ace04ae33fc370091c0b..46e0485ae299f90eacbed7f70c89cc44fc6e9b1d 100644 (file)
@@ -127,6 +127,11 @@ extension options as the @option{-mcpu} option.  Unlike
 @option{-mcpu}, extensions are not always enabled by default.
 @xref{AArch64 Extensions}.
 
+@cindex @samp{-mbig-obj} option, AArch64
+@item -mbig-obj
+On PE/COFF target this option forces the use of big object file
+format, which allows more than 32768 sections.
+
 @cindex @code{-mverbose-error} command-line option, AArch64
 @item -mverbose-error
 This option enables verbose error messages for AArch64 gas.  This option
index 2185feba90e4f464f8f0fd7d2ec2f3be7af73328..f43bd14896ea78c8cab1523ff7c8fb4de029ea6e 100644 (file)
@@ -374,6 +374,18 @@ static pe_details_type pe_detail_list[] =
     false,
     autofilter_symbollist_generic
   },
+  {
+    "pei-aarch64-little",
+    "pe-bigobj-aarch64-little",
+    2,  /* IMAGE_REL_ARM64_ADDR32NB */
+    8,  /* IMAGE_REL_ARM64_SECREL */
+    11, /* IMAGE_REL_ARM64_SECREL_LOW12L */
+    13, /* IMAGE_REL_ARM64_SECTION */
+    PE_ARCH_aarch64,
+    bfd_arch_aarch64,
+    false,
+    autofilter_symbollist_generic
+  },
   { NULL, NULL, 0, 0, 0, 0, 0, 0, false, NULL }
 };