When linker relaxation converts CALL (auipc+jalr, 8 bytes) to JAL
(4 bytes), further relaxation to C.J or C.JAL (2 bytes) may become
possible as code shrinks and jump distances decrease.
This patch adds _bfd_riscv_relax_jal to perform this second-pass
relaxation. To enable this, we introduce R_RISCV_DELETE_AND_RELAX,
a new internal relocation that combines piecewise deletion with
preservation of relaxation capability. When _bfd_riscv_relax_call
relaxes CALL to JAL, it marks the deletion as R_RISCV_DELETE_AND_RELAX
instead of R_RISCV_DELETE. After the piecewise deletion is resolved,
R_RISCV_DELETE_AND_RELAX is converted back to R_RISCV_RELAX at the
JAL instruction offset, allowing _bfd_riscv_relax_jal to further
relax JAL to C.J/C.JAL.
C.JAL is only available on RV32 (rd=ra), while C.J is available on
both RV32 and RV64 (rd=x0).
Changes since v1:
- Use R_RISCV_DELETE_AND_RELAX with piecewise deletion instead of
calling _riscv_relax_delete_immediate directly, to maintain
relaxation performance.
- Add preserve_relax parameter to riscv_relax_delete_bytes to
simplify the logic in _bfd_riscv_relax_call.
There is no value assigned in `_bfd_mips_elf_generic_reloc' via the
`error_message' parameter and consequently the original `error_message'
variable in `_bfd_mips_elf_orphan_shr16_reloc' remains uninitialized in
the error case, which newer versions of GCC can correctly diagnose:
In function '_bfd_mips_elf_orphan_shr16_reloc',
inlined from 'mips_elf_free_hi16_list' at ../../binutils-gdb/bfd/elfxx-mips.c:13309:12:
../../binutils-gdb/bfd/elfxx-mips.c:13281:5: error: 'error_message' may be used uninitialized [-Werror=maybe-uninitialized]
13281 | _bfd_link_reloc_status_error (abfd, info, hi->input_section,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13282 | &hi->rel, error_message, r);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../binutils-gdb/bfd/elfxx-mips.c: In function 'mips_elf_free_hi16_list':
../../binutils-gdb/bfd/elfxx-mips.c:13255:9: note: 'error_message' declared here
13255 | char *error_message;
| ^~~~~~~~~~~~~
cc1: all warnings being treated as errors
Fix the problem by preinitializing the variable to NULL as at other
places.
This patch is in response to fuzzing testcases that manage to cause
segfaults due to stale references to freed memory via mips_hi16.data.
A number of the error/warning handlers in ldmain.c use %C. This can
cause debug info to be parsed for the first time in order to print
file/function/line. If one of those warnings is triggered after some
hi16 relocs have been processed but before the matching lo16 reloc is
handled, *and* the debug info is corrupted with a lo16 reloc, then the
mips_hi16_list will be flushed with the result that printing a warning
changes linker output. It is also possible that corrupted debug info
adds to the hi16 list, with the result that when the linker handles a
later lo16 reloc in a text section, ld will segfault accessing
mips_hi16.data after the debug buffers have be freed. Both of these
problems are fixed by keeping a per-section mips_hi16_list rather than
a per-file list.
* elfxx-mips.c (struct mips_hi16): Move earlier, deleting
input_section field.
(struct _mips_elf_section_data): Add mips_hi16_list.
(struct mips_elf_obj_tdata): Delete mips_hi16_list.
(_bfd_mips_elf_free_cached_info): Adjust to suit new location
of mips_hi16_list.
(_bfd_mips_elf_hi16_reloc, _bfd_mips_elf_lo16_reloc): Likewise.
(_bfd_mips_elf_orphan_shr16_reloc): Likewise.
(mips_elf_free_hi16_list): Likewise.
(_bfd_mips_elf_finalize_section_relocs): Likewise.
(_bfd_elf_mips_get_relocated_section_contents): Likewise.
Correct the addend being ignored for orphan REL HI16 relocations.
For assembly and non-ELF links `_bfd_mips_elf_hi16_reloc' is called from
`bfd_install_relocation' and `bfd_perform_relocation' respectively via
the respective howtos. It caches the relocation for later processing as
`_bfd_mips_elf_lo16_reloc' is called via the corresponding LO16 reloc's
howto, at which point both the HI16 and the LO16 parts are calculated
and installed.
If no matching LO16 relocation has been later encountered, then the
cached entry is never processed, with the outstanding cached entries
silently dropped at the conclusion of processing, resulting in zero
addend being used for the field relocated.
Dropping of the entries only happens in `_bfd_mips_elf_free_cached_info'
at the time the BFD is being successfully closed and section contents
long written to output. For non-ELF links dropping will also execute in
`_bfd_elf_mips_get_relocated_section_contents' via a separate piece of
code if the function has encountered an error.
Address the issues first by factoring out code to process outstanding
cached entries to `mips_elf_free_hi16_list' and then by making the
function actually install the relocations cached as required. This has
to happen before section contents have been written and therefore the
success path wires the function call to `bfd_finalize_section_relocs',
for assembly and `_bfd_elf_mips_get_relocated_section_contents' for
non-ELF links.
For housekeeping purposes the latter call will just drop cached entries
as it happens now in the case of an error, and likewise the call from
`_bfd_mips_elf_free_cached_info' is retained in case a fatal error in
the assembler prevents `bfd_finalize_section_relocs' from being called.
This also results in a warning being issued now about orphan REL HI16
relocations encountered in non-ELF links. Previously no such warning
was produced since the cached entries were dropped. For assembly we
expect the tool to have issued its own warning, so we process orphan
relocations silently if successful, but still issue a warning if an
error is returned.
We are careful in `mips_elf_free_hi16_list' to retain any incoming BFD
error as the function may be called under an error condition and if
there's another failure in processing at this stage we don't want to
clobber the original error.
Test cases will be added with a separate change.
Correct the addend being ignored for orphan REL HI16 relocations.
For ELF links `_bfd_mips_elf_relocate_section' handles relocation and
uses `mips_elf_add_lo16_rel_addend' to shift the incoming HI16 in-place
addend into its intended [31:16] bit positions and combine it with the
LO16 part. If no matching LO16 reloc has been found, then the function
returns early and consequently the incoming HI16 addend is not shifted
and remains in bits [0:15]. For final links any value of the symbol
referred is then added. Then the final value is shifted back into bits
[0:15] for installation into the field relocated. It is obviously wrong
as the original HI16 in-place addend has now been lost.
Fix the issue by shifting the incoming HI16 in-place addend before using
`mips_elf_next_relocation' to find the matching LO16 relocation. Then
upon early return from `mips_elf_add_lo16_rel_addend' the addend is in
the intended [31:16] bit positions already.
Test cases will be added with a separate change.
Use the warning callback for the orphan REL HI16 relocation warning just
as with any other linker relocation processing warnings, standardizing
the message format and providing source location where available.
Test cases will be added with a separate change.
Update `bfd_finalize_section_relocs' to return status so that backends
can fail in this interface and propagate that to the respective callers.
Add suitable error reporting there. No failure cases in the existing
handlers though.
The `*_set_reloc' interface is to be called at the conclusion of section
relocation processing, however its name reflects a particular action to
take rather than the context of invocation. Implementation is already
backend-specific.
Rename the interface such as not to make its name artificially limit the
intended purpose. Update the callers and documentation accordingly. No
functional change.
Call _bfd_elf_section_from_bfd_section to get the sh_link value from
the section flag 'o' directive, which may point to special sections,
like SHN_ABS or SHN_COMM. Update readelf to print the special section
names in the sh_link field and replace "internal->sh_link > num" with
"internal->sh_link >= num".
bfd/
PR gas/33744
* elf.c (assign_section_numbers): Call
_bfd_elf_section_from_bfd_section to get the sh_link value.
binutils/
PR gas/33744
* readelf.c (special_defined_section_index): New.
(get_32bit_section_headers): Don't warn special section indexes
in the sh_link field.
(get_64bit_section_headers): Likewise.
(process_section_headers): Print special defined section names.
gas/
PR gas/33744
* testsuite/gas/elf/elf.exp: Run PR gas/33744 tests.
* testsuite/gas/elf/sh-link-abs-1.d: New file.
* testsuite/gas/elf/sh-link-abs-2.d: Likewise.
* testsuite/gas/elf/sh-link-abs-3-32.d: Likewise.
* testsuite/gas/elf/sh-link-abs-3-64.d: Likewise.
* testsuite/gas/elf/sh-link-abs-4-32.d: Likewise.
* testsuite/gas/elf/sh-link-abs-4-64.d: Likewise.
* testsuite/gas/elf/sh-link-abs.s: Likewise.
* testsuite/gas/elf/sh-link-common-1.d: Likewise.
* testsuite/gas/elf/sh-link-common-2.d: Likewise.
* testsuite/gas/elf/sh-link-common-3-32.d: Likewise.
* testsuite/gas/elf/sh-link-common-3-64.d: Likewise.
* testsuite/gas/elf/sh-link-common-4-32.d: Likewise.
* testsuite/gas/elf/sh-link-common-4-64.d: Likewise.
* testsuite/gas/elf/sh-link-common.s: Likewise.
* testsuite/gas/elf/sh-link-large-common-1.d: Likewise.
* testsuite/gas/elf/sh-link-large-common-2.d: Likewise.
* testsuite/gas/elf/sh-link-large-common-3.d: Likewise.
* testsuite/gas/elf/sh-link-large-common-4.d: Likewise.
* testsuite/gas/elf/sh-link-large-common.s: Likewise.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
When packing relative relocations, x86 linker may load the same symbol
table repeatedly, which can take a long time. On Intel Core i7-1195G7
with 32GB RAM, it takes more than 45 minutes to create an output with
-pie -z pack-relative-relocs from an input with 208025 code sections.
Cache the symbol table to reduce the link time to less than 2 seconds.
On the same machine, creating 3.1GB clang executable in LLVM 21.1.3 debug
build:
user 55.39 seconds
system 6.71 seconds
total 65.80 seconds
maximum set(GB) 10.43
page faults 2406941
PR ld/33765
* elfxx-x86.c (elf_x86_relative_reloc_record_add): Remove
keep_symbuf_p.
(_bfd_x86_elf_link_relax_section): Updated. Cache the symbol
table to avoid loading it again.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
The erratum mitigation support for the Cortex-A53 843419 erratum
inserts a new stub for every possible instance of the erratum. Since
each stub ends up inserting 4k of space into the binary, in order to
avoid perturbing the alignment of other potential erratum sequences we
can end up adding substantially more space than the distance to the
next long-branch stub that we've prepared for.
The problem is, fundamentally a phase ordering problem, but that's
easily resolvable by running the 843419 erratum pass first and then
creating the stub groups once that is done. In this way we take into
account the additional padding when forming the groups to ensure that
they remain within range.
If the target symbol for a stub was empty we would previously end up
using an anonymous stub name of the form ___veneer. To make things a
little clearer use the section symbol for the target section in this
case. We now end up with veneer symbols like __.text_veneer.
Adjusted the tests accordingly.
It is absurd to build this file when it's not possibly used. Move its
references to where other elf-*.* are and introduce a compiler define
(paralleling what gas uses, as having the same purpose) to isolate out
ELF-specific pieces in compress.c (which is where the references into
elf-properties.c are coming from).
On my Fedora 41 machine, a cross-hosted mingw build fails with:
../../binutils-gdb/bfd/bfdio.c:249:50: error: implicit declaration of function 'ARRAY_SIZE'; did you mean 'ARRAYSIZE'? [-Wimplicit-function-declaration]
Including libiberty.h in bfdio.c fixes the failure.
The idea of this patch is to match the solaris target over other
targets if e_ident contains ELFOSABI_SOLARIS. The solaris target will
continue to recognise ELFOSABI_NONE objects.
This has the side effect of disabling gnu features that require
ELFOSABI_GNU, such as ifuncs. I think that is correct, so I've made
the required testsuite changes to fix the resulting regressions:
FAIL: nm --ifunc-chars (assembly)
FAIL: mbind sections without SHF_ALLOC
The patch also sets ELF_OSABI for the gnu x86 and sparc targets,
for the same reason as the solaris targets. This doesn't mean object
files will automatically be marked ELFOSABI_GNU/LINUX. As before that
will only happen when certain GNU extensions are present.
bfd/
* elf32-i386.c: Define ELF_OSABI for solaris and gnu targets.
* elf32-sparc.c: Likewise.
* elf64-sparc.c: Likewise.
* elf64-x86-64.c: Likewise.
* format.c (bfd_check_format_matches): Bump match_priority
for matching e_ident EI_OSABI.
binutils/
* testsuite/binutils-all/nm.exp: Use !supports_gnu_osabi to
disable ifunc test.
gas/
* testsuite/gas/elf/section13.d: Only run on supports_gnu_osabi
targets. Remove xfails.
Currently a binutils ELF target with ELF_OSABI defined to something
other than the default ELFOSABI_NONE will only accept object files
with e_ident[EI_OSABI] having the value ELF_OSABI. An ELF target with
ELF_OSABI as ELFOSABI_NONE will match any e_ident[EI_OSABI] value, and
typically that target's object files will have ELFOSABI_NONE or one
other value in e_ident[EI_OSABI]. Given an object file with that
"other value" we'd like to be able to choose the correct target but
currently have no way to do so. This patch is a step towards
implementing better target matching.
It does so by adding an ELF_OSABI_EXACT to the target description,
setting that true for all targets that currently define ELF_OSABI, and
testing the new flag for exact matching. This will allow a future
patch to define ELF_OSABI without forcing exact matching but giving a
hint as to the best target match.
Some other tweaks are done as shown by the changelog below but no
user functional changes should be seen with this patch.
* elf-bfd.h (struct elf_backend_data): Add osabi_exact.
* elf.c (_bfd_elf_final_write_processing): Only set e_ident
from elf_osabi when osabi_exact.
* elfcode.h (elf_object_p): Test osabi_exact to reject
mismatching e_ident. Remove unnecessary EM_NONE test.
* elfcore.h (elf_core_file_p): Likewise.
* elfxx-target.h (ELF_OSABI_EXACT): Provide default of 0,
and init elfNN_bed.
(elf_match_priority): Handle ELF_OSABI_EXACT.
* elf32-arm.c (ELF_OSABI_EXACT): Define and undef along with
ELF_OSABI.
* elf32-hppa.c: Likewise.
* elf32-i386.c: Likewise.
* elf32-mips.c: Likewise.
* elf32-ppc.c: Likewise.
* elf32-tic6x.c: Likewise.
* elf32-visium.c: Likewise.
* elf64-alpha.c: Likewise.
* elf64-hppa.c: Likewise.
* elf64-ia64-vms.c: Likewise.
* elf64-mips.c: Likewise.
* elf64-ppc.c: Likewise.
* elf64-sparc.c: Likewise.
* elf64-x86-64.c: Likewise.
* elfn32-mips.c: Likewise.
* elfnn-ia64.c: Likewise.
* elf32-msp430.c: Likewise. Don't define ELF_OSABI to
ELFOSABI_NONE.
"const struct elf_backend_data" appears many places in the source,
and in some cases makes a line too long without wrapping. This patch
introduces a "typedef const struct elf_backend_data elf_backend_data;"
and uses it throughout binutils sources, with a few exceptions for c++
use of header files.
* elf-bfd.h (struct elf_backend_data): Make arch, elf_osabi,
elf_machine_code and target_os bitfields, and reorder. Make
maxpagesize, minpagesize, commonpagesize and p_align unsigned
int.
* elfxx-target.h (elfNN_bed): Reorder to suit. Delete useless
comments.
This flag is never set for any target. Delete it. Also, I think it
is safe to unconditionally enable what it was supposed to control.
* elf-bfd.h (struct elf_backend_data): Delete
elf_backend_can_make_multiple_eh_frame.
* elfxx-target.h (elf_backend_can_make_multiple_eh_frame): Don't
define or use.
* elflink.c (_bfd_elf_default_action_discarded): Move
SHT_GNU_SFRAME check earlier. Return 0 for ".eh_frame"
and ".eh_frame.*".
ELF_TARGET_ID is supposed to be an enum elf_target_id.
* elf-bfd.h (enum elf_target_id): Add WEBASSEMBLY_ELF_DATA
and re-order VAX_ELF_DATA.
* elf32-wasm32.c (ELF_TARGET_ID): Use WEBASSEMBLY_ELF_DATA.
These sections have SHF_STRINGS in sh_flags on Solaris. Commit
8486501545 in part implemented this variation by an elf_backend_data
field used to set the flags, but that only works of course if one of
the solaris targets is used. Which in some ways is fair enough. If
you want solaris support then it is reasonable to require the solaris
targets to be compiled in. However if they are not the default, other
ELF targets may be used even when the solaris targets are compiled in,
because many ELF targets allow any ELFOSABI object to match. (Which
is arguably a bug.)
So instead of the current scheme this patch implements the solaris
specific sh_flags in _bfd_elf_final_write_processing. That way either
a solaris target being used, or ELFOSABI_SOLARIS in the object will
get the correct sh_flags.
PR 19938
* elf-bfd.h (struct elf_backend_data): Delete elf_strtab_flags.
* elf.c (_bfd_elf_final_write_processing): Handle solaris
peculiarities here.
(_bfd_elf_compute_section_file_positions): Leave shstrtab sh_flags
zero, and don't re-zero other fields.
(swap_out_syms): Similarly for sym strtab.
* elflink.c (_bfd_elf_final_link): Likewise.
* elf32-i386.c (elf_backend_strtab_flags): Don't define.
* elf32-sparc.c: Likewise.
* elf64-sparc.c: Likewise.
* elf64-x86-64.c: Likewise.
* elfxx-target.h: Likewise.
Avoid warnings about invalid escapes in etc/update-copyright.py by
using raw strings, add BinutilsFilter to skip psql.rc and add
"Kalray SA." as another copyright holder.
One of the recent Solaris patches removed want64=true from the 32-bit
Solaris targets. This breaks GCC bootstrap: unlike Linux, GCC on
Solaris is always biarch, both in 32-bit-default and 64-bit-default
configurations, so the 64-bit multilib fails to build.
This patch undoes this incompatible change.
Tested on i386-pc-solaris2.11 and sparc-sun-solaris2.11.
2025-12-24 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
bfd:
* config.bfd <i[3-7]86-*-solaris2*> (want64): Add.
<sparc-*-solaris2*>: Likewise.
What I committed in f4e835a40c wasn't wrong but it wasn't elegant.
Unlike looking for a word separated by spaces, it isn't necessary
to prepend and append the separators in the match string.
* configure.ac (assocvecs): Tidy uniquify code.
* configure: Regenerate.
This improves "nearby" section choice when memory regions are active,
preferring a section in the same region as the excluded section over
other sections.
PR 33726
include/
* bfdlink.h (struct bfd_link_callbacks): Add nearby_section.
(_bfd_nearby_section): Delete.
(bfd_fix_excluded_sec_syms): Rename and remove bfd param from
_bfd_fix_excluded_sec_syms.
bfd/
* linker.c (_bfd_nearby_section): Delete.
(fix_syms): Use linker callback.
* elflink.c (elf_link_input_bfd): Likewise.
(_bfd_elf_final_link): Update.
ld/
* ldemul.c (finish_default): Update.
* ldlang.c (lang_output_section_get): Delete.
(ldlang_nearby_section): New function.
* ldlang.h (ldlang_nearby_section): Declare.
(lang_output_section_get): New static inline.
* ldmain.c (link_callbacks): Add ldlang_nearby_section.
... between specification and implmentation.
Move to definition in the implementation (gas/ld/libsframe) and not the
specification (include/sframe.h). At this time the implementation in
gas and ld generate the sections in the latest SFrame version only.
Reviewed-by: Jens Remus <jremus@linux.ibm.com>
bfd/
* elf-sframe.c: Add definition here.
gas/
* gen-sframe.c: Likewise.
libsframe/
* sframe.c: Likewise.
include/
* sframe.h: Remove the definition.