[x86,PE,MingW] Add i386 PE big-object support

Message ID 20200421164410.GA11801@arm.com
State New
Headers show
Series
  • [x86,PE,MingW] Add i386 PE big-object support
Related show

Commit Message

Tamar Christina April 21, 2020, 4:44 p.m.
Hi All,

The 64-bit version of binutils got support for the PE COFF BIG OBJ format a
couple of years ago.   The BIG OBJ format is a slightly different COFF format
which extends the size of the number of section field in the header from a
uint16_t to a uint32_t and so greatly increases the number of sections allowed.

However the 32-bit version of bfd never got support for this.  The GHC Haskell
compiler generates a great deal of symbols due to it's use of
-ffunction-sections and -fdata-sections.

This meant that we could not build the 32-bit version of the GHC Compiler for
many releases now as binutils didn't have this support.

This patch adds the support to the 32-bit port of binutils as well and also does
come cleanup in the code.

build on native hardware and regtested on
  i386-w64-mingw32 and x86_64-w64-mingw64

and no issues.

Ok for master?

Thanks,
Tamar

bfd/ChangeLog:

2020-04-21  Tamar Christina  <tamar.christina@arm.com>

	PR binutils/XXXX
	* coff-i386.c (COFF_WITH_PE_BIGOBJ): New.
	* coff-x86_64.c (COFF_WITH_PE_BIGOBJ): New.
	* config.bfd (targ_selvecs): Rename x86_64_pe_be_vec
	to x86_64_pe_big_vec as it not a big-endian format.
	(vec i386_pe_big_vec): New.
	* configure.ac: Likewise.
	* targets.c: Likewise.
	* configure: Regenerate.
	* pe-i386.c (TARGET_SYM_BIG, TARGET_NAME_BIG,
	COFF_WITH_PE_BIGOBJ): New.
	* pe-x86_64.c (TARGET_SYM_BIG, TARGET_NAME_BIG):
	New.
	(x86_64_pe_be_vec): Moved.

gas/ChangeLog:

2020-04-21  Tamar Christina  <tamar.christina@arm.com>

	PR binutils/XXXX
	* NEWS: Add news entry for big-obj.
	* config/tc-i386.c (i386_target_format): Support new format.
	* doc/c-i386.texi: Add i386 support.
	* testsuite/gas/pe/big-obj.d: Rename test to not be x64 specific.
	* testsuite/gas/pe/pe.exp (big-obj): Make test run on i386 as well.

ld/ChangeLog:

2020-04-21  Tamar Christina  <tamar.christina@arm.com>

	PR binutils/XXXX
	* pe-dll.c (pe_detail_list):  Add pe-bigobj-i386.

--

Comments

Tamar Christina April 27, 2020, 10:36 a.m. | #1
Ping.

> -----Original Message-----

> From: Binutils <binutils-bounces@sourceware.org> On Behalf Of Tamar 

> Christina

> Sent: Tuesday, April 21, 2020 5:44 PM

> To: binutils@sourceware.org

> Cc: me+binutils@cgf.cx; nd <nd@arm.com>; dave.korn.cygwin@gmail.com

> Subject: [PATCH][Binutils][x86][PE][MingW] Add i386 PE big-object 

> support

> 

> Hi All,

> 

> The 64-bit version of binutils got support for the PE COFF BIG OBJ format a

> couple of years ago.   The BIG OBJ format is a slightly different COFF format

> which extends the size of the number of section field in the header 

> from a uint16_t to a uint32_t and so greatly increases the number of 

> sections allowed.

> 

> However the 32-bit version of bfd never got support for this.  The GHC 

> Haskell compiler generates a great deal of symbols due to it's use of 

> - ffunction-sections and -fdata-sections.

> 

> This meant that we could not build the 32-bit version of the GHC 

> Compiler for many releases now as binutils didn't have this support.

> 

> This patch adds the support to the 32-bit port of binutils as well and 

> also does come cleanup in the code.

> 

> build on native hardware and regtested on

>   i386-w64-mingw32 and x86_64-w64-mingw64

> 

> and no issues.

> 

> Ok for master?

> 

> Thanks,

> Tamar

> 

> bfd/ChangeLog:

> 

> 2020-04-21  Tamar Christina  <tamar.christina@arm.com>

> 

> 	PR binutils/XXXX

> 	* coff-i386.c (COFF_WITH_PE_BIGOBJ): New.

> 	* coff-x86_64.c (COFF_WITH_PE_BIGOBJ): New.

