| # REQUIRES: x86 |
| # RUN: rm -rf %t; split-file %s %t |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/test.s -o %t/test.o |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/libfoo.s -o %t/libfoo.o |
| # RUN: %lld -dylib %t/libfoo.o -o %t/libfoo.dylib |
| # RUN: %lld %t/test.o -L%t -lfoo -o %t/test -lSystem |
| # RUN: llvm-objdump -d --no-show-raw-insn --rebase --bind --lazy-bind \ |
| # RUN: --weak-bind --full-contents %t/test | FileCheck %s |
| |
| # CHECK: Contents of section __DATA_CONST,__got: |
| ## Check that this section contains a nonzero pointer. It should point to |
| ## _weak_external_for_gotpcrel. |
| # CHECK-NEXT: {{[0-9a-f]+}} {{[0-9a-f ]*[1-9a-f]+[0-9a-f ]*}} |
| |
| # CHECK: Contents of section __DATA,__la_symbol_ptr: |
| ## Check that this section contains a nonzero pointer. It should point to |
| ## _weak_external_fn, but we don't have a good way of testing the exact value as |
| ## the bytes here are in little-endian order. |
| # CHECK-NEXT: {{[0-9a-f]+}} {{[0-9a-f ]*[1-9a-f]+[0-9a-f ]*}} |
| |
| # CHECK: <_main>: |
| # CHECK-NEXT: movq [[#]](%rip), %rax ## 0x[[#%X,WEAK_DY_GOT_ADDR:]] |
| # CHECK-NEXT: movq [[#]](%rip), %rax ## 0x[[#%X,WEAK_EXT_GOT_ADDR:]] |
| # CHECK-NEXT: leaq [[#]](%rip), %rax ## 0x[[#%X,WEAK_INT_GOT_ADDR:]] |
| # CHECK-NEXT: movq [[#]](%rip), %rax ## 0x[[#%X,WEAK_TLV_ADDR:]] |
| # CHECK-NEXT: movq [[#]](%rip), %rax ## 0x[[#%X,WEAK_DY_TLV_ADDR:]] |
| # CHECK-NEXT: leaq [[#]](%rip), %rax ## 0x[[#%X,WEAK_INT_TLV_ADDR:]] |
| # CHECK-NEXT: callq 0x{{[0-9a-f]*}} |
| # CHECK-NEXT: callq 0x{{[0-9a-f]*}} |
| # CHECK-NEXT: callq 0x{{[0-9a-f]*}} |
| |
| # CHECK-LABEL: Rebase table: |
| # CHECK: __DATA __la_symbol_ptr 0x[[#%x,WEAK_EXT_FN:]] pointer |
| |
| # CHECK-LABEL: Bind table: |
| # CHECK-DAG: __DATA_CONST __got 0x[[#WEAK_DY_GOT_ADDR]] pointer 0 libfoo _weak_dysym_for_gotpcrel |
| # CHECK-DAG: __DATA __la_symbol_ptr 0x[[#%x,WEAK_DY_FN:]] pointer 0 libfoo _weak_dysym_fn |
| # CHECK-DAG: __DATA __data 0x[[#%x,WEAK_DY:]] pointer 0 libfoo _weak_dysym |
| # CHECK-DAG: __DATA __thread_vars 0x{{[0-9a-f]*}} pointer 0 libSystem __tlv_bootstrap |
| # CHECK-DAG: __DATA __thread_vars 0x{{[0-9a-f]*}} pointer 0 libSystem __tlv_bootstrap |
| # CHECK-DAG: __DATA __thread_ptrs 0x[[#WEAK_DY_TLV_ADDR]] pointer 0 libfoo _weak_dysym_tlv |
| ## Check that we don't have any other bindings |
| # CHECK-EMPTY: |
| |
| # CHECK-LABEL: Lazy bind table: |
| # CHECK-NEXT: segment section address dylib symbol |
| ## Verify that we have no lazy bindings |
| # CHECK-EMPTY: |
| |
| # CHECK-LABEL: Weak bind table: |
| # CHECK-DAG: __DATA_CONST __got 0x[[#WEAK_DY_GOT_ADDR]] pointer 0 _weak_dysym_for_gotpcrel |
| # CHECK-DAG: __DATA_CONST __got 0x[[#WEAK_EXT_GOT_ADDR]] pointer 0 _weak_external_for_gotpcrel |
| # CHECK-DAG: __DATA __data 0x[[#WEAK_DY]] pointer 0 _weak_dysym |
| # CHECK-DAG: __DATA __thread_ptrs 0x[[#WEAK_TLV_ADDR]] pointer 0 _weak_tlv |
| # CHECK-DAG: __DATA __thread_ptrs 0x[[#WEAK_DY_TLV_ADDR]] pointer 0 _weak_dysym_tlv |
| # CHECK-DAG: __DATA __data 0x{{[0-9a-f]*}} pointer 2 _weak_external |
| # CHECK-DAG: __DATA __la_symbol_ptr 0x[[#WEAK_DY_FN]] pointer 0 _weak_dysym_fn |
| # CHECK-DAG: __DATA __la_symbol_ptr 0x[[#WEAK_EXT_FN]] pointer 0 _weak_external_fn |
| ## Check that we don't have any other bindings |
| # CHECK-EMPTY: |
| |
| ## Weak internal symbols don't get bindings |
| # RUN: llvm-objdump --macho --bind --lazy-bind --weak-bind %t/test | FileCheck %s --check-prefix=WEAK-INTERNAL |
| # WEAK-INTERNAL-NOT: _weak_internal |
| # WEAK-INTERNAL-NOT: _weak_internal_fn |
| # WEAK-INTERNAL-NOT: _weak_internal_tlv |
| |
| #--- libfoo.s |
| |
| .globl _weak_dysym |
| .weak_definition _weak_dysym |
| _weak_dysym: |
| .quad 0x1234 |
| |
| .globl _weak_dysym_for_gotpcrel |
| .weak_definition _weak_dysym_for_gotpcrel |
| _weak_dysym_for_gotpcrel: |
| .quad 0x1234 |
| |
| .globl _weak_dysym_fn |
| .weak_definition _weak_dysym_fn |
| _weak_dysym_fn: |
| ret |
| |
| .section __DATA,__thread_vars,thread_local_variables |
| |
| .globl _weak_dysym_tlv |
| .weak_definition _weak_dysym_tlv |
| _weak_dysym_tlv: |
| .quad 0x1234 |
| |
| #--- test.s |
| |
| .globl _main, _weak_external, _weak_external_for_gotpcrel, _weak_external_fn |
| .weak_definition _weak_external, _weak_external_for_gotpcrel, _weak_external_fn, _weak_internal, _weak_internal_for_gotpcrel, _weak_internal_fn |
| |
| _main: |
| mov _weak_dysym_for_gotpcrel@GOTPCREL(%rip), %rax |
| mov _weak_external_for_gotpcrel@GOTPCREL(%rip), %rax |
| mov _weak_internal_for_gotpcrel@GOTPCREL(%rip), %rax |
| mov _weak_tlv@TLVP(%rip), %rax |
| mov _weak_dysym_tlv@TLVP(%rip), %rax |
| mov _weak_internal_tlv@TLVP(%rip), %rax |
| callq _weak_dysym_fn |
| callq _weak_external_fn |
| callq _weak_internal_fn |
| mov $0, %rax |
| ret |
| |
| _weak_external: |
| .quad 0x1234 |
| |
| _weak_external_for_gotpcrel: |
| .quad 0x1234 |
| |
| _weak_external_fn: |
| ret |
| |
| _weak_internal: |
| .quad 0x1234 |
| |
| _weak_internal_for_gotpcrel: |
| .quad 0x1234 |
| |
| _weak_internal_fn: |
| ret |
| |
| .data |
| .quad _weak_dysym |
| .quad _weak_external + 2 |
| .quad _weak_internal |
| |
| .tbss _weak_tlv$tlv$init, 4, 2 |
| .tbss _weak_internal_tlv$tlv$init, 4, 2 |
| |
| .section __DATA,__thread_vars,thread_local_variables |
| .globl _weak_tlv |
| .weak_definition _weak_tlv, _weak_internal_tlv |
| |
| _weak_tlv: |
| .quad __tlv_bootstrap |
| .quad 0 |
| .quad _weak_tlv$tlv$init |
| |
| _weak_internal_tlv: |
| .quad __tlv_bootstrap |
| .quad 0 |
| .quad _weak_internal_tlv$tlv$init |