Rather then defining these tags in each object file that requires them
we can can declare them as undefined and require that they defined
externally in, for example, compiler-rt or libcxxabi.
Add `--print-gc-sections=<file>` to redirect garbage collection section
listing to a file, avoiding contamination of stdout with other linker
output. mold has recently added the option.
GNU ld feature request:
https://sourceware.org/bugzilla/show_bug.cgi?id=33331
Previously, `/summary` was meant to print some PDB information. Now move
handling of `/summary` to `Writer.cpp` so that it can have an effect
when `/debug` isn't provided. This will also provide grounds for
extending with more general information.
When a symbol is imported from a DLL, a base relocation record is
normally emitted.
However, if the import is pulled in via a wrapped symbol (using
`--wrap`) and later dropped because it is only referenced weakly, a
dangling base relocation remains in the output.
At runtime, this relocation changes the symbol value from null to a
garbage pointer.
This patch adds checks to avoid emitting relocation records for
non-`Defined` symbols, and to prevent creating an auto-import entry if
an import entry for the wrapped symbol already exists.
Fixes https://github.com/llvm/llvm-project/issues/150739
When `/summary` is used, we now also display the cumulative size of all
input OBJ files, including those pulled from archives. Lazy OBJ files
that were not pulled in are not accounted for.
Also added separators between digit groups, to make the output more
bearable.
Example output:
```
> lld-link ... /summary
Summary
--------------------------------------------------------------------------------
4,958 Input OBJ files (expanded from all cmd-line inputs)
46,715,790,512 Size of all consumed OBJ files (non-lazy), in bytes
42 PDB type server dependencies
0 Precomp OBJ dependencies
293,910,064 Input type records
16,931,361,928 Size of all input type records, in bytes
11,201,549 Merged TPI records
2,765,494 Merged IPI records
38,649 Output PDB strings
21,512,230 Global symbol records
82,380,837 Module symbol records
715,313 Public symbol records
```
I've skipped over the exact amounts for "Size of all consumed inputs
(non-lazy)" in the unit tests, since the sizes of OBJ files can
fluctuate between compilers.
_(this is a reopening of
https://github.com/llvm/llvm-project/pull/157279 which wasa committed by
mistake)_
Those are all MS link.exe compatible flags.
### CET (Control-flow Enforcement Technology) family
- Added LLD test that covers `/cetcompat[:no]`
- Added `/cetcompatstrict[:no]` flag in LLD/COFF
- Added `/cetipvalidationrelaxed[:no]` flag in LLD/COFF
- Added `/cetdynamicapisinproc[:no]` flag in LLD/COFF
### Misc
- Added `/hotpatchcompatible[:no]` flag in LLD/COFF
- This flag requires at least 6 bytes of function padding
(`/functionpadmin:#`) as per link.exe
When `/summary` is used, we now also display the cumulative size of all
input OBJ files, including those pulled from archives. Lazy OBJ files
that were not pulled in are not accounted for.
Also added separators between digit groups, to make the output more
bearable.
Example output:
```
> lld-link ... /summary
Summary
--------------------------------------------------------------------------------
4,958 Input OBJ files (expanded from all cmd-line inputs)
46,715,790,512 Size of all consumed OBJ files (non-lazy), in bytes
42 PDB type server dependencies
0 Precomp OBJ dependencies
293,910,064 Input type records
16,931,361,928 Size of all input type records, in bytes
11,201,549 Merged TPI records
2,765,494 Merged IPI records
38,649 Output PDB strings
21,512,230 Global symbol records
82,380,837 Module symbol records
715,313 Public symbol records
```
We skip over the exact amounts for "Size of all consumed inputs
(non-lazy)" in the unit tests, since the sizes of OBJ files can
fluctuate between compilers.
In order to better see what's going on during ThinLTO linking, this PR
adds more profile tags when using `--time-trace` on a `lld-link.exe`
invocation.
After PR, linking `clang.exe`:
<img width="3839" height="2026" alt="Capture d’écran 2025-09-02 082021"
src="https://github.com/user-attachments/assets/bf0c85ba-2f85-4bbf-a5c1-800039b56910"
/>
Linking a custom (Unreal Engine game) binary gives a completly
different picture, probably because of using Unity files, and the sheer
amount of input files (here, providing over 60 GB of .OBJs/.LIBs).
<img width="1940" height="1008" alt="Capture d’écran 2025-09-02 102048"
src="https://github.com/user-attachments/assets/60b28630-7995-45ce-9e8c-13f3cb5312e0"
/>
Previously, llvm-readelf dumped hex format values in different ways.
Some of them were printed in upper-case, while the others were in
lower-case format. This change switches the format to lower-case in all
cases.
Why is this useful? As an example, FileCheck comparisons are
case-sensitive by default. This change means it's easier to compare
those values, because they have the same format.
MS link.exe provides the `/sectionlayout:@` option to specify the order
of output sections at the granularity of individual sections. LLD/COFF
currently does not have capability for user-controlled ordering of one
or more output sections (as LLD/COFF does not support linker scripts),
and this PR adds the option to align with MS link.exe.
The option accepts only a file that specifies the order of sections, one
per line. For example, `mylayout.txt` could emit the `.text` section
after all other sections while preserving the original relative order of
the remaining sections.
```
.data
.rdata
.pdata
.rsrc
.reloc
.text
```
```bash
echo 'int main() { return 0; }' > main.c
cl main.c /link /entry:main /sectionlayout:@mylayout.txt
llvm-readobj --sections main.exe
```
This reverts commit 2b9328c788f60d70f8cf021c56fc6dfa080e1c32.
This was broken originally because echo -e does not work on MacOS. This
has been fixed by the previous commit which updates the relevant tests
to use printf.
Otherwise we break some MacOS bots when using the lit internal shell
because /bin/echo on MacOS does not support -e. Using the external shell
we end up using the echo builtin to /bin/bash, which does support this.
The echo builtin implementation in lit does support this, but that is
currently not enabled in pipelines. Might be worth looking into fixing
at some point.
This patch updates the lld lit test config to use the internal shell by
default. This has some performance advantages (~10-15%) and also
produces nicer failure output. This should have no impact on test
coverage now that all tests previously requiring a shell have been
ported over to work with the internal shell.
Fixes#102700.
Reviewers: MaskRay, petrhosek, cmtice, mysterymath, ilovepi
Reviewed By: MaskRay, petrhosek, cmtice
Pull Request: https://github.com/llvm/llvm-project/pull/156538
These tests were using subexpressions to change the cache size. Change
them up to write out the necessary commands to a response file and then
load that on the lld command line.
Towards #102700.
Reviewers: ilovepi, cmtice, mysterymath, MaskRay, petrhosek
Reviewed By: MaskRay
Pull Request: https://github.com/llvm/llvm-project/pull/156537
Subshells are not supported in the lit internal shell. We can remove
them by constructing sed commands directly inside of a separate file.
Towards #102700.
Reviewers: ilovepi, MaskRay, petrhosek, mysterymath, cmtice, kyulee-com
Reviewed By: MaskRay, cmtice, petrhosek
Pull Request: https://github.com/llvm/llvm-project/pull/156533
This patch updates two LLD tests that were redirecting multiple commands
to the same FileCheck invocation to not use this strategy. This
construction is not supported by lit's internal shell and given its
rarirty, it does not make sense to add support. The workaround is to
dump the contents of multiple commands into a file and then run
FileCheck on that.
Towards #102700.
Reviewers: petrhosek, mysterymath, cmtice, ilovepi, carlocab, MaskRay
Reviewed By: carlocab, cmtice
Pull Request: https://github.com/llvm/llvm-project/pull/156526
These tests all pass inside the lit internal shell. A couple were marked
as requiring a shell to exclude them on Windows. Update those tests to
explicitly carve out Windows rather than any configuration that does not
provide the shell feature.
Towards #102700.
Reviewers: petrhosek, cmtice, mysterymath, MaskRay, ilovepi
Reviewed By: cmtice
Pull Request: https://github.com/llvm/llvm-project/pull/156510
The parsing of the --read-workers argument v is implemented like this:
unsigned threads = 0
if (!llvm::to_integer(v, threads, 0) || threads < 0) {
...
As reported by a compiler warning, the value of the "threads < 0"
expession is never going to be true. It could only evaluate to true if v
represents a negative number, but in this case llvm::to_integer returns
false since threads is unsigned and hence the second operand of the ||
operator will not be evaluated.
This patch removes the useless || operand to silence compiler warnings.
Since I had to first find out if --read-workers=0 is valid or not (it is),
I also added a test to document the valid values for the option and I adjusted
the error message on invalid values to clearly state that 0 is valid.
If an export trie is encoded incorrectly, and one of the children
offsets points back to one of the nodes earlier in the serialization,
the current code will end up in an infinite recursion, and eventually
fail exhausting the available memory.
The failure can be avoided if, before recursing, one checks that the
offset is valid, that is, that the offset is beyond the current
position. This is similar to a check done by llvm-objdump which reports
the trie being corrupted.
Reland 9c994f5 after fixing ubsan bots failures.
This commit overrides `updateState` and `resetState` hooks in
`MCInstrAnalysis` in order to be able to analyze pcaddu18i+jirl pairs
inside `evaluateBranch`.
After this commit, `llvm-objdump` is able to correctly analyze and print
detailed information. `lld/test/ELF/loongarch-call36.s` shows the
changes.
Besides, this commit also teaches sancov to resolve such call sequences.
Without this commit, some tests in compiler-rt failed:
```
Failed Tests :
SanitizerCommon-asan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard-dso.cpp
SanitizerCommon-asan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard.cpp
SanitizerCommon-lsan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard-dso.cpp
SanitizerCommon-lsan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard.cpp
SanitizerCommon-msan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard-dso.cpp
SanitizerCommon-msan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard.cpp
```
The reason is that sancov could not resolve pcaddu18i+jirl call sequence
correctly and caused mismatches between coverage points in the binary
and the .sancov file:
```
ERROR: Coverage points in binary and .sancov file do not match.
```
NOTE: A similar issue might also occur on RISC-V when relaxation is
disabled (not verified). This commit can also fix for it.
This commit overrides `updateState` and `resetState` hooks in
`MCInstrAnalysis` in order to be able to analyze pcaddu18i+jirl pairs
inside `evaluateBranch`.
After this commit, `llvm-objdump` is able to correctly analyze and print
detailed information. `lld/test/ELF/loongarch-call36.s` shows the
changes.
Besides, this commit also teaches sancov to resolve such call sequences.
Without this commit, some tests in compiler-rt failed:
```
Failed Tests :
SanitizerCommon-asan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard-dso.cpp
SanitizerCommon-asan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard.cpp
SanitizerCommon-lsan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard-dso.cpp
SanitizerCommon-lsan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard.cpp
SanitizerCommon-msan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard-dso.cpp
SanitizerCommon-msan-loongarch64-Linux :: sanitizer_coverage_trace_pc_guard.cpp
```
The reason is that sancov could not resolve pcaddu18i+jirl call sequence
correctly and caused mismatches between coverage points in the binary
and the .sancov file:
```
ERROR: Coverage points in binary and .sancov file do not match.
```
NOTE: A similar issue might also occur on RISC-V when relaxation is
disabled (not verified). This commit can also fix for it.
This PR adds a new option to lld `--read-workers=20` that defers all
disk I/o then performs it multithreaded so the process is never stalled
waiting for the I/o of the page-in of mapped input files. This results
in a saving of elapsed time. For a large link (iterating on Chromium)
these are the baseline linkage times saving a single file and rebuilding
(seconds inside Xcode):
26.01, 25.84, 26.15, 26.03, 27.10, 25.90, 25.86, 25.81, 25.80, 25.87
With the proposed code change, and using the `--read-workers=20` option,
the linking times reduce to the following:
21.13, 20.35, 20.01, 20.01, 20.30, 20.39, 19.97, 20.23, 20.17, 20.23
The secret sauce is in the new function `multiThreadedPageIn()` in
Driver.cpp. Without the option lld behaves as before.
Edit: with subsequent commits I've taken this novel i/o approach to its
full potential. Latest linking times are now:
13.2, 11.9, 12.12, 12.01, 11.99, 13.11, 11.93, 11.95, 12.18, 11.97
Chrome is still linking and running so it doesn't look like anything is
broken. Despite being multi-threaded all memory access is readonly and
the original code paths are not changed. All that is happening is the
system is being asked to proactively page in files rather than waiting
for processing to page fault which would otherwise stall the process.
---------
Co-authored-by: Daniel Rodríguez Troitiño <drodrigueztroitino@gmail.com>
Co-authored-by: Ellis Hoag <ellis.sparky.hoag@gmail.com>
Similay to
94655dc8ae
The difference is that in LoongArch, the ALIGN is synthesized when the
alignment is >4, (instead of >=4), and the number of bytes inserted is
`sec->addralign - 4`.
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.
The script copies `ReleaseNotesTemplate.txt` to corresponding
`ReleaseNotes.rst`/`.md` to clear release notes.
The suffix of `ReleaseNotesTemplate.txt` must be `.txt`. If it is
`.rst`/`.md`, it will be treated as a documentation source file when
building documentation.
Clear `synthesizedAligns` to prevent stray relocations to an unrelated
text section. Enhance the test to check llvm-readelf -r output.
---
Without linker relaxation enabled for a particular relocatable file or
section (e.g., using .option norelax), the assembler will not generate
R_RISCV_ALIGN relocations for alignment directives. This becomes
problematic in a two-stage linking process:
```
ld -r a.o b.o -o ab.o
// b.o is norelax. Its alignment information is lost in ab.o.
ld ab.o -o ab
```
When ab.o is linked into an executable, the preceding relaxed section
(a.o's content) might shrink. Since there's no R_RISCV_ALIGN relocation
in b.o for the linker to act upon, the `.word 0x3a393837` data in b.o
may end up unaligned in the final executable.
To address the issue, this patch inserts NOP bytes and synthesizes an
R_RISCV_ALIGN relocation at the beginning of a text section when the
alignment >= 4.
For simplicity, when RVC is disabled, we synthesize an ALIGN relocation
(addend: 2) for a 4-byte aligned section, allowing the linker to trim
the excess 2 bytes.
See also https://sourceware.org/bugzilla/show_bug.cgi?id=33236
This reverts commit 6f53f1c8d2bdd13e30da7d1b85ed6a3ae4c4a856.
synthesiedAligns is not cleared, leading to stray relocations for
unrelated sections. Revert for now.
Without linker relaxation enabled for a particular relocatable file or
section (e.g., using .option norelax), the assembler will not generate
R_RISCV_ALIGN relocations for alignment directives. This becomes
problematic in a two-stage linking process:
```
ld -r a.o b.o -o ab.o
// b.o is norelax. Its alignment information is lost in ab.o.
ld ab.o -o ab
```
When ab.o is linked into an executable, the preceding relaxed section
(a.o's content) might shrink. Since there's no R_RISCV_ALIGN relocation
in b.o for the linker to act upon, the `.word 0x3a393837` data in b.o
may end up unaligned in the final executable.
To address the issue, this patch inserts NOP bytes and synthesizes an
R_RISCV_ALIGN relocation at the beginning of a text section when the
alignment >= 4.
For simplicity, when RVC is disabled, we synthesize an ALIGN relocation
(addend: 2) for a 4-byte aligned section, allowing the linker to trim
the excess 2 bytes.
See also https://sourceware.org/bugzilla/show_bug.cgi?id=33236
Pull Request: https://github.com/llvm/llvm-project/pull/151639
When using Temporal Profiling with the BP algorithm, we encounter an
issue with the internal function reorder. In cases where the symbol
table contains entries like:
```
Symbol table '.symtab' contains 45 entries:
Num: Value Size Type Bind Vis Ndx Name
10: 0000000000000000 0 SECTION LOCAL DEFAULT 18 .text.L1
11: 0000000000000000 24 FUNC LOCAL DEFAULT 18 L1
````
The zero-sized section symbol .text.L1 gets stored in the secToSym map
first. However, when the function lookup searches for L1 (as seen in
[BPSectionOrdererBase.inc:191](https://github.com/llvm/llvm-project/blob/main/lld/include/lld/Common/BPSectionOrdererBase.inc#L191)),
it fails to find the correct entry in rootSymbolToSectionIdxs because
the section symbol has already claimed that slot.
This patch fixes the issue by skipping zero-sized symbols during the
addSections process, ensuring that function symbols are properly
registered for lookup.
Each section now tracks the index of the first linker-relaxable
fragment, enabling two changes:
* Delete redundant ALIGN relocations before the first linker-relaxable
instruction in a section. The primary example is the offset 0
R_RISCV_ALIGN relocation for a text section aligned by 4.
* For alignments larger than the NOP size after the first
linker-relaxable instruction, ALIGN relocations are now generated, even in
norelax regions. This fixes the issue #150159.
The new test llvm/test/MC/RISCV/Relocations/align-after-relax.s
verifies the required ALIGN in a norelax region following
linker-relaxable instructions.
By using a fragment index within the subsection (which is less than or
equal to the section's index), the implementation may generate redundant
ALIGN relocations in lower-numbered subsections before the first
linker-relaxable instruction.
align-option-relax.s demonstrates the ALIGN optimization.
Add an initial `call` to a few tests to prevent the ALIGN optimization.
---
When the alignment exceeds 2, we insert $alignment-2 bytes of NOPs, even
in non-RVC code. This enables non-RVC code following RVC code to handle
a 2-byte adjustment without requiring an additional state in MCSection
or AsmParser.
```
.globl _start
_start:
// GNU ld can relax this to 6505 lui a0, 0x1
// LLD hasn't implemented this transformation.
lui a0, %hi(foo)
.option push
.option norelax
.option norvc
// Now we generate R_RISCV_ALIGN with addend 2, even if this is a norvc region.
.balign 4
b0:
.word 0x3a393837
.option pop
foo:
```
Pull Request: https://github.com/llvm/llvm-project/pull/150816
The processing of `-oso_prefix` uses `llvm::sys::fs::real_path` from the
user value, but it is later tried to be matched with the result of
`make_absolute`. While `real_path` resolves special symbols like `.`,
`..` and `~`, and resolves symlinks along the path, `make_absolute` does
neither, causing an incompatibility in some situations.
In macOS, temporary directories would normally be reported as
`/var/folders/<random>`, but `/var` is in fact a symlink to
`private/var`. If own is working on a temporary directory and uses
`-oso_prefix .`, it will be expanded to `/private/var/folder/<random>`,
while `make_absolute` will expand to `/var/folder/<random>` instead, and
`-oso_prefix` will fail to remove the prefix from the `N_OSO` entries,
leaving absolute paths to the temporary directory in the resulting file.
This would happen in any situation in which the working directory
includes a symlink, not only in temporary directories.
One can change the usage of `make_absolute` to use `real_path` as well,
but `real_path` will mean checking the file system for each `N_OSO`
entry. The other solution is stop using `real_path` when processing
`-oso_prefix` and manually expand an input of `.` like `make_absolute`
will do.
This second option is the one implemented here, since it is the closest
to the visible behaviour of ld64 (like the removed comment notes), so it
is the better one for compatibility. This means that a test that checked
the usage of the tilde as `-oso_prefix` needs to be removed (since it
was done by using `real_path`), and two new tests are provided checking
that symlinks do not affect the result. The second test checks a change
in behaviour, in which if one provides the input files with a prefix of
`./`, even when using `-oso_prefix .` because the matching is textual,
the `./` prefix will stay in the `N_OSO` entries. This matches the
observed behaviour of ld64.
The fixed-point layout algorithm handles linker scripts, thunks, and
relaxOnce (to suppress out-of-range GOT-indirect-to-PC-relative
optimization). These passes are not needed for relocatable links because
they require address information that is not yet available.
Since we don't scan relocations for relocatable links, the
`createThunks` and `relaxOnce` functions are no-ops anyway, making these
passes redundant.
To prevent cluttering the line history, I place the `if (...) break;`
inside the for loop.
Pull Request: https://github.com/llvm/llvm-project/pull/152240
Fixes crashes reported in #151255.
The alias may have already been stored for later resolution, which can
lead to treating a resolved alias as if it were still undefined.
Instead, use the alias target directly for the import.
Also extended the test to make reproducing the problem more likely, and
added an assert that catches the issue.