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
Instead, export `__wasm_apply_data_relocs` and `__wasm_call_ctors`
separately.
This is required since user code in a shared library (such as static
constructors) should not be run until relocations have been applied to
all loaded libraries.
See: https://github.com/emscripten-core/emscripten/issues/17295
Differential Revision: https://reviews.llvm.org/D128515
-dc is deprecated in release/14.x. Remove it for 15.0.
The only usage I know was FreeBSD crungen which was removed by https://reviews.freebsd.org/D34215
glibc just dropped -Wl,-d today. Keep -d for now.
For 1 != 1 <= 1 ? 1 : 2, the current code incorrectly considers that ?
has a higher precedence than != (minPrec).
Also, add a test for right associativity.
GOT references to absolute symbols can't be relaxed to use ADRP/ADD in
position-independent code because these instructions produce a relative
address.
Differential Revision: https://reviews.llvm.org/D128492
`--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
Allows ThinLTO indices to be written to disk on-the-fly/as-part-of “normal” linker execution. Previously ThinLTO indices could be written via --thinlto-index-only but that would cause the linker to exit early. For MLGO specifically, this enables saving the ThinLTO index files without having to restart the linker to collect data only available at later stages (i.e. output of --save-temps) of the linker's execution.
Note, this option does not currently work with:
--thinlto-object-suffix-replace, as this is intended to be used to consume minimized IR bitcode files while --thinlto-emit-index-files is intended to be run together with InProcessThinLTO (which cannot parse minimized IR).
--thinlto-prefix-replace support is left unimplemented but can be implemented if needed
Differential Revision: https://reviews.llvm.org/D127777
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 858e8b17f7, this change here to use parallelFor is an 18% speedup,
and doing 858e8b17f7 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 0cc7ad4175.
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
This reverts commit 9ffeaaa0ea.
This fixes debugging large executables with lldb and gdb.
When StringTableBuilder is used, the string offsets for any string
can point anywhere in the string table - while previously, all strings
were inserted in order (without deduplication and tail merging).
For symbols, there's no complications in encoding the string offset;
the offset is encoded as a raw 32 bit binary number in half of the
symbol name field.
For sections, the string table offset is written as
"/<decimaloffset>", but if the decimal offset would be larger than
7 digits, it's instead written as "//<base64offset>". Tools that
operate on object files can handle the base64 offset format, but
apparently neither lldb nor gdb expect that syntax when locating the
debug information section. Prior to the reverted commit, all long
section names were located at the start of the string table, so
their offset never exceeded the range for the decimal syntax.
Just reverting this change for now, as the actual benefit from it
was fairly modest.
Longer term, lld could write all long section names unoptimized
at the start of the string table, followed by all the strings for
symbol names, with deduplication and tail merging. And lldb and
gdb could be fixed to handle sections with the base64 offset syntax.
This fixes https://github.com/mstorsjo/llvm-mingw/issues/289.
Microsoft does not seem to document the flag. Ignoring it for now is probably
better than getting an unknown flag error.
Reviewed By: thakis
Differential Revision: https://reviews.llvm.org/D128231
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
I realized we'd forgotten to cover this case (though our existing
behavior is indeed correct / matches ld64's).
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D128025
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
It seems to be a bug in `LinkerDriver::findFile`, the file name is not converted
to lowercase when being inserted into `visitedLibs`. This is the only exception
in the file and all other places always convert file names to lowercase when
inserting them into `visitedLibs` (or `visitedFiles`).
Reviewed By: thieta, hans
Differential Revision: https://reviews.llvm.org/D127709
Since binutils 2.36, GNU ld defaults to emitting base relocations,
and that version added the new option --disable-reloc-section to
disable it.
Differential Revision: https://reviews.llvm.org/D127478
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
This reverts commit 942f4e3a7c.
The additional change required to avoid the assertion errors seen
previously is:
--- a/lld/MachO/ICF.cpp
+++ b/lld/MachO/ICF.cpp
@@ -443,7 +443,9 @@ void macho::foldIdenticalSections() {
/*relocVA=*/0);
isec->data = copy;
}
- } else {
+ } else if (!isEhFrameSection(isec)) {
+ // EH frames are gathered as hashables from unwindEntry above; give a
+ // unique ID to everything else.
isec->icfEqClass[0] = ++icfUniqueID;
}
}
Differential Revision: https://reviews.llvm.org/D123435
Just matter of enabling the config option.
(Also changed the platform of the input test file to macOS, since that's
the default that we specify in the `%lld` substitution. The conflict was
causing errors when linking with LTO.)
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D127600
This flag suppresses warnings produced by the linker. In ld64 this has
an interesting interaction with -fatal_warnings, it silences the
warnings but the link still fails. Instead of doing that here we still
print the warning and eagerly fail the link in case both are passed,
this seems more reasonable so users can understand why the link fails.
Differential Revision: https://reviews.llvm.org/D127564
First of all, `LLVM_TOOLS_INSTALL_DIR` put there breaks our NixOS
builds, because `LLVM_TOOLS_INSTALL_DIR` defined the same as
`CMAKE_INSTALL_BINDIR` becomes an *absolute* path, and then when
downstream projects try to install there too this breaks because our
builds always install to fresh directories for isolation's sake.
Second of all, note that `LLVM_TOOLS_INSTALL_DIR` stands out against the
other specially crafted `LLVM_CONFIG_*` variables substituted in
`llvm/cmake/modules/LLVMConfig.cmake.in`.
@beanz added it in d0e1c2a550 to fix a
dangling reference in `AddLLVM`, but I am suspicious of how this
variable doesn't follow the pattern.
Those other ones are carefully made to be build-time vs install-time
variables depending on which `LLVMConfig.cmake` is being generated, are
carefully made relative as appropriate, etc. etc. For my NixOS use-case
they are also fine because they are never used as downstream install
variables, only for reading not writing.
To avoid the problems I face, and restore symmetry, I deleted the
exported and arranged to have many `${project}_TOOLS_INSTALL_DIR`s.
`AddLLVM` now instead expects each project to define its own, and they
do so based on `CMAKE_INSTALL_BINDIR`. `LLVMConfig` still exports
`LLVM_TOOLS_BINARY_DIR` which is the location for the tools defined in
the usual way, matching the other remaining exported variables.
For the `AddLLVM` changes, I tried to copy the existing pattern of
internal vs non-internal or for LLVM vs for downstream function/macro
names, but it would good to confirm I did that correctly.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D117977
This silences the following warning:
../tools/lld/ELF/SyntheticSections.cpp:1596:48: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
1596 | assert((index != 0 || type != target->gotRel && type != target->pltRel ||
Differential Revision: https://reviews.llvm.org/D127395
For arm64, llvm-mc emits relocations for the target function
address like so:
ltmp:
<CIE start>
...
<CIE end>
... multiple FDEs ...
<FDE start>
<target function address - (ltmp + pcrel offset)>
...
If any of the FDEs in `multiple FDEs` get dead-stripped, then `FDE start`
will move to an earlier address, and `ltmp + pcrel offset` will no longer
reflect an accurate pcrel value. To avoid this problem, we "canonicalize"
our relocation by adding an `EH_Frame` symbol at `FDE start`, and updating
the reloc to be `target function address - (EH_Frame + new pcrel offset)`.
Reviewed By: #lld-macho, Roger
Differential Revision: https://reviews.llvm.org/D124561
== Background ==
`llvm-mc` generates unwind info in both compact unwind and DWARF
formats. LLD already handles the compact unwind format; this diff gets
us close to handling the DWARF format properly.
== Caveats ==
It's not quite done yet, but I figure it's worth getting this reviewed
and landed first as it's shaping up to be a fairly large code change.
**Known limitations of the current code:**
* Only works for x86_64, for which `llvm-mc` emits "abs-ified"
relocations as described in 618def651b.
`llvm-mc` emits regular relocations for ARM EH frames, which we do not
yet handle correctly.
Since the feature is not ready for real use yet, I've gated it behind a
flag that only gets toggled on during test suite runs. With most of the
new code disabled, we see just a hint of perf regression, so I don't
think it'd be remiss to land this as-is:
base diff difference (95% CI)
sys_time 1.926 ± 0.168 1.979 ± 0.117 [ -1.2% .. +6.6%]
user_time 3.590 ± 0.033 3.606 ± 0.028 [ +0.0% .. +0.9%]
wall_time 7.104 ± 0.184 7.179 ± 0.151 [ -0.2% .. +2.3%]
samples 30 31
== Design ==
Like compact unwind entries, EH frames are also represented as regular
ConcatInputSections that get pointed to via `Defined::unwindEntry`. This
allows them to be handled generically by e.g. the MarkLive and ICF
code. (But note that unlike compact unwind subsections, EH frame
subsections do end up in the final binary.)
In order to make EH frames "look like" a regular ConcatInputSection,
some processing is required. First, we need to split the `__eh_frame`
section along EH frame boundaries rather than along symbol boundaries.
We do this by decoding the length field of each EH frame. Second, the
abs-ified relocations need to be turned into regular Relocs.
== Next Steps ==
In order to support EH frames on ARM targets, we will either have to
teach LLD how to handle EH frames with explicit relocs, or we can try to
make `llvm-mc` emit abs-ified relocs for ARM as well. I'm hoping to do
the latter as I think it will make the LLD implementation both simpler
and faster to execute.
== Misc ==
The `obj-file-with-stabs.s` test had to be updated as the previous
version would trip assertion errors in the code. It appears that in our
attempt to produce a minimal YAML test input, we created a file with
invalid EH frame data. I've fixed this by re-generating the YAML and not
doing any hand-pruning of it.
Reviewed By: #lld-macho, Roger
Differential Revision: https://reviews.llvm.org/D123435
This reduces linking time by ~8% for my project (1.19s -> 0.53s for
writeSections()). writeTo is const, which bodes well for it being
parallelizable, and I've looked through the different overridden versions and
can't see any race conditions. It produces the same byte-for-byte output for my
project.
Differential Revision: https://reviews.llvm.org/D126800
This reverts commit dcf3368e33.
It breaks -DLLVM_ENABLE_ASSERTIONS=on builds. In addition, the description is
incorrect about ld.lld behavior. For wasm, there should be justification to add
the new mode.
As well as ELF linker does, retain all data segments named X referenced
through `__start_X` or `__stop_X`.
For example, `FOO_MD` should not be stripped in the below case, but it's currently mis-stripped
```llvm
@FOO_MD = global [4 x i8] c"bar\00", section "foo_md", align 1
@__start_foo_md = external constant i8*
@__stop_foo_md = external constant i8*
@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @foo_md_size to i8*)], section "llvm.metadata"
define i32 @foo_md_size() {
entry:
ret i32 sub (
i32 ptrtoint (i8** @__stop_foo_md to i32),
i32 ptrtoint (i8** @__start_foo_md to i32)
)
}
```
This fixes https://github.com/llvm/llvm-project/issues/55839
Reviewed By: sbc100
Differential Revision: https://reviews.llvm.org/D126950
.zdebug is unlikely used any longer: gcc -gz switched from legacy
.zdebug to SHF_COMPRESSED with binutils 2.26 (2016), which has been
several years. clang 14 dropped -gz=zlib-gnu support. According to
Debian Code Search (`gz=zlib-gnu`), no project uses -gz=zlib-gnu.
Remove .zdebug support to (a) simplify code and (b) allow removal of llvm-mc's
--compress-debug-sections=zlib-gnu.
In case the old object file `a.o` uses .zdebug, run `objcopy --decompress-debug-sections a.o`
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D126793
LTO code may end up mixing bitcode files from various sources varying in
their use of opaque pointer types. The current strategy to decide
between opaque / typed pointers upon the first bitcode file loaded does
not work here, since we could be loading a non-opaque bitcode file first
and would then be unable to load any files with opaque pointer types
later.
So for LTO this:
- Adds an `lto::Config::OpaquePointer` option and enforces an upfront
decision between the two modes.
- Adds `-opaque-pointers`/`-no-opaque-pointers` options to the gold
plugin; disabled by default.
- `--opaque-pointers`/`--no-opaque-pointers` options with
`-plugin-opt=-opaque-pointers`/`-plugin-opt=-no-opaque-pointers`
aliases to lld; disabled by default.
- Adds an `-lto-opaque-pointers` option to the `llvm-lto2` tool.
- Changes the clang driver to pass `-plugin-opt=-opaque-pointers` to
the linker in LTO modes when clang was configured with opaque
pointers enabled by default.
This fixes https://github.com/llvm/llvm-project/issues/55377
Differential Revision: https://reviews.llvm.org/D125847
This reduces the time emitStabs() takes by about 275ms, or 3% of overall
linking time for the project I'm on. Although the parent function is run in
parallel, it's one of the slowest tasks in that concurrent batch (I have
another optimization for another slow task as well).
Differential Revision: https://reviews.llvm.org/D126785
Symbols from LTO objects don't contain Wasm signatures, but we need a
signature when we create undefined/stub functions for missing weakly
undefined symbols.
Luckily, after LTO, we know that symbols that are not referenced by a
regular object file must not be needed in the final output so there
is no need to generate undefined/stub function for them.
Differential Revision: https://reviews.llvm.org/D126554
Currently there are 2 duplicate implementation, and I want to add
a use in a 3rd place. Combine them in lib/BinaryFormat so they can
be shared.
Also update toString for symbol and reloc types to use StringRef
Differential Revision: https://reviews.llvm.org/D126553
This matches the behaviour of the ELF backend (in fact this change
is mostly just copying directly from ELF/Options.td).
Differential Revision: https://reviews.llvm.org/D126500
I'm really not sure how this was overlooked when we first ported lld
to Wasm. The upstream code in the ELF backend has these two lines but
for some reason they never make it into the Wasm version.
Differential Revision: https://reviews.llvm.org/D126497
It turns out we were already allocating static address space for TLS
data along with the non-TLS static data, but this space was going
unused/ignored.
With this change, we include the TLS segment in `__wasm_init_memory`
(which does the work of loading the passive segments into memory when a
module is first loaded). We also set the `__tls_base` global to point
to the start of this segment.
This means that the runtime can use this static copy of the TLS data for
the first/primary thread if it chooses, rather than doing a runtime
allocation prior to calling `__wasm_init_tls`.
Practically speaking, this will allow emscripten to avoid dynamic
allocation of TLS region on the main thread.
Differential Revision: https://reviews.llvm.org/D126107
The <internal> symbol was tripping an assertion in getVA() because it
was not marked as used. Per the comment above that symbols creation,
dead stripping has already occurred so marking this symbol as used is
accurate.
Fixes https://github.com/llvm/llvm-project/issues/55565
Differential revision: https://reviews.llvm.org/D126072
This became empty when we removed the legacy macho lld. This results in
a warning when running `check-lld`. We can revert this in the future if
we want unit tests.
Differential Revision: https://reviews.llvm.org/D125436
Details:
The test was incorrectly expecting the error messages for the export symbols to have a particular order.
It shouldn't because the export symbol list is processed concurrently.
GNU ld does not allow `.foo : { (*foo) }`, but we may recognize it as three
input section descriptions: file "(" with any section name, file "*foo" with
any section name, file ")" with any section name. Disallow the error-prone usage.
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D125523
We picked common-page-size to match GNU ld. Recently, the resolution to GNU ld
https://sourceware.org/bugzilla/show_bug.cgi?id=28824 (milestone: 2.39) switched
to max-page-size so that the last page can be protected by RELRO in case the
system page size is larger than common-page-size.
Thanks to our two RW PT_LOAD scheme (D58892), switching to max-page-size does
not change file size (while GNU ld's scheme may increase file size).
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D125410
This flag is added by clang::driver::tools::addLTOOptions() and was causing
errors for me when building the llvm-test-suite repository with LTO and
-DTEST_SUITE_COLLECT_STATS=ON. This replaces the --stats-file= option
added in 1c04b52b25 since the flag is only
used for LTO and should therefore be in the -plugin-opt= namespace.
Additionally, this commit fixes the `REQUIRES: asserts` that was added in
948d05324a150a5a24e93bad07c9090d5b8bd129: the feature was never defined in
the lld test suite so it effectively disabled the test.
Reviewed By: MaskRay, MTC
Differential Revision: https://reviews.llvm.org/D124105
Placing a non-SHT_NOBITS input section in an output section specified with
(NOLOAD) is fishy but used by some projects. D118840 changed the output type to
SHT_PROGBITS, but using the specified type seems to make more sense and improve
GNU ld compatibility: `(NOLOAD)` seems to change the output section type
regardless of input.
I think we should keep the current type mismatch warning as it does indicate an
error-prone usage.
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D125074
With -platform_version flags for two distinct platforms,
this writes a LC_BUILD_VERSION header for each.
The motivation is that this is needed for self-hosting with lld as linker
after D124059.
To create a zippered output at the clang driver level, pass
-target arm64-apple-macos -darwin-target-variant arm64-apple-ios-macabi
to create a zippered dylib.
(In Xcode's clang, `-darwin-target-variant` is spelled just `-target-variant`.)
(If you pass `-target arm64-apple-ios-macabi -target-variant arm64-apple-macos`
instead, ld64 crashes!)
This results in two -platform_version flags being passed to the linker.
ld64 also verifies that the iOS SDK version is at least 13.1. We don't do that
yet. But ld64 also does that for other platforms and we don't. So we need to
do that at some point, but not in this patch.
Only dylib and bundle outputs can be zippered.
I verified that a Catalyst app linked against a dylib created with
clang -shared foo.cc -o libfoo.dylib \
-target arm64-apple-macos \
-target-variant arm64-apple-ios-macabi \
-Wl,-install_name,@rpath/libfoo.dylib \
-fuse-ld=$PWD/out/gn/bin/ld64.lld
runs successfully. (The app calls a function `f()` in libfoo.dylib
that returns a const char* "foo", and NSLog(@"%s")s it.)
ld64 is a bit more permissive when writing zippered outputs,
see references to "unzippered twins". That's not implemented yet.
(If anybody wants to implement that, D124275 is a good start.)
Differential Revision: https://reviews.llvm.org/D124887
The arm64-apple-macos triple is only valid for versions >= 11.0. (If
one passes arm64-apple-macos10.15 to llvm-mc, the output's min version is still
11.0). In order to write tests easily for both target archs, let's up the
default min version in our tests.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D124562
We currently hard code RELRO sections. When a custom section is between
DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END, we may report a spurious
`error: section: ... is not contiguous with other relro sections`. GNU ld
makes such sections RELRO.
glibc recently switched to default --with-default-link=no. This configuration
places `__libc_atexit` and others between DATA_SEGMENT_ALIGN and
DATA_SEGMENT_RELRO_END. This patch allows such a ld.bfd --verbose
linker script to be fed into lld.
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D124656
This change implements --icf=safe for MachO based on addrsig section that is implemented in D123751.
Reviewed By: int3, #lld-macho
Differential Revision: https://reviews.llvm.org/D123752
Similar to D117734. Take AArch64 as an example when the branch range is +-0x8000000.
getISDThunkSec returns `ts` when `src-0x8000000-r_addend <= tsBase < src-0x8000000`
and the new thunk will be placed in `ts` (`ts->addThunk(t)`). However, the new
thunk (at the end of ts) may be unreachable from src. In the next pass,
`normalizeExistingThunk` reverts the relocation back to the original target.
Then a new thunk is created and the same `ts` is picked as before. The `ts` is
still unreachable.
I have observed it in one test with a sufficiently large r_addend (47664): there
are initially 245 Thunk's, then in each pass 14 new Thunk's are created and get
appended to the unreachable ThunkSection. After 15 passes lld fails with
`thunk creation not converged`.
The new test aarch64-thunk-reuse2.s checks the case.
Without `- pcBias`, arm-thumb-thunk-empty-pass.s and arm-thunk-multipass-plt.s
will fail.
Reviewed By: peter.smith
Differential Revision: https://reviews.llvm.org/D124653
After 1af25a9860, we stop unconditionally
retaining wrapped symbols, which means that LTO's summary-based global
dead stripping can eliminate them even if they'll be referenced by a
linker script after the wrapping is performed. Mark symbols referenced
in linker scripts as `referenced` in addition to `isUsedInRegularObj`,
so that the wrapping logic correctly sets `referencedAfterWrap` for the
symbols which will be referenced after wrapping, which will prevent LTO
from eliminating them.
An alternative would have been to change the `referencedAfterWrap` logic
to look at `isUsedInRegularObj` in addition to `referenced`, but
`isUsedInRegularObj` is also set in other places (e.g. for the entry
symbol), and it's not clear that we want `referencedAfterWrap` to take
all those places into account, so it seemed better to keep that logic
as-is and instead set `referenced` for linker script-referenced symbols.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D124433
Before this,
clang empty.cc -target x86_64-apple-ios13.1-macabi \
-framework CoreServices -fuse-ld=lld
would error out with
ld64.lld: error: path/to/MacOSX.sdk/System/Library/Frameworks/
CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/
Versions/A/CarbonCore.tbd(
/System/Library/Frameworks/
CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/
Versions/A/CarbonCore) is incompatible with x86_64 (macCatalyst)
Now it works, like with ld64.
Differential Revision: https://reviews.llvm.org/D124336
It seems like we are overly asserting when running `-dead_strip` with
exported symbols. ld64 treats exported private extern symbols as a liveness
root. Loosen the assert to match ld64's behavior.
Reviewed By: #lld-macho, int3
Differential Revision: https://reviews.llvm.org/D124143
We were previously only omitting the original of a wrapped symbol if it
was not used by an object file and undefined. We can tighten the second
condition to drop any symbol that isn't defined instead, which lets us
drop a previous check (added in https://reviews.llvm.org/D118756) that
was only covering some such symbols.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D124065
We were previously not correctly wrapping symbols that were only
produced during LTO codegen and unreferenced before then, or symbols
only referenced from such symbols. The root cause was that we weren't
marking the wrapped symbol as used if we only saw the use after LTO
codegen, leading to the failed wrapping.
Fix this by explicitly tracking whether a symbol will become referenced
after wrapping is done. We can use this property to tell LTO to preserve
such symbols, instead of overload isUsedInRegularObj for this purpose.
Since we're no longer setting isUsedInRegularObj for all symbols which
will be wrapped, its value at the time of performing the wrapping in the
symbol table will accurately reflect whether the symbol was actually
used in an object (including in an LTO-generated object), and we can
propagate that value to the wrapped symbol and thereby ensure we wrap
correctly.
This incorrect wrapping was the only scenario I was aware of where we
produced an invalid PLT relocation, which D123985 started diagnosing,
and with it fixed, we lose the test for that diagnosis. I think it's
worth keeping the diagnosis though, in case we run into other issues in
the future which would be caught by it.
Fixes PR50675.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D124056
Otherwise they fires for every single file which includes the header,
which is very noisy when building.
Reviewed By: MaskRay, peter.smith
Differential Revision: https://reviews.llvm.org/D124041
Previously, when encountering a symbol reloc located in a literal section, we
would look up the contents of the literal at the `symbol value + addend` offset
within the literal section. However, it seems that this offset is not guaranteed
to be valid. Instead, we should use just the symbol value to retrieve the
literal's contents, and compare the addend values separately. ld64 seems to do
this.
Reviewed By: #lld-macho, thevinster
Differential Revision: https://reviews.llvm.org/D124223
Previously, we stored a pointer from the ObjFile to its compact unwind
section in order to avoid iterating over the file's sections a second
time. However, given the small number of sections (not subsections) per
file, this caching was really quite unnecessary. We will soon do lookups
for more sections (such as the `__eh_frame` section), so let's simplify
the code first.
Reviewed By: #lld-macho, Roger
Differential Revision: https://reviews.llvm.org/D123434
A "zippered" dylib contains several LC_BUILD_VERSION load commands, usually
one each for "normal" macOS and one for macCatalyst.
These are usually created by passing something like
-shared -target arm64-apple-macos -darwin-target-variant arm64-apple-ios13.1-macabi
to clang, which turns it into
-platform_version macos 12.0.0 12.3 -platform_version "mac catalyst" 14.0.0 15.4
for the linker.
ld64.lld can read these files fine, but it can't write them. Before this
change, it would just silently use the last -platform_version flag and ignore
the rest.
This change adds a warning that writing zippered dylibs isn't implemented yet
instead.
Sadly, parts of ld64.lld's test suite relied on the previous
"silently use last flag" semantics for its test suite: `%lld` always expanded
to `ld64.lld -platform_version macos 10.15 11.0` and tests that wanted a
different value passed a 2nd `-platform_version` flag later on. But this now
produces a warning if the platform passed to `-platform_version` is not `macos`.
There weren't very many cases of this, so move these to use `%no-arg-lld` and
manually pass `-arch`.
Differential Revision: https://reviews.llvm.org/D124106
Linux kernel arch/arm64/kernel/vmlinux.lds.S discards .dynsym . D123985 triggers
a spurious assertion failure. Detect the case with
`!mainPart->dynSymTab->getParent()`.
STB_HIPROC and STT_HIPROC are both 15, so we can fit the symbol binding
and type in 4 bits. This gives us an additional byte to use for Symbol
flags (without increasing the type's size), which I'll be making use of
in the next diff.
Reorder type and binding based on a suggestion from @MaskRay, to
optimize st_info computation on little-endian systems (see
https://godbolt.org/z/nMn8Yar43).
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D124042
Because of https://llvm.org/PR50675, we can end up producing a PLT
relocation referencing a symbol that's dropped from the dynamic symbol
table, which in turn causes a crash at runtime. We ran into this again
recently, resulting in crashes for our users. A subsequent diff will fix
that issue, but add an assert to catch it if it happens again.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D123985
Otherwise, with recent versions of libstdc++, clang can't tell that the
atomic operations are properly aligned, and generates calls to
libatomic. (Actually, because of the use of reinterpret_cast, it wasn't
guaranteed to be aligned, but I think it ended up being aligned in
practice.)
Fixes https://github.com/llvm/llvm-project/issues/54790 , the part where
LLVM failed to build.
Differential Revision: https://reviews.llvm.org/D123872
Updated MipsInstPrinter to print absolute hex offsets for branch instructions.
It is necessary to make the llvm-objdump output close to the gnu objdump output.
This implementation is based on the implementation for RISC-V.
OS Laboratory. Huawei Russian Research Institute. Saint-Petersburg
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D123764
Similar to D119787 for PPC64.
A hidden undefined weak may change its binding to local before some
`isUndefinedWeak` code, so some `isUndefinedWeak` code needs to be changed to
`isUndefined`. The undefined non-weak case has been errored, so just using
`isUndefined` is fine.
The Linux kernel recently has a usage that a branch from 0xffff800008491ee0
references a hidden undefined weak symbol `vfio_group_set_kvm`.
It relies on the behavior that a branch to undefined weak resolving to the next
instruction, otherwise it'd see spurious relocation out of range errors.
Fixes https://github.com/ClangBuiltLinux/linux/issues/1624
Differential Revision: https://reviews.llvm.org/D123750
Follow-on to {D123276}. Now that we work with an internal
representation of compact unwind entries, we no longer need to template
our UnwindInfoSectionImpl code based on the pointer size of the target
architecture.
I've still kept the split between `UnwindInfoSectionImpl` and
`UnwindInfoSection`. I'd introduced that split in order to do type
erasure, but I think it's still useful to have in order to keep
`UnwindInfoSection`'s definition in the header file clean.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D123277
Mostly for compatibility reasons with link.exe this flag
makes sure we don't write a implib - not even when /implib
is also passed, that's how link.exe works.
Differential Revision: https://reviews.llvm.org/D123591