[v2] gdb, configure: Add disable-formats option for configure

Message ID 20241206170150.1301359-1-guinevere@redhat.com
State New
Headers
Series [v2] gdb, configure: Add disable-formats option for configure |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed

Commit Message

Guinevere Larsen Dec. 6, 2024, 5:01 p.m. UTC
  GDB has support for many binary file formats, some which might be very
unlikely to be found in some situations (such as the COFF format in
linux). This commit introduces the option for a user to choose which
formats GDB will support at build configuration time.

This is especially useful to avoid possible security concerns with
readers that aren't expected to be used at all, as they are one of
the simplest vectors for an attacker to try and hit GDB with.  This
change can also reduce the size of the final binary, if that is a
concern.

This commit adds a switch to the configure script allowing a user to
only enable selected file formats, called --enable-binary-file-formats.
The default behavior when the switch is omitted is to compile all file
formats, keeping the original behavior of the script. At the time of
this commit, the valid options for this option are: dbx, coff (which
includes coff-pe), xcoff, mips, elf, macho and all. All is treated
especially, activating all supported readers.

A few targets may require specific binary file format support, as they
directly call functions defined by the file reader. Specifically,
windows targets require coff support, and rs6000 aix and lynx178 targets
require xcoff support. Considering that those formats are the main - or
only - one available in those targets, I believe it makes sense to
re-enable those readers. If that happens, the script will emit the
following warning:

  FOO is required to support one or more requested targets. Adding it

Users aren't able to force the disabling of those formats, since GDB
will not compile without those readers. Ideally we'd like to be able
to disable even those formats, in case a user wants to build GDB only
to examine remote files for example, but the current infrastructure
for the file format readers doesn't allow us to do it.

Mach-O and elf support are also dependent on BFD support being compiled
in.  In case one of those was requested and BFD does not support them,
the following error is emitted:

    FOO was requested, but BFD does not support it.

Finally, this configure switch is also printed by the "show
configuration" command in GDB.
---
 gdb/Makefile.in      | 13 +++----
 gdb/NEWS             | 11 ++++++
 gdb/README           | 24 +++++++++++++
 gdb/config.in        |  3 ++
 gdb/configure        | 80 +++++++++++++++++++++++++++++++++++++++++---
 gdb/configure.ac     | 64 +++++++++++++++++++++++++++++++++--
 gdb/configure.format | 51 ++++++++++++++++++++++++++++
 gdb/configure.tgt    | 20 +++++++++--
 gdb/doc/gdb.texinfo  |  8 +++++
 gdb/top.c            |  3 ++
 10 files changed, 260 insertions(+), 17 deletions(-)
 create mode 100644 gdb/configure.format
  

Comments

Tom Tromey Dec. 20, 2024, 5:25 p.m. UTC | #1
>>>>> "Guinevere" == Guinevere Larsen <guinevere@redhat.com> writes:

Guinevere> +# File formats that will be enabled based on the selected
Guinevere> +# target(s).  These are chosen because they are required to
Guinevere> +# compile one or more of the selected targets.
Guinevere> +target_formats=
Guinevere> +# If all targets were requested, this is all formats that should accompany
Guinevere> +# them.
Guinevere> +all_target_formats="coff xcoff"

I don't understand why all_target_formats doesn't include all the target
formats.  Like why aren't elf, macho, etc in here?

Guinevere> +# Decide which file formats are absolutely required based on
Guinevere> +# the requested targets.  Warn later that they are added, in
Guinevere> +# case the user didn't manually request them, or all readers.
Guinevere> +# It's fine to add the same format multiple times since the
Guinevere> +# loop that reads the options to FORMAT_OBS will ensure that
Guinevere> +# they are only added once.
Guinevere> +for i in $gdb_target_obs; do
Guinevere> +    case "${i}" in
Guinevere> +    *"windows-tdep.o" ) target_formats="${target_formats} coff";;
Guinevere> +    "rs6000-aix-tdep.o" ) target_formats="${target_formats} xcoff";;
Guinevere> +    "rs6000-lynx178-tdep.o" ) target_formats="${target_formats} xcoff";;
Guinevere> +    esac

Similarly (?) why aren't elf and macho checked for here?

I think the patch as a whole is good.  I just had some trouble following
the logic and/or understanding how the parts all fit together.

Tom
  
