Commit Graph

565 Commits

Author SHA1 Message Date
Nico Weber f3091831f4 [lld] Use checkError more
No behavior change.
2021-10-04 11:46:16 -04:00
Daniel Rodríguez Troitiño 657f02d458 Revert "Extract LC_CODE_SIGNATURE related implementation out of LLD"
This reverts commit cc8229603b.

As discussed in the review of https://reviews.llvm.org/D109972, this was not
right approach, so we are reverting to start with a different approach.

Differential Revision: https://reviews.llvm.org/D110974
2021-10-01 17:19:50 -07:00
Nico Weber c19315ef60 [lld/mac] Don't warn on both --icf=all and -no_deduplicate
Instead, just make the later flag win, like usual.
Implement this by making -no_deduplicate an actual alias for --icf=none
at the Options.td level.

Differential Revision: https://reviews.llvm.org/D110672
2021-09-29 08:25:21 -04:00
Mike Hommey 08ef24f6ab Wrap xar/xar.h include in extern "C" block
Without such wrapping, linking lld fails with missing symbols because of
C++ symbol mangling with older versions of the MacOSX SDK, in which
xar.h doesn't have an extern "C" block itself.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D110224
2021-09-23 09:37:30 +02:00
Nico Weber 1b2c36aa5f [lld/mac] Fix comment typo to cycle bots 2021-09-18 11:15:21 -04:00
Jez Ng 91ace9f062 [lld-macho] Construct CFString literals by copying the ConcatInputSection
... instead of constructing a new one each time. This allows us
to take advantage of {D105305}.

I didn't see a substantial difference when linking chromium_framework,
but this paves the way for reusing similar logic for splitting compact
unwind entries into sections. There are a lot more of those, so the
performance impact is significant.

Differential Revision: https://reviews.llvm.org/D109895
2021-09-17 19:46:20 -04:00
Vy Nguyen b428c3e8c1 [lld-macho] Ignore local personality symbols if non-local with the same name exisst, to avoid "too many personalities" error.
Sometimes people intentionally re-define a dylib personlity symbol as a local defined symbol as a workaround to a ld -r bug.
    As a result, we could see "too many personalities" to encode. This patch tries to handle this case by ignoring the local symbols entirely.

    Differential Revision: https://reviews.llvm.org/D107533
2021-09-17 12:59:42 -04:00
Nuri Amari cc8229603b Extract LC_CODE_SIGNATURE related implementation out of LLD
Move the functionality in lld that handles writing of the LC_CODE_SIGNATURE load command and associated data section to a central reusable location.

This change is in preparation for another change that modifies llvm-objcopy to reproduce the LC_CODE_SIGNATURE load command and corresponding
data section to maintain the validity of signed macho object files passed through llvm-objcopy.

Reviewed By: #lld-macho, int3, oontvoo

Differential Revision: https://reviews.llvm.org/D109803
2021-09-16 17:43:39 -07:00
Nico Weber ed2f0ad307 [lld/mac] Search .tbd before binary for framework files too
This matters for example for the iPhoneSimulator14.0.sdk, which has
a System/Library/Frameworks/UIKit.framework/UIKit that has
LC_BUILD_VERSION with minos of 14.0, so linking against that file
will produce warnings like:

   .../iPhoneSimulator14.0.sdk/System/Library/Frameworks/UIKit.framework/UIKit
   has version 14.0.0, which is newer than target minimum of 12.0.0

when targeting x86_64-apple-ios12.0-simulator. That doens't happen when
linking against UIKit.tbd instead, obviously.

Linking with RC_TRACE_DYLIB_SEARCHING=1 shows that ld64 also searches
the tbd file first, and we already get that right for non-framework
dylibs.

Fixes crbug.com/1249456.

Differential Revision: https://reviews.llvm.org/D109768
2021-09-14 15:26:45 -04:00
Jez Ng d9ab62ca3d [lld-macho] Initialize LTO backend with diagnostic handler
Failing to do so results in `std::bad_function_call` being
thrown when a pass tries to emit a diagnostic.

