150 lines
5.8 KiB
ArmAsm
150 lines
5.8 KiB
ArmAsm
|
# REQUIRES: x86
|
||
|
## This test checks that when we coalesce weak definitions, their local symbol
|
||
|
## aliases defs don't cause the coalesced data to be retained. This was
|
||
|
## motivated by MC's aarch64 backend which automatically creates `ltmp<N>`
|
||
|
## symbols at the start of each .text section. These symbols are frequently
|
||
|
## aliases of other symbols created by clang or other inputs to MC. I've chosen
|
||
|
## to explicitly create them here since we can then reference those symbols for
|
||
|
## a more complete test.
|
||
|
##
|
||
|
## Not retaining the data matters for more than just size -- we have a use case
|
||
|
## that depends on proper data coalescing to emit a valid file format. We also
|
||
|
## need this behavior to properly deduplicate the __objc_protolist section;
|
||
|
## failure to do this can result in dyld crashing on iOS 13.
|
||
|
##
|
||
|
## Finally, ld64 does all this regardless of whether .subsections_via_symbols is
|
||
|
## specified. We don't. But again, given how rare the lack of that directive is
|
||
|
## (I've only seen it from hand-written assembly inputs), I don't think we need
|
||
|
## to worry about it.
|
||
|
|
||
|
# RUN: rm -rf %t; split-file %s %t
|
||
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/weak-then-local.s -o %t/weak-then-local.o
|
||
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/local-then-weak.s -o %t/local-then-weak.o
|
||
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/no-subsections.s -o %t/no-subsections.o
|
||
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/no-dead-strip.s -o %t/no-dead-strip.o
|
||
|
|
||
|
# RUN: %lld -lSystem -dylib %t/weak-then-local.o %t/local-then-weak.o -o %t/test1
|
||
|
# RUN: llvm-objdump --macho --syms --section="__DATA,__data" --weak-bind %t/test1 | FileCheck %s
|
||
|
# RUN: %lld -lSystem -dylib %t/local-then-weak.o %t/weak-then-local.o -o %t/test2
|
||
|
# RUN: llvm-objdump --macho --syms --section="__DATA,__data" --weak-bind %t/test2 | FileCheck %s
|
||
|
|
||
|
## Check that we only have one copy of 0x123 in the data, not two.
|
||
|
# CHECK: Contents of (__DATA,__data) section
|
||
|
# CHECK-NEXT: 0000000000001000 23 01 00 00 00 00 00 00 00 10 00 00 00 00 00 00 {{$}}
|
||
|
# CHECK-NEXT: 0000000000001010 00 10 00 00 00 00 00 00 {{$}}
|
||
|
# CHECK-EMPTY:
|
||
|
# CHECK-NEXT: SYMBOL TABLE:
|
||
|
# CHECK-NEXT: 0000000000001000 l O __DATA,__data _alias
|
||
|
# CHECK-NEXT: 0000000000001008 l O __DATA,__data _ref
|
||
|
# CHECK-NEXT: 0000000000001000 l O __DATA,__data _alias
|
||
|
# CHECK-NEXT: 0000000000001010 l O __DATA,__data _ref
|
||
|
# CHECK-NEXT: 0000000000001000 w O __DATA,__data _weak
|
||
|
# CHECK-NEXT: 0000000000000000 *UND* dyld_stub_binder
|
||
|
# CHECK-EMPTY:
|
||
|
## Even though the references were to the non-weak `_alias` symbols, ld64 still
|
||
|
## emits weak binds as if they were the `_weak` symbol itself. We do not. I
|
||
|
## don't know of any programs that rely on this behavior, so I'm just
|
||
|
## documenting it here.
|
||
|
# CHECK-NEXT: Weak bind table:
|
||
|
# CHECK-NEXT: segment section address type addend symbol
|
||
|
# CHECK-EMPTY:
|
||
|
|
||
|
# RUN: %lld -lSystem -dylib %t/local-then-weak.o %t/no-subsections.o -o %t/sub-nosub
|
||
|
# RUN: llvm-objdump --macho --syms --section="__DATA,__data" %t/sub-nosub | FileCheck %s --check-prefix SUB-NOSUB
|
||
|
|
||
|
## This test case demonstrates a shortcoming of LLD: If .subsections_via_symbols
|
||
|
## isn't enabled, we don't elide the contents of coalesced weak symbols if they
|
||
|
## are part of a section that has other non-coalesced symbols. In contrast, LD64
|
||
|
## does elide the contents.
|
||
|
# SUB-NOSUB: Contents of (__DATA,__data) section
|
||
|
# SUB-NOSUB-NEXT: 0000000000001000 23 01 00 00 00 00 00 00 00 10 00 00 00 00 00 00
|
||
|
# SUB-NOSUB-NEXT: 0000000000001010 00 00 00 00 00 00 00 00 23 01 00 00 00 00 00 00
|
||
|
# SUB-NOSUB-EMPTY:
|
||
|
# SUB-NOSUB-NEXT: SYMBOL TABLE:
|
||
|
# SUB-NOSUB-NEXT: 0000000000001000 l O __DATA,__data _alias
|
||
|
# SUB-NOSUB-NEXT: 0000000000001008 l O __DATA,__data _ref
|
||
|
# SUB-NOSUB-NEXT: 0000000000001010 l O __DATA,__data _zeros
|
||
|
# SUB-NOSUB-NEXT: 0000000000001000 l O __DATA,__data _alias
|
||
|
# SUB-NOSUB-NEXT: 0000000000001000 w O __DATA,__data _weak
|
||
|
# SUB-NOSUB-NEXT: 0000000000000000 *UND* dyld_stub_binder
|
||
|
|
||
|
# RUN: %lld -lSystem -dylib %t/no-subsections.o %t/local-then-weak.o -o %t/nosub-sub
|
||
|
# RUN: llvm-objdump --macho --syms --section="__DATA,__data" %t/nosub-sub | FileCheck %s --check-prefix NOSUB-SUB
|
||
|
|
||
|
# NOSUB-SUB: Contents of (__DATA,__data) section
|
||
|
# NOSUB-SUB-NEXT: 0000000000001000 00 00 00 00 00 00 00 00 23 01 00 00 00 00 00 00
|
||
|
# NOSUB-SUB-NEXT: 0000000000001010 08 10 00 00 00 00 00 00 {{$}}
|
||
|
# NOSUB-SUB-EMPTY:
|
||
|
# NOSUB-SUB-NEXT: SYMBOL TABLE:
|
||
|
# NOSUB-SUB-NEXT: 0000000000001000 l O __DATA,__data _zeros
|
||
|
# NOSUB-SUB-NEXT: 0000000000001008 l O __DATA,__data _alias
|
||
|
# NOSUB-SUB-NEXT: 0000000000001008 l O __DATA,__data _alias
|
||
|
# NOSUB-SUB-NEXT: 0000000000001010 l O __DATA,__data _ref
|
||
|
# NOSUB-SUB-NEXT: 0000000000001008 w O __DATA,__data _weak
|
||
|
# NOSUB-SUB-NEXT: 0000000000000000 *UND* dyld_stub_binder
|
||
|
|
||
|
## Verify that we don't drop any flags that the aliases have (such as
|
||
|
## .no_dead_strip). This is a regression test. We previously had subsections
|
||
|
## that were mistakenly stripped.
|
||
|
|
||
|
# RUN: %lld -lSystem -dead_strip %t/no-dead-strip.o -o %t/no-dead-strip
|
||
|
# RUN: llvm-objdump --macho --section-headers %t/no-dead-strip | FileCheck %s \
|
||
|
# RUN: --check-prefix=NO-DEAD-STRIP
|
||
|
# NO-DEAD-STRIP: __data 00000010
|
||
|
|
||
|
#--- weak-then-local.s
|
||
|
.globl _weak
|
||
|
.weak_definition _weak
|
||
|
.data
|
||
|
_weak:
|
||
|
_alias:
|
||
|
.quad 0x123
|
||
|
|
||
|
_ref:
|
||
|
.quad _alias
|
||
|
|
||
|
.subsections_via_symbols
|
||
|
|
||
|
#--- local-then-weak.s
|
||
|
.globl _weak
|
||
|
.weak_definition _weak
|
||
|
.data
|
||
|
_alias:
|
||
|
_weak:
|
||
|
.quad 0x123
|
||
|
|
||
|
_ref:
|
||
|
.quad _alias
|
||
|
|
||
|
.subsections_via_symbols
|
||
|
|
||
|
#--- no-subsections.s
|
||
|
.globl _weak
|
||
|
.weak_definition _weak
|
||
|
.data
|
||
|
_zeros:
|
||
|
.space 8
|
||
|
|
||
|
_weak:
|
||
|
_alias:
|
||
|
.quad 0x123
|
||
|
|
||
|
#--- no-dead-strip.s
|
||
|
.globl _main
|
||
|
|
||
|
_main:
|
||
|
ret
|
||
|
|
||
|
.data
|
||
|
.no_dead_strip l_foo, l_bar
|
||
|
|
||
|
_foo:
|
||
|
l_foo:
|
||
|
.quad 0x123
|
||
|
|
||
|
l_bar:
|
||
|
_bar:
|
||
|
.quad 0x123
|
||
|
|
||
|
.subsections_via_symbols
|