751 Commits

Author SHA1 Message Date
Fangrui Song
46d29d43ba
[ELF] Remove unused handleTlsRelocation (#184951)
Now that all targets use target-specific relocation scanning for TLS
(#181332 RISC-V being the last), handleTlsRelocation is unused.
2026-03-06 05:53:28 +00:00
Fangrui Song
4ea72c1e8c
[ELF] Add target-specific relocation scanning for RISC-V (#181332)
Implement RISCV::scanSectionImpl, following the pattern established
for x86 (#178846) and AArch64 (#181099). This merges the getRelExpr
and TLS handling for SHF_ALLOC sections into the target-specific
scanner, enabling devirtualization and eliminating abstraction
overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic rs.scan() path.
- Use processR_PC/processR_PLT_PC for common PC-relative and PLT
  relocations.
- Handle TLS IE and GD directly (RISC-V does not optimize GD/LD/IE).
- Replace TLS-optimization-specific expressions for TLSDESC, following
  the x86 pattern: R_RELAX_TLS_GD_TO_IE -> R_GOT_PC,
  R_RELAX_TLS_GD_TO_LE -> R_TPREL. Update relocateAlloc and relax()
  to dispatch on relocation type instead of RelExpr for TLSDESC.
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc and preprocessRelocs.
- Remove RISC-V-specific checks from handleTlsRelocation (isRISCV
  variable, TLSDESC label special cases).
- Move R_RISCV_VENDOR handling into the relocation type switch. An
  undefined vendor symbol now gets the standard undefined symbol error
  instead of a vendor-specific diagnostic.
2026-03-06 04:08:40 +00:00
Fangrui Song
cd01e6526a
[ELF] Add target-specific relocation scanning for LoongArch (#182236)
Implement LoongArch::scanSectionImpl, following the pattern established
for x86, PPC64, SystemZ, AArch64. This merges the getRelExpr and TLS
handling for SHF_ALLOC sections into the target-specific scanner,
enabling devirtualization and eliminating abstraction overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic rs.scan() path.
- Use processR_PC/processR_PLT_PC for common PC-relative and PLT
  relocations.
- Inline TLS handling: IE->LE optimization for _PC_ variants only (not
  _PCADD_ or absolute), TLSDESC->IE/LE for non-extreme code model,
  GD/LD flag setting without going through generic handleTlsRelocation.
- Remove adjustTlsExpr by inlining its logic into scanSectionImpl.
- Remove LoongArch-specific code from Relocations.cpp:
  handleTlsRelocation, execOptimizeInLoongArch, and the sort condition.
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc, scanEhSection, and the extreme code model fallback
  in relocateAlloc.
2026-03-03 22:22:55 -08:00
Fangrui Song
c04b00de75
[ELF] Add target-specific relocation scanning for ARM (#182440)
Implement ARM::scanSectionImpl, following the pattern established for
AArch64 and other targets. This merges the getRelExpr and TLS handling
for SHF_ALLOC sections into the target-specific scanner, enabling
devirtualization and eliminating abstraction overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic rs.scan() path.
- Use processR_PC/processR_PLT_PC for common PC-relative and PLT
  relocations.
- Handle TLS inline: checkTlsLe for TLS LE, handleTlsIe<false> for
  TLS IE (no IE-to-LE optimization for ARM), and direct flag/reloc
  emission for TLS GD/LD (no GD/LD optimization for ARM).
- Set hasGotOffRel for R_GOTREL/R_GOTONLY_PC relocations.
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc and preprocessRelocs.
2026-02-22 00:42:09 +00:00
Fangrui Song
371e0e2082
[ELF] Add target-specific relocation scanning for AArch64 (#181099)
Implement AArch64::scanSectionImpl, following the pattern established
for x86 (#178846), PPC64 (#181496), and SystemZ (#181563). This merges
the getRelExpr and TLS handling for SHF_ALLOC sections into the
target-specific scanner, enabling devirtualization and eliminating
abstraction overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic rs.scan() path.
- Use processR_PC/processR_PLT_PC for common PC-relative and PLT
  relocations, and handleTlsIe/handleTlsDesc for TLS IE/TLSDESC.
- Remove some AArch64-specific RelExpr members (RE_AARCH64_AUTH_GOT,
  RE_AARCH64_AUTH_GOT_PC, RE_AARCH64_AUTH_GOT_PAGE_PC,
  RE_AARCH64_AUTH_TLSDESC_PAGE, RE_AARCH64_AUTH_TLSDESC,
  RE_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC) by using regular RelExpr
  members with flag-based dispatch (NEEDS_GOT_AUTH, NEEDS_TLSDESC_AUTH).
AUTH GOT relocations now call `sym.setFlags(NEEDS_GOT | NEEDS_GOT_AUTH)`
  and `rs.processAux` directly.
- Remove adjustTlsExpr and handleAArch64PAuthTlsRelocation by inlining
  their logic into scanSectionImpl and relocateAlloc.
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc and EhInputSection::preprocessRelocs.
2026-02-18 05:47:33 +00:00
Fangrui Song
6d91695530
[ELF] Add target-specific relocation scanning for Hexagon (#181596)
Implement Hexagon::scanSectionImpl, following the pattern established
for x86 (#178846) and PPC64. This merges the getRelExpr and TLS handling
for
SHF_ALLOC sections into the target-specific scanner, enabling
devirtualization and eliminating abstraction overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic rs.scan() path.
- Use processR_PC/processR_PLT_PC for common PC-relative and PLT
  relocations.
- Handle GD PLT relocations inline, always setting NEEDS_PLT. Remove
  the R_HEX_GD_PLT special case from process().
- Handle TLS IE, GD GOT, and TPREL directly, bypassing
  handleTlsRelocation. Remove EM_HEXAGON from the execOptimize check.
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc and scanEhSection.
2026-02-16 22:20:43 +00:00
Fangrui Song
aec1c98426
[ELF] Add target-specific relocation scanning for SystemZ (#181563)
Implement SystemZ::scanSectionImpl, following the pattern established
for x86 (#178846) and PPC64 (#181496). This merges the getRelExpr and
TLS handling for SHF_ALLOC sections into the target-specific scanner,
enabling devirtualization and eliminating abstraction overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic `rs.scan()` path.
- Use processR_PC/processR_PLT_PC for common PC-relative and PLT
  relocations.
- Handle TLS GD, LD, and DTPREL directly, eliminating
  handleTlsRelocation, getTlsGdRelaxSkip, and adjustTlsExpr overrides.
  Replace R_RELAX_TLS_GD_TO_IE_GOT_OFF with R_GOT_OFF and
  R_RELAX_TLS_GD_TO_LE/R_RELAX_TLS_LD_TO_LE with R_TPREL, using
  type-based dispatch in relocate() for marker relocation types.
- Handle TLS IE inline without IE-to-LE optimization. Cannot use
  `handleTlsIe`.
- Remove `sortRels`: instead of sorting relocations to process GDCALL
  before PLT32DBL, skip PLT32DBL by peeking ahead at the next
  relocation to check for a TLS marker (GDCALL/LDCALL).
  This fixes SHT_CREL as an alternative to #149640
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc and .eh_frame.

Fix #149511
2026-02-16 20:10:37 +00:00
Fangrui Song
5a0261c553 [ELF] Defer ctx.hasTlsIe assignment to postScanRelocations. NFC
Move ctx.hasTlsIe stores from the relocation scan phase to
postScanRelocations. The ctx.hasTlsIe value is ignored for
`!shared` case, so we can remove some redundant assignment.
2026-02-15 18:20:51 -08:00
Fangrui Song
5e87f8147d
[ELF] Add target-specific relocation scanning for PPC32 (#181517)
Implement PPC::scanSectionImpl, following the pattern established for
x86 (#178846) and PPC64 (#181496). This merges the getRelExpr and TLS
handling for SHF_ALLOC sections into the target-specific scanner,
enabling devirtualization and eliminating abstraction overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic rs.scan() path.
- Use processR_PC/processR_PLT_PC for common PC-relative and PLT
  relocations.
- Handle R_PPC_PLTREL24 inline with addend masking via processAux,
  removing the EM_PPC special case from process().
- Handle TLS GD/LD/IE directly, eliminating handleTlsRelocation,
  getTlsGdRelaxSkip, and adjustTlsExpr overrides. Use handleTlsIe
  for TLS IE, and handleTlsGd for R_PPC_GOT_TLSGD16.
- Use R_DTPREL unconditionally for DTPREL relocations, removing
  R_RELAX_TLS_LD_TO_LE_ABS (PPC32 was the only user).
- Move TLS relaxation dispatch from relocateAlloc into relocate,
  removing the relocateAlloc override.
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc and .eh_frame.
2026-02-15 01:13:35 +00:00
Fangrui Song
aecc4997bf
[ELF] Add target-specific relocation scanning for PPC64 (#181496)
Implement PPC64::scanSectionImpl, following the pattern established for
x86. This merges the getRelExpr and TLS handling for SHF_ALLOC sections
into the target-specific scanner, enabling devirtualization and
eliminating abstraction overhead.

- Inline relocation classification into scanSectionImpl with a switch
  on relocation type, replacing the generic rs.scan() path.
- Use processR_PC/processR_PLT_PC for common PC-relative and PLT
  relocations.
- Handle TLS GD, LD, and DTPREL directly, eliminating
  handleTlsRelocation, getTlsGdRelaxSkip, and adjustTlsExpr overrides.
  Use handleTlsIe for TLS IE, enabling IE-to-LE optimization even when
  ppc64DisableTLSRelax is set (lifted a limitation from
  the workaround patch https://reviews.llvm.org/D92959).
- Use processAux for R_PPC64_PCREL_OPT. Remove the PPC64-specific
  special case from process().
- Replace RE_PPC64_RELAX_GOT_PC with R_RELAX_GOT_PC, which computes
  the same value (sym + addend - PC).
- Replace RE_PPC64_RELAX_TOC with R_GOTREL, moving the
  ctx.arg.tocOptimize check to relocateAlloc.
- Switch relocateAlloc from expr-based to type-based dispatch.
- Simplify getRelExpr to only handle relocations needed by
  relocateNonAlloc.
2026-02-14 19:25:51 +00:00
Fangrui Song
4b88753338 [ELF] Add target-specific relocation scanning for x86 (#178846)
Implement scanSection/scanSectionImpl for i386 and x86-64 to

* enable devirtualization of getRelExpr calls
* eliminate abstraction overhead for PLT-to-PCRel optimization, TLS
relocations
* optimize for R_X86_64_PC32 and R_X86_64_PLT32: they consist of 95%
  relocations in `lld/ELF/**/*.o` files.
* enable future optimization to remove `loc` from `getRelExpr` (only
  used by X86.cpp `R_386_GOT32[X]`)

at the cost of more boilerplate.

TLS relocation handling is inlined into scanSectionImpl. Also,

- Remove getTlsGdRelaxSkip
- Replace TLS-optimization-specific expressions:
- R_RELAX_TLS_GD_TO_LE, R_RELAX_TLS_LD_TO_LE, R_RELAX_TLS_IE_TO_LE →
R_TPREL
  - R_RELAX_TLS_GD_TO_IE → R_GOT_PC

This follows the pattern established for MIPS and PPC64 in `#163138`.

getRelExpr is simplified to only handle relocations needed for
relocateNonAlloc and relocateEH.

Average "Scan relocations" time (measured by --time-trace) decreases
from 110078 to 101585.

(
```
ruby -rjson -e 't=[]; 50.times { system("numactl -C 0-7 /t/lld1 -flavor gnu --threads=8 @response.txt -o a.out --time-trace"); t << JSON.parse(File.read("a.out.time-trace"))["traceEvents"].find { |e| e["name"] == "Scan relocations" }["dur"] }; puts "Average: #{t.sum / t.size}"'
```
)
2026-02-12 22:10:13 -08:00
Andrew Lazarev
685507d9be
Revert "[ELF] Add target-specific relocation scanning for x86" (#181274)
Reverts llvm/llvm-project#178846

Brakes buildbot:
https://lab.llvm.org/buildbot/#/builders/25/builds/15566
2026-02-12 20:03:17 -08:00
Fangrui Song
8a3b830c94
[ELF] Add target-specific relocation scanning for x86 (#178846)
Implement scanSection/scanSectionImpl for i386 and x86-64 to

* enable devirtualization of getRelExpr calls
* eliminate abstraction overhead for PLT-to-PCRel optimization, TLS
relocations
* optimize for R_X86_64_PC32 and R_X86_64_PLT32: they consist of 95%
  relocations in `lld/ELF/**/*.o` files.

at the cost of more code.

TLS relocation handling is inlined into scanSectionImpl. Also,

- Remove getTlsGdRelaxSkip
- Replace TLS-optimization-specific expressions:
- R_RELAX_TLS_GD_TO_LE, R_RELAX_TLS_LD_TO_LE, R_RELAX_TLS_IE_TO_LE →
R_TPREL
  - R_RELAX_TLS_GD_TO_IE → R_GOT_PC

This follows the pattern established for MIPS and PPC64 in `#163138`.

getRelExpr is simplified to only handle relocations needed for
relocateNonAlloc and relocateEH.

Average "Scan relocations" time (measured by --time-trace) decreases
from 110078 to 101585.

(
```
ruby -rjson -e 't=[]; 50.times { system("numactl -C 0-7 /t/lld1 -flavor gnu --threads=8 @response.txt -o a.out --time-trace"); t << JSON.parse(File.read("a.out.time-trace"))["traceEvents"].find { |e| e["name"] == "Scan relocations" }["dur"] }; puts "Average: #{t.sum / t.size}"'
```
)
2026-02-11 21:04:09 -08:00
Jessica Clarke
fbcfbd9d3a [NFC][ELF] Fix overzealous find/replace affecting comments
Commit a94060ca0c87 ("[ELF] Pass Ctx & to Relocations") swapped the
InputSectionBase &c argument for an InputSectionBase *sec member, and so
"c." was replaced with "sec->". However, this must have done in such a
way that "Local-Exec." was transformed to "Local-Exesec->" and
"RISCV::relocateAlloc." to "RISCV::relocateAllosec->", i.e. without the
use of something like clangd, and without appropriate word boundaries in
a regex.
2026-02-09 14:35:50 +00:00
Fangrui Song
bc45ea2c4f
[ELF] Fix IRELATIVE addend if the resolver address is updated by linker relaxation (#179063)
For a non-preemptible ifunc, `handleNonPreemptibleIfunc` creates a
cloned
symbol (`directSym`) to compute the addend of the IRELATIVE dynamic
relocation.
This cloned symbol wasn't tracked by `initSymbolAnchors`, so its value
wasn't adjusted during RISC-V/LoongArch linker relaxation.
This caused IRELATIVE addends to point to pre-relaxation addresses.

Fix this by:

- Tracking cloned IRELATIVE symbols in `ctx.irelativeSyms`
- Adding these symbols to `relaxAux->anchors` in `initSymbolAnchors`
2026-01-31 21:51:03 +00:00
Jessica Clarke
85236008ea
[NFCI][ELF][AArch64][PAC] Teach addRelativeReloc to emit R_AARCH64_AUTH_RELATIVE
This allows R_AARCH64_AUTH_ABS64 to follow R_AARCH64_ABS64's flow rather
than being implemented on the side in the place that is normally for
symbolic relocations.

Note that this has one implementation change: the RelExpr passed to
relaDyn is now RE_AARCH64_AUTH rather than R_ABS, but the two are
handled identically by InputSectionbase::getRelocTargetVA, and it was
inconsistent with relrAuthDyn which was passed RE_AARCH64_AUTH.

Reviewers: kovdan01

Pull Request: https://github.com/llvm/llvm-project/pull/171180
2026-01-31 18:09:27 +00:00
Jessica Clarke
859d3b8e9c
[ELF][AArch64][PAC][MTE] Handle Memtag globals for R_AARCH64_AUTH_ABS64
Currently, R_AARCH64_AUTH_ABS64 against a tagged global just ignores the
tagging and so, if out of the symbol's bounds, does not write the
negated original addend for the loader to determine which granule's tag
to use for it. Handle the composition of the two.

Note that R_AARCH64_AUTH_ABS64/RELATIVE encode the signing schema in the
upper 32 bits of the value at the relocation target, and so only the
lower 32 bits are available for use as an addend, including for Memtag's
disambiguation, and so if a wildly out-of-bounds PAuth relocation
against a tagged global is used we have no choice but to error out with
the current ABI.

Reviewers: MaskRay, kovdan01, smithp35, asl

Reviewed By: smithp35

Pull Request: https://github.com/llvm/llvm-project/pull/173291
2026-01-31 18:06:31 +00:00
Fangrui Song
55e1d3ab7e [ELF] Rename isAbsoluteValue for clarity. NFC
and fix a stale comment.
2026-01-29 23:42:42 -08:00
Fangrui Song
6bba170a26 [ELF] Remove unneeded -z ifunc-noplt check. NFC
The `isIfunc && zIfuncNoplt` code path does not use the RelExpr, so we
don't need to adjust it.
2026-01-29 20:35:15 -08:00
hev
019bf03697
[lld][LoongArch] Support reloc types for LA32R/LA32S (#172618)
This patch adds support for processing the relocation types introduced
in la-abi-specs v2.50.

Link: https://github.com/loongson/la-abi-specs/pull/16
Link:
https://sourceware.org/pipermail/binutils/2025-December/146091.html
2026-01-15 19:54:52 +08:00
Tarcísio Fischer
e91447f44d
Fix lld crash using --fix-cortex-a53-843419 (#170495)
Original crash was observed in Chromium, in [1]. The problem occurs in
elf::isAArch64BTILandingPad because it didn't handle synthetic sections,
which can have a nullptr as a buf, so it crashed while trying to read
that buf.

After fixing that, a second issue occurs: When the patched code grows
too
much, it gets far away from the short jump, and the current
implementation
assumes a R_AARCH64_JUMP26 will be enough.

This PR changes the implementation to:
(a) In isAArch64BTILandingPad, checks if a section is synthetic, and
assumes that it'll NOT contain a landing pad, avoiding the buffer check;
(b) Suppress the size rounding for thunks that preceeds section
(Making the situation less likely to happen);
(c) Reimplements the patch by using a R_AARCH64_ABS64 in case the
patched code is still far away.

[1] https://issues.chromium.org/issues/440019454

---------

Co-authored-by: Tarcisio Fischer <tarcisio.fischer@arm.com>
2026-01-09 11:08:09 +00:00
Jessica Clarke
6edfda1693
[NFC][ELF][AArch64][MTE] Don't duplicate addRelativeReloc call for MTE globals
This call to addRelativeReloc is the same as the one at the end of the
function, so skip the relrDyn code for this case and add the special
out-of-bounds handling code to the end of the function. This makes it
obvious where MTE globals differ in behaviour rather than having to
compare the two different implementations.

This also adds a comment documenting why relrDyn isn't used, and in it
highlights that it's probably safe to use relrDyn so long as the offset
is within the symbol's bounds.

Reviewers: pcc, kovdan01, MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/171181
2025-12-24 11:00:36 +00:00
Jessica Clarke
67727a6eeb
[NFC][ELF] Abstract RelrBaseSection more like RelocationBaseSection
This makes addRelativeReloc a bit more readable and uniform, as well as
the relrAuthDyn call in RelocScan::process.

Reviewers: MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/171178
2025-12-24 10:58:21 +00:00
Jessica Clarke
7e9f52c2bb
[NFC][ELF] Use InputSectionBase::addReloc in addRelativeReloc
There's no need to poke into the internals, we can just use the more
abstract member function like everywhere else in LLD.

Reviewers: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/171176
2025-12-24 10:57:47 +00:00
Jessica Clarke
669c755d1f
[NFC][ELF][AArch64][MTE] Replace addend hack with less-confusing code
The current implementation in addRelativeReloc makes it look like we're
writing the symbol's VA + addend to the section, because that's what the
given relocation will evaluate to, but we're supposed to be writing the
negated original addend (since the relative relocation's addend will be
the sum of the symbol's VA and the original addend). This only works
because deep down in AArch64::relocate we throw away the computed value
and peek back inside the relocation to extract the addend and negate it.

Do this properly by having a relocation that evaluates to the right
value instead.

Reviewers: kovdan01, MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/171182
2025-12-22 16:19:50 +00:00
Jessica Clarke
79d9cf8944
[NFC][ELF][AArch64][PAC] Use existing addSymbolReloc for R_AARCH64_AUTH_ABS64
The only difference between these calls is whether rel or type is passed
as the first argument, but AArch64::getDynRel returns type unchanged for
R_AARCH64_AUTH_ABS64, so they are the same.

Reviewers: MaskRay, kovdan01

Pull Request: https://github.com/llvm/llvm-project/pull/171179
2025-12-22 16:18:11 +00:00
Jessica Clarke
4afc92e43a
[NFC][ELF] Remove pointless NEEDS_TLSGD_TO_IE (#171046)
NEEDS_TLSGD_TO_IE is only ever set when the symbol is preeptible, in
which case addTpOffsetGotEntry will just add the symbol to the GOT and
emit a symbolic tlsGotRel anyway, so there is no need to give it its own
special case.

As well as simplifying the code upstream, this is useful downstream for
Morello, which doesn't really have a proper GD/IE-to-LE relaxation, and
so for GD-to-IE can benefit from being able to use the optimisations
addTpOffsetGotEntry has for non-preemptible symbols, rather than having
to reimplement them here.
2025-12-09 15:26:09 +00:00
Peter Collingbourne
13e09ebe2d
ELF: Add support for relocating R_AARCH64_FUNCINIT64.
R_AARCH64_FUNCINIT64 is a dynamic relocation type for relocating
word-sized data in the output file using the return value of
a function. An R_AARCH64_FUNCINIT64 shall be relocated as an
R_AARCH64_IRELATIVE with the target symbol address if the target
symbol is non-preemptible, and it shall be a usage error to relocate an
R_AARCH64_FUNCINIT64 with a preemptible or STT_GNU_IFUNC target symbol.

The initial use case for this relocation type shall be for emitting
global variable field initializers for structure protection. With
structure protection, the relocation value computation is tied to the
compiler implementation in such a way that it would not be reasonable to
define a relocation type for it (for example, it may involve computing
a hash using a compiler-determined algorithm), hence the need for the
computation to be implemented as code in the binary.

Part of the AArch64 psABI extension:
https://github.com/ARM-software/abi-aa/issues/340

Reviewers: smithp35, fmayer, MaskRay

Reviewed By: fmayer

Pull Request: https://github.com/llvm/llvm-project/pull/156564
2025-11-19 11:44:09 -08:00
Fangrui Song
22bf331933
[ELF] Refactor RelocScan::scan to be target-specific (#163138)
- Extract RelocScan to RelocScan.h. The file includes Target.h, and
cannot be merged with Relocations.h
- Add MIPS and PPC64 specific relocation scanners, removing runtime
checks for other targets.

This refactoring prepares the codebase for better target-specific
optimizations and easier addition of target-specific behavior.
2025-10-13 23:32:34 -07:00
Fangrui Song
3554c78d97
ELF: Use preprocessed relocations for EhInputSection scanning
.eh_frame sections require special sub-section processing, specifically,
CIEs are de-duplicated and FDEs are garbage collected. Create a
specialized scanEhSection() function utilizing the just-added
EhInputSection::rels. OffsetGetter is moved to scanEhSection.

This improves separation of concerns between InputSection and
EhInputSection processing.

This removes another `relsOrRelas` call using `supportsCrel=false`.
DWARF.cpp now has the last call.

Pull Request: https://github.com/llvm/llvm-project/pull/161091
2025-09-29 20:39:49 -07:00
Fangrui Song
2f9ae0b603
ELF: Rename Relocations.cpp functions and rewrite the file-level comment. NFC
Pull Request: https://github.com/llvm/llvm-project/pull/161229
2025-09-29 20:33:41 -07:00
Fangrui Song
fd5d7c5048
ELF: Split relocateAlloc to relocateAlloc and relocateEh. NFC
relocateAlloc can be called with either InputSection (including
SyntheticSection like GotSection) or EhInputSection.

Introduce relocateEh so that we can remove some boilerplate and replace
relocateAlloc's parameter type with `InputSection`.

Pull Request: https://github.com/llvm/llvm-project/pull/160031
2025-09-22 09:08:12 -07:00
Kazu Hirata
4831d92005
[lld] Replace SmallSet with SmallPtrSet (NFC) (#154263)
This patch replaces SmallSet<T *, N> with SmallPtrSet<T *, N>.  Note
that SmallSet.h "redirects" SmallSet to SmallPtrSet for pointer
element types:

  template <typename PointeeType, unsigned N>
class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N>
{};

We only have 30 instances that rely on this "redirection".  Since the
redirection doesn't improve readability, this patch replaces SmallSet
with SmallPtrSet for pointer element types.

I'm planning to remove the redirection eventually.
2025-08-18 22:39:45 -07:00
Peter Collingbourne
53c41f19e3
ELF: Add support for R_AARCH64_PATCHINST relocation type.
The R_AARCH64_PATCHINST relocation type is to support deactivation
symbols. For more information, see the RFC:
https://discourse.llvm.org/t/rfc-deactivation-symbols/85556

Part of the AArch64 psABI extension:
https://github.com/ARM-software/abi-aa/issues/340

Reviewers: smithp35, davemgreen, MaskRay

Reviewed By: MaskRay, davemgreen, smithp35

Pull Request: https://github.com/llvm/llvm-project/pull/133534
2025-08-11 11:33:08 -07:00
Jessica Clarke
723b40a8d9 [ELF][Hexagon] Fix host endianness assumption
Fixes: b42f96bc057f ("[lld] Add thunks for hexagon (#111217)")
2025-08-03 21:30:17 +01:00
Jessica Clarke
de15d36574 [NFC][ELF][Hexagon] Avoid pointless ArrayRef::drop_front
Fixes: b42f96bc057f ("[lld] Add thunks for hexagon (#111217)")
2025-08-03 21:30:17 +01:00
Jessica Clarke
b03d1e1e2e [NFC][ELF] Add missing blank line between functions
Fixes: b42f96bc057f ("[lld] Add thunks for hexagon (#111217)")
2025-08-03 21:30:16 +01:00
Jessica Clarke
52ddcfd8d6
[NFC][ELF] Replace DynamicReloc::Kind with the equivalent bool in APIs
DynamicReloc::AgainstSymbol is now true and DynamicReloc::AddendOnly is
now false; uses of the constants were replaced mechanically.

Reviewers: rnk, MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/150813
2025-07-30 17:08:36 +01:00
Jessica Clarke
54df4b8c35
[NFCI][ELF] Merge AgainstSymbol and AgainstSymbolWithTargetVA
The former is just a special case of the latter, ignoring the expr and
always just using the addend. If we use R_ADDEND as expr (which
previously had no effect, and so was misleadingly R_ABS not R_ADDEND in
all but one use) then we don't need to maintain this as a separate case.

Aside from the internal Computed Kind, this just leaves MipsMultiGotPage
as a special case; the only difference between the other two Kind values
is what needsDynSymIndex returns.

Reviewers: MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/150798
2025-07-30 17:06:59 +01:00
Jessica Clarke
e027b9258a
[NFCI][ELF] Merge AddendOnly and AddendOnlyWithTargetVA
The former is just a special case of the latter, ignoring the expr and
always just using the addend, allowing (and enforcing) the sym is null.
If we just use dummySym then we don't need to maintain this as a
separate case, since R_ADDEND will return the addend unmodified for the
call to getRelocTargetVA.

Reviewers: MaskRay, arichardson

Reviewed By: MaskRay, arichardson

Pull Request: https://github.com/llvm/llvm-project/pull/150797
2025-07-30 17:05:15 +01:00
Jessica Clarke
58e6bc87b7
[ELF] Add a dummySym member to Ctx
This ensures subsequent calls to elf::postScanRelocations with a new Ctx
will correctly use an instance with the right internalFile (with the old
one presumably deleted, even). It also avoids having to create a new
instance in elf::getErrorPlace, and will allow more uses of such a dummy
symbol in future commits.

Reviewers: MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/150796
2025-07-30 17:03:34 +01:00
Brian Cain
3e9ceae29f
[lld] [hexagon] guard allocateAux: only if idx nonzero (#149690)
While building libclang_rt.asan-hexagon.so, lld would assert in
lld:🧝:hexagonTLSSymbolUpdate().

Fixes #132766
2025-07-20 14:39:03 -05:00
Brian Cain
b42f96bc05
[lld] Add thunks for hexagon (#111217)
Without thunks, programs will encounter link errors complaining that the
branch target is out of range. Thunks will extend the range of branch
targets, which is a critical need for large programs. Thunks provide
this flexibility at a cost of some modest code size increase.

When configured with the maximal feature set, the hexagon port of the
linux kernel would often encounter these limitations when linking with
`lld`.

The relocations which will be extended by thunks are:

* R_HEX_B22_PCREL, R_HEX_{G,L}D_PLT_B22_PCREL, R_HEX_PLT_B22_PCREL
relocations have a range of ± 8MiB on the baseline
* R_HEX_B15_PCREL: ±65,532 bytes
* R_HEX_B13_PCREL: ±16,380 bytes
* R_HEX_B9_PCREL: ±1,020 bytes

Fixes #149689 

Co-authored-by: Alexey Karyakin <akaryaki@quicinc.com>

---------

Co-authored-by: Alexey Karyakin <akaryaki@quicinc.com>
2025-07-20 11:46:31 -05:00
Fangrui Song
3cb0c7f45b MC: Rework .reloc directive and fix the offset when it evaluates to a constant
* Fix `.reloc constant` to mean section_symbol+constant instead of
  .+constant . The initial .reloc support from MIPS incorrectly
  interpreted the offset.
* Delay the evaluation of the offset expression after
  MCAssembler::layout, deleting a lot of code working with MCFragment.
* Delete many FIXME from https://reviews.llvm.org/D79625
* Some lld/ELF/Arch/LoongArch.cpp relaxation tests rely on .reloc .,
  R_LARCH_ALIGN generating ALIGN relocations at specific location.
  Sort the relocations.
2025-07-17 00:36:11 -07:00
Zhaoxin Yang
2c1900860c
[lld][LoongArch] Support TLSDESC GD/LD to IE/LE (#123715)
Support TLSDESC to initial-exec or local-exec optimizations. Introduce a
new hook RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC and use existing
R_RELAX_TLS_GD_TO_IE_ABS to support TLSDESC => IE, while use existing
R_RELAX_TLS_GD_TO_LE to support TLSDESC => LE.
    
In normal or medium code model, there are two forms of code sequences:
* pcalau12i  $a0, %desc_pc_hi20(sym_desc)
* addi.d     $a0, $a0, %desc_pc_lo12(sym_desc)
* ld.d       $ra, $a0, %desc_ld(sym_desc)
* jirl       $ra, $ra, %desc_call(sym_desc)
------
* pcaddi     $a0, %desc_pcrel_20(sym_desc)
* ld.d       $ra, $a0, %desc_ld(sym_desc)
* jirl       $ra, $ra, %desc_call(sym_desc)
    
Convert to IE:
* pcalau12i $a0, %ie_pc_hi20(sym_ie)
* ld.[wd]   $a0, $a0, %ie_pc_lo12(sym_ie)

Convert to LE:
* lu12i.w $a0, %le_hi20(sym_le) # le_hi20 != 0, otherwise NOP
* ori $a0 src, %le_lo12(sym_le) # le_hi20 != 0, src = $a0, otherwise src = $zero

Simplicity, whether tlsdescToIe or tlsdescToLe, we always tend to
convert the preceding instructions to NOPs, due to both forms of code
sequence (corresponding to relocation combinations:
R_LARCH_TLS_DESC_PC_HI20+R_LARCH_TLS_DESC_PC_LO12 and
R_LARCH_TLS_DESC_PCREL20_S2) have same process.
    
TODO: When relaxation enables, redundant NOPs can be removed. It will be
implemented in a future patch.
    
Note: All forms of TLSDESC code sequences should not appear interleaved
in the normal, medium or extreme code model, which compilers do not
generate and lld is unsupported. This is thanks to the guard in
PostRASchedulerList.cpp in llvm.
```
Calls are not scheduling boundaries before register allocation,
but post-ra we don't gain anything by scheduling across calls
since we don't need to worry about register pressure.
```
2025-07-02 16:09:51 +08:00
Peter Collingbourne
494a74882b
Reapply "ELF: Add branch-to-branch optimization."
Fixed assertion failure when reading .eh_frame sections, and added
.eh_frame sections to tests.

This reverts commit 1e95349dbe329938d2962a78baa0ec421e9cd7d1.

Original commit message follows:

When code calls a function which then immediately tail calls another
function there is no need to go via the intermediate function. By
branching directly to the target function we reduce the program's working
set for a slight increase in runtime performance.

Normally it is relatively uncommon to have functions that just tail call
another function, but with LLVM control flow integrity we have jump tables
that replace the function itself as the canonical address. As a result,
when a function address is taken and called directly, for example after
a compiler optimization resolves the indirect call, or if code built
without control flow integrity calls the function, the call will go via
the jump table.

The impact of this optimization was measured using a large internal
Google benchmark. The results were as follows:

CFI enabled:  +0.1% ± 0.05% queries per second
CFI disabled: +0.01% queries per second [not statistically significant]

The optimization is enabled by default at -O2 but may also be enabled
or disabled individually with --{,no-}branch-to-branch.

This optimization is implemented for AArch64 and X86_64 only.

lld's runtime performance (real execution time) after adding this
optimization was measured using firefox-x64 from lld-speed-test [1]
with ldflags "-O2 -S" on an Apple M2 Ultra. The results are as follows:

```
    N           Min           Max        Median           Avg        Stddev
x 512     1.2264546     1.3481076     1.2970261     1.2965788   0.018620888
+ 512     1.2561196     1.3839965     1.3214632     1.3209327   0.019443971
Difference at 95.0% confidence
        0.0243538 +/- 0.00233202
        1.87831% +/- 0.179859%
        (Student's t, pooled s = 0.0190369)
```

[1] https://discourse.llvm.org/t/improving-the-reproducibility-of-linker-benchmarking/86057

Reviewers: zmodem, MaskRay

Reviewed By: MaskRay

Pull Request: https://github.com/llvm/llvm-project/pull/145579
2025-06-24 22:16:18 -07:00
Hans Wennborg
1e95349dbe Revert "ELF: Add branch-to-branch optimization."
This caused assertion failures in applyBranchToBranchOpt():

  llvm/include/llvm/Support/Casting.h:578:
  decltype(auto) llvm::cast(From*)
  [with To = lld:🧝:InputSection; From = lld:🧝:InputSectionBase]:
  Assertion `isa<To>(Val) && "cast<Ty>() argument of incompatible type!"' failed.

See comment on the PR (https://github.com/llvm/llvm-project/pull/138366)

This reverts commit 491b82a5ec1add78d2c93370580a2f1897b6a364.

This also reverts the follow-up "[lld] Use llvm::partition_point (NFC) (#145209)"

This reverts commit 2ac293f5ac4cf65c0c038bf75a88f1d6715e467d.
2025-06-23 13:26:02 +02:00
Peter Collingbourne
491b82a5ec ELF: Add branch-to-branch optimization.
When code calls a function which then immediately tail calls another
function there is no need to go via the intermediate function. By
branching directly to the target function we reduce the program's working
set for a slight increase in runtime performance.

Normally it is relatively uncommon to have functions that just tail call
another function, but with LLVM control flow integrity we have jump tables
that replace the function itself as the canonical address. As a result,
when a function address is taken and called directly, for example after
a compiler optimization resolves the indirect call, or if code built
without control flow integrity calls the function, the call will go via
the jump table.

The impact of this optimization was measured using a large internal
Google benchmark. The results were as follows:

CFI enabled:  +0.1% ± 0.05% queries per second
CFI disabled: +0.01% queries per second [not statistically significant]

The optimization is enabled by default at -O2 but may also be enabled
or disabled individually with --{,no-}branch-to-branch.

This optimization is implemented for AArch64 and X86_64 only.

lld's runtime performance (real execution time) after adding this
optimization was measured using firefox-x64 from lld-speed-test [1]
with ldflags "-O2 -S" on an Apple M2 Ultra. The results are as follows:

```
    N           Min           Max        Median           Avg        Stddev
x 512     1.2264546     1.3481076     1.2970261     1.2965788   0.018620888
+ 512     1.2561196     1.3839965     1.3214632     1.3209327   0.019443971
Difference at 95.0% confidence
	0.0243538 +/- 0.00233202
	1.87831% +/- 0.179859%
	(Student's t, pooled s = 0.0190369)
```

[1] https://discourse.llvm.org/t/improving-the-reproducibility-of-linker-benchmarking/86057

Pull Request: https://github.com/llvm/llvm-project/pull/138366
2025-06-20 13:16:24 -07:00
Fangrui Song
2fcaa00d1e [ELF] -z undefs: handle relocations referencing undefined non-weak like undefined weak
* Merge the special case into isStaticLinkTimeConstant
* Generalize isUndefWeak to isUndefined. undefined non-weak is an error
  case. We choose to be general, which also brings us in line with GNU ld.
2025-06-11 20:37:15 -07:00
Alexander Ziaee
44a7ecd1d7
[doc] Use ISO nomenclature for 1024 byte units (#133148)
Increase specificity by using the correct unit sizes. KBytes is an
abbreviation for kB, 1000 bytes, and the hardware industry as well as
several operating systems have now switched to using 1000 byte kBs.

If this change is acceptable, sometimes GitHub mangles merges to use the
original email of the account. $dayjob asks contributions have my work
email. Thanks!
2025-06-11 13:27:23 +02:00