> 	* config.bfd (targ_selvecs): Rename x86_64_pe_be_vec

> 	to x86_64_pe_big_vec as it not a big-endian format.

> 	(vec i386_pe_big_vec): New.

> 	* configure.ac: Likewise.

> 	* targets.c: Likewise.

> 	* configure: Regenerate.

> 	* pe-i386.c (TARGET_SYM_BIG, TARGET_NAME_BIG,

> 	COFF_WITH_PE_BIGOBJ): New.

> 	* pe-x86_64.c (TARGET_SYM_BIG, TARGET_NAME_BIG):

> 	New.

> 	(x86_64_pe_be_vec): Moved.

> 

> gas/ChangeLog:

> 

> 2020-04-21  Tamar Christina  <tamar.christina@arm.com>

> 

> 	PR binutils/XXXX

> 	* NEWS: Add news entry for big-obj.

> 	* config/tc-i386.c (i386_target_format): Support new format.

> 	* doc/c-i386.texi: Add i386 support.

> 	* testsuite/gas/pe/big-obj.d: Rename test to not be x64 specific.

> 	* testsuite/gas/pe/pe.exp (big-obj): Make test run on i386 as well.

> 

> ld/ChangeLog:

> 

> 2020-04-21  Tamar Christina  <tamar.christina@arm.com>

> 

> 	PR binutils/XXXX

> 	* pe-dll.c (pe_detail_list):  Add pe-bigobj-i386.

> 

> --
Alan Modra via Binutils April 27, 2020, 1:17 p.m. | #2
Hi Tamar,

> Ping.


Oops - sorry.

>> bfd/ChangeLog:

>>

>> 2020-04-21  Tamar Christina  <tamar.christina@arm.com>

>>

>> 	PR binutils/XXXX

>> 	* coff-i386.c (COFF_WITH_PE_BIGOBJ): New.

>> 	* coff-x86_64.c (COFF_WITH_PE_BIGOBJ): New.

>> 	* config.bfd (targ_selvecs): Rename x86_64_pe_be_vec

>> 	to x86_64_pe_big_vec as it not a big-endian format.

>> 	(vec i386_pe_big_vec): New.

>> 	* configure.ac: Likewise.

>> 	* targets.c: Likewise.

>> 	* configure: Regenerate.

>> 	* pe-i386.c (TARGET_SYM_BIG, TARGET_NAME_BIG,

>> 	COFF_WITH_PE_BIGOBJ): New.

>> 	* pe-x86_64.c (TARGET_SYM_BIG, TARGET_NAME_BIG):

>> 	New.

>> 	(x86_64_pe_be_vec): Moved.

>>

>> gas/ChangeLog:

>>

>> 2020-04-21  Tamar Christina  <tamar.christina@arm.com>

>>

>> 	PR binutils/XXXX

>> 	* NEWS: Add news entry for big-obj.

>> 	* config/tc-i386.c (i386_target_format): Support new format.

>> 	* doc/c-i386.texi: Add i386 support.

>> 	* testsuite/gas/pe/big-obj.d: Rename test to not be x64 specific.

>> 	* testsuite/gas/pe/pe.exp (big-obj): Make test run on i386 as well.

>>

>> ld/ChangeLog:

>>

>> 2020-04-21  Tamar Christina  <tamar.christina@arm.com>

>>

>> 	PR binutils/XXXX

>> 	* pe-dll.c (pe_detail_list):  Add pe-bigobj-i386.


Approved - please apply.

Cheers
  Nick

Patch

diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
index d3075f5a63821313e6100d4bdb5158e7097e9e2f..c89b1fc13be634e369b0dd001e35866d8d362be2 100644
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -701,3 +701,75 @@  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.  */
+
+  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 */
+  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_CHECK_FORMAT,
+    bfd_generic_archive_p,
+    COFF_CHECK_FORMAT
+  },
+  {				/* 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_CONTENTS,
+    _bfd_write_archive_contents,
+    _bfd_bool_bfd_false_error
+  },
+
+  BFD_JUMP_TABLE_GENERIC (coff),
+  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
\ No newline at end of file
diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index e0b32fddb8aacc8963d8be2b15fced571aacf4c8..a6632910da450106048d1b651b6f1c8f096b7475 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -824,3 +824,76 @@  const bfd_target
 
   COFF_SWAP_TABLE
 };
+
+/* Entry for big object files.  */
+
+#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.  */
+#if defined(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.  */
+
+  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.  */
+  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,
+    amd64coff_object_p,
+    bfd_generic_archive_p,
+    amd64coff_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),
+  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
\ No newline at end of file
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 4c65e5ea32f96935efbf98eedfef05824c59fc6a..40f259c92aa60c89d0b21d0c6c86f4ad8a53200b 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -701,7 +701,7 @@  case "${targ}" in
     ;;
   x86_64-*-mingw* | x86_64-*-pe | x86_64-*-pep | x86_64-*-cygwin)
     targ_defvec=x86_64_pe_vec
