bfd_check_format currently does not take much notice of the target
set in its abfd arg, merely checking that target first if
target_defaulted is false. As the comment says this was due to
complications with archive handling which I think was fixed in
commit f832531609. It should now be possible to just check the
given target, except for linker input files. This will speed checking
the target of the first file in archives, which is done in the process
of matching archive targets.
This will no doubt expose some misuse of target options, as found in
the binutils "efi app" tests.
The stricter checking also exposed some errors. Cris targets gave
"FAIL: objcopy decompress debug sections in archive (reason: unexpected output)"
"FAIL: objcopy decompress debug sections in archive with zlib-gabi (reason: unexpected output)"
without the bfd_generic_archive_p fix. cris has a default target of
cris-aout which doesn't match objects for any of the cris-elf or
cris-linux targets. The problem here was that checking the first
object file in archives didn't match but a logic error there meant
bfd_error_wrong_object_format wasn't returned as it should be. There
was also a possibility of bfd_error_wrong_object_format persisting
from one target check to the next.
bfd/
* archive.c (bfd_generic_archive_p): Correct object in archive
target test.
* format.c (bfd_check_format_matches_lto): Try to match given
target first even when target_defaulted is set. Don't try
other targets if !target_defaulted except for linker input.
Clear bfd_error before attempted target matches.
* targets.c (bfd_find_target): Set target_defaulted for
plugin target.
binutils/
* bucomm.h (set_plugin_target): Set target_defaulted.
* testsuite/binutils-all/aarch64/pei-aarch64-little.d: Don't
wrongly specify both input and output target, just specify
output.
* testsuite/binutils-all/loongarch64/pei-loongarch64.d: Likewise.
* testsuite/binutils-all/riscv/pei-riscv64.d: Likewise.
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.
That means an archive will never get past bfd_check_format with a
target of plugin_vec, even if it is opened using "plugin". Instead,
archives will have their elements opened using the plugin target
selected is such a way that the plugin target will be tried first in
bfd_check_format and then continue to try other targets if that fails.
The patch tries to avoid opening archives using "plugin" because that
is guaranteed to fail the first target check in bfd_check_format, but
mm.c still does so, and nested archives will also be opened using
"plugin".
The patch also fixes poor arsup.c plugin support.
bfd/
* plugin.c (plugin_vec): Remove archive support.
* configure.ac: Remove plugin archive warning, and don't disable
plugins by default on anything but aout targets.
* configure: Regenerate.
binutils/
* bucomm.h (set_plugin_target): New inline function.
* ar.c: Remove unneeded forward declarations.
(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.
* arsup.c: Remove unneeded forward declarations.
(plugin_target): New.
(ar_open): Don't open archives using "plugin", use it when
opening elements.
(ar_addmod): Use plugin_target.
(ar_replace): Use plugin_target when opening replacement or
additional elements.
(ar_extract): Don't bfd_openr.
* nm.c (display_archive): Open archive elements using the
"plugin" target.
Commit 3fa785190a ("Altered the CREATE_xxx_COFF_TARGET_VEC macro
arguments") pretty clearly screwed up the data swapping functions in the
new CREATE_BIGHDR_COFF_TARGET_VEC() macro. Since the flaw went unnoticed,
and since the correction doesn't cause any testsuite fallout, it further
seems pretty clear that all of this is entirely untested and largely
unused.
There's no reason to have the compiler materialize objects onto the
stack.
In fact we can save some space and a level of indirection (and hence
relocation entries in the final binary) by converting to an array of
char[12] or larger. Pick char[16] for easier / faster calculations.
The spec doesn't tie entity size to just SHF_MERGE and SHF_STRINGS
sections. Introduce a new "section letter" 'E' to allow recording (and
checking) of entity size even without 'M' or 'S'.
Silently zapping them is certainly wrong. When they're not replaced due
to user request, simply keeping them may not always be correct (we don't
know what such a flag means, after all), but is certainly at least
closer to having the output object still represent what the input object
had.
This introduces new binutils/ testsuite failures, but only for two
targets where most of the tests there fail anyway (amdgcn-elf and
nfp-elf), due to there not being an assembler available.
Slim LLVM IR object is a standalone file whose first 4 bytes are 'B',
'C', 0xc0, 0xde. GCC IR object is regular ELF object with sections
whose names start with .gnu.lto_.* or .gnu.debuglto_.*. GCC IR object
uses a .gnu.lto_.lto.<some_hash> section to encode the LTO bytecode
information:
struct lto_section
{
int16_t major_version;
int16_t minor_version;
unsigned char slim_object;
/* Flags is a private field that is not defined publicly. */
uint16_t flags;
};
In slim GCC IR object, the slim_object field is non-zero. Strip should
treat slim GCC/LLVM IR objects the same. Since strip won't change slim
LLVM IR objects, it should leave slim GCC IR object unchanged even when
asked to remove all IR objects:
1. Set the lto_type field to lto_slim_ir_object for slim LLVM IR object.
2. Always copy slim IR object as unknown object.
bfd/
PR binutils/33271
* format.c (bfd_set_lto_type): Set the lto_type field to
lto_slim_ir_object for slim LLVM IR object.
binutils/
PR binutils/33271
* objcopy.c (lto_sections_removed): Removed.
(copy_archive): Always copy slim IR object as unknown object.
(copy_file): Likewise.
(strip_main): Updated.
ld/
PR binutils/33271
* testsuite/ld-plugin/lto-binutils.exp: Don't check if fat IR is
available when running slim IR tests.
* testsuite/ld-plugin/strip-1a-s-all.nd: Expect full symbol list.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Fix PR ld/33199 SEGV in _bfd_x86_elf_create_sframe_plt
Currently, the selection for sframe_plt was not being done (and simply
set to NULL) for the case when !normal_target, causing SEGV on Solaris.
Initialize sframe_plt to init_table->sframe_lazy_plt when lazy_plt is
true, and NULL otherwise. This is in line with htab->non_lazy_plt being
set to NULL for !normal_target.
bfd/
PR ld/33199
* elfxx-x86.c (_bfd_x86_elf_link_setup_gnu_properties):
Setup sframe_plt for !normal_target.
In a later commit I'd like to add support to GDB for including the
NT_386_TLS note in the core files that GDB creates (using 'gcore'
command).
To achieve this we need some standard boilerplate code added to bfd.
The only part of this patch which I think needs consideration is the
name I selected for the pseudo section to hold the note contents when
a core file is loaded. I chose '.reg-i386-tls'. The '.reg' prefix is
the standard used by most other pseudo sections, and the '-i386-tls'
suffix seemed to match the note name, though I added the 'i' to
'i386', instead of just using '.reg-386-tls'. I thought 'i386' seemed
clearer.
There's no test included here, but when I merge the NT_386_TLS
creation to GDB it will depend on this and act as a test. I plan to
post that work to the GDB list once this patch is merged.
Recognise ECOFF archives and reject them so that the ecoff archive
support has a chance to handle the archive. Also use memcmp rather
than startswith (strncmp) as we know the string length.
* archive.c (bfd_slurp_armap): Recognize ECOFF armap. Use memcmp
to match names, and tidy buffer sizes.
This tidies objcopy/strip handling of IR objects, in the process of
removing the unnecessary is_strip_input flag.
The first thing I noticed when looking at is_strip_input code was that
the abfd->my_archive test in bfd_check_format_matches meant that
plugins were disabled when reading archive elements. We can instead
disable plugins by setting bfd_no_plugin, so there doesn't seem to be
a need for is_strip_input in objcopy.c:copy_archive. This isn't
exactly the same, because bfd_no_plugin prevents the plugin target
recognising archive elements in the bfd_check_format_matches loop over
all targets as well as just the first !target_defaulted test. But
that turns out to be fine. IR code is handled in copy_archive as for
other unknown format files. In fact, the only need for the plugin
target when copying archives is when reading symbols for the archive
map. I've made that plain by moving the plugin target override and
commenting on why it is really needed.
So on to plain object files. Here, IR code is also copied unchanged,
so there doesn't seem a need for the plugin target there either. It
isn't quite so simple though, because the objcopy/strip code handling
object files wants to verify the format of the object file. Allowing
objcopy/strip to copy unknown format files would be a change in
behaviour (and results in mmix testsuite fails, ld-mmix/b-badfil1 and
others). However, always excluding the plugin target results in a
fail of tests added in commit c2729c37f1. So I've enabled a plugin
format check only for files that are otherwise unrecognised, and
commented why this is done. I question the need to objcopy LLVM
bytecode files.
bfd/
* bfd.c (struct bfd<is_strip_input>): Delete.
* format.c (bfd_check_format_matches): Delete is_strip_input
special case code.
* bfd-in2.h: Regenerate.
binutils/
* objcopy.c (copy_archive): Don't set is_strip_input. Always
set bfd_plugin_no when reading elements. Enable plugins when
opening copied elements.
(check_format_object): Delete.
(copy_file): Don't enable plugin target here. Don't set
is_strip_input. Set bfd_plugin_no. Move bfd_core handling
code earlier to remove goto. Enable plugin for llvm bytecode.
Copy slim IR files as unknown objects.
If all external symbol accesses are indirect, we can treat protected
symbols as local since there will be no copy relocation for data and
external function pointer access will go through GOT, instead of PLT.
No PLT slot should be used for external function pointer in executable.
bfd/
PR ld/33260
* elfxx-x86.h (COPY_INPUT_RELOC_P): Treat protected symbols with
indirect external access as local.
ld/
PR ld/33260
* testsuite/ld-i386/i386.exp: Run PR ld/33260 test.
* testsuite/ld-x86-64/x86-64.exp: Likewise.
* testsuite/ld-i386/pr33260.d: New file.
* testsuite/ld-i386/pr33260.s: Likewise.
* testsuite/ld-x86-64/pr33260-x32.d: Likewise.
* testsuite/ld-x86-64/pr33260.d: Likewise.
* testsuite/ld-x86-64/pr33260.s: Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
There's no reason to have the compiler materialize objects onto the
stack. And there's also no reason to allow comb[] and name_table[] to be
modifiable.
There's no reason for riscv_all_supported_ext[] to appear in libbfd.so's
dynamic symbol table. There's also no reason for various pieces of data
to live in .data, when .data.rel.ro or even .rodata can do.
... and const. There's no reason to have the compiler copy anonymous
objects onto the stack. And there's also no reason to allow the arrays
to be modifiable.
It isn't needed anywhere except plugin.c. The typedef can disappear.
Also make a forward declaraion for ld_plugin_input_file in plugin.h
so that this header can be used without first including plugin-api.h.
bfd/
* plugin.h (struct ld_plugin_input_file): Forward declare.
(struct plugin_data_struct): Move to..
* plugin.c: ..here.
(add_symbols): Size plugin_data without using type.
* archive.c: Don't include plugin-api.h.
* elflink.c: Likewise.
* format.c: Likewise.
binutils/
* ar.c: Don't include plugin-api.h or ansidecl.h. Only
include plugin.h when BFD_SUPPORTS_PLUGINS.
* nm.c: Don't include plugin-api.h. Only include plugin.h
when BFD_SUPPORTS_PLUGINS.
* objcopy.c: Likewise.
ld/
* ldfile.c: Don't include plugin-api.h.
* ldmain.c: Likewise.
There's a logic error in loongarch_relax_perform_deletes: when there's
not any delete operation of which the start address is strictly smaller
than the symbol address, splay_tree_predecessor() will return nullptr
and the symbol size will be unchanged even if some bytes of it are
removed.
Make the logic more complete to fix this issue. Also factor out the
symbol size adjustment logic into a function to avoid code bloating.
Tested-by: WANG Xuerui <git@xen0n.name>
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
Fat IR objects contains both regular sections and IR sections. After
commit 717a38e9a0
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sun May 4 05:12:46 2025 +0800
strip: Add GCC LTO IR support
"strip --strip-debug" no longer strips debug sections in fat IR objects
since fat IR objects are recognized as plugin object and copied as unknown
objects. Add a is_strip_input field to bfd to indicate called from strip.
Update bfd_check_format_matches not to treat archive member nor standalone
fat IR object as IR object so that strip can remove debug and IR sections
in fat IR object. For archive member, it is copied as an unknown object
if the plugin target is in use or it is a slim IR object. For standalone
fat IR object, it is copied as non-IR object.
bfd/
PR binutils/33246
* archive.c: Include "plugin-api.h" and "plugin.h" if plugin is
enabled.
(_bfd_compute_and_write_armap): Don't complain plugin is needed
when the plugin target is in use.
* bfd-in2.h: Regenerated.
* bfd.c (bfd): Add is_strip_input.
* format.c (bfd_set_lto_type): If there is .llvm.lto section,
set LTO type to lto_fat_ir_object.
(bfd_check_format_matches): Don't set LTO type when setting
format. When called from strip, don't treat archive member nor
standalone fat IR object as an IR object.
* plugin.c (bfd_plugin_get_symbols_in_object_only): Copy LTO
type derived from input sections.
nm/
PR binutils/33246
* nm.c (filter_symbols): Don't complain plugin is needed when
the plugin target is in use.
(display_rel_file): Likewise.
* objcopy.c (copy_archive): Set the BFD is_strip_input field of
archive member to 1 to indicate called from strip. Also copy
slim IR archive member as unknown object.
(copy_file): Set the BFD is_strip_input field of input bfd to
1 to indicate called from strip.
(strip_main): Keep .gnu.debuglto_* sections unless all GCC LTO
sections will be removed.
ld/
PR binutils/33246
* testsuite/ld-plugin/lto-binutils.exp (run_pr33246_test): New.
Run binutils/33246 tests with GCC and Clang.
* testsuite/ld-plugin/pr33246.c: New file.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
Tidy changes to bfd_check_format_matches made by commit 9b854f169d
which added a bfd_plugin_specified_p test and commit f752be8f91
which added an lto_sections_removed arg. Both of these changes are
unnecessary if plugin_format is set to bfd_plugin_no before calling
bfd_check_format. bfd_plugin_no will prevent the plugin object_p
function from returning a match (and in the first case from a segfault
when loading plugins while a plugin is running). The plugin object_p
function already protected itself from recursive calls by setting
bfd_plugin_no before loading a plugin, but commit 9b854f169d opened
new bfds so they were unprotected.
It isn't strictly necessary to test for bfd_plugin_no in
bfd_check_format_matches but I kept the check to minimise functional
changes. Close inspection of the patch will notice I've added an
is_linker_input test too. That also isn't strictly necessary, I
think, but the match_count test was for the linker. See commit
999d6dff80.
PR 12291
PR 12430
PR 13298
PR 33198
bfd/
* format.c (bfd_check_format_lto): Revert to bfd_check_format.
(bfd_check_format_matches_lto): Revert to bfd_check_format_matches.
Correct comments. Manage both the lto_sections_removed and
bfd_plugin_specified_p cases by testing for bfd_plugin_no.
* plugin.c (bfd_plugin_get_symbols_in_object_only): Set
plugin_format to bfd_plugin_no before checking new bfds.
(try_load_plugin): Comment setting bfd_plugin_no.
(bfd_plugin_specified_p): Delete.
* plugin.h (bfd_plugin_specified_p): Delete.
* bfd-in2.h: Regenerate.
binutils/
* objcopy.c (copy_archive): Replace bfd_check_format_lto calls
with bfd_check_format using plugin_format set to bfd_plugin_no.
(check_format_object): New function.
(copy_file): Use it.
ppc32 isn't susceptible to the PR33223 segfault, but could hit a
_bfd_clear_contents segfault with a carefully crafted invalid object.
* elf32-ppc.c (ARRAY_SIZE): Define.
(ppc_elf_howto_init): Use ARRAY_SIZE.
(ppc_elf_reloc_name_lookup): Likewise.
(ppc_elf_info_to_howto): Likewise, and consolidate error
handling.
(ppc_elf_check_relocs): Guard against segfaults caused by a NULL
howto passed to _bfd_clear_contents. Use ARRAY_SIZE.
Bounds check accesses to ppc64_elf_howto_table and don't dereference a
NULL howto. I think this catches all cases where that might happen.
PR 33223
bfd/
* elf64-ppc.c (ppc64_elf_info_to_howto): Consolidate error handling.
(ppc64_elf_check_relocs): Tidy error messages.
(ppc64_elf_relocate_section): Don't segfault when attempting to
report an unsupported relocation. Don't pass a NULL howto to
_bfd_clear_contents.
ld/
* testsuite/ld-powerpc/elfv2-2so.d: Adjust to suit error message
change.
commit 717a38e9a0
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sun May 4 05:12:46 2025 +0800
strip: Add GCC LTO IR support
added "-R .gnu.lto_.*" to strip to remove all GCC LTO sections. When
"-R .gnu.lto_.*" is used, the plugin target is ignored so that all LTO
sections are stripped as the regular sections. It works for the slim
GCC LTO IR since the GCC LTO IR is stored in the regular sections. When
the plugin target is ignored, the GCC LTO IR can be recognized as the
normal object files. But it doesn't work for the slim LLVM IR which
is stored in a standalone file.
1. Add bfd_check_format_matches_lto and bfd_check_format_lto to take an
argument, lto_sections_removed, to indicate if all LTO sections should
be removed.
2. Update strip to always enable the plugin target so that the plugin
target is enabled when checking for bfd_archive.
3. Update strip to ignore the plugin target for bfd_object when all LTO
sections should be removed. If the object is unknown, copy it as an
unknown file without any messages.
4. Treat the "-R .llvm.lto" strip option as removing all LTO sections.
bfd/
PR binutils/33198
* format.c (bfd_check_format_lto): New function.
(bfd_check_format): Call bfd_check_format_matches_lto.
(bfd_check_format_matches): Renamed to ...
(bfd_check_format_matches_lto): This. Add an argument,
lto_sections_removed, to indicate if all LTO sections should be
removed and don't match the plugin target if lto_sections_removed
is true.
(bfd_check_format_matches): Call bfd_check_format_matches_lto.
* bfd-in2.h: Regenerated.
binutils/
PR binutils/33198
* objcopy.c (copy_archive): Call bfd_check_format_lto, instead
of bfd_check_format, and pass lto_sections_removed. Remove the
non-fatal message on unknown element since it will be copied as
an unknown file.
(copy_file): Don't check lto_sections_removed when enabling LTO
plugin in strip.
(copy_file): Ignore the plugin target first if all LTO sections
should be removed. Try with the plugin target next if ignoring
the plugin target failed to match the format.
(strip_main): Also set lto_sections_removed for -R .llvm.lto.
* testsuite/binutils-all/x86-64/pr33198.c: New file.
* testsuite/binutils-all/x86-64/x86-64.exp (run_pr33198_test):
New.
Run binutils/33198 tests.
* testsuite/lib/binutils-common.exp (llvm_plug_opt): New.
(CLANG_FOR_TARGET): New. Set to "clang" for native build if
"clang -v" reports "clang version".
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>