Guinevere Larsen Dec. 20, 2024, 5:52 p.m. UTC | #2
On 12/20/24 2:25 PM, Tom Tromey wrote:
>>>>>> "Guinevere" == Guinevere Larsen <guinevere@redhat.com> writes:
> Guinevere> +# File formats that will be enabled based on the selected
> Guinevere> +# target(s).  These are chosen because they are required to
> Guinevere> +# compile one or more of the selected targets.
> Guinevere> +target_formats=
> Guinevere> +# If all targets were requested, this is all formats that should accompany
> Guinevere> +# them.
> Guinevere> +all_target_formats="coff xcoff"
>
> I don't understand why all_target_formats doesn't include all the target
> formats.  Like why aren't elf, macho, etc in here?

This is supposed to be the list of all formats required to be able to 
compile all targets (and similarly below, with specific targets). By 
"required" I mean that compilation will fail.

For example, if you're compiling the windows-tdep.c file, there are 
functions from coff-pe-read.c directly called there, not via sym_fns, 
and I couldn't figure out how to do that through the dynamic interface, 
so instead I accepted that if you're compiling some targets, you'll get 
supported formats you may not have asked for. Macho and Elf aren't there 
because they aren't required by any target.

If you're thinking of my original patch, I had intended to also include 
the main format for the selected target, not just the ones needed for 
compilation to not fail. I walked back on that idea because I don't 
think it's reasonable to put it on us - GDB maintainers - to keep an 
updated list of what targets support what formats. Simon also commented 
on IRC that, conceptually, it would be nice if you could build GDB for 
only remote debugging, in case some user had that idea.

I can do a better job at naming and/or the comments around this.
  
Tom Tromey Dec. 20, 2024, 6:21 p.m. UTC | #3
>>>>> "Guinevere" == Guinevere Larsen <guinevere@redhat.com> writes:

Guinevere> This is supposed to be the list of all formats required to be able to
Guinevere> compile all targets (and similarly below, with specific targets). By
Guinevere> "required" I mean that compilation will fail.

Guinevere> For example, if you're compiling the windows-tdep.c file, there are
Guinevere> functions from coff-pe-read.c directly called there, not via sym_fns,
Guinevere> and I couldn't figure out how to do that through the dynamic
Guinevere> interface, so instead I accepted that if you're compiling some
Guinevere> targets, you'll get supported formats you may not have asked
Guinevere> for. Macho and Elf aren't there because they aren't required by any
Guinevere> target.

Ok, I see now.
Maybe just a comment would be good enough then, the idea being if a new
format is added, provide some guidance to whether or not it should be
listed there.

Guinevere> I walked back on that idea because
Guinevere> I don't think it's reasonable to put it on us - GDB maintainers - to
Guinevere> keep an updated list of what targets support what formats. Simon also
Guinevere> commented on IRC that, conceptually, it would be nice if you could
Guinevere> build GDB for only remote debugging, in case some user had that idea.

Yeah, makes sense.
Honestly I wouldn't even object to a setup where if the user asks for
something nonsensical (Windows target without COFF), the build just fails.

Tom
  
Guinevere Larsen Jan. 3, 2025, 1:24 p.m. UTC | #4
On 12/20/24 3:21 PM, Tom Tromey wrote:
>>>>>> "Guinevere" == Guinevere Larsen <guinevere@redhat.com> writes:
> Guinevere> This is supposed to be the list of all formats required to be able to
> Guinevere> compile all targets (and similarly below, with specific targets). By
> Guinevere> "required" I mean that compilation will fail.
>
> Guinevere> For example, if you're compiling the windows-tdep.c file, there are
> Guinevere> functions from coff-pe-read.c directly called there, not via sym_fns,
> Guinevere> and I couldn't figure out how to do that through the dynamic
> Guinevere> interface, so instead I accepted that if you're compiling some
> Guinevere> targets, you'll get supported formats you may not have asked
> Guinevere> for. Macho and Elf aren't there because they aren't required by any
> Guinevere> target.
>
> Ok, I see now.
> Maybe just a comment would be good enough then, the idea being if a new
> format is added, provide some guidance to whether or not it should be
> listed there.

Ok, I updated the comment above the all_target_formats to say the following:

# If all targets were requested, this is all formats that should
# accompany them.  These are just the ones required for compilation
# to succeed, not the formats suggested based on targets.