I've copied the relevant test over from LLD-ELF's test suite.

Reviewed By: #lld-macho, thevinster

Differential Revision: https://reviews.llvm.org/D109274
2021-09-04 17:40:07 -04:00
Nico Weber c15b588852 [lld/mac] Don't assert during thunk insertion if there are undefined symbols
We end up calling resolveBranchVA(), which asserts for Undefineds.

As fix, just return early in Writer::run() if there are any diagnostics
after processing relocations (which is where undefined symbol errors are
emitted). This matches what the ELF port does.

Differential Revision: https://reviews.llvm.org/D109079
2021-09-03 12:22:41 -04:00
Nico Weber 86c8f395ae [lld/mac] Leave more room for thunks in thunk placement code
Fixes PR51578 in practice.

Currently there's only enough room for a single thunk, which for real-life code
isn't enough. The error case only happens when there are many branch statements
very close to each other (0 or 1 instructions apart), with the function at the
finalization barrier small.

There's a FIXME on what to do if we hit this case, but that suggestion sounds
complicated to me (see end of PR51578 comment 5 for why).

Instead, just leave more room for thunks. Chromium's unit_tests links fine with
room for 3 thunks. Leave room for 100, which should fix this for most cases in
practice.

There's little cost for leaving lots of room: This slop value only determines
when we finalize sections, and we insert thunks for forward jumps into
unfinalized sections. So leaving room means we'll need a few more thunks, but
the thunk jump range is 128 MiB while a single thunk is just 12 bytes.

For Chromium's unit_tests:
With a slop of   3: thunk calls = 355418, thunks = 10903
With a slop of 100: thunk calls = 355426, thunks = 10904

Chances are 100 is enough for all use cases we'll hit in practice, but even
bumping it to 1000 would probably be fine.

Differential Revision: https://reviews.llvm.org/D108930
2021-08-30 22:09:05 -04:00
Nico Weber 83df94067d [lld/mac] Tweak estimateStubsInRangeVA a bit
- Move a few variables closer to their uses, remove some completely
  (no behavior change)
- Add some comments
- Make maxPotentialThunks include calls to stubs. It's possible that
  an earlier call to a stub late in the stub table will need a thunk,
  and that inserted thunk could push a stub earlier in the stub table
  out of range. This is unlikely to happen, but usually there are
  way fewer stub calls than non-stub calls, so if we're doing a
  conservative approximation here we might as well do it correctly.
  (For chromium's unit_tests target, 134421/242639 stub calls are
  direct calls without this change, compared to 134408/242639 with
  this change)

No real, meaningful behavior difference.

Differential Revision: https://reviews.llvm.org/D108924
2021-08-30 13:56:45 -04:00
Nico Weber 9721197520 [lld/mac] Set branchRange a bit more carefully
- Don't subtract thunkSize from branchRange. Most places care about
  the actual maximal branch range. Subtract thunkSize in the one place
  that wants to leave room for a thunk.
- Set it to 0x800_0000 instead of 0xFF_FFFF
- Subtract 4 for the positive branch direction since it's a
  two's complement 24bit number sign-extended mutiplied by 4,
  so its range is -0x800_0000..+0x7FF_FFFC
- Make boundary checks include the boundary values

This doesn't make a huge difference in practice. It's preparation
for a "real" fix for PR51578 -- but it also lets the repro in comment 0
in that bug place one more thunk before hitting the TODO.

Differential Revision: https://reviews.llvm.org/D108897
2021-08-30 12:36:06 -04:00
Nico Weber 28be02f334 [lld/mac] Don't assert on -dead_strip + arm64 range extension thunks
The assert is harmless and thinks worked fine in builds with asserts enabled,
but it's still nice to fix the assert.

Differential Revision: https://reviews.llvm.org/D108853
2021-08-27 23:27:45 -04:00
Jez Ng c74eb05f21 [lld-macho][nfc] Clean up InputSection constructors 2021-08-26 19:07:48 -04:00
Jez Ng 9b5148d426 [lld-macho] Have -ObjC load archive members before symbol resolution
This is what ld64 does. Deviating in behavior here can result
in some subtle duplicate symbol errors, as detailed in the objc.s test.

