`advanceSubsection()` didn't account for the possibility that a section
could have no subsections.
Reviewed By: #lld-macho, thakis, BertalanD
Differential Revision: https://reviews.llvm.org/D130288
If there are multiple symbols at the same address, our unwind info
implementation assumes that we always register unwind entries to a
single canonical symbol.
This assumption was violated by the `registerEhFrame` code.
Fixes#56570.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D130208
It's only used in one branch, so we were unnecessarily calculating the
length of many symbol names.
Tiny speedup when linking chromium_framework on my M1 Mac mini:
x before.txt
+ after.txt
N Min Max Median Avg Stddev
x 10 3.9917109 4.0418 4.0318099 4.0203902 0.021459873
+ 10 3.944725 4.053988 3.9708955 3.9825602 0.037257609
Difference at 95.0% confidence
-0.03783 +/- 0.0285663
-0.940953% +/- 0.710536%
(Student's t, pooled s = 0.0304028)
Differential Revision: https://reviews.llvm.org/D130234
This commit reduces the size of the emitted rebase sections by
generating the REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB and
REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB opcodes.
With this change, chromium_framework's rebase section is a 40% smaller
197 kilobytes, down from the previous 320 kB. That is 6 kB smaller than
what ld64 produces for the same input.
Performance figures from my M1 Mac mini:
x before
+ after
N Min Max Median Avg Stddev
x 10 4.2269349 4.3300061 4.2689675 4.2690016 0.031151669
+ 10 4.219331 4.2914009 4.2398136 4.2448277 0.023817308
No difference proven at 95.0% confidence
Differential Revision: https://reviews.llvm.org/D130180
Similar to cstrings ld64 always deduplicates cfstrings. This was already
being done when enabling ICF, but for debug builds you may want to flip
this on if you cannot eliminate your instances of this, so this change
makes --deduplicate-literals also apply to cfstrings.
Differential Revision: https://reviews.llvm.org/D130134
This is a follow-on to {D129556}. I've refactored the code such that
`addFile()` no longer needs to take an extra parameter. Additionally,
the "do we force-load or not" policy logic is now fully contained within
addFile, instead of being split between `addFile` and
`parseLCLinkerOptions`. This also allows us to move the `ForceLoad` (now
`LoadType`) enum out of the header file.
Additionally, we can now correctly report loads induced by
`LC_LINKER_OPTION` in our `-why_load` output.
I've also added another test to check that CLI library non-force-loads
take precedence over `LC_LINKER_OPTION` + `-force_load_swift_libs`. (The
existing logic is correct, just untested.)
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D130137
The new format uses symbol relocations, as described in {D127637}.
Reviewed By: #lld-macho, alx32
Differential Revision: https://reviews.llvm.org/D128938
This fixes https://github.com/llvm/llvm-project/issues/56059 and
https://github.com/llvm/llvm-project/issues/56440. This is inspired by
tapthaker's patch (https://reviews.llvm.org/D127941), and has reused his
test cases. This patch adds an bool "isCommandLineLoad" to indicate
where archives are from. If lld tries to load the same library loaded
previously by LC_LINKER_OPTION from CLI, it will use this
isCommandLineLoad to determine if it should be affected by -all_load &
-ObjC flags. This also prevents -force_load from affecting archives
loaded previously from CLI without such flag, whereas tapthaker's patch
will fail such test case (introduced by
https://reviews.llvm.org/D128025).
Reviewed By: int3, #lld-macho
Differential Revision: https://reviews.llvm.org/D129556
This creates a symbol alias similar to --defsym in the elf linker. This
is used by swiftpm for all executables, so it's useful to support. This
doesn't implement -alias_list but that could be done pretty easily as
needed.
Differential Revision: https://reviews.llvm.org/D129938
To do this, we need to slice away the LSDA pointer, just like we are
slicing away the functionAddress pointer.
No observable difference in perf on chromium_framework:
base diff difference (95% CI)
sys_time 1.769 ± 0.068 1.761 ± 0.065 [ -2.7% .. +1.8%]
user_time 9.517 ± 0.110 9.528 ± 0.116 [ -0.6% .. +0.8%]
wall_time 8.291 ± 0.174 8.307 ± 0.183 [ -1.1% .. +1.5%]
samples 21 25
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D129830
This method is called on each relocation when parsing input files, so
the overhead of using virtual functions ends up being quite large. We
now have a single non-virtual method, which reads from the appropriate
array of relocation attributes set in the TargetInfo constructor.
This change results in a modest 2.3% reduction in link time for
chromium_framework measured on an x86-64 VPS, and 0.7% on an arm64 Mac.
N Min Max Median Avg Stddev
x 10 11.869417 12.032609 11.935041 11.938268 0.045802324
+ 10 11.581526 11.785265 11.649885 11.659507 0.054634834
Difference at 95.0% confidence
-0.278761 +/- 0.0473673
-2.33502% +/- 0.396768%
(Student's t, pooled s = 0.0504124)
Differential Revision: https://reviews.llvm.org/D130000
Clang passes a filename rather than a directory in -lto_object_path when
using FullLTO. Previously, it was always treated it as a directory, so
lld would crash when it attempted to create temporary files inside it.
Fixes#54805
Differential Revision: https://reviews.llvm.org/D129705
While working on {D129830}, I realized that our handling of ICF +
eh_frame combined was untested. Additionally I realized that the comment
explaining why we were safely slicing away the functionAddress reloc
from our compact unwind entries was... insufficient and slightly
misleading. I've tried to clarify it.
Reviewed By: #lld-macho, thevinster
Differential Revision: https://reviews.llvm.org/D129894
This just removes the code that gates the logic. The main issue here is
perf impact: without {D122258}, LLD takes a significant perf hit because
it now has to do a lot more work in the input parsing phase. But with
that change to eliminate unnecessary EH frames from input object files,
the perf overhead here is minimal. Concretely, here are the numbers for
some builds as measured on my 16-core Mac Pro:
**chromium_framework**
This is without the use of `-femit-dwarf-unwind=no-compact-unwind`:
base diff difference (95% CI)
sys_time 1.826 ± 0.019 1.962 ± 0.034 [ +6.5% .. +8.4%]
user_time 9.306 ± 0.054 9.926 ± 0.082 [ +6.2% .. +7.1%]
wall_time 8.225 ± 0.068 8.947 ± 0.128 [ +8.0% .. +9.6%]
samples 15 22
With that flag enabled, the regression mostly disappears, as hoped:
base diff difference (95% CI)
sys_time 1.839 ± 0.062 1.866 ± 0.068 [ -0.9% .. +3.8%]
user_time 9.452 ± 0.068 9.490 ± 0.067 [ -0.1% .. +0.9%]
wall_time 8.383 ± 0.127 8.452 ± 0.114 [ -0.1% .. +1.8%]
samples 17 21
**Unnamed internal app**
Without `-femit-dwarf-unwind`, this is the perf hit:
base diff difference (95% CI)
sys_time 1.372 ± 0.029 1.317 ± 0.024 [ -4.6% .. -3.5%]
user_time 2.835 ± 0.028 2.980 ± 0.027 [ +4.8% .. +5.4%]
wall_time 3.205 ± 0.079 3.383 ± 0.066 [ +4.9% .. +6.2%]
samples 102 83
With `-femit-dwarf-unwind`, the perf hit almost disappears:
base diff difference (95% CI)
sys_time 1.274 ± 0.026 1.270 ± 0.025 [ -0.9% .. +0.3%]
user_time 2.812 ± 0.023 2.822 ± 0.035 [ +0.1% .. +0.7%]
wall_time 3.166 ± 0.047 3.174 ± 0.059 [ -0.2% .. +0.7%]
samples 95 97
Just for fun, I measured the impact of `-femit-dwarf-unwind` on ld64
(`base` has the extra DWARF unwind info in the input object files,
`diff` doesn't):
base diff difference (95% CI)
sys_time 1.128 ± 0.010 1.124 ± 0.023 [ -1.3% .. +0.6%]
user_time 7.176 ± 0.030 7.106 ± 0.094 [ -1.5% .. -0.4%]
wall_time 7.874 ± 0.041 7.795 ± 0.121 [ -1.7% .. -0.3%]
samples 16 25
And for LLD:
base diff difference (95% CI)
sys_time 1.315 ± 0.019 1.280 ± 0.019 [ -3.2% .. -2.0%]
user_time 2.980 ± 0.022 2.822 ± 0.016 [ -5.5% .. -5.0%]
wall_time 3.369 ± 0.038 3.175 ± 0.033 [ -6.2% .. -5.3%]
samples 47 47
So parsing the extra EH frames is a lot more expensive for us than for
ld64. But given that we are quite a lot faster than ld64 to begin with,
I guess this isn't entirely unexpected...
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D129540
This load command specifies the offset and size of the exports trie.
This information used to be a field in LC_DYLD_INFO, but in newer
libraries, it has a dedicated load command: LC_DYLD_EXPORTS_TRIE.
The format of the trie is the same for both load commands, so the code
for parsing it can be shared.
LLD does not generate this yet; it is mainly useful when chained fixups
are in use, as the other members of LC_DYLD_INFO are unused then, so the
smaller LC_DYLD_EXPORTS_TRIE can be output instead.
LLDB gained support for this in D107673.
Fixes#54550
Differential Revision: https://reviews.llvm.org/D129430
This hint instructs the linker to relax a GOT-indirect load.
If the referenced symbol is external and its GOT entry is within +/- 1
MiB, the GOT entry can be loaded with a single literal ldr instruction.
If the referenced symbol is local, its address may be loaded directly if
it's close enough, or with an adr(p) + ldr pair if it's not.
This type accounts for more than half of all LOHs in chromium_framework.
This commit moves the eligibility checks into helper functions to
improve the readability of the LOH processing code. Ho functional
changes are intended to the previously implemented LOH types.
Differential Revision: https://reviews.llvm.org/D129427
This fixes https://github.com/llvm/llvm-project/issues/56238. ld64.lld currently does not generate __dof section in Mach-O, and -no_dtrace_dof option is on by default. However when there are user-defined dtrace symbols, ld64.lld will treat them as undefined symbols, which causes the linking to fail because lld cannot find their definitions. This patch allows ld64.lld to rewrite the instructions calling dtrace symbols to instructions like nop as what ld64 does; therefore, when encountered with user-provided dtrace probes, the linking can still succeed.
I'm not sure whether support for dtrace is expected in lld, so for now I didn't add codes to make lld emit __dof section like ld64, and only made it possible to link with dtrace symbols provided. If this feature is needed, I can add that part in Dtrace.cpp & Dtrace.h.
Reviewed By: int3, #lld-macho
Differential Revision: https://reviews.llvm.org/D129062
This test was failing on our 32 bit build bot:
https://lab.llvm.org/buildbot/#/builders/178/builds/2463
This happened because in UnwindInfoSectionImpl::finalize
a decision is made whether to write out regular or compressed
unwind info.
One check in this does:
```
if (cuPtr->functionAddress >= functionAddressMax) {
break;
```
Where cuPtr->functionAddress was uint64_t and functionAddressMax
was uintptr_t, which is 4 bytes on a 32 bit system.
Using uint64_t for functionAddressMax fixes this problem.
Presumably because at only 4 bytes, the max is much lower than
we expect. We're targetting 64 bit though so the size of the max
should match the size of the addresses.
Reviewed By: #lld-macho, int3
Differential Revision: https://reviews.llvm.org/D129363
This hint instructs the linker to perform the AdrpLdr or AdrpAdd
transformation depending on whether the GOT load has been relaxed to
load a local symbol's address.
Differential Revision: https://reviews.llvm.org/D129059
This linker optimization hint transforms a pair of adrp+ldr (immediate)
instructions into an ldr (literal) load from a PC-relative address if
it is 4-byte aligned and within +/- 1 MiB, as ldr can encode a signed
19-bit offset that gets multiplied by 4.
In the wild, only a small number of these hints are applicable because
not many loads end up close enough to the data segment. However, the
added helper functions will be useful in implementing the rest of the
LOH types.
Differential Revision: https://reviews.llvm.org/D128942
Linker optimization hints mark a sequence of instructions used for
synthesizing an address, like ADRP+ADD. If the referenced symbol ends up
close enough, it can be replaced by a faster sequence of instructions
like ADR+NOP.
This commit adds support for 2 of the 7 defined ARM64 optimization
hints:
- LOH_ARM64_ADRP_ADD, which transforms a pair of ADRP+ADD into ADR+NOP
if the referenced address is within +/- 1 MiB
- LOH_ARM64_ADRP_ADRP, which transforms two ADRP instructions into
ADR+NOP if they reference the same page
These two kinds already cover more than 50% of all LOHs in
chromium_framework.
Differential Review: https://reviews.llvm.org/D128093
An ADD_ADDR rebase opcode's argument can be encoded as an immediate if
the offset is less than 15 * word size. This change reduces the size of
chromium_framework by 100+ KiB.
Differential Revision: https://reviews.llvm.org/D128798
`--time-trace=foo` has the same behavior as `--time-trace --time-trace-file=<file>`
had previously.
Also, for mac, make --time-trace-granularity *not* imply --time-trace, to match
behavior of the ELF port.
Differential Revision: https://reviews.llvm.org/D128451
Identical literal folding takes ~1.4% of the time, and was missing
from the trace.
Signature computation still needs ~2.2% of the time, so probably worth
explicitly marking its contribution to "Write output file" (9.1%)
Differential Revision: https://reviews.llvm.org/D128343
Similarly to how undefined symbol diagnostics were changed in D128184,
we now show where in the source file duplicate symbols are defined at:
ld64.lld: error: duplicate symbol: _foo
>> defined in bar.c:42
>> /path/to/bar.o
>> defined in baz.c:1
>> /path/to/libbaz.a(baz.o)
For objects that don't contain DWARF data, the format is unchanged.
A slight difference to undefined symbol diagnostics is that we don't
print the name of the symbol on the third line, as it's already
contained on the first line.
Differential Revision: https://reviews.llvm.org/D128425
According to ministat, this is a small but measurable speedup
(using the repro in PR56121):
N Min Max Median Avg Stddev
x 10 3.7439518 3.7783802 3.7730219 3.7655502 0.012375226
+ 10 3.6149218 3.692198 3.6519327 3.6502951 0.025905601
Difference at 95.0% confidence
-0.115255 +/- 0.0190746
-3.06078% +/- 0.506554%
(Student's t, pooled s = 0.0203008)
(Without 858e8b17f7365, this change here to use parallelFor is an 18% speedup,
and doing 858e8b17f7365 on top of this change is just a 2.55% +/- 0.58% win.
Doing both results in a total speedup of 20.85% +/- 0.44%.)
Differential Revision: https://reviews.llvm.org/D128298
The error used to look like this:
ld64.lld: error: undefined symbol: _foo
>>> referenced by /path/to/bar.o:(symbol _baz+0x4)
If DWARF line information is available, we now show where in the source
the references are coming from:
ld64.lld: error: unreferenced symbol: _foo
>>> referenced by: bar.cpp:42 (/path/to/bar.cpp:42)
>>> /path/to/bar.o:(symbol _baz+0x4)
The reland is identical to the first time this landed. The fix was in D128294.
This reverts commit 0cc7ad417585b3185c32e395cc5e6cf082a347af.
Differential Revision: https://reviews.llvm.org/D128184
If ld64.lld was supplied an object file that had a `__debug_abbrev` or
`__debug_str` section, but didn't have any compile unit DIEs in
`__debug_info`, it would dereference an iterator pointing to the empty
array of DIEs. This underlying issue started causing segmentation faults
when parsing for `__debug_info` was addded in D128184. That commit was
reverted, and this one fixes the invalid dereference to allow relanding
it.
This commit adds an assertion to `filter_iterator_base`'s dereference
operators to catch bugs like this one.
Ran check-llvm, check-clang and check-lld.
Differential Revision: https://reviews.llvm.org/D128294
It's in libSystem, so it doesn't bring in any new deps, and it's
currently much faster than LLVM's current SHA256 implementation.
Makes linking (arm64) Chromium Framework with ld64.lld 17% faster.
See also PR56121.
No behavior change.
Differential Revision: https://reviews.llvm.org/D128290
The error used to look like this:
ld64.lld: error: undefined symbol: _foo
>>> referenced by /path/to/bar.o:(symbol _baz+0x4)
If DWARF line information is available, we now show where in the source
the references are coming from:
ld64.lld: error: unreferenced symbol: _foo
>>> referenced by: bar.cpp:42 (/path/to/bar.cpp:42)
>>> /path/to/bar.o:(symbol _baz+0x4)
Differential Revision: https://reviews.llvm.org/D128184
Patch created by running:
rg -l parallelForEachN | xargs sed -i '' -c 's/parallelForEachN/parallelFor/'
No behavior change.
Differential Revision: https://reviews.llvm.org/D128140
As an optimization for ld64 sometimes it can be useful to not export any
symbols for top level binaries that don't need any exports, to do this
you can pass `-exported_symbols_list /dev/null`, or new with Xcode 14
(ld64 816) there is a `-no_exported_symbols` flag for the same behavior.
This reproduces this behavior where previously an empty exported symbols
list file would have been ignored.
Differential Revision: https://reviews.llvm.org/D127562
ld64.lld used to print the "undefined symbol" line for each reference to
an undefined symbol previously:
ld64.lld: error: undefined symbol: _foo
>>> referenced by /path/to/bar.o:(symbol _baz+0x0)
ld64.lld: error: undefined symbol: _foo
>>> referenced by /path/to/bar.o:(symbol _quux+0x1)
Now they are deduplicated:
ld64.lld: error: undefined symbol: _foo
>>> referenced by /path/to/bar.o:(symbol _baz+0x0)
>>> referenced by /path/to/bar.o:(symbol _quux+0x1)
As with the other lld ports, only the first 3 references are printed.
Differential Revision: https://reviews.llvm.org/D127753
The error used to look like this:
ld64.lld: error: undefined symbol: _foo
>>> referenced by /path/to/bar.o
Now it displays the name of the function that contains the undefined
reference as well:
ld64.lld: error: undefined symbol: _foo
>>> referenced by /path/to/bar.o:(symbol _baz+0x4)
Differential Revision: https://reviews.llvm.org/D127696
This commit fixes the issue that getLocation always printed the name of
the first symbol in the section.
For clarity, upper_bound is used instead of a linear search for finding
the closest symbol name. Note that this change does not affect
performance: this function is only called when printing errors and
`symbols` typically contains a single symbol because of
.subsections_via_symbols.
Differential Revision: https://reviews.llvm.org/D127670