Along with the comment on target_formats, I would hope this is clear 
enough. As to whether new formats should be listed here, I would hope 
this would never happen, and we keep this list as small as possible (in 
fact, a future improvement would be to rework those 2 files so that this 
isn't ever necessarily).

>
> Guinevere> I walked back on that idea because
> Guinevere> I don't think it's reasonable to put it on us - GDB maintainers - to
> Guinevere> keep an updated list of what targets support what formats. Simon also
> Guinevere> commented on IRC that, conceptually, it would be nice if you could
> Guinevere> build GDB for only remote debugging, in case some user had that idea.
>
> Yeah, makes sense.
> Honestly I wouldn't even object to a setup where if the user asks for
> something nonsensical (Windows target without COFF), the build just fails.
The main reason I didn't do that is that build fails on the linking 
step, with hard to understand if you're not familiar with the codebase 
and are just playing around with configure options.
>
> Tom
>
  

Patch

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 52950759711..60d79811a15 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -899,13 +899,15 @@  ALL_TARGET_OBS = \
 	vax-tdep.o \
 	windows-tdep.o \
 	x86-tdep.o \
-	xcoffread.o \
 	xstormy16-tdep.o \
 	xtensa-config.o \
 	xtensa-linux-tdep.o \
 	xtensa-tdep.o \
 	z80-tdep.o
 
+# Object files for reading specific types of debug information.
+FORMAT_OBS = @FORMAT_OBS@
+
 # The following native-target dependent variables are defined on
 # configure.nat.
 NAT_FILE = @NAT_FILE@
@@ -1062,8 +1064,6 @@  COMMON_SFILES = \
 	c-varobj.c \
 	charset.c \
 	cli-out.c \
-	coff-pe-read.c \
-	coffread.c \
 	complaints.c \
 	completer.c \
 	copying.c \
@@ -1077,7 +1077,6 @@  COMMON_SFILES = \
 	d-lang.c \
 	d-namespace.c \
 	d-valprint.c \
-	dbxread.c \
 	dcache.c \
 	debug.c \
 	debuginfod-support.c \
@@ -1168,7 +1167,6 @@  COMMON_SFILES = \
 	memtag.c \
 	minidebug.c \
 	minsyms.c \
-	mipsread.c \
 	namespace.c \
 	objc-lang.c \
 	objfiles.c \
@@ -1261,7 +1259,6 @@  SFILES = \
 	d-exp.y \
 	dtrace-probe.c \
 	elf-none-tdep.c \
-	elfread.c \
 	f-exp.y \
 	gcore-elf.c \
 	gdb.c \
@@ -1880,7 +1877,6 @@  ALLDEPFILES = \
 	windows-tdep.c \
 	x86-nat.c \
 	x86-tdep.c \
-	xcoffread.c \
 	xstormy16-tdep.c \
 	xtensa-config.c \
 	xtensa-linux-nat.c \
@@ -1902,7 +1898,8 @@  COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
 	$(SUBDIR_CLI_OBS) \
 	$(SUBDIR_MI_OBS) \
 	$(SUBDIR_TARGET_OBS) \
-	$(SUBDIR_GCC_COMPILE_OBS)
+	$(SUBDIR_GCC_COMPILE_OBS) \
+	$(FORMAT_OBS)
 
 SUBDIRS = doc @subdirs@ data-directory
 CLEANDIRS = $(SUBDIRS)
diff --git a/gdb/NEWS b/gdb/NEWS
index 361d7726ba0..9f4de38c638 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -174,6 +174,17 @@  vFile:stat
   vFile:fstat but takes a filename rather than an open file
   descriptor.
 
+* Configure changes
+
+enable-binary-file-formats=[FORMAT,...]
+enable-binary-file-formats=all
+  A user can now decide to only compile support for certain file formats.
+  The available formats at this point are: dbx, coff, xcoff, elf, mach-o
+  and mips.  Some targets require specific file formats to be available,
+  and in such cases, the configure script will warn the user and add
+  support anyway.  By default, all formats will be compiled in, to
+  continue the behavior from before adding the switch.
+
 *** Changes in GDB 15
 
 * The MPX commands "show/set mpx bound" have been deprecated, as Intel
diff --git a/gdb/README b/gdb/README
index d85c37d5d17..945db6677ee 100644
--- a/gdb/README
+++ b/gdb/README
@@ -403,6 +403,30 @@  more obscure GDB `configure' options are not listed here.
      specified list of targets.  The special value `all' configures
      GDB for debugging programs running on any target it supports.
 
+`--enable-binary-file-formats=FORMAT,FORMAT,...'
+`--enable-binary-file-formats=all'
+    Configure GDB to only be be able to read selected file formats.
+    The special value "all" causes all file formats to be compiled
+    in, and is the the default behavior of the option.  This option
+    is meant for advanced users who are sure of what they expect,
+    if you are unsure which options you will need on your debugging
+    sessions, we recommend that you not use this feature.  The
+    accepted options are:
+      * coff: Main format on windows systems. This is required to
+        compile with windows target support;
+      * dbx (also known as a.out): is a legacy file format, this
+        is recommended if you know you will be dealing with this
+        file format;
+      * elf: Main format of linux systems. This is heavily
+        recommended when compiling with linux support;
+      * macho: Main format on MacOS systems, this is heavily
+        recommended when compiling for those targets;
+      * mips (also known as ecoff): this is the main file format
+        for targets running on MIPS CPUs. It is heavily recommended
+        when supporting those targets.
+      * xcoff: Main format of AIX systems, this is required to
+        compile for AIX targets and rs6000 CPUs.
+
 `--with-gdb-datadir=PATH'
      Set the GDB-specific data directory.  GDB will look here for
      certain supporting files or scripts.  This defaults to the `gdb'
diff --git a/gdb/config.in b/gdb/config.in
index db63aeaec75..e258cff2c8e 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -733,6 +733,9 @@ 
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
+/* which file formats were requested at configure time. */
+#undef SUPPORTED_FORMATS
+
 /* automatically load a system-wide gdbinit file */
 #undef SYSTEM_GDBINIT
 
diff --git a/gdb/configure b/gdb/configure
index de750f4fafe..52ed177445f 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -706,6 +706,7 @@  LIBGUI
 LTLIBLZMA
 LIBLZMA
 HAVE_LIBLZMA
+FORMAT_OBS
 SER_HARDWIRE
 WERROR_CFLAGS
 WARN_CFLAGS
@@ -933,6 +934,7 @@  with_relocated_sources
 with_auto_load_dir
 with_auto_load_safe_path
 enable_targets
+enable_binary_file_formats
 enable_64_bit_bfd
 with_amd_dbgapi
 enable_tui
@@ -1644,6 +1646,9 @@  Optional Features:
   --disable-nls           do not use Native Language Support
   --enable-targets=TARGETS
                           alternative target configurations
+  --enable-binary-file-formats=FILE_FORMATS
+                          enable support for selected file formats (default
+                          'all')
   --enable-64-bit-bfd     64-bit support (on hosts with narrower word sizes)
   --enable-tui            enable full-screen terminal user interface (TUI)
   --enable-gdbtk          enable gdbtk graphical user interface (GUI)
@@ -11499,7 +11504,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11502 "configure"
+#line 11507 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11605,7 +11610,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11608 "configure"
+#line 11613 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -24874,6 +24879,18 @@  esac
 fi
 
 
+# Check whether --enable-binary_file_formats was given.
+if test "${enable_binary_file_formats+set}" = set; then :
+  enableval=$enable_binary_file_formats; case "${enableval}" in
+ yes | "") as_fn_error $? "enable-formats option must specify file formats or 'all'" "$LINENO" 5
+            ;;
+  no)       enable_binary_file_formats= ;;
+  *)        enable_binary_file_formats=$enableval ;;
+esac
+else
+  enable_binary_file_formats=all
+fi
+
 
 # Check whether --enable-64-bit-bfd was given.
 if test "${enable_64_bit_bfd+set}" = set; then :
