In #86751 we moved the IRELATIVE relocations to .rela.plt when
--pack-dyn-relocs=android was enabled but we neglected to also move
the __rela_iplt_{start,end} symbols. As a result, static binaries
linked with this flag were unable to find their IRELATIVE relocations.
Fix it by having the symbols surround the correct section.
Reviewers: MaskRay, smithp35
Reviewed By: MaskRay
Pull Request: https://github.com/llvm/llvm-project/pull/118585
The R_ARM_SBREL32 relocation is used in debug info for ARM RWPI
(read-write position independent) code. Compiler-generated DWARF info
will use an expression to add the relocated value to the actual value of
the static base (held in r9) at run-time, so it should be relocated as
if the static base is at address 0.
Follow-up to the NFC refactoring
43e3871a327b8e2ff57e16b46d5bc44beb430d91 and test cleanup
3cecf17065919da0a7fa9b38f37592e5462c2f85.
SHF_MERGE sections with relocations are handled as InputSection (without
duplicate elimination). The output section retains the original
sh_entsize in non-relocatable links. This patch ports the behavior for
relocatable links as well.
https://github.com/ClangBuiltLinux/linux/issues/2057
When we create a thunk we don't know whether it will be short or long.
Move the emission of the long thunk mapping symbol to when we transition
to a long thunk. This improves disassembly and binary analysis as tools
like BOLT identify thunks by disassembly.
This removes a FIXME added in #108989 aarch64-thunk-bti-multipass.s
which had a corrupt disassembly due to missing mapping symbols.
Rename R_X86_64_REX2_GOTPCRELX to R_X86_64_CODE_4_GOTPCRELX, to align
with GCC/binutils and ABI.
GCC/binutils:
3d5a60de52
and
4a54cb0658
ABI:
357de358ba
Range checks for R_HEX_B22_PCREL did not account for the fact that
offset is measured in instructions, not bytes.
Add a test for all range-checked relocations.
A follow up to PR #116402 to add a regression test. The original change
fixed the reproducer but that was not suitable to use as a regression
test.
This test case will fail with a LLD prior to #116402.
The disassembly for the thunk that starts as a short thunk but is later
a long thunk isn't quite right. It is missing a $d mapping symbol. I
think this can be fixed, but I've not done that in this patch to keep it
test only. It is not a regression introduced in #116402.
I've also removed a spurious --threads=1 I noticed in the original test
aarch64-thunk-bti.s
Assume PAC instructions being supported with PAuth core info different from (0,0). The (0,0) value means that an ELF file is incompatible with PAuth - see https://github.com/ARM-software/abi-aa/blob/2024Q3/pauthabielf64/pauthabielf64.rst#core-information. With PAC non-hint instructions supported, `autia1716; br x17` can be replaced with `braa x17, x16; nop`, where `braa` is an authenticated branch instruction using IA key, discriminator from x16 and signed target address from x17.
Commit 93589057830b2c3c35500ee8cac25c717a1e98f9 was reverted because it
caused a failure with test `lld :: ELF/ppc64-local-exec-tls.s`. This
relands the commit with a fix for the test.
When PAuth core info is present and (platform,version) is not (0,0),
treat input files as pac-enabled and do not emit a warning with
`-z pac-plt` passed.
b6162622c054f changed semantics of `-z pac-plt` initially introduced in
e208208a3132c, so, the following comment from test/ELF/aarch64-feature-pac.s
is no longer true:
> There are no warnings in this case as the choice to use PAC in PLT entries
> is orthogonal to the choice of using PAC in relocatable objects. The
> presence of the PAC .note.gnu.property is an indication of preference by
> the relocatable object.
This patch updates the test so we ensure a warning is emitted for an
input file when `-z pac-plt` is passed but the file does not have
GNU_PROPERTY_AARCH64_FEATURE_1_PAC set in GNU_PROPERTY_AARCH64_FEATURE_1_AND
property.
The inaccurate #111945 condition fixes a PROVIDE regression (#111478)
but introduces another regression: in a DSO link, if a symbol referenced
only by bitcode files is defined as PROVIDE_HIDDEN, lld would not set
the visibility correctly, leading to an assertion failure in
DynamicReloc::getSymIndex (https://reviews.llvm.org/D123985).
This is because `(sym->isUsedInRegularObj || sym->exportDynamic)` is
initially false (bitcode undef does not set `isUsedInRegularObj`) then
true (in `addSymbol`, after LTO compilation).
Fix this by making the condition accurate: use a map to track defined
symbols.
Reviewers: smithp35
Reviewed By: smithp35
Pull Request: https://github.com/llvm/llvm-project/pull/112386
When encountering an instruction like `if (p0) r0 = add(r0,##bar@GOT)`,
lld would fail with:
```
ld.lld: error: unrecognized instruction for 16_X type: 0x7400C000
```
This issue was encountered while building libreadline with clang 19.1.0.
Fixes: #111876
Case: `PROVIDE(f1 = bar);` when both `f1` and `bar` are in separate
sections that would be discarded by GC.
Due to `demoteDefined`, `shouldAddProvideSym(f1)` may initially return
false (when Defined) and then return true (been demoted to Undefined).
```
addScriptReferencedSymbolsToSymTable
shouldAddProvideSym(f1): false
// the RHS (bar) is not added to `referencedSymbols` and may be GCed
declareSymbols
shouldAddProvideSym(f1): false
markLive
demoteSymbolsAndComputeIsPreemptible
// demoted f1 to Undefined
processSymbolAssignments
addSymbol
shouldAddProvideSym(f1): true
```
The inconsistency can cause `cmd->expression()` in `addSymbol` to be
evaluated, leading to `symbol not found: bar` errors (since `bar` in the
RHS is not in `referencedSymbols` and is GCed) (#111478).
Fix this by adding a `sym->isUsedInRegularObj` condition, making
`shouldAddProvideSym(f1)` values consistent. In addition, we need a
`sym->exportDynamic` condition to keep provide-shared.s working.
Fixes: ebb326a51fec37b5a47e5702e8ea157cd4f835cd
Pull Request: https://github.com/llvm/llvm-project/pull/111945
The RISC-V psABI states that "The `R_RISCV_PCREL_LO12_I` or
`R_RISCV_PCREL_LO12_S` relocations contain a label pointing to an
instruction in the same section with an `R_RISCV_PCREL_HI20` relocation
entry that points to the target symbol."
Without this patch, GNU ld errors, but LLD does not -- I think because LLD is
doing the right thing, certainly in the testcase provided.
Nonetheless, I think an error is good here to bring LLD in line with
what GNU ld is doing in showing that the object the user provided is not
following the psABI as written.
Fixes#107304
We've noticed that for large builds executing thin-link can take on the
order of 10s of minutes. We are only using a single thread to write the
sharded indices and import files for each input bitcode file. While we
need to ensure the index file produced lists modules in a deterministic
order, that doesn't prevent us from executing the rest of the work in
parallel.
In this change we use a thread pool to execute as much of the backend's
work as possible in parallel. In local testing on a machine with 80
cores, this change makes a thin-link for ~100,000 input files run in ~2
minutes. Without this change it takes upwards of 10 minutes.
---------
Co-authored-by: Nuri Amari <nuriamari@fb.com>
When Branch Target Identification BTI is enabled all indirect branches
must target a BTI instruction. A long branch thunk is a source of
indirect branches. To date LLD has been assuming that the object
producer is responsible for putting a BTI instruction at all places the
linker might generate an indirect branch to. This is true for clang, but
not for GCC. GCC will elide the BTI instruction when it can prove that
there are no indirect branches from outside the translation unit(s). GNU
ld was fixed to generate a landing pad stub (gnu ld speak for thunk) for
the destination when a long range stub was needed [1].
This means that using GCC compiled objects with LLD may lead to LLD
generating an indirect branch to a location without a BTI. The ABI [2]
has also been clarified to say that it is a static linker's
responsibility to generate a landing pad when the target does not have a
BTI.
This patch implements the same mechansim as GNU ld. When the output ELF
file is setting the
GNU_PROPERTY_AARCH64_FEATURE_1_BTI property, then we check the
destination to see if it has a BTI instruction. If it does not we
generate a landing pad consisting of:
BTI c
B <destination>
The B <destination> can be elided if the thunk can be placed so that
control flow drops through. For example:
BTI c
<destination>:
This will be common when -ffunction-sections is used.
The landing pad thunks are effectively alternative entry points for the
function. Direct branches are unaffected but any linker generated
indirect branch needs to use the alternative. We place these as close as
possible to the destination section.
There is some further optimization possible. Consider the case:
.text
fn1
...
fn2
...
If we need landing pad thunks for both fn1 and fn2 we could order them
so that the thunk for fn1 immediately precedes fn1. This could save a
single branch. However I didn't think that would be worth the additional
complexity.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106671
[2] https://github.com/ARM-software/abi-aa/issues/196
Swap `!DisassembleZeroes` and `if (DumpARMELFData)` conditions so that
in the false DisassembleZeroes case (default), `...` will be printed for
long consecutive zeroes, even when a data mapping symbol is active.
This is especially useful for certain lld tests that insert a huge
padding within a code section. Without `...` the output will be huge.
Pull Request: https://github.com/llvm/llvm-project/pull/109553
Similar to commit 686cff17cc310884e48ae963bf7507f96950cc90 for SHT_REL (#57693).
CREL hasn't been tested with ICF before.
And avoid a pitfall that eqClass[0] might interfere with ICF.
When both CREL and the experimental lld partitions feature are enabled,
the relocation section may look like .crel.llvm_sympart.f1, and
`rels.relas` is empty. While here, support relocation sections with zero
entry.
In AArch64, the endianness of instruction encodings is always little,
whereas the endianness of data swaps between LE and BE modes. So
getImplicitAddend must use the right one of read32() and read32le(), for
data and code respectively. It was using read32() throughout, causing
instructions to be read as big-endian in BE mode, getting the wrong
addend.
Fixed, and updated the existing test to check both endiannesses. The
expected results for data must be byte-swapped, but the ones for code
need no adjustment.
Time trace profiler support was added into LLVMgold in
cd3255abede5e3687c1538f2d3857deb2c51af1b. This patch adds its
`-plugin-opt` counterpart, which is just an alias to `--time-trace=`,
into LLD for compatibility.
This retries #90692 which was reverted previously due to issues with
lld-available being set, even if the copy of lld is not built from
source.
This does not change any code compared to #90692 to address the
lld-available issue.
The main change w.r.t, lld-available is xfailing tests in PR #99056
(until a longer term fix is available).
The start state of a new section is `EMS_None`, often leading to a
$d/$x at offset 0. Introduce a MCTargetOption/cl::opt
"implicit-mapsyms" to allow an alternative behavior
(https://github.com/ARM-software/abi-aa/issues/274):
* Set the start state to `EMS_Data` or `EMS_A64`.
* For text sections, add an ending $x only if the final data is not instructions.
* For non-text sections, add an ending $d only if the final data is not data commands.
```
.section .text.1,"ax"
nop
// emit $d
.long 42
// emit $x
.section .text.2,"ax"
nop
```
This new behavior decreases the .symtab size significantly:
```
% bloaty a64-2/bin/clang -- a64-0/bin/clang
FILE SIZE VM SIZE
-------------- --------------
-5.4% -1.13Mi [ = ] 0 .strtab
-50.9% -4.09Mi [ = ] 0 .symtab
-4.0% -5.22Mi [ = ] 0 TOTAL
```
---
This scheme works as long as the user can rule out some error scenarios:
* .text.1 assembled using the traditional behavior is combined with .text.2 using the new behavior
* A linker script combining non-text sections and text sections. The
lack of mapping symbols in the non-text sections could make them
treated as code, unless the linker inserts extra mapping symbols.
The above mix-and-match scenarios aren't an issue at all for a
significant portion of users.
A text section may start with data commands in rare cases (e.g.
-fsanitize=function) that many users don't care about. When combing
`(.text.0; .word 0)` and `(.text.1; .word 0)`, the ending $x of .text.0
and the initial $d of .text.1 may have the same address. If both
sections reside in the same file, ensure the ending symbol comes before
the initial $d of .text.1, so that a dumb linker respecting the symbol
order will place the ending $x before the initial $d.
Disassemblers using stable sort will see both symbols at the same
address, and the second will win.
When section ordering mechanisms (e.g. --symbol-ordering-file,
--call-graph-profile-sort, `.text : { second.o(.text) first.o(.text) }`)
are involved, the initial data in a text section following a text
section with trailing data could be misidentified as code, but the issue
is local and the risk could be acceptable.
Pull Request: https://github.com/llvm/llvm-project/pull/99718
* Use split-file
* Remove -o /dev/null
* Avoid `{ list; }` compound command not supported by the lit internal shell (#102382)
* Don't test "ld.lld" before "error:" as per convention
Pull Request: https://github.com/llvm/llvm-project/pull/105454
RISC-V GCC with `-fdata-sections` will emit `.sbss.<name>`,
`.srodata.<name>`, and `.sdata.<name>` sections for small data items of
different kinds. Clang/LLVM already emits `.srodata.*` sections, and we
intend to emit the other two section name patterns in #87040.
This change ensures that any input sections starting `.sbss` are
combined into one output section called `.sbss`, and the same
respectively for `.srodata` and `.sdata`. This also allows the existing
RISC-V specific code for determining an output order for `.sbss` and
`.sdata` sections to apply to placing the sections.
so that --noinhibit-exec downgrades the error to a warning, which helps
debugging when `PHDRS` is specified without `PT_TLS`. Also update the
message to make it accurate: STT_TLS may exist in the absence of PT_TLS.
In addition, invoking `exitLld(1)` (through `fatal`) is problematic
(#66974): When a thread is `exitLld(1)`, triggering `llvm_shutdown`,
another thread may be at `relocateAlloc`, accessing `sec.relocs()` which
got destroyed(tampered?), leading to
incorrect `llvm_unreachable("invalid expression")`.
Follow-up to #98115. For EhInputSection, RelocationScanner::scan calls
sortRels, which doesn't support the CREL iterator. We should set
supportsCrel to false to ensure that the initial_location fields in
.eh_frame FDEs are relocated.