-    targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_be_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec"
+    targ_selvecs="x86_64_pe_vec x86_64_pei_vec x86_64_pe_big_vec x86_64_elf64_vec l1om_elf64_vec k1om_elf64_vec i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec"
     want64=true
     targ_underscore=no
     ;;
@@ -751,7 +751,7 @@  case "${targ}" in
     ;;
   i[3-7]86-*-mingw32* | i[3-7]86-*-cygwin* | i[3-7]86-*-winnt | i[3-7]86-*-pe)
     targ_defvec=i386_pe_vec
-    targ_selvecs="i386_pe_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec"
+    targ_selvecs="i386_pe_vec i386_pe_big_vec i386_pei_vec i386_elf32_vec iamcu_elf32_vec"
     targ_underscore=yes
     ;;
   i[3-7]86-*-vxworks*)
diff --git a/bfd/configure b/bfd/configure
index a000929b4eeab3710eb5d0c97dc343ab5f308b8e..59b867bbbf5dea71737a2ab3ebb0d59a31b9e471 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -14764,6 +14764,7 @@  do
     i386_mach_o_vec)		 tb="$tb mach-o-i386.lo" ;;
     i386_msdos_vec)		 tb="$tb i386msdos.lo" ;;
     i386_pe_vec)		 tb="$tb pe-i386.lo peigen.lo $coff" ;;
+    i386_pe_big_vec)		 tb="$tb pe-i386.lo peigen.lo $coff" ;;
     i386_pei_vec)		 tb="$tb pei-i386.lo peigen.lo $coff" ;;
     iamcu_elf32_vec)		 tb="$tb elf32-i386.lo $elfxx_x86 elf32.lo $elf" ;;
     ia64_elf32_be_vec)		 tb="$tb elf32-ia64.lo elfxx-ia64.lo elf32.lo $elf" ;;
@@ -14947,7 +14948,7 @@  do
     x86_64_elf64_sol2_vec)	 tb="$tb elf64-x86-64.lo $elfxx_x86 elf64.lo $elf"; target_size=64 ;;
     x86_64_mach_o_vec)		 tb="$tb mach-o-x86-64.lo" ;;
     x86_64_pe_vec)		 tb="$tb pe-x86_64.lo pex64igen.lo $coff"; target_size=64 ;;
-    x86_64_pe_be_vec)		 tb="$tb pe-x86_64.lo pex64igen.lo $coff"; target_size=64 ;;
+    x86_64_pe_big_vec)		 tb="$tb pe-x86_64.lo pex64igen.lo $coff"; target_size=64 ;;
     x86_64_pei_vec)		 tb="$tb pei-x86_64.lo pex64igen.lo $coff"; target_size=64 ;;
     xc16x_elf32_vec)		 tb="$tb elf32-xc16x.lo elf32.lo $elf" ;;
     xgate_elf32_vec)		 tb="$tb elf32-xgate.lo elf32.lo $elf" ;;
diff --git a/bfd/configure.ac b/bfd/configure.ac
index 84d07688ad9ca981dfb4d4cfee43d04c627af793..0528e54c3b08fd0570af9efc6a27848cfaeee3f8 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -500,6 +500,7 @@  do
     i386_mach_o_vec)		 tb="$tb mach-o-i386.lo" ;;
     i386_msdos_vec)		 tb="$tb i386msdos.lo" ;;
     i386_pe_vec)		 tb="$tb pe-i386.lo peigen.lo $coff" ;;
+    i386_pe_big_vec)		 tb="$tb pe-i386.lo peigen.lo $coff" ;;
     i386_pei_vec)		 tb="$tb pei-i386.lo peigen.lo $coff" ;;
     iamcu_elf32_vec)		 tb="$tb elf32-i386.lo $elfxx_x86 elf32.lo $elf" ;;
     ia64_elf32_be_vec)		 tb="$tb elf32-ia64.lo elfxx-ia64.lo elf32.lo $elf" ;;