@@ -24957,11 +24974,19 @@  fi
 TARGET_OBS=
 all_targets=
 HAVE_NATIVE_GCORE_TARGET=
+# File formats that will be enabled based on the selected
+# target(s).  These are chosen because they are required to
+# compile one or more of the selected targets.
+target_formats=
+# If all targets were requested, this is all formats that should accompany
+# them.
+all_target_formats="coff xcoff"
 
 for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'`
 do
   if test "$targ_alias" = "all"; then
     all_targets=true
+    target_formats=$all_target_formats
   else
     # Canonicalize the secondary target names.
     result=`$ac_config_sub $targ_alias 2>/dev/null`
@@ -31537,6 +31562,10 @@  fi
 # Note that WIN32APILIBS is set by GDB_AC_COMMON.
 WIN32LIBS="$WIN32LIBS $WIN32APILIBS"
 
+# Object files to be used when building with support for all file formats.
+all_binary_format_obs="dbxread.o mipsread.o coffread.o coff-pe-read.o xcoffread.o"
+
+support_elf=no
 # Add ELF support to GDB, but only if BFD includes ELF support.
 
   OLD_CFLAGS=$CFLAGS
@@ -31589,7 +31618,7 @@  $as_echo "$gdb_cv_var_elf" >&6; }
   LDFLAGS=$OLD_LDFLAGS
   LIBS=$OLD_LIBS
 if test "$gdb_cv_var_elf" = yes; then
