also rename `TargetInfo *getXXXTargetInfo` to `void setXXXTargetInfo`
and change it to set `ctx.target`. This ensures that when `ctx` becomes
a local variable, two lld invocations will not reuse the function-local
static variable.
---
Reland after commit c35214c131
([ELF] Initialize TargetInfo members).
also rename `TargetInfo *getXXXTargetInfo` to `void setXXXTargetInfo`
and change it to set `ctx.target`. This ensures that when `ctx` becomes
a local variable, two lld invocations will not reuse the function-local
static variable.
Ctx was introduced in March 2022 as a more suitable place for such
singletons.
llvm/Support/thread.h includes <thread>, which transitively includes
sstream in libc++ and uses ios_base::in, so we cannot use `#define in ctx.sec`.
`symtab, config, ctx` are now the only variables using
LLVM_LIBRARY_VISIBILITY.
Ctx was introduced in March 2022 as a more suitable place for such
singletons. ctx's hidden visibility optimizes generated instructions.
This change fixes a pitfall: certain ElfSym members (e.g.
globalOffsetTable, tlsModuleBase) were not zeroed and might be stale
when lld::elf::link was invoked the second time.
See the comment in handleTlsRelocation. For TLSDESC=>IE (the TLS symbol
is defined in another DSO), R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL}
referencing a non-preemptible label uses the `R_RELAX_TLS_GD_TO_LE` code
path.
If there is no TLS section, `getTlsTpOffset` will be called with null
`Out::tlsPhdr`, leading to a null pointer dereference. Since the return
value is used by `RISCV::relocateAlloc` and ignored there, just return
0.
LoongArch TLSDESC doesn't use STT_NOTYPE labels. The `if (..) return 0;`
is a no-op for LoongArch.
This patch is a follow-up to #79239 and fixes some comments.
Pull Request: https://github.com/llvm/llvm-project/pull/98569
lld was using RISCVISAInfo(unsigned XLen,
RISCVISAUtils::OrderedExtensionMap &Exts). This required a call to
RISCVISAInfo::postProcessAndChecking to validate the RISCVISAInfo that
was created. This exposes too much about RISCVISAInfo to lld.
Replace with a new RISCVISAInfo::createFromExtMap that is responsible
for creating the object and calling postProcessAndChecking.
This patch adds support for merging the atomic_abi attribute, specified
in
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#tag_riscv_atomic_abi-14-uleb128version,
to LLD.
The atomics_abi tag merging is conducted as follows:
UNKNOWN is safe to merge with all other values.
A6C is compatible with A6S, and results in the A6C ABI.
A6C is incompatible with A7, and results in an error.
A6S and A7 are compatible, and merging results in the A7 ABI.
Note: the A7 is not yet supported in either LLVM or in any current
hardware, and is therefore omitted from attribute generation in
RISCVTargetStreamer.
LLD support was split from
https://github.com/llvm/llvm-project/pull/90266
This patch adds support for the `atomic_abi` attribute, specifid in
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#tag_riscv_atomic_abi-14-uleb128version.
The atomics_abi tag merging is conducted as follows:
- UNKNOWN is safe to merge with all other values.
- A6C is compatible with A6S, and results in the A6C ABI.
- A6C is incompatible with A7, and results in an error.
- A6S and A7 are compatible, and merging results in the A7 ABI.
Note: the A7 is not yet supported in either LLVM or in any current
hardware,
and is therefore ommited from attribute generation in
RISCVTargetStreamer.
This introduces a new file, RISCVISAUtils.cpp and moves the rest of
RISCVISAInfo to the TargetParser library.
This will allow us to generate part of RISCVISAInfo.cpp using tablegen.
g++ -flto has a diagnostic `-Wodr` about mismatched redeclarations,
which even apply to `enum`.
Fix#83529
Reviewers: thesamesam
Reviewed By: thesamesam
Pull Request: https://github.com/llvm/llvm-project/pull/83604
Refer to commit 6611d58f5b ("Relax R_RISCV_ALIGN"), we can relax
R_LARCH_ALIGN by same way. Reuse `SymbolAnchor`, `RISCVRelaxAux` and
`initSymbolAnchors` to simplify codes. As `riscvFinalizeRelax` is an
arch-specific function, put it override on `TargetInfo::finalizeRelax`,
so that LoongArch can override it, too.
The flow of relax R_LARCH_ALIGN is almost consistent with RISCV. The
difference is that LoongArch only has 4-bytes NOP and all executable
insn is 4-bytes aligned. So LoongArch not need rewrite NOP sequence.
Alignment maxBytesEmit parameter is supported in psABI v2.30.
Support
R_RISCV_TLSDESC_HI20/R_RISCV_TLSDESC_LOAD_LO12/R_RISCV_TLSDESC_ADD_LO12/R_RISCV_TLSDESC_CALL.
LOAD_LO12/ADD_LO12/CALL relocations reference a label at the HI20
location, which requires special handling. We save the value of HI20 to
be reused. Two interleaved TLSDESC code sequences, which compilers do
not generate, are unsupported.
For -no-pie/-pie links, TLSDESC to initial-exec or local-exec
optimizations are eligible. Implement the relevant hooks
(R_RELAX_TLS_GD_TO_LE, R_RELAX_TLS_GD_TO_IE): the first two instructions
are converted to NOP while the latter two are converted to a GOT load or
a lui+addi.
The first two instructions, which would be converted to NOP, are removed
instead in the presence of relaxation. Relaxation is eligible as long as
the R_RISCV_TLSDESC_HI20 relocation has a pairing R_RISCV_RELAX,
regardless of whether the following instructions have a R_RISCV_RELAX.
In addition, for the TLSDESC to LE optimization (`lui a0,<hi20>; addi a0,a0,<lo12>`),
`lui` can be removed (i.e. use the short form) if hi20 is 0.
```
// TLSDESC to LE/IE optimization
.Ltlsdesc_hi2:
auipc a4, %tlsdesc_hi(c) # if relax: remove; otherwise, NOP
load a5, %tlsdesc_load_lo(.Ltlsdesc_hi2)(a4) # if relax: remove; otherwise, NOP
addi a0, a4, %tlsdesc_add_lo(.Ltlsdesc_hi2) # if LE && !hi20 {if relax: remove; otherwise, NOP}
jalr t0, 0(a5), %tlsdesc_call(.Ltlsdesc_hi2)
add a0, a0, tp
```
The implementation carefully ensures that an instruction unrelated to
the current TLSDESC code sequence, if immediately follows a removable
instruction (HI20 or LOAD_LO12 OR (LE-specific) ADD_LO12), is not
converted to NOP.
* `riscv64-tlsdesc.s` is inspired by `i386-tlsdesc-gd.s` (https://reviews.llvm.org/D112582).
* `riscv64-tlsdesc-relax.s` tests linker relaxation.
* `riscv-tlsdesc-gd-mixed.s` is inspired by `x86-64-tlsdesc-gd-mixed.s` (https://reviews.llvm.org/D116900).
Link: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373
Reviewed By: ilovepi
Pull Request: https://github.com/llvm/llvm-project/pull/79239
If we have a RISCV_ALIGN relocation which can't be satisfied with the
available space provided, report an error rather than silently
continuing with a corrupt state.
For context, https://github.com/llvm/llvm-project/pull/73977 fixes an
LLD bug which can cause this effect, but that's not the only source of
such cases.
Another is our hard-to-fix set of LTO problems. We can have a single
function which was compiled without C in an otherwise entirely C module.
Until we have all of the mapping symbols and related mechanisms
implemented, this case can continue to arise.
I think it's very important from a user interface perspective to have
non-assertion builds report an error in this case. If we don't report an
error here, we can crash the linker (due to the fatal error at the
bottom of the function), or if we're less lucky silently produce a
malformed binary.
There's a couple of known defects with this patch.
First, there's no test case. I don't know how to write a stable test
case for this that doesn't involve hex editing an object file, or
abusing the LTO bug that we hope to fix.
Second, this will report an error on each relax iteration. I explored
trying to report an error only once after relaxation, but ended up
deciding I didn't have the context to implement it safely.
I would be thrilled if someone more knowledgeable of this code wants to
write a better version of this patch, but in the meantime, I believe we
should land this to address the user experience problem described above.
We have two structs for representing the version of an extension in
RISCVISAInfo, RISCVExtensionInfo and RISCVExtensionVersion, both
with the exact same fields. This patch deduplicates them.
Complement #72610 (non-SHF_ALLOC sections). GCC-generated
.gcc_exception_table has the SHF_ALLOC flag and may contain
R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128 relocations.
This fixes a mis-link when mixing compressed and non-compressed input to
LLD. When relaxing calls, we must respect the source file that the
section came from when deciding whether it's legal to use compressed
instructions. If the call in question comes from a non-rvc source, then it will not
expect 2-byte alignments and cascading failures may result.
This fixes https://github.com/llvm/llvm-project/issues/63964. The symptom
seen there is that a latter RISCV_ALIGN can't be satisfied and we either
fail an assert or produce a totally bogus link result. (It can be easily
reproduced by putting .p2align 5 right before the nop in the reduced
test case and running check-lld on an assertions enabled build.) However,
it's important to note this is just one possible symptom of the problem.
If the resulting binary has a runtime switch between rvc and non-rvc
routines (via e.g. ifuncs), then even if we manage to link we may execute invalid
instructions on a machine which doesn't implement compressed instructions.
For a label difference like `.uleb128 A-B`, MC generates a pair of
R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128 if A-B cannot be folded as a
constant. GNU assembler generates a pair of relocations in more cases
(when A or B is in a code section with linker relaxation).
`.uleb128 A-B` is primarily used by DWARF v5
.debug_loclists/.debug_rnglists (DW_LLE_offset_pair/DW_RLE_offset_pair
entry kinds) implemented in Clang and GCC.
`.uleb128 A-B` can be used in SHF_ALLOC sections as well (e.g.
`.gcc_except_table`). This patch does not handle SHF_ALLOC.
`-z dead-reloc-in-nonalloc=` can be used to change the relocated value,
if the R_RISCV_SET_ULEB128 symbol is in a discarded section. We don't
check the R_RISCV_SUB_ULEB128 symbol since for the expected cases A and
B should be defined in the same input section.
Note that llvm::support::endianness has been renamed to
llvm::endianness while becoming an enum class as opposed to an
enum. This patch replaces support::{big,little,native} with
llvm::endianness::{big,little,native}.
With --wrap=foo, we may have `d->file != file` for a defined symbol `foo`.
For the object file defining `foo`, its symbol table may not contain
`foo` after `redirectSymbols` changed the `foo` entry to `__wrap_foo` (see D50569).
Therefore, skipping `foo` with the condition `if (!d || d->file != file)` may
cause `__wrap_foo` not to be updated. See `ab.o w.o --wrap=foo` in the new test
(originally reported by D150220).
We could adjust the condition to `if (!d)`, but that would leave many `anchors`
entries if a symbol is referenced by many files. Switch to iterating over
`symtab` instead.
Note: D149735 (actually not NFC) allowed duplicate `anchors` entries and fixed
`a.o bw.o --wrap=foo`.
Reviewed By: jobnoorman
Differential Revision: https://reviews.llvm.org/D151768
In a real-world case with functions that have many, many
R_RISCV_CALL_PLT relocations due to asan and ubsan
instrumentation, all these can be relaxed by an instruction and
the net result is more than 65536 bytes of reduction in the
output .text section that totals about 1.2MiB in final size.
This changes InputSection to use a 32-bit field for bytesDropped.
The RISCV relaxation keeps track in a 64-bit field and detects
32-bit overflow as it previously detected 16-bit overflow. It
doesn't seem likely that 32-bit overflow will arise, but it's not
inconceivable and it's cheap enough to detect it.
This unfortunately increases the size of InputSection on 64-bit
hosts by a word, but that seems hard to avoid.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D150722
The `valueDelta` map was used to calculate the symbol value deltas from
the previous iteration. Since the symbol values themselves are also
updated every iteration, the following invariant holds:
```
sa[i].offset == sa[i].d->value + valueDelta[sa[i].d]
```
Note that `sa[i].offset` contains the original value of `sa[i].d` and is
never changed.
This means that the current way of updating symbol values can be
rewritten to not need the `valueDelta` map:
```
sa[i].d->value -= delta - valueDelta.find(sa[i].d)->second;
<=> (replace invariant)
sa[i].d->value -= delta - (sa[i].offset - sa[i].d->value);
<=>
sa[i].d->value = sa[i].d->value - (delta - (sa[i].offset - sa[i].d->value));
<=>
sa[i].d->value = sa[i].d->value - delta + sa[i].offset - sa[i].d->value;
<=>
sa[i].d->value = sa[i].offset - delta;
```
This patch implements this simplification. I believe this improves the
readability of the code as it took me quite some time to understand the
use of `valueDelta`. It might also have a slight performance benefit as
it removes one iteration over all relocations every relax iteration.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D149735
This implements support for relaxing these relocations to use the GP
register to compute addresses of globals in the .sdata and .sbss
sections.
This feature is off by default and must be enabled by passing
--relax-gp to the linker.
The GP register might not always be the "global pointer". It can
be used for other purposes. See discussion here
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/371
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D143673