@@ -683,7 +684,7 @@  do
     x86_64_elf64_sol2_vec)	 tb="$tb elf64-x86-64.lo $elfxx_x86 elf64.lo $elf"; target_size=64 ;;
     x86_64_mach_o_vec)		 tb="$tb mach-o-x86-64.lo" ;;
     x86_64_pe_vec)		 tb="$tb pe-x86_64.lo pex64igen.lo $coff"; target_size=64 ;;
-    x86_64_pe_be_vec)		 tb="$tb pe-x86_64.lo pex64igen.lo $coff"; target_size=64 ;;
+    x86_64_pe_big_vec)		 tb="$tb pe-x86_64.lo pex64igen.lo $coff"; target_size=64 ;;
     x86_64_pei_vec)		 tb="$tb pei-x86_64.lo pex64igen.lo $coff"; target_size=64 ;;
     xc16x_elf32_vec)		 tb="$tb elf32-xc16x.lo elf32.lo $elf" ;;
     xgate_elf32_vec)		 tb="$tb elf32-xgate.lo elf32.lo $elf" ;;
diff --git a/bfd/pe-i386.c b/bfd/pe-i386.c
index f55722e232b24974c18d503d7d0460d5e34c3c6d..c7e107e0836ccf874cb6900068de32428d0c8e2c 100644
--- a/bfd/pe-i386.c
+++ b/bfd/pe-i386.c
@@ -23,7 +23,10 @@ 
 
 #define TARGET_SYM		i386_pe_vec
 #define TARGET_NAME		"pe-i386"
+#define TARGET_SYM_BIG		i386_pe_big_vec
+#define TARGET_NAME_BIG		"pe-bigobj-i386"
 #define COFF_WITH_PE
+#define COFF_WITH_PE_BIGOBJ
 #define PCRELOFFSET		TRUE
 #define TARGET_UNDERSCORE	'_'
 #define COFF_LONG_SECTION_NAMES
diff --git a/bfd/pe-x86_64.c b/bfd/pe-x86_64.c
index 12d29e4fa76fac882ab4fce6fa4b4c68f78daace..1c383293e115492c3fe159c680109d2d6426e664 100644
--- a/bfd/pe-x86_64.c
+++ b/bfd/pe-x86_64.c
@@ -25,6 +25,8 @@ 
 
 #define TARGET_SYM		x86_64_pe_vec
 #define TARGET_NAME		"pe-x86-64"
+#define TARGET_SYM_BIG		x86_64_pe_big_vec
+#define TARGET_NAME_BIG		"pe-bigobj-x86-64"
 #define COFF_WITH_PE
 #define COFF_WITH_pex64
 #define COFF_WITH_PE_BIGOBJ
@@ -66,67 +68,3 @@  extern bfd_boolean pex64_bfd_print_pdata (bfd *, void *);
 
 #include "coff-x86_64.c"
 
-/* Entry for big object files.  */
-
-const bfd_target
-x86_64_pe_be_vec =
-{
-  "pe-bigobj-x86-64",			/* Name.  */
-  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.  */
-   | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
-   | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
-
-  TARGET_UNDERSCORE,		/* Leading underscore.  */
-  '/',				/* Ar_pad_char.  */
-  15,				/* Ar_max_namelen.  */
-  0,				/* match priority.  */
-
-  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.  */
-  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,
-    amd64coff_object_p,
-    bfd_generic_archive_p,
-    amd64coff_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),
-  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
-};
diff --git a/bfd/targets.c b/bfd/targets.c
index d05b9158536fc3239898474ac8d4e0ddca664b2e..9c2db0aeb65293fe6dd259d8c216760830dc710a 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -742,6 +742,7 @@  extern const bfd_target i386_elf32_vxworks_vec;
 extern const bfd_target i386_mach_o_vec;
 extern const bfd_target i386_msdos_vec;
 extern const bfd_target i386_pe_vec;
+extern const bfd_target i386_pe_big_vec;
 extern const bfd_target i386_pei_vec;
 extern const bfd_target iamcu_elf32_vec;
 extern const bfd_target ia64_elf32_be_vec;
@@ -926,7 +927,7 @@  extern const bfd_target x86_64_elf64_nacl_vec;
 extern const bfd_target x86_64_elf64_sol2_vec;
 extern const bfd_target x86_64_mach_o_vec;
 extern const bfd_target x86_64_pe_vec;
-extern const bfd_target x86_64_pe_be_vec;
+extern const bfd_target x86_64_pe_big_vec;
 extern const bfd_target x86_64_pei_vec;
 extern const bfd_target xc16x_elf32_vec;
 extern const bfd_target xgate_elf32_vec;