-  CONFIG_OBS="$CONFIG_OBS elfread.o stap-probe.o dtrace-probe.o \
+  CONFIG_OBS="$CONFIG_OBS stap-probe.o dtrace-probe.o \
 		gcore-elf.o elf-none-tdep.o"
 
 $as_echo "#define HAVE_ELF 1" >>confdefs.h
@@ -31653,9 +31682,12 @@  if test "$ac_res" != no; then :
 fi
 
   fi
+  support_elf=yes
+  all_binary_format_obs="$all_binary_format_obs elfread.o"
 fi
 
 # Add macho support to GDB, but only if BFD includes it.
+support_macho=no
 
   OLD_CFLAGS=$CFLAGS
   OLD_LDFLAGS=$LDFLAGS
@@ -31707,9 +31739,49 @@  $as_echo "$gdb_cv_var_macho" >&6; }
   LDFLAGS=$OLD_LDFLAGS
   LIBS=$OLD_LIBS
 if test "$gdb_cv_var_macho" = yes; then
-  CONFIG_OBS="$CONFIG_OBS machoread.o"
+    support_macho=yes
+  all_binary_format_obs="$all_binary_format_obs machoread.o"
 fi
 
+FORMAT_OBS=
+
+if test "$enable_binary_file_formats" != "all"; then
+    # Formats that are required by some requested target(s).
+    # Warn users that they are added, so no one is surprised.
+    for req in $target_formats; do
+	if ! echo "$enable_binary_file_formats" | grep -wq "$req"; then
+	    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"$req is required to support one or more requested targets.  Adding it\"" >&5
+$as_echo "$as_me: WARNING: \"$req is required to support one or more requested targets.  Adding it\"" >&2;}
+	    enable_binary_file_formats="${enable_binary_file_formats},$req"
+	fi
+    done
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define SUPPORTED_FORMATS "$enable_binary_file_formats"
+_ACEOF
+
+
+enable_binary_file_formats=$(echo $enable_binary_file_formats | sed 's/,/ /g')
+
+for format in $enable_binary_file_formats
+do
+    if test "$format" = "elf"; then
+	if test "$support_elf" != "yes"; then
+	    as_fn_error but BFD does not support it." "\"elf support was requested" "$LINENO" 5;
+	fi
+    elif test "$format" = "macho"; then
+	if test "$support_macho" != "yes"; then
+	    as_fn_error but BFD does not support it." "\"Mach-O support was requested" "$LINENO" 5;
+	fi
+    fi
+
+    . ${srcdir}/configure.format
+done
+
+
+
 # Add any host-specific objects to GDB.
 CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}"
 
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 230c0be79c7..a0d88a58771 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -191,6 +191,15 @@  AS_HELP_STRING([--enable-targets=TARGETS], [alternative target configurations]),
 	;;
 esac])
 
+AC_ARG_ENABLE(binary_file_formats,
+	      AS_HELP_STRING([--enable-binary-file-formats=FILE_FORMATS],
+			     [enable support for selected file formats (default 'all')]),
+[case "${enableval}" in
+ yes | "") AC_MSG_ERROR(enable-formats option must specify file formats or 'all')
+            ;;
+  no)       enable_binary_file_formats= ;;
+  *)        enable_binary_file_formats=$enableval ;;
+esac], [enable_binary_file_formats=all])
 
 BFD_64_BIT
 
@@ -211,11 +220,19 @@  fi
 TARGET_OBS=
 all_targets=
 HAVE_NATIVE_GCORE_TARGET=
