2021-06-28 17:36:04 +08:00
|
|
|
# REQUIRES: x86, llvm-64-bits
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
|
|
|
|
# RUN: rm -rf %t; split-file %s %t
|
|
|
|
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/basics.s -o %t/basics.o
|
|
|
|
|
|
|
|
## Check that .private_extern symbols are marked as local in the symbol table
|
|
|
|
## and aren't in the export trie.
|
|
|
|
# RUN: %lld -lSystem -dead_strip -map %t/map -u _ref_private_extern_u \
|
|
|
|
# RUN: %t/basics.o -o %t/basics
|
|
|
|
# RUN: llvm-objdump --syms --section-headers %t/basics | \
|
|
|
|
# RUN: FileCheck --check-prefix=EXEC --implicit-check-not _unref %s
|
|
|
|
# RUN: llvm-objdump --macho --section=__DATA,__ref_section \
|
|
|
|
# RUN: --exports-trie --indirect-symbols %t/basics | \
|
|
|
|
# RUN: FileCheck --check-prefix=EXECDATA --implicit-check-not _unref %s
|
|
|
|
# RUN: llvm-otool -l %t/basics | grep -q 'segname __PAGEZERO'
|
|
|
|
# EXEC-LABEL: Sections:
|
|
|
|
# EXEC-LABEL: Name
|
|
|
|
# EXEC-NEXT: __text
|
|
|
|
# EXEC-NEXT: __got
|
|
|
|
# EXEC-NEXT: __ref_section
|
|
|
|
# EXEC-NEXT: __common
|
|
|
|
# EXEC-LABEL: SYMBOL TABLE:
|
2022-01-06 10:58:12 +08:00
|
|
|
# EXEC-DAG: l {{.*}} _ref_data
|
|
|
|
# EXEC-DAG: l {{.*}} _ref_local
|
|
|
|
# EXEC-DAG: l {{.*}} _ref_from_no_dead_strip_globl
|
|
|
|
# EXEC-DAG: l {{.*}} _no_dead_strip_local
|
|
|
|
# EXEC-DAG: l {{.*}} _ref_from_no_dead_strip_local
|
|
|
|
# EXEC-DAG: l {{.*}} _ref_private_extern_u
|
|
|
|
# EXEC-DAG: l {{.*}} _main
|
|
|
|
# EXEC-DAG: l {{.*}} _ref_private_extern
|
|
|
|
# EXEC-DAG: g {{.*}} _no_dead_strip_globl
|
|
|
|
# EXEC-DAG: g {{.*}} _ref_com
|
|
|
|
# EXEC-DAG: g {{.*}} __mh_execute_header
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
# EXECDATA-LABEL: Indirect symbols
|
|
|
|
# EXECDATA-NEXT: name
|
|
|
|
# EXECDATA-NEXT: _ref_com
|
|
|
|
# EXECDATA-LABEL: Contents of (__DATA,__ref_section) section
|
|
|
|
# EXECDATA-NEXT: 04 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00
|
|
|
|
# EXECDATA-LABEL: Exports trie:
|
2022-01-06 10:58:12 +08:00
|
|
|
# EXECDATA-DAG: _ref_com
|
|
|
|
# EXECDATA-DAG: _no_dead_strip_globl
|
|
|
|
# EXECDATA-DAG: __mh_execute_header
|
2022-01-29 02:51:27 +08:00
|
|
|
|
|
|
|
## Check that dead stripped symbols get listed properly.
|
|
|
|
# RUN: FileCheck --check-prefix=MAP %s < %t/map
|
|
|
|
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
# MAP: _main
|
2022-01-29 02:51:27 +08:00
|
|
|
# MAP-LABEL: Dead Stripped Symbols
|
|
|
|
# MAP: <<dead>> [ 1] _unref_com
|
|
|
|
# MAP: <<dead>> [ 1] _unref_data
|
|
|
|
# MAP: <<dead>> [ 1] _unref_extern
|
|
|
|
# MAP: <<dead>> [ 1] _unref_local
|
|
|
|
# MAP: <<dead>> [ 1] _unref_private_extern
|
|
|
|
# MAP: <<dead>> [ 1] l_unref_data
|
|
|
|
|
|
|
|
## Run dead stripping on code without any dead symbols.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/no-dead-symbols.s -o %t/no-dead-symbols.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip -map %t/no-dead-symbols-map \
|
|
|
|
# RUN: %t/no-dead-symbols.o -o %t/no-dead-symbols
|
|
|
|
## Mark the end of the file with a string.
|
|
|
|
# RUN: FileCheck --check-prefix=NODEADSYMBOLS %s < %t/no-dead-symbols-map
|
|
|
|
|
|
|
|
# NODEADSYMBOLS-LABEL: # Symbols:
|
|
|
|
# NODEADSYMBOLS-NEXT: # Address File Name
|
|
|
|
# NODEADSYMBOLS-NEXT: _main
|
|
|
|
# NODEADSYMBOLS-LABEL: # Dead Stripped Symbols:
|
|
|
|
# NODEADSYMBOLS-NEXT: # Address File Name
|
|
|
|
# NODEADSYMBOLS-EMPTY:
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
|
|
|
|
# RUN: %lld -dylib -dead_strip -u _ref_private_extern_u %t/basics.o -o %t/basics.dylib
|
|
|
|
# RUN: llvm-objdump --syms %t/basics.dylib | \
|
|
|
|
# RUN: FileCheck --check-prefix=DYLIB --implicit-check-not _unref %s
|
|
|
|
# RUN: %lld -bundle -dead_strip -u _ref_private_extern_u %t/basics.o -o %t/basics.dylib
|
|
|
|
# RUN: llvm-objdump --syms %t/basics.dylib | \
|
|
|
|
# RUN: FileCheck --check-prefix=DYLIB --implicit-check-not _unref %s
|
|
|
|
# DYLIB-LABEL: SYMBOL TABLE:
|
2022-01-06 10:58:12 +08:00
|
|
|
# DYLIB-DAG: l {{.*}} _ref_data
|
|
|
|
# DYLIB-DAG: l {{.*}} _ref_local
|
|
|
|
# DYLIB-DAG: l {{.*}} _ref_from_no_dead_strip_globl
|
|
|
|
# DYLIB-DAG: l {{.*}} _no_dead_strip_local
|
|
|
|
# DYLIB-DAG: l {{.*}} _ref_from_no_dead_strip_local
|
|
|
|
# DYLIB-DAG: l {{.*}} _ref_private_extern_u
|
|
|
|
# DYLIB-DAG: l {{.*}} _ref_private_extern
|
|
|
|
# DYLIB-DAG: g {{.*}} _ref_com
|
|
|
|
# DYLIB-DAG: g {{.*}} _unref_com
|
|
|
|
# DYLIB-DAG: g {{.*}} _unref_extern
|
|
|
|
# DYLIB-DAG: g {{.*}} _no_dead_strip_globl
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
|
2021-07-06 12:25:01 +08:00
|
|
|
## Extern symbols aren't stripped from executables with -export_dynamic
|
|
|
|
# RUN: %lld -lSystem -dead_strip -export_dynamic -u _ref_private_extern_u \
|
2021-10-25 10:46:46 +08:00
|
|
|
# RUN: %t/basics.o -o %t/basics-export-dyn
|
|
|
|
# RUN: llvm-objdump --syms --section-headers %t/basics-export-dyn | \
|
2021-07-06 12:25:01 +08:00
|
|
|
# RUN: FileCheck --check-prefix=EXECDYN %s
|
|
|
|
# EXECDYN-LABEL: Sections:
|
|
|
|
# EXECDYN-LABEL: Name
|
|
|
|
# EXECDYN-NEXT: __text
|
|
|
|
# EXECDYN-NEXT: __got
|
|
|
|
# EXECDYN-NEXT: __ref_section
|
|
|
|
# EXECDYN-NEXT: __common
|
|
|
|
# EXECDYN-LABEL: SYMBOL TABLE:
|
2022-01-06 10:58:12 +08:00
|
|
|
# EXECDYN-DAG: l {{.*}} _ref_data
|
|
|
|
# EXECDYN-DAG: l {{.*}} _ref_local
|
|
|
|
# EXECDYN-DAG: l {{.*}} _ref_from_no_dead_strip_globl
|
|
|
|
# EXECDYN-DAG: l {{.*}} _no_dead_strip_local
|
|
|
|
# EXECDYN-DAG: l {{.*}} _ref_from_no_dead_strip_local
|
|
|
|
# EXECDYN-DAG: l {{.*}} _ref_private_extern_u
|
|
|
|
# EXECDYN-DAG: l {{.*}} _main
|
|
|
|
# EXECDYN-DAG: l {{.*}} _ref_private_extern
|
|
|
|
# EXECDYN-DAG: g {{.*}} _ref_com
|
|
|
|
# EXECDYN-DAG: g {{.*}} _unref_com
|
|
|
|
# EXECDYN-DAG: g {{.*}} _unref_extern
|
|
|
|
# EXECDYN-DAG: g {{.*}} _no_dead_strip_globl
|
|
|
|
# EXECDYN-DAG: g {{.*}} __mh_execute_header
|
2021-07-06 12:25:01 +08:00
|
|
|
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
## Absolute symbol handling.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/abs.s -o %t/abs.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/abs.o -o %t/abs
|
|
|
|
# RUN: llvm-objdump --macho --syms --exports-trie %t/abs | \
|
|
|
|
# RUN: FileCheck --check-prefix=ABS %s
|
|
|
|
#ABS-LABEL: SYMBOL TABLE:
|
|
|
|
#ABS-NEXT: g {{.*}} _main
|
|
|
|
#ABS-NEXT: g *ABS* _abs1
|
|
|
|
#ABS-NEXT: g {{.*}} __mh_execute_header
|
|
|
|
#ABS-LABEL: Exports trie:
|
|
|
|
#ABS-NEXT: __mh_execute_header
|
|
|
|
#ABS-NEXT: _main
|
|
|
|
#ABS-NEXT: _abs1 [absolute]
|
|
|
|
|
|
|
|
## Check that symbols from -exported_symbol(s_list) are preserved.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/exported-symbol.s -o %t/exported-symbol.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip -exported_symbol _my_exported_symbol \
|
|
|
|
# RUN: %t/exported-symbol.o -o %t/exported-symbol
|
|
|
|
# RUN: llvm-objdump --syms %t/exported-symbol | \
|
|
|
|
# RUN: FileCheck --check-prefix=EXPORTEDSYMBOL --implicit-check-not _unref %s
|
|
|
|
# EXPORTEDSYMBOL-LABEL: SYMBOL TABLE:
|
|
|
|
# EXPORTEDSYMBOL-NEXT: l {{.*}} _main
|
|
|
|
# EXPORTEDSYMBOL-NEXT: l {{.*}} __mh_execute_header
|
|
|
|
# EXPORTEDSYMBOL-NEXT: g {{.*}} _my_exported_symbol
|
|
|
|
|
|
|
|
## Check that mod_init_funcs and mod_term_funcs are not stripped.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/mod-funcs.s -o %t/mod-funcs.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/mod-funcs.o -o %t/mod-funcs
|
|
|
|
# RUN: llvm-objdump --syms %t/mod-funcs | \
|
|
|
|
# RUN: FileCheck --check-prefix=MODFUNCS --implicit-check-not _unref %s
|
|
|
|
# MODFUNCS-LABEL: SYMBOL TABLE:
|
|
|
|
# MODFUNCS-NEXT: l {{.*}} _ref_from_init
|
|
|
|
# MODFUNCS-NEXT: l {{.*}} _ref_init
|
|
|
|
# MODFUNCS-NEXT: l {{.*}} _ref_from_term
|
|
|
|
# MODFUNCS-NEXT: l {{.*}} _ref_term
|
|
|
|
# MODFUNCS-NEXT: g {{.*}} _main
|
|
|
|
# MODFUNCS-NEXT: g {{.*}} __mh_execute_header
|
|
|
|
|
|
|
|
## Check that DylibSymbols in dead subsections are stripped: They should
|
|
|
|
## not be in the import table and should have no import stubs.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/dylib.s -o %t/dylib.o
|
|
|
|
# RUN: %lld -dylib -dead_strip %t/dylib.o -o %t/dylib.dylib
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/strip-dylib-ref.s -o %t/strip-dylib-ref.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/strip-dylib-ref.o %t/dylib.dylib \
|
|
|
|
# RUN: -o %t/strip-dylib-ref -U _ref_undef_fun -U _unref_undef_fun
|
|
|
|
# RUN: llvm-objdump --syms --bind --lazy-bind --weak-bind %t/strip-dylib-ref | \
|
|
|
|
# RUN: FileCheck --check-prefix=STRIPDYLIB --implicit-check-not _unref %s
|
|
|
|
# STRIPDYLIB: SYMBOL TABLE:
|
|
|
|
# STRIPDYLIB-NEXT: l {{.*}} __dyld_private
|
|
|
|
# STRIPDYLIB-NEXT: g {{.*}} _main
|
|
|
|
# STRIPDYLIB-NEXT: g {{.*}} __mh_execute_header
|
|
|
|
# STRIPDYLIB-NEXT: *UND* dyld_stub_binder
|
|
|
|
# STRIPDYLIB-NEXT: *UND* _ref_dylib_fun
|
2021-07-22 23:20:36 +08:00
|
|
|
# STRIPDYLIB-NEXT: *UND* _ref_undef_fun
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
# STRIPDYLIB: Bind table:
|
|
|
|
# STRIPDYLIB: Lazy bind table:
|
|
|
|
# STRIPDYLIB: __DATA __la_symbol_ptr {{.*}} flat-namespace _ref_undef_fun
|
|
|
|
# STRIPDYLIB: __DATA __la_symbol_ptr {{.*}} dylib _ref_dylib_fun
|
|
|
|
# STRIPDYLIB: Weak bind table:
|
|
|
|
## Stubs smoke check: There should be two stubs entries, not four, but we
|
|
|
|
## don't verify that they belong to _ref_undef_fun and _ref_dylib_fun.
|
|
|
|
# RUN: llvm-objdump -d --section=__stubs --section=__stub_helper \
|
|
|
|
# RUN: %t/strip-dylib-ref |FileCheck --check-prefix=STUBS %s
|
|
|
|
# STUBS-LABEL: <__stubs>:
|
|
|
|
# STUBS-NEXT: jmpq
|
|
|
|
# STUBS-NEXT: jmpq
|
|
|
|
# STUBS-NOT: jmpq
|
|
|
|
# STUBS-LABEL: <__stub_helper>:
|
|
|
|
# STUBS: pushq $0
|
|
|
|
# STUBS: jmp
|
|
|
|
# STUBS: jmp
|
|
|
|
# STUBS-NOT: jmp
|
|
|
|
## An undefined symbol referenced from a dead-stripped function shouldn't
|
|
|
|
## produce a diagnostic:
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/strip-dylib-ref.o %t/dylib.dylib \
|
|
|
|
# RUN: -o %t/strip-dylib-ref -U _ref_undef_fun
|
|
|
|
|
2021-07-22 23:37:29 +08:00
|
|
|
## Check that referenced undefs are kept with -undefined dynamic_lookup.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/ref-undef.s -o %t/ref-undef.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/ref-undef.o \
|
|
|
|
# RUN: -o %t/ref-undef -undefined dynamic_lookup
|
|
|
|
# RUN: llvm-objdump --syms --lazy-bind %t/ref-undef | \
|
|
|
|
# RUN: FileCheck --check-prefix=STRIPDYNLOOKUP %s
|
|
|
|
# STRIPDYNLOOKUP: SYMBOL TABLE:
|
|
|
|
# STRIPDYNLOOKUP: *UND* _ref_undef_fun
|
|
|
|
# STRIPDYNLOOKUP: Lazy bind table:
|
|
|
|
# STRIPDYNLOOKUP: __DATA __la_symbol_ptr {{.*}} flat-namespace _ref_undef_fun
|
|
|
|
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
## S_ATTR_LIVE_SUPPORT tests.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/live-support.s -o %t/live-support.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/live-support.o %t/dylib.dylib \
|
|
|
|
# RUN: -U _ref_undef_fun -U _unref_undef_fun -o %t/live-support
|
|
|
|
# RUN: llvm-objdump --syms %t/live-support | \
|
|
|
|
# RUN: FileCheck --check-prefix=LIVESUPP --implicit-check-not _unref %s
|
|
|
|
# LIVESUPP-LABEL: SYMBOL TABLE:
|
|
|
|
# LIVESUPP-NEXT: l {{.*}} _ref_ls_fun_fw
|
|
|
|
# LIVESUPP-NEXT: l {{.*}} _ref_ls_fun_bw
|
|
|
|
# LIVESUPP-NEXT: l {{.*}} _ref_ls_dylib_fun
|
|
|
|
# LIVESUPP-NEXT: l {{.*}} _ref_ls_undef_fun
|
|
|
|
# LIVESUPP-NEXT: l {{.*}} __dyld_private
|
|
|
|
# LIVESUPP-NEXT: g {{.*}} _main
|
|
|
|
# LIVESUPP-NEXT: g {{.*}} _bar
|
|
|
|
# LIVESUPP-NEXT: g {{.*}} _foo
|
|
|
|
# LIVESUPP-NEXT: g {{.*}} __mh_execute_header
|
|
|
|
# LIVESUPP-NEXT: *UND* dyld_stub_binder
|
|
|
|
# LIVESUPP-NEXT: *UND* _ref_dylib_fun
|
2021-07-22 23:20:36 +08:00
|
|
|
# LIVESUPP-NEXT: *UND* _ref_undef_fun
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/live-support-iterations.s -o %t/live-support-iterations.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/live-support-iterations.o \
|
|
|
|
# RUN: -o %t/live-support-iterations
|
|
|
|
# RUN: llvm-objdump --syms %t/live-support-iterations | \
|
|
|
|
# RUN: FileCheck --check-prefix=LIVESUPP2 --implicit-check-not _unref %s
|
|
|
|
# LIVESUPP2-LABEL: SYMBOL TABLE:
|
|
|
|
# LIVESUPP2-NEXT: l {{.*}} _bar
|
|
|
|
# LIVESUPP2-NEXT: l {{.*}} _foo_refd
|
|
|
|
# LIVESUPP2-NEXT: l {{.*}} _bar_refd
|
|
|
|
# LIVESUPP2-NEXT: l {{.*}} _baz
|
|
|
|
# LIVESUPP2-NEXT: l {{.*}} _baz_refd
|
|
|
|
# LIVESUPP2-NEXT: l {{.*}} _foo
|
|
|
|
# LIVESUPP2-NEXT: g {{.*}} _main
|
|
|
|
# LIVESUPP2-NEXT: g {{.*}} __mh_execute_header
|
|
|
|
|
|
|
|
## Dead stripping should not remove the __TEXT,__unwind_info
|
|
|
|
## and __TEXT,__gcc_except_tab functions, but it should still
|
|
|
|
## remove the unreferenced function __Z5unref.
|
|
|
|
## The reference to ___gxx_personality_v0 should also not be
|
|
|
|
## stripped.
|
|
|
|
## (Need to use darwin19.0.0 to make -mc emit __LD,__compact_unwind.)
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 \
|
|
|
|
# RUN: %t/unwind.s -o %t/unwind.o
|
|
|
|
# RUN: %lld -lc++ -lSystem -dead_strip %t/unwind.o -o %t/unwind
|
|
|
|
# RUN: llvm-objdump --syms %t/unwind | \
|
|
|
|
# RUN: FileCheck --check-prefix=UNWIND --implicit-check-not unref %s
|
2021-06-02 23:33:08 +08:00
|
|
|
# RUN: llvm-otool -l %t/unwind | FileCheck --check-prefix=UNWINDSECT %s
|
|
|
|
# UNWINDSECT-DAG: sectname __unwind_info
|
|
|
|
# UNWINDSECT-DAG: sectname __gcc_except_tab
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
# UNWIND-LABEL: SYMBOL TABLE:
|
|
|
|
# UNWIND-NEXT: l O __TEXT,__gcc_except_tab GCC_except_table1
|
|
|
|
# UNWIND-NEXT: l O __DATA,__data __dyld_private
|
|
|
|
# UNWIND-NEXT: g F __TEXT,__text _main
|
|
|
|
# UNWIND-NEXT: g F __TEXT,__text __mh_execute_header
|
|
|
|
# UNWIND-NEXT: *UND* ___cxa_allocate_exception
|
|
|
|
# UNWIND-NEXT: *UND* ___cxa_end_catch
|
|
|
|
# UNWIND-NEXT: *UND* __ZTIi
|
|
|
|
# UNWIND-NEXT: *UND* ___cxa_throw
|
|
|
|
# UNWIND-NEXT: *UND* ___gxx_personality_v0
|
|
|
|
# UNWIND-NEXT: *UND* ___cxa_begin_catch
|
|
|
|
# UNWIND-NEXT: *UND* dyld_stub_binder
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
# UNWIND-NOT: GCC_except_table0
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
|
|
|
|
## If a dead stripped function has a strong ref to a dylib symbol but
|
|
|
|
## a live function only a weak ref, the dylib is still not a WEAK_DYLIB.
|
|
|
|
## This matches ld64.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/weak-ref.s -o %t/weak-ref.o
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/strong-dead-ref.s -o %t/strong-dead-ref.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/weak-ref.o %t/strong-dead-ref.o \
|
|
|
|
# RUN: %t/dylib.dylib -o %t/weak-ref
|
|
|
|
# RUN: llvm-otool -l %t/weak-ref | FileCheck -DDIR=%t --check-prefix=WEAK %s
|
|
|
|
# WEAK: cmd LC_LOAD_DYLIB
|
|
|
|
# WEAK-NEXT: cmdsize
|
|
|
|
# WEAK-NEXT: name /usr/lib/libSystem.dylib
|
|
|
|
# WEAK: cmd LC_LOAD_DYLIB
|
|
|
|
# WEAK-NEXT: cmdsize
|
|
|
|
# WEAK-NEXT: name [[DIR]]/dylib.dylib
|
|
|
|
|
|
|
|
## A strong symbol that would override a weak import does not emit the
|
|
|
|
## "this overrides a weak import" opcode if it is dead-stripped.
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/weak-dylib.s -o %t/weak-dylib.o
|
|
|
|
# RUN: %lld -dylib -dead_strip %t/weak-dylib.o -o %t/weak-dylib.dylib
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/dead-weak-override.s -o %t/dead-weak-override.o
|
|
|
|
# RUN: %lld -dead_strip %t/dead-weak-override.o %t/weak-dylib.dylib \
|
|
|
|
# RUN: -o %t/dead-weak-override
|
|
|
|
# RUN: llvm-objdump --macho --weak-bind --private-header \
|
|
|
|
# RUN: %t/dead-weak-override | FileCheck --check-prefix=DEADWEAK %s
|
|
|
|
# DEADWEAK-NOT: WEAK_DEFINES
|
|
|
|
# DEADWEAK: Weak bind table:
|
|
|
|
# DEADWEAK: segment section address type addend symbol
|
|
|
|
# DEADWEAK-NOT: strong _weak_in_dylib
|
|
|
|
|
|
|
|
## Stripped symbols should not be in the debug info stabs entries.
|
|
|
|
# RUN: llvm-mc -g -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/debug.s -o %t/debug.o
|
|
|
|
# RUN: %lld -lSystem -dead_strip %t/debug.o -o %t/debug
|
|
|
|
# RUN: dsymutil -s %t/debug | FileCheck --check-prefix=EXECSTABS %s
|
|
|
|
# EXECSTABS-NOT: N_FUN {{.*}} '_unref'
|
|
|
|
# EXECSTABS: N_FUN {{.*}} '_main'
|
|
|
|
# EXECSTABS-NOT: N_FUN {{.*}} '_unref'
|
|
|
|
|
2021-06-12 07:49:54 +08:00
|
|
|
# RUN: llvm-mc -g -filetype=obj -triple=x86_64-apple-macos \
|
|
|
|
# RUN: %t/literals.s -o %t/literals.o
|
|
|
|
# RUN: %lld -dylib -dead_strip --deduplicate-literals %t/literals.o -o %t/literals
|
|
|
|
# RUN: llvm-objdump --macho --section="__TEXT,__cstring" --section="__DATA,str_ptrs" \
|
|
|
|
# RUN: --section="__TEXT,__literals" %t/literals | FileCheck %s --check-prefix=LIT
|
|
|
|
|
|
|
|
# LIT: Contents of (__TEXT,__cstring) section
|
|
|
|
# LIT-NEXT: foobar
|
|
|
|
# LIT-NEXT: Contents of (__DATA,str_ptrs) section
|
|
|
|
# LIT-NEXT: __TEXT:__cstring:bar
|
|
|
|
# LIT-NEXT: __TEXT:__cstring:bar
|
|
|
|
# LIT-NEXT: Contents of (__TEXT,__literals) section
|
|
|
|
# LIT-NEXT: ef be ad de {{$}}
|
|
|
|
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
#--- basics.s
|
|
|
|
.comm _ref_com, 1
|
|
|
|
.comm _unref_com, 1
|
|
|
|
|
|
|
|
.section __DATA,__unref_section
|
|
|
|
_unref_data:
|
|
|
|
.quad 4
|
|
|
|
|
|
|
|
l_unref_data:
|
|
|
|
.quad 5
|
|
|
|
|
|
|
|
## Referenced by no_dead_strip == S_ATTR_NO_DEAD_STRIP
|
|
|
|
.section __DATA,__ref_section,regular,no_dead_strip
|
|
|
|
|
|
|
|
## Referenced because in no_dead_strip section.
|
|
|
|
_ref_data:
|
|
|
|
.quad 4
|
|
|
|
|
|
|
|
## This is a local symbol so it's not in the symbol table, but
|
|
|
|
## it is still in the section data.
|
|
|
|
l_ref_data:
|
|
|
|
.quad 5
|
|
|
|
|
|
|
|
.text
|
|
|
|
|
|
|
|
# Exported symbols should not be stripped from dylibs
|
|
|
|
# or bundles, but they should be stripped from executables.
|
|
|
|
.globl _unref_extern
|
|
|
|
_unref_extern:
|
|
|
|
callq _ref_local
|
|
|
|
retq
|
|
|
|
|
|
|
|
# Unreferenced local symbols should be stripped.
|
|
|
|
_unref_local:
|
|
|
|
retq
|
|
|
|
|
|
|
|
# Same for unreferenced private externs.
|
|
|
|
.globl _unref_private_extern
|
|
|
|
.private_extern _unref_private_extern
|
|
|
|
_unref_private_extern:
|
|
|
|
# This shouldn't create an indirect symbol since it's
|
|
|
|
# a reference from a dead function.
|
|
|
|
movb _unref_com@GOTPCREL(%rip), %al
|
|
|
|
retq
|
|
|
|
|
|
|
|
# Referenced local symbols should not be stripped.
|
|
|
|
_ref_local:
|
|
|
|
callq _ref_private_extern
|
|
|
|
retq
|
|
|
|
|
|
|
|
# Same for referenced private externs.
|
|
|
|
# This one is referenced by a relocation.
|
|
|
|
.globl _ref_private_extern
|
|
|
|
.private_extern _ref_private_extern
|
|
|
|
_ref_private_extern:
|
|
|
|
retq
|
|
|
|
|
|
|
|
# This one is referenced by a -u flag.
|
|
|
|
.globl _ref_private_extern_u
|
|
|
|
.private_extern _ref_private_extern_u
|
|
|
|
_ref_private_extern_u:
|
|
|
|
retq
|
|
|
|
|
|
|
|
# Entry point should not be stripped for executables, even if hidden.
|
|
|
|
# For shared libraries this is stripped since it's just a regular hidden
|
|
|
|
# symbol there.
|
|
|
|
.globl _main
|
|
|
|
.private_extern _main
|
|
|
|
_main:
|
|
|
|
movb _ref_com@GOTPCREL(%rip), %al
|
|
|
|
callq _ref_local
|
|
|
|
retq
|
|
|
|
|
|
|
|
# Things marked no_dead_strip should not be stripped either.
|
|
|
|
# (clang emits this e.g. for `__attribute__((used))` globals.)
|
|
|
|
# Both for .globl symbols...
|
|
|
|
.globl _no_dead_strip_globl
|
|
|
|
.no_dead_strip _no_dead_strip_globl
|
|
|
|
_no_dead_strip_globl:
|
|
|
|
callq _ref_from_no_dead_strip_globl
|
|
|
|
retq
|
|
|
|
_ref_from_no_dead_strip_globl:
|
|
|
|
retq
|
|
|
|
|
|
|
|
# ...and for locals.
|
|
|
|
.no_dead_strip _no_dead_strip_local
|
|
|
|
_no_dead_strip_local:
|
|
|
|
callq _ref_from_no_dead_strip_local
|
|
|
|
retq
|
|
|
|
_ref_from_no_dead_strip_local:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- exported-symbol.s
|
|
|
|
.text
|
|
|
|
|
|
|
|
.globl _unref_symbol
|
|
|
|
_unref_symbol:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _my_exported_symbol
|
|
|
|
_my_exported_symbol:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- abs.s
|
|
|
|
.globl _abs1, _abs2, _abs3
|
|
|
|
|
|
|
|
.no_dead_strip _abs1
|
|
|
|
_abs1 = 1
|
|
|
|
_abs2 = 2
|
|
|
|
_abs3 = 3
|
|
|
|
|
|
|
|
.section __DATA,__foo,regular,no_dead_strip
|
|
|
|
# Absolute symbols are not in a section, so the no_dead_strip
|
|
|
|
# on the section above has no effect.
|
|
|
|
.globl _abs4
|
|
|
|
_abs4 = 4
|
|
|
|
|
|
|
|
.text
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
# This is relaxed away, so there's no relocation here and
|
|
|
|
# _abs3 isn't in the exported symbol table.
|
|
|
|
mov _abs3, %rax
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- mod-funcs.s
|
|
|
|
## Roughly based on `clang -O2 -S` output for `struct A { A(); ~A(); }; A a;`
|
|
|
|
## for mod_init_funcs. mod_term_funcs then similar to that.
|
|
|
|
.section __TEXT,__StaticInit,regular,pure_instructions
|
|
|
|
|
|
|
|
__unref:
|
|
|
|
retq
|
|
|
|
|
|
|
|
_ref_from_init:
|
|
|
|
retq
|
|
|
|
|
|
|
|
_ref_init:
|
|
|
|
callq _ref_from_init
|
|
|
|
retq
|
|
|
|
|
|
|
|
_ref_from_term:
|
|
|
|
retq
|
|
|
|
|
|
|
|
_ref_term:
|
|
|
|
callq _ref_from_term
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.section __DATA,__mod_init_func,mod_init_funcs
|
|
|
|
.quad _ref_init
|
|
|
|
|
|
|
|
.section __DATA,__mod_term_func,mod_term_funcs
|
|
|
|
.quad _ref_term
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- dylib.s
|
|
|
|
.text
|
|
|
|
|
|
|
|
.globl _ref_dylib_fun
|
|
|
|
_ref_dylib_fun:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _unref_dylib_fun
|
|
|
|
_unref_dylib_fun:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- strip-dylib-ref.s
|
|
|
|
.text
|
|
|
|
|
|
|
|
_unref:
|
|
|
|
callq _ref_dylib_fun
|
|
|
|
callq _unref_dylib_fun
|
|
|
|
callq _ref_undef_fun
|
|
|
|
callq _unref_undef_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
callq _ref_dylib_fun
|
|
|
|
callq _ref_undef_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- live-support.s
|
|
|
|
## In practice, live_support is used for instruction profiling
|
|
|
|
## data and asan. (Also for __eh_frame, but that needs special handling
|
|
|
|
## in the linker anyways.)
|
|
|
|
## This test isn't based on anything happening in real code though.
|
|
|
|
.section __TEXT,__ref_ls_fw,regular,live_support
|
|
|
|
_ref_ls_fun_fw:
|
|
|
|
# This is called by _main and is kept alive by normal
|
|
|
|
# forward liveness propagation, The live_support attribute
|
|
|
|
# does nothing in this case.
|
|
|
|
retq
|
|
|
|
|
|
|
|
.section __TEXT,__unref_ls_fw,regular,live_support
|
|
|
|
_unref_ls_fun_fw:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.section __TEXT,__ref_ls_bw,regular,live_support
|
|
|
|
_ref_ls_fun_bw:
|
|
|
|
# This _calls_ something that's alive but isn't referenced itself. This is
|
|
|
|
# kept alive only due to this being in a live_support section.
|
|
|
|
callq _foo
|
|
|
|
|
|
|
|
# _bar on the other hand is kept alive since it's called from here.
|
|
|
|
callq _bar
|
|
|
|
retq
|
|
|
|
|
|
|
|
## Kept alive by a live symbol form a dynamic library.
|
|
|
|
_ref_ls_dylib_fun:
|
|
|
|
callq _ref_dylib_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
## Kept alive by a live undefined symbol.
|
|
|
|
_ref_ls_undef_fun:
|
|
|
|
callq _ref_undef_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
## All symbols in this live_support section reference dead symbols
|
|
|
|
## and are hence dead themselves.
|
|
|
|
.section __TEXT,__unref_ls_bw,regular,live_support
|
|
|
|
_unref_ls_fun_bw:
|
|
|
|
callq _unref
|
|
|
|
retq
|
|
|
|
|
|
|
|
_unref_ls_dylib_fun_bw:
|
|
|
|
callq _unref_dylib_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
_unref_ls_undef_fun_bw:
|
|
|
|
callq _unref_undef_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
.text
|
|
|
|
.globl _unref
|
|
|
|
_unref:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _bar
|
|
|
|
_bar:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _foo
|
|
|
|
_foo:
|
|
|
|
callq _ref_ls_fun_fw
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
callq _ref_ls_fun_fw
|
|
|
|
callq _foo
|
|
|
|
callq _ref_dylib_fun
|
|
|
|
callq _ref_undef_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- live-support-iterations.s
|
|
|
|
.section __TEXT,_ls,regular,live_support
|
|
|
|
|
|
|
|
## This is a live_support subsection that only becomes
|
|
|
|
## live after _foo below is processed. This means the algorithm of
|
|
|
|
## 1. mark things reachable from gc roots live
|
|
|
|
## 2. go through live sections and mark the ones live pointing to
|
|
|
|
## live symbols or sections
|
|
|
|
## needs more than one iteration, since _bar won't be live when step 2
|
|
|
|
## runs for the first time.
|
|
|
|
## (ld64 gets this wrong -- it has different output based on if _bar is
|
|
|
|
## before _foo or after it.)
|
|
|
|
_bar:
|
|
|
|
callq _foo_refd
|
|
|
|
callq _bar_refd
|
|
|
|
retq
|
|
|
|
|
|
|
|
## Same here. This is maybe more interesting since it references a live_support
|
|
|
|
## symbol instead of a "normal" symbol.
|
|
|
|
_baz:
|
|
|
|
callq _foo_refd
|
|
|
|
callq _baz_refd
|
|
|
|
retq
|
|
|
|
|
|
|
|
_foo:
|
|
|
|
callq _main
|
|
|
|
callq _foo_refd
|
|
|
|
retq
|
|
|
|
|
|
|
|
## Test no_dead_strip on a symbol in a live_support section.
|
|
|
|
## ld64 ignores this, but that doesn't look intentional. So lld honors it.
|
|
|
|
.no_dead_strip
|
|
|
|
_quux:
|
|
|
|
retq
|
|
|
|
|
|
|
|
|
|
|
|
.text
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
movq $0, %rax
|
|
|
|
retq
|
|
|
|
|
|
|
|
_foo_refd:
|
|
|
|
retq
|
|
|
|
|
|
|
|
_bar_refd:
|
|
|
|
retq
|
|
|
|
|
|
|
|
_baz_refd:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- unwind.s
|
|
|
|
## This is the output of `clang -O2 -S throw.cc` where throw.cc
|
|
|
|
## looks like this:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
## int unref() {
|
|
|
|
## try {
|
|
|
|
## throw 0;
|
|
|
|
## } catch (int i) {
|
|
|
|
## return i + 1;
|
|
|
|
## }
|
|
|
|
## }
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
## int main() {
|
|
|
|
## try {
|
|
|
|
## throw 0;
|
|
|
|
## } catch (int i) {
|
|
|
|
## return i;
|
|
|
|
## }
|
|
|
|
## }
|
|
|
|
.section __TEXT,__text,regular,pure_instructions
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
.globl __Z5unrefv ## -- Begin function _Z5unrefv
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
.p2align 4, 0x90
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
__Z5unrefv: ## @_Z5unrefv
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
Lfunc_begin0:
|
|
|
|
.cfi_startproc
|
|
|
|
.cfi_personality 155, ___gxx_personality_v0
|
|
|
|
.cfi_lsda 16, Lexception0
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
## %bb.0:
|
|
|
|
pushq %rbp
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
.cfi_def_cfa_offset 16
|
|
|
|
.cfi_offset %rbp, -16
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
movq %rsp, %rbp
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
.cfi_def_cfa_register %rbp
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
subq $16, %rsp
|
|
|
|
movl $4, %edi
|
|
|
|
callq ___cxa_allocate_exception
|
|
|
|
movl $0, (%rax)
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
Ltmp0:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
movq __ZTIi@GOTPCREL(%rip), %rsi
|
|
|
|
movq %rax, %rdi
|
|
|
|
xorl %edx, %edx
|
|
|
|
callq ___cxa_throw
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
Ltmp1:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
## %bb.1:
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
ud2
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
LBB0_2:
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
Ltmp2:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
leaq -4(%rbp), %rcx
|
|
|
|
movq %rax, %rdi
|
|
|
|
movl %edx, %esi
|
|
|
|
movq %rcx, %rdx
|
|
|
|
callq __Z5unrefv.cold.1
|
|
|
|
movl -4(%rbp), %eax
|
|
|
|
addq $16, %rsp
|
|
|
|
popq %rbp
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
retq
|
|
|
|
Lfunc_end0:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
.cfi_endproc
|
|
|
|
.section __TEXT,__gcc_except_tab
|
|
|
|
.p2align 2
|
|
|
|
GCC_except_table0:
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
Lexception0:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
.byte 255 ## @LPStart Encoding = omit
|
|
|
|
.byte 155 ## @TType Encoding = indirect pcrel sdata4
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
.uleb128 Lttbase0-Lttbaseref0
|
|
|
|
Lttbaseref0:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
.byte 1 ## Call site Encoding = uleb128
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
.uleb128 Lcst_end0-Lcst_begin0
|
|
|
|
Lcst_begin0:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
.uleb128 Lfunc_begin0-Lfunc_begin0 ## >> Call Site 1 <<
|
|
|
|
.uleb128 Ltmp0-Lfunc_begin0 ## Call between Lfunc_begin0 and Ltmp0
|
|
|
|
.byte 0 ## has no landing pad
|
|
|
|
.byte 0 ## On action: cleanup
|
|
|
|
.uleb128 Ltmp0-Lfunc_begin0 ## >> Call Site 2 <<
|
|
|
|
.uleb128 Ltmp1-Ltmp0 ## Call between Ltmp0 and Ltmp1
|
|
|
|
.uleb128 Ltmp2-Lfunc_begin0 ## jumps to Ltmp2
|
|
|
|
.byte 1 ## On action: 1
|
|
|
|
.uleb128 Ltmp1-Lfunc_begin0 ## >> Call Site 3 <<
|
|
|
|
.uleb128 Lfunc_end0-Ltmp1 ## Call between Ltmp1 and Lfunc_end0
|
|
|
|
.byte 0 ## has no landing pad
|
|
|
|
.byte 0 ## On action: cleanup
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
Lcst_end0:
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
.byte 1 ## >> Action Record 1 <<
|
|
|
|
## Catch TypeInfo 1
|
|
|
|
.byte 0 ## No further actions
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
.p2align 2
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
## >> Catch TypeInfos <<
|
|
|
|
.long __ZTIi@GOTPCREL+4 ## TypeInfo 1
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
Lttbase0:
|
|
|
|
.p2align 2
|
[lld-macho] Associate compact unwind entries with function symbols
Compact unwind entries (CUEs) contain pointers to their respective
function symbols. However, during the link process, it's far more useful
to have pointers from the function symbol to the CUE than vice versa.
This diff adds that pointer in the form of `Defined::compactUnwind`.
In particular, when doing dead-stripping, we want to mark CUEs live when
their function symbol is live; and when doing ICF, we want to dedup
sections iff the symbols in that section have identical CUEs. In both
cases, we want to be able to locate the symbols within a given section,
as well as locate the CUEs belonging to those symbols. So this diff also
adds `InputSection::symbols`.
The ultimate goal of this refactor is to have ICF support dedup'ing
functions with unwind info, but that will be handled in subsequent
diffs. This diff focuses on simplifying `-dead_strip` --
`findFunctionsWithUnwindInfo` is no longer necessary, and
`Defined::isLive()` is now a lot simpler. Moreover, UnwindInfoSection no
longer has to check for dead CUEs -- we simply avoid adding them in the
first place.
Additionally, we now support stripping of dead LSDAs, which follows
quite naturally since `markLive()` can now reach them via the CUEs.
Reviewed By: #lld-macho, gkm
Differential Revision: https://reviews.llvm.org/D109944
2021-10-27 04:04:04 +08:00
|
|
|
## -- End function
|
|
|
|
.section __TEXT,__text,regular,pure_instructions
|
|
|
|
.globl _main ## -- Begin function main
|
|
|
|
.p2align 4, 0x90
|
|
|
|
_main: ## @main
|
|
|
|
Lfunc_begin1:
|
|
|
|
.cfi_startproc
|
|
|
|
.cfi_personality 155, ___gxx_personality_v0
|
|
|
|
.cfi_lsda 16, Lexception1
|
|
|
|
## %bb.0:
|
|
|
|
pushq %rbp
|
|
|
|
.cfi_def_cfa_offset 16
|
|
|
|
.cfi_offset %rbp, -16
|
|
|
|
movq %rsp, %rbp
|
|
|
|
.cfi_def_cfa_register %rbp
|
|
|
|
pushq %rbx
|
|
|
|
pushq %rax
|
|
|
|
.cfi_offset %rbx, -24
|
|
|
|
movl $4, %edi
|
|
|
|
callq ___cxa_allocate_exception
|
|
|
|
movl $0, (%rax)
|
|
|
|
Ltmp3:
|
|
|
|
movq __ZTIi@GOTPCREL(%rip), %rsi
|
|
|
|
movq %rax, %rdi
|
|
|
|
xorl %edx, %edx
|
|
|
|
callq ___cxa_throw
|
|
|
|
Ltmp4:
|
|
|
|
## %bb.1:
|
|
|
|
ud2
|
|
|
|
LBB1_2:
|
|
|
|
Ltmp5:
|
|
|
|
movq %rax, %rdi
|
|
|
|
callq ___cxa_begin_catch
|
|
|
|
movl (%rax), %ebx
|
|
|
|
callq ___cxa_end_catch
|
|
|
|
movl %ebx, %eax
|
|
|
|
addq $8, %rsp
|
|
|
|
popq %rbx
|
|
|
|
popq %rbp
|
|
|
|
retq
|
|
|
|
Lfunc_end1:
|
|
|
|
.cfi_endproc
|
|
|
|
.section __TEXT,__gcc_except_tab
|
|
|
|
.p2align 2
|
|
|
|
GCC_except_table1:
|
|
|
|
Lexception1:
|
|
|
|
.byte 255 ## @LPStart Encoding = omit
|
|
|
|
.byte 155 ## @TType Encoding = indirect pcrel sdata4
|
|
|
|
.uleb128 Lttbase1-Lttbaseref1
|
|
|
|
Lttbaseref1:
|
|
|
|
.byte 1 ## Call site Encoding = uleb128
|
|
|
|
.uleb128 Lcst_end1-Lcst_begin1
|
|
|
|
Lcst_begin1:
|
|
|
|
.uleb128 Lfunc_begin1-Lfunc_begin1 ## >> Call Site 1 <<
|
|
|
|
.uleb128 Ltmp3-Lfunc_begin1 ## Call between Lfunc_begin1 and Ltmp3
|
|
|
|
.byte 0 ## has no landing pad
|
|
|
|
.byte 0 ## On action: cleanup
|
|
|
|
.uleb128 Ltmp3-Lfunc_begin1 ## >> Call Site 2 <<
|
|
|
|
.uleb128 Ltmp4-Ltmp3 ## Call between Ltmp3 and Ltmp4
|
|
|
|
.uleb128 Ltmp5-Lfunc_begin1 ## jumps to Ltmp5
|
|
|
|
.byte 1 ## On action: 1
|
|
|
|
.uleb128 Ltmp4-Lfunc_begin1 ## >> Call Site 3 <<
|
|
|
|
.uleb128 Lfunc_end1-Ltmp4 ## Call between Ltmp4 and Lfunc_end1
|
|
|
|
.byte 0 ## has no landing pad
|
|
|
|
.byte 0 ## On action: cleanup
|
|
|
|
Lcst_end1:
|
|
|
|
.byte 1 ## >> Action Record 1 <<
|
|
|
|
## Catch TypeInfo 1
|
|
|
|
.byte 0 ## No further actions
|
|
|
|
.p2align 2
|
|
|
|
## >> Catch TypeInfos <<
|
|
|
|
.long __ZTIi@GOTPCREL+4 ## TypeInfo 1
|
|
|
|
Lttbase1:
|
|
|
|
.p2align 2
|
|
|
|
## -- End function
|
|
|
|
.section __TEXT,__text,regular,pure_instructions
|
|
|
|
.p2align 4, 0x90 ## -- Begin function _Z5unrefv.cold.1
|
|
|
|
__Z5unrefv.cold.1: ## @_Z5unrefv.cold.1
|
|
|
|
.cfi_startproc
|
|
|
|
## %bb.0:
|
|
|
|
pushq %rbp
|
|
|
|
.cfi_def_cfa_offset 16
|
|
|
|
.cfi_offset %rbp, -16
|
|
|
|
movq %rsp, %rbp
|
|
|
|
.cfi_def_cfa_register %rbp
|
|
|
|
pushq %rbx
|
|
|
|
pushq %rax
|
|
|
|
.cfi_offset %rbx, -24
|
|
|
|
movq %rdx, %rbx
|
|
|
|
callq ___cxa_begin_catch
|
|
|
|
movl (%rax), %eax
|
|
|
|
incl %eax
|
|
|
|
movl %eax, (%rbx)
|
|
|
|
addq $8, %rsp
|
|
|
|
popq %rbx
|
|
|
|
popq %rbp
|
|
|
|
jmp ___cxa_end_catch ## TAILCALL
|
|
|
|
.cfi_endproc
|
|
|
|
## -- End function
|
[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
2021-05-08 05:10:05 +08:00
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- weak-ref.s
|
|
|
|
.text
|
|
|
|
.weak_reference _ref_dylib_fun
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
callq _ref_dylib_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- strong-dead-ref.s
|
|
|
|
.text
|
|
|
|
.globl _unref_dylib_fun
|
|
|
|
_unref:
|
|
|
|
callq _unref_dylib_fun
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- weak-dylib.s
|
|
|
|
.text
|
|
|
|
.globl _weak_in_dylib
|
|
|
|
.weak_definition _weak_in_dylib
|
|
|
|
_weak_in_dylib:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- dead-weak-override.s
|
|
|
|
|
|
|
|
## Overrides the _weak_in_dylib symbol in weak-dylib, but is dead stripped.
|
|
|
|
.text
|
|
|
|
|
|
|
|
#.no_dead_strip _weak_in_dylib
|
|
|
|
.globl _weak_in_dylib
|
|
|
|
_weak_in_dylib:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
|
|
|
|
|
|
|
#--- debug.s
|
|
|
|
.text
|
|
|
|
.globl _unref
|
|
|
|
_unref:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
retq
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
2021-06-12 07:49:54 +08:00
|
|
|
|
2022-01-29 02:51:27 +08:00
|
|
|
#--- no-dead-symbols.s
|
|
|
|
.text
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
retq
|
|
|
|
|
2021-06-12 07:49:54 +08:00
|
|
|
#--- literals.s
|
|
|
|
.cstring
|
|
|
|
_unref_foo:
|
|
|
|
.ascii "foo"
|
|
|
|
_bar:
|
|
|
|
Lbar:
|
|
|
|
.asciz "bar"
|
|
|
|
_unref_baz:
|
|
|
|
.asciz "baz"
|
|
|
|
|
|
|
|
.literal4
|
|
|
|
.p2align 2
|
|
|
|
L._foo4:
|
|
|
|
.long 0xdeadbeef
|
|
|
|
L._bar4:
|
|
|
|
.long 0xdeadbeef
|
|
|
|
L._unref:
|
|
|
|
.long 0xfeedface
|
|
|
|
|
|
|
|
.section __DATA,str_ptrs,literal_pointers
|
|
|
|
.globl _data
|
|
|
|
_data:
|
|
|
|
.quad _bar
|
|
|
|
.quad Lbar
|
|
|
|
|
|
|
|
## The output binary has these integer literals put into a section that isn't
|
|
|
|
## marked with a S_*BYTE_LITERALS flag, so we don't mark word_ptrs with the
|
|
|
|
## S_LITERAL_POINTERS flag in order not to confuse llvm-objdump.
|
|
|
|
.section __DATA,word_ptrs
|
|
|
|
.globl _more_data
|
|
|
|
_more_data:
|
|
|
|
.quad L._foo4
|
|
|
|
.quad L._bar4
|
|
|
|
|
|
|
|
.subsections_via_symbols
|
2021-07-22 23:37:29 +08:00
|
|
|
|
|
|
|
#--- ref-undef.s
|
|
|
|
.globl _main
|
|
|
|
_main:
|
|
|
|
callq _ref_undef_fun
|
|
|
|
.subsections_via_symbols
|