Commit Graph

310 Commits

Author SHA1 Message Date
Vincent Lee f030132c72 [lld-macho] Allow linking with ABI compatible architectures
Linking fails when targeting `x86_64-apple-darwin` for runtimes. The issue
is that LLD strictly assumes the target architecture be present in the tbd
files (which isn't always true). For example, when targeting `x86_64h`, it should
work with `x86_64` because they are ABI compatible. This is also inline with what
ld64 does.

An environment variable (which ld64 also supports) is also added to preserve the
existing behavior of strict architecture matching.

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D130683
2022-07-28 17:16:32 -07:00
Jez Ng 31760e8189 [lld-macho] `-exported_symbols` should hide symbols before LTO runs
We were previously doing it after LTO, which did have the desired effect
of having the un-exported symbols marked as private extern in the final
output binary, but doing it before LTO creates more optimization
opportunities.

One observable difference is that LTO can now elide un-exported symbols
entirely, so they may not even be present as private externs in the
output.

This is also what ld64 implements.

Reviewed By: #lld-macho, thevinster

Differential Revision: https://reviews.llvm.org/D130429
2022-07-28 17:55:49 -04:00
Daniel Bertalan b2c53a9217 [lld-macho] Implement -hidden-l
Similarly to -load_hidden, this flag instructs the linker to not export
symbols from the specified archive. While that flag takes a path,
-hidden-l looks for the specified library name in the search path.

The test changes are needed because -hidden-lfoo resolves to libfoo.a,
not foo.a.

Differential Revision: https://reviews.llvm.org/D130529
2022-07-26 01:41:51 +02:00
Daniel Bertalan 595fc59f74 Reland "[lld-macho] Implement -load_hidden"
This flag was introduced in ld64-609. It instructs the linker to link to
a static library while treating its symbols as if they had hidden
visibility. This is useful when building a dylib that links to static
libraries but we don't want the symbols from those to be exported.

Closes #51505

This reland adds bitcode file handling, so we won't get any compile
errors due to BitcodeFile::forceHidden being unused.

Differential Revision: https://reviews.llvm.org/D130473
2022-07-25 22:51:24 +02:00
Daniel Bertalan 9bf1c6dabf Revert "[lld-macho] Implement -load_hidden"
This reverts commit 4c79e1a3f4.

Broke this bot: https://lab.llvm.org/buildbot/#builders/57/builds/20319
2022-07-25 21:11:19 +02:00
Daniel Bertalan 4c79e1a3f4 [lld-macho] Implement -load_hidden
This flag was introduced in ld64-609. It instructs the linker to link to
a static library while treating its symbols as if they had hidden
visibility. This is useful when building a dylib that links to static
libraries but we don't want the symbols from those to be exported.

Closes #51505

Differential Revision: https://reviews.llvm.org/D130473
2022-07-25 20:59:33 +02:00
Jez Ng d23da0ec6c [lld-macho] Fold __objc_imageinfo sections
Previously, we treated it as a regular ConcatInputSection. However, ld64
actually parses its contents and uses that to synthesize a single image
info struct, generating one 8-byte section instead of `8 * number of
object files with ObjC code`.

I'm not entirely sure what impact this section has on the runtime, so I
just tried to follow ld64's semantics as closely as possible in this
diff. My main motivation though was to reduce binary size.

No significant perf change on chromium_framework on my 16-core Mac Pro:

             base           diff           difference (95% CI)
  sys_time   1.764 ± 0.062  1.748 ± 0.032  [  -2.4% ..   +0.5%]
  user_time  5.112 ± 0.104  5.106 ± 0.046  [  -0.9% ..   +0.7%]
  wall_time  6.111 ± 0.184  6.085 ± 0.076  [  -1.6% ..   +0.8%]
  samples    30             32

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D130125
2022-07-23 12:12:01 -04:00
Keith Smiley 15f685eaa8
[lld-macho] Fold cfstrings with --deduplicate-literals
Similar to cstrings ld64 always deduplicates cfstrings. This was already
being done when enabling ICF, but for debug builds you may want to flip
this on if you cannot eliminate your instances of this, so this change
makes --deduplicate-literals also apply to cfstrings.

Differential Revision: https://reviews.llvm.org/D130134
2022-07-20 11:11:09 -07:00
Kazu Hirata 360c1111e3 Use llvm::is_contained (NFC) 2022-07-20 09:09:19 -07:00
Jez Ng 87ce7b41d8 [lld-macho] Simplify archive loading logic
This is a follow-on to {D129556}. I've refactored the code such that
`addFile()` no longer needs to take an extra parameter. Additionally,
the "do we force-load or not" policy logic is now fully contained within
addFile, instead of being split between `addFile` and
`parseLCLinkerOptions`. This also allows us to move the `ForceLoad` (now
`LoadType`) enum out of the header file.

Additionally, we can now correctly report loads induced by
`LC_LINKER_OPTION` in our `-why_load` output.

I've also added another test to check that CLI library non-force-loads
take precedence over `LC_LINKER_OPTION` + `-force_load_swift_libs`. (The
existing logic is correct, just untested.)

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D130137
2022-07-19 21:56:24 -04:00
Kaining Zhong dd5635541c [lld-macho] Fix loading same libraries from both LC_LINKER_OPTION and command line
This fixes https://github.com/llvm/llvm-project/issues/56059 and
https://github.com/llvm/llvm-project/issues/56440. This is inspired by
tapthaker's patch (https://reviews.llvm.org/D127941), and has reused his
test cases. This patch adds an bool "isCommandLineLoad" to indicate
where archives are from. If lld tries to load the same library loaded
previously by LC_LINKER_OPTION from CLI, it will use this
isCommandLineLoad to determine if it should be affected by -all_load &
-ObjC flags. This also prevents -force_load from affecting archives
loaded previously from CLI without such flag, whereas tapthaker's patch
will fail such test case (introduced by
https://reviews.llvm.org/D128025).

Reviewed By: int3, #lld-macho

Differential Revision: https://reviews.llvm.org/D129556
2022-07-19 17:46:14 -04:00
Keith Smiley 0bc100986c
[lld-macho] Add support for -alias
This creates a symbol alias similar to --defsym in the elf linker. This
is used by swiftpm for all executables, so it's useful to support. This
doesn't implement -alias_list but that could be done pretty easily as
needed.

Differential Revision: https://reviews.llvm.org/D129938
2022-07-19 13:55:56 -07:00
Jez Ng 403d61aedd [lld-macho] Enable EH frame relocation / pruning
This just removes the code that gates the logic. The main issue here is
perf impact: without {D122258}, LLD takes a significant perf hit because
it now has to do a lot more work in the input parsing phase. But with
that change to eliminate unnecessary EH frames from input object files,
the perf overhead here is minimal. Concretely, here are the numbers for
some builds as measured on my 16-core Mac Pro:

**chromium_framework**

This is without the use of `-femit-dwarf-unwind=no-compact-unwind`:

             base           diff           difference (95% CI)
  sys_time   1.826 ± 0.019  1.962 ± 0.034  [  +6.5% ..   +8.4%]
  user_time  9.306 ± 0.054  9.926 ± 0.082  [  +6.2% ..   +7.1%]
  wall_time  8.225 ± 0.068  8.947 ± 0.128  [  +8.0% ..   +9.6%]
  samples    15             22

With that flag enabled, the regression mostly disappears, as hoped:

             base           diff           difference (95% CI)
  sys_time   1.839 ± 0.062  1.866 ± 0.068  [  -0.9% ..   +3.8%]
  user_time  9.452 ± 0.068  9.490 ± 0.067  [  -0.1% ..   +0.9%]
  wall_time  8.383 ± 0.127  8.452 ± 0.114  [  -0.1% ..   +1.8%]
  samples    17             21

**Unnamed internal app**

Without `-femit-dwarf-unwind`, this is the perf hit:

             base           diff           difference (95% CI)
  sys_time   1.372 ± 0.029  1.317 ± 0.024  [  -4.6% ..   -3.5%]
  user_time  2.835 ± 0.028  2.980 ± 0.027  [  +4.8% ..   +5.4%]
  wall_time  3.205 ± 0.079  3.383 ± 0.066  [  +4.9% ..   +6.2%]
  samples    102            83

With `-femit-dwarf-unwind`, the perf hit almost disappears:

             base           diff           difference (95% CI)
  sys_time   1.274 ± 0.026  1.270 ± 0.025  [  -0.9% ..   +0.3%]
  user_time  2.812 ± 0.023  2.822 ± 0.035  [  +0.1% ..   +0.7%]
  wall_time  3.166 ± 0.047  3.174 ± 0.059  [  -0.2% ..   +0.7%]
  samples    95             97

Just for fun, I measured the impact of `-femit-dwarf-unwind` on ld64
(`base` has the extra DWARF unwind info in the input object files,
`diff` doesn't):

             base           diff           difference (95% CI)
  sys_time   1.128 ± 0.010  1.124 ± 0.023  [  -1.3% ..   +0.6%]
  user_time  7.176 ± 0.030  7.106 ± 0.094  [  -1.5% ..   -0.4%]
  wall_time  7.874 ± 0.041  7.795 ± 0.121  [  -1.7% ..   -0.3%]
  samples    16             25

And for LLD:

             base           diff           difference (95% CI)
  sys_time   1.315 ± 0.019  1.280 ± 0.019  [  -3.2% ..   -2.0%]
  user_time  2.980 ± 0.022  2.822 ± 0.016  [  -5.5% ..   -5.0%]
  wall_time  3.369 ± 0.038  3.175 ± 0.033  [  -6.2% ..   -5.3%]
  samples    47             47

So parsing the extra EH frames is a lot more expensive for us than for
ld64. But given that we are quite a lot faster than ld64 to begin with,
I guess this isn't entirely unexpected...

Reviewed By: #lld-macho, oontvoo

Differential Revision: https://reviews.llvm.org/D129540
2022-07-13 21:14:05 -04:00
Daniel Bertalan a3f67f0920 [lld-macho] Initial support for Linker Optimization Hints
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
2022-06-30 06:28:42 +02:00
Nico Weber a2c1f7c90d [lld, ELF and mac] Add --time-trace=<file>, remove --time-trace-file=<file>
`--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
2022-06-23 15:46:22 -04:00
Nico Weber 0ec87addb7 [lld/mac] Add a few TimeTraceScopes
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
2022-06-23 11:46:57 -04:00
Keith Smiley 272bf0fc41
[lld-macho] Add support for exporting no symbols
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
2022-06-15 15:07:27 -07:00
Jez Ng e183bf8e15 [lld-macho][reland] Initial support for EH Frames
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
2022-06-13 07:45:16 -04:00
Douglas Yung 942f4e3a7c Revert "[lld-macho] Initial support for EH Frames"
This reverts commit 826be330af.

This was causing a test failure on build bots:
  - https://lab.llvm.org/buildbot/#/builders/36/builds/21770
  - https://lab.llvm.org/buildbot/#/builders/58/builds/23913
2022-06-09 05:25:43 -07:00
Jez Ng 826be330af [lld-macho] Initial support for EH Frames
== 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
2022-06-08 23:40:52 -04:00
Vy Nguyen 82de9bb66b [lld-macho] Addressed additional post-commit comments from D126046
- fixed newlines
- renamed helper function for clarity
- added additional comment

Differential Revision: https://reviews.llvm.org/D126792
2022-06-03 15:48:11 -04:00
Vy Nguyen fae6bd7563 [lld-macho] Support -non_global_symbols_strip_list, -non_global_symbols_no_strip_list, -x
PR/55600

Differential Revision: https://reviews.llvm.org/D126046
2022-05-25 19:22:04 +07:00
Vy Nguyen 4c5b187f2c [lld-macho] Demangle symbol names in export-symbol error messages when -demangle is specified.
PR/55512

Reviewed By: keith

Differential Revision: https://reviews.llvm.org/D125732
2022-05-16 19:48:03 -04:00
Nico Weber 895a72111b [lld/mac] Support writing zippered dylibs and bundles
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
2022-05-04 19:23:35 -04:00
Alex Borcan e29dc0c6fd [lld] Implement safe icf for MachO
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
2022-05-03 21:01:03 -04:00
Nico Weber 3254f46884 [lld/mac] For catalyst outputs, tolerate implicitly linking against mac-only tbd files
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
2022-04-23 21:43:46 -04:00
Keith Smiley 2d8cf26d08 [lld-macho] Fix crash on invalid framework tbd
Previously these would crash because `file` is null in the case there is
an invalid tbd file.

Differential Revision: https://reviews.llvm.org/D124271
2022-04-22 10:26:48 -07:00
Nico Weber 889847922d [lld/mac] Warn that writing zippered outputs isn't implemented
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
2022-04-21 12:05:56 -04:00
Jez Ng 1cff723ff5 [lld-macho][nfc] Use includeInSymtab for all symtab-skipping logic
{D123302} got me looking deeper at `includeInSymtab`. I thought it was a
little odd that there were excluded (live) symbols for which
`includeInSymtab` was false; we shouldn't have so many different ways to
exclude a symbol. As such, this diff makes the `L`-prefixed-symbol
exclusion code use `includeInSymtab` too. (Note that as part of our
support for `__eh_frame`, we will also be excluding all `__eh_frame`
symbols from the symtab in a future diff.)

Another thing I noticed is that the `emitStabs` code never has to deal
with excluded symbols because `SymtabSection::finalize()` already
filters them out. As such, I've updated the comments and asserts from
{D123302} to reflect this.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D123433
2022-04-11 15:45:46 -04:00
Jez Ng f004ecf6ec [lld-macho][nfc] Remove indirection when looking up common section members
{D118797} means that we can now check the name/segname of a given
section directly, instead of having to look those properties up on one
of its subsections. This allows us to simplify our code.

Reviewed By: #lld-macho, oontvoo

Differential Revision: https://reviews.llvm.org/D123275
2022-04-07 14:28:52 -04:00
Nikita Popov b8f50abd04 [lld] Remove support for legacy pass manager
This removes options for performing LTO with the legacy pass
manager in LLD. Options that explicitly enable the new pass manager
are retained as no-ops.

Differential Revision: https://reviews.llvm.org/D123219
2022-04-07 10:17:31 +02:00
Nikita Popov ed4e6e0398 [cmake] Remove LLVM_ENABLE_NEW_PASS_MANAGER cmake option
Or rather, error out if it is set to something other than ON. This
removes the ability to enable the legacy pass manager by default,
but does not remove the ability to explicitly enable it through
various flags like -flegacy-pass-manager or -enable-new-pm=0.

I checked, and our test suite definitely doesn't pass with
LLVM_ENABLE_NEW_PASS_MANAGER=OFF anymore.

Differential Revision: https://reviews.llvm.org/D123126
2022-04-06 09:52:21 +02:00
Roger Kim f858fba631 [lld][Macho][NFC] Encapsulate priorities map in a priority class
`config->priorities` has been used to hold the intermediate state during the construction of the order in which sections should be laid out. This is not a good place to hold this state since the intermediate state is not a "configuration" for LLD. It should be encapsulated in a class for building a mapping from section to priority (which I created in this diff as the `PriorityBuilder` class).

The same thing is being done for `config->callGraphProfile`.

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D122156
2022-03-23 13:57:26 -04:00
Jez Ng 850592ec14 [lld-macho] Implement -why_live (without perf overhead)
This was based off @thakis' draft in {D103517}. I employed templates to ensure
the support for `-why_live` wouldn't slow down the regular non-why-live code
path.

No stat sig perf difference on my 3.2 GHz 16-Core Intel Xeon W:

             base           diff           difference (95% CI)
  sys_time   1.195 ± 0.015  1.199 ± 0.022  [  -0.4% ..   +1.0%]
  user_time  3.716 ± 0.022  3.701 ± 0.025  [  -0.7% ..   -0.1%]
  wall_time  4.606 ± 0.034  4.597 ± 0.046  [  -0.6% ..   +0.2%]
  samples    44             37

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D120377
2022-02-24 15:49:36 -05:00
Leonard Grey a52b9102d1 [lld-macho] Allow order files and call graph sorting to be used together
If both an order file and a call graph profile are present, the edges of the
call graph which use symbols present in the order file are not used. All of
the symbols in the order file will appear at the beginning of the section just
as they do currently. In other words, the highest priority derived from the
call graph will be below the lowest priority derived from the order file.

Practically, this change renames CallGraphSort.{h,cpp} to SectionPriorities.{h,cpp},
and most order file and call graph profile related code is moved into the new
file to reduce duplication.

Differential Revision: https://reviews.llvm.org/D117354
2022-02-17 14:19:34 -05:00
Jez Ng 103e1d934a [lld-macho] Unset ExportDynamic where possible for LTO
By unsetting this property, we are now able to internalize more symbols
during LTO. I compared the output of `-save-temps` for both LLD and
ld64, and we now match ld64's behavior as far as `lto-internalize.ll` is
concerned.

(Thanks @smeenai for working on an initial version of this diff!)

Fixes https://github.com/llvm/llvm-project/issues/50574.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D119372
2022-02-11 22:26:19 -05:00
Jared Irwin 31626cc111 [lld-macho] Add -pagezero_size
Adds `-pagezero_size`. `-pagezero_size` commonly used for kernel development.
`-pagezero_size` changes the `__PAGEZERO` size, removing that segment if it is set to zero.

One of the four flags from {D118570}
Now with error messages and tests.

Differential Revision: https://reviews.llvm.org/D118724
2022-02-06 13:15:16 -05:00
Jez Ng 2b78ef06c2 [lld-macho][nfc] Eliminate InputSection::Shared
Earlier in LLD's evolution, I tried to create the illusion that
subsections were indistinguishable from "top-level" sections. Thus, even
though the subsections shared many common field values, I hid those
common values away in a private Shared struct (see D105305). More
recently, however, @gkm added a public `Section` struct in D113241 that
served as an explicit way to store values that are common to an entire
set of subsections (aka InputSections). Now that we have another "common
value" struct, `Shared` has been rendered redundant. All its fields can
be moved into `Section` instead, and the pointer to `Shared` can be replaced
with a pointer to `Section`.

This `Section` pointer also has the advantage of letting us inspect other
subsections easily, simplifying the implementation of {D118798}.

P.S. I do think that having both `Section` and `InputSection` makes for
a slightly confusing naming scheme. I considered renaming `InputSection`
to `Subsection`, but that would break the symmetry with `OutputSection`.
It would also make us deviate from LLD-ELF's naming scheme.

This change is perf-neutral on my 3.2 GHz 16-Core Intel Xeon W machine:

             base           diff           difference (95% CI)
  sys_time   1.258 ± 0.031  1.248 ± 0.023  [  -1.6% ..   +0.1%]
  user_time  3.659 ± 0.047  3.658 ± 0.041  [  -0.5% ..   +0.4%]
  wall_time  4.640 ± 0.085  4.625 ± 0.063  [  -1.0% ..   +0.3%]
  samples    49             61

There's also no stat sig change in RSS (as measured by `time -l`):

           base                         diff                           difference (95% CI)
  time     998038627.097 ± 13567305.958 1003327715.556 ± 15210451.236  [  -0.2% ..   +1.2%]
  samples  31                           36

Reviewed By: #lld-macho, oontvoo

Differential Revision: https://reviews.llvm.org/D118797
2022-02-03 19:55:42 -05:00
Vy Nguyen 36f32ffd2a [lld-macho] Minor clean up: use .find() to check for key existence rather than [], which would create a new entry.
Differential Revision: https://reviews.llvm.org/D118945
2022-02-03 17:17:14 -05:00
Keith Smiley 187ce07a06 [lld-macho] Fix duplicate symbols with relocatable objects
In the case your framework bundles contain relocatable objects, and your
objects include LC_LINKER_OPTIONs for the framework, previously they
would not be deduplicated like they would have if they were static
archives. This was also the case if you passed `-framework` for the
framework as well.

Reviewed By: #lld-macho, thakis, oontvoo

Differential Revision: https://reviews.llvm.org/D114841
2022-02-02 14:54:10 -08:00
Keith Smiley a6298fb160 [lld-macho] Add support for -add_empty_section
This is a ld64 option equivalent to `-sectcreate seg sect /dev/null`
that's useful for creating sections like the RESTRICT section.

Differential Revision: https://reviews.llvm.org/D117749
2022-01-30 10:03:41 -08:00
Leonard Grey a5c9d71780 [lld-macho] Move order file and call graph sorting into SectionPriorities
See https://reviews.llvm.org/D117354 for context and discussion.
2022-01-25 12:18:15 -05:00
Alexandre Ganea 83d59e05b2 Re-land [LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.

See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html

The previous land f860fe3622 caused issues in https://lab.llvm.org/buildbot/#/builders/123/builds/8383, fixed by 22ee510dac.

Differential Revision: https://reviews.llvm.org/D108850
2022-01-20 14:53:26 -05:00
Keith Smiley 67090e3446 [lld-macho] Implement -noall_load
This flag is the default, so in ld64 it is not implemented, but it can
be useful to negate previous -all_load arguments. Specifically if your
build system has some global linker flags, that you may want to negate
for specific links. We use something like this today to make sure some
C++ symbols are automatically discovered for all links, which passing
-all_load hides.

Differential Revision: https://reviews.llvm.org/D117629
2022-01-19 13:12:18 -08:00
Fangrui Song 0aae2bf373 [lld-macho] Add --start-lib --end-lib
In ld.lld, when an ObjFile/BitcodeFile is read in --start-lib state, the file is
given archive semantics. --end-lib closes the previous --start-lib. A build
system can use this feature as an alternative to archives. This patch ports
the feature to lld-macho.

--start-lib and --end-lib are positional, unlike usual ld64 options.
I think the slight drawback does not matter as (a) reusing option names
make build systems convenient (b) `--start-lib a.o b.o --end-lib` conveys more
information than an alternative design: `-objlib a.o -objlib b.o` because
--start-lib makes it clear which objects are in the same conceptual archive.
This provides flexibility (c) `-objlib`/`-filelist` interaction may be weird.

Close https://github.com/llvm/llvm-project/issues/52931

Reviewed By: #lld-macho, Jez Ng, oontvoo

Differential Revision: https://reviews.llvm.org/D116913
2022-01-19 10:14:49 -08:00
Vincent Lee e5347f2556 [lld-macho] Allow deduplicate-literals to be overridden
It's still uncertain but whether we want to have `deduplicate-literals` be the
default flag for LLD out of the box or not. If `deduplicate-literals` is the default
behavior, then we will need a way override it and not deduplicate. Luckily, we
have `no_deduplicate` to fill this gap. For now, I've set the default to be false
which aligns with the existing behavior. That can only always be changed after
discussions on D117250.

Reviewed By: #lld-macho, int3

Differential Revision: https://reviews.llvm.org/D117387
2022-01-18 15:42:59 -08:00
Alexandre Ganea e6b153947d Revert [LLD] Remove global state in lldCommon
It seems to be causing issues on https://lab.llvm.org/buildbot/#/builders/123/builds/8383
2022-01-16 11:03:06 -05:00
Alexandre Ganea f860fe3622 [LLD] Remove global state in lldCommon
Move all variables at file-scope or function-static-scope into a hosting structure (lld::CommonLinkerContext) that lives at lldMain()-scope. Drivers will inherit from this structure and add their own global state, in the same way as for the existing COFFLinkerContext.

See discussion in https://lists.llvm.org/pipermail/llvm-dev/2021-June/151184.html

Differential Revision: https://reviews.llvm.org/D108850
2022-01-16 08:57:57 -05:00
Juergen Ributzka 3025c3eded Replace PlatformKind with PlatformType.
The PlatformKind/PlatformType enums contain the same information, which requires
them to be kept in-sync. This commit changes over to PlatformType as the sole
source of truth, which allows the removal of the redundant PlatformKind.

The majority of the changes were in LLD and TextAPI.

Reviewed By: cishida

Differential Revision: https://reviews.llvm.org/D117163
2022-01-13 09:23:49 -08:00
Leonard Grey 6db04b97e6 [lld-macho] Port CallGraphSort from COFF/ELF
Depends on D112160

This adds the new options `--call-graph-profile-sort` (default),
`--no-call-graph-profile-sort` and `--print-symbol-order=`. If call graph
profile sorting is enabled, reads `__LLVM,__cg_profile` sections from object
files and uses the resulting graph to put callees and callers close to each
other in the final binary via the C3 clustering heuristic.

Differential Revision: https://reviews.llvm.org/D112164
2022-01-12 10:47:04 -05:00