+# File formats that will be enabled based on the selected
+# target(s).  These are chosen because they are required to
+# compile one or more of the selected targets.
+target_formats=
+# If all targets were requested, this is all formats that should accompany
+# them.
+all_target_formats="coff xcoff"
 
 for targ_alias in `echo $target_alias $enable_targets | sed 's/,/ /g'`
 do
   if test "$targ_alias" = "all"; then
     all_targets=true
+    target_formats=$all_target_formats
   else
     # Canonicalize the secondary target names.
     result=`$ac_config_sub $targ_alias 2>/dev/null`
@@ -1888,11 +1905,15 @@  fi
 # Note that WIN32APILIBS is set by GDB_AC_COMMON.
 WIN32LIBS="$WIN32LIBS $WIN32APILIBS"
 
+# Object files to be used when building with support for all file formats.
+all_binary_format_obs="dbxread.o mipsread.o coffread.o coff-pe-read.o xcoffread.o"
+
+support_elf=no
 # Add ELF support to GDB, but only if BFD includes ELF support.
 GDB_AC_CHECK_BFD([for ELF support in BFD], gdb_cv_var_elf,
                  [bfd_get_elf_phdr_upper_bound (NULL)], elf-bfd.h)
 if test "$gdb_cv_var_elf" = yes; then
-  CONFIG_OBS="$CONFIG_OBS elfread.o stap-probe.o dtrace-probe.o \
+  CONFIG_OBS="$CONFIG_OBS stap-probe.o dtrace-probe.o \
 		gcore-elf.o elf-none-tdep.o"
   AC_DEFINE(HAVE_ELF, 1,
 	    [Define if ELF support should be included.])
@@ -1900,15 +1921,54 @@  if test "$gdb_cv_var_elf" = yes; then
   if test "$plugins" = "yes"; then
     AC_SEARCH_LIBS(dlopen, dl)
   fi
+  support_elf=yes
+  all_binary_format_obs="$all_binary_format_obs elfread.o"
 fi
 
 # Add macho support to GDB, but only if BFD includes it.
+support_macho=no
 GDB_AC_CHECK_BFD([for Mach-O support in BFD], gdb_cv_var_macho,
                  [bfd_mach_o_lookup_command (NULL, 0, NULL)], mach-o.h)
 if test "$gdb_cv_var_macho" = yes; then
-  CONFIG_OBS="$CONFIG_OBS machoread.o"
+    support_macho=yes
+  all_binary_format_obs="$all_binary_format_obs machoread.o"
 fi
 
+FORMAT_OBS=
+
+if test "$enable_binary_file_formats" != "all"; then
+    # Formats that are required by some requested target(s).
+    # Warn users that they are added, so no one is surprised.
+    for req in $target_formats; do
+	if ! echo "$enable_binary_file_formats" | grep -wq "$req"; then
+	    AC_MSG_WARN("$req is required to support one or more requested targets.  Adding it")
+	    enable_binary_file_formats="${enable_binary_file_formats},$req"
+	fi
+    done
+fi
+
+AC_DEFINE_UNQUOTED(SUPPORTED_FORMATS, "$enable_binary_file_formats",
+		   which file formats were requested at configure time. )
+
+enable_binary_file_formats=$(echo $enable_binary_file_formats | sed 's/,/ /g')
+
+for format in $enable_binary_file_formats
+do
+    if test "$format" = "elf"; then
+	if test "$support_elf" != "yes"; then
+	    AC_MSG_ERROR("elf support was requested, but BFD does not support it.");
+	fi
+    elif test "$format" = "macho"; then
+	if test "$support_macho" != "yes"; then
+	    AC_MSG_ERROR("Mach-O support was requested, but BFD does not support it.");
+	fi
+    fi
+
+    . ${srcdir}/configure.format
+done
+
+AC_SUBST(FORMAT_OBS)
+
 # Add any host-specific objects to GDB.
 CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}"
 