Differential Revision: https://reviews.llvm.org/D108781
2021-08-26 18:52:07 -04:00
Jez Ng 9065fe5591 [lld-macho] Refactor archive loading
The previous logic was duplicated between symbol-initiated
archive loads versus flag-initiated loads (i.e. `-force_load` and
`-ObjC`). This resulted in code duplication as well as redundant work --
we would create Archive instances twice whenever we had one of those
flags; once in `getArchiveMembers` and again when we constructed the
ArchiveFile.

This was motivated by an upcoming diff where we load archive members
containing ObjC-related symbols before loading those containing
ObjC-related sections, as well as before performing symbol resolution.
Without this refactor, it would be difficult to do that while avoiding
loading the same archive member twice.

Differential Revision: https://reviews.llvm.org/D108780
2021-08-26 18:52:07 -04:00
Jez Ng 2179930868 [lld-macho] Fix unwind info personality size
This was missed by {D107035}. This fix addresses the following warning:

  loop variable 'personality' has type 'const uint32_t &' (aka 'const unsigned int &') but is initialized with type 'const unsigned long long' resulting in a copy [-Wrange-loop-analysis]

In addition to fixing the size, I also removed the const reference,
since there's no performance benefit to avoiding copies of integer-sized
values.
2021-08-26 18:52:06 -04:00
Vincent Lee 08d55c5c01 [lld-macho] Refactor parseSections to avoid creating isec on LLVM segments
Address post follow up comment in D108016. Avoid creating isec for
LLVM segments since we are skipping over it.

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D108167
2021-08-16 18:47:50 -07:00
Vincent Lee 15dc93e61c [lld-macho] Ignore LLVM segments to prevent duplicate syms
There was an instance of a third-party archive containing multiple
_llvm symbols from different files that clashed with each other
producing duplicate symbols. Symbols under the LLVM segment
don't seem to be producing any meaningful value, so just ignore them.

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D108016
2021-08-16 12:41:03 -07:00
Fangrui Song 7a6482216f [CMake][gn] lldMachO=>lldMachOOld, lldMachO2=>lldMachO
Now that D95204 switched default to new Darwin backend, rename some CMake
targets to match.

Reviewed By: #lld-macho, smeenai, int3

Differential Revision: https://reviews.llvm.org/D107516
2021-08-04 18:52:41 -07:00
Vy Nguyen 0bd14711ac [lld-macho] Change personalities entry type to Ptr to avoid overflowing uint32
PR51262

Differential Revision: https://reviews.llvm.org/D107035
2021-07-29 14:26:07 -04:00
Jez Ng e49374f9e0 [lld-macho] Support common symbols in bitcode (but differently from ld64)
ld64 seems to handle common symbols in bitcode rather
bizarrely. They follow entirely different precedence rules from their
non-bitcode counterparts. I initially tried to emulate ld64 in D106597,
but I'm not sure the extra complexity is worth it, especially given that
common symbols are not, well, very common.

This diff accords common bitcode symbols the same precedence as regular
common symbols, just as we treat all other pairs of bitcode and
non-bitcode symbol types. The tests document ld64's behavior in detail,
just in case we want to revisit this.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D107027
2021-07-29 11:07:50 -04:00
Jez Ng dc9ee39251 [lld-macho] Downgrade "cannot export hidden symbol" to warning
This matches ld64's behavior, and makes it easier to fit LLD
into existing build systems.

Reviewed By: #lld-macho, smeenai

Differential Revision: https://reviews.llvm.org/D107011
2021-07-28 18:46:26 -04:00
Nico Weber dd57915b1e [lld/mac] Fix sub-library.s on Windows after 8e8701abca
The endswith() check for the framework name fails when joining
with the native path separator. Always use the posix separator as fix.
2021-07-27 15:25:52 -04:00
Nico Weber 8e8701abca [lld/mac] When loading reexports, look for basename in -F / -L first
Matches ld64 (cf Options::findIndirectDylib()), and fixes PR51218.

