1# REQUIRES: x86 2# RUN: rm -rf %t; split-file %s %t 3 4# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \ 5# RUN: %t/weak-foo.s -o %t/weak-foo.o 6 7# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \ 8# RUN: %t/weak-autohide-foo.s -o %t/weak-autohide-foo.o 9 10# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \ 11# RUN: %t/weak-foo-pe.s -o %t/weak-foo-pe.o 12 13# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \ 14# RUN: %t/weak-autohide-foo-pe.s -o %t/weak-autohide-foo-pe.o 15 16# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos \ 17# RUN: %t/ref-foo.s -o %t/ref-foo.o 18 19## Basics: A weak_def_can_be_hidden symbol should not be in the output's 20## export table, nor in the weak bind table, and references to it from 21## within the dylib should not use weak indirect lookups. 22## Think: Inline function compiled without any -fvisibility flags, inline 23## function does not have its address taken. In -O2 compiles, GlobalOpt will 24## upgrade the inline function from .weak_definition to .weak_def_can_be_hidden. 25# RUN: %lld -dylib -o %t/weak-autohide-foo.dylib \ 26# RUN: %t/weak-autohide-foo.o %t/ref-foo.o 27# RUN: llvm-objdump --syms --exports-trie %t/weak-autohide-foo.dylib | \ 28# RUN: FileCheck --check-prefix=EXPORTS %s 29# RUN: llvm-nm -m %t/weak-autohide-foo.dylib | \ 30# RUN: FileCheck --check-prefix=EXPORTS-NM %s 31# RUN: llvm-objdump --macho --bind --weak-bind %t/weak-autohide-foo.dylib | \ 32# RUN: FileCheck --check-prefix=WEAKBIND %s 33# RUN: llvm-objdump --macho --private-header %t/weak-autohide-foo.dylib | \ 34# RUN: FileCheck --check-prefix=HEADERS %s 35 36## ld64 doesn't treat .weak_def_can_be_hidden as weak symbols in the 37## exports trie or bind tables, but it claims they are weak in the symbol 38## table. lld marks them as local in the symbol table, see also test 39## weak-private-extern.s. These FileCheck lines match both outputs. 40# EXPORTS-LABEL: SYMBOL TABLE: 41# EXPORTS-DAG: [[#%x, FOO_ADDR:]] {{.*}} _foo 42# EXPORTS-LABEL: Exports trie: 43# EXPORTS-NOT: 0x{{0*}}[[#%X, FOO_ADDR]] _foo 44 45## nm output for .weak_def_can_be_hidden says "was a private external" even 46## though it wasn't .private_extern: It was just .weak_def_can_be_hidden. 47## This matches ld64. 48# EXPORTS-NM: (__TEXT,__text) non-external (was a private external) _foo 49 50# WEAKBIND-NOT: __got 51# WEAKBIND-NOT: __la_symbol_ptr 52 53## ld64 sets WEAKBIND and BINDS_TO_WEAK in the mach-o header even though there 54## are no weak bindings or weak definitions after processing the autohide. That 55## looks like a bug in ld64 (?) If you change lit.local.cfg to set %lld to ld to 56## test compatibility, you have to add some arbitrary suffix to these two lines: 57# HEADERS-NOT: WEAK_DEFINES 58# HEADERS-NOT: BINDS_TO_WEAK 59 60## Same behavior for a symbol that's both .weak_def_can_be_hidden and 61## .private_extern. Think: Inline function compiled with 62## -fvisibility-inlines-hidden. 63# RUN: %lld -dylib -o %t/weak-autohide-foo-pe.dylib \ 64# RUN: %t/weak-autohide-foo-pe.o %t/ref-foo.o 65# RUN: llvm-objdump --syms --exports-trie %t/weak-autohide-foo-pe.dylib | \ 66# RUN: FileCheck --check-prefix=EXPORTS %s 67# RUN: llvm-nm -m %t/weak-autohide-foo-pe.dylib | \ 68# RUN: FileCheck --check-prefix=EXPORTS-NM %s 69# RUN: llvm-objdump --macho --bind --weak-bind %t/weak-autohide-foo-pe.dylib | \ 70# RUN: FileCheck --check-prefix=WEAKBIND %s 71# RUN: llvm-objdump --macho --private-header %t/weak-autohide-foo-pe.dylib | \ 72# RUN: FileCheck --check-prefix=HEADERS %s 73 74## In fact, a regular weak symbol that's .private_extern behaves the same 75## as well. 76# RUN: %lld -dylib -o %t/weak-foo-pe.dylib %t/weak-foo-pe.o %t/ref-foo.o 77# RUN: llvm-objdump --syms --exports-trie %t/weak-foo-pe.dylib | \ 78# RUN: FileCheck --check-prefix=EXPORTS %s 79# RUN: llvm-nm -m %t/weak-foo-pe.dylib | \ 80# RUN: FileCheck --check-prefix=EXPORTS-NM %s 81# RUN: llvm-objdump --macho --bind --weak-bind %t/weak-foo-pe.dylib | \ 82# RUN: FileCheck --check-prefix=WEAKBIND %s 83# RUN: llvm-objdump --macho --private-header %t/weak-foo-pe.dylib | \ 84# RUN: FileCheck --check-prefix=HEADERS %s 85 86## Combining a regular weak_definition with a weak_def_can_be_hidden produces 87## a regular weak external. 88# RUN: %lld -dylib -o %t/weak-foo.dylib -lSystem \ 89# RUN: %t/weak-autohide-foo.o %t/weak-foo.o %t/ref-foo.o 90# RUN: llvm-objdump --syms --exports-trie %t/weak-foo.dylib | \ 91# RUN: FileCheck --check-prefix=WEAK %s 92# RUN: llvm-nm -m %t/weak-foo.dylib | \ 93# RUN: FileCheck --check-prefix=WEAK-NM %s 94# RUN: llvm-objdump --macho --bind --weak-bind %t/weak-foo.dylib | \ 95# RUN: FileCheck --check-prefix=WEAK-WEAKBIND %s 96# RUN: llvm-objdump --macho --private-header %t/weak-foo.dylib | \ 97# RUN: FileCheck --check-prefix=WEAK-HEADERS %s 98# WEAK-LABEL: SYMBOL TABLE: 99# WEAK-DAG: [[#%x, FOO_ADDR:]] w {{.*}} _foo 100# WEAK-LABEL: Exports trie: 101# WEAK-DAG: 0x{{0*}}[[#%X, FOO_ADDR]] _foo 102# WEAK-NM: (__TEXT,__text) weak external _foo 103# WEAK-WEAKBIND: __la_symbol_ptr 0x{{.*}} pointer 0 _foo 104# WEAK-HEADERS: WEAK_DEFINES 105# WEAK-HEADERS: BINDS_TO_WEAK 106 107#--- weak-foo.s 108.globl _foo 109.weak_definition _foo 110_foo: 111 retq 112 113#--- weak-autohide-foo.s 114.globl _foo 115.weak_def_can_be_hidden _foo 116_foo: 117 retq 118 119# An alias is the only way to set .weak_def_can_be_hidden on an already-hidden symbol. 120# Veryify that LLD can handle these double-hidden symbols gracefully. 121.set l_foo, _foo 122 123#--- weak-foo-pe.s 124.private_extern _foo 125.globl _foo 126.weak_definition _foo 127_foo: 128 retq 129 130#--- weak-autohide-foo-pe.s 131.private_extern _foo 132.globl _foo 133.weak_def_can_be_hidden _foo 134_foo: 135 retq 136 137#--- ref-foo.s 138.globl _bar 139_bar: 140 callq _foo 141 retq 142