diff --git a/gdb/configure.format b/gdb/configure.format
new file mode 100644
index 00000000000..025b7ea1723
--- /dev/null
+++ b/gdb/configure.format
@@ -0,0 +1,51 @@ 
+# Copyright (C) 2024 Free Software Foundation, Inc.
+#
+# This file is part of GDB.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is used to decide which files need to be compiled to support
+# the requested file formats
+
+case $format in
+    xcoff)
+	FORMAT_OBS="$FORMAT_OBS xcoffread.o"
+	;;
+
+    # Despite the naming convention implying coff-pe to be a separate
+    # reader, it is in fact just a helper for coffread;
+    coff)
+	FORMAT_OBS="$FORMAT_OBS coffread.o coff-pe-read.o"
+	;;
+
+    dbx)
+	FORMAT_OBS="$FORMAT_OBS dbxread.o"
+	;;
+
+    elf)
+	FORMAT_OBS="$FORMAT_OBS elfread.o"
+	;;
+
+    macho)
+	FORMAT_OBS="$FORMAT_OBS machoread.o"
+	;;
+
+    mips)
+	FORMAT_OBS="$FORMAT_OBS mipsread.o"
+	;;
+
+    all)
+	FORMAT_OBS="$all_binary_format_obs"
+	;;
+esac
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index f7b9e32cba9..a89f28e464e 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -496,7 +496,7 @@  powerpc-*-openbsd*)
 	;;
 powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
 	# Target: PowerPC running AIX
-	gdb_target_obs="rs6000-tdep.o rs6000-aix-tdep.o xcoffread.o \
+	gdb_target_obs="rs6000-tdep.o rs6000-aix-tdep.o \
 			ppc-sysv-tdep.o solib-aix.o \
 			ravenscar-thread.o ppc-ravenscar-thread.o"
 	;;
@@ -512,8 +512,8 @@  powerpc*-*-linux*)
 powerpc-*-lynx*178)
 	# Target: PowerPC running Lynx178.
 	gdb_target_obs="rs6000-tdep.o rs6000-lynx178-tdep.o \
-			xcoffread.o ppc-sysv-tdep.o \
-			ravenscar-thread.o ppc-ravenscar-thread.o"
+			ppc-sysv-tdep.o ravenscar-thread.o \
+			ppc-ravenscar-thread.o"
 	;;
 powerpc*-*-*)
 	# Target: PowerPC running eabi
@@ -813,3 +813,17 @@  for t in x ${gdb_target_obs}; do
     gdb_have_gcore=true
   fi
 done
+
+# Decide which file formats are absolutely required based on
+# the requested targets.  Warn later that they are added, in
+# case the user didn't manually request them, or all readers.
+# It's fine to add the same format multiple times since the
+# loop that reads the options to FORMAT_OBS will ensure that
+# they are only added once.
+for i in $gdb_target_obs; do
+    case "${i}" in
+    *"windows-tdep.o" ) target_formats="${target_formats} coff";;
+    "rs6000-aix-tdep.o" ) target_formats="${target_formats} xcoff";;
+    "rs6000-lynx178-tdep.o" ) target_formats="${target_formats} xcoff";;
+    esac
+done
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 85ac3d9aab6..d60ca90eddc 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -41109,6 +41109,14 @@  Configure @value{GDBN} for cross-debugging programs running on the
 specified list of targets.  The special value @samp{all} configures
 @value{GDBN} for debugging programs running on any target it supports.
 
+@item --enable-formats=@r{[}@var{format}@r{]}@dots{}
+@itemx --enable-formats=all
+Configure @value{GDBN} to support certain binary file formats.  If a
+format is the main (or only) file format for a given target, the
+configure script may add support to it anyway, and warn the user.
+If not given, all file formats that @value{GDBN} supports are compiled
+in.
+
 @item --with-gdb-datadir=@var{path}
 Set the @value{GDBN}-specific data directory.  @value{GDBN} will look
 here for certain supporting files or scripts.  This defaults to the
diff --git a/gdb/top.c b/gdb/top.c
index d750f3305f2..86ecd0658d6 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1595,6 +1595,9 @@  This GDB was configured as follows:\n\
 	     --with-system-gdbinit-dir=%s%s\n\
 "), SYSTEM_GDBINIT_DIR, SYSTEM_GDBINIT_DIR_RELOCATABLE ? " (relocatable)" : "");
 
+  gdb_printf (stream, _("\
+	     --enable-binary-file-formats=%s\n"), SUPPORTED_FORMATS);
+
   /* We assume "relocatable" will be printed at least once, thus we always
      print this text.  It's a reasonably safe assumption for now.  */
   gdb_printf (stream, _("\n\