[lld/mac] Implement -dead_strip

Authored by thakis on May 7 2021, 2:10 PM.


[lld/mac] Implement -dead_strip

Also adds support for live_support sections, no_dead_strip sections,
.no_dead_strip symbols.

Chromium Framework 345MB unstripped -> 250MB stripped
(vs 290MB unstripped -> 236M stripped with ld64).

Doing dead stripping is a bit faster than not, because so much less
data needs to be processed:

% ministat lld_*
x lld_nostrip.txt
+ lld_strip.txt
    N           Min           Max        Median           Avg        Stddev
x  10      3.929414       4.07692     4.0269079     4.0089678   0.044214794
+  10     3.8129408     3.9025559     3.8670411     3.8642573   0.024779651
Difference at 95.0% confidence
        -0.144711 +/- 0.0336749
        -3.60967% +/- 0.839989%
        (Student's t, pooled s = 0.0358398)

This interacts with many parts of the linker. I tried to add test coverage
for all added isLive() checks, so that some test will fail if any of them
is removed. I checked that the test expectations for the most part match
ld64's behavior (except for live-support-iterations.s, see the comment
in the test). Interacts with:

  • debug info
  • export tries
  • import opcodes
  • flags like -exported_symbol(s_list)
  • -U / dynamic_lookup
  • mod_init_funcs, mod_term_funcs
  • weak symbol handling
  • unwind info
  • stubs
  • map files
  • -sectcreate
  • undefined, dylib, common, defined (both absolute and normal) symbols

It's possible it interacts with more features I didn't think of,
of course.

I also did some manual testing:

  • check-llvm check-clang check-lld work with lld with this patch as host linker and -dead_strip enabled
  • Chromium still starts
  • Chromium's base_unittests still pass, including unwind tests

Implemenation-wise, this is InputSection-based, so it'll work for
object files with .subsections_via_symbols (which includes all
object files generated by clang). I first based this on the COFF
implementation, but later realized that things are more similar to ELF.
I think it'd be good to refactor MarkLive.cpp to look more like the ELF
part at some point, but I'd like to get a working state checked in first.

Mechanical parts:

  • Rename canOmitFromOutput to wasCoalesced (no behavior change) since it really is for weak coalesced symbols
  • Add noDeadStrip to Defined, corresponding to N_NO_DEAD_STRIP (.no_dead_strip in asm)

Fixes PR49276.

Differential Revision: https://reviews.llvm.org/D103324


thakisJun 2 2021, 8:09 AM
Differential Revision
D103324: [lld/mac] Implement -dead_strip
rG66a1ecd2cf90: [lld/mac] Implement -needed_framework, -needed_library, -needed-l