Differential Revision: https://reviews.llvm.org/D106842
2021-07-27 14:28:52 -04:00
Nico Weber 80caa1eb4a [lld/mac] Add support for segment$start$ and segment$end$ symbols
These symbols are somewhat interesting in that they create non-existing
segments, which as far as I know is the only way to create segments
that don't contain any sections.

Final part of part of PR50760. Like D106629, but for segments instead
of sections. I'm not aware of anything that needs this in practice.

Differential Revision: https://reviews.llvm.org/D106767
2021-07-25 18:25:13 -04:00
Nico Weber afdeb432f0 [lld/mac] Move output segment rename logic into OutputSegment
Fixes the output segment name if both -rename_section and
-rename_segment are used and the post-section-rename segment
name is the same as the pre-segment-rename segment name to
match ld64's behavior.

The motivation is that segment$start$ can create section-less segments,
and this makes a corner case in the interaction between segment$start and
-rename_segment in the upcoming segment$start patch.

Differential Revision: https://reviews.llvm.org/D106766
2021-07-25 18:20:09 -04:00
Nico Weber 04f5eb407c [lld/mac] Fix start-stop.s test with expensive checks enabled
See e.g. https://lab.llvm.org/buildbot/#/builders/16/builds/14317
Not 100% sure why this fails yet, but this fixes it. Let's get
the bots green again first :)

Differential Revision: https://reviews.llvm.org/D106711
2021-07-23 17:01:16 -04:00
Nico Weber 04e8d0b62d [lld/mac] Implement support for section$start and section$ end symbols
With this, libclang_rt.profile_osx.a can be linked, that is coverage
and PGO-instrumented builds should now work with lld.

section$start and section$end symbols can create non-existing sections.
They're also undefined symbols that are only magic if there isn't a
regular symbol with their name, which means the need to be handled
in treatUndefined() instead of just looping over all existing
sections and adding start and end symbols like the ELF port does.

To represent the actual symbols, this uses absolute symbols that
get their value updated once an output section is layed out.

segment$start and segment$end are still missing for now, but they produce a
nicer error message after this patch.

Main part of PR50760.

Differential Revision: https://reviews.llvm.org/D106629
2021-07-23 16:01:09 -04:00
Jez Ng 3313b84481 [lld-macho] ICF: Do more work in equalsConstant, less in equalsVariable
In particular, relocations to absolute symbols or literal sections can
be handled in equalsConstant(), since their output addresses will not
change across each iteration of ICF. Offsets and addends can also be
dealt with entirely in equalsConstant(), making the code somewhat easier
to reason about. Only ConcatInputSections need to be handled in
equalsVariable().

LLD-ELF's implementation takes a similar approach.

Although this should make ICF do less work, in practice it seems like
there is no stat sig difference in time taken when linking
chromium_framework.

This refactor is motivated by an upcoming diff which improves ICF's handling of
addends.

Reviewed By: #lld-macho, gkm

Differential Revision: https://reviews.llvm.org/D106212
2021-07-23 11:49:00 -04:00
Nico Weber 9482aa98e5 [lld/mac] Let OutputSegment store its start address
segment$start$/segment$end$ symbols allow creating segments without
sections, so getting the segment address off the first section
won't work there. Storing the address on the segment is arguably a
bit simpler too.

No behavior change, part of PR50760.

Differential Revision: https://reviews.llvm.org/D106665
2021-07-23 11:43:25 -04:00
Nico Weber 2c508cf583 [lld/mac] Don't crash on absolute symbols in order files
Absolute symbols have a nullptr isec. buildInputSectionPriorities()
would defer isec, causing crashes. Ordering absolute symbols doesn't
make sense, so just ignore them. This seems to match ld64.

Differential Revision: https://reviews.llvm.org/D106628
2021-07-23 11:33:23 -04:00
Leonard Grey 5acc6d4572 [lld-macho] Disambiguate bitcode files with the same name by archive name/offset in archive
Ported from COFF/ELF; test is adapted from
test/COFF/thinlto-archivecollision.ll

