| # REQUIRES: x86 |
| # RUN: rm -rf %t; split-file %s %t |
| |
| ## This tests that if two input files define the same weak symbol, we only |
| ## write it to the output once (...assuming both input files use |
| ## .subsections_via_symbols). |
| |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/weak-sub.s -o %t/weak-sub.o |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %t/weak-nosub.s -o %t/weak-nosub.o |
| |
| ## Test that weak symbols are emitted just once with .subsections_via_symbols |
| # RUN: %lld -dylib -o %t/out.dylib %t/weak-sub.o %t/weak-sub.o |
| # RUN: llvm-otool -jtV %t/out.dylib | FileCheck --check-prefix=SUB %s |
| # RUN: %lld -dylib -o %t/out.dylib %t/weak-nosub.o %t/weak-sub.o |
| # RUN: llvm-otool -jtV %t/out.dylib | FileCheck --check-prefix=SUB %s |
| # RUN: %lld -dylib -o %t/out.dylib %t/weak-sub.o %t/weak-nosub.o |
| # RUN: llvm-otool -jtV %t/out.dylib | FileCheck --check-prefix=SUB %s |
| # SUB: _foo |
| # SUB-NEXT: retq |
| # SUB-NOT: retq |
| # SUB: _bar |
| # SUB-NEXT: retq |
| # SUB-NOT: retq |
| |
| ## We can even strip weak symbols without subsections_via_symbols as long |
| ## as none of the weak symbols in a section are needed. |
| # RUN: %lld -dylib -o %t/out.dylib %t/weak-nosub.o %t/weak-nosub.o |
| # RUN: llvm-otool -jtV %t/out.dylib | FileCheck --check-prefix=SUB %s |
| |
| ## Test that omitted weak symbols don't add entries to the compact unwind table. |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/weak-sub-lsda.s -o %t/weak-sub-lsda.o |
| # RUN: %lld -dylib -lc++ -o %t/out.dylib %t/weak-sub-lsda.o %t/weak-sub-lsda.o |
| # RUN: llvm-objdump --macho --unwind-info --syms %t/out.dylib | FileCheck %s --check-prefix=ONE-UNWIND |
| # RUN: %lld -dylib -lc++ -o %t/out.dylib %t/weak-sub.o %t/weak-sub-lsda.o |
| # RUN: llvm-objdump --macho --unwind-info --syms %t/out.dylib | FileCheck %s --check-prefix=NO-UNWIND |
| # RUN: yaml2obj %t/weak-sub-lsda-r.yaml -o %t/weak-sub-lsda-r.o |
| # RUN: %lld -dylib -lc++ -o %t/out.dylib %t/weak-sub.o %t/weak-sub-lsda-r.o |
| # RUN: llvm-objdump --macho --unwind-info --syms %t/out.dylib | FileCheck %s --check-prefix=NO-UNWIND |
| |
| # ONE-UNWIND: SYMBOL TABLE: |
| # ONE-UNWIND-DAG: [[#%x,FOO:]] w F __TEXT,__text _foo |
| # ONE-UNWIND-NOT: __TEXT,__text _foo |
| |
| # ONE-UNWIND: Contents of __unwind_info section: |
| # ONE-UNWIND: LSDA descriptors: |
| # ONE-UNWIND: [0]: function offset=0x[[#%.8x,FOO]] |
| # ONE-UNWIND-NOT: [1]: |
| # ONE-UNWIND: Second level indices: |
| # ONE-UNWIND-DAG: [0]: function offset=0x[[#%.8x,FOO]] |
| # ONE-UNWIND-NOT: [1]: |
| |
| # NO-UNWIND: SYMBOL TABLE: |
| # NO-UNWIND-DAG: [[#%x,FOO:]] w F __TEXT,__text _foo |
| # NO-UNWIND-NOT: __TEXT,__text _foo |
| # NO-UNWIND-NOT: Contents of __unwind_info section: |
| |
| ## Test interaction with .alt_entry |
| ## FIXME: ld64 manages to strip both one copy of _foo and _bar each. |
| ## We only manage this if we're lucky and the object files are in |
| ## the right order. We're happy to not crash at link time for now. |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/weak-sub-alt.s -o %t/weak-sub-alt.o |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/weak-sub-alt2.s -o %t/weak-sub-alt2.o |
| # RUN: %lld -dylib -o %t/out.dylib %t/weak-sub-alt.o %t/weak-sub-alt2.o |
| # RUN: %lld -dylib -o %t/out.dylib %t/weak-sub-alt2.o %t/weak-sub-alt.o |
| |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/weak-aligned-1.s -o %t/weak-aligned-1.o |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/weak-aligned-2.s -o %t/weak-aligned-2.o |
| # RUN: %lld -o %t/out -lSystem %t/weak-aligned-1.o %t/weak-aligned-2.o |
| # RUN: llvm-objdump --syms --section=__const --full-contents %t/out | FileCheck --check-prefix=ALIGN %s |
| # ALIGN: SYMBOL TABLE: |
| # ALIGN-DAG: [[#%x, ADDR:]] l O __DATA_CONST,__const _weak1 |
| # ALIGN-DAG: {{0*}}[[#ADDR+ 0x4]] l O __DATA_CONST,__const _weak3 |
| # ALIGN-DAG: {{0*}}[[#ADDR+ 0x8]] l O __DATA_CONST,__const _weak2 |
| # ALIGN-DAG: {{0*}}[[#ADDR+0x10]] g O __DATA_CONST,__const _aligned |
| # ALIGN: Contents of section __DATA_CONST,__const: |
| # ALIGN-NEXT: {{0*}}[[#ADDR]] 11111111 33333333 22222222 00000000 |
| # ALIGN-NEXT: {{0*}}[[#ADDR+0x10]] 81818181 81818181 82828282 82828282 |
| |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/weak-def.s -o %t/weak-def.o |
| # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin19.0.0 %t/strong-def.s -o %t/strong-def.o |
| # RUN: %lld -dylib -lc++ -o %t/weak-strong-mixed.dylib %t/weak-def.o %t/strong-def.o |
| # RUN: %lld -dylib -lc++ -o %t/strong-weak-mixed.dylib %t/strong-def.o %t/weak-def.o |
| ## Check that omitted weak symbols are not adding their section and unwind stuff. |
| |
| # RUN: llvm-otool -jtV %t/weak-strong-mixed.dylib | FileCheck --check-prefix=MIXED %s |
| # RUN: llvm-otool -jtV %t/strong-weak-mixed.dylib | FileCheck --check-prefix=MIXED %s |
| # MIXED: (__TEXT,__text) section |
| # MIXED-NEXT: _foo: |
| # MIXED-NEXT: {{.+}} 33 33 xorl (%rbx), %esi |
| # MIXED-NEXT: {{.+}} 33 33 xorl (%rbx), %esi |
| # MIXED-NEXT: {{.+}} c3 retq |
| |
| # RUN: llvm-objdump --macho --syms --unwind-info %t/weak-strong-mixed.dylib | FileCheck --check-prefix=MIXED-UNWIND %s |
| # RUN: llvm-objdump --macho --syms --unwind-info %t/strong-weak-mixed.dylib | FileCheck --check-prefix=MIXED-UNWIND %s |
| # MIXED-UNWIND: g F __TEXT,__text _foo |
| # MIXED-UNWIND-NOT: Contents of __unwind_info section: |
| |
| #--- weak-sub.s |
| .globl _foo, _bar |
| .weak_definition _foo, _bar |
| _foo: |
| retq |
| _bar: |
| retq |
| .subsections_via_symbols |
| |
| #--- weak-nosub.s |
| .globl _foo, _bar |
| .weak_definition _foo, _bar |
| _foo: |
| retq |
| _bar: |
| retq |
| |
| #--- weak-sub-lsda.s |
| .section __TEXT,__text,regular,pure_instructions |
| |
| .globl _foo |
| .weak_definition _foo |
| _foo: |
| .cfi_startproc |
| .cfi_personality 155, ___gxx_personality_v0 |
| .cfi_lsda 16, Lexception |
| pushq %rbp |
| .cfi_def_cfa_offset 128 |
| .cfi_offset %rbp, 48 |
| movq %rsp, %rbp |
| .cfi_def_cfa_register %rbp |
| popq %rbp |
| retq |
| .cfi_endproc |
| |
| .section __TEXT,__gcc_except_tab |
| Lexception: |
| .space 0x10 |
| |
| .subsections_via_symbols |
| |
| #--- weak-sub-alt.s |
| .globl _foo, _bar |
| .weak_definition _foo |
| _foo: |
| retq |
| |
| # Alternative entry point to _foo (strong) |
| .alt_entry _bar |
| _bar: |
| retq |
| |
| .globl _main, _ref |
| _main: |
| callq _ref |
| callq _bar |
| |
| .subsections_via_symbols |
| |
| #--- weak-sub-alt2.s |
| .globl _foo, _bar |
| .weak_definition _foo |
| _foo: |
| retq |
| |
| # Alternative entry point to _foo (weak) |
| .weak_definition _bar |
| .alt_entry _bar |
| _bar: |
| retq |
| |
| .globl _ref |
| _ref: |
| callq _bar |
| |
| .subsections_via_symbols |
| |
| #--- weak-aligned-1.s |
| .section __DATA,__const |
| .p2align 3 |
| .globl _weak1 |
| .weak_def_can_be_hidden _weak1 |
| _weak1: |
| .4byte 0x11111111 |
| |
| .globl _weak3 |
| .weak_def_can_be_hidden _weak3 |
| _weak3: |
| .4byte 0x33333333 |
| |
| .subsections_via_symbols |
| |
| #--- weak-aligned-2.s |
| # _weak1 and _weak3 are already in weak-aligned-1, |
| # so from _weak1-3 in this file only _weak2 is used. |
| # However, _aligned still has to stay aligned to a 16-byte boundary. |
| .section __DATA,__const |
| .p2align 3 |
| .globl _weak1 |
| .weak_def_can_be_hidden _weak1 |
| _weak1: |
| .4byte 0x11111111 |
| |
| .globl _weak2 |
| .weak_def_can_be_hidden _weak2 |
| _weak2: |
| .4byte 0x22222222 |
| |
| .globl _weak3 |
| .weak_def_can_be_hidden _weak3 |
| _weak3: |
| .4byte 0x33333333 |
| |
| .section __DATA,__const |
| .p2align 4 |
| .globl _aligned |
| _aligned: |
| .8byte 0x8181818181818181 |
| .8byte 0x8282828282828282 |
| |
| .section __TEXT,__text |
| .globl _main |
| _main: |
| movl _weak1(%rip), %eax |
| movl _weak2(%rip), %ebx |
| movaps _aligned(%rip), %xmm0 |
| retq |
| |
| .subsections_via_symbols |
| |
| #--- weak-def.s |
| .section __TEXT,__text,regular,pure_instructions |
| |
| .globl _foo |
| .weak_definition _foo |
| _foo: |
| .cfi_startproc |
| .cfi_personality 155, ___gxx_personality_v0 |
| .cfi_lsda 16, Lexception |
| pushq %rbp |
| .cfi_def_cfa_offset 128 |
| .cfi_offset %rbp, 48 |
| movq %rsp, %rbp |
| .cfi_def_cfa_register %rbp |
| popq %rbp |
| retq |
| .cfi_endproc |
| |
| .section __TEXT,__gcc_except_tab |
| Lexception: |
| .space 0x10 |
| |
| .subsections_via_symbols |
| #--- strong-def.s |
| .globl _foo, _bar |
| |
| _foo: |
| .4byte 0x33333333 |
| retq |
| |
| .subsections_via_symbols |
| |
| #--- weak-sub-lsda-r.yaml |
| ## This was generated from compiling weak-sub-lsda.s above at rev a2404f11c77e |
| ## and then running it through `ld -r`. This converts a number of unwind-related |
| ## relocations from section- to symbol-based ones. |
| --- !mach-o |
| FileHeader: |
| magic: 0xFEEDFACF |
| cputype: 0x1000007 |
| cpusubtype: 0x3 |
| filetype: 0x1 |
| ncmds: 2 |
| sizeofcmds: 464 |
| flags: 0x2000 |
| reserved: 0x0 |
| LoadCommands: |
| - cmd: LC_SEGMENT_64 |
| cmdsize: 392 |
| segname: '' |
| vmaddr: 0 |
| vmsize: 152 |
| fileoff: 528 |
| filesize: 152 |
| maxprot: 7 |
| initprot: 7 |
| nsects: 3 |
| flags: 0 |
| Sections: |
| - sectname: __text |
| segname: __TEXT |
| addr: 0x0 |
| size: 6 |
| offset: 0x210 |
| align: 0 |
| reloff: 0x0 |
| nreloc: 0 |
| flags: 0x80000400 |
| reserved1: 0x0 |
| reserved2: 0x0 |
| reserved3: 0x0 |
| content: 554889E55DC3 |
| - sectname: __gcc_except_tab |
| segname: __TEXT |
| addr: 0x6 |
| size: 32 |
| offset: 0x216 |
| align: 0 |
| reloff: 0x0 |
| nreloc: 0 |
| flags: 0x0 |
| reserved1: 0x0 |
| reserved2: 0x0 |
| reserved3: 0x0 |
| content: '0000000000000000000000000000000000000000000000000000000000000000' |
| - sectname: __eh_frame |
| segname: __TEXT |
| addr: 0x28 |
| size: 80 |
| offset: 0x238 |
| align: 3 |
| reloff: 0x2A8 |
| nreloc: 7 |
| flags: 0x0 |
| reserved1: 0x0 |
| reserved2: 0x0 |
| reserved3: 0x0 |
| content: 1C00000000000000017A504C5200017810079B0400000010100C0708900100002C00000004000000F8FFFFFFFFFFFFFF060000000000000008E7FFFFFFFFFFFFFF410E800111067A430D060000000000 |
| relocations: |
| - address: 0x13 |
| symbolnum: 5 |
| pcrel: true |
| length: 2 |
| extern: true |
| type: 4 |
| scattered: false |
| value: 0 |
| - address: 0x24 |
| symbolnum: 2 |
| pcrel: false |
| length: 2 |
| extern: true |
| type: 5 |
| scattered: false |
| value: 0 |
| - address: 0x24 |
| symbolnum: 3 |
| pcrel: false |
| length: 2 |
| extern: true |
| type: 0 |
| scattered: false |
| value: 0 |
| - address: 0x28 |
| symbolnum: 3 |
| pcrel: false |
| length: 3 |
| extern: true |
| type: 5 |
| scattered: false |
| value: 0 |
| - address: 0x28 |
| symbolnum: 4 |
| pcrel: false |
| length: 3 |
| extern: true |
| type: 0 |
| scattered: false |
| value: 0 |
| - address: 0x39 |
| symbolnum: 3 |
| pcrel: false |
| length: 3 |
| extern: true |
| type: 5 |
| scattered: false |
| value: 0 |
| - address: 0x39 |
| symbolnum: 1 |
| pcrel: false |
| length: 3 |
| extern: true |
| type: 0 |
| scattered: false |
| value: 0 |
| - sectname: __compact_unwind |
| segname: __LD |
| addr: 0x78 |
| size: 32 |
| offset: 0x288 |
| align: 3 |
| reloff: 0x2E0 |
| nreloc: 4 |
| flags: 0x2000000 |
| reserved1: 0x0 |
| reserved2: 0x0 |
| reserved3: 0x0 |
| content: '0000000000000000060000000000004100000000000000000000000000000000' |
| relocations: |
| - address: 0x0 |
| symbolnum: 4 |
| pcrel: false |
| length: 3 |
| extern: true |
| type: 0 |
| scattered: false |
| value: 0 |
| - address: 0x18 |
| symbolnum: 1 |
| pcrel: false |
| length: 3 |
| extern: true |
| type: 0 |
| scattered: false |
| value: 0 |
| - address: 0x10 |
| symbolnum: 5 |
| pcrel: false |
| length: 3 |
| extern: true |
| type: 0 |
| scattered: false |
| value: 0 |
| - address: 0x18 |
| symbolnum: 1 |
| pcrel: false |
| length: 3 |
| extern: true |
| type: 0 |
| scattered: false |
| value: 0 |
| - cmd: LC_SYMTAB |
| cmdsize: 24 |
| symoff: 768 |
| nsyms: 6 |
| stroff: 864 |
| strsize: 57 |
| LinkEditData: |
| NameList: |
| - n_strx: 29 |
| n_type: 0xE |
| n_sect: 2 |
| n_desc: 0 |
| n_value: 6 |
| - n_strx: 34 |
| n_type: 0xE |
| n_sect: 2 |
| n_desc: 0 |
| n_value: 22 |
| - n_strx: 39 |
| n_type: 0xE |
| n_sect: 3 |
| n_desc: 0 |
| n_value: 40 |
| - n_strx: 49 |
| n_type: 0xE |
| n_sect: 3 |
| n_desc: 0 |
| n_value: 72 |
| - n_strx: 2 |
| n_type: 0xF |
| n_sect: 1 |
| n_desc: 128 |
| n_value: 0 |
| - n_strx: 7 |
| n_type: 0x1 |
| n_sect: 0 |
| n_desc: 0 |
| n_value: 0 |
| StringTable: |
| - ' ' |
| - _foo |
| - ___gxx_personality_v0 |
| - l001 |
| - l002 |
| - EH_Frame1 |
| - func.eh |
| ... |