archives and plugin target
Alan Modra
amodra@gmail.com
Thu Aug 14 13:35:14 GMT 2025
Automatically choosing "plugin" for the archive target when plugins
are enabled can result in making archives as specified by the plugin
target vec, ie. COFF style archives (also used by most ELF
binutils targets). This is wrong for aix, hpux, vms, aout, macho
and possibly other targets, if compatibility with target system
archives matters.
This patch removes archive support entirely from the plugin target.
Instead, archives will have their elements opened using the plugin
target.
* plugin.c (plugin_vec): Remove archive support.
* ar.c (open_inarch): Don't use "plugin" if defaulting target
when opening an archive, use "plugin" when opening elements.
(replace_members): Use "plugin" when opening replacement or
additional elements.
* nm.c (display_archive): Open archive elements using the
"plugin" target.
diff --git a/bfd/plugin.c b/bfd/plugin.c
index 733e7f0f322..d052455fd4e 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -1002,13 +1002,13 @@ const bfd_target plugin_vec =
{ /* bfd_check_format. */
_bfd_dummy_target,
bfd_plugin_object_p,
- bfd_generic_archive_p,
+ _bfd_dummy_target,
_bfd_dummy_target
},
{ /* bfd_set_format. */
_bfd_bool_bfd_false_error,
_bfd_bool_bfd_false_error,
- _bfd_generic_mkarchive,
+ _bfd_bool_bfd_false_error,
_bfd_bool_bfd_false_error,
},
{ /* bfd_write_contents. */
@@ -1021,11 +1021,7 @@ const bfd_target plugin_vec =
BFD_JUMP_TABLE_GENERIC (bfd_plugin),
BFD_JUMP_TABLE_COPY (bfd_plugin),
BFD_JUMP_TABLE_CORE (bfd_plugin),
-#ifdef USE_64_BIT_ARCHIVE
- BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_64_bit),
-#else
- BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
-#endif
+ BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
BFD_JUMP_TABLE_SYMBOLS (bfd_plugin),
BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
BFD_JUMP_TABLE_WRITE (bfd_plugin),
diff --git a/binutils/ar.c b/binutils/ar.c
index 3cac3f3fb26..b1e4b6eb462 100644
--- a/binutils/ar.c
+++ b/binutils/ar.c
@@ -977,12 +977,11 @@ open_inarch (const char *archive_filename, const char *file)
struct stat sbuf;
bfd *arch;
char **matching;
+ const char *arch_target = target;
+ const struct bfd_target *plugin_vec;
bfd_set_error (bfd_error_no_error);
- if (target == NULL)
- target = plugin_target;
-
if (stat (archive_filename, &sbuf) != 0)
{
#if !defined(__GO32__) || defined(__DJGPP__)
@@ -1008,16 +1007,16 @@ open_inarch (const char *archive_filename, const char *file)
/* If the target isn't set, try to figure out the target to use
for the archive from the first object on the list. */
- if (target == NULL && file != NULL)
+ if (arch_target == NULL && file != NULL)
{
bfd *obj;
- obj = bfd_openr (file, target);
+ obj = bfd_openr (file, arch_target);
if (obj != NULL)
{
if (bfd_check_format (obj, bfd_object)
&& bfd_target_supports_archives (obj))
- target = bfd_get_target (obj);
+ arch_target = bfd_get_target (obj);
(void) bfd_close (obj);
}
}
@@ -1026,7 +1025,7 @@ open_inarch (const char *archive_filename, const char *file)
output_filename = xstrdup (archive_filename);
/* Create an empty archive. */
- arch = bfd_openw (archive_filename, target);
+ arch = bfd_openw (archive_filename, arch_target);
if (arch == NULL
|| ! bfd_set_format (arch, bfd_archive)
|| ! bfd_close (arch))
@@ -1035,7 +1034,7 @@ open_inarch (const char *archive_filename, const char *file)
non_fatal (_("creating %s"), archive_filename);
}
- arch = bfd_openr (archive_filename, target);
+ arch = bfd_openr (archive_filename, arch_target);
if (arch == NULL)
{
bloser:
@@ -1069,12 +1068,27 @@ open_inarch (const char *archive_filename, const char *file)
}
}
+ /* We didn't open the archive using plugin_target, because the
+ plugin bfd_target does not support archives. Select
+ plugin_target now for elements so that we can recognise LTO IR
+ files and read IR symbols for use in the archive map. */
+ plugin_vec = NULL;
+ if (!target && plugin_target)
+ plugin_vec = bfd_find_target (plugin_target, NULL);
+
+ /* Open all the archive contents. */
last_one = &(arch->archive_next);
- /* Read all the contents right away, regardless. */
for (next_one = bfd_openr_next_archived_file (arch, NULL);
next_one;
next_one = bfd_openr_next_archived_file (arch, next_one))
{
+ /* Don't change the target for archives like pdb that handle
+ elements specially, as detected by my_archive being NULL. */
+ if (next_one->my_archive && plugin_vec)
+ {
+ next_one->xvec = plugin_vec;
+ next_one->target_defaulted = false;
+ }
*last_one = next_one;
last_one = &next_one->archive_next;
}
@@ -1566,8 +1580,9 @@ replace_members (bfd *arch, char **files_to_move, bool quick)
}
else
{
+ const char *targ = target ? target : plugin_target;
replaced = ar_emul_replace (after_bfd, *files_to_move,
- target, verbose);
+ targ, verbose);
}
if (replaced)
{
@@ -1593,7 +1608,8 @@ replace_members (bfd *arch, char **files_to_move, bool quick)
}
else
{
- changed |= ar_emul_append (after_bfd, *files_to_move, target,
+ const char *targ = target ? target : plugin_target;
+ changed |= ar_emul_append (after_bfd, *files_to_move, targ,
verbose, make_thin_archive);
}
diff --git a/binutils/nm.c b/binutils/nm.c
index a7f0e9d9409..eb569705ee7 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -1601,6 +1601,14 @@ display_archive (bfd *file)
if (print_armap)
print_symdef_entry (file);
+ /* We didn't open the archive using plugin_target, because the
+ plugin bfd_target does not support archives. Select
+ plugin_target now for elements so that we can recognise LTO IR
+ files and print IR symbols. */
+ const struct bfd_target *plugin_vec = NULL;
+ if (!target && plugin_target)
+ plugin_vec = bfd_find_target (plugin_target, NULL);
+
bfd *last_arfile = NULL;
for (;;)
{
@@ -1618,6 +1626,14 @@ display_archive (bfd *file)
if (last_arfile != NULL)
bfd_close (last_arfile);
+ /* Don't change the target for archives like pdb that handle
+ elements specially, as detected by my_archive being NULL. */
+ if (arfile->my_archive && plugin_vec)
+ {
+ arfile->xvec = plugin_vec;
+ arfile->target_defaulted = false;
+ }
+
char **matching;
if (bfd_check_format_matches (arfile, bfd_object, &matching))
{
--
Alan Modra
More information about the Binutils
mailing list