@@ -1091,6 +1092,7 @@  static const bfd_target * const _bfd_target_vector[] =
 	&i386_mach_o_vec,
 	&i386_msdos_vec,
 	&i386_pe_vec,
+	&i386_pe_big_vec,
 	&i386_pei_vec,
 
 	&iamcu_elf32_vec,
@@ -1343,7 +1345,7 @@  static const bfd_target * const _bfd_target_vector[] =
 	&x86_64_elf64_sol2_vec,
 	&x86_64_mach_o_vec,
 	&x86_64_pe_vec,
-	&x86_64_pe_be_vec,
+	&x86_64_pe_big_vec,
 	&x86_64_pei_vec,
 #endif
 
diff --git a/gas/NEWS b/gas/NEWS
index 6748c179f15ef331fe7e412f2b973b6f3b96477b..8af51dae01a25268e1231e1f546280ee10c73d3c 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -10,6 +10,8 @@ 
   (if such output is being generated).  Added the ability to generate
   version 5 .debug_line sections.
 
+* Add -mbig-obj support to i386 MingW targets.
+
 Changes in 2.34:
 
 * Add -malign-branch-boundary=NUM, -malign-branch=TYPE[+TYPE...],
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 093497becdbe295b982fd4a4ebfac38dce953e0d..8450f613c332fe142ed869687248198568dcbdf5 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -13450,7 +13450,7 @@  i386_target_format (void)
       if (flag_code == CODE_64BIT)
 	return use_big_obj ? "pe-bigobj-x86-64" : "pe-x86-64";
       else
-	return "pe-i386";
+	return use_big_obj ? "pe-bigobj-i386" : "pe-i386";
 # elif defined (TE_GO32)
     case bfd_target_coff_flavour:
       return "coff-go32";
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 628fb1ad5a62bf9aabe89fd3733c4fb3688772c3..c1a42a94be86ddae5341e5fd871ce1bde309bc81 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -390,9 +390,10 @@  with default visibility can be preempted.  The resulting code is
 slightly bigger.  This option only affects the handling of branch
 instructions.
 
+@cindex @samp{-mbig-obj} option, i386
 @cindex @samp{-mbig-obj} option, x86-64
 @item -mbig-obj
-On x86-64 PE/COFF target this option forces the use of big object file
+On PE/COFF target this option forces the use of big object file
 format, which allows more than 32768 sections.
 
 @cindex @samp{-momit-lock-prefix=} option, i386
diff --git a/gas/testsuite/gas/pe/big-obj.d b/gas/testsuite/gas/pe/big-obj.d
index 95ff1d82883975a4fd5e94b9dec33002712338bf..27b351a7d60e3ed4bef721e61488669f44410e7f 100644
--- a/gas/testsuite/gas/pe/big-obj.d
+++ b/gas/testsuite/gas/pe/big-obj.d
@@ -1,6 +1,6 @@ 
 #as: -mbig-obj
 #objdump: -h
-#name: PE x64 big obj
+#name: PE big obj
 
 .*: *file format pe-bigobj-.*
 
diff --git a/gas/testsuite/gas/pe/pe.exp b/gas/testsuite/gas/pe/pe.exp
index e2132130aae83fbc529979659ceeb0d10026fe8b..76345ba50023fec9a94c7990eac142d127aa826a 100644
--- a/gas/testsuite/gas/pe/pe.exp
+++ b/gas/testsuite/gas/pe/pe.exp
@@ -55,7 +55,6 @@  if ([istarget "x86_64-*-mingw*"]) then {
 # Big obj
 
 
-if ([istarget "x86_64-*-mingw*"]) then {
-        # Currently only supported on x86_64
+if ([istarget "*-*-mingw*"]) then {
 	run_dump_test "big-obj"
 }
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 0addde231863a50e7111e2ce23cd00699dcfb98c..0ed21facd07dd5a12f29817b32ad2c47fd1a4e92 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -280,6 +280,16 @@  static pe_details_type pe_detail_list[] =
     FALSE,
     autofilter_symbollist_i386
   },
+#else
+  {
+    "pei-i386",
+    "pe-bigobj-i386",
+    7 /* R_IMAGEBASE */,
+    PE_ARCH_i386,
+    bfd_arch_i386,
+    TRUE,
+    autofilter_symbollist_i386
+  },
 #endif
   {
     "pei-shl",