This diff paves the way for {D102964} which adds a new kind of
InputSection.
We previously maintained section ordering implicitly: we created
InputSections as we parsed each file in command-line order, and passed
on this ordering when we created OutputSections and OutputSegments by
iterating over these InputSections. The implicitness of the ordering
made it difficult to refactor the code to e.g. handle a new type of
InputSection. As such, I've codified the ordering explicitly via
`inputOrder` fields. This also allows us to use `sort` instead of
`stable_sort`.
Benchmarking chromium_framework on my 3.2 GHz 16-Core Intel Xeon W:
N Min Max Median Avg Stddev
x 20 4.23 4.35 4.27 4.274 0.030157481
+ 20 4.24 4.38 4.27 4.2815 0.033759989
No difference proven at 95.0% confidence
Reviewed By: #lld-macho, alexshap
Differential Revision: https://reviews.llvm.org/D102972
The ELF format has the concept of merge sections (marked by SHF_MERGE),
which contain data that can be safely deduplicated. The Mach-O
equivalents are called literal sections (marked by S_CSTRING_LITERALS or
S_{4,8,16}BYTE_LITERALS). While the Mach-O format doesn't use the word
'merge', to avoid confusion, I've renamed our MergedOutputSection to
ConcatOutputSection. I believe it's a more descriptive name too.
This renaming sets the stage for {D102964}.
Reviewed By: #lld-macho, alexshap
Differential Revision: https://reviews.llvm.org/D102971
* Move `static_asserts` into cpp instead of header file. I noticed they
had been separated from the main class definition in the header, so I
set about to clean that up, then figured it made more sense as part of
the cpp file so as not to incur unnecessary compile-time overhead.
* Remove unnecessary `virtual`s
* Remove unnecessary comment / reword another comment
lld/MachO/Driver.cpp and lld/MachO/SyntheticSections.cpp include
llvm/Config/config.h which doesn't exist when building standalone lld.
This patch replaces llvm/Config/config.h include with llvm/Config/llvm-config.h
just like it is in lld/ELF/Driver.cpp and HAVE_LIBXAR with LLVM_HAVE_LIXAR and
moves LLVM_HAVE_LIBXAR from config.h to llvm-config.h
Also it adds LLVM_HAVE_LIBXAR to LLVMConfig.cmake and links liblldMachO2.so
with XAR_LIB if LLVM_HAVE_LIBXAR is set.
Differential Revision: https://reviews.llvm.org/D102084
In LC_DYSYMTAB, private externs were still emitted as exported symbols instead
of as locals.
Fixes PR50373. See bug for details.
Differential Revision: https://reviews.llvm.org/D102662
That way, it's done only once instead of every time shouldExportSymbol() is
called.
Possibly a bit faster:
% ministat at_main at_symtodo
x at_main
+ at_symtodo
N Min Max Median Avg Stddev
x 30 3.9732189 4.114846 4.024621 4.0304692 0.037022865
+ 30 3.93766 4.0510042 3.9973931 3.991469 0.028472565
Difference at 95.0% confidence
-0.0390002 +/- 0.0170714
-0.967635% +/- 0.423559%
(Student's t, pooled s = 0.0330256)
In other runs with n=30 it makes no perf difference, so maybe it's just noise.
But being able to quickly and conveniently answer "is this symbol exported?"
is useful for fixing PR50373 and for implementing -dead_strip, so this seems
like a good change regardless.
No behavior change.
Differential Revision: https://reviews.llvm.org/D102661
This diff changes the type of the argument of isCodeSection to const InputSection *.
NFC.
Test plan: make check-lld-macho
Differential revision: https://reviews.llvm.org/D102664
`match()` can only return for non-empty vectors, but at least in
non-LTO builds that isn't clear to the compiler. Help it out.
This is a minor but measurable speedup on my machine (but less
than what we might've lost in https://reviews.llvm.org/D100818#2764272 --
bot note higher N on this measurement here, so higher confidence here):
% ministat at_main at_branch
x at_main
+ at_branch
N Min Max Median Avg Stddev
x 30 3.9243979 4.0395119 3.987375 3.9826236 0.027567796
+ 30 3.8495831 4.0009291 3.931325 3.9347135 0.037832878
Difference at 95.0% confidence
-0.0479101 +/- 0.0171102
-1.20298% +/- 0.429622%
(Student's t, pooled s = 0.0331007)
No behavior change.
Eventually we should apply these lists at symbol parse time instead of
every time shouldExportSymbol() though :)
Differential Revision: https://reviews.llvm.org/D102655
Has the effect that `__mh_execute_header` stays in the symbol table of
outputs even after running `strip` on the output. I don't know if that's
important for anything -- my motivation for the patch is just is to make
the output more similar to ld64.
(Corresponds to symbolTableInAndNeverStrip in ld64.)
Differential Revision: https://reviews.llvm.org/D102619
Extend the range of calls beyond an architecture's limited branch range by first calling a thunk, which loads the far address into a scratch register (x16 on ARM64) and branches through it.
Other ports (COFF, ELF) use multiple passes with successively-refined guesses regarding the expansion of text-space imposed by thunk-space overhead. This MachO algorithm places thunks during MergedOutputSection::finalize() in a single pass using exact thunk-space overheads. Thunks are kept in a separate vector to avoid the overhead of inserting into the `inputs` vector of `MergedOutputSection`.
FIXME:
* arm64-stubs.s test is broken
* add thunk tests
* Handle thunks to DylibSymbol in MergedOutputSection::finalize()
Differential Revision: https://reviews.llvm.org/D100818
We had a hardcoded check and a stale TODO, written back when we only had
support for one architecture.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D102154
In particular, we should apply the `-undefined` behavior to all
such symbols, include those that are specified via the command line
(i.e. `-e`, `-u`, and `-exported_symbol`). ld64 supports this too.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D102143
On a section with alignment of 16, subsections aligned to 16-byte
boundaries should keep their 16-byte alignment.
Fixes PR50274. (The same bug could have happened with -order_file
previously.)
Differential Revision: https://reviews.llvm.org/D102139
This would cause us to pull in symbols (and code) that should
be unused.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D102137
Symbols explicitly exported via command-line options `--exported_symbol SYM` and `--exported_symbols_list FILE` must be defined. Before this fix, lazy symbols defined in archives would be left to languish. We now force them to be included in the linked output.
Differential Revision: https://reviews.llvm.org/D102100
Before this, if an inline function was defined in several input files,
lld would write each copy of the inline function the output. With this
patch, it only writes one copy.
Reduces the size of Chromium Framework from 378MB to 345MB (compared
to 290MB linked with ld64, which also does dead-stripping, which we
don't do yet), and makes linking it faster:
N Min Max Median Avg Stddev
x 10 3.9957051 4.3496981 4.1411121 4.156837 0.10092097
+ 10 3.908154 4.169318 3.9712729 3.9846753 0.075773012
Difference at 95.0% confidence
-0.172162 +/- 0.083847
-4.14165% +/- 2.01709%
(Student's t, pooled s = 0.0892373)
Implementation-wise, when merging two weak symbols, this sets a
"canOmitFromOutput" on the InputSection belonging to the weak symbol not put in
the symbol table. We then don't write InputSections that have this set, as long
as they are not referenced from other symbols. (This happens e.g. for object
files that don't set .subsections_via_symbols or that use .alt_entry.)
Some restrictions:
- not yet done for bitcode inputs
- no "comdat" handling (`kindNoneGroupSubordinate*` in ld64) --
Frame Descriptor Entries (FDEs), Language Specific Data Areas (LSDAs)
(that is, catch block unwind information) and Personality Routines
associated with weak functions still not stripped. This is wasteful,
but harmless.
- However, this does strip weaks from __unwind_info (which is needed for
correctness and not just for size)
- This nopes out on InputSections that are referenced form more than
one symbol (eg from .alt_entry) for now
Things that work based on symbols Just Work:
- map files (change in MapFile.cpp is no-op and not needed; I just
found it a bit more explicit)
- exports
Things that work with inputSections need to explicitly check if
an inputSection is written (e.g. unwind info).
This patch is useful in itself, but it's also likely also a useful foundation
for dead_strip.
I used to have a "canoncialRepresentative" pointer on InputSection instead of
just the bool, which would be handy for ICF too. But I ended up not needing it
for this patch, so I removed that again for now.
Differential Revision: https://reviews.llvm.org/D102076
ld64 can emit dylibs that support more than one platform (typically macOS and
macCatalyst). This diff allows LLD to read in those dylibs. Note that this is a
super bare-bones implementation -- in particular, I haven't added support for
LLD to emit those multi-platform dylibs, nor have I added a variety of
validation checks that ld64 does. Until we have a use-case for emitting zippered
dylibs, I think this is good enough.
Fixes PR49597.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D101954
Currently the linker causes unnecessary errors when either the target or the config's platform is a simulator.
Differential Revision: https://reviews.llvm.org/D101855
ARM_RELOC_BR24 is used for BL/BLX instructions from within ARM (i.e. not
Thumb) code. This diff just handles the basic case: branches from ARM to
ARM, or from ARM to Thumb where no shimming is required. (See comments
in ARM.cpp for why shims are required.)
Note: I will likely be deprioritizing ARM work for the near future to
focus on other parts of LLD. Apologies for the half-done state of this;
I'm just trying to wrap up what I've already worked on.
Reviewed By: #lld-macho, alexshap
Differential Revision: https://reviews.llvm.org/D101814
We need to account for path rerooting when generating the response
file. We could either reroot the paths before generating the file, or pass
through the original filenames and change just the syslibroot. I've opted for
the latter, in order that the reproduction run more closely mirrors the
original.
We must also be careful *not* to make an absolute path relative if it is
shadowed by a rerooted path. See repro6.tar in reroot-path.s for
details.
I've moved the call to `createResponseFile()` after the initialization of
`config->systemLibraryRoots`, since it now needs to know what those roots are.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D101224
ld64 automatically renames many sections depending on output type and assorted flags. Here, we implement the most common configs. We can add more obscure flags and behaviors as needed.
Depends on D101393
Differential Revision: https://reviews.llvm.org/D101395
@thakis pointed out that `mach_header` and `mach_header_64`
actually have the same set of (used) fields, with the 64-bit version
having extra padding. So we can access the fields we need using the
single `mach_header` type instead of using templates to switch between
the two.
I also spotted a potential issue where hasObjCSection tries to parse a
file w/o checking if it does indeed match the target arch... As such,
I've added a quick magic number check to ensure we don't access invalid
memory during `findCommand()`.
Addresses PR50180.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D101724
This just parses the `-arch armv7` and emits the right header flags.
The rest will be slowly fleshed out in upcoming diffs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D101557
Modern versions of macOS (>= 10.7) and in general all modern Mach-O
target archs want PIEs by default. ld64 defaults to PIE for iOS >= 4.3,
as well as for all versions of watchOS and simulators. Basically all the
platforms LLD is likely to target want PIE. So instead of cluttering LLD's
code with legacy version checks, I think it's simpler to just default to
PIE for everything.
Note that `-no_pie` still works, so users can still opt out of it.
Reviewed By: #lld-macho, thakis, MaskRay
Differential Revision: https://reviews.llvm.org/D101513
As preparation for a subsequent diff that implements builtin section renaming, define more `constexpr` strings in namespaces `lld::macho::segment_names` and `lld::macho::section_names`, and use them to replace string literals.
Differential Revision: https://reviews.llvm.org/D101393
Add option to limit (or remove limits) on the number of errors printed before exiting. This option exists in the other lld ports: COFF & ELF.
Differential Revision: https://reviews.llvm.org/D101274
When I added this assert in D93609, it asserted that a symbol that
is privateExtern is also isExternal().
In D98381 the privateExtern check moved into shouldExportSymbol()
but the assert didn't -- now it checked that _every_ non-exported
symbol is isExternal(), which isn't true. Move the assert into the
privateExtern check where it used to be.
Fixes PR50098.
Differential Revision: https://reviews.llvm.org/D101223
We were taking a reference to a value in `loadedDylibs`, which in turn
called `make<DylibFile>()`, which could then recursively call
`loadDylibs`, which would then potentially resize `loadedDylibs` and
invalidate that reference.
Fixes PR50101.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D101175
I was a bit confused by the comment because I thought that "Tests
that..." was describing the tests contained within the same file.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D101160
I went through the callers of `readFile()` and `addFile()` in Driver.cpp
and checked that the options that use them all get rewritten in the
--reproduce response file. -(un)exported_symbols_list and -bundle_loader
weren't, so add them.
Also spruce up the test for reproduce a bit and actually try linking
with the exptracted repro archive.
Motivated by the response file in PR50098 complaining abou the
-exported_symbols_list path being wrong :)
Differential Revision: https://reviews.llvm.org/D101182
I first had a more invasive patch for this (D101069), but while trying
to get that polished for review I realized that lld's current symbol
merging semantics mean that only a very small code change is needed.
So this goes with the smaller patch for now.
This has no effect on projects that build with -fvisibility=hidden
(e.g. chromium), since these see .private_extern symbols instead.
It does have an effect on projects that build with -fvisibility-inlines-hidden
(e.g. llvm) in -O2 builds, where LLVM's GlobalOpt pass will promote most inline
functions from .weak_definition to .weak_def_can_be_hidden.
Before this patch:
% ls -l out/gn/bin/clang out/gn/lib/libclang.dylib
-rwxr-xr-x 1 thakis staff 113059936 Apr 22 11:51 out/gn/bin/clang
-rwxr-xr-x 1 thakis staff 86370064 Apr 22 11:51 out/gn/lib/libclang.dylib
% out/gn/bin/llvm-objdump --macho --weak-bind out/gn/bin/clang | wc -l
8291
% out/gn/bin/llvm-objdump --macho --weak-bind out/gn/lib/libclang.dylib | wc -l
5698
With this patch:
% ls -l out/gn/bin/clang out/gn/lib/libclang.dylib
-rwxr-xr-x 1 thakis staff 111721096 Apr 22 11:55 out/gn/bin/clang
-rwxr-xr-x 1 thakis staff 85291208 Apr 22 11:55 out/gn/lib/libclang.dylib
thakis@MBP llvm-project % out/gn/bin/llvm-objdump --macho --weak-bind out/gn/bin/clang | wc -l
725
thakis@MBP llvm-project % out/gn/bin/llvm-objdump --macho --weak-bind out/gn/lib/libclang.dylib | wc -l
542
Linking clang becomes a tiny bit faster with this patch:
x 100 0.67263818 0.77847815 0.69430709 0.69877208 0.017715892
+ 100 0.67209601 0.73323393 0.68600798 0.68917346 0.012824377
Difference at 95.0% confidence
-0.00959861 +/- 0.00428661
-1.37364% +/- 0.613449%
(Student's t, pooled s = 0.0154648)
This only happens if lld with the patch and lld without the patch are both
linked with an lld with the patch or both linked with an lld without the patch
(...or with ld64). I accidentally linked the lld with the patch with an lld
without the patch and the other way round at first. In that setup, no
difference is found. That makese sense, since having fewer weak imports will
make the linked output a bit faster too. So not only does this make linking
binaries such as clang a bit faster (since fewer exports need to be written to
the export trie by lld), the linked output binary binary is also a bit faster
(since dyld needs to process fewer dynamic imports).
This also happens to fix the one `check-clang` failure when using lld as host
linker, but mostly for silly reasons: See crbug.com/1183336, mostly comment 26.
The real bug here is that c-index-test links all of LLVM both statically and
dynamically, which is an ODR violation. Things just happen to work with this
patch.
So after this patch, check-clang, check-lld, check-llvm all pass with lld as
host linker :)
Differential Revision: https://reviews.llvm.org/D101080
We had got it backwards... the minimum version of the target
should be higher than the min version of the object files, presumably
since new platforms are backwards-compatible with older formats.
Fixes PR50078.
The original commit (aa05439c9c) broke many tests that had inputs too
new for our target platform (10.0). This commit changes the inputs to
target 10.0, which was the simpler thing to do, but we should really
just have our lit.local.cfg default to targeting 10.15... we're not
likely to ever have proper support for the older versions anyway. I will
follow up with a change to that effect.
Differential Revision: https://reviews.llvm.org/D101114
We had got it backwards... the minimum version of the target
should be higher than the min version of the object files, presumably
since new platforms are backwards-compatible with older formats.
Fixes PR50078.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D101114
This load command records a range spanning from the end of the load
commands to the end of the `__TEXT` segment. Presumably the kernel will encrypt
all this data.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D100973
This diff adds initial support for the legacy LC_VERSION_MIN_* load commands.
Test plan: make check-lld-macho
Differential revision: https://reviews.llvm.org/D100523
XCode 12 ships with mismatched platforms for these libraries,
so this hack is necessary...
Fixes PR49799.
Reviewed By: #lld-macho, gkm, smeenai
Differential Revision: https://reviews.llvm.org/D100913
codesign/libstuff checks that the `__LLVM` segment is directly
before `__LINKEDIT` by checking that `fileOff + fileSize == next segment
fileOff`. Previously, there would be gaps between the segments due to
the fact that their fileOffs are page-aligned but their fileSizes
aren't. In order to satisfy codesign, we page-align fileOff *before*
calculating fileSize. (I don't think codesign checks for the relative
ordering of other segments, so in theory we could do this just for
`__LLVM`, but ld64 seems to do it for all segments.)
Note that we *don't* round up the fileSize of the `__LINKEDIT` segment.
Since it's the last segment, it doesn't need to worry about contiguity;
in addition, codesign checks that the last (hidden) section in
`__LINKEDIT` covers the last byte of the segment, so if we rounded up
`__LINKEDIT`'s size we would have to do the same for its last section,
which is a bother.
While at it, I also addressed a FIXME in the linkedit-contiguity.s test
to cover more `__LINKEDIT` sections.
Reviewed By: #lld-macho, thakis, alexshap
Differential Revision: https://reviews.llvm.org/D100848
The minuend (but not the subtrahend) can reference a section.
Note that we do not yet properly validate that the subtrahend isn't
referencing a section; I've filed PR50034 to track that.
I've also extended the reloc-subtractor.s test to reorder symbols, to
make sure that the addends are being associated with the minuend (and not
the subtrahend) relocation.
Fixes PR49999.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D100804
This diff creates an empty XAR file and copies it into
`__LLVM,__bundle`. Follow-up work will actually populate the contents of
that XAR.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D100650
MSVC from VSCode 2017 appears unhappy with it (causes an
internal compiler error.)
This also means that we need to avoid doing `sizeof(stubCode)` as
`sizeof(int[N])` on function array parameters decays into `sizeof(int *)`.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D100605
arm64_32 uses 32-bit GOT loads, so we should accept those
instructions in `ARM64Common::relaxGotLoad()` too.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D100229
This could probably have been part of D99633, but I split it up to make
things a bit more reviewable. I also fixed some bugs in the implementation that
were masked through integer underflows when operating in 64-bit mode.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99823
From what I can tell, it's pretty similar to arm64. The two main differences
are:
1. No 64-bit relocations
2. Stub code writes to 32-bit registers instead of 64-bit
Plus of course the various on-disk structures like `segment_command` are using
the 32-bit instead of the 64-bit variants.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99822
This allows LLVM's LTO to internalize symbols that are not referenced
directly by regular objects. Naturally, this means we need to track
which symbols are referenced by regular objects. The approach taken here
is similar to LLD-COFF's: like the COFF port, we extend
`SymbolTable::insert()` to set the isVisibleToRegularObj bit. (LLD-ELF
relies on the Symbol constructor and `Symbol::mergeProperties()`, but
the Mach-O port does not have a `mergeProperties()` equivalent.)
From what I can tell, ld64 (which uses libLTO) doesn't do this
optimization at all. I'm not even sure libLTO provides a way to do this.
Not having ld64's behavior as a reference implementation is unfortunate;
instead, I am relying on LLD-ELF/COFF's behavior as references while
erring on the conservative side. In particular, LLD-MachO will only do
this optimization for executables right now.
We also don't attempt it when `-flat_namespace` is used -- otherwise
we'd need scan the symbol table to find matches for every un-namespaced
symbol reference, which is expensive.
internalize.ll is based off the LLD-ELF tests `internalize-basic.ll` and
`internalize-undef.ll`. Looks like @davide added some of LLD-ELF's internalize
tests, so adding him as a reviewer...
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99105
arm64_32 uses 32-bit GOT loads, so we should accept those
instructions in `ARM64Common::relaxGotLoad()` too.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D100229
It doesn't make sense to take just the base filename for archives when we emit
the full path for object files. (LLD-ELF emits the full path too.)
This will also make it easier to write a proper test for {D100147}.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D100357
This could probably have been part of D99633, but I split it up to make
things a bit more reviewable. I also fixed some bugs in the implementation that
were masked through integer underflows when operating in 64-bit mode.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99823
From what I can tell, it's pretty similar to arm64. The two main differences
are:
1. No 64-bit relocations
2. Stub code writes to 32-bit registers instead of 64-bit
Plus of course the various on-disk structures like `segment_command` are using
the 32-bit instead of the 64-bit variants.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99822
It's likely redundant, per discussion with @gkm. The BYTE8
attribute covers the bit width requirement already.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D100133
Swift builds seem to use it. All it requires is emitting the
corresponding paths as STABS.
Fixes llvm.org/PR49385.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D100076
The test is loosely based off LLD-ELF's `thinlto.ll`. However, I
found that test questionable because the the -save_temps behavior it
checks for is identical regardless of whether we are running in single-
or multi-threaded mode. I tried writing a test based on `--time-trace`
but couldn't get it to run deterministically... so I've opted to just
skip checking that behavior for now.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99356
Benchmarking chromium_framework on a 3.2 GHz 16-Core Intel Xeon W Mac Pro:
N Min Max Median Avg Stddev
x 20 4.33 4.42 4.37 4.37 0.021026299
+ 20 4.12 4.23 4.18 4.175 0.035318103
Difference at 95.0% confidence
-0.195 +/- 0.0186025
-4.46224% +/- 0.425686%
(Student's t, pooled s = 0.0290644)
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D99998
If either `time-trace-granularity` or `time-trace-file` is specified, then don't make users specify `-time-trace`.
It seems silly that I have to type all three options, eg, `-time-trace -time-trace-file=- -time-trace-granularity=...`.
Differential Revision: https://reviews.llvm.org/D100011
- use "empty()" instead of "size()"
- refactor the re-export code so it doesn't create a new vector every time.
Differential Revision: https://reviews.llvm.org/D100019
We had been giving them a string index of zero, which actually corresponds to a
string with a single space due to {D89639}.
This was far from obvious in the old test because llvm-nm doesn't quote the
symbol names, making the empty string look identical to a string of a single
space. `dsymutil -s` quotes its strings, so I've changed the test accordingly.
Fixes llvm.org/PR48714. Thanks @clayborg for the tips!
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D100003
I noticed two problems with the previous implementation:
* N_ALT_ENTRY symbols weren't being handled correctly -- they should
determine the size of the previous symbol, even though they don't
cause a new section to be created
* The last symbol in a section had its size calculated wrongly;
the first subsection's size was used instead of the last one
I decided to take the opportunity to refactor things as well, mainly to
realize my observation
[here](https://reviews.llvm.org/D98837#inline-931511) that we could
avoid doing a binary search to match symbols with subsections. I think
the resulting code is a bit simpler too.
N Min Max Median Avg Stddev
x 20 4.31 4.43 4.37 4.3775 0.034162922
+ 20 4.32 4.43 4.38 4.3755 0.02799906
No difference proven at 95.0% confidence
Reviewed By: #lld-macho, alexshap
Differential Revision: https://reviews.llvm.org/D99972
We bikeshedded about it here: https://reviews.llvm.org/D98837#inline-931557
I initially suggested SubsectionMapping, but I thought the discussion
landed on doing `std::vector<SubsectionEntry>`. @alexshap went and did
both, but on hindsight I regret adding 3 more characters to an already
long name, and I think SubsectionEntry is descriptive enough...
This diff also renames `subsectionMap` to `subsecMap` for consistency
with other variable names in the codebase.
TextAPI/ELF has moved out into InterfaceStubs, so theres no longer a
need to seperate out TextAPI between formats.
Reviewed By: ributzka, int3, #lld-macho
Differential Revision: https://reviews.llvm.org/D99811
The main challenge was handling the different on-disk structures (e.g.
`mach_header` vs `mach_header_64`). I tried to strike a balance between
sprinkling `target->wordSize == 8` checks everywhere (branchy = slow, and ugly)
and templatizing everything (causes code bloat, also ugly). I think I struck a
decent balance by judicious use of type erasure.
Note that LLD-ELF has a similar architecture, though it seems to use more templating.
Linking chromium_framework takes about the same time before and after this
change:
N Min Max Median Avg Stddev
x 20 4.52 4.67 4.595 4.5945 0.044423204
+ 20 4.5 4.71 4.575 4.582 0.056344803
No difference proven at 95.0% confidence
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D99633
`class Symbol` defines a data member `InputFile *file;`
`class Defined` inherits from `Symbol` and also defines a data member `InputFile *file;` for no apparent purpose.
Differential Revision: https://reviews.llvm.org/D99783
This diff addresses FIXME in SyntheticSections.cpp and removes
the dependency of emitEndFunStab on .subsections_via_symbols.
Test plan: make check-lld-macho
Differential revision: https://reviews.llvm.org/D99054
This diff is a preparation for fixing FunStabs (incorrect size calculation).
std::map<uint32_t, InputSection*> (SubsectionMap) is replaced with
a sorted vector + binary search. If .subsections_via_symbols is set
this vector will contain the list of subsections, otherwise,
the offsets will be used for calculating the symbols sizes.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D98837
This reuses the approach (and some code) from LLD-ELF.
It's a decent win when linking chromium_framework on a Mac Pro (3.2 GHz 16-Core Intel Xeon W):
N Min Max Median Avg Stddev
x 20 4.58 4.83 4.66 4.6685 0.066591844
+ 20 4.42 4.61 4.5 4.505 0.04751731
Difference at 95.0% confidence
-0.1635 +/- 0.0370242
-3.5022% +/- 0.793064%
(Student's t, pooled s = 0.0578462)
The output binary is 381MB.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D99279
Within `lld/macho/`, only `InputFiles.cpp` and `Symbols.h` require the `macho::` namespace qualifier to disambiguate references to `class Symbol`.
Add braces to outer `for` of a 5-level single-line `if`/`for` nest.
Differential Revision: https://reviews.llvm.org/D99555
Summary: We needed to use `Joined` instead of `Flag`. This wasn't caught
because the relevant test that was copied from LLD-ELF was still
invoking LLD-ELF instead of LLD-MachO...
Differential Revision: https://reviews.llvm.org/D99313
Pretty simple code-wise. Also threw in some refactoring:
* Put the functionStartSection under Writer instead of InStruct, since
it doesn't need to be accessed outside of Writer
* Adjusted the test to put all files under the temp dir instead of at
the top-level
* Added some CHECK-LABELs to make it clearer where the function starts
data is
Differential Revision: https://reviews.llvm.org/D99112
I added just enough to allow us to see a top-level breakdown of time taken. This
is the result of loading the time-trace output into `chrome:://tracing`:
ef5e8234f3/tracing.png
Reviewed By: oontvoo
Differential Revision: https://reviews.llvm.org/D99311
This reverts commit 4876ba5b2d.
Third-attemp relanding D98559, new change:
- explicitly cast enum to underlying type to avoid ambiguity (workaround to clang's bug).
This reverts commit 3c21166a94.
The build is broken (clang-8 host compiler):
lld/MachO/DriverUtils.cpp:271:8: error: use of overloaded operator '<<' is ambiguous (with operand types 'llvm::raw_fd_ostream' and 'lld::macho::DependencyTracker::DepOpCode')
os << opcode;
~~ ^ ~~~~~~
This reverts commit 9670d2e4af.
Second attemp to reland D98559. New changes:
- inline functions removed from cpp file.
- updated tests to use CHECK-DAG instead of CHECK-NEXT
- fixed ambiguous "<<" operator by switching `char` to uint8_t
This reverts commit 2554b95db5.
Relanding [lld-macho] Implement -dependency_info (D98559) with changes:
- inline functions removed from cpp file.
- updated tests to not check libSystem.tbd with other input files (because of possible indeterministic ordering)
This reverts commit c53a1322f3.
Test only passes depending on build dir having a lexicographically later name
than the source dir, and doesn't link on mac/win. See
https://reviews.llvm.org/D98559#2640265 onward.
Bug: https://bugs.llvm.org/show_bug.cgi?id=49278
The flag is not well documented, so this implementation is based on observed behaviour.
When specified, `-dependency_info <path>` produced a text file containing information pertaining to the current linkage, such as input files, output file, linker version, etc.
This file's layout is also not documented, but it seems to be a series of null ('\0') terminated strings in the form `<op code><path>`
`<op code>` could be:
`0x00` : linker version
`0x10` : input
`0x11` : files not found(??)
`0x40` : output
`<path>` : is the file path, except for the linker-version case.
(??) This part is a bit unclear. I think it means all the files the linker attempted to look at, but could not find.
Differential Revision: https://reviews.llvm.org/D98559
Move some functions closer to their uses. Move detailed address-assignment logic out of the otherwise abstract `Writer::run()`. This prepares the ground for a diff to implement branch range extension thunks.
* `SyntheticSections.cpp`
** move `needsBinding()` and `prepareBranchTarget()` into `Writer.cpp`
** move `addNonLazyBindingEntries()` adjacent to its use.
* `Writer.cpp`
** move address-assignment logic from `Writer::run()` into new function `Writer::assignAddresses()`
** move `needsBinding()` and `prepareBranchTarget()` from `SyntheticSections.cpp`
* `Target.h`
** remove orphaned decls of `prepareSymbolRelocation()` and `validateRelocationInfo()` which were moved to other files in earlier diffs.
Differential Revision: https://reviews.llvm.org/D98795
This fixes defects in D98223 [lld-macho] implement options -(un)exported_symbol(s_list):
* disallow export of hidden symbols
* verify that whitelisted literal names are defined in the symbol table
* reflect export-status overrides in `nlist` attribute of `N_EXT` or `N_PEXT`
Thanks to @thakis for raising these issues
Differential Revision: https://reviews.llvm.org/D98381
This pleases the codesign
(Otherwise it complains about "function starts data out of place")
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D98648
They were previously in SyntheticSections.h, but now there are
a bunch of non-synthetic section names in the list.
Also renamed `__functionStarts` to `__func_starts` for uniformity with
other section names + keeps the name under 16 characters (in case we ever
want to write it out as a real section).
Reviewed By: #lld-macho, compnerd
Differential Revision: https://reviews.llvm.org/D98586
Previously, it was difficult to write code that handled both synthetic
and regular sections generically. We solve this problem by creating a
fake InputSection at the start of every SyntheticSection.
This refactor allows us to handle DSOHandle like a regular Defined
symbol (since Defined symbols must be attached to an InputSection), and
paves the way for supporting `__mh_*header` symbols. Additionally, it
simplifies our binding/rebase code.
I did have to extend Defined a little -- it now has a `linkerInternal`
flag, to indicate that `___dso_handle` should not be in the final symbol
table.
I've also added some additional testing for `___dso_handle`.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D98545
This diff required fixing `getEmbeddedAddend` to apply sign
extension to 32-bit values. We were previously passing around wrong
64-bit addend values that became "right" after being truncated back to
32-bit.
I've also made `getEmbeddedAddend` return a signed int, which is similar
to what LLD-ELF does for its `getImplicitAddend`.
`reportRangeError`, `checkUInt`, and `checkInt` are counterparts of similar
functions in LLD-ELF.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D98387
SUBTRACTOR relocations are always paired with UNSIGNED
relocations to indicate a pair of symbols whose address difference we
want. Functionally they are like a single relocation: only one pointer
gets written / relocated. Previously, we would handle these pairs by
skipping over the SUBTRACTOR relocation and writing the pointer when
handling the UNSIGNED reloc. This diff reverses things, so we write
while handling SUBTRACTORs and skip over the UNSIGNED relocs instead.
Being able to distinguish between SUBTRACTOR and UNSIGNED relocs in the
write phase (i.e. inside `relocateOne`) is useful for the upcoming range
check diff: we want to check that SUBTRACTOR relocs write signed values,
but UNSIGNED relocs (naturally) write unsigned values.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D98386
The previous implementation miscalculated the addend, resulting
in an underflow. This meant that every SIGNED_N section relocation would
be associated with the last subsection (since the addend would now be a
huge number). We were "lucky" that this mistake was typically cancelled
out -- 64-to-32-bit-truncation meant that the final value was correct,
as long as subsections were not rearranged.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D98385
Previously, SyntheticSections.cpp did not have a top-level `using namespace
llvm::MachO` because it caused a naming conflict: `llvm::MachO::Symbol` would
collide with `lld::macho::Symbol`.
`MachO::Symbol` represents the symbols defined in InterfaceFiles (TBDs). By
moving the inclusion of InterfaceFile.h into our .cpp files, we can avoid this
name collision in other files where we are only dealing with LLD's own symbols.
Along the way, I removed all unnecessary "MachO::" prefixes in our code.
Cons of this approach: If TextAPI/MachO/Symbol.h gets included via some other
header file in the future, we could run into this collision again.
Alternative 1: Have either TextAPI/MachO or BinaryFormat/MachO.h use a different
namespace. Most of the benefit of `using namespace llvm::MachO` comes from being
able to use things in BinaryFormat/MachO.h conveniently; if TextAPI was under a
different (and fully-qualified) namespace like `llvm::tapi` that would solve our
problems. Cons: lots of files across llvm-project will need to be updated, and
folks who own the TextAPI code need to agree to the name change.
Alternative 2: Rename our Symbol to something like `LldSymbol`. I think this is
ugly.
Personally I think alternative #1 is ideal, but I'm not sure the effort to do it is
worthwhile, this diff's halfway solution seems good enough to me. Thoughts?
Reviewed By: #lld-macho, oontvoo, MaskRay
Differential Revision: https://reviews.llvm.org/D98149
This is the minimal port from ELF. Any extension should easy from here
Test plan: ninja check-all-macho
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D98419
Pointer and reference induction variables of range-based for loops are often const, and code authors often lax about qualifying them.
Differential Revision: https://reviews.llvm.org/D98317
The flag doesn't (and shouldn't) have an effect in that case.
ld64 doesn't warn on this, but it seems like a good thing to do.
If it causes problems in practice for some reason, we can revert it.
Also add a dedicated test for install_name.
Differential Revision: https://reviews.llvm.org/D98259
lld doesn't read MH_DEAD_STRIPPABLE_DYLIB to strip dead dylibs yet,
but now it can produce dylibs with it set.
While here, also switch an existing test that looks only at the main Mach-O
header from --all-headers to --private-header.
Differential Revision: https://reviews.llvm.org/D98262
Top-level `using llvm::opt` has been present in `lld/MachO/Driver*.cpp` for some time, so remove lingering `opt::` prefixes.
Differential Revision: https://reviews.llvm.org/D98314
lld policy discourages `auto`. Replace it with a type name whenever reasonable. Retain `auto` to avoid ...
* redundancy, as for decls such as `auto *t = mumble_cast<TYPE *>` or similar that specifies the result type on the RHS
* verbosity, as for iterators
* gratuitous suffering, as for lambdas
Along the way, add `const` when appropriate.
Note: a future diff will ...
* add more `const` qualifiers
* remove `opt::` when we are already `using llvm::opt`
Differential Revision: https://reviews.llvm.org/D98313
Implement command-line options to alter a dylib's exported-symbols list:
* `-exported_symbol*` options override the default export list. The export list is compiled according to the command-line option(s) only.
* `-unexported_symbol*` options hide otherwise public symbols.
* `-*exported_symbol PATTERN` options specify a single literal or glob pattern.
* `-*exported_symbols_list FILE` options specify a file containing a series of lines containing symbol literals or glob patterns. Whitespace and `#`-prefix comments are stripped.
Note: This is a simple implementation of the primary use case. ld64 has much more complexity surrounding interactions with other options, many of which are obscure and undocumented. We will start simple and complexity as necessary.
Differential Revision: https://reviews.llvm.org/D98223
Add first bits for emitting LC_FUNCTION_STARTS.
This is a recommit of f344dfeb with the adjusted test
which should address build bots breakages.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D97260
These are mostly things that ld64 has itself marked obsolete.
In the case of `-sectorder`, it's suggested in ld64's manpage that it
could be deprecated, so let's skip implementing it for now.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D98066
clang appears to emit symbols in `__debug_aranges`, at least
for arm64... in the examples I've seen, it doesn't seem like those
symbols are referenced outside of `__DWARF`, so I think they're safe to
ignore. But hopefully @clayborg can confirm.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D98073
We'll need to properly handle object files with multiple source inputs
eventually, but remove the assert for now so we can successfully emit binaries
for testing.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D98067
With this, llvm-tblgen no longer tries and fails to allocate 7953 petabyte
when it runs during the build. Instead, `check-llvm` with lld/mac as host
linker now completes without any failures on an m1 mac.
This vector op handling code matches what happens in:
- ld64's OutputFile::applyFixUps() in OutputFile.cpp for kindStoreARM64PageOff12
- lld.ld64.darwinold's offset12KindFromInstruction() in
lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp for offset12scale16
- RuntimeDyld's decodeAddend() in
llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h for
ARM64_RELOC_PAGEOFF12
Fixes PR49444.
Differential Revision: https://reviews.llvm.org/D98053
Previously, lld/mac only ad-hoc codesigned executables on arm64.
Matches ld64 behavior. Part of PR49443. Fixes 14 of 17 failures when running
check-llvm with lld as host linker on an M1 MBP.
Differential Revision: https://reviews.llvm.org/D97994
Since multiple dylibs can be defined in one TBD, this is
necessary to avoid confusion.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D97905
Previously, we were loading re-exports without checking whether
they were compatible with our target. Prior to {D97209}, it meant that
we were defining dylib symbols that were invalid -- usually a silent
failure unless our binary actually used them. D97209 exposed this as an
explicit error.
Along the way, I've extended our TAPI compatibility check to cover the
platform as well, instead of just checking the arch. To this end, I've
replaced MachO::Architecture with MachO::Target in our Config struct.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D97867
The reexport-nested-libs test added in D97438 was a bit wonky.
First, it was linking against libReexportSystem.tbd which targets the
iOS simulator, and which in turn attempted to re-export the iOS
simulator's libSystem. However, due to the way `-syslibroot` works, it
was actually re-exporting the macOS libSystem.
As a result, the test was not actually able to resolve the symbols in
the desired libSystem. I'm guessing that @oontvoo was confused by this
and therefore included those symbols in libReexportSystem.tbd itself.
But this means that the test wasn't actually testing the resolution of
re-exported symbols (though it did at least verify that the re-exported
libraries could be located).
After some consideration, I figured that stub-link.s could be extended
to cover what reexport-nested-libs.s was attempting to do. The test
targets macOS, so we only have one `-syslibroot` and no chance of
confusion.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D97866
Suppose we are linking against libFoo, which re-exports the
implicitly-bound libSystem, which in turn re-exports some
non-explicitly-bound library like `/usr/lib/system/libsystem_c.dylib`.
Then any bindings we have to a symbol in libsystem_c should use
libSystem (and not libFoo) as the umbrella library.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D97865
We previously defaulted to x86_64 and an unknown platform, which was fine when
we only supported one arch and did no platform checks, but that will no longer
be true going ahead. Therefore, we should require those flags to be specified
whenever the linker is invoked.
Note that LLD-ELF and ld64 both infer the arch from their input object files,
but the usefulness of that is questionable since clang will always specify these
flags, and most of the time `lld` will be invoked via clang.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D97799
The option-iterating loop should be reserved for options whose command-line
order is important. I think LLD-ELF follows a similar design.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D97797
This reverts diff D97610 (commit 0223ab035c) and adds a one-line fix to verify that a `MemoryBufferRef` has sufficient length before reading a 4-byte magic number.
Differential Revision: https://reviews.llvm.org/D97757
Currently, it was delibrately impleneted to not handle this case, but as it has turnt out, we need this feature.
The concrete use case is
`System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa` reexports
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit , which then rexports
/System/Library/PrivateFrameworks/UIFoundation.framework/Versions/A/UIFoundation
The current implemention uses a global currentTopLevelTapi, which is not reset until it finishes loading the whole tree.
This is a problem because if the top-level is set to Cocoa, then when we get to UIFoundation, it will try to find UIFoundation in the current top level, which is Cocoa and will not find it.
The right thing should be:
- When loading a library from a TBD file, re-exports need to be looked up in the auxiliary documents within the same TBD.
- When loading from an actual dylib, no additional TBD documents need to be examined.
- In no case does a re-export mentioned in one TBD file need to be looked up in a document in an auxiliary document from a different TBD file
Differential Revision: https://reviews.llvm.org/D97438
This adds support for `-undefined dynamic_lookup`, and for
`-undefined warning` and `-undefined suppress` with `-flat_namespace`.
We just replace undefined symbols with a DynamicLookup when we hit them.
With this, `check-llvm` passes when using ld64.lld.darwinnew as host linker.
Differential Revision: https://reviews.llvm.org/D97642
-flat_namespace makes lld emit binaries that use name lookup that's more in
line with other POSIX systems: Instead of looking up symbols as (dylib,name)
pairs by dyld, they're instead looked up just by name.
-flat_namespace has three effects:
1. MH_TWOLEVEL and MH_NNOUNDEFS are no longer set in the Mach-O header
2. All symbols use BIND_SPECIAL_DYLIB_FLAT_LOOKUP as ordinal
3. When a dylib is added to the link, its dependent dylibs are also added,
so that lld can verify that no undefined symbols remain at the end of
a link with -flat_namespace. These transitive dylibs are added for symbol
resolution, but they are not emitted in LC_LOAD_COMMANDs.
-undefined with -flat_namespace still isn't implemented. Before this change,
it was impossible to hit that combination because -flat_namespace caused a
diagnostic. Now that it no longer does, emit a dedicated temporary diagnostic
when both flags are used.
Differential Revision: https://reviews.llvm.org/D97641
Matches the ELF and COFF ports, which use ld.lld and lld-link, respectively.
While here, also move up `cleanupCallback` to match ELF / COFF.
Differential Revision: https://reviews.llvm.org/D97715
There was initially some concern around the correct handling of pcrel
section relocations with r_length != 2. But it looks like there are no such
relocations in practice -- x86_64's pcrel section relocs all have r_length == 2,
and ARM64 doesn't even have pcrel section relocs. So we can replace the TODO
with an assert.
Reviewed By: #lld-macho, thakis
Differential Revision: https://reviews.llvm.org/D97576
Only one of the two callers used the lastBinding parameter, so
do that work at that one call site. Extract a ordinalForDylibSymbol()
helper to make this tidy.
No behavior change.
Differential Revision: https://reviews.llvm.org/D97597
Bifurcate the `readFile()` API into ...
* `readRawFile()` which performs no checks, and
* `readLinkableFile()` which enforces minimum length of 20 bytes, same as ld64
There are no new tests because tweaks to existing tests are sufficient.
Differential Revision: https://reviews.llvm.org/D97610
On arm64, UNSIGNED relocs are the only ones that use embedded addends
instead of the ADDEND relocation.
Also ensure that the addend works when UNSIGNED is part of a SUBTRACTOR
pair.
Reviewed By: #lld-macho, alexshap
Differential Revision: https://reviews.llvm.org/D97105
Also add a few asserts to verify that we are indeed handling an
UNSIGNED relocation as the minued. I haven't made it an actual
user-facing error since I don't think llvm-mc is capable of generating
SUBTRACTOR relocations without an associated UNSIGNED.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D97103
`llvm-mc` doesn't generate any relocations for subtractions
between local symbols -- they must be global -- so the previous test
wasn't actually testing any relocation logic. I've fixed that and
extended the test to cover r_length=3 relocations as well as both x86_64
and arm64.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D97057
Dynamic lookup symbols are symbols that work like dynamic symbols
in ELF: They're not bound to a dylib like normal Mach-O twolevel lookup
symbols, but they live in a global pool and dyld resolves them against
exported symbols from all loaded dylibs.
This adds support for dynamical lookup symbols to lld/mac. They are
represented as DylibSymbols with file set to nullptr.
This also uses this support to implement the -U flag, which makes
a specific symbol that's undefined at the end of the link a
dynamic lookup symbol.
For -U, it'd be sufficient to just to a pass over remaining undefined symbols
at the end of the link and to replace them with dynamic lookup symbols then.
But I'd like to use this code to implement flat_namespace too, and that will
require real support for resolving dynamic lookup symbols in SymbolTable. So
this patch adds this now already.
While writing tests for this, I noticed that we didn't set N_WEAK_DEF in the
symbol table for DylibSymbols, so this fixes that too.
Differential Revision: https://reviews.llvm.org/D97521
When parsing bitcode, convert LTO Symbols to LLD Symbols in order to perform
resolution. The "winning" symbol will then be marked as Prevailing at LTO
compilation time. This is similar to what the other LLD ports do.
This change allows us to handle `linkonce` symbols correctly, and to deal with
duplicate bitcode symbols gracefully. Previously, both scenarios would result in
an assertion failure inside the LTO code, complaining that multiple Prevailing
definitions are not allowed.
While at it, I also added basic logic around visibility. We don't do anything
useful with it yet, but we do check that its value is valid. LLD-ELF appears to
use it only to set FinalDefinitionInLinkageUnit for LTO, which I think is just a
performance optimization.
From my local experimentation, the linker itself doesn't seem to do anything
differently when encountering linkonce / linkonce_odr / weak / weak_odr. So I've
only written a test for one of them. LLD-ELF has more, but they seem to mostly
be testing the intermediate bitcode output of their LTO backend...? I'm far from
an expert here though, so I might very well be missing things.
Reviewed By: #lld-macho, MaskRay, smeenai
Differential Revision: https://reviews.llvm.org/D94342
{D95809} introduced a mechanism for synthetic symbol creation of personality
pointers. When multiple section relocations referred to the same personality
pointer, it would deduplicate them. However, it neglected to consider that we
could have symbol relocations that also refer to the same personality pointer.
This diff fixes it.
In practice, this mix of relocations arises when there is a statically-linked
personality routine that is referenced from multiple object files. Within the
same object file, it will be referred to via section relocations, but
(obviously) other object files will refer to it via symbol relocations. Failing
to deduplicate these references resulted in us going over the
3-personality-pointer limit when linking some larger applications.
Fixes llvm.org/PR48389.
Reviewed By: #lld-macho, thakis, alexshap
Differential Revision: https://reviews.llvm.org/D97245
The silent failures had confused me a few times.
I haven't added a similar check for platform yet as we don't yet have logic to
infer the platform automatically, and so adding that check would require
updating dozens of test files.
Reviewed By: #lld-macho, thakis, alexshap
Differential Revision: https://reviews.llvm.org/D97209
I've adjusted the RelocAttrBits to better fit the semantics of
the relocations. In particular:
1. *_UNSIGNED relocations are no longer marked with the `TLV` bit, even
though they can occur within TLV sections. Instead the `TLV` bit is
reserved for relocations that can reference thread-local symbols, and
*_UNSIGNED relocations have their own `UNSIGNED` bit. The previous
implementation caused TLV and regular UNSIGNED semantics to be
conflated, resulting in rebase opcodes being incorrectly emitted for TLV
relocations.
2. I've added a new `POINTER` bit to denote non-relaxable GOT
relocations. This distinction isn't important on x86 -- the GOT
relocations there are either relaxable or non-relaxable loads -- but
arm64 has `GOT_LOAD_PAGE21` which loads the page that the referent
symbol is in (regardless of whether the symbol ends up in the GOT). This
relocation must reference a GOT symbol (so must have the `GOT` bit set)
but isn't itself relaxable (so must not have the `LOAD` bit). The
`POINTER` bit is used for relocations that *must* reference a GOT
slot.
3. A similar situation occurs for TLV relocations.
4. ld64 supports both a pcrel and an absolute version of
ARM64_RELOC_POINTER_TO_GOT. But the semantics of the absolute version
are pretty weird -- it results in the value of the GOT slot being
written, rather than the address. (That means a reference to a
dynamically-bound slot will result in zeroes being written.) The
programs I've tried linking don't use this form of the relocation, so
I've dropped our partial support for it by removing the relevant
RelocAttrBits.
Reviewed By: alexshap
Differential Revision: https://reviews.llvm.org/D97031
See discussion on https://reviews.llvm.org/D93263
-flat_namespace isn't implemented yet, and neither is -undefined dynamic,
so this makes -undefined pretty pointless in lld/MachO for now. But once
we implement -flat_namespace (which we need to do anyways to get check-llvm
to pass with lld as host linker), the code's already there.
Follow-up to https://reviews.llvm.org/D93263#2491865
Differential Revision: https://reviews.llvm.org/D96963
Differential Revision: https://reviews.llvm.org/D95913
Usage: -bundle_loader <executable>
This option specifies the executable that will load the build output file being linked.
When building a bundle, users can use the --bundle_loader to specify an executable
that contains symbols referenced, but not implemented in the bundle.
Since we emit diagnostics for undefineds in Writer::scanRelocations()
and symbols referenced by -u flags aren't referenced by any relocations,
this needs some manual code (similar to the entry point).
Differential Revision: https://reviews.llvm.org/D94371
This is an initial base commit for ARM64 target arch support. I don't represent that it complete or bug-free, but wish to put it out for review now that some basic things like branch target & load/store address relocs are working.
I can add more tests to this base commit, or add them in follow-up commits.
It is not entirely clear whether I use the "ARM64" (Apple) or "AArch64" (non-Apple) naming convention. Guidance is appreciated.
Differential Revision: https://reviews.llvm.org/D88629
The LSDA pointers are encoded as offsets from the image base,
and arranged in one big contiguous array. Each second-level page records
the offset within that LSDA array which corresponds to the LSDA for its
first CU entry.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D95810
Note that there is a triple indirection involved with
personalities and compact unwind:
1. Two bits of each CU encoding are used as an offset into the
personality array.
2. Each entry of the personality array is an offset from the image base.
The resulting address (after adding the image base) should point within the
GOT.
3. The corresponding GOT entry contains the actual pointer to the
personality function.
To further complicate things, when the personality function is in the
object file (as opposed to a dylib), its references in
`__compact_unwind` may refer to it via a section + offset relocation
instead of a symbol relocation. Since our GOT implementation can only
create entries for symbols, we have to create a synthetic symbol at the
given section offset.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D95809
The Mach kernel & codesign on arm64 macOS has strict requirements for alignment and sequence of segments and sections. Dyld probably is just as picky, though kernel & codesign reject malformed Mach-O files before dyld ever has a chance.
I developed this diff by incrementally changing alignments & sequences to match the output of ld64. I stopped when my hello-world test program started working: `codesign --verify` succeded, and `execve(2)` didn't immediately fail with `errno == EBADMACHO` = `"Malformed Mach-O file"`.
Differential Revision: https://reviews.llvm.org/D94935
This extends {D92539} to work even when we are loading archive
members via `-force_load`. I uncovered this issue while trying to
force-load archives containing bitcode -- we were segfaulting.
In addition to fixing the `-force_load` case, this diff also addresses
the behavior of `-ObjC` when LTO bitcode is involved -- we need to
force-load those archive members if they contain ObjC categories.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D95265
This makes our error messages more informative. But the bigger motivation is for
LTO symbol resolution, which will be in an upcoming diff. The changes in this
one are largely mechanical.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D94316
Add per-reloc-type attribute bits and migrate code from per-target file into target independent code, driven by reloc attributes.
Many cleanups
Differential Revision: https://reviews.llvm.org/D95121
Not sure what the difference is, but using the latter appears to cause
issues in standalone builds. See llvm.org/PR48853.
Reviewed By: #lld-macho, compnerd
Differential Revision: https://reviews.llvm.org/D95359
I noticed that this option was not appearing at all in the `--help`
messages for `wasm-ld` or `ld.lld`.
Add help text and make it consistent across all ports.
Differential Revision: https://reviews.llvm.org/D94925
Just getting rid of some logspew as I test LLD under existing build
systems.
Reviewed By: #lld-macho, smeenai
Differential Revision: https://reviews.llvm.org/D95213
Run the ObjCARCContractPass during LTO. The legacy LTO backend (under
LTO/ThinLTOCodeGenerator.cpp) already does this; this diff just adds that
behavior to the new LTO backend. Without that pass, the objc.clang.arc.use
intrinsic will get passed to the instruction selector, which doesn't know how to
handle it.
In order to test both the new and old pass managers, I've also added support for
the `--[no-]lto-legacy-pass-manager` flags.
P.S. Not sure if the ordering of the pass within the pipeline matters...
Reviewed By: fhahn
Differential Revision: https://reviews.llvm.org/D94547