494 Commits

Author SHA1 Message Date
Fangrui Song
43b13341fb
[ELF] Add internal InputFile (#78944)
Based on https://reviews.llvm.org/D45375 . Introduce a new InputFile
kind `InternalKind`, use it for

* `ctx.internalFile`: for linker-defined symbols and some synthesized
`Undefined`
* `createInternalFile`: for symbol assignments and --defsym

I picked "internal" instead of "synthetic" to avoid confusion with
SyntheticSection.

Currently a symbol's file is one of: nullptr, ObjKind, SharedKind,
BitcodeKind, BinaryKind. Now it's non-null (I plan to add an
`assert(file)` to Symbol::Symbol and change `toString(const InputFile
*)`
separately).

Debugging and error reporting gets improved. The immediate user-facing
difference is more descriptive "File" column in the --cref output. This
patch may unlock further simplification.

Currently each symbol assignment gets its own
`createInternalFile(cmd->location)`. Two symbol assignments in a linker
script do not share the same file. Making the file the same would be
nice, but would require non trivial code.
2024-01-22 09:09:46 -08:00
Fangrui Song
3a4615c0fe [ELF] Clarify the first entry of .got.plt NFC
Differential Revision: https://reviews.llvm.org/D47053
2024-01-21 16:42:44 -08:00
Philip Reames
987123e4f1
[LLD][RISCV] Report error for unsatisfiable RISCV_ALIGN (#74121)
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.
2024-01-17 14:32:20 -08:00
Luke Lau
79889fedc5
[RISCV] Deduplicate version struct in RISCVISAInfo. NFC (#77645)
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.
2024-01-11 15:07:24 +07:00
PiJoules
f7678c81fe
[llvm][lld] Support R_RISCV_GOT32_PCREL (#72587)
This is the followup implementation to
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/402 that
supports this relocation in llvm and lld.
2024-01-10 15:16:55 -08:00
PiJoules
04a906ec98
[llvm][lld] Support R_AARCH64_GOTPCREL32 (#72584)
This is the follopw implementation to
https://github.com/ARM-software/abi-aa/pull/223 that supports this
relocation in llvm and lld.
2024-01-10 15:12:42 -08:00
Lu Weining
38394a3d0b
[lld][LoongArch] Handle extreme code model relocs according to psABI v2.30 (#73387)
psABI v2.30 requires the extreme code model instructions sequence
(pcalau12i+addi.d+lu32i.d+lu52i.d) to be adjacent.

See https://github.com/llvm/llvm-project/pull/71907 and
https://github.com/loongson-community/discussions/issues/17 for details.
2024-01-10 18:03:52 +08:00
Fangrui Song
3fa17954de
[ELF] Support R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128 in SHF_ALLOC sections (#77261)
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.
2024-01-08 20:24:00 -08:00
Mitch Phillips
a831a21e4d
[lld] [MTE] Allow android note for static executables. (#77078)
Florian pointed out that we're accidentally eliding the Android note for
static executables, as it's guarded behind the "can have memtag globals"
conditional. Of course, memtag globals are unsupported for static
executables, but we should still allow static binaries to produce the
Android note (as that's the only way they get MTE).
2024-01-08 11:22:38 +01:00
Nicholas Mosier
c5e35986d8
[lld][ELF][X86] Add missing X86_64_TPOFF64 case in switches (#77208)
Close #77201. When linking code with a R_X86_64_TPOFF64 relocation, LLD
exits with an 'unknown reloaction' error message due to two missing
cases in relocation switch statements. This patch adds in those cases so
that LLD successfully links code R_X86_64_TPOFF64 relocations.
2024-01-07 11:59:49 -08:00
Lu Weining
88548df0fc
[lld][LoongArch] Support the R_LARCH_CALL36 relocation type (#73346)
R_LARCH_CALL36 was designed for function call on medium code model where
the 2 instructions (pcaddu18i + jirl) must be adjacent. This is expected
to replace current medium code model implementation, i.e.
R_LARCH_PCALA_{HI20,LO12} on pcalau12i + jirl.

See https://github.com/loongson/la-abi-specs/pull/3 for more details.
2023-12-25 17:40:48 +08:00
Kazu Hirata
732bccb8c1 Use StringRef::{starts,ends}_with (NFC)
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
2023-12-14 07:53:20 -08:00
Philip Reames
62213be872
[LLD][RISCV] Fix incorrect call relaxation when mixing +c and -c objects (#73977)
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.
2023-12-01 11:02:53 -08:00
Weining Lu
84a20989c6 [lld][LoongArch] Add a another corner testcase for elf::getLoongArchPageDelta
Similar to e752b58e0d26.
2023-11-25 20:38:45 +08:00
Fangrui Song
7ffabb61a5
[ELF] Support R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128 in non-SHF_ALLOC sections (#72610)
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.
2023-11-21 07:43:29 -08:00
Jinyang He
72accbfd0a
[lld][LoongArch] Support the R_LARCH_{ADD,SUB}6 relocation type (#72190)
The R_LARCH_{ADD,SUB}6 relocation type are usually used by DwarfCFA to
calculate a tiny offset. They appear after binutils 2.41, with GAS
enabling relaxation by default.
2023-11-15 09:57:45 +08:00
Kazu Hirata
4a0ccfa865 Use llvm::endianness::{big,little,native} (NFC)
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}.
2023-10-12 21:21:45 -07:00
Ben Shi
488a62f86e
[lld][ELF][AVR] Add range check for R_AVR_13_PCREL (#67636)
Some large AVR programs (for devices without long jump) may exceed
128KiB, and lld should give explicit errors other than generate wrong
executables silently.
2023-10-06 18:20:03 +08:00
Arthur Eubanks
9d6ec280fc [lld/ELF] Don't relax R_X86_64_(REX_)GOTPCRELX when offset is too far
For each R_X86_64_(REX_)GOTPCRELX relocation, check that the offset to the symbol is representable with 2^32 signed offset. If not, add a GOT entry for it and set its expr to R_GOT_PC so that we emit the GOT load instead of the relaxed lea. Do this in finalizeAddressDependentContent() where we iteratively attempt this (e.g. RISCV uses this for relaxation, ARM uses this to insert thunks).

Decided not to do the opposite of inserting GOT entries initially and removing them when relaxable because removing GOT entries isn't simple.

One drawback of this approach is that if we see any GOTPCRELX relocation, we'll create an empty .got even if it's not required in the end.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D157020
2023-10-04 13:03:56 -07:00
simpal01
3cde1d8000
[ELF] Handle relocations in synthetic .eh_frame with a non-zero offset within the output section (#65966)
When the .eh_frame section is placed at a non-zero
offset within its output section, the relocation
value within .eh_frame are computed incorrectly.

We had similar issue in .ARM.exidx section and it has been
fixed already in https://reviews.llvm.org/D148033.

While applying the relocation using S+A-P,  the value
 of P (the location of the relocation) is getting wrong. 
P is:
  P = SecAddr + rel.offset, But SecAddr points to the
starting address of the outputsection rather than the
starting address of the eh frame section within that
output section.

This issue affects all targets which generates .eh_frame 
section. Hence fixing in all the corresponding targets it affecting.
2023-10-03 10:20:14 +01:00
Fangrui Song
71d7e69c56 [ELF] Implement getImplicitAddend and enable checkDynamicRelocsDefault for Hexagon 2023-09-15 23:10:17 -07:00
Fangrui Song
df979228ef [ELF] Implement getImplicitAddend and enable checkDynamicRelocsDefault for AMDGPU 2023-09-15 22:59:08 -07:00
Fangrui Song
0cbe49eade [ELF] Implement getImplicitAddend and enable checkDynamicRelocsDefault for PPC32 2023-09-15 22:49:18 -07:00
Amy Kwan
698b45aa90 [PowerPC][lld] Account for additional X-Forms -> D-Form/DS-Forms load/stores when relaxing initial-exec to local-exec
D153645 added additional X-Form load/stores that can be generated for TLS accesses.
However, these added instructions have not been accounted for in lld. As a result,
lld does not know how to handle them and cannot relax initial-exec to local-exec
when the initial-exec sequence contains these additional load/stores.

This patch aims to resolve https://github.com/llvm/llvm-project/issues/64424.

Differential Revision: https://reviews.llvm.org/D158197
2023-08-31 08:45:10 -05:00
Weining Lu
8a31f7ddb8 [lld][LoongArch] Support the R_LARCH_PCREL20_S2 relocation type
`R_LARCH_PCREL20_S2` is a new added relocation type in LoongArch ELF
psABI v2.10 [1] which is not corvered by D138135 except `R_LARCH_64_PCREL`.

A motivation to support `R_LARCH_PCREL20_S2` in lld is to build the
runtime of .NET core (a.k.a `CoreCLR`) in which strict PC-relative
semantics need to be guaranteed [2]. The normal `pcalau12i + addi.d`
approach doesn't work because the code will be copied to other places
with different "page" and offsets. To achieve this, we can use `pcaddi`
with explicit `R_LARCH_PCREL20_S2` reloc to address +-2MB PC-relative
range with 4-bytes aligned.

[1]: https://github.com/loongson/la-abi-specs/releases/tag/v2.10
[2]: https://github.com/dotnet/runtime/blob/release/7.0/src/coreclr/vm/loongarch64/asmhelpers.S#L307

Reviewed By: xen0n, MaskRay

Differential Revision: https://reviews.llvm.org/D156772
2023-08-09 09:55:27 +08:00
Mitch Phillips
ca35a19aca [lld] Synthesize metadata for MTE globals
As per the ABI at
https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst,
this patch interprets the SHT_AARCH64_MEMTAG_GLOBALS_STATIC section,
which contains R_NONE relocations to tagged globals, and emits a
SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section, with the correct
DT_AARCH64_MEMTAG_GLOBALS and DT_AARCH64_MEMTAG_GLOBALSSZ dynamic
entries. This section describes, in a uleb-encoded stream, global memory
ranges that should be tagged with MTE.

We are also out of bits to spare in the LLD Symbol class. As a result,
I've reused the 'needsTocRestore' bit, which is a PPC64 only feature.
Now, it's also used for 'isTagged' on AArch64.

An entry in SHT_AARCH64_MEMTAG_GLOBALS_STATIC is practically a guarantee
from an objfile that all references to the linked symbol are through the
GOT, and meet correct alignment requirements. As a result, we go through
all symbols and make sure that, for all symbols $SYM, all object files
that reference $SYM also have a SHT_AARCH64_MEMTAG_GLOBALS_STATIC entry
for $SYM. If this isn't the case, we demote the symbol to being
untagged. Symbols that are imported from other DSOs should always be
fine, as they're GOT-referenced (and thus the GOT entry either has the
correct tag or not, depending on whether it's tagged in the defining DSO
or not).

Additionally hand-tested by building {libc, libm, libc++, libm, and libnetd}
on Android with some experimental MTE globals support in the
linker/libc.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D152921
2023-07-31 17:07:42 +02:00
WANG Xuerui
6084ee7420 [lld][ELF] Support LoongArch
This adds support for the LoongArch ELF psABI v2.00 [1] relocation
model to LLD. The deprecated stack-machine-based psABI v1 relocs are not
supported.

The code is tested by successfully bootstrapping a Gentoo/LoongArch
stage3, complete with common GNU userland tools and both the LLVM and
GNU toolchains (GNU toolchain is present only for building glibc,
LLVM+Clang+LLD are used for the rest). Large programs like QEMU are
tested to work as well.

[1]: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html

Reviewed By: MaskRay, SixWeining

Differential Revision: https://reviews.llvm.org/D138135
2023-07-25 17:06:07 +08:00
Amilendra Kodithuwakku
9acbab60e5 [LLD][ELF] Cortex-M Security Extensions (CMSE) Support
This commit provides linker support for Cortex-M Security Extensions (CMSE).
The specification for this feature can be found in ARM v8-M Security Extensions:
Requirements on Development Tools.

The linker synthesizes a security gateway veneer in a special section;
`.gnu.sgstubs`, when it finds non-local symbols `__acle_se_<entry>` and `<entry>`,
defined relative to the same text section and having the same address. The
address of `<entry>` is retargeted to the starting address of the
linker-synthesized security gateway veneer in section `.gnu.sgstubs`.

In summary, the linker translates input:

```
    .text
  entry:
  __acle_se_entry:
    [entry_code]

```
into:

```
    .section .gnu.sgstubs
  entry:
    SG
    B.W __acle_se_entry

    .text
  __acle_se_entry:
    [entry_code]
```

If addresses of `__acle_se_<entry>` and `<entry>` are not equal, the linker
considers that `<entry>` already defines a secure gateway veneer so does not
synthesize one.

If `--out-implib=<out.lib>` is specified, the linker writes the list of secure
gateway veneers into a CMSE import library `<out.lib>`. The CMSE import library
will have 3 sections: `.symtab`, `.strtab`, `.shstrtab`. For every secure gateway
veneer <entry> at address `<addr>`, `.symtab` contains a `SHN_ABS` symbol `<entry>` with
value `<addr>`.

If `--in-implib=<in.lib>` is specified, the linker reads the existing CMSE import
library `<in.lib>` and preserves the entry function addresses in the resulting
executable and new import library.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D139092
2023-07-06 11:34:07 +01:00
Daniel Kiss
92fbb602f3 [lld][AArch64] Add BTI landing pad to PLT entries when the symbol is exported.
With relative vtables the caller jumps directly to the plt entries in the shared object,
therefore landing pad is need for these entries.

Reproducer:
main.cpp
```
#include "v.hpp"
int main() {
    A* a = new B();
    a->do_something2();
    return 0;
}
```
v.hpp
```
struct A {
    virtual void do_something() = 0;
    virtual void do_something2();
};
struct B : public A {
    void do_something() override;
    void do_something2() override;
};
```
v.cpp
```
#include "v.hpp"
void A::do_something2() { }
void B::do_something() { }
void B::do_something2() { }
```
```
CC="clang++ --target=aarch64-unknown-linux-gnu -fuse-ld=lld -mbranch-protection=bti"
F=-fexperimental-relative-c++-abi-vtables
${=CC} $F -shared v.cpp -o v.so -z force-bti
${=CC} $F main.cpp -L./ v.so -Wl,-rpath=. -z force-bti
qemu-aarch64-static -L /usr/aarch64-linux-gnu -cpu max ./a.out
```
For v.so, the regular vtable entry is relocated by an R_AARCH64_ABS64 relocation referencing _ZN1B13do_something2Ev.
```
_ZTV1B:
.xword  _ZN1B13do_something2Ev
```
Using relative vtable entry for a DSO has a downside of creating many PLT entries and making their addresses escape.
The relative vtable entry references a PLT entry _ZN1B13do_something2Ev@plt.
```
.L_ZTV1A.local:
        .word   (_ZN1A13do_something2Ev@PLT-.L_ZTV1A.local)-8
```

fixes: #63580

Reviewed By: peter.smith, MaskRay

Differential Revision: https://reviews.llvm.org/D153264
2023-06-29 22:17:17 +02:00
John Brawn
5421ab4625 [lld][ARM] Add support for 16-bit thumb group relocations
This adds support for the following relocations:
 * R_ARM_THM_ALU_ABS_G0_NC
 * R_ARM_THM_ALU_ABS_G1_NC
 * R_ARM_THM_ALU_ABS_G2_NC
 * R_ARM_THM_ALU_ABS_G3
as defined in:
https://github.com/ARM-software/abi-aa/blob/main/aaelf32/aaelf32.rst#5615static-thumb16-relocations

Differential Revision: https://reviews.llvm.org/D153407
2023-06-23 13:43:04 +01:00
Simi Pallipurath
f146763e07 Revert "Revert "[lld][Arm] Big Endian - Byte invariant support.""
This reverts commit d8851384c6ac2a1cea15e05228dbde5f13654e23.

Reason: Applied the fix for the Asan buildbot failures.
2023-06-22 16:10:18 +01:00
Mitch Phillips
cd116e0460 Revert "Revert "Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support"""
This reverts commit 9246df7049b0bb83743f860caff4221413c63de2.

Reason: This patch broke the UBSan buildbots. See more information in
the original phabricator review: https://reviews.llvm.org/D139092
2023-06-22 14:33:57 +02:00
Amilendra Kodithuwakku
9246df7049 Revert "Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support""
This reverts commit a685ddf1d104b3ce9d53cf420521f5aaff429630.

This relands Arm CMSE support (D139092) and fixes the GCC build bot errors.
2023-06-21 22:27:13 +01:00
Amilendra Kodithuwakku
a685ddf1d1 Revert "[LLD][ELF] Cortex-M Security Extensions (CMSE) Support"
This reverts commit c4fea3905617af89d1ad87319893e250f5b72dd6.

I am reverting this for now until I figure out how to fix
the build bot errors and warnings.

Errors:
llvm-project/lld/ELF/Arch/ARM.cpp:1300:29: error: expected primary-expression before ‘>’ token
 osec->writeHeaderTo<ELFT>(++sHdrs);

Warnings:
llvm-project/lld/ELF/Arch/ARM.cpp:1306:31: warning: left operand of comma operator has no effect [-Wunused-value]
2023-06-21 16:13:44 +01:00
Amilendra Kodithuwakku
c4fea39056 [LLD][ELF] Cortex-M Security Extensions (CMSE) Support
This commit provides linker support for Cortex-M Security Extensions (CMSE).
The specification for this feature can be found in ARM v8-M Security Extensions:
Requirements on Development Tools.

The linker synthesizes a security gateway veneer in a special section;
`.gnu.sgstubs`, when it finds non-local symbols `__acle_se_<entry>` and `<entry>`,
defined relative to the same text section and having the same address. The
address of `<entry>` is retargeted to the starting address of the
linker-synthesized security gateway veneer in section `.gnu.sgstubs`.

In summary, the linker translates input:

```
    .text
  entry:
  __acle_se_entry:
    [entry_code]

```
into:

```
    .section .gnu.sgstubs
  entry:
    SG
    B.W __acle_se_entry

    .text
  __acle_se_entry:
    [entry_code]
```

If addresses of `__acle_se_<entry>` and `<entry>` are not equal, the linker
considers that `<entry>` already defines a secure gateway veneer so does not
synthesize one.

If `--out-implib=<out.lib>` is specified, the linker writes the list of secure
gateway veneers into a CMSE import library `<out.lib>`. The CMSE import library
will have 3 sections: `.symtab`, `.strtab`, `.shstrtab`. For every secure gateway
veneer <entry> at address `<addr>`, `.symtab` contains a `SHN_ABS` symbol `<entry>` with
value `<addr>`.

If `--in-implib=<in.lib>` is specified, the linker reads the existing CMSE import
library `<in.lib>` and preserves the entry function addresses in the resulting
executable and new import library.

Reviewed By: MaskRay, peter.smith

Differential Revision: https://reviews.llvm.org/D139092
2023-06-21 14:47:34 +01:00
Simi Pallipurath
d8851384c6 Revert "[lld][Arm] Big Endian - Byte invariant support."
This reverts commit 8cf8956897ce9bca3176c6339077b1ca17b27abc.
2023-06-20 17:27:44 +01:00
Simi Pallipurath
8cf8956897 [lld][Arm] Big Endian - Byte invariant support.
Arm has BE8 big endian configuration called a byte-invariant(every byte has the same address on little and big-endian systems).

When in BE8 mode:
  1. Instructions are big-endian in relocatable objects but
     little-endian in executables and shared objects.
  2. Data is big-endian.
  3. The data encoding of the ELF file is ELFDATA2MSB.

To support BE8 without an ABI break for relocatable objects,the linker takes on the responsibility of changing the endianness of instructions. At a high level the only difference between BE32 and BE8 in the linker is that for BE8:
  1. The linker sets the flag EF_ARM_BE8 in the ELF header.
  2. The linker endian reverses the instructions, but not data.

This patch adds BE8 big endian support for Arm. To endian reverse the instructions we'll need access to the mapping symbols. Code sections can contain a mix of Arm, Thumb and literal data. We need to endian reverse Arm instructions as words, Thumb instructions
as half-words and ignore literal data.The only way to find these transitions precisely is by using mapping symbols. The instruction reversal will need to take place after relocation. For Arm BE8 code sections (Section has SHF_EXECINSTR flag ) we inserted a step after relocation to endian reverse the instructions. The implementation strategy i have used here is to write all sections BE32  including SyntheticSections then endian reverse all code in InputSections via mapping symbols.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D150870
2023-06-20 14:08:21 +01:00
Fangrui Song
8634b43a03 [ELF][RISCV] --wrap=foo: Correctly update st_value(foo)
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
2023-05-31 07:19:44 -07:00
Roland McGrath
9d37ea95df [lld][RISCV] Handle relaxation reductions of more than 65536 bytes
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
2023-05-16 14:59:36 -07:00
Job Noorman
9fb5af5909 [lld][RISCV][NFC] Simplify symbol value calculation in relax
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
2023-05-04 09:08:52 +02:00
Vitaly Buka
90f0bf0b4d Revert "[NFC][LLD] Disambiguate RISCV and llvm::RISCV"
This reverts commit 176cc70abe8d85df9aae223e0b35ce65238c4333.
2023-04-29 19:20:41 -07:00
Vitaly Buka
176cc70abe [NFC][LLD] Disambiguate RISCV and llvm::RISCV
Build is broken after ee9cbe35.
2023-04-29 19:06:37 -07:00
Ben Shi
229fcad7fc [lld][ELF] Support relocations R_AVR_LO8_LDI_GS/R_AVR_HI8_LDI_GS
Relocations R_AVR_LO8_LDI_GS/R_AVR_HI8_LDI_GS (indirect calls
via function pointers) only cover range 128KiB. They are
equivalent to R_AVR_LO8_LDI_PM/R_AVR_HI8_LDI_PM within this
range.

But for function addresses beyond this range, GNU-ld emits
trampolines. And this patch implements corresponding thunks
for them in lld.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D147364
2023-04-28 11:42:06 +08:00
Daniel Kiss
60827df765 [lld][AArch64] Add BTI landing pad to PLT when it is accessed by a range extension thunk.
Adding BTI to those PLT's which accessed with by a range extension thunk due to those preform an indirect call.
Fixes: #62140

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D148704
2023-04-23 23:17:02 +02:00
Craig Topper
85444794cd [lld][RISCV] Implement GP relaxation for R_RISCV_HI20/R_RISCV_LO12_I/R_RISCV_LO12_S.
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
2023-04-13 10:52:15 -07:00
Simi Pallipurath
2f68ddc604 [lld][ARM][2/3]Big Endian support - Word invariant support
Changes:
 - Adding BE32 big endian Support for Arm.
 - Replace the writele and readle with their endian-aware versions.
 - Adding test cases for the big-endian be32 arm configuration.

     Patch by: Milosz Plichta. This patch merges all the changes from
     this patch https://reviews.llvm.org/D140203 as well.

Reviewed By: peter.smith, MaskRay

Differential Revision: https://reviews.llvm.org/D140202
2023-03-29 10:21:00 +01:00
Ben Shi
504df554d2 [lld][ELF] Support relocations R_AVR_8_LO8/R_AVR_8_HI8/R_AVR_8_HLO8
Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D147100
2023-03-29 10:33:47 +08:00
Alex Bradbury
ff93c9beef [lld][RISCV] Avoid error when encountering unrecognised ISA extensions/versions in RISC-V attributes
This patch follows on from this RFC thread
<https://discourse.llvm.org/t/rfc-resolving-issues-related-to-extension-versioning-in-risc-v/68472/>
and the ensuing discussion in the RISC-V LLVM sync-up call. The
consensus agreed that the behaviour change in LLD introduced in D138550
that results in object files including arch attributes with unrecognised
extensions or versions of extensions is a regression and should be
treated as such. As it stands, this logic means that LLD will error out
if trying to link a RISC-V object file from LLVM HEAD (rv32i2p0/rv64i2p0)
with one from current GCC (rv32i2p1/rv64i2p1 by default).

There's a bigger discussion about exactly when to warn vs error and so
on, and how to control that, and this patch doesn't attempt to address
all those questions. It simply tries to fix the problem with a minimally
invasive change, intended to be cherry-picked for 16.0.x (ideally
16.0.0, but queued for 16.0.1 if we're too late in the release cycle).

As you can see from the test changes, although the changed logic is
mostly more permissive, it will reject some embedded arch strings that
were accepted before. Because the same logic was previously used for
parsing human-written -march as for the arch attribute (intended to be
stored in normalised form), various short-hand formats were previously
accepted. Maintaining support for such ill-formed attributes would
substantially complicate the logic, and given the previous
implementation was so much stricter in every other way, was surely a bug
rather than a design choice.

Surprisingly, the precise rules for how numbers can be embedded into
extension names isn't fully defined (there is a PR to the ISA manual
that is not yet merged
<https://github.com/riscv/riscv-isa-manual/pull/718>).
In the absence of specific criteria for rejecting extensions names that
would be ambiguous in abbreviated form,
`RISCVISAInfo::parseArchStringNormalized` just pulls out the version
information from the end of each extension description.

Differential Revision: https://reviews.llvm.org/D144353
2023-02-25 06:17:50 +00:00
Leonard Chan
4f0aa2517d [lld][RISCV] Introduce handling for R_RISCV_PLT32 relocation
This introduces R_RISCV_PLT32, a PC-relative data relocation that takes
the 32-bit relative offset to a function or its PLT entry.

This is needed to support relative vtables on RISCV.

Github PR: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/363

D143226 has the llvm parts.

Differential Revision: https://reviews.llvm.org/D143115
2023-02-23 22:05:52 +00:00
Simi Pallipurath
674f094d85 [lld][ARM][NFCI][1/3]Big Endian support - Removing assumptions
Change:
 - Replacing the memcpy that assume little endian with the endian-aware write.

Shouldn't affect the output for now, just a prerequisite for the next patches.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D140201
2023-02-15 11:42:49 +00:00