LTO expects every bitcode file to have a unique name. If given multiple bitcode
files with the same name, it errors with "Expected at most one ThinLTO module
per bitcode file".

This change incorporates the archive name, to disambiguate members with the
same name in different archives and the offset in archive to disambiguate
members with the same name in the same archive.

Differential Revision: https://reviews.llvm.org/D106179
2021-07-22 22:50:25 -04:00
Nico Weber 393116faad [lld/mac] Remove "else" after return
No behavior change
2021-07-22 21:31:52 -04:00
Nico Weber 2d6fb62ef2 [lld/mac] Handle symbols from -U in treatUndefinedSymbol()
In ld64, `-U section$start$FOO$bar` handles `section$start$FOO$bar`
as a regular `section$start` symbol, that is section$start processing
happens before -U processing.

Likely, nobody uses that in practice so it doesn't seem very important
to be compatible with this, but it also moves the -U handling code next
to the `-undefined dynamic_lookup` handling code, which is nice because
they do the same thing. And, in fact, this did identify a bug in a corner
case in the intersection of `-undefined dynamic_lookup` and dead-stripping
(fix for that in D106565).

Vaguely related to PR50760.

No interesting behavior change.

Differential Revision: https://reviews.llvm.org/D106566
2021-07-22 19:43:57 -04:00
Nico Weber 5ae39d4f97 [lld/mac] Fix bug in interaction of -dead_strip and -undefined dynamic_lookup
We lost the `used` bit on the Undefined when we replaced it with a DylibSymbol
in treatUndefined().

Differential Revision: https://reviews.llvm.org/D106565
2021-07-22 19:30:46 -04:00
Nico Weber 9d43c000e1 [lld/mac] Move handling of special undefineds later
treatUndefinedSymbol() was previously called before gatherInputSections()
and markLive() for these special symbols, but after them for normal
undefineds.

For PR50760, treatUndefinedSymbol() will have to potentially create
sections, so it's good to move treatUndefinedSymbol() for special
undefineds later, so that it can assume that gatherInputSections()
and markLive() has already been called always.

No intended behavior change, but part of PR50760 (and covered in
tests in the patch for the full feature).

Differential Revision: https://reviews.llvm.org/D106552
2021-07-22 11:43:49 -04:00
Vincent Lee 33ab995617 Recommit "[lld-macho] Use DO_BIND_ADD_ADDR_IMM_SCALED for bind opcodes"
Implement pass 3 of bind opcodes from ld64 (which supports both 32-bit and 64-bit).
Pass 3 implementation condenses BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB opcode
to BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED.  This change is already behind an
O2 flag so it shouldn't impact current performance. I verified ld64's output with x86_64 LLD
and they were both emitting the same optimized bind opcodes (although in a slightly different
order). Tested with arm64_32 LLD and compared that with x86 LLD that the order of the bind
opcodes are the same (offset values are different which should be expected).

Reviewed By: int3, #lld-macho, MaskRay

Differential Revision: https://reviews.llvm.org/D106128
2021-07-20 13:45:24 -07:00
Fangrui Song 88e2268a34 Revert D106128 "[lld-macho] Use DO_BIND_ADD_ADDR_IMM_SCALED for bind opcodes"
This reverts commit 321b2bef09.

`for (BindIR *p = &opcodes[0]; p->opcode != BIND_OPCODE_DONE; ++p) {` has a heap-buffer-overflow with test/MachO/bind-opcodes.
2021-07-19 18:13:52 -07:00
Vincent Lee 321b2bef09 [lld-macho] Use DO_BIND_ADD_ADDR_IMM_SCALED for bind opcodes
Implement pass 3 of bind opcodes from ld64 (which supports both 32-bit and 64-bit).
Pass 3 implementation condenses BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB opcode
to BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED.  This change is already behind an
O2 flag so it shouldn't impact current performance. I verified ld64's output with x86_64 LLD
and they were both emitting the same optimized bind opcodes (although in a slightly different
order). Tested with arm64_32 LLD and compared that with x86 LLD that the order of the bind
opcodes are the same (offset values are different which should be expected).

Reviewed By: int3, #lld-macho

Differential Revision: https://reviews.llvm.org/D106128
2021-07-19 16:18:33 -07:00
Nico Weber fbb45947b2 [lld/mac] Resolve defined symbols before undefined symbols
Ports https://reviews.llvm.org/D95985 to the MachO port.
Happens to fix PR51135; see that bug for details.
Also makes lld's behavior match ld64 for the included test case.

Differential Revision: https://reviews.llvm.org/D106293
2021-07-19 16:37:41 -04:00
Nico Weber bcbb3066ce [lld/mac] Change load command order to be more like ld64
No meaningful behavior change. Makes diffing `otool -l` output a bit easier.

Differential Revision: https://reviews.llvm.org/D106219
2021-07-19 15:04:32 -04:00
Jez Ng 428a7c1b38 [lld-macho] Have ICF operate on all sections at once
ICF previously operated only within a given OutputSection. We would
merge all CFStrings first, then merge all regular code sections in a
second phase. This worked fine since CFStrings would never reference
regular `__text` sections. However, I would like to expand ICF to merge
functions that reference unwind info. Unwind info references the LSDA
section, which can in turn reference the `__text` section, so we cannot
perform ICF in phases.

In order to have ICF operate on InputSections spanning multiple
OutputSections, we need a way to distinguish InputSections that are
destined for different OutputSections, so that we don't fold across
section boundaries. We achieve this by creating OutputSections early,
and setting `InputSection::parent` to point to them. This is what
LLD-ELF does. (This change should also make it easier to implement the
`section$start$` symbols.)

This diff also folds InputSections w/o checking their flags, which I
think is the right behavior -- if they are destined for the same
OutputSection, they will have the same flags in the output (even if
their input flags differ). I.e. the `parent` pointer check subsumes the
`flags` check. In practice this has nearly no effect (ICF did not become
any more effective on chromium_framework).

I've also updated ICF.cpp's block comment to better reflect its current
status.

Reviewed By: #lld-macho, smeenai

Differential Revision: https://reviews.llvm.org/D105641
2021-07-17 13:42:51 -04:00
Vincent Lee d695d0d6f6 [lld-macho] Optimize bind opcodes with multiple passes
In D105866, we used an intermediate container to store a list of opcodes. Here,
we use that data structure to help us perform optimization passes that would allow
a more efficient encoding of bind opcodes. Currently, the functionality mirrors the
optimization pass {1,2} done in ld64 for bind opcodes under optimization gate
to prevent slight regressions.

Reviewed By: int3, #lld-macho

Differential Revision: https://reviews.llvm.org/D105867
2021-07-15 20:52:46 -07:00
Vincent Lee f2b1264141 [lld-macho] Use intermediate arrays to store opcodes
We want to incorporate some of the optimization passes in bind opcodes from ld64.
This revision makes no functional changes but to start storing opcodes in intermediate
containers in preparation for implementing the optimization passes in a follow-up revision.

Differential Revision: https://reviews.llvm.org/D105866
2021-07-15 16:57:45 -07:00
Leonard Grey c931ff72bd [lld-macho] Add LTO cache support
This adds support for the lld-only `--thinlto-cache-policy` option, as well as
implementations for ld64's `-cache_path_lto`, `-prune_interval_lto`,
`-prune_after_lto`, and `-max_relative_cache_size_lto`.

Test is adapted from lld/test/ELF/lto/cache.ll

Differential Revision: https://reviews.llvm.org/D105922
2021-07-15 12:56:13 -04:00
Alexander Shaposhnikov d21772fa21 [lld][MachO] Code cleanup
Make use of ArgList::getLastArgValue. NFC.

Test plan: make check-lld-macho

Differential revision: https://reviews.llvm.org/D105452
2021-07-14 04:33:09 -07:00
Nico Weber f21801dab2 [lld/mac] Implement -application_extension
Differential Revision: https://reviews.llvm.org/D105818
2021-07-12 13:42:16 -04:00