diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:48:50 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:48:50 +0000 |
commit | 1c98619801a5705c688e683be3ef9d70169a0686 (patch) | |
tree | 8422105cd1a94c368315f2db16b9ac746cf7c000 /test/ELF | |
parent | f4f3ce4613680903220815690ad79fc7ba0a2e26 (diff) | |
download | src-test2-1c98619801a5705c688e683be3ef9d70169a0686.tar.gz src-test2-1c98619801a5705c688e683be3ef9d70169a0686.zip |
Notes
Diffstat (limited to 'test/ELF')
508 files changed, 13685 insertions, 674 deletions
diff --git a/test/ELF/Inputs/aarch64-copy2.s b/test/ELF/Inputs/aarch64-copy2.s new file mode 100644 index 000000000000..8f3f748366be --- /dev/null +++ b/test/ELF/Inputs/aarch64-copy2.s @@ -0,0 +1,5 @@ + .global foo + .type foo, @function +foo: + .global bar +bar: diff --git a/test/ELF/Inputs/aarch64-tls-gdie.s b/test/ELF/Inputs/aarch64-tls-gdie.s new file mode 100644 index 000000000000..289cae523fe8 --- /dev/null +++ b/test/ELF/Inputs/aarch64-tls-gdie.s @@ -0,0 +1,4 @@ + .section .tdata,"awT",@progbits + .globl a +a: + .word 42 diff --git a/test/ELF/Inputs/abs-hidden.s b/test/ELF/Inputs/abs-hidden.s new file mode 100644 index 000000000000..44bff383a8e0 --- /dev/null +++ b/test/ELF/Inputs/abs-hidden.s @@ -0,0 +1,3 @@ +.global foo +.hidden foo +foo = 0x42 diff --git a/test/ELF/Inputs/allow-shlib-undefined.s b/test/ELF/Inputs/allow-shlib-undefined.s index e2fb7de2301a..5e3a46179027 100644 --- a/test/ELF/Inputs/allow-shlib-undefined.s +++ b/test/ELF/Inputs/allow-shlib-undefined.s @@ -1,3 +1,3 @@ .globl _shared _shared: - call _unresolved + callq _unresolved@PLT diff --git a/test/ELF/Inputs/archive.s b/test/ELF/Inputs/archive.s index 42ccfd47b48b..568bc1fc0a49 100644 --- a/test/ELF/Inputs/archive.s +++ b/test/ELF/Inputs/archive.s @@ -1,5 +1,5 @@ -.globl _start; +.globl _start _start: -.globl end; +.globl end end: diff --git a/test/ELF/Inputs/arm-plt-reloc.s b/test/ELF/Inputs/arm-plt-reloc.s new file mode 100644 index 000000000000..29f133e6eb8f --- /dev/null +++ b/test/ELF/Inputs/arm-plt-reloc.s @@ -0,0 +1,14 @@ +.text + .align 2 + .globl func1 + .type func1,%function +func1: + bx lr + .globl func2 + .type func2,%function +func2: + bx lr + .globl func3 + .type func3,%function +func3: + bx lr diff --git a/test/ELF/Inputs/arm-thumb-blx-targets.s b/test/ELF/Inputs/arm-thumb-blx-targets.s new file mode 100644 index 000000000000..4585ac4399cb --- /dev/null +++ b/test/ELF/Inputs/arm-thumb-blx-targets.s @@ -0,0 +1,36 @@ + .syntax unified + .arm + .section .R_ARM_CALL24_callee_low, "ax",%progbits + .align 2 + .globl callee_low + .type callee_low,%function +callee_low: + bx lr + + .section .R_ARM_CALL24_callee_thumb_low, "ax",%progbits + .balign 0x100 + .thumb + .type callee_thumb_low,%function + .globl callee_thumb_low +callee_thumb_low: + bx lr + + .section .R_ARM_CALL24_callee_high, "ax",%progbits + .balign 0x100 + .arm + .globl callee_high + .type callee_high,%function +callee_high: + bx lr + + .section .R_ARM_CALL24_callee_thumb_high, "ax",%progbits + .balign 0x100 + .thumb + .type callee_thumb_high,%function + .globl callee_thumb_high +callee_thumb_high: + bx lr + + .globl blx_far + .type blx_far, %function +blx_far = 0x1010018 diff --git a/test/ELF/Inputs/arm-thumb-narrow-branch.s b/test/ELF/Inputs/arm-thumb-narrow-branch.s new file mode 100644 index 000000000000..473a8e64ef74 --- /dev/null +++ b/test/ELF/Inputs/arm-thumb-narrow-branch.s @@ -0,0 +1,18 @@ +// This input must be assembled by the GNU assembler, as llvm-mc does not emit +// the R_ARM_JUMP11 relocation for a Thumb narrow branch. This is permissible +// by the ABI for the ARM architecture as the range of the Thumb narrow branch +// is short enough (+- 2048 bytes) that widespread use would be impractical. +// +// The test case will use a pre compiled object arm-thumb-narrow-branch.o + .syntax unified + .section .caller, "ax",%progbits + .thumb + .align 2 + .type callers,%function + .globl callers +callers: + b.n callee_low_far + b.n callee_low + b.n callee_high + b.n callee_high_far + bx lr diff --git a/test/ELF/Inputs/conflict.s b/test/ELF/Inputs/conflict.s new file mode 100644 index 000000000000..545ae99c845a --- /dev/null +++ b/test/ELF/Inputs/conflict.s @@ -0,0 +1,7 @@ +.globl _Z3muldd, foo, baz +_Z3muldd: +foo: +baz: + mov $60, %rax + mov $42, %rdi + syscall diff --git a/test/ELF/Inputs/copy-in-shared.s b/test/ELF/Inputs/copy-in-shared.s new file mode 100644 index 000000000000..52e99c6707a7 --- /dev/null +++ b/test/ELF/Inputs/copy-in-shared.s @@ -0,0 +1,4 @@ +.type foo, @object +.global foo +foo: +.size foo, 4 diff --git a/test/ELF/Inputs/copy-rel-corrupted.s b/test/ELF/Inputs/copy-rel-corrupted.s new file mode 100644 index 000000000000..b8d1b1aa04c4 --- /dev/null +++ b/test/ELF/Inputs/copy-rel-corrupted.s @@ -0,0 +1,4 @@ +.type x,@object +.globl x +x: +.size x, 0 diff --git a/test/ELF/Inputs/copy-rel-pie.s b/test/ELF/Inputs/copy-rel-pie.s new file mode 100644 index 000000000000..6cd681fcecb4 --- /dev/null +++ b/test/ELF/Inputs/copy-rel-pie.s @@ -0,0 +1,9 @@ +.global foo +.type foo, @object +.size foo, 4 +foo: +.long 0 + +.global bar +.type bar, @function +bar: diff --git a/test/ELF/Inputs/ctors_dtors_priority1.s b/test/ELF/Inputs/ctors_dtors_priority1.s new file mode 100644 index 000000000000..2eb19d7edad9 --- /dev/null +++ b/test/ELF/Inputs/ctors_dtors_priority1.s @@ -0,0 +1,5 @@ +.section .ctors, "aw", @progbits + .byte 0xA1 + +.section .dtors, "aw", @progbits + .byte 0xA2 diff --git a/test/ELF/Inputs/ctors_dtors_priority2.s b/test/ELF/Inputs/ctors_dtors_priority2.s new file mode 100644 index 000000000000..fb85ce87c5c5 --- /dev/null +++ b/test/ELF/Inputs/ctors_dtors_priority2.s @@ -0,0 +1,5 @@ +.section .ctors, "aw", @progbits + .byte 0xB1 + +.section .dtors, "aw", @progbits + .byte 0xB2 diff --git a/test/ELF/Inputs/ctors_dtors_priority3.s b/test/ELF/Inputs/ctors_dtors_priority3.s new file mode 100644 index 000000000000..96418d351a85 --- /dev/null +++ b/test/ELF/Inputs/ctors_dtors_priority3.s @@ -0,0 +1,5 @@ +.section .ctors, "aw", @progbits + .byte 0xC1 + +.section .dtors, "aw", @progbits + .byte 0xC2 diff --git a/test/ELF/Inputs/duplicated-plt-entry.s b/test/ELF/Inputs/duplicated-plt-entry.s new file mode 100644 index 000000000000..689f3af0ef4a --- /dev/null +++ b/test/ELF/Inputs/duplicated-plt-entry.s @@ -0,0 +1,3 @@ +.global bar +.type bar, @gnu_indirect_function +bar: diff --git a/test/ELF/Inputs/dynamic-reloc-weak.s b/test/ELF/Inputs/dynamic-reloc-weak.s new file mode 100644 index 000000000000..2310749d9f85 --- /dev/null +++ b/test/ELF/Inputs/dynamic-reloc-weak.s @@ -0,0 +1,11 @@ + .type sym1,@function + .global sym1 +sym1: + + .type sym2,@function + .global sym2 +sym2: + + .type sym3,@function + .global sym3 +sym3: diff --git a/test/ELF/Inputs/ehframe-relocation.s b/test/ELF/Inputs/ehframe-relocation.s new file mode 100644 index 000000000000..7ba6c0510cc8 --- /dev/null +++ b/test/ELF/Inputs/ehframe-relocation.s @@ -0,0 +1,2 @@ + .cfi_startproc + .cfi_endproc diff --git a/test/ELF/Inputs/empty-ver.ver b/test/ELF/Inputs/empty-ver.ver new file mode 100644 index 000000000000..7d4b4ede7675 --- /dev/null +++ b/test/ELF/Inputs/empty-ver.ver @@ -0,0 +1,2 @@ +ver { +}; diff --git a/test/ELF/Inputs/far-arm-abs.s b/test/ELF/Inputs/far-arm-abs.s new file mode 100644 index 000000000000..68d6aabe00b8 --- /dev/null +++ b/test/ELF/Inputs/far-arm-abs.s @@ -0,0 +1,13 @@ +.global far +.type far,%function +far = 0x201001c + +.global too_far1 +.type too_far1,%function +too_far1 = 0x2020008 +.global too_far2 +.type too_far2,%function +too_far2 = 0x202000c +.global too_far3 +.type too_far3,%function +too_far3 = 0x2020010 diff --git a/test/ELF/Inputs/far-arm-thumb-abs.s b/test/ELF/Inputs/far-arm-thumb-abs.s new file mode 100644 index 000000000000..0eb99b8e6ee9 --- /dev/null +++ b/test/ELF/Inputs/far-arm-thumb-abs.s @@ -0,0 +1,24 @@ +.global far_cond +.type far_cond,%function +far_cond = 0x110023 +.global far_uncond +.type far_uncond,%function +far_uncond = 0x101001b + +.global too_far1 +.type too_far1,%function +too_far1 = 0x1020005 +.global too_far2 +.type too_far1,%function +too_far2 = 0x1020009 +.global too_far3 +.type too_far3,%function +too_far3 = 0x12000d + +.global blx_far +.type blx_far, %function +blx_far = 0x2010025 + +.global blx_far2 +.type blx_far2, %function +blx_far2 = 0x2010029 diff --git a/test/ELF/Inputs/gc-sections-weak.s b/test/ELF/Inputs/gc-sections-weak.s new file mode 100644 index 000000000000..27baa6694e3d --- /dev/null +++ b/test/ELF/Inputs/gc-sections-weak.s @@ -0,0 +1,8 @@ +.weak foo +foo: + nop + +.data +.global bar2 +bar2: +.quad foo diff --git a/test/ELF/Inputs/gnu-ifunc-gotpcrel.s b/test/ELF/Inputs/gnu-ifunc-gotpcrel.s new file mode 100644 index 000000000000..83b06e05d461 --- /dev/null +++ b/test/ELF/Inputs/gnu-ifunc-gotpcrel.s @@ -0,0 +1,4 @@ +.type foo STT_GNU_IFUNC +.globl foo +foo: +ret diff --git a/test/ELF/Inputs/gotpc-relax-und-dso.s b/test/ELF/Inputs/gotpc-relax-und-dso.s new file mode 100644 index 000000000000..cbe39f38ef0b --- /dev/null +++ b/test/ELF/Inputs/gotpc-relax-und-dso.s @@ -0,0 +1,4 @@ +.globl dsofoo +.type dsofoo, @function +dsofoo: + nop diff --git a/test/ELF/Inputs/icf2.s b/test/ELF/Inputs/icf2.s new file mode 100644 index 000000000000..d332130bc935 --- /dev/null +++ b/test/ELF/Inputs/icf2.s @@ -0,0 +1,5 @@ +.globl f1, f2 +.section .text.f2, "ax" +f2: + mov $60, %rdi + call f1 diff --git a/test/ELF/Inputs/invalid-cie-version2.elf b/test/ELF/Inputs/invalid-cie-version2.elf Binary files differnew file mode 100644 index 000000000000..87f8a5be76f4 --- /dev/null +++ b/test/ELF/Inputs/invalid-cie-version2.elf diff --git a/test/ELF/Inputs/libsearch-dyn.s b/test/ELF/Inputs/libsearch-dyn.s index c0c33f92944d..091b3b9b6ece 100644 --- a/test/ELF/Inputs/libsearch-dyn.s +++ b/test/ELF/Inputs/libsearch-dyn.s @@ -1,3 +1,3 @@ -.globl _bar,_dynamic; +.globl _bar,_dynamic _bar: _dynamic: diff --git a/test/ELF/Inputs/libsearch-st.s b/test/ELF/Inputs/libsearch-st.s index c02ee741c803..6da62f79d52f 100644 --- a/test/ELF/Inputs/libsearch-st.s +++ b/test/ELF/Inputs/libsearch-st.s @@ -1,3 +1,3 @@ -.globl _bar,_static; +.globl _bar,_static _bar: _static: diff --git a/test/ELF/Inputs/mips-align-err.s b/test/ELF/Inputs/mips-align-err.s new file mode 100644 index 000000000000..2d813b754a45 --- /dev/null +++ b/test/ELF/Inputs/mips-align-err.s @@ -0,0 +1,2 @@ + .global _foo +_foo: diff --git a/test/ELF/Inputs/mips-dynamic.s b/test/ELF/Inputs/mips-dynamic.s index eba5b7f327b4..6f15cf334d9d 100644 --- a/test/ELF/Inputs/mips-dynamic.s +++ b/test/ELF/Inputs/mips-dynamic.s @@ -1,4 +1,28 @@ + .option pic2 .text .globl _foo _foo: nop + + .globl foo0 + .type foo0, @function +foo0: + nop + + .globl foo1 + .type foo1, @function +foo1: + nop + + .data + .globl data0 + .type data0, @object + .size data0, 4 +data0: + .word 0 + + .globl data1 + .type data1, @object + .size data1, 4 +data1: + .word 0 diff --git a/test/ELF/Inputs/mips-gp-disp.so b/test/ELF/Inputs/mips-gp-disp.so Binary files differindex 9cbb43720606..150de18fcca1 100644 --- a/test/ELF/Inputs/mips-gp-disp.so +++ b/test/ELF/Inputs/mips-gp-disp.so diff --git a/test/ELF/Inputs/mips-nonalloc.s b/test/ELF/Inputs/mips-nonalloc.s new file mode 100644 index 000000000000..72bfd274335c --- /dev/null +++ b/test/ELF/Inputs/mips-nonalloc.s @@ -0,0 +1,2 @@ + .section .debug_info + .word __start diff --git a/test/ELF/Inputs/mips-pic.s b/test/ELF/Inputs/mips-pic.s new file mode 100644 index 000000000000..880903241d3d --- /dev/null +++ b/test/ELF/Inputs/mips-pic.s @@ -0,0 +1,19 @@ + .option pic2 + + .section .text.1,"ax",@progbits + .align 4 + .globl foo1a + .type foo1a, @function +foo1a: + nop + .globl foo1b + .type foo1b, @function +foo1b: + nop + + .section .text.2,"ax",@progbits + .align 4 + .globl foo2 + .type foo2, @function +foo2: + nop diff --git a/test/ELF/Inputs/mips-tls.s b/test/ELF/Inputs/mips-tls.s new file mode 100644 index 000000000000..9e0a0983e1cd --- /dev/null +++ b/test/ELF/Inputs/mips-tls.s @@ -0,0 +1,5 @@ + .globl foo + .section .tdata,"awT",%progbits + .type foo, %object +foo: + .word 0 diff --git a/test/ELF/Inputs/plt-aarch64.s b/test/ELF/Inputs/plt-aarch64.s new file mode 100644 index 000000000000..0f7a4eda7be1 --- /dev/null +++ b/test/ELF/Inputs/plt-aarch64.s @@ -0,0 +1,5 @@ +.global bar +bar: + +.global weak +weak: diff --git a/test/ELF/Inputs/ppc64-addr16-error.s b/test/ELF/Inputs/ppc64-addr16-error.s new file mode 100644 index 000000000000..d83a9f929c6e --- /dev/null +++ b/test/ELF/Inputs/ppc64-addr16-error.s @@ -0,0 +1,3 @@ +.global sym +.hidden sym +sym = 0 diff --git a/test/ELF/Inputs/protected-shared.s b/test/ELF/Inputs/protected-shared.s new file mode 100644 index 000000000000..5f4b1daf63cc --- /dev/null +++ b/test/ELF/Inputs/protected-shared.s @@ -0,0 +1,10 @@ + .global foo + .protected foo +foo: + + .global bar + .protected bar +bar: + + .global zed +zed: diff --git a/test/ELF/Inputs/relocatable-ehframe.s b/test/ELF/Inputs/relocatable-ehframe.s new file mode 100644 index 000000000000..384aac6e7ced --- /dev/null +++ b/test/ELF/Inputs/relocatable-ehframe.s @@ -0,0 +1,14 @@ +.section foo1,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.section bar1,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.section dah1,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc diff --git a/test/ELF/Inputs/relocatable.s b/test/ELF/Inputs/relocatable.s new file mode 100644 index 000000000000..de34a6b3bf0e --- /dev/null +++ b/test/ELF/Inputs/relocatable.s @@ -0,0 +1,22 @@ +.text +.type xx,@object +.bss +.globl xx +.align 4 +xx: +.long 0 +.size xx, 4 +.type yy,@object +.globl yy +.align 4 +yy: +.long 0 +.size yy, 4 + +.text +.globl foo +.align 16, 0x90 +.type foo,@function +foo: +movl $1, xx +movl $2, yy diff --git a/test/ELF/Inputs/relocatable2.s b/test/ELF/Inputs/relocatable2.s new file mode 100644 index 000000000000..93e23bc7ae69 --- /dev/null +++ b/test/ELF/Inputs/relocatable2.s @@ -0,0 +1,22 @@ +.text +.type xxx,@object +.bss +.globl xxx +.align 4 +xxx: +.long 0 +.size xxx, 4 +.type yyy,@object +.globl yyy +.align 4 +yyy: +.long 0 +.size yyy, 4 + +.text +.globl bar +.align 16, 0x90 +.type bar,@function +bar: +movl $8, xxx +movl $9, yyy diff --git a/test/ELF/Inputs/relocation-copy-alias.s b/test/ELF/Inputs/relocation-copy-alias.s new file mode 100644 index 000000000000..a9bc3d76a12c --- /dev/null +++ b/test/ELF/Inputs/relocation-copy-alias.s @@ -0,0 +1,25 @@ +.data + +.globl a1 +.type a1, @object +.size a1, 1 +a1: +.weak a2 +.type a2, @object +.size a2, 1 +a2: +.byte 1 + +.weak b1 +.type b1, @object +.size b1, 1 +b1: +.weak b2 +.type b2, @object +.size b2, 1 +b2: +.globl b3 +.type b3, @object +.size b3, 1 +b3: +.byte 1 diff --git a/test/ELF/Inputs/relocation-copy-arm.s b/test/ELF/Inputs/relocation-copy-arm.s new file mode 100644 index 000000000000..ba5ab73043c9 --- /dev/null +++ b/test/ELF/Inputs/relocation-copy-arm.s @@ -0,0 +1,22 @@ +.bss + +.type x,%object +.globl x +.balign 16 +x: +.long 0 +.size x, 4 + +.type y,%object +.globl y +.balign 16 +y: +.long 0 +.size y, 4 + +.type z,%object +.globl z +.balign 4 +z: +.long 0 +.size z, 4 diff --git a/test/ELF/Inputs/resolution-shared.s b/test/ELF/Inputs/resolution-shared.s new file mode 100644 index 000000000000..2f0ccf81e395 --- /dev/null +++ b/test/ELF/Inputs/resolution-shared.s @@ -0,0 +1,2 @@ + .global foo +foo: diff --git a/test/ELF/Inputs/shared.s b/test/ELF/Inputs/shared.s index 1cfebbfaf373..c3c22fe4b4fb 100644 --- a/test/ELF/Inputs/shared.s +++ b/test/ELF/Inputs/shared.s @@ -2,5 +2,9 @@ .type bar, @function bar: +.global bar2 +.type bar2, @function +bar2: + .global zed zed: diff --git a/test/ELF/Inputs/start-lib-comdat.s b/test/ELF/Inputs/start-lib-comdat.s new file mode 100644 index 000000000000..dcbaaf443851 --- /dev/null +++ b/test/ELF/Inputs/start-lib-comdat.s @@ -0,0 +1,5 @@ + .global bar +bar: + .section .sec,"aG",@progbits,zed,comdat + .global zed +zed: diff --git a/test/ELF/Inputs/start-lib1.s b/test/ELF/Inputs/start-lib1.s new file mode 100644 index 000000000000..d401b20e65dc --- /dev/null +++ b/test/ELF/Inputs/start-lib1.s @@ -0,0 +1,3 @@ +.globl foo +foo: + call bar diff --git a/test/ELF/Inputs/start-lib2.s b/test/ELF/Inputs/start-lib2.s new file mode 100644 index 000000000000..f500936565f7 --- /dev/null +++ b/test/ELF/Inputs/start-lib2.s @@ -0,0 +1,2 @@ +.globl bar +bar: diff --git a/test/ELF/Inputs/symbol-override.s b/test/ELF/Inputs/symbol-override.s new file mode 100644 index 000000000000..21f3ae244c77 --- /dev/null +++ b/test/ELF/Inputs/symbol-override.s @@ -0,0 +1,16 @@ +.text +.globl foo +.type foo,@function +foo: +nop + +.globl bar +.type bar,@function +bar: +nop + +.globl do +.type do,@function +do: +callq foo@PLT +callq bar@PLT diff --git a/test/ELF/Inputs/tls-got-entry.s b/test/ELF/Inputs/tls-got-entry.s new file mode 100644 index 000000000000..e1e09a3306a2 --- /dev/null +++ b/test/ELF/Inputs/tls-got-entry.s @@ -0,0 +1,13 @@ +.globl __tls_get_addr +.align 16, 0x90 +.type __tls_get_addr,@function +__tls_get_addr: + +.type tlsshared0,@object +.section .tbss,"awT",@nobits +.globl tlsshared0 +.align 4 +tlsshared0: + .long 0 + .size tlsshared0, 4 + diff --git a/test/ELF/Inputs/tls-in-archive.s b/test/ELF/Inputs/tls-in-archive.s new file mode 100644 index 000000000000..0474a417659e --- /dev/null +++ b/test/ELF/Inputs/tls-in-archive.s @@ -0,0 +1,3 @@ + .type foo, @tls_object + .globl foo +foo: diff --git a/test/ELF/Inputs/trace-ar1.s b/test/ELF/Inputs/trace-ar1.s new file mode 100644 index 000000000000..0292bae6b4d4 --- /dev/null +++ b/test/ELF/Inputs/trace-ar1.s @@ -0,0 +1,2 @@ +.globl _used +_used: diff --git a/test/ELF/Inputs/trace-ar2.s b/test/ELF/Inputs/trace-ar2.s new file mode 100644 index 000000000000..d56f304c82f3 --- /dev/null +++ b/test/ELF/Inputs/trace-ar2.s @@ -0,0 +1,2 @@ +.globl _notused +_notused: diff --git a/test/ELF/Inputs/trace-symbols-foo-strong.s b/test/ELF/Inputs/trace-symbols-foo-strong.s new file mode 100644 index 000000000000..874642978c9b --- /dev/null +++ b/test/ELF/Inputs/trace-symbols-foo-strong.s @@ -0,0 +1,14 @@ +.text +.globl foo +.type foo, @function +foo: +nop + +.globl bar +.type bar, @function +bar: +nop + +.global func2 +.type func2, @function +func2: diff --git a/test/ELF/Inputs/trace-symbols-foo-weak.s b/test/ELF/Inputs/trace-symbols-foo-weak.s new file mode 100644 index 000000000000..d071ebecc4b5 --- /dev/null +++ b/test/ELF/Inputs/trace-symbols-foo-weak.s @@ -0,0 +1,12 @@ +.comm common,4,4 +.text +.weak foo +.type foo, @function +foo: +callq bar@PLT + +.globl func1 +.type func1, @function +func1: +call func2@PLT + diff --git a/test/ELF/Inputs/undef-with-plt-addr.s b/test/ELF/Inputs/undef-with-plt-addr.s new file mode 100644 index 000000000000..b12737d9e098 --- /dev/null +++ b/test/ELF/Inputs/undef-with-plt-addr.s @@ -0,0 +1,7 @@ + .globl set_data + .type set_data,@function +set_data: + + .globl foo + .type foo,@function +foo: diff --git a/test/ELF/Inputs/undef.s b/test/ELF/Inputs/undef.s new file mode 100644 index 000000000000..01776bf3505e --- /dev/null +++ b/test/ELF/Inputs/undef.s @@ -0,0 +1,3 @@ + .global zed1 +zed1: + .quad zed2 diff --git a/test/ELF/Inputs/unresolved-symbols.s b/test/ELF/Inputs/unresolved-symbols.s new file mode 100644 index 000000000000..b504708e43da --- /dev/null +++ b/test/ELF/Inputs/unresolved-symbols.s @@ -0,0 +1,3 @@ +.globl _shared +_shared: + callq undef@PLT diff --git a/test/ELF/Inputs/verdef-defaultver.s b/test/ELF/Inputs/verdef-defaultver.s new file mode 100644 index 000000000000..2e1d1c36fb92 --- /dev/null +++ b/test/ELF/Inputs/verdef-defaultver.s @@ -0,0 +1,22 @@ +b@LIBSAMPLE_1.0 = b_1 +b@@LIBSAMPLE_2.0 = b_2 + +.globl a +.type a,@function +a: +retq + +.globl b_1 +.type b_1,@function +b_1: +retq + +.globl b_2 +.type b_2,@function +b_2: +retq + +.globl c +.type c,@function +c: +retq diff --git a/test/ELF/Inputs/verdef.s b/test/ELF/Inputs/verdef.s new file mode 100644 index 000000000000..349d5fd0c261 --- /dev/null +++ b/test/ELF/Inputs/verdef.s @@ -0,0 +1,6 @@ +.text +.globl _start +_start: + callq a + callq b + callq c diff --git a/test/ELF/Inputs/verneed.so.sh b/test/ELF/Inputs/verneed.so.sh new file mode 100755 index 000000000000..3423f678e47a --- /dev/null +++ b/test/ELF/Inputs/verneed.so.sh @@ -0,0 +1,58 @@ +#!/bin/sh -eu + +# This script was used to produce the verneed{1,2}.so files. + +tmp=$(mktemp -d) + +echo "v1 {}; v2 {}; v3 {}; { local: *; };" > $tmp/verneed.script + +cat > $tmp/verneed1.s <<eof +.globl f1_v1 +f1_v1: +ret + +.globl f1_v2 +f1_v2: +ret + +.globl f1_v3 +f1_v3: +ret + +.symver f1_v1, f1@v1 +.symver f1_v2, f1@v2 +.symver f1_v3, f1@@v3 + +.globl f2_v1 +f2_v1: +ret + +.globl f2_v2 +f2_v2: +ret + +.symver f2_v1, f2@v1 +.symver f2_v2, f2@@v2 + +.globl f3_v1 +f3_v1: +ret + +.symver f3_v1, f3@v1 +eof + +as -o $tmp/verneed1.o $tmp/verneed1.s +ld.gold -shared -o verneed1.so $tmp/verneed1.o --version-script $tmp/verneed.script -soname verneed1.so.0 + +cat > $tmp/verneed2.s <<eof +.globl g1_v1 +g1_v1: +ret + +.symver g1_v1, g1@@v1 +eof + +as -o $tmp/verneed2.o $tmp/verneed2.s +ld.gold -shared -o verneed2.so $tmp/verneed2.o --version-script $tmp/verneed.script -soname verneed2.so.0 + +rm -rf $tmp diff --git a/test/ELF/Inputs/version-script-err.script b/test/ELF/Inputs/version-script-err.script new file mode 100644 index 000000000000..37de5980466e --- /dev/null +++ b/test/ELF/Inputs/version-script-err.script @@ -0,0 +1,4 @@ +{ + global: + foo +}; diff --git a/test/ELF/Inputs/version-use.script b/test/ELF/Inputs/version-use.script new file mode 100644 index 000000000000..5b2721b05b61 --- /dev/null +++ b/test/ELF/Inputs/version-use.script @@ -0,0 +1,6 @@ +ABC { +global: +foo; +local: +*; +}; diff --git a/test/ELF/Inputs/visibility.s b/test/ELF/Inputs/visibility.s index 6ef027d315fa..fe7cd9a49e7e 100644 --- a/test/ELF/Inputs/visibility.s +++ b/test/ELF/Inputs/visibility.s @@ -1,3 +1,4 @@ +.data .quad default .protected protected diff --git a/test/ELF/Inputs/warn-common.s b/test/ELF/Inputs/warn-common.s new file mode 100644 index 000000000000..fc4509ba70c7 --- /dev/null +++ b/test/ELF/Inputs/warn-common.s @@ -0,0 +1,2 @@ +.type arr,@object +.comm arr,8,4 diff --git a/test/ELF/Inputs/warn-common2.s b/test/ELF/Inputs/warn-common2.s new file mode 100644 index 000000000000..976c5becb09f --- /dev/null +++ b/test/ELF/Inputs/warn-common2.s @@ -0,0 +1,8 @@ +.type arr,@object +.data +.globl arr +.p2align 2 +arr: + .long 1 + .long 0 + .size arr, 8 diff --git a/test/ELF/Inputs/whole-archive.s b/test/ELF/Inputs/whole-archive.s index f9d56fc2fa21..816b24e2beca 100644 --- a/test/ELF/Inputs/whole-archive.s +++ b/test/ELF/Inputs/whole-archive.s @@ -1,2 +1,2 @@ -.globl _bar; +.globl _bar _bar: diff --git a/test/ELF/Inputs/x86-64-relax-offset.s b/test/ELF/Inputs/x86-64-relax-offset.s new file mode 100644 index 000000000000..780d1d0e64c1 --- /dev/null +++ b/test/ELF/Inputs/x86-64-relax-offset.s @@ -0,0 +1,7 @@ +.global foo +.hidden foo +foo: + nop + nop + nop + nop diff --git a/test/ELF/Inputs/x86-64-reloc-error.s b/test/ELF/Inputs/x86-64-reloc-error.s new file mode 100644 index 000000000000..bce6f8fafaaa --- /dev/null +++ b/test/ELF/Inputs/x86-64-reloc-error.s @@ -0,0 +1,7 @@ +.global big +.hidden big +big = 0x1000000000 + +.global foo +.hidden foo +foo = 0 diff --git a/test/ELF/Inputs/x86-64-tls-gd-got.s b/test/ELF/Inputs/x86-64-tls-gd-got.s new file mode 100644 index 000000000000..67a021a44fce --- /dev/null +++ b/test/ELF/Inputs/x86-64-tls-gd-got.s @@ -0,0 +1,6 @@ + .globl bar + .section .tdata,"awT",@progbits + .align 4 + .type bar, @object +bar: + .long 42 diff --git a/test/ELF/aarch64-abs64-dyn.s b/test/ELF/aarch64-abs64-dyn.s new file mode 100644 index 000000000000..2220225d5300 --- /dev/null +++ b/test/ELF/aarch64-abs64-dyn.s @@ -0,0 +1,27 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o + +// Creates a R_AARCH64_ABS64 relocation against foo and bar + .globl foo +foo: + + .global bar + .hidden bar +bar: + + .data + .xword foo + .xword bar + +// RUN: ld.lld -shared -o %t.so %t.o +// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s + +// CHECK: Dynamic Relocations { +// CHECK-NEXT: {{.*}} R_AARCH64_RELATIVE - [[BAR_ADDR:.*]] +// CHECK-NEXT: {{.*}} R_AARCH64_ABS64 foo 0x0 +// CHECK-NEXT: } + +// CHECK: Symbols [ +// CHECK: Symbol { +// CHECK: Name: bar +// CHECK-NEXT: Value: [[BAR_ADDR]] diff --git a/test/ELF/aarch64-copy.s b/test/ELF/aarch64-copy.s index 86d972057df0..6e0af27a0c6b 100644 --- a/test/ELF/aarch64-copy.s +++ b/test/ELF/aarch64-copy.s @@ -5,7 +5,7 @@ // RUN: ld.lld %t.o %t2.so -o %t3 // RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s // RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s -// RUN: llvm-objdump -s -section=.data %t3 | FileCheck -check-prefix=DATA %s +// RUN: llvm-objdump -s -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s .text .globl _start @@ -13,7 +13,7 @@ _start: adr x1, x adrp x2, y add x2, x2, :lo12:y -.data +.rodata .word z // CHECK: Name: .bss @@ -22,7 +22,7 @@ _start: // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x13010 +// CHECK-NEXT: Address: 0x13000 // CHECK-NEXT: Offset: // CHECK-NEXT: Size: 24 // CHECK-NEXT: Link: @@ -32,19 +32,19 @@ _start: // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.dyn { // CHECK-NEXT: Relocation { -// CHECK-NEXT: Offset: 0x13010 +// CHECK-NEXT: Offset: 0x13000 // CHECK-NEXT: Type: R_AARCH64_COPY // CHECK-NEXT: Symbol: x // CHECK-NEXT: Addend: 0x0 // CHECK-NEXT: } // CHECK-NEXT: Relocation { -// CHECK-NEXT: Offset: 0x13020 +// CHECK-NEXT: Offset: 0x13010 // CHECK-NEXT: Type: R_AARCH64_COPY // CHECK-NEXT: Symbol: y // CHECK-NEXT: Addend: 0x0 // CHECK-NEXT: } // CHECK-NEXT: Relocation { -// CHECK-NEXT: Offset: 0x13024 +// CHECK-NEXT: Offset: 0x13014 // CHECK-NEXT: Type: R_AARCH64_COPY // CHECK-NEXT: Symbol: z // CHECK-NEXT: Addend: 0x0 @@ -54,21 +54,21 @@ _start: // CHECK: Symbols [ // CHECK: Name: x -// CHECK-NEXT: Value: 0x13010 +// CHECK-NEXT: Value: 0x13000 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object // CHECK-NEXT: Other: // CHECK-NEXT: Section: .bss // CHECK: Name: y -// CHECK-NEXT: Value: 0x13020 +// CHECK-NEXT: Value: 0x13010 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object // CHECK-NEXT: Other: // CHECK-NEXT: Section: .bss // CHECK: Name: z -// CHECK-NEXT: Value: 0x13024 +// CHECK-NEXT: Value: 0x13014 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -78,16 +78,16 @@ _start: // CODE: Disassembly of section .text: // CODE-NEXT: _start: -// S(x) = 0x13010, A = 0, P = 0x11000 -// S + A - P = 0x10B0 = 8208 -// CODE-NEXT: 11000: {{.*}} adr x1, #8208 -// S(y) = 0x13020, A = 0, P = 0x11004 +// S(x) = 0x13000, A = 0, P = 0x11000 +// S + A - P = 0x2000 = 8208 +// CODE-NEXT: 11000: {{.*}} adr x1, #8192 +// S(y) = 0x13010, A = 0, P = 0x11004 // Page(S + A) - Page(P) = 0x13000 - 0x11000 = 0x2000 = 8192 // CODE-NEXT: 11004: {{.*}} adrp x2, #8192 -// S(y) = 0x13020, A = 0 -// (S + A) & 0xFFF = 0x20 = 32 -// CODE-NEXT: 11008: {{.*}} add x2, x2, #32 +// S(y) = 0x13010, A = 0 +// (S + A) & 0xFFF = 0x10 = 16 +// CODE-NEXT: 11008: {{.*}} add x2, x2, #16 -// DATA: Contents of section .data: -// S(z) = 0x13024 -// DATA-NEXT: 13000 24300100 +// RODATA: Contents of section .rodata: +// S(z) = 0x13014 +// RODATA-NEXT: 101c8 14300100 diff --git a/test/ELF/aarch64-copy2.s b/test/ELF/aarch64-copy2.s new file mode 100644 index 000000000000..af99d8ec2aee --- /dev/null +++ b/test/ELF/aarch64-copy2.s @@ -0,0 +1,27 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux +// RUN: llvm-mc %p/Inputs/aarch64-copy2.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t +// RUN: llvm-readobj -t %t | FileCheck %s + + .global _start +_start: + adrp x8, foo + bl bar + +// CHECK: Name: bar +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined + +// CHECK: Name: foo +// CHECK-NEXT: Value: 0x11030 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Function +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined diff --git a/test/ELF/aarch64-fpic-abs16.s b/test/ELF/aarch64-fpic-abs16.s index 02ac90d3a1f2..e123f57447a5 100644 --- a/test/ELF/aarch64-fpic-abs16.s +++ b/test/ELF/aarch64-fpic-abs16.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_ABS16 cannot be used when making a shared object; recompile with -fPIC. +// CHECK: relocation R_AARCH64_ABS16 cannot be used against shared object; recompile with -fPIC. .data .hword foo diff --git a/test/ELF/aarch64-fpic-add_abs_lo12_nc.s b/test/ELF/aarch64-fpic-add_abs_lo12_nc.s index 9e3216b1e090..7e0b6b833006 100644 --- a/test/ELF/aarch64-fpic-add_abs_lo12_nc.s +++ b/test/ELF/aarch64-fpic-add_abs_lo12_nc.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_ADD_ABS_LO12_NC cannot be used when making a shared object; recompile with -fPIC. +// CHECK: can't create dynamic relocation R_AARCH64_ADD_ABS_LO12_NC against readonly segment add x0, x0, :lo12:dat .data diff --git a/test/ELF/aarch64-fpic-adr_prel_lo21.s b/test/ELF/aarch64-fpic-adr_prel_lo21.s index 2246b64c6a71..501a724616e3 100644 --- a/test/ELF/aarch64-fpic-adr_prel_lo21.s +++ b/test/ELF/aarch64-fpic-adr_prel_lo21.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_ADR_PREL_LO21 cannot be used when making a shared object; recompile with -fPIC. +// CHECK: can't create dynamic relocation R_AARCH64_ADR_PREL_LO21 against readonly segment adr x0, dat .data diff --git a/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s b/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s index af6ebfc3e879..572ecffa6d71 100644 --- a/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s +++ b/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_ADR_PREL_PG_HI21 cannot be used when making a shared object; recompile with -fPIC. +// CHECK: can't create dynamic relocation R_AARCH64_ADR_PREL_PG_HI21 against readonly segment adrp x0, dat .data diff --git a/test/ELF/aarch64-fpic-got.s b/test/ELF/aarch64-fpic-got.s new file mode 100644 index 000000000000..70b2a7a76f86 --- /dev/null +++ b/test/ELF/aarch64-fpic-got.s @@ -0,0 +1,18 @@ +# REQUIRES: aarch64 + +# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %p/Inputs/shared.s -o %t-lib.o +# RUN: ld.lld -shared %t-lib.o -o %t-lib.so +# RUN: ld.lld %t-lib.so %t.o -o %t.exe +# RUN: llvm-readobj -dyn-relocations %t.exe | FileCheck %s + +## Checks if got access to dynamic objects is done through a got relative +## dynamic relocation and not using plt relative (R_AARCH64_JUMP_SLOT). +# CHECK: Dynamic Relocations { +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_GLOB_DAT bar 0x0 +# CHECK-NEXT: } + +.globl _start +_start: + adrp x0, :got:bar + ldr x0, [x0, :got_lo12:bar] diff --git a/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s b/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s index 2b1e6769e1a0..85772f10fcc7 100644 --- a/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s +++ b/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_LDST32_ABS_LO12_NC cannot be used when making a shared object; recompile with -fPIC. +// CHECK: can't create dynamic relocation R_AARCH64_LDST32_ABS_LO12_NC against readonly segment ldr s4, [x0, :lo12:dat] .data diff --git a/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s b/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s index f2553879cf37..d9f7b0c9ad1b 100644 --- a/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s +++ b/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_LDST64_ABS_LO12_NC cannot be used when making a shared object; recompile with -fPIC. +// CHECK: can't create dynamic relocation R_AARCH64_LDST64_ABS_LO12_NC against readonly segment ldr x0, [x0, :lo12:dat] .data diff --git a/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s b/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s index f7b465731b46..20e1bba49d1e 100644 --- a/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s +++ b/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_LDST8_ABS_LO12_NC cannot be used when making a shared object; recompile with -fPIC. +// CHECK: can't create dynamic relocation R_AARCH64_LDST8_ABS_LO12_NC against readonly segment ldrsb x0, [x1, :lo12:dat] .data diff --git a/test/ELF/aarch64-fpic-prel16.s b/test/ELF/aarch64-fpic-prel16.s index d80b6e88a67a..52e2402a4831 100644 --- a/test/ELF/aarch64-fpic-prel16.s +++ b/test/ELF/aarch64-fpic-prel16.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_PREL16 cannot be used when making a shared object; recompile with -fPIC. +// CHECK: relocation R_AARCH64_PREL16 cannot be used against shared object; recompile with -fPIC. .data .hword foo - . diff --git a/test/ELF/aarch64-fpic-prel32.s b/test/ELF/aarch64-fpic-prel32.s index af540ce734bb..72ba58f84d56 100644 --- a/test/ELF/aarch64-fpic-prel32.s +++ b/test/ELF/aarch64-fpic-prel32.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_PREL32 cannot be used when making a shared object; recompile with -fPIC. +// CHECK: relocation R_AARCH64_PREL32 cannot be used against shared object; recompile with -fPIC. .data .word foo - . diff --git a/test/ELF/aarch64-fpic-prel64.s b/test/ELF/aarch64-fpic-prel64.s index 2cf4cc916b3e..53a4820962b6 100644 --- a/test/ELF/aarch64-fpic-prel64.s +++ b/test/ELF/aarch64-fpic-prel64.s @@ -1,7 +1,7 @@ // REQUIRES: aarch64 // RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o // RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -// CHECK: Relocation R_AARCH64_PREL64 cannot be used when making a shared object; recompile with -fPIC. +// CHECK: relocation R_AARCH64_PREL64 cannot be used against shared object; recompile with -fPIC. .data .xword foo - . diff --git a/test/ELF/aarch64-gnu-ifunc-nosym.s b/test/ELF/aarch64-gnu-ifunc-nosym.s index d85bf1076601..bb3a0b8b5116 100644 --- a/test/ELF/aarch64-gnu-ifunc-nosym.s +++ b/test/ELF/aarch64-gnu-ifunc-nosym.s @@ -6,20 +6,18 @@ // Check that no __rela_iplt_end/__rela_iplt_start // appear in symtab if there is no references to them. // CHECK: Symbols [ -// CHECK-NEXT-NOT: __rela_iplt_end -// CHECK-NEXT-NOT: __rela_iplt_start +// CHECK-NOT: __rela_iplt_end +// CHECK-NOT: __rela_iplt_start // CHECK: ] .text .type foo STT_GNU_IFUNC .globl foo -.type foo, @function foo: ret .type bar STT_GNU_IFUNC .globl bar -.type bar, @function bar: ret diff --git a/test/ELF/aarch64-gnu-ifunc.s b/test/ELF/aarch64-gnu-ifunc.s index 4cc94200789d..351d0ed0440a 100644 --- a/test/ELF/aarch64-gnu-ifunc.s +++ b/test/ELF/aarch64-gnu-ifunc.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o // RUN: ld.lld -static %t.o -o %tout // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM -// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s --check-prefix=CHECK +// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s // REQUIRES: aarch64 // CHECK: Sections [ @@ -51,8 +51,10 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rela.plt // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: __rela_iplt_start @@ -60,8 +62,10 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rela.plt // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start @@ -126,13 +130,11 @@ .text .type foo STT_GNU_IFUNC .globl foo -.type foo, @function foo: ret .type bar STT_GNU_IFUNC .globl bar -.type bar, @function bar: ret diff --git a/test/ELF/aarch64-got-relocations.s b/test/ELF/aarch64-got-relocations.s new file mode 100644 index 000000000000..13ee09a892e9 --- /dev/null +++ b/test/ELF/aarch64-got-relocations.s @@ -0,0 +1,21 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t.o +# RUN: ld.lld -pie %t.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s + +# If we're addressing a global relatively through the GOT, we still need to +# emit a relocation for the entry in the GOT itself. +# CHECK: Relocations [ +# CHECK: Section (4) .rela.dyn { +# CHECK: 0x{{[0-9A-F]+}} R_AARCH64_RELATIVE - 0x{{[0-9A-F]+}} +# CHECK: } +# CHECK: ] + + .globl _start + .type _start,@function +_start: + adrp x8, :got:i + ldr x8, [x8, :got_lo12:i] + + .type i,@object + .comm i,4,4 diff --git a/test/ELF/aarch64-got.s b/test/ELF/aarch64-got.s new file mode 100644 index 000000000000..f56d8a734784 --- /dev/null +++ b/test/ELF/aarch64-got.s @@ -0,0 +1,18 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK-NOT: Name: .got + +.globl _start +_start: + adrp x0, :gottprel:foo + + .global foo + .section .tdata,"awT",%progbits + .align 2 + .type foo, %object + .size foo, 4 +foo: + .word 5 diff --git a/test/ELF/aarch64-relative.s b/test/ELF/aarch64-relative.s new file mode 100644 index 000000000000..b10dd80fae6c --- /dev/null +++ b/test/ELF/aarch64-relative.s @@ -0,0 +1,26 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -r %t.so | FileCheck %s + + adr x8, .Lfoo // R_AARCH64_ADR_PREL_LO21 + adrp x8, .Lfoo // R_AARCH64_ADR_PREL_PG_HI21 + strb w9, [x8, :lo12:.Lfoo] // R_AARCH64_LDST8_ABS_LO12_NC + ldr h17, [x19, :lo12:.Lfoo] // R_AARCH64_LDST16_ABS_LO12_NC + ldr w0, [x8, :lo12:.Lfoo] // R_AARCH64_LDST32_ABS_LO12_NC + ldr x0, [x8, :lo12:.Lfoo] // R_AARCH64_LDST64_ABS_LO12_NC + ldr q20, [x19, #:lo12:.Lfoo] // R_AARCH64_LDST128_ABS_LO12_NC + add x0, x0, :lo12:.Lfoo // R_AARCH64_ADD_ABS_LO12_NC + bl .Lfoo // R_AARCH64_CALL26 + b .Lfoo // R_AARCH64_JUMP26 + beq .Lfoo // R_AARCH64_CONDBR19 +.Lbranch: + tbz x1, 7, .Lbranch // R_AARCH64_TSTBR14 +.data +.Lfoo: + +.rodata +.long .Lfoo - . +.xword .Lfoo - . // R_AARCH64_PREL64 +// CHECK: Relocations [ +// CHECK-NEXT: ] diff --git a/test/ELF/aarch64-relocs.s b/test/ELF/aarch64-relocs.s index 56b04a679111..90541329587a 100644 --- a/test/ELF/aarch64-relocs.s +++ b/test/ELF/aarch64-relocs.s @@ -120,3 +120,33 @@ foo8: # CHECK: Disassembly of section .R_AARCH64_LDST8_ABS_LO12_NC: # CHECK-NEXT: ldst8: # CHECK-NEXT: 11044: ab 21 81 39 ldrsb x11, [x13, #72] + +.section .R_AARCH64_LDST128_ABS_LO12_NC,"ax",@progbits +ldst128: + ldr q20, [x19, #:lo12:foo128] +foo128: + .asciz "foo" + .size mystr, 3 + +# S = 0x1104c, A = 0x4 +# R = ((S + A) & 0xFF8) << 6 = 0x00001400 +# 0x00001400 | 0x3dc00274 = 0x3dc01674 +# CHECK: Disassembly of section .R_AARCH64_LDST128_ABS_LO12_NC: +# CHECK: ldst128: +# CHECK: 1104c: 74 16 c0 3d ldr q20, [x19, #80] +#foo128: +# 11050: 66 6f 6f 00 .word + +.section .R_AARCH64_LDST16_ABS_LO12_NC,"ax",@progbits +ldst16: + ldr h17, [x19, :lo12:foo16] +foo16: + .asciz "foo" + .size mystr, 3 + +# S = 0x11054, A = 0x4 +# R = ((S + A) & 0x0FFC) << 9 = 0xb000 +# 0xb000 | 0x7d400271 = 0x7d40b271 +# CHECK: Disassembly of section .R_AARCH64_LDST16_ABS_LO12_NC: +# CHECK-NEXT: ldst16: +# CHECK-NEXT: 11054: 71 b2 40 7d ldr h17, [x19, #88] diff --git a/test/ELF/aarch64-tls-gdie.s b/test/ELF/aarch64-tls-gdie.s new file mode 100644 index 000000000000..709cc53a8c47 --- /dev/null +++ b/test/ELF/aarch64-tls-gdie.s @@ -0,0 +1,34 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux +// RUN: llvm-mc %p/Inputs/aarch64-tls-gdie.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t +// RUN: llvm-readobj -s %t | FileCheck --check-prefix=SEC %s +// RUN: llvm-objdump -d %t | FileCheck %s + + .globl _start +_start: + nop + adrp x0, :tlsdesc:a + ldr x1, [x0, :tlsdesc_lo12:a] + add x0, x0, :tlsdesc_lo12:a + .tlsdesccall a + blr x1 + +// SEC: Name: .got +// SEC-NEXT: Type: SHT_PROGBITS +// SEC-NEXT: Flags [ +// SEC-NEXT: SHF_ALLOC +// SEC-NEXT: SHF_WRITE +// SEC-NEXT: ] +// SEC-NEXT: Address: 0x120B0 + +// page(0x120B0) - page(0x11004) = 4096 +// 0x0B0 = 176 + +// CHECK: _start: +// CHECK-NEXT: 11000: {{.*}} nop +// CHECK-NEXT: 11004: {{.*}} adrp x0, #4096 +// CHECK-NEXT: 11008: {{.*}} ldr x0, [x0, #176] +// CHECK-NEXT: 1100c: {{.*}} nop +// CHECK-NEXT: 11010: {{.*}} nop diff --git a/test/ELF/aarch64-tls-gdle.s b/test/ELF/aarch64-tls-gdle.s new file mode 100644 index 000000000000..dc0c02a31d1c --- /dev/null +++ b/test/ELF/aarch64-tls-gdle.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o +# RUN: ld.lld %tmain.o %ttlsie.o -o %tout +# RUN: llvm-objdump -d %tout | FileCheck %s +# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s +# REQUIRES: aarch64 + +#Local-Dynamic to Initial-Exec relax creates no +#RELOC: Relocations [ +#RELOC-NEXT: ] + +# TCB size = 0x16 and foo is first element from TLS register. +# CHECK: Disassembly of section .text: +# CHECK: _start: +# CHECK: 11000: 00 00 a0 d2 movz x0, #0, lsl #16 +# CHECK: 11004: 00 02 80 f2 movk x0, #16 +# CHECK: 11008: 1f 20 03 d5 nop +# CHECK: 1100c: 1f 20 03 d5 nop + +.globl _start +_start: + adrp x0, :tlsdesc:foo + ldr x1, [x0, :tlsdesc_lo12:foo] + add x0, x0, :tlsdesc_lo12:foo + .tlsdesccall foo + blr x1 diff --git a/test/ELF/aarch64-tls-ie.s b/test/ELF/aarch64-tls-ie.s index 0462addba22d..0cec402b294a 100644 --- a/test/ELF/aarch64-tls-ie.s +++ b/test/ELF/aarch64-tls-ie.s @@ -1,3 +1,4 @@ +// REQUIRES: aarch64 # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tls-ie.s -o %tdso.o # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o # RUN: ld.lld -shared %tdso.o -o %tdso.so @@ -24,8 +25,8 @@ #RELOC-NEXT: } #RELOC: Relocations [ #RELOC-NEXT: Section ({{.*}}) .rela.dyn { -#RELOC-NEXT: 0x120B0 R_AARCH64_TLS_TPREL64 foo 0x0 #RELOC-NEXT: 0x120B8 R_AARCH64_TLS_TPREL64 bar 0x0 +#RELOC-NEXT: 0x120B0 R_AARCH64_TLS_TPREL64 foo 0x0 #RELOC-NEXT: } #RELOC-NEXT:] diff --git a/test/ELF/aarch64-tls-iele.s b/test/ELF/aarch64-tls-iele.s new file mode 100644 index 000000000000..91efc092a2cf --- /dev/null +++ b/test/ELF/aarch64-tls-iele.s @@ -0,0 +1,33 @@ +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o +# RUN: ld.lld %tmain.o %ttlsie.o -o %tout +# RUN: llvm-objdump -d %tout | FileCheck %s +# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s +# REQUIRES: aarch64 + +# Initial-Exec to Local-Exec relax creates no dynamic relocations. +# RELOC: Relocations [ +# RELOC-NEXT: ] + +# TCB size = 0x16 and foo is first element from TLS register. +# CHECK: Disassembly of section .text: +# CHECK: _start: +# CHECK-NEXT: 11000: 00 00 a0 d2 movz x0, #0, lsl #16 +# CHECK-NEXT: 11004: 80 02 80 f2 movk x0, #20 +# CHECK-NEXT: 11008: 00 00 a0 d2 movz x0, #0, lsl #16 +# CHECK-NEXT: 1100c: 00 02 80 f2 movk x0, #16 + +.section .tdata +.align 2 +.type foo_local, %object +.size foo_local, 4 +foo_local: +.word 5 +.text + +.globl _start +_start: + adrp x0, :gottprel:foo + ldr x0, [x0, :gottprel_lo12:foo] + adrp x0, :gottprel:foo_local + ldr x0, [x0, :gottprel_lo12:foo_local] diff --git a/test/ELF/aarch64-tls-le.s b/test/ELF/aarch64-tls-le.s new file mode 100644 index 000000000000..22bd0ef2dad7 --- /dev/null +++ b/test/ELF/aarch64-tls-le.s @@ -0,0 +1,31 @@ +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o +# RUN: ld.lld %tmain.o -o %tout +# RUN: llvm-objdump -d %tout | FileCheck %s +# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s +# REQUIRES: aarch64 + +#Local-Dynamic to Initial-Exec relax creates no +#RELOC: Relocations [ +#RELOC-NEXT: ] + +.globl _start +_start: + mrs x0, TPIDR_EL0 + add x0, x0, :tprel_hi12:v1 + add x0, x0, :tprel_lo12_nc:v1 + +# TCB size = 0x16 and foo is first element from TLS register. +#CHECK: Disassembly of section .text: +#CHECK: _start: +#CHECK: 11000: 40 d0 3b d5 mrs x0, TPIDR_EL0 +#CHECK: 11004: 00 00 00 91 add x0, x0, #0 +#CHECK: 11008: 00 40 00 91 add x0, x0, #16 + +.type v1,@object +.section .tbss,"awT",@nobits +.globl v1 +.p2align 2 +v1: +.word 0 +.size v1, 4 + diff --git a/test/ELF/aarch64-tls-pie.s b/test/ELF/aarch64-tls-pie.s new file mode 100644 index 000000000000..466045d6765d --- /dev/null +++ b/test/ELF/aarch64-tls-pie.s @@ -0,0 +1,28 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t1.o +# RUN: ld.lld -pie %t1.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s + +# Similar to bug 27174: R_AARCH64_TLSLE_*TPREL* relocations should be +# eliminated when building a PIE executable, as the static TLS layout is +# fixed. +# +# CHECK: Relocations [ +# CHECK-NEXT: ] + + .globl _start +_start: + # Accessing the variable directly. + add x11, x8, :tprel_hi12:i + add x11, x11, :tprel_lo12_nc:i + + # Accessing the variable through the GOT. + adrp x10, :gottprel:i + mrs x8, TPIDR_EL0 + ldr x10, [x10, :gottprel_lo12:i] + + .section .tbss.i,"awT",@nobits + .globl i +i: + .word 0 + .size i, 4 diff --git a/test/ELF/aarch64-tls-static.s b/test/ELF/aarch64-tls-static.s new file mode 100644 index 000000000000..c8508ee58b7f --- /dev/null +++ b/test/ELF/aarch64-tls-static.s @@ -0,0 +1,37 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc %s -o %t.o -triple aarch64-pc-linux -filetype=obj +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -s %t.so | FileCheck --check-prefix=SEC %s +// RUN: llvm-objdump -d %t.so | FileCheck %s + +foo: + adrp x0, :tlsdesc:bar + ldr x1, [x0, :tlsdesc_lo12:bar] + add x0, x0, :tlsdesc_lo12:bar + .tlsdesccall bar + blr x1 + + + .section .tdata,"awT",@progbits +bar: + .word 42 + + +// SEC: Name: .got +// SEC-NEXT: Type: SHT_PROGBITS +// SEC-NEXT: Flags [ +// SEC-NEXT: SHF_ALLOC +// SEC-NEXT: SHF_WRITE +// SEC-NEXT: ] +// SEC-NEXT: Address: 0x2098 +// SEC-NEXT: Offset: 0x2098 +// SEC-NEXT: Size: 16 + +// page(0x2098) - page(0x1000) = 4096 +// 0x98 = 152 + +// CHECK: foo: +// CHECK-NEXT: 1000: {{.*}} adrp x0, #4096 +// CHECK-NEXT: 1004: {{.*}} ldr x1, [x0, #152] +// CHECK-NEXT: 1008: {{.*}} add x0, x0, #152 +// CHECK-NEXT: 100c: {{.*}} blr x1 diff --git a/test/ELF/aarch64-tlsdesc.s b/test/ELF/aarch64-tlsdesc.s new file mode 100644 index 000000000000..f8c73aff243d --- /dev/null +++ b/test/ELF/aarch64-tlsdesc.s @@ -0,0 +1,24 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-linux %s -o %t.o +// RUN: ld.lld -shared %t.o -o %t.so +// RUN: llvm-objdump -d %t.so | FileCheck %s +// RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=REL %s + + adrp x0, :tlsdesc:a + ldr x1, [x0, :tlsdesc_lo12:a] + add x0, x0, :tlsdesc_lo12:a + .tlsdesccall a + blr x1 + +// CHECK: 1000: {{.*}} adrp x0, #4096 +// CHECK-NEXT: 1004: {{.*}} ldr x1, [x0, #144] +// CHECK-NEXT: 1008: {{.*}} add x0, x0, #144 +// CHECK-NEXT: 100c: {{.*}} blr x1 + +// 0x1000 + 4096 + 144 = 0x2090 + +// REL: Relocations [ +// REL-NEXT: Section (4) .rela.dyn { +// REL-NEXT: 0x2090 R_AARCH64_TLSDESC a 0x0 +// REL-NEXT: } +// REL-NEXT: ] diff --git a/test/ELF/abs-hidden.s b/test/ELF/abs-hidden.s new file mode 100644 index 000000000000..b93c2c692919 --- /dev/null +++ b/test/ELF/abs-hidden.s @@ -0,0 +1,46 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/abs-hidden.s -o %t2.o +// RUN: ld.lld %t.o %t2.o -o %t.so -shared +// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s + + .quad foo + .long foo@gotpcrel + +// CHECK: Name: .text +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x1000 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 12 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 4 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 42000000 00000000 58100000 +// 0x2060 - (0x1000 + 8) = 1058 +// CHECK-NEXT: ) + +// CHECK: Name: .got (38) +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2060 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 8 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 42000000 00000000 +// CHECK-NEXT: ) + +// CHECK: Relocations [ +// CHECK-NEXT: ] diff --git a/test/ELF/allow-shlib-undefined.s b/test/ELF/allow-shlib-undefined.s index 541a7e12007b..2d068b0f60ed 100644 --- a/test/ELF/allow-shlib-undefined.s +++ b/test/ELF/allow-shlib-undefined.s @@ -22,4 +22,4 @@ .globl _start _start: - call _shared + callq _shared@PLT diff --git a/test/ELF/amdgpu-entry.s b/test/ELF/amdgpu-entry.s index a17d243214b7..2a47b1778de8 100644 --- a/test/ELF/amdgpu-entry.s +++ b/test/ELF/amdgpu-entry.s @@ -1,5 +1,5 @@ # RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o -# RUN: not lld -e kernel0 -flavor gnu %t.o -o %t +# RUN: not ld.lld -e kernel0 %t.o -o %t # REQUIRES: amdgpu diff --git a/test/ELF/amdgpu-globals.s b/test/ELF/amdgpu-globals.s index ff0899f60a98..7f46b989b955 100644 --- a/test/ELF/amdgpu-globals.s +++ b/test/ELF/amdgpu-globals.s @@ -77,7 +77,7 @@ program_global_readonly: # CHECK: Symbol { # CHECK: Name: module_global_agent -# CHECK: Value: 0x0 +# CHECK: Value: # CHECK: Size: 4 # CHECK: Binding: Local # CHECK: Section: .hsadata_global_agent @@ -85,7 +85,7 @@ program_global_readonly: # CHECK: Symbol { # CHECK: Name: module_global_program -# CHECK: Value: 0x0 +# CHECK: Value: # CHECK: Size: 4 # CHECK: Binding: Local # CHECK: Section: .hsadata_global_program @@ -93,7 +93,7 @@ program_global_readonly: # CHECK: Symbol { # CHECK: Name: module_global_readonly -# CHECK: Value: 0x0 +# CHECK: Value: # CHECK: Size: 4 # CHECK: Binding: Local # CHECK: Type: Object @@ -102,7 +102,7 @@ program_global_readonly: # CHECK: Symbol { # CHECK: Name: program_global_agent -# CHECK: Value: 0x4 +# CHECK: Value: # CHECK: Size: 4 # CHECK: Binding: Global # CHECK: Type: Object @@ -111,7 +111,7 @@ program_global_readonly: # CHECK: Symbol { # CHECK: Name: program_global_program -# CHECK: Value: 0x4 +# CHECK: Value: # CHECK: Size: 4 # CHECK: Binding: Global # CHECK: Type: Object @@ -120,7 +120,7 @@ program_global_readonly: # CHECK: Symbol { # CHECK: Name: program_global_readonly -# CHECK: Value: 0x4 +# CHECK: Value: # CHECK: Size: 4 # CHECK: Binding: Global # CHECK: Type: Object @@ -128,11 +128,11 @@ program_global_readonly: # CHECK: } # CHECK: ProgramHeader { -# CHECK: Type: PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM -# CHECK: VirtualAddress: [[HSADATA_GLOBAL_PROGRAM_ADDR]] +# CHECK: Type: PT_LOAD +# CHECK: VirtualAddress: # CHECK: } # CHECK: ProgramHeader { -# CHECK: Type: PT_AMDGPU_HSA_LOAD_CODE_AGENT -# CHECK: VirtualAddress: [[HSATEXT_ADDR]] +# CHECK: Type: PT_LOAD +# CHECK: VirtualAddress: # CHECK: } diff --git a/test/ELF/amdgpu-kernels.s b/test/ELF/amdgpu-kernels.s index 3f43c71f65d7..62a8cb74a541 100644 --- a/test/ELF/amdgpu-kernels.s +++ b/test/ELF/amdgpu-kernels.s @@ -1,5 +1,5 @@ # RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o -# RUN: lld -flavor gnu %t.o -o %t +# RUN: ld.lld %t.o -o %t # RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s # REQUIRES: amdgpu @@ -41,7 +41,7 @@ kernel1: # CHECK: Symbol { # CHECK: Name: kernel0 -# CHECK: Value: 0x0 +# CHECK: Value: # CHECK: Size: 4 # CHECK: Binding: Global # CHECK: Type: AMDGPU_HSA_KERNEL @@ -50,7 +50,7 @@ kernel1: # CHECK: Symbol { # CHECK: Name: kernel1 -# CHECK: Value: 0x100 +# CHECK: Value: # CHECK: Size: 8 # CHECK: Binding: Global # CHECK: Type: AMDGPU_HSA_KERNEL @@ -58,6 +58,6 @@ kernel1: # CHECK: } # CHECK: ProgramHeader { -# CHECK: Type: PT_AMDGPU_HSA_LOAD_CODE_AGENT -# CHECK: VirtualAddress: [[HSATEXT_ADDR]] +# CHECK: Type: PT_LOAD +# CHECK: VirtualAddress: # CHECK: } diff --git a/test/ELF/amdgpu-relocs.s b/test/ELF/amdgpu-relocs.s new file mode 100644 index 000000000000..58c9582a84f1 --- /dev/null +++ b/test/ELF/amdgpu-relocs.s @@ -0,0 +1,33 @@ +# RUN: llvm-mc -filetype=obj -triple=amdgcn--amdhsa -mcpu=fiji %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-readobj -r %t.so | FileCheck %s + +# REQUIRES: amdgpu + + .text + +kernel0: + s_mov_b32 s0, common_var@GOTPCREL+4 + s_mov_b32 s0, extern_var@GOTPCREL+4 + s_mov_b32 s0, local_var+4 + s_mov_b32 s0, global_var@GOTPCREL+4 + s_mov_b32 s0, weak_var@GOTPCREL+4 + s_mov_b32 s0, weakref_var@GOTPCREL+4 + s_endpgm + + .comm common_var,1024,4 + .globl global_var + .local local_var + .weak weak_var + .weakref weakref_var, weakref_alias_var + +# The relocation for local_var should be resolved by the linker. +# CHECK: Relocations [ +# CHECK: .rela.dyn { +# CHECK-NEXT: R_AMDGPU_ABS64 common_var 0x0 +# CHECK-NEXT: R_AMDGPU_ABS64 extern_var 0x0 +# CHECK-NEXT: R_AMDGPU_ABS64 global_var 0x0 +# CHECK-NEXT: R_AMDGPU_ABS64 weak_var 0x0 +# CHECK-NEXT: R_AMDGPU_ABS64 weakref_alias_var 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] diff --git a/test/ELF/archive.s b/test/ELF/archive.s index 41d74451cdd6..59c96a5fba9b 100644 --- a/test/ELF/archive.s +++ b/test/ELF/archive.s @@ -6,6 +6,10 @@ # RUN: llvm-ar rcs %tar %t2 %t3 %t4 # RUN: ld.lld %t %tar %t5 -o %tout # RUN: llvm-nm %tout | FileCheck %s +# RUN: rm -f %tarthin +# RUN: llvm-ar --format=gnu rcsT %tarthin %t2 %t3 %t4 +# RUN: ld.lld %t %tarthin %t5 -o %tout +# RUN: llvm-nm %tout | FileCheck %s # REQUIRES: x86 # Nothing here. Just needed for the linker to create a undefined _start symbol. diff --git a/test/ELF/arm-abs32-dyn.s b/test/ELF/arm-abs32-dyn.s new file mode 100644 index 000000000000..68183fe6f198 --- /dev/null +++ b/test/ELF/arm-abs32-dyn.s @@ -0,0 +1,32 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux %s -o %t.o + +// Creates a R_ARM_ABS32 relocation against foo and bar, bar has hidden +// visibility so we expect a R_ARM_RELATIVE + .syntax unified + .globl foo +foo: + .globl bar + .hidden bar +bar: + + .data + .word foo + .word bar + +// RUN: ld.lld -shared -o %t.so %t.o +// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s + +// CHECK: Dynamic Relocations { +// CHECK-NEXT: 0x2004 R_ARM_RELATIVE +// CHECK-NEXT: 0x2000 R_ARM_ABS32 foo 0x0 +// CHECK-NEXT: } + +// CHECK: Symbols [ +// CHECK: Symbol { +// CHECK: Name: bar +// CHECK-NEXT: Value: 0x1000 + +// CHECK: Symbol { +// CHECK: Name: foo +// CHECK-NEXT: Value: 0x1000 diff --git a/test/ELF/arm-attributes-remove.s b/test/ELF/arm-attributes-remove.s new file mode 100644 index 000000000000..010f366cd7fb --- /dev/null +++ b/test/ELF/arm-attributes-remove.s @@ -0,0 +1,45 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: ld.lld %t.o -o %t +// RUN: llvm-readobj -s %t | FileCheck %s +// RUN: ld.lld %t.o -shared -o %t2 +// RUN: llvm-readobj -s %t2 | FileCheck %s +// RUN: ld.lld %t.o -r -o %t3 +// RUN: llvm-readobj -s %t3 | FileCheck %s + +// The .ARM.attributes section should be removed from executables and +// shared objects. + +// At present we remove it from the -r object output as well which isn't ideal. +// Unfortunately combining per-object attributes cannot be safely done by just +// concatentation of input sections. + +// CHECK-NOT: Name: .ARM.attributes +// REQUIRES: arm + .text + .syntax unified + .eabi_attribute 67, "2.09" @ Tag_conformance + .cpu cortex-a8 + .eabi_attribute 6, 10 @ Tag_CPU_arch + .eabi_attribute 7, 65 @ Tag_CPU_arch_profile + .eabi_attribute 8, 1 @ Tag_ARM_ISA_use + .eabi_attribute 9, 2 @ Tag_THUMB_ISA_use + .fpu neon + .eabi_attribute 15, 1 @ Tag_ABI_PCS_RW_data + .eabi_attribute 16, 1 @ Tag_ABI_PCS_RO_data + .eabi_attribute 17, 2 @ Tag_ABI_PCS_GOT_use + .eabi_attribute 20, 1 @ Tag_ABI_FP_denormal + .eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions + .eabi_attribute 23, 3 @ Tag_ABI_FP_number_model + .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access + .eabi_attribute 24, 1 @ Tag_ABI_align_needed + .eabi_attribute 25, 1 @ Tag_ABI_align_preserved + .eabi_attribute 38, 1 @ Tag_ABI_FP_16bit_format + .eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t + .eabi_attribute 26, 2 @ Tag_ABI_enum_size + .eabi_attribute 14, 0 @ Tag_ABI_PCS_R9_use + .eabi_attribute 68, 1 @ Tag_Virtualization_use + .globl _start + .p2align 2 + .type _start,%function +_start: + bx lr diff --git a/test/ELF/arm-blx.s b/test/ELF/arm-blx.s new file mode 100644 index 000000000000..cccb1324fc8b --- /dev/null +++ b/test/ELF/arm-blx.s @@ -0,0 +1,113 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar +// RUN: echo "SECTIONS { \ +// RUN: .callee1 : { *(.callee_low) } \ +// RUN: .callee2 : { *(.callee_arm_low) } \ +// RUN: .caller : { *(.text) } \ +// RUN: .callee3 : { *(.callee_high) } \ +// RUN: .callee4 : { *(.callee_arm_high) } } " > %t.script +// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s +// REQUIRES: arm + +// Test BLX instruction is chosen for ARM BL/BLX instruction and Thumb callee +// Using two callees to ensure at least one has 2-byte alignment. + .syntax unified + .thumb + .section .callee_low, "ax",%progbits + .align 2 + .type callee_low,%function +callee_low: + bx lr + .type callee_low2, %function +callee_low2: + bx lr + + .section .callee_arm_low, "ax",%progbits + .arm + .balign 0x100 + .type callee_arm_low,%function + .align 2 +callee_arm_low: + bx lr + +.section .text, "ax",%progbits + .arm + .globl _start + .balign 0x10000 + .type _start,%function +_start: + bl callee_low + blx callee_low + bl callee_low2 + blx callee_low2 + bl callee_high + blx callee_high + bl callee_high2 + blx callee_high2 + bl blx_far + blx blx_far2 +// blx to ARM instruction should be written as a BL + bl callee_arm_low + blx callee_arm_low + bl callee_arm_high + blx callee_arm_high + bx lr + + .section .callee_high, "ax",%progbits + .balign 0x100 + .thumb + .type callee_high,%function +callee_high: + bx lr + .type callee_high2,%function +callee_high2: + bx lr + + .section .callee_arm_high, "ax",%progbits + .arm + .balign 0x100 + .type callee_arm_high,%function +callee_arm_high: + bx lr + +// CHECK-THUMB: Disassembly of section .callee1: +// CHECK-THUMB-NEXT: callee_low: +// CHECK-THUMB-NEXT: b4: 70 47 bx lr +// CHECK-THUMB: callee_low2: +// CHECK-THUMB-NEXT: b6: 70 47 bx lr + +// CHECK-ARM: Disassembly of section .callee2: +// CHECK-ARM-NEXT: callee_arm_low: +// CHECK-ARM-NEXT: 100: 1e ff 2f e1 bx lr + +// CHECK-ARM: Disassembly of section .caller: +// CHECK-ARM-NEXT: _start: +// CHECK-ARM-NEXT: 10000: 2b c0 ff fa blx #-65364 <callee_low> +// CHECK-ARM-NEXT: 10004: 2a c0 ff fa blx #-65368 <callee_low> +// CHECK-ARM-NEXT: 10008: 29 c0 ff fb blx #-65370 <callee_low2> +// CHECK-ARM-NEXT: 1000c: 28 c0 ff fb blx #-65374 <callee_low2> +// CHECK-ARM-NEXT: 10010: 3a 00 00 fa blx #232 <callee_high> +// CHECK-ARM-NEXT: 10014: 39 00 00 fa blx #228 <callee_high> +// CHECK-ARM-NEXT: 10018: 38 00 00 fb blx #226 <callee_high2> +// CHECK-ARM-NEXT: 1001c: 37 00 00 fb blx #222 <callee_high2> +// 10020 + 1FFFFFC + 8 = 0x2010024 = blx_far +// CHECK-ARM-NEXT: 10020: ff ff 7f fa blx #33554428 +// 10024 + 1FFFFFC + 8 = 0x2010028 = blx_far2 +// CHECK-ARM-NEXT: 10024: ff ff 7f fa blx #33554428 +// CHECK-ARM-NEXT: 10028: 34 c0 ff eb bl #-65328 <callee_arm_low> +// CHECK-ARM-NEXT: 1002c: 33 c0 ff eb bl #-65332 <callee_arm_low> +// CHECK-ARM-NEXT: 10030: 72 00 00 eb bl #456 <callee_arm_high> +// CHECK-ARM-NEXT: 10034: 71 00 00 eb bl #452 <callee_arm_high> +// CHECK-ARM-NEXT: 10038: 1e ff 2f e1 bx lr + +// CHECK-THUMB: Disassembly of section .callee3: +// CHECK-THUMB: callee_high: +// CHECK-THUMB-NEXT: 10100: 70 47 bx lr +// CHECK-THUMB: callee_high2: +// CHECK-THUMB-NEXT: 10102: 70 47 bx lr + +// CHECK-ARM: Disassembly of section .callee4: +// CHECK-NEXT-ARM: callee_arm_high: +// CHECK-NEXT-ARM: 10200: 1e ff 2f e1 bx lr diff --git a/test/ELF/arm-branch-error.s b/test/ELF/arm-branch-error.s new file mode 100644 index 000000000000..f1a855d7373f --- /dev/null +++ b/test/ELF/arm-branch-error.s @@ -0,0 +1,19 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar +// RUN: not ld.lld %t %tfar -o %t2 2>&1 | FileCheck %s +// REQUIRES: arm + .syntax unified + .section .text, "ax",%progbits + .globl _start + .balign 0x10000 + .type _start,%function +_start: + // address of too_far symbols are just out of range of ARM branch with + // 26-bit immediate field and an addend of -8 + bl too_far1 + b too_far2 + beq too_far3 + +// CHECK: R_ARM_CALL out of range +// CHECK-NEXT: R_ARM_JUMP24 out of range +// CHECK-NEXT: R_ARM_JUMP24 out of range diff --git a/test/ELF/arm-branch.s b/test/ELF/arm-branch.s new file mode 100644 index 000000000000..38266fabf852 --- /dev/null +++ b/test/ELF/arm-branch.s @@ -0,0 +1,59 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar +// RUN: echo "SECTIONS { \ +// RUN: .callee1 : { *(.callee_low) } \ +// RUN: .caller : { *(.text) } \ +// RUN: .callee2 : { *(.callee_high) } } " > %t.script +// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s +// REQUIRES: arm + .syntax unified + .section .callee_low, "ax",%progbits + .align 2 + .type callee_low,%function +callee_low: + bx lr + + .section .text, "ax",%progbits + .globl _start + .balign 0x10000 + .type _start,%function +_start: + bl callee_low + b callee_low + beq callee_low + bl callee_high + b callee_high + bne callee_high + bl far + b far + bgt far + bx lr + + .section .callee_high, "ax",%progbits + .align 2 + .type callee_high,%function +callee_high: + bx lr + +// CHECK: Disassembly of section .caller: +// CHECK-NEXT: _start: +// S(callee_low) = 0xb4 P = 0x10000 A = -8 = -0xff54 = -65364 +// CHECK-NEXT: 10000: 2b c0 ff eb bl #-65364 <callee_low> +// S(callee_low) = 0xb4 P = 0x10004 A = -8 = -0xff58 = -65368 +// CHECK-NEXT: 10004: 2a c0 ff ea b #-65368 <callee_low> +// S(callee_low) = 0xb4 P = 0x10008 A = -8 = -0xff5c -65372 +// CHECK-NEXT: 10008: 29 c0 ff 0a beq #-65372 <callee_low> +// S(callee_high) = 0x10028 P = 0x1000c A = -8 = 0x14 = 20 +// CHECK-NEXT: 1000c: 05 00 00 eb bl #20 <callee_high> +// S(callee_high) = 0x10028 P = 0x10010 A = -8 = 0x10 = 16 +// CHECK-NEXT: 10010: 04 00 00 ea b #16 <callee_high> +// S(callee_high) = 0x10028 P = 0x10014 A = -8 = 0x0c =12 +// CHECK-NEXT: 10014: 03 00 00 1a bne #12 <callee_high> +// S(far) = 0x201001c P = 0x10018 A = -8 = 0x1fffffc = 33554428 +// CHECK-NEXT: 10018: ff ff 7f eb bl #33554428 +// S(far) = 0x201001c P = 0x1001c A = -8 = 0x1fffff8 = 33554424 +// CHECK-NEXT: 1001c: fe ff 7f ea b #33554424 +// S(far) = 0x201001c P = 0x10020 A = -8 = 0x1fffff4 = 33554420 +// CHECK-NEXT: 10020: fd ff 7f ca bgt #33554420 +// CHECK-NEXT: 10024: 1e ff 2f e1 bx lr diff --git a/test/ELF/arm-copy.s b/test/ELF/arm-copy.s new file mode 100644 index 000000000000..e5ce1577babd --- /dev/null +++ b/test/ELF/arm-copy.s @@ -0,0 +1,81 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/relocation-copy-arm.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t2.so +// RUN: ld.lld %t.o %t2.so -o %t3 +// RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CODE %s +// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s + +// Copy relocations R_ARM_COPY are required for y and z + .syntax unified + .text + .globl _start +_start: + movw r2,:lower16: y + movt r2,:upper16: y + ldr r3,[pc,#4] + ldr r3,[r3,#0] + .rodata + .word z + +// CHECK: Name: .bss +// CHECK-NEXT: Type: SHT_NOBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x13000 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: 16 + +// CHECK: Relocations [ +// CHECK-NEXT: Section (5) .rel.dyn { +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: 0x13000 +// CHECK-NEXT: Type: R_ARM_COPY +// CHECK-NEXT: Symbol: y +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: 0x13004 +// CHECK-NEXT: Type: R_ARM_COPY +// CHECK-NEXT: Symbol: z +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: Symbols [ +// CHECK: Name: y +// CHECK-NEXT: Value: 0x13000 +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .bss +// CHECK: Name: z +// CHECK-NEXT: Value: 0x13004 +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .bss + +// CODE: Disassembly of section .text: +// CODE-NEXT: _start: +// S(y) = 0x13000, A = 0 +// (S + A) & 0x0000ffff = 0x3000 = #12288 +// CODE-NEXT: 11000: 00 20 03 e3 movw r2, #12288 +// S(y) = 0x13000, A = 0 +// ((S + A) & 0xffff0000) >> 16 = 0x1 +// CODE-NEXT: 11004: 01 20 40 e3 movt r2, #1 +// CODE-NEXT: 11008: 04 30 9f e5 ldr r3, [pc, #4] +// CODE-NEXT: 1100c: 00 30 93 e5 ldr r3, [r3] + + +// RODATA: Contents of section .rodata: +// S(z) = 0x13004 +// RODATA-NEXT: 10114 04300100 diff --git a/test/ELF/arm-data-prel.s b/test/ELF/arm-data-prel.s new file mode 100644 index 000000000000..590d8118ae6e --- /dev/null +++ b/test/ELF/arm-data-prel.s @@ -0,0 +1,63 @@ +// RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o %t.o +// RUN: echo "SECTIONS { \ +// RUN: .text : { *(.text) } \ +// RUN: .ARM.exidx : { *(.ARM.exidx) } \ +// RUN: .ARM.exidx.TEST1 : { *(.ARM.exidx.TEST1) } \ +// RUN: .TEST1 : { *(.TEST1) } } " > %t.script +// RUN: ld.lld --script %t.script %t.o -o %t +// RUN: llvm-readobj -s -sd %t | FileCheck --check-prefix=CHECK %s +// REQUIRES: arm + +// The R_ARM_PREL31 relocation is used in by the .ARM.exidx exception tables +// bit31 of the place denotes whether the field is an inline table entry +// (bit31=1) or relocation (bit31=0) +// The linker must preserve the value of bit31 + +// This test case is adapted from llvm/test/MC/ARM/eh-compact-pr0.s +// We use a linker script to place the .ARM.exidx sections in between +// the code sections so that we can test positive and negative offsets + .syntax unified + + .section .TEST1, "ax",%progbits + .globl _start + .align 2 + .type _start,%function +_start: + .fnstart + .save {r11, lr} + push {r11, lr} + .setfp r11, sp + mov r11, sp + pop {r11, lr} + mov pc, lr + .fnend + + .section .text, "ax",%progbits +// The generated .ARM.exidx section will refer to the personality +// routine __aeabi_unwind_cpp_pr0. Provide a dummy implementation +// to stop an undefined symbol error + .globl __aeabi_unwind_cpp_pr0 + .align 2 + .type __aeabi_unwind_cpp_pr0,%function +__aeabi_unwind_cpp_pr0: + .fnstart + bx lr + .fnend + +// The expected value of the exception table is +// Word0 0 in bit 31, -4 encoded in 31-bit signed offset +// Word1 Inline table entry EHT Inline Personality Routine #0 +// CHECK: Name: .ARM.exidx +// CHECK: SectionData ( +// CHECK: 0000: FCFFFF7F B0B0B080 +// CHECK: ) + +// The expected value of the exception table is +// Word0 0 in bit 31, +8 encoded in 31-bit signed offset +// Word1 Inline table entry EHT Inline Personality Routine #0 +// set vsp = r11 +// pop r11, r14 +// CHECK: Name: .ARM.exidx.TEST1 +// CHECK: SectionData ( +// CHECK: 0000: 08000000 80849B80 +// CHECK: ) diff --git a/test/ELF/arm-data-relocs.s b/test/ELF/arm-data-relocs.s new file mode 100644 index 000000000000..ed237850c4c1 --- /dev/null +++ b/test/ELF/arm-data-relocs.s @@ -0,0 +1,20 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/abs256.s -o %t256.o +// RUN: ld.lld %t %t256.o -o %t2 +// RUN: llvm-objdump -d %t2 | FileCheck %s +// REQUIRES: arm + .syntax unified + .globl _start +_start: + .section .R_ARM_ABS32POS, "ax",%progbits + .word foo + 0x24 + +// S = 0x100, A = 0x24 +// S + A = 0x124 +// CHECK: Disassembly of section .R_ARM_ABS32POS: +// CHECK: 11000: 24 01 00 00 + .section .R_ARM_ABS32NEG, "ax",%progbits + .word foo - 0x24 +// S = 0x100, A = -0x24 +// CHECK: Disassembly of section .R_ARM_ABS32NEG: +// CHECK: 11004: dc 00 00 00 diff --git a/test/ELF/arm-fpic-got.s b/test/ELF/arm-fpic-got.s new file mode 100644 index 000000000000..4b6002d3c077 --- /dev/null +++ b/test/ELF/arm-fpic-got.s @@ -0,0 +1,63 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: ld.lld %t.o -o %t +// RUN: llvm-readobj -s %t | FileCheck %s +// RUN: llvm-readobj -s -symbols %t | FileCheck -check-prefix=SYMBOLS %s +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s + +// Test the R_ARM_GOT_PREL relocation + .syntax unified + .text + .globl _start + .align 2 +_start: + ldr r0, .LCPI0_0 +.LPC0_0: + ldr r0, [pc, r0] + ldr r0, [r0] + bx lr +.LCPI0_0: +.Ltmp0: + // Generate R_ARM_GOT_PREL + .long val(GOT_PREL)-((.LPC0_0+8)-.Ltmp0) + + .data + .type val,%object + .globl val + .align 2 +val: + .long 10 + .size val, 4 + +// CHECK: Section { +// CHECK: Name: .got +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x12000 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: 4 +// CHECK-NEXT: EntrySize: + +// SYMBOLS: Name: val +// SYMBOLS-NEXT: Value: 0x13000 +// SYMBOLS-NEXT: Size: 4 +// SYMBOLS-NEXT: Binding: Global +// SYMBOLS-NEXT: Type: Object +// SYMBOLS-NEXT: Other: +// SYMBOLS-NEXT: Section: .data + +// CODE: Disassembly of section .text: +// CODE-NEXT: _start: +// CODE-NEXT: 11000: 08 00 9f e5 ldr r0, [pc, #8] +// CODE-NEXT: 11004: 00 00 9f e7 ldr r0, [pc, r0] +// CODE-NEXT: 11008: 00 00 90 e5 ldr r0, [r0] +// CODE-NEXT: 1100c: 1e ff 2f e1 bx lr +// CODE: $d.1: +// 0x11004 + 0x0ff4 + 8 = 0x12000 = .got +// CODE-NEXT: 11010: f4 0f 00 00 diff --git a/test/ELF/arm-gnu-ifunc-nosym.s b/test/ELF/arm-gnu-ifunc-nosym.s new file mode 100644 index 000000000000..fa79aef7ced8 --- /dev/null +++ b/test/ELF/arm-gnu-ifunc-nosym.s @@ -0,0 +1,27 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: ld.lld -static %t.o -o %tout +// RUN: llvm-readobj -symbols %tout | FileCheck %s +// REQUIRES: arm + +// Check that no __rel_iplt_end/__rel_iplt_start +// appear in symtab if there are no references to them. +// CHECK: Symbols [ +// CHECK-NOT: __rel_iplt_end +// CHECK-NOT: __rel_iplt_start +// CHECK: ] + .syntax unified + .text + .type foo STT_GNU_IFUNC + .globl foo +foo: + bx lr + + .type bar STT_GNU_IFUNC + .globl bar +bar: + bx lr + + .globl _start +_start: + bl foo + bl bar diff --git a/test/ELF/arm-gnu-ifunc.s b/test/ELF/arm-gnu-ifunc.s new file mode 100644 index 000000000000..c1e8a7183530 --- /dev/null +++ b/test/ELF/arm-gnu-ifunc.s @@ -0,0 +1,131 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: ld.lld -static %t.o -o %tout +// RUN: llvm-objdump -triple armv7a-none-linux-gnueabi -d %tout | FileCheck %s --check-prefix=DISASM +// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s +// REQUIRES: arm + .syntax unified + .text + .type foo STT_GNU_IFUNC + .globl foo +foo: + bx lr + + .type bar STT_GNU_IFUNC + .globl bar +bar: + bx lr + + .globl _start +_start: + bl foo + bl bar + movw r0,:lower16:__rel_iplt_start + movt r0,:upper16:__rel_iplt_start + movw r0,:lower16:__rel_iplt_end + movt r0,:upper16:__rel_iplt_end + +// CHECK: Sections [ +// CHECK: Section { +// CHECK: Index: 1 +// CHECK-NEXT: Name: .rel.plt +// CHECK-NEXT: Type: SHT_REL +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: ] +// CHECK-NEXT: Address: [[REL:.*]] +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 16 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: 4 +// CHECK-NEXT: EntrySize: 8 +// CHECK-NEXT: } +// CHECK: Relocations [ +// CHECK-NEXT: Section (1) .rel.plt { +// CHECK-NEXT: 0x1200C R_ARM_IRELATIVE +// CHECK-NEXT: 0x12010 R_ARM_IRELATIVE +// CHECK-NEXT: } +// CHECK-NEXT:] +// CHECK: Symbols [ +// CHECK: Symbol { +// CHECK: Name: __rel_iplt_end +// CHECK-NEXT: Value: 0x100E4 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rel.plt +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: __rel_iplt_start +// CHECK-NEXT: Value: 0x100D4 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rel.plt +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _start (6) +// CHECK-NEXT: Value: 0x11008 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: bar +// CHECK-NEXT: Value: 0x11004 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: GNU_IFunc +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: foo +// CHECK-NEXT: Value: 0x11000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: GNU_IFunc +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } + +// DISASM: Disassembly of section .text: +// DISASM-NEXT: foo: +// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr +// DISASM: bar: +// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr +// DISASM: _start: +// DISASM-NEXT: 11008: 09 00 00 eb bl #36 +// DISASM-NEXT: 1100c: 0c 00 00 eb bl #48 +// DISASM-NEXT: 11010: d4 00 00 e3 movw r0, #212 +// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1 +// r0 = 212 + 1 * 65536 = 100D4 = __rel_iplt_start +// DISASM-NEXT: 11018: e4 00 00 e3 movw r0, #228 +// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1 +// r1 = 228 + 1 * 65536 = 100E4 = __rel_iplt_end +// DISASM-NEXT: Disassembly of section .plt: +// DISASM-NEXT: .plt: +// DISASM-NEXT: 11020: 04 e0 2d e5 str lr, [sp, #-4]! +// DISASM-NEXT: 11024: 04 e0 9f e5 ldr lr, [pc, #4] +// DISASM-NEXT: 11028: 0e e0 8f e0 add lr, pc, lr +// DISASM-NEXT: 1102c: 08 f0 be e5 ldr pc, [lr, #8]! +// 0x0fd0 + 0x11028 + 0x8 = 0x12000 +// DISASM-NEXT: 11030: d0 0f 00 00 +// DISASM-NEXT: 11034: 04 c0 9f e5 ldr r12, [pc, #4] +// DISASM-NEXT: 11038: 0f c0 8c e0 add r12, r12, pc +// DISASM-NEXT: 1103c: 00 f0 9c e5 ldr pc, [r12] +// 0x0fcc + 0x11038 + 0x8 = 0x1200C +// DISASM-NEXT: 11040: cc 0f 00 00 +// DISASM-NEXT: 11044: 04 c0 9f e5 ldr r12, [pc, #4] +// DISASM-NEXT: 11048: 0f c0 8c e0 add r12, r12, pc +// DISASM-NEXT: 1104c: 00 f0 9c e5 ldr pc, [r12] +// 0x0fc0 + 0x11048 + 0x8 = 0x12010 +// DISASM-NEXT: 11050: c0 0f 00 00 diff --git a/test/ELF/arm-got-relative.s b/test/ELF/arm-got-relative.s new file mode 100644 index 000000000000..22ccb16a2a58 --- /dev/null +++ b/test/ELF/arm-got-relative.s @@ -0,0 +1,53 @@ +// REQUIRES: arm +// RUN: llvm-mc -position-independent -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: ld.lld %t.o -shared -o %t +// RUN: llvm-readobj -s -symbols -dyn-relocations %t | FileCheck %s +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s + .syntax unified + .text + .globl _start + .align 2 +_start: + .type _start, %function + ldr r3, .LGOT + ldr r2, .LGOT+4 +.LPIC: + add r0, pc, r3 + bx lr + .align 2 +.LGOT: + // gas implicitly uses (GOT_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC + // llvm-mc needs the (GOT_PREL) suffix or it generates R_ARM_REL32 + .word _GLOBAL_OFFSET_TABLE_(GOT_PREL) - (.LPIC+8) + .word function(GOT) + + .globl function + .align 2 +function: + .type function, %function + bx lr + +// CHECK: Dynamic Relocations { +// CHECK-NEXT: 0x204C R_ARM_GLOB_DAT function 0x0 + +// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (16) +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: Absolute + +// CODE: Disassembly of section .text: +// CODE-NEXT: _start: +// CODE-NEXT: 1000: 08 30 9f e5 ldr r3, [pc, #8] +// CODE-NEXT: 1004: 08 20 9f e5 ldr r2, [pc, #8] +// CODE-NEXT: 1008: 03 00 8f e0 add r0, pc, r3 +// CODE-NEXT: 100c: 1e ff 2f e1 bx lr +// CODE:$d.1: +// (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038 +// CODE-NEXT: 1010: 38 10 00 00 +// (Got(function) - GotBase = 0x4 +// CODE-NEXT: 1014: 04 00 00 00 diff --git a/test/ELF/arm-gotoff.s b/test/ELF/arm-gotoff.s new file mode 100644 index 000000000000..5169f84e6a01 --- /dev/null +++ b/test/ELF/arm-gotoff.s @@ -0,0 +1,74 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t.o +// RUN: ld.lld %t.o -o %t +// RUN: llvm-readobj -s -r -t %t | FileCheck %s +// RUN: llvm-objdump -triple=armv7a-linux-gnueabi -d %t | FileCheck --check-prefix=DISASM %s +// REQUIRES: arm + +// Test the R_ARM_GOTOFF32 relocation + +// CHECK: Name: .got +// CHECK-NEXT: Type: SHT_PROGBITS (0x1) +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x12000 +// CHECK-NEXT: Offset: 0x2000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: + +// CHECK: Name: .bss +// CHECK-NEXT: Type: SHT_NOBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x12000 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 20 +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: 1 + +// CHECK-NEXT: EntrySize: 0 + +// CHECK: Symbol { +// CHECK: Name: bar +// CHECK-NEXT: Value: 0x12000 +// CHECK-NEXT: Size: 10 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .bss +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: obj +// CHECK-NEXT: Value: 0x1200A +// CHECK-NEXT: Size: 10 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .bss + +// DISASM: Disassembly of section .text: +// DISASM-NEXT :_start: +// DISASM-NEXT 11000: 1e ff 2f e1 bx lr +// Offset 0 from .got = bar +// DISASM 11004: 00 00 00 00 +// Offset 10 from .got = obj +// DISASM-NEXT 11008: 0a 00 00 00 +// Offset 15 from .got = obj +5 +// DISASM-NEXT 1100c: 0f 00 00 00 + .syntax unified + .globl _start +_start: + bx lr + .word bar(GOTOFF) + .word obj(GOTOFF) + .word obj(GOTOFF)+5 + .type bar, %object + .comm bar, 10 + .type obj, %object + .comm obj, 10 diff --git a/test/ELF/arm-mov-relocs.s b/test/ELF/arm-mov-relocs.s new file mode 100644 index 000000000000..31ccba4cceaf --- /dev/null +++ b/test/ELF/arm-mov-relocs.s @@ -0,0 +1,94 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-unknown-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 +// RUN: llvm-objdump -d %t2 -triple=armv7a-unknown-linux-gnueabi | FileCheck %s +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-unknown-linux-gnueabi %s -o %t3 +// RUN: ld.lld %t3 -o %t4 +// RUN: llvm-objdump -d %t4 -triple=thumbv7a-unknown-linux-gnueabi | FileCheck %s +// REQUIRES: arm + +// Test the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocations as well as +// the R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS relocations. + .syntax unified + .globl _start +_start: + .section .R_ARM_MOVW_ABS_NC, "ax",%progbits + movw r0, :lower16:label + movw r1, :lower16:label1 + movw r2, :lower16:label2 + 4 + movw r3, :lower16:label3 + movw r4, :lower16:label3 + 4 +// CHECK: Disassembly of section .R_ARM_MOVW_ABS_NC +// CHECK: movw r0, #0 +// CHECK: movw r1, #4 +// CHECK: movw r2, #12 +// CHECK: movw r3, #65532 +// CHECK: movw r4, #0 + .section .R_ARM_MOVT_ABS, "ax",%progbits + movt r0, :upper16:label + movt r1, :upper16:label1 +// FIXME: We shouldn't need to multiply by 65536. +// arguably llvm-mc incorrectly assembles addends for +// SHT_REL relocated movt instructions. When there is a relocation +// the interpretation of the addend for SHT_REL is not shifted + movt r2, :upper16:label2 + (4 * 65536) + movt r3, :upper16:label3 +// FIXME: We shouldn't need to multiply by 65536 see comment above. + movt r4, :upper16:label3 + (4 * 65536) +// CHECK: Disassembly of section .R_ARM_MOVT_ABS +// CHECK: movt r0, #2 +// CHECK: movt r1, #2 +// CHECK: movt r2, #2 +// CHECK: movt r3, #2 +// CHECK: movt r4, #3 + +.section .R_ARM_MOVW_PREL_NC, "ax",%progbits + movw r0, :lower16:label - . + movw r1, :lower16:label1 - . + movw r2, :lower16:label2 + 4 - . + movw r3, :lower16:label3 - . + movw r4, :lower16:label3 + 0x103c - . +// 0x20000 - 0x11028 = :lower16:0xefd8 (61400) +// CHECK: 11028: {{.*}} movw r0, #61400 +// 0x20004 = 0x1102c = :lower16:0xefd8 (61400) +// CHECK: 1102c: {{.*}} movw r1, #61400 +// 0x20008 - 0x11030 + 4 = :lower16:0xefdc (61404) +// CHECK: 11030: {{.*}} movw r2, #61404 +// 0x2fffc - 0x11034 = :lower16:0x1efc8 (61384) +// CHECK: 11034: {{.*}} movw r3, #61384 +// 0x2fffc - 0x11038 +0x103c :lower16:0x20000 (0) +// CHECK: 11038: {{.*}} movw r4, #0 + +.section .R_ARM_MOVT_PREL, "ax",%progbits + movt r0, :upper16:label - . + movt r1, :upper16:label1 - . + movt r2, :upper16:label2 + 0x4 - . + movt r3, :upper16:label3 - . + movt r4, :upper16:label3 + 0x1050 - . +// 0x20000 - 0x1103c = :upper16:0xefc4 = 0 +// CHECK: 1103c: {{.*}} movt r0, #0 +// 0x20004 - 0x11040 = :upper16:0xefc0 = 0 +// CHECK: 11040: {{.*}} movt r1, #0 +// 0x20008 - 0x11044 + 4 = :upper16:0xefc8 = 0 +// CHECK: 11044: {{.*}} movt r2, #0 +// 0x2fffc - 0x11048 = :upper16:0x1efb4 = 1 +// CHECK: 11048: {{.*}} movt r3, #1 +// 0x2fffc - 0x1104c + 0x1050 = :upper16:0x20000 = 2 +// CHECK: 1104c: {{.*}} movt r4, #2 + .section .destination, "aw",%progbits + .balign 65536 +// 0x20000 +label: + .word 0 +// 0x20004 +label1: + .word 1 +// 0x20008 +label2: + .word 2 +// Test label3 is immediately below 2^16 alignment boundary + .space 65536 - 16 +// 0x2fffc +label3: + .word 3 +// label3 + 4 is on a 2^16 alignment boundary + .word 4 diff --git a/test/ELF/arm-plt-reloc.s b/test/ELF/arm-plt-reloc.s new file mode 100644 index 000000000000..0616aa7966a9 --- /dev/null +++ b/test/ELF/arm-plt-reloc.s @@ -0,0 +1,90 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 +// RUN: ld.lld %t1 %t2 -o %t +// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t | FileCheck %s +// RUN: ld.lld -shared %t1 %t2 -o %t3 +// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSO %s +// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s +// REQUIRES: arm +// +// Test PLT entry generation + .syntax unified + .text + .align 2 + .globl _start + .type _start,%function +_start: + b func1 + bl func2 + beq func3 + +// Executable, expect no PLT +// CHECK: Disassembly of section .text: +// CHECK-NEXT: func1: +// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr +// CHECK: func2: +// CHECK-NEXT: 11004: 1e ff 2f e1 bx lr +// CHECK: func3: +// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr +// CHECK: _start: +// CHECK-NEXT: 1100c: fb ff ff ea b #-20 <func1> +// CHECK-NEXT: 11010: fb ff ff eb bl #-20 <func2> +// CHECK-NEXT: 11014: fb ff ff 0a beq #-20 <func3> + +// Expect PLT entries as symbols can be preempted +// DSO: Disassembly of section .text: +// DSO-NEXT: func1: +// DSO-NEXT: 1000: 1e ff 2f e1 bx lr +// DSO: func2: +// DSO-NEXT: 1004: 1e ff 2f e1 bx lr +// DSO: func3: +// DSO-NEXT: 1008: 1e ff 2f e1 bx lr +// DSO: _start: +// S(0x1034) - P(0x100c) + A(-8) = 0x20 = 32 +// DSO-NEXT: 100c: 08 00 00 ea b #32 +// S(0x1044) - P(0x1010) + A(-8) = 0x2c = 44 +// DSO-NEXT: 1010: 0b 00 00 eb bl #44 +// S(0x1054) - P(0x1014) + A(-8) = 0x38 = 56 +// DSO-NEXT: 1014: 0e 00 00 0a beq #56 +// DSO: Disassembly of section .plt: +// DSO-NEXT:.plt: +// DSO-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! +// DSO-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] +// DSO-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr +// DSO-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! +// 0x1028 + 8 + 1fd0 = 0x3000 +// DSO-NEXT: 1030: d0 1f 00 00 +// DSO-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] +// DSO-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc +// DSO-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] +// 0x1038 + 8 + 1fcc = 0x300c +// DSO-NEXT: 1040: cc 1f 00 00 +// DSO-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] +// DSO-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc +// DSO-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] +// 0x1048 + 8 + 1fc0 = 0x3010 +// DSO-NEXT: 1050: c0 1f 00 00 +// DSO-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4] +// DSO-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc +// DSO-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12] +// 0x1058 + 8 + 1fb4 = 0x3014 +// DSO-NEXT: 1060: b4 1f 00 00 + +// DSOREL: Name: .got.plt +// DSOREL-NEXT: Type: SHT_PROGBITS +// DSOREL-NEXT: Flags [ +// DSOREL-NEXT: SHF_ALLOC +// DSOREL-NEXT: SHF_WRITE +// DSOREL-NEXT: ] +// DSOREL-NEXT: Address: 0x3000 +// DSOREL-NEXT: Offset: +// DSOREL-NEXT: Size: 24 +// DSOREL-NEXT: Link: +// DSOREL-NEXT: Info: +// DSOREL-NEXT: AddressAlignment: 4 +// DSOREL-NEXT: EntrySize: +// DSOREL: Relocations [ +// DSOREL-NEXT: Section (4) .rel.plt { +// DSOREL-NEXT: 0x300C R_ARM_JUMP_SLOT func1 0x0 +// DSOREL-NEXT: 0x3010 R_ARM_JUMP_SLOT func2 0x0 +// DSOREL-NEXT: 0x3014 R_ARM_JUMP_SLOT func3 0x0 diff --git a/test/ELF/arm-thumb-blx.s b/test/ELF/arm-thumb-blx.s new file mode 100644 index 000000000000..b581d1dd3acd --- /dev/null +++ b/test/ELF/arm-thumb-blx.s @@ -0,0 +1,85 @@ +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/arm-thumb-blx-targets.s -o %ttarget +// RUN: echo "SECTIONS { \ +// RUN: .R_ARM_CALL24_callee1 : { *(.R_ARM_CALL24_callee_low) } \ +// RUN: .R_ARM_CALL24_callee2 : { *(.R_ARM_CALL24_callee_thumb_low) } \ +// RUN: .caller : { *(.text) } \ +// RUN: .R_ARM_CALL24_callee3 : { *(.R_ARM_CALL24_callee_high) } \ +// RUN: .R_ARM_CALL24_callee4 : { *(.R_ARM_CALL24_callee_thumb_high) } } " > %t.script +// RUN: ld.lld --script %t.script %t %ttarget -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s +// REQUIRES: arm +// Test BLX instruction is chosen for Thumb BL/BLX instruction and ARM callee +// 2 byte nops are used to test the pc-rounding behaviour. As a BLX from a +// 2 byte aligned destination is defined as Align(PC,4) + immediate:00 +// FIXME: llvm-mc has problems assembling BLX unless the destination is +// external. The targets of the BL and BLX instructions are in arm-thumb-blx-target.s + .syntax unified + .section .text, "ax",%progbits + .thumb + .globl _start + .balign 0x10000 + .type _start,%function +_start: + blx callee_low + nop + bl callee_low + nop + blx callee_high + nop + bl callee_high + nop + blx blx_far + nop + bl blx_far + nop +// Expect BLX to thumb target to be written out as a BL + blx callee_thumb_low + nop + blx callee_thumb_high + bx lr + +// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee1: +// CHECK-NEXT-ARM: callee_low: +// CHECK-NEXT-ARM: b4: 1e ff 2f e1 bx lr + +// CHECK-THUMB: Disassembly of section .R_ARM_CALL24_callee2: +// CHECK-NEXT-THUMB: callee_thumb_low: +// CHECK-NEXT-THUMB: 100: 70 47 bx lr + +// CHECK-THUMB: Disassembly of section .caller: +// CHECK-THUMB: _start: +// Align(0x10000,4) - 0xff50 (65360) + 4 = 0xb4 = callee_low +// CHECK-NEXT-THUMB: 10000: f0 f7 58 e8 blx #-65360 +// CHECK-NEXT-THUMB: 10004: 00 bf nop +// Align(0x10006,4) - 0xff54 (65364) + 4 = 0xb4 = callee_low +// CHECK-NEXT-THUMB: 10006: f0 f7 56 e8 blx #-65364 +// CHECK-NEXT-THUMB: 1000a: 00 bf nop +// Align(0x1000c,4) + 0xf0 (240) + 4 = 0x10100 = callee_high +// CHECK-NEXT-THUMB: 1000c: 00 f0 78 e8 blx #240 +// CHECK-NEXT-THUMB: 10010: 00 bf nop +// Align(0x10012,4) + 0xec (236) + 4 = 0x10100 = callee_high +// CHECK-NEXT-THUMB: 10012: 00 f0 76 e8 blx #236 +// CHECK-NEXT-THUMB: 10016: 00 bf nop +// Align(0x10018,4) + 0xfffffc (16777212) = 0x1010018 = blx_far +// CHECK-NEXT-THUMB: 10018: ff f3 fe c7 blx #16777212 +// CHECK-NEXT-THUMB: 1001c: 00 bf nop +// Align(0x1001e,4) + 0xfffff8 (16777208) = 0x1010018 = blx_far +// CHECK-NEXT-THUMB: 1001e: ff f3 fc c7 blx #16777208 +// CHECK-NEXT-THUMB: 10022: 00 bf nop +// 10024 - 0xff28 (65320) + 4 = 0x100 = callee_thumb_low +// CHECK-NEXT-THUMB: 10024: f0 f7 6c f8 bl #-65320 +// CHECK-NEXT-THUMB: 10028: 00 bf nop +// 1002a + 0x1d2 (466) + 4 = 0x10200 = callee_thumb_high +// CHECK-NEXT-THUMB: 1002a: 00 f0 e9 f8 bl #466 +// CHECK-NEXT-THUMB: 1002e: 70 47 bx lr + + +// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee3: +// CHECK-NEXT-ARM: callee_high: +// CHECK-NEXT-ARM: 10100: 1e ff 2f e1 bx lr + +// CHECK: Disassembly of section .R_ARM_CALL24_callee4: +// CHECK-NEXT-THUMB:callee_thumb_high: +// CHECK-NEXT-THUMB: 10200: 70 47 bx lr diff --git a/test/ELF/arm-thumb-branch-error.s b/test/ELF/arm-thumb-branch-error.s new file mode 100644 index 000000000000..de6c1bc16c96 --- /dev/null +++ b/test/ELF/arm-thumb-branch-error.s @@ -0,0 +1,19 @@ +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar +// RUN: not ld.lld %t %tfar -o %t2 2>&1 | FileCheck %s +// REQUIRES: arm + .syntax unified + .section .text, "ax",%progbits + .globl _start + .balign 0x10000 + .type _start,%function +_start: + // address of too_far symbols are just out of range of ARM branch with + // 26-bit immediate field and an addend of -8 + bl too_far1 + b too_far2 + beq.w too_far3 + +// CHECK: R_ARM_THM_CALL out of range +// CHECK-NEXT: R_ARM_THM_JUMP24 out of range +// CHECK-NEXT: R_ARM_THM_JUMP19 out of range diff --git a/test/ELF/arm-thumb-branch.s b/test/ELF/arm-thumb-branch.s new file mode 100644 index 000000000000..94be9ecb6e53 --- /dev/null +++ b/test/ELF/arm-thumb-branch.s @@ -0,0 +1,59 @@ +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar +// RUN: echo "SECTIONS { \ +// RUN: .callee1 : { *(.callee_low) } \ +// RUN: .caller : { *(.text) } \ +// RUN: .callee2 : { *(.callee_high) } } " > %t.script +// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s +// REQUIRES: arm + + .syntax unified + .thumb + .section .callee_low, "ax",%progbits + .align 2 + .type callee_low,%function +callee_low: + bx lr + + .section .text, "ax",%progbits + .globl _start + .balign 0x10000 + .type _start,%function +_start: + bl callee_low + b callee_low + beq callee_low + bl callee_high + b callee_high + bne callee_high + bl far_uncond + b far_uncond + bgt far_cond + bx lr + + .section .callee_high, "ax",%progbits + .align 2 + .type callee_high,%function +callee_high: + bx lr + +// CHECK: Disassembly of section .callee1: +// CHECK-NEXT: callee_low: +// CHECK-NEXT: b4: 70 47 bx lr +// CHECK-NEXT: Disassembly of section .caller: +// CHECK-NEXT: _start: +// CHECK-NEXT: 10000: f0 f7 58 f8 bl #-65360 +// CHECK-NEXT: 10004: f0 f7 56 b8 b.w #-65364 +// CHECK-NEXT: 10008: 30 f4 54 a8 beq.w #-65368 +// CHECK-NEXT: 1000c: 00 f0 0c f8 bl #24 +// CHECK-NEXT: 10010: 00 f0 0a b8 b.w #20 +// CHECK-NEXT: 10014: 40 f0 08 80 bne.w #16 +// CHECK-NEXT: 10018: ff f3 ff d7 bl #16777214 +// CHECK-NEXT: 1001c: ff f3 fd 97 b.w #16777210 +// CHECK-NEXT: 10020: 3f f3 ff af bgt.w #1048574 +// CHECK-NEXT: 10024: 70 47 bx lr +// CHECK-NEXT: 10026: 00 00 movs r0, r0 +// CHECK-NEXT: Disassembly of section .callee2: +// CHECK-NEXT: callee_high: +// CHECK-NEXT: 10028: 70 47 bx lr diff --git a/test/ELF/arm-thumb-interwork-thunk.s b/test/ELF/arm-thumb-interwork-thunk.s new file mode 100644 index 000000000000..6173df3c066b --- /dev/null +++ b/test/ELF/arm-thumb-interwork-thunk.s @@ -0,0 +1,375 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: .R_ARM_JUMP24_callee_1 : { *(.R_ARM_JUMP24_callee_low) } \ +// RUN: .R_ARM_THM_JUMP_callee_1 : { *(.R_ARM_THM_JUMP_callee_low)} \ +// RUN: .text : { *(.text) } \ +// RUN: .arm_caller : { *(.arm_caller) } \ +// RUN: .thumb_caller : { *(.thumb_caller) } \ +// RUN: .R_ARM_JUMP24_callee_2 : { *(.R_ARM_JUMP24_callee_high) } \ +// RUN: .R_ARM_THM_JUMP_callee_2 : { *(.R_ARM_THM_JUMP_callee_high) } } " > %t.script +// RUN: ld.lld --script %t.script %t -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-ABS-THUMB %s +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-ABS-ARM %s +// RUN: ld.lld --script %t.script %t -pie -o %t3 2>&1 +// RUN: ld.lld --script %t.script %t --shared -o %t4 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-THUMB %s +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-ARM %s +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-PLT-THUMB %s +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-PLT-ARM %s +// RUN: llvm-readobj -s -r %t4 | FileCheck -check-prefix=CHECK-DSO-REL %s +// REQUIRES: arm + +// Test ARM Thumb Interworking +// The file is linked and checked 3 times to check the following contexts +// - Absolute executables, absolute Thunks are used. +// - Position independent executables, position independent Thunks are used. +// - Shared object, position independent Thunks to PLT entries are used. + + .syntax unified + +// Target Sections for thunks at a lower address than the callers. +.section .R_ARM_JUMP24_callee_low, "ax", %progbits + .thumb + .balign 0x1000 + .globl thumb_callee1 + .type thumb_callee1, %function +thumb_callee1: + bx lr + +// CHECK-THUMB: Disassembly of section .R_ARM_JUMP24_callee_1: +// CHECK-THUMB: thumb_callee1: +// CHECK-THUMB: 1000: 70 47 bx + .section .R_ARM_THM_JUMP_callee_low, "ax", %progbits + .arm + .balign 0x100 + .globl arm_callee1 + .type arm_callee1, %function +arm_callee1: + bx lr +// Disassembly of section .R_ARM_THM_JUMP_callee_1: +// CHECK-ARM: arm_callee1: +// CHECK-ARM-NEXT: 1100: 1e ff 2f e1 bx lr + + // Calling sections + // At present ARM and Thumb interworking thunks are always added to the calling + // section. + .section .arm_caller, "ax", %progbits + .arm + .balign 0x100 + .globl arm_caller + .type arm_caller, %function +arm_caller: + // If target supports BLX and target is in range we don't need an + // interworking thunk for a BL or BLX instruction. + bl thumb_callee1 + blx thumb_callee1 + // A B instruction can't be transformed into a BLX and needs an interworking + // thunk + b thumb_callee1 + // As long as the thunk is in range it can be reused + b thumb_callee1 + // There can be more than one thunk associated with a section + b thumb_callee2 + b thumb_callee3 + // In range ARM targets do not require interworking thunks + b arm_callee1 + beq arm_callee2 + bne arm_callee3 + bx lr +// CHECK-ABS-ARM: Disassembly of section .arm_caller: +// CHECK-ABS-ARM-NEXT: arm_caller: +// CHECK-ABS-ARM-NEXT: 1300: 3e ff ff fa blx #-776 <thumb_callee1> +// CHECK-ABS-ARM-NEXT: 1304: 3d ff ff fa blx #-780 <thumb_callee1> +// CHECK-ABS-ARM-NEXT: 1308: 06 00 00 ea b #24 <arm_caller+0x28> +// CHECK-ABS-ARM-NEXT: 130c: 05 00 00 ea b #20 <arm_caller+0x28> +// CHECK-ABS-ARM-NEXT: 1310: 07 00 00 ea b #28 <arm_caller+0x34> +// CHECK-ABS-ARM-NEXT: 1314: 09 00 00 ea b #36 <arm_caller+0x40> +// CHECK-ABS-ARM-NEXT: 1318: 78 ff ff ea b #-544 <arm_callee1> +// CHECK-ABS-ARM-NEXT: 131c: b7 00 00 0a beq #732 <arm_callee2> +// CHECK-ABS-ARM-NEXT: 1320: b7 00 00 1a bne #732 <arm_callee3> +// CHECK-ABS-ARM-NEXT: 1324: 1e ff 2f e1 bx lr +// 0x1001 = thumb_callee1 +// CHECK-ABS-ARM-NEXT: 1328: 01 c0 01 e3 movw r12, #4097 +// CHECK-ABS-ARM-NEXT: 132c: 00 c0 40 e3 movt r12, #0 +// CHECK-ABS-ARM-NEXT: 1330: 1c ff 2f e1 bx r12 +// 0x1501 = thumb_callee2 +// CHECK-ABS-ARM-NEXT: 1334: 01 c5 01 e3 movw r12, #5377 +// CHECK-ABS-ARM-NEXT: 1338: 00 c0 40 e3 movt r12, #0 +// CHECK-ABS-ARM-NEXT: 133c: 1c ff 2f e1 bx r12 +// 0x1503 = thumb_callee3 +// CHECK-ABS-ARM-NEXT: 1340: 03 c5 01 e3 movw r12, #5379 +// CHECK-ABS-ARM-NEXT: 1344: 00 c0 40 e3 movt r12, #0 +// CHECK-ABS-ARM-NEXT: 1348: 1c ff 2f e1 bx r12 + +// CHECK-PI-ARM: Disassembly of section .arm_caller: +// CHECK-PI-ARM-NEXT: arm_caller: +// CHECK-PI-ARM-NEXT: 1300: 3e ff ff fa blx #-776 <thumb_callee1> +// CHECK-PI-ARM-NEXT: 1304: 3d ff ff fa blx #-780 <thumb_callee1> +// 0x1308 + 8 + 0x18 = 0x1328 +// CHECK-PI-ARM-NEXT: 1308: 06 00 00 ea b #24 <arm_caller+0x28> +// 0x130c + 8 + 0x14 = 0x1328 +// CHECK-PI-ARM-NEXT: 130c: 05 00 00 ea b #20 <arm_caller+0x28> +// 0x1310 + 8 + 0x20 = 0x1338 +// CHECK-PI-ARM-NEXT: 1310: 08 00 00 ea b #32 <arm_caller+0x38> +// 0x1314 + 8 + 0x2c = 0x1348 +// CHECK-PI-ARM-NEXT: 1314: 0b 00 00 ea b #44 <arm_caller+0x48> +// CHECK-PI-ARM-NEXT: 1318: 78 ff ff ea b #-544 <arm_callee1> +// CHECK-PI-ARM-NEXT: 131c: b7 00 00 0a beq #732 <arm_callee2> +// CHECK-PI-ARM-NEXT: 1320: b7 00 00 1a bne #732 <arm_callee3> +// CHECK-PI-ARM-NEXT: 1324: 1e ff 2f e1 bx lr +// 0x1330 + 8 - 0x337 = 0x1001 = thumb_callee1 +// CHECK-PI-ARM-NEXT: 1328: c9 cc 0f e3 movw r12, #64713 +// CHECK-PI-ARM-NEXT: 132c: ff cf 4f e3 movt r12, #65535 +// CHECK-PI-ARM-NEXT: 1330: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-NEXT: 1334: 1c ff 2f e1 bx r12 +// 0x1340 + 8 + 0x1b9 = 0x1501 +// CHECK-PI-ARM-NEXT: 1338: b9 c1 00 e3 movw r12, #441 +// CHECK-PI-ARM-NEXT: 133c: 00 c0 40 e3 movt r12, #0 +// CHECK-PI-ARM-NEXT: 1340: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-NEXT: 1344: 1c ff 2f e1 bx r12 +// 1350 + 8 + 0x1ab = 0x1503 +// CHECK-PI-ARM-NEXT: 1348: ab c1 00 e3 movw r12, #427 +// CHECK-PI-ARM-NEXT: 134c: 00 c0 40 e3 movt r12, #0 +// CHECK-PI-ARM-NEXT: 1350: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-NEXT: 1354: 1c ff 2f e1 bx r12 + +// All PLT entries are ARM, no need for interworking thunks +// CHECK-PI-ARM-PLT: Disassembly of section .arm_caller: +// CHECK-PI-ARM-PLT-NEXT: arm_caller: +// 0x17e4 PLT(thumb_callee1) +// CHECK-PI-ARM-PLT-NEXT: 1300: 37 01 00 eb bl #1244 +// 0x17e4 PLT(thumb_callee1) +// CHECK-PI-ARM-PLT-NEXT: 1304: 36 01 00 eb bl #1240 +// 0x17e4 PLT(thumb_callee1) +// CHECK-PI-ARM-PLT-NEXT: 1308: 35 01 00 ea b #1236 +// 0x17e4 PLT(thumb_callee1) +// CHECK-PI-ARM-PLT-NEXT: 130c: 34 01 00 ea b #1232 +// 0x17f4 PLT(thumb_callee2) +// CHECK-PI-ARM-PLT-NEXT: 1310: 37 01 00 ea b #1244 +// 0x1804 PLT(thumb_callee3) +// CHECK-PI-ARM-PLT-NEXT: 1314: 3a 01 00 ea b #1256 +// 0x1814 PLT(arm_callee1) +// CHECK-PI-ARM-PLT-NEXT: 1318: 3d 01 00 ea b #1268 +// 0x1824 PLT(arm_callee2) +// CHECK-PI-ARM-PLT-NEXT: 131c: 40 01 00 0a beq #1280 +// 0x1834 PLT(arm_callee3) +// CHECK-PI-ARM-PLT-NEXT: 1320: 43 01 00 1a bne #1292 +// CHECK-PI-ARM-PLT-NEXT: 1324: 1e ff 2f e1 bx lr + + .section .thumb_caller, "ax", %progbits + .balign 0x100 + .thumb + .globl thumb_caller + .type thumb_caller, %function +thumb_caller: + // If target supports BLX and target is in range we don't need an + // interworking thunk for a BL or BLX instruction. + bl arm_callee1 + blx arm_callee1 + // A B instruction can't be transformed into a BLX and needs an interworking + // thunk + b.w arm_callee1 + // As long as the thunk is in range it can be reused + b.w arm_callee2 + // There can be more than one thunk associated with a section + b.w arm_callee3 + // Conditional branches also require interworking thunks, they can use the + // same interworking thunks. + beq.w arm_callee1 + beq.w arm_callee2 + bne.w arm_callee3 +// CHECK-ABS-THUMB: Disassembly of section .thumb_caller: +// CHECK-ABS-THUMB-NEXT: thumb_caller: +// 0x1400 + 4 - 0x304 = 0x1100 = arm_callee1 +// CHECK-ABS-THUMB-NEXT: 1400: ff f7 7e ee blx #-772 +// 0x1404 + 4 - 0x308 = 0x1100 = arm_callee1 +// CHECK-ABS-THUMB-NEXT: 1404: ff f7 7c ee blx #-776 +// 0x1408 + 4 + 0x14 = 0x520 +// CHECK-ABS-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20 +// 0x140c + 4 + 0x1a = 0x52a +// CHECK-ABS-THUMB-NEXT: 140c: 00 f0 0d b8 b.w #26 +// 0x1410 + 4 + 0x20 = 0x534 +// CHECK-ABS-THUMB-NEXT: 1410: 00 f0 10 b8 b.w #32 +// 0x1414 + 4 + 8 = 0x520 +// CHECK-ABS-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8 +// 0x1418 + 4 + 0xe = 0x52a +// CHECK-ABS-THUMB-NEXT: 1418: 00 f0 07 80 beq.w #14 +// 0x141c + 4 + 0x14 = 0x534 +// CHECK-ABS-THUMB-NEXT: 141c: 40 f0 0a 80 bne.w #20 +// 0x1100 = arm_callee1 +// CHECK-ABS-THUMB-NEXT: 1420: 41 f2 00 1c movw r12, #4352 +// CHECK-ABS-THUMB-NEXT: 1424: c0 f2 00 0c movt r12, #0 +// CHECK-ABS-THUMB-NEXT: 1428: 60 47 bx r12 +// 0x1600 = arm_callee2 +// CHECK-ABS-THUMB-NEXT: 142a: 41 f2 00 6c movw r12, #5632 +// CHECK-ABS-THUMB-NEXT: 142e: c0 f2 00 0c movt r12, #0 +// CHECK-ABS-THUMB-NEXT: 1432: 60 47 bx r12 +// 0x1604 = arm_callee3 +// CHECK-ABS-THUMB-NEXT: 1434: 41 f2 04 6c movw r12, #5636 +// CHECK-ABS-THUMB-NEXT: 1438: c0 f2 00 0c movt r12, #0 +// CHECK-ABS-THUMB-NEXT: 143c: 60 47 bx r12 + +// CHECK-PI-THUMB: Disassembly of section .thumb_caller: +// CHECK-PI-THUMB-NEXT: thumb_caller: +// CHECK-PI-THUMB-NEXT: 1400: ff f7 7e ee blx #-772 +// CHECK-PI-THUMB-NEXT: 1404: ff f7 7c ee blx #-776 +// CHECK-PI-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20 +// CHECK-PI-THUMB-NEXT: 140c: 00 f0 0e b8 b.w #28 +// CHECK-PI-THUMB-NEXT: 1410: 00 f0 12 b8 b.w #36 +// CHECK-PI-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8 +// CHECK-PI-THUMB-NEXT: 1418: 00 f0 08 80 beq.w #16 +// CHECK-PI-THUMB-NEXT: 141c: 40 f0 0c 80 bne.w #24 +// 0x1428 + 4 - 0x32c = 0x1100 = arm_callee1 +// CHECK-PI-THUMB-NEXT: 1420: 4f f6 d4 4c movw r12, #64724 +// CHECK-PI-THUMB-NEXT: 1424: cf f6 ff 7c movt r12, #65535 +// CHECK-PI-THUMB-NEXT: 1428: fc 44 add r12, pc +// CHECK-PI-THUMB-NEXT: 142a: 60 47 bx r12 +// 0x1434 + 4 + 0x1c8 = 0x1600 = arm_callee2 +// CHECK-PI-THUMB-NEXT: 142c: 40 f2 c8 1c movw r12, #456 +// CHECK-PI-THUMB-NEXT: 1430: c0 f2 00 0c movt r12, #0 +// CHECK-PI-THUMB-NEXT: 1434: fc 44 add r12, pc +// CHECK-PI-THUMB-NEXT: 1436: 60 47 bx r12 +// 0x1440 + 4 + 0x1c0 = 0x1604 = arm_callee3 +// CHECK-PI-THUMB-NEXT: 1438: 40 f2 c0 1c movw r12, #448 +// CHECK-PI-THUMB-NEXT: 143c: c0 f2 00 0c movt r12, #0 +// CHECK-PI-THUMB-NEXT: 1440: fc 44 add r12, pc +// CHECK-PI-THUMB-NEXT: 1442: 60 47 bx r12 + +// CHECK-PI-THUMB-PLT: Disassembly of section .arm_caller: +// CHECK-PI-THUMB-PLT-NEXT: thumb_caller: +// 0x1400 + 4 + 0x410 = 0x1814 = PLT(arm_callee1) +// CHECK-PI-THUMB-PLT-NEXT: 1400: 00 f0 08 ea blx #1040 +// 0x1404 + 4 + 0x40c = 0x1814 = PLT(arm_callee1) +// CHECK-PI-THUMB-PLT-NEXT: 1404: 00 f0 06 ea blx #1036 +// 0x1408 + 4 + 0x14 = 0x1420 = IWV(PLT(arm_callee1) +// CHECK-PI-THUMB-PLT-NEXT: 1408: 00 f0 0a b8 b.w #20 +// 0x140c + 4 + 0x1c = 0x142c = IWV(PLT(arm_callee2) +// CHECK-PI-THUMB-PLT-NEXT: 140c: 00 f0 0e b8 b.w #28 +// 0x1410 + 4 + 0x24 = 0x1438 = IWV(PLT(arm_callee3) +// CHECK-PI-THUMB-PLT-NEXT: 1410: 00 f0 12 b8 b.w #36 +// 0x1414 + 4 + 8 = 0x1420 = IWV(PLT(arm_callee1) +// CHECK-PI-THUMB-PLT-NEXT: 1414: 00 f0 04 80 beq.w #8 +// 0x1418 + 4 + 0x10 = 0x142c = IWV(PLT(arm_callee2) +// CHECK-PI-THUMB-PLT-NEXT: 1418: 00 f0 08 80 beq.w #16 +// 0x141c + 4 + 0x18 = 0x1438 = IWV(PLT(arm_callee3) +// CHECK-PI-THUMB-PLT-NEXT: 141c: 40 f0 0c 80 bne.w #24 +// 0x1428 + 4 + 0x3e8 = 0x1814 = PLT(arm_callee1) +// CHECK-PI-THUMB-PLT-NEXT: 1420: 40 f2 e8 3c movw r12, #1000 +// CHECK-PI-THUMB-PLT-NEXT: 1424: c0 f2 00 0c movt r12, #0 +// CHECK-PI-THUMB-PLT-NEXT: 1428: fc 44 add r12, pc +// CHECK-PI-THUMB-PLT-NEXT: 142a: 60 47 bx r12 +// 0x1434 + 4 + 0x3ec = 0x1824 = PLT(arm_callee2) +// CHECK-PI-THUMB-PLT-NEXT: 142c: 40 f2 ec 3c movw r12, #1004 +// CHECK-PI-THUMB-PLT-NEXT: 1430: c0 f2 00 0c movt r12, #0 +// CHECK-PI-THUMB-PLT-NEXT: 1434: fc 44 add r12, pc +// CHECK-PI-THUMB-PLT-NEXT: 1436: 60 47 bx r12 +// 0x1440 + 4 + 0x3f0 = 0x1834 = PLT(arm_callee3) +// CHECK-PI-THUMB-PLT-NEXT: 1438: 40 f2 f0 3c movw r12, #1008 +// CHECK-PI-THUMB-PLT-NEXT: 143c: c0 f2 00 0c movt r12, #0 +// CHECK-PI-THUMB-PLT-NEXT: 1440: fc 44 add r12, pc +// CHECK-PI-THUMB-PLT-NEXT: 1442: 60 47 bx r12 + +// Target Sections for thunks at a higher address than the callers. +.section .R_ARM_JUMP24_callee_high, "ax", %progbits + .thumb + .balign 0x100 + .globl thumb_callee2 + .type thumb_callee2, %function +thumb_callee2: + bx lr + + .globl thumb_callee3 + .type thumb_callee3, %function +thumb_callee3: + bx lr +// CHECK-THUMB: Disassembly of section .R_ARM_JUMP24_callee_2: +// CHECK-THUMB-NEXT: thumb_callee2: +// CHECK-THUMB-NEXT: 1500: 70 47 bx lr +// CHECK-THUMB: thumb_callee3: +// CHECK-THUMB-NEXT: 1502: 70 47 bx lr + + .section .R_ARM_THM_JUMP_callee_high, "ax", %progbits + .arm + .balign 0x100 + .globl arm_callee2 + .type arm_callee2, %function +arm_callee2: + bx lr + .globl arm_callee3 + .type arm_callee3, %function +arm_callee3: + bx lr +// CHECK-ARM: Disassembly of section .R_ARM_THM_JUMP_callee_2: +// CHECK-ARM-NEXT: arm_callee2: +// CHECK-ARM-NEXT: 1600: 1e ff 2f e1 bx lr +// CHECK-ARM: arm_callee3: +// CHECK-ARM-NEXT: 1604: 1e ff 2f e1 bx lr + +// _start section just calls the arm and thumb calling sections + .text + .arm + .globl _start + .balign 0x100 + .type _start, %function +_start: + bl arm_caller + bl thumb_caller + bx lr + + +// CHECK-PI-ARM-PLT: Disassembly of section .plt: +// CHECK-PI-ARM-PLT-NEXT: .plt: +// CHECK-PI-ARM-PLT-NEXT: 17b0: 04 e0 2d e5 str lr, [sp, #-4]! +// CHECK-PI-ARM-PLT-NEXT: 17b4: 04 e0 9f e5 ldr lr, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 17b8: 0e e0 8f e0 add lr, pc, lr +// CHECK-PI-ARM-PLT-NEXT: 17bc: 08 f0 be e5 ldr pc, [lr, #8]! +// CHECK-PI-ARM-PLT-NEXT: 17c0: d4 00 00 00 +// 0x17c8 + 8 + 0xd0 = 0x18a0 arm_caller +// CHECK-PI-ARM-PLT-NEXT: 17c4: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 17c8: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-PLT-NEXT: 17cc: 00 f0 9c e5 ldr pc, [r12] +// CHECK-PI-ARM-PLT-NEXT: 17d0: d0 00 00 00 +// 0x17d8 + 8 + 0xc4 = 0x18a4 thumb_caller +// CHECK-PI-ARM-PLT-NEXT: 17d4: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 17d8: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-PLT-NEXT: 17dc: 00 f0 9c e5 ldr pc, [r12] +// CHECK-PI-ARM-PLT-NEXT: 17e0: c4 00 00 00 +// 0x17e8 + 8 + 0xb8 = 0x18a8 thumb_callee1 +// CHECK-PI-ARM-PLT-NEXT: 17e4: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 17e8: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-PLT-NEXT: 17ec: 00 f0 9c e5 ldr pc, [r12] +// CHECK-PI-ARM-PLT-NEXT: 17f0: b8 00 00 00 +// 0x17f8 + 8 + 0xac = 0x18ac thumb_callee2 +// CHECK-PI-ARM-PLT-NEXT: 17f4: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 17f8: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-PLT-NEXT: 17fc: 00 f0 9c e5 ldr pc, [r12] +// CHECK-PI-ARM-PLT-NEXT: 1800: ac 00 00 00 +// 0x1808 + 8 + 0xa0 = 0x18b0 thumb_callee3 +// CHECK-PI-ARM-PLT-NEXT: 1804: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 1808: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-PLT-NEXT: 180c: 00 f0 9c e5 ldr pc, [r12] +// CHECK-PI-ARM-PLT-NEXT: 1810: a0 00 00 00 +// 0x1818 + 8 + 0x94 = 0x18b4 arm_callee1 +// CHECK-PI-ARM-PLT-NEXT: 1814: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 1818: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-PLT-NEXT: 181c: 00 f0 9c e5 ldr pc, [r12] +// CHECK-PI-ARM-PLT-NEXT: 1820: 94 00 00 00 +// 0x1828 + 8 + 0x88 = 0x18b8 arm_callee2 +// CHECK-PI-ARM-PLT-NEXT: 1824: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 1828: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-PLT-NEXT: 182c: 00 f0 9c e5 ldr pc, [r12] +// CHECK-PI-ARM-PLT-NEXT: 1830: 88 00 00 00 +// 0x1838 + 8 + 0x7c = 0x18bc arm_callee3 +// CHECK-PI-ARM-PLT-NEXT: 1834: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECK-PI-ARM-PLT-NEXT: 1838: 0f c0 8c e0 add r12, r12, pc +// CHECK-PI-ARM-PLT-NEXT: 183c: 00 f0 9c e5 ldr pc, [r12] +// CHECK-PI-ARM-PLT-NEXT: 1840: 7c 00 00 00 + +// CHECK-DSO-REL: 0x18A0 R_ARM_JUMP_SLOT arm_caller +// CHECK-DSO-REL-NEXT: 0x18A4 R_ARM_JUMP_SLOT thumb_caller +// CHECK-DSO-REL-NEXT: 0x18A8 R_ARM_JUMP_SLOT thumb_callee1 +// CHECK-DSO-REL-NEXT: 0x18AC R_ARM_JUMP_SLOT thumb_callee2 +// CHECK-DSO-REL-NEXT: 0x18B0 R_ARM_JUMP_SLOT thumb_callee3 +// CHECK-DSO-REL-NEXT: 0x18B4 R_ARM_JUMP_SLOT arm_callee1 +// CHECK-DSO-REL-NEXT: 0x18B8 R_ARM_JUMP_SLOT arm_callee2 +// CHECK-DSO-REL-NEXT: 0x18BC R_ARM_JUMP_SLOT arm_callee3 diff --git a/test/ELF/arm-thumb-narrow-branch-check.s b/test/ELF/arm-thumb-narrow-branch-check.s new file mode 100644 index 000000000000..b601b6d5dc26 --- /dev/null +++ b/test/ELF/arm-thumb-narrow-branch-check.s @@ -0,0 +1,72 @@ +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: .R_ARM_PC11_1 : { *(.R_ARM_PC11_1) } \ +// RUN: .caller : { *(.caller) } \ +// RUN: .R_ARM_PC11_2 : { *(.R_ARM_PC11_2) } \ +// RUN: .text : { *(.text) } } " > %t.script +// RUN: ld.lld --script %t.script %t %S/Inputs/arm-thumb-narrow-branch.o -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s +// REQUIRES: arm + +// Test the R_ARM_PC11 relocation which is used with the narrow encoding of B.N +// the source of these relocations is a binary file arm-thumb-narrow-branch.o +// which has been assembled with the GNU assembler as llvm-mc doesn't emit it +// as the range of +-2048 bytes is too small to be practically useful for out +// of section branches. + .syntax unified + +.global callee_low_far +.type callee_low_far,%function +callee_low_far = 0x809 + + .section .R_ARM_PC11_1,"ax",%progbits + .thumb + .balign 0x1000 + .type callee_low,%function + .globl callee_low +callee_low: + bx lr + + .text + .align 2 + .thumb + .globl _start + .type _start, %function +_start: + bl callers + bx lr + + .section .R_ARM_PC11_2,"ax",%progbits + .thumb + .align 2 + .type callee_high,%function + .globl callee_high +callee_high: + bx lr + +.global callee_high_far +.type callee_high_far,%function +callee_high_far = 0x180d + +// CHECK: Disassembly of section .R_ARM_PC11_1: +// CHECK-NEXT: callee_low: +// CHECK-NEXT: 1000: 70 47 bx lr +// CHECK-NEXT: Disassembly of section .caller: +// CHECK-NEXT: callers: +// 1004 - 0x800 (2048) + 4 = 0x808 = callee_low_far +// CHECK-NEXT: 1004: 00 e4 b #-2048 +// 1006 - 0xa (10) + 4 = 0x1000 = callee_low +// CHECK-NEXT: 1006: fb e7 b #-10 +// 1008 + 4 + 4 = 0x1010 = callee_high +// CHECK-NEXT: 1008: 02 e0 b #4 +// 100a + 0x7fe (2046) + 4 = 0x180c = callee_high_far +// CHECK-NEXT: 100a: ff e3 b #2046 +// CHECK-NEXT: 100c: 70 47 bx lr +// CHECK-NEXT: 100e: 00 bf nop +// CHECK-NEXT: Disassembly of section .R_ARM_PC11_2: +// CHECK-NEXT: callee_high: +// CHECK-NEXT: 1010: 70 47 bx lr +// CHECK-NEXT: Disassembly of section .text: +// CHECK-NEXT: _start: +// CHECK-NEXT: 1014: ff f7 f6 ff bl #-20 +// CHECK-NEXT: 1018: 70 47 bx lr diff --git a/test/ELF/arm-thumb-plt-reloc.s b/test/ELF/arm-thumb-plt-reloc.s new file mode 100644 index 000000000000..6294e909f078 --- /dev/null +++ b/test/ELF/arm-thumb-plt-reloc.s @@ -0,0 +1,101 @@ +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1 +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2 +// RUN: ld.lld %t1 %t2 -o %t +// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t | FileCheck %s +// RUN: ld.lld -shared %t1 %t2 -o %t3 +// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s +// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s +// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s +// REQUIRES: arm +// +// Test PLT entry generation + .syntax unified + .text + .align 2 + .globl _start + .type _start,%function +_start: +// FIXME, interworking is only supported for BL via BLX at the moment, when +// interworking thunks are available for b.w and b<cond>.w this can be altered +// to test the different forms of interworking. + bl func1 + bl func2 + bl func3 + +// Executable, expect no PLT +// CHECK: Disassembly of section .text: +// CHECK-NEXT: func1: +// CHECK-NEXT: 11000: 70 47 bx lr +// CHECK: func2: +// CHECK-NEXT: 11002: 70 47 bx lr +// CHECK: func3: +// CHECK-NEXT: 11004: 70 47 bx lr +// CHECK-NEXT: 11006: 00 00 movs r0, r0 +// CHECK: _start: +// 11008 + 4 -12 = 0x11000 = func1 +// CHECK-NEXT: 11008: ff f7 fa ff bl #-12 +// 1100c + 4 -14 = 0x11002 = func2 +// CHECK-NEXT: 1100c: ff f7 f9 ff bl #-14 +// 11010 + 4 -16 = 0x11004 = func3 +// CHECK-NEXT: 11010: ff f7 f8 ff bl #-16 + +// Expect PLT entries as symbols can be preempted +// .text is Thumb and .plt is ARM, llvm-objdump can currently only disassemble +// as ARM or Thumb. Work around by disassembling twice. +// DSOTHUMB: Disassembly of section .text: +// DSOTHUMB: func1: +// DSOTHUMB-NEXT: 1000: 70 47 bx lr +// DSOTHUMB: func2: +// DSOTHUMB-NEXT: 1002: 70 47 bx lr +// DSOTHUMB: func3: +// DSOTHUMB-NEXT: 1004: 70 47 bx lr +// DSOTHUMB-NEXT: 1006: 00 00 movs r0, r0 +// DSOTHUMB: _start: +// 0x1008 + 0x28 + 4 = 0x1034 = PLT func1 +// DSOTHUMB-NEXT: 1008: 00 f0 14 e8 blx #40 +// 0x100c + 0x34 + 4 = 0x1044 = PLT func2 +// DSOTHUMB-NEXT: 100c: 00 f0 1a e8 blx #52 +// 0x1010 + 0x40 + 4 = 0x1054 = PLT func3 +// DSOTHUMB-NEXT: 1010: 00 f0 20 e8 blx #64 +// DSOARM: Disassembly of section .plt: +// DSOARM: .plt: +// DSOARM-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! +// DSOARM-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] +// DSOARM-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr +// DSOARM-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! +// DSOARM-NEXT: 1030: d0 1f 00 00 +// 0x1028 + 8 + 1fd0 = 0x3000 +// DSOARM-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] +// DSOARM-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc +// DSOARM-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] +// DSOARM-NEXT: 1040: cc 1f 00 00 +// 0x1038 + 8 + 1fcc = 0x300c +// DSOARM-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] +// DSOARM-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc +// DSOARM-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] +// DSOARM-NEXT: 1050: c0 1f 00 00 +// 0x1048 + 8 + 1fc0 = 0x3010 +// DSOARM-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4] +// DSOARM-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc +// DSOARM-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12] +// DSOARM-NEXT: 1060: b4 1f 00 00 +// 0x1058 + 8 + 1fb4 = 0x3014 + +// DSOREL: Name: .got.plt +// DSOREL-NEXT: Type: SHT_PROGBITS +// DSOREL-NEXT: Flags [ +// DSOREL-NEXT: SHF_ALLOC +// DSOREL-NEXT: SHF_WRITE +// DSOREL-NEXT: ] +// DSOREL-NEXT: Address: 0x3000 +// DSOREL-NEXT: Offset: +// DSOREL-NEXT: Size: 24 +// DSOREL-NEXT: Link: +// DSOREL-NEXT: Info: +// DSOREL-NEXT: AddressAlignment: 4 +// DSOREL-NEXT: EntrySize: +// DSOREL: Relocations [ +// DSOREL-NEXT: Section (4) .rel.plt { +// DSOREL-NEXT: 0x300C R_ARM_JUMP_SLOT func1 0x0 +// DSOREL-NEXT: 0x3010 R_ARM_JUMP_SLOT func2 0x0 +// DSOREL-NEXT: 0x3014 R_ARM_JUMP_SLOT func3 0x0 diff --git a/test/ELF/as-needed-no-reloc.s b/test/ELF/as-needed-no-reloc.s new file mode 100644 index 000000000000..0706ca0a932d --- /dev/null +++ b/test/ELF/as-needed-no-reloc.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t2.so +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -o %t %t.o --as-needed %t2.so +# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s + + +# There must be a NEEDED entry for each undefined + +# CHECK: Name: bar +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined + +# CHECK: NEEDED SharedLibrary ({{.*}}2.so) + + .globl _start +_start: + .global bar diff --git a/test/ELF/as-needed.s b/test/ELF/as-needed.s index 2c5174d54077..4f1a48abac36 100644 --- a/test/ELF/as-needed.s +++ b/test/ELF/as-needed.s @@ -20,11 +20,11 @@ /// GROUP directive is the same as --as-needed. -// RUN: echo "GROUP(" %t2.so %t3.so %t4.so ")" > %t.script +// RUN: echo "GROUP(\"%t2.so\" \"%t3.so\" \"%t4.so\")" > %t.script // RUN: ld.lld %t.o %t.script -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s -// RUN: echo "GROUP(AS_NEEDED(" %t2.so %t3.so %t4.so "))" > %t.script +// RUN: echo "GROUP(AS_NEEDED(\"%t2.so\" \"%t3.so\" \"%t4.so\"))" > %t.script // RUN: ld.lld %t.o %t.script -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s @@ -38,6 +38,7 @@ .global _start _start: +.data .long bar .long zed .weak baz diff --git a/test/ELF/avoid-empty-program-headers.s b/test/ELF/avoid-empty-program-headers.s new file mode 100644 index 000000000000..f7315677e1a3 --- /dev/null +++ b/test/ELF/avoid-empty-program-headers.s @@ -0,0 +1,78 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: ld.lld %t -o %tout +// RUN: llvm-readobj -program-headers %tout | FileCheck %s + +.global _start +_start: + retq + +.section .tbss,"awT",@nobits + .zero 4 +// FIXME: Test that we don't create unecessary empty PT_LOAD and PT_GNU_RELRO +// for the .tbss section. + +// CHECK: ProgramHeaders [ +// CHECK-NEXT: ProgramHeader { +// CHECK-NEXT: Type: PT_PHDR (0x6) +// CHECK-NEXT: Offset: 0x40 +// CHECK-NEXT: VirtualAddress: 0x10040 +// CHECK-NEXT: PhysicalAddress: 0x10040 +// CHECK-NEXT: FileSize: 280 +// CHECK-NEXT: MemSize: 280 +// CHECK-NEXT: Flags [ (0x4) +// CHECK-NEXT: PF_R (0x4) +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 8 +// CHECK-NEXT: } +// CHECK-NEXT: ProgramHeader { +// CHECK-NEXT: Type: PT_LOAD (0x1) +// CHECK-NEXT: Offset: 0x0 +// CHECK-NEXT: VirtualAddress: 0x10000 +// CHECK-NEXT: PhysicalAddress: 0x10000 +// CHECK-NEXT: FileSize: 344 +// CHECK-NEXT: MemSize: 344 +// CHECK-NEXT: Flags [ (0x4) +// CHECK-NEXT: PF_R (0x4) +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 4096 +// CHECK-NEXT: } +// CHECK-NEXT: ProgramHeader { +// CHECK-NEXT: Type: PT_LOAD (0x1) +// CHECK-NEXT: Offset: 0x1000 +// CHECK-NEXT: VirtualAddress: 0x11000 +// CHECK-NEXT: PhysicalAddress: 0x11000 +// CHECK-NEXT: FileSize: 1 +// CHECK-NEXT: MemSize: 1 +// CHECK-NEXT: Flags [ (0x5) +// CHECK-NEXT: PF_R (0x4) +// CHECK-NEXT: PF_X (0x1) +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 4096 +// CHECK-NEXT: } +// CHECK-NEXT: ProgramHeader { +// CHECK-NEXT: Type: PT_TLS (0x7) +// CHECK-NEXT: Offset: 0x1001 +// CHECK-NEXT: VirtualAddress: 0x11001 +// CHECK-NEXT: PhysicalAddress: 0x11001 +// CHECK-NEXT: FileSize: 0 +// CHECK-NEXT: MemSize: 4 +// CHECK-NEXT: Flags [ (0x4) +// CHECK-NEXT: PF_R (0x4) +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 1 +// CHECK-NEXT: } +// CHECK-NEXT: ProgramHeader { +// CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) +// CHECK-NEXT: Offset: 0x0 +// CHECK-NEXT: VirtualAddress: 0x0 +// CHECK-NEXT: PhysicalAddress: 0x0 +// CHECK-NEXT: FileSize: 0 +// CHECK-NEXT: MemSize: 0 +// CHECK-NEXT: Flags [ (0x6) +// CHECK-NEXT: PF_R (0x4) +// CHECK-NEXT: PF_W (0x2) +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 0 +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/basic-aarch64.s b/test/ELF/basic-aarch64.s index 61b6707e49a4..84105f0acdb7 100644 --- a/test/ELF/basic-aarch64.s +++ b/test/ELF/basic-aarch64.s @@ -5,7 +5,7 @@ # REQUIRES: aarch64 # exits with return code 42 on FreeBSD/AArch64 -.globl _start; +.globl _start _start: mov x0, 42 mov x8, 1 diff --git a/test/ELF/basic-mips.s b/test/ELF/basic-mips.s index 7b2ef564f1ce..c598c7b5f2f7 100644 --- a/test/ELF/basic-mips.s +++ b/test/ELF/basic-mips.s @@ -27,7 +27,7 @@ __start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: 0x20000 # CHECK-NEXT: ProgramHeaderOffset: 0x34 -# CHECK-NEXT: SectionHeaderOffset: 0x20084 +# CHECK-NEXT: SectionHeaderOffset: 0x30088 # CHECK-NEXT: Flags [ # CHECK-NEXT: EF_MIPS_ABI_O32 # CHECK-NEXT: EF_MIPS_ARCH_32R2 @@ -35,10 +35,10 @@ __start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 52 # CHECK-NEXT: ProgramHeaderEntrySize: 32 -# CHECK-NEXT: ProgramHeaderCount: 5 +# CHECK-NEXT: ProgramHeaderCount: 6 # CHECK-NEXT: SectionHeaderEntrySize: 40 -# CHECK-NEXT: SectionHeaderCount: 9 -# CHECK-NEXT: StringTableSectionIndex: 7 +# CHECK-NEXT: SectionHeaderCount: 10 +# CHECK-NEXT: StringTableSectionIndex: 8 # CHECK-NEXT: } # CHECK-NEXT: Sections [ # CHECK-NEXT: Section { @@ -62,8 +62,8 @@ __start: # CHECK-NEXT: Flags [ (0x2) # CHECK-NEXT: SHF_ALLOC (0x2) # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x100D4 -# CHECK-NEXT: Offset: 0xD4 +# CHECK-NEXT: Address: 0x100F4 +# CHECK-NEXT: Offset: 0xF4 # CHECK-NEXT: Size: 24 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -77,8 +77,8 @@ __start: # CHECK-NEXT: Flags [ (0x2) # CHECK-NEXT: SHF_ALLOC (0x2) # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x100F0 -# CHECK-NEXT: Offset: 0xF0 +# CHECK-NEXT: Address: 0x10110 +# CHECK-NEXT: Offset: 0x110 # CHECK-NEXT: Size: 24 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -103,14 +103,31 @@ __start: # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 4 -# CHECK-NEXT: Name: .data +# CHECK-NEXT: Name: .got (31) # CHECK-NEXT: Type: SHT_PROGBITS (0x1) -# CHECK-NEXT: Flags [ (0x3) +# CHECK-NEXT: Flags [ (0x10000003) # CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: SHF_MIPS_GPREL (0x10000000) # CHECK-NEXT: SHF_WRITE (0x1) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x30000 # CHECK-NEXT: Offset: 0x20000 +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 5 +# CHECK-NEXT: Name: .data +# CHECK-NEXT: Type: SHT_PROGBITS (0x1) +# CHECK-NEXT: Flags [ (0x3) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: SHF_WRITE (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x40000 +# CHECK-NEXT: Offset: 0x30000 # CHECK-NEXT: Size: 0 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -118,15 +135,15 @@ __start: # CHECK-NEXT: EntrySize: 0 # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 5 -# CHECK-NEXT: Name: .bss (37) +# CHECK-NEXT: Index: 6 +# CHECK-NEXT: Name: .bss # CHECK-NEXT: Type: SHT_NOBITS (0x8) # CHECK-NEXT: Flags [ (0x3) # CHECK-NEXT: SHF_ALLOC (0x2) # CHECK-NEXT: SHF_WRITE (0x1) # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x30000 -# CHECK-NEXT: Offset: 0x20000 +# CHECK-NEXT: Address: 0x40000 +# CHECK-NEXT: Offset: 0x30000 # CHECK-NEXT: Size: 0 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -134,41 +151,41 @@ __start: # CHECK-NEXT: EntrySize: 0 # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 6 +# CHECK-NEXT: Index: 7 # CHECK-NEXT: Name: .symtab # CHECK-NEXT: Type: SHT_SYMTAB (0x2) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x20000 +# CHECK-NEXT: Offset: 0x30000 # CHECK-NEXT: Size: 48 -# CHECK-NEXT: Link: 8 +# CHECK-NEXT: Link: 9 # CHECK-NEXT: Info: 1 # CHECK-NEXT: AddressAlignment: 4 # CHECK-NEXT: EntrySize: 16 # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 7 +# CHECK-NEXT: Index: 8 # CHECK-NEXT: Name: .shstrtab # CHECK-NEXT: Type: SHT_STRTAB (0x3) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x20030 -# CHECK-NEXT: Size: 68 +# CHECK-NEXT: Offset: 0x30030 +# CHECK-NEXT: Size: 73 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 # CHECK-NEXT: EntrySize: 0 # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 8 -# CHECK-NEXT: Name: .strtab (60) +# CHECK-NEXT: Index: 9 +# CHECK-NEXT: Name: .strtab # CHECK-NEXT: Type: SHT_STRTAB (0x3) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x20074 +# CHECK-NEXT: Offset: 0x30079 # CHECK-NEXT: Size: 13 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -188,12 +205,14 @@ __start: # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: _gp -# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Value: 0x37FF0 # CHECK-NEXT: Size: 0 -# CHECK-NEXT: Binding: Local (0x0) +# CHECK-NEXT: Binding: Local # CHECK-NEXT: Type: None (0x0) -# CHECK-NEXT: Other: 0 -# CHECK-NEXT: Section: Absolute (0xFFF1) +# CHECK-NEXT: Other [ (0x2) +# CHECK-NEXT: STV_HIDDEN (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Section: .got # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: __start @@ -211,20 +230,20 @@ __start: # CHECK-NEXT: Offset: 0x34 # CHECK-NEXT: VirtualAddress: 0x10034 # CHECK-NEXT: PhysicalAddress: 0x10034 -# CHECK-NEXT: FileSize: 160 -# CHECK-NEXT: MemSize: 160 +# CHECK-NEXT: FileSize: 192 +# CHECK-NEXT: MemSize: 192 # CHECK-NEXT: Flags [ (0x4) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: ] -# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: Alignment: 4 # CHECK-NEXT: } # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x10000 # CHECK-NEXT: PhysicalAddress: 0x10000 -# CHECK-NEXT: FileSize: 264 -# CHECK-NEXT: MemSize: 264 +# CHECK-NEXT: FileSize: 296 +# CHECK-NEXT: MemSize: 296 # CHECK-NEXT: Flags [ (0x4) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: ] @@ -248,8 +267,8 @@ __start: # CHECK-NEXT: Offset: 0x20000 # CHECK-NEXT: VirtualAddress: 0x30000 # CHECK-NEXT: PhysicalAddress: 0x30000 -# CHECK-NEXT: FileSize: 0 -# CHECK-NEXT: MemSize: 0 +# CHECK-NEXT: FileSize: 65536 +# CHECK-NEXT: MemSize: 65536 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R # CHECK-NEXT: PF_W @@ -257,6 +276,18 @@ __start: # CHECK-NEXT: Alignment: 65536 # CHECK-NEXT: } # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_GNU_RELRO (0x6474E552) +# CHECK-NEXT: Offset: 0x20000 +# CHECK-NEXT: VirtualAddress: 0x30000 +# CHECK-NEXT: PhysicalAddress: 0x30000 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 1 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_GNU_STACK # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x0 diff --git a/test/ELF/basic-ppc.s b/test/ELF/basic-ppc.s index 90acd8d8ddac..83ace9a4983d 100644 --- a/test/ELF/basic-ppc.s +++ b/test/ELF/basic-ppc.s @@ -28,7 +28,7 @@ // CHECK-NEXT: Version: 1 // CHECK-NEXT: Entry: 0x0 // CHECK-NEXT: ProgramHeaderOffset: 0x34 -// CHECK-NEXT: SectionHeaderOffset: 0x2084 +// CHECK-NEXT: SectionHeaderOffset: 0x209C // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: HeaderSize: 52 @@ -157,13 +157,14 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 // CHECK-NEXT: Offset: 0x2030 -// CHECK-NEXT: Size: 16 +// CHECK-NEXT: Size: 32 // CHECK-NEXT: Link: 8 // CHECK-NEXT: Info: 1 // CHECK-NEXT: AddressAlignment: 4 // CHECK-NEXT: EntrySize: 16 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................| +// CHECK-NEXT: 0010: 00000001 00002000 00000000 00020005 |...... .........| // CHECK-NEXT: ) // CHECK-NEXT: } // CHECK-NEXT: Section { @@ -173,7 +174,7 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x2040 +// CHECK-NEXT: Offset: 0x2050 // CHECK-NEXT: Size: 64 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 @@ -193,14 +194,14 @@ // CHECK-NEXT: Flags [ (0x0) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 -// CHECK-NEXT: Offset: 0x2080 +// CHECK-NEXT: Offset: 0x2090 // CHECK-NEXT: Size: 1 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( -// CHECK-NEXT: 0000: 00 |.| +// CHECK-NEXT: 0000: 005F4459 4E414D49 4300 |._DYNAMIC.| // CHECK-NEXT: ) // CHECK-NEXT: } // CHECK-NEXT: ] @@ -215,7 +216,7 @@ // CHECK-NEXT: Flags [ (0x4) // CHECK-NEXT: PF_R (0x4) // CHECK-NEXT: ] -// CHECK-NEXT: Alignment: 8 +// CHECK-NEXT: Alignment: 4 // CHECK-NEXT: } // CHECK-NEXT: ProgramHeader { // CHECK-NEXT: Type: PT_LOAD (0x1) diff --git a/test/ELF/basic.s b/test/ELF/basic.s index bbc674ced2ed..28449331d3fa 100644 --- a/test/ELF/basic.s +++ b/test/ELF/basic.s @@ -6,7 +6,7 @@ # RUN: | FileCheck %s # exits with return code 42 on linux -.globl _start; +.globl _start _start: mov $60, %rax mov $42, %rdi @@ -184,12 +184,23 @@ _start: # CHECK-NEXT: } # CHECK-NEXT: ] -# Test for the response file +# Test for the response file (POSIX quoting style) # RUN: echo " -o %t2" > %t.responsefile -# RUN: ld.lld %t @%t.responsefile +# RUN: ld.lld %t --rsp-quoting=posix @%t.responsefile # RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \ # RUN: | FileCheck %s +# Test for the response file (Windows quoting style) +# RUN: echo " c:\blah\foo" > %t.responsefile +# RUN: not ld.lld --rsp-quoting=windows %t @%t.responsefile 2>&1 | FileCheck \ +# RUN: %s --check-prefix=WINRSP +# WINRSP: cannot open c:\blah\foo + +# Test for the response file (invalid quoting style) +# RUN: not ld.lld --rsp-quoting=patatino %t 2>&1 | FileCheck %s \ +# RUN: --check-prefix=INVRSP +# INVRSP: invalid response file quoting: patatino + # RUN: not ld.lld %t.foo -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=MISSING %s # MISSING: cannot open {{.*}}.foo: {{[Nn]}}o such file or directory @@ -213,4 +224,7 @@ _start: # DUP: duplicate symbol: _start in {{.*}} and {{.*}} # RUN: not ld.lld %t -o %t -m wrong_emul 2>&1 | FileCheck --check-prefix=UNKNOWN_EMUL %s -# UNKNOWN_EMUL: Unknown emulation: wrong_emul +# UNKNOWN_EMUL: unknown emulation: wrong_emul + +# RUN: not ld.lld %t --lto-jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s +# NOTHREADS: number of threads must be > 0 diff --git a/test/ELF/basic32.s b/test/ELF/basic32.s index f4f9c410a048..44ebe7a46225 100644 --- a/test/ELF/basic32.s +++ b/test/ELF/basic32.s @@ -4,7 +4,7 @@ # REQUIRES: x86 # exits with return code 42 on linux -.globl _start; +.globl _start _start: mov $1, %eax mov $42, %ebx @@ -120,7 +120,7 @@ _start: # CHECK-NEXT: Flags [ (0x4) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: ] -# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: Alignment: 4 # CHECK-NEXT: } # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD (0x1) diff --git a/test/ELF/basic64be.s b/test/ELF/basic64be.s index 32d8974dae01..fb0bf7bfdb80 100644 --- a/test/ELF/basic64be.s +++ b/test/ELF/basic64be.s @@ -43,10 +43,10 @@ _start: # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 # CHECK-NEXT: ProgramHeaderEntrySize: 56 -# CHECK-NEXT: ProgramHeaderCount: 5 +# CHECK-NEXT: ProgramHeaderCount: 6 # CHECK-NEXT: SectionHeaderEntrySize: 64 -# CHECK-NEXT: SectionHeaderCount: 8 -# CHECK-NEXT: StringTableSectionIndex: 6 +# CHECK-NEXT: SectionHeaderCount: 9 +# CHECK-NEXT: StringTableSectionIndex: 7 # CHECK-NEXT: } # CHECK-NEXT: Sections [ # CHECK-NEXT: Section { @@ -85,6 +85,24 @@ _start: # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .got +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10020000 +# CHECK-NEXT: Offset: 0x20000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: ) +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 3 # CHECK-NEXT: Name: .toc # CHECK-NEXT: Type: SHT_PROGBITS (0x1) # CHECK-NEXT: Flags [ (0x3) @@ -104,7 +122,7 @@ _start: # CHECK-NEXT: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Index: 4 # CHECK-NEXT: Name: .toc1 # CHECK-NEXT: Type: SHT_PROGBITS (0x1) # CHECK-NEXT: Flags [ (0x3) @@ -124,7 +142,7 @@ _start: # CHECK-NEXT: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 4 +# CHECK-NEXT: Index: 5 # CHECK-NEXT: Name: .opd # CHECK-NEXT: Type: SHT_PROGBITS (0x1) # CHECK-NEXT: Flags [ (0x3) @@ -139,12 +157,12 @@ _start: # CHECK-NEXT: AddressAlignment: 1 # CHECK-NEXT: EntrySize: 0 # CHECK-NEXT: SectionData ( -# CHECK-NEXT: 0000: 00000000 10010000 00000000 00008000 |................| -# CHECK-NEXT: 0010: 00000000 00000000 |........| +# CHECK-NEXT: 0000: 00000000 10010000 00000000 10028000 |................| +# CHECK-NEXT: 0010: 00000000 00000000 |........| # CHECK-NEXT: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 5 +# CHECK-NEXT: Index: 6 # CHECK-NEXT: Name: .symtab # CHECK-NEXT: Type: SHT_SYMTAB (0x2) # CHECK-NEXT: Flags [ (0x0) @@ -152,7 +170,7 @@ _start: # CHECK-NEXT: Address: 0x0 # CHECK-NEXT: Offset: 0x20058 # CHECK-NEXT: Size: 48 -# CHECK-NEXT: Link: 7 +# CHECK-NEXT: Link: 8 # CHECK-NEXT: Info: 1 # CHECK-NEXT: AddressAlignment: 8 # CHECK-NEXT: EntrySize: 24 @@ -160,14 +178,14 @@ _start: # CHECK: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 6 +# CHECK-NEXT: Index: 7 # CHECK-NEXT: Name: .shstrtab -# CHECK-NEXT: Type: SHT_STRTAB (0x3) -# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: Type: SHT_STRTAB +# CHECK-NEXT: Flags [ # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 # CHECK-NEXT: Offset: 0x20088 -# CHECK-NEXT: Size: 49 +# CHECK-NEXT: Size: 54 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 @@ -176,13 +194,13 @@ _start: # CHECK: ) # CHECK-NEXT: } # CHECK-NEXT: Section { -# CHECK-NEXT: Index: 7 -# CHECK-NEXT: Name: .strtab (41) -# CHECK-NEXT: Type: SHT_STRTAB (0x3) +# CHECK-NEXT: Index: 8 +# CHECK-NEXT: Name: .strtab +# CHECK-NEXT: Type: SHT_STRTAB # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x200B9 +# CHECK-NEXT: Offset: 0x200BE # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -199,10 +217,10 @@ _start: # CHECK-NEXT: Offset: 0x40 # CHECK-NEXT: VirtualAddress: 0x10000040 # CHECK-NEXT: PhysicalAddress: 0x10000040 -# CHECK-NEXT: FileSize: 280 -# CHECK-NEXT: MemSize: 280 -# CHECK-NEXT: Flags [ (0x4) -# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: FileSize: 336 +# CHECK-NEXT: MemSize: 336 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R # CHECK-NEXT: ] # CHECK-NEXT: Alignment: 8 # CHECK-NEXT: } @@ -211,8 +229,8 @@ _start: # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x10000000 # CHECK-NEXT: PhysicalAddress: 0x10000000 -# CHECK-NEXT: FileSize: 344 -# CHECK-NEXT: MemSize: 344 +# CHECK-NEXT: FileSize: 400 +# CHECK-NEXT: MemSize: 400 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R # CHECK-NEXT: ] @@ -245,6 +263,18 @@ _start: # CHECK-NEXT: Alignment: 65536 # CHECK-NEXT: } # CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_GNU_RELRO +# CHECK-NEXT: Offset: 0x20000 +# CHECK-NEXT: VirtualAddress: 0x10020000 +# CHECK-NEXT: PhysicalAddress: 0x10020000 +# CHECK-NEXT: FileSize: 0 +# CHECK-NEXT: MemSize: 0 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 1 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x0 diff --git a/test/ELF/bsymbolic-undef.s b/test/ELF/bsymbolic-undef.s new file mode 100644 index 000000000000..6590bbcb50b7 --- /dev/null +++ b/test/ELF/bsymbolic-undef.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -shared -Bsymbolic %t.o -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: @ (0) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local (0x0) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: undef@ (1) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: ] + +call undef@PLT diff --git a/test/ELF/bsymbolic.s b/test/ELF/bsymbolic.s new file mode 100644 index 000000000000..d713588d5952 --- /dev/null +++ b/test/ELF/bsymbolic.s @@ -0,0 +1,34 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +// RUN: ld.lld -shared %t.o -o %t0.so +// RUN: ld.lld -shared -Bsymbolic %t.o -o %t1.so +// RUN: ld.lld -shared -Bsymbolic-functions %t.o -o %t2.so +// RUN: llvm-readobj -s %t0.so | FileCheck -check-prefix=NOOPTION %s +// RUN: llvm-readobj -s %t1.so | FileCheck -check-prefix=SYMBOLIC %s +// RUN: llvm-readobj -s %t2.so | FileCheck -check-prefix=SYMBOLIC %s + +// NOOPTION: Section { +// NOOPTION: Name: .plt + +// SYMBOLIC: Section { +// SYMBOLIC-NOT: Name: .plt + +.text +.globl foo +.type foo,@function +foo: +nop + +.globl bar +.type bar,@function +bar: +nop + +.globl do +.type do,@function +do: +callq foo@PLT +callq bar@PLT + +.weak zed +.protected zed +.quad zed diff --git a/test/ELF/build-id.s b/test/ELF/build-id.s new file mode 100644 index 000000000000..f1eac42812b4 --- /dev/null +++ b/test/ELF/build-id.s @@ -0,0 +1,38 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld --build-id %t -o %t2 +# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s +# RUN: ld.lld --build-id=md5 %t -o %t2 +# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=MD5 %s +# RUN: ld.lld --build-id=sha1 %t -o %t2 +# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SHA1 %s +# RUN: ld.lld --build-id=0x12345678 %t -o %t2 +# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=HEX %s +# RUN: ld.lld %t -o %t2 +# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s +# RUN: ld.lld --build-id=md5 --build-id=none %t -o %t2 +# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s + +.globl _start +_start: + nop + +.section .note.test, "a", @note + .quad 42 + +# DEFAULT: Contents of section .note.gnu.build-id: +# DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU. +# DEFAULT: Contents of section .note.test: + +# MD5: Contents of section .note.gnu.build-id: +# MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU. + +# SHA1: Contents of section .note.gnu.build-id: +# SHA1-NEXT: 04000000 14000000 03000000 474e5500 ............GNU. + +# HEX: Contents of section .note.gnu.build-id: +# HEX-NEXT: 04000000 04000000 03000000 474e5500 ............GNU. +# HEX-NEXT: 12345678 + +# NONE-NOT: Contents of section .note.gnu.build-id: diff --git a/test/ELF/combrelocs.s b/test/ELF/combrelocs.s new file mode 100644 index 000000000000..5b876ee221a4 --- /dev/null +++ b/test/ELF/combrelocs.s @@ -0,0 +1,92 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.out +# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.dyn { +# CHECK-NEXT: Relocation { +# CHECK-NEXT: Offset: 0x2000 +# CHECK-NEXT: Type: R_X86_64_64 +# CHECK-NEXT: Symbol: aaa (1) +# CHECK-NEXT: Addend: 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: Relocation { +# CHECK-NEXT: Offset: 0x2018 +# CHECK-NEXT: Type: R_X86_64_64 +# CHECK-NEXT: Symbol: aaa (1) +# CHECK-NEXT: Addend: 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: Relocation { +# CHECK-NEXT: Offset: 0x2010 +# CHECK-NEXT: Type: R_X86_64_64 +# CHECK-NEXT: Symbol: bbb (2) +# CHECK-NEXT: Addend: 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: Relocation { +# CHECK-NEXT: Offset: 0x2008 +# CHECK-NEXT: Type: R_X86_64_64 +# CHECK-NEXT: Symbol: ccc (3) +# CHECK-NEXT: Addend: 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: Relocation { +# CHECK-NEXT: Offset: 0x2020 +# CHECK-NEXT: Type: R_X86_64_64 +# CHECK-NEXT: Symbol: ddd (4) +# CHECK-NEXT: Addend: 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK: DynamicSection [ +# CHECK-NEXT: Tag +# CHECK-NOT: RELACOUNT + +# RUN: ld.lld -z nocombreloc -shared %t.o -o %t.out +# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | \ +# RUN: FileCheck --check-prefix=NOCOMB %s + +# NOCOMB: Relocations [ +# NOCOMB-NEXT: Section ({{.*}}) .rela.dyn { +# NOCOMB-NEXT: Relocation { +# NOCOMB-NEXT: Offset: 0x2000 +# NOCOMB-NEXT: Type: R_X86_64_64 +# NOCOMB-NEXT: Symbol: aaa (1) +# NOCOMB-NEXT: Addend: 0x0 +# NOCOMB-NEXT: } +# NOCOMB-NEXT: Relocation { +# NOCOMB-NEXT: Offset: 0x2008 +# NOCOMB-NEXT: Type: R_X86_64_64 +# NOCOMB-NEXT: Symbol: ccc (3) +# NOCOMB-NEXT: Addend: 0x0 +# NOCOMB-NEXT: } +# NOCOMB-NEXT: Relocation { +# NOCOMB-NEXT: Offset: 0x2010 +# NOCOMB-NEXT: Type: R_X86_64_64 +# NOCOMB-NEXT: Symbol: bbb (2) +# NOCOMB-NEXT: Addend: 0x0 +# NOCOMB-NEXT: } +# NOCOMB-NEXT: Relocation { +# NOCOMB-NEXT: Offset: 0x2018 +# NOCOMB-NEXT: Type: R_X86_64_64 +# NOCOMB-NEXT: Symbol: aaa (1) +# NOCOMB-NEXT: Addend: 0x0 +# NOCOMB-NEXT: } +# NOCOMB-NEXT: Relocation { +# NOCOMB-NEXT: Offset: 0x2020 +# NOCOMB-NEXT: Type: R_X86_64_64 +# NOCOMB-NEXT: Symbol: ddd (4) +# NOCOMB-NEXT: Addend: 0x0 +# NOCOMB-NEXT: } +# NOCOMB-NEXT: } +# NOCOMB-NEXT: ] +# NOCOMB: DynamicSection [ +# NOCOMB-NEXT: Tag +# NOCOMB-NOT: RELACOUNT + +.data + .quad aaa + .quad ccc + .quad bbb + .quad aaa + .quad ddd diff --git a/test/ELF/comdat.s b/test/ELF/comdat.s index 4f8955e289d5..d422ee8fba33 100644 --- a/test/ELF/comdat.s +++ b/test/ELF/comdat.s @@ -61,6 +61,17 @@ foo: // READ-NEXT: Section: .text // READ-NEXT: } // READ-NEXT: Symbol { +// READ-NEXT: Name: _DYNAMIC +// READ-NEXT: Value: 0x2000 +// READ-NEXT: Size: 0 +// READ-NEXT: Binding: Local +// READ-NEXT: Type: None +// READ-NEXT: Other [ (0x2) +// READ-NEXT: STV_HIDDEN +// READ-NEXT: ] +// READ-NEXT: Section: .dynamic +// READ-NEXT: } +// READ-NEXT: Symbol { // READ-NEXT: Name: abc // READ-NEXT: Value: 0x0 // READ-NEXT: Size: 0 diff --git a/test/ELF/common.s b/test/ELF/common.s index 67cedbccb866..f16f948fe64e 100644 --- a/test/ELF/common.s +++ b/test/ELF/common.s @@ -13,6 +13,9 @@ // CHECK-NEXT: Address: 0x11000 // CHECK-NEXT: Offset: // CHECK-NEXT: Size: 22 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 16 // CHECK: Name: sym1 // CHECK-NEXT: Value: 0x11004 diff --git a/test/ELF/compressed-debug-input.s b/test/ELF/compressed-debug-input.s new file mode 100644 index 000000000000..7339833dbb7f --- /dev/null +++ b/test/ELF/compressed-debug-input.s @@ -0,0 +1,61 @@ +# REQUIRES: zlib + +# RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: llvm-readobj -sections %t | FileCheck -check-prefix=COMPRESSED %s + +# COMPRESSED: Section { +# COMPRESSED: Index: 2 +# COMPRESSED: Name: .debug_str +# COMPRESSED-NEXT: Type: SHT_PROGBITS +# COMPRESSED-NEXT: Flags [ +# COMPRESSED-NEXT: SHF_COMPRESSED (0x800) +# COMPRESSED-NEXT: SHF_MERGE (0x10) +# COMPRESSED-NEXT: SHF_STRINGS (0x20) +# COMPRESSED-NEXT: ] +# COMPRESSED-NEXT: Address: +# COMPRESSED-NEXT: Offset: +# COMPRESSED-NEXT: Size: 66 +# COMPRESSED-NEXT: Link: +# COMPRESSED-NEXT: Info: +# COMPRESSED-NEXT: AddressAlignment: 1 +# COMPRESSED-NEXT: EntrySize: 1 +# COMPRESSED-NEXT: } + +# RUN: ld.lld %t -o %t.so -shared +# RUN: llvm-readobj -sections -section-data %t.so | FileCheck -check-prefix=UNCOMPRESSED %s + +# UNCOMPRESSED: Section { +# UNCOMPRESSED: Index: 6 +# UNCOMPRESSED: Name: .debug_str +# UNCOMPRESSED-NEXT: Type: SHT_PROGBITS +# UNCOMPRESSED-NEXT: Flags [ +# UNCOMPRESSED-NEXT: SHF_MERGE (0x10) +# UNCOMPRESSED-NEXT: SHF_STRINGS (0x20) +# UNCOMPRESSED-NEXT: ] +# UNCOMPRESSED-NEXT: Address: 0x0 +# UNCOMPRESSED-NEXT: Offset: 0x1060 +# UNCOMPRESSED-NEXT: Size: 69 +# UNCOMPRESSED-NEXT: Link: 0 +# UNCOMPRESSED-NEXT: Info: 0 +# UNCOMPRESSED-NEXT: AddressAlignment: 1 +# UNCOMPRESSED-NEXT: EntrySize: 1 +# UNCOMPRESSED-NEXT: SectionData ( +# UNCOMPRESSED-NEXT: 0000: 73686F72 7420756E 7369676E 65642069 |short unsigned i| +# UNCOMPRESSED-NEXT: 0010: 6E740075 6E736967 6E656420 696E7400 |nt.unsigned int.| +# UNCOMPRESSED-NEXT: 0020: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in| +# UNCOMPRESSED-NEXT: 0030: 74006368 61720075 6E736967 6E656420 |t.char.unsigned | +# UNCOMPRESSED-NEXT: 0040: 63686172 00 |char.| +# UNCOMPRESSED-NEXT: ) +# UNCOMPRESSED-NEXT: } + +.section .debug_str,"MS",@progbits,1 +.LASF2: + .string "short unsigned int" +.LASF3: + .string "unsigned int" +.LASF0: + .string "long unsigned int" +.LASF8: + .string "char" +.LASF1: + .string "unsigned char" diff --git a/test/ELF/conflict.s b/test/ELF/conflict.s new file mode 100644 index 000000000000..7598eea3711c --- /dev/null +++ b/test/ELF/conflict.s @@ -0,0 +1,26 @@ +# REQUIRES: x86, shell + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: not ld.lld %t1.o %t1.o -o %t2 2>&1 | FileCheck -check-prefix=DEMANGLE %s + +# DEMANGLE: duplicate symbol: mul(double, double) in +# DEMANGLE: duplicate symbol: foo in + +# RUN: not ld.lld %t1.o %t1.o -o %t2 --no-demangle 2>&1 | \ +# RUN: FileCheck -check-prefix=NO_DEMANGLE %s + +# NO_DEMANGLE: duplicate symbol: _Z3muldd in +# NO_DEMANGLE: duplicate symbol: foo in + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/conflict.s -o %t2.o +# RUN: llvm-ar rcs %t3.a %t2.o +# RUN: not ld.lld %t1.o %t3.a -u baz -o %t2 2>&1 | FileCheck -check-prefix=ARCHIVE %s + +# ARCHIVE: duplicate symbol: foo in {{.*}}1.o and {{.*}}3.a({{.*}}2.o) + +.globl _Z3muldd, foo +_Z3muldd: +foo: + mov $60, %rax + mov $42, %rdi + syscall diff --git a/test/ELF/copy-errors.s b/test/ELF/copy-errors.s new file mode 100644 index 000000000000..9d8b72ddb43b --- /dev/null +++ b/test/ELF/copy-errors.s @@ -0,0 +1,15 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/protected-shared.s -o %t2.o +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s + +.global _start +_start: + + +call bar +// CHECK: cannot preempt symbol + +call zed +// CHECK: symbol is missing type diff --git a/test/ELF/copy-in-shared.s b/test/ELF/copy-in-shared.s new file mode 100644 index 000000000000..4114d95fb101 --- /dev/null +++ b/test/ELF/copy-in-shared.s @@ -0,0 +1,10 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-in-shared.s -o %t1.o +// RUN: ld.lld -shared %t1.o -o %t1.so +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o +// RUN: not ld.lld %t2.o %t1.so -o %t2.so -shared 2>&1 | FileCheck %s + + +.quad foo + +// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment diff --git a/test/ELF/copy-rel-corrupted.s b/test/ELF/copy-rel-corrupted.s new file mode 100644 index 000000000000..a3f72f71c1da --- /dev/null +++ b/test/ELF/copy-rel-corrupted.s @@ -0,0 +1,10 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: llvm-mc %p/Inputs/copy-rel-corrupted.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: not ld.lld %t.o %t2.so -o %t.exe 2>&1 | FileCheck %s + +// CHECK: cannot create a copy relocation for x + +.global _start +_start: + call x diff --git a/test/ELF/copy-rel-pie-error.s b/test/ELF/copy-rel-pie-error.s new file mode 100644 index 000000000000..1f427023baa5 --- /dev/null +++ b/test/ELF/copy-rel-pie-error.s @@ -0,0 +1,12 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: not ld.lld %t.o %t2.so -o %t.exe -pie 2>&1 | FileCheck %s + +// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment +// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment + +.global _start +_start: + .quad bar + .quad foo diff --git a/test/ELF/copy-rel-pie.s b/test/ELF/copy-rel-pie.s new file mode 100644 index 000000000000..be7d5acaeba9 --- /dev/null +++ b/test/ELF/copy-rel-pie.s @@ -0,0 +1,44 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t.exe -pie +// RUN: llvm-readobj -s -r %t.exe | FileCheck %s +// RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASM %s + +.global _start +_start: + call bar + call foo + +// CHECK: Name: .plt +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x1010 + +// CHECK: Name: .bss +// CHECK-NEXT: Type: SHT_NOBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x3020 + +// CHECK: Relocations [ +// CHECK-NEXT: Section (4) .rela.dyn { +// CHECK-NEXT: 0x3020 R_X86_64_COPY foo 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Section (5) .rela.plt { +// CHECK-NEXT: 0x3018 R_X86_64_JUMP_SLOT bar 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] + +// (0x1010 + 0x10) - 0x1005 = 27 +// 0x3020 - 0x100a = 8214 + +// DISASM: Disassembly of section .text: +// DISASM-NEXT: _start: +// DISASM-NEXT: 1000: e8 1b 00 00 00 callq 27 +// DISASM-NEXT: 1005: e8 16 20 00 00 callq 8214 <foo> diff --git a/test/ELF/ctors_dtors_priority.s b/test/ELF/ctors_dtors_priority.s new file mode 100644 index 000000000000..10d6471f953a --- /dev/null +++ b/test/ELF/ctors_dtors_priority.s @@ -0,0 +1,41 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +// RUN: %p/Inputs/ctors_dtors_priority1.s -o %t-crtbegin.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +// RUN: %p/Inputs/ctors_dtors_priority2.s -o %t2 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +// RUN: %p/Inputs/ctors_dtors_priority3.s -o %t-crtend.o +// RUN: ld.lld %t1 %t2 %t-crtend.o %t-crtbegin.o -o %t.exe +// RUN: llvm-objdump -s %t.exe | FileCheck %s +// REQUIRES: x86 + +.globl _start +_start: + nop + +.section .ctors, "aw", @progbits + .byte 1 +.section .ctors.100, "aw", @progbits + .byte 2 +.section .ctors.005, "aw", @progbits + .byte 3 +.section .ctors, "aw", @progbits + .byte 4 +.section .ctors, "aw", @progbits + .byte 5 + +.section .dtors, "aw", @progbits + .byte 0x11 +.section .dtors.100, "aw", @progbits + .byte 0x12 +.section .dtors.005, "aw", @progbits + .byte 0x13 +.section .dtors, "aw", @progbits + .byte 0x14 +.section .dtors, "aw", @progbits + .byte 0x15 + +// CHECK: Contents of section .ctors: +// CHECK-NEXT: a1010405 b10302c1 +// CHECK: Contents of section .dtors: +// CHECK-NEXT: a2111415 b21312c2 diff --git a/test/ELF/default-output.s b/test/ELF/default-output.s index 8da3bb40eac0..c0766acf6e55 100644 --- a/test/ELF/default-output.s +++ b/test/ELF/default-output.s @@ -9,7 +9,7 @@ # RUN: ld.lld %t # RUN: llvm-readobj a.out > /dev/null 2>&1 -.globl _start; +.globl _start _start: mov $60, %rax mov $42, %rdi diff --git a/test/ELF/discard-merge-locals.s b/test/ELF/discard-merge-locals.s index 51676da192ca..01b4d337cb2d 100644 --- a/test/ELF/discard-merge-locals.s +++ b/test/ELF/discard-merge-locals.s @@ -21,4 +21,15 @@ // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x2000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/test/ELF/discard-merge-unnamed.s b/test/ELF/discard-merge-unnamed.s index bd0058cbd7db..be174f27b50b 100644 --- a/test/ELF/discard-merge-unnamed.s +++ b/test/ELF/discard-merge-unnamed.s @@ -13,4 +13,15 @@ // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x2000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/test/ELF/discard-none.s b/test/ELF/discard-none.s index c13b544f514d..e3a7a2032082 100644 --- a/test/ELF/discard-none.s +++ b/test/ELF/discard-none.s @@ -21,7 +21,7 @@ // CHECK-NEXT: EntrySize: // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 002E4C6D 796F7468 65727661 72002E4C |..Lmyothervar..L| -// CHECK-NEXT: 0010: 6D797661 7200 |myvar.| +// CHECK-NEXT: 0010: 6D797661 72005F44 594E414D 494300 |myvar._DYNAMIC.| // CHECK-NEXT: ) // CHECK-NEXT: } diff --git a/test/ELF/dont-export-hidden.s b/test/ELF/dont-export-hidden.s new file mode 100644 index 000000000000..8819a6e99fdb --- /dev/null +++ b/test/ELF/dont-export-hidden.s @@ -0,0 +1,39 @@ +// RUN: llvm-mc %p/Inputs/shared.s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: ld.lld %t2.o %t.so -o %t.exe +// RUN: llvm-readobj --dyn-symbols %t.exe | FileCheck %s + + .global _start +_start: + .global bar + .hidden bar +bar: + + .global bar2 +bar2: + + .global foo +foo: + +// CHECK: DynamicSymbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: @ (0) +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: bar2 +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: ] + diff --git a/test/ELF/driver.test b/test/ELF/driver.test new file mode 100644 index 000000000000..95e2100b4abf --- /dev/null +++ b/test/ELF/driver.test @@ -0,0 +1,49 @@ +# REQUIRES: x86 + +# RUN: not ld.lld --unknown1 --unknown2 -m foo /no/such/file -lnosuchlib \ +# RUN: 2>&1 | FileCheck -check-prefix=UNKNOWN %s + +# UNKNOWN: unknown argument: --unknown1 +# UNKNOWN: unknown argument: --unknown2 +# UNKNOWN: unknown emulation: foo +# UNKNOWN: cannot open /no/such/file +# UNKNOWN: unable to find library -lnosuchlib + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: not ld.lld %t -o /no/such/file 2>&1 | FileCheck -check-prefix=MISSING %s +# MISSING: failed to open /no/such/file + +# RUN: ld.lld --help 2>&1 | FileCheck -check-prefix=HELP %s +# HELP: USAGE: + +# RUN: ld.lld --version 2>&1 | FileCheck -check-prefix=VERSION %s +# VERSION: LLD + +## Attempt to link DSO with -r +# RUN: ld.lld -shared %t -o %t.so +# RUN: not ld.lld -r %t.so %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR %s +# ERR: attempted static link of dynamic object + +## Attempt to use -r and -shared together +# RUN: not ld.lld -r -shared %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR2 %s +# ERR2: -r and -shared may not be used together + +## Attempt to use -r and --gc-sections together +# RUN: not ld.lld -r --gc-sections %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR3 %s +# ERR3: -r and --gc-sections may not be used together + +## Attempt to use -r and --icf together +# RUN: not ld.lld -r --icf=all %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR4 %s +# ERR4: -r and --icf may not be used together + +## Attempt to use -r and -pie together +# RUN: not ld.lld -r -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR5 %s +# ERR5: -r and -pie may not be used together + +## Attempt to use -shared and -pie together +# RUN: not ld.lld -shared -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR6 %s +# ERR6: -shared and -pie may not be used together + +.globl _start +_start: + nop diff --git a/test/ELF/duplicate-internal.s b/test/ELF/duplicate-internal.s index 2395a6cae0db..d1ccf5322127 100644 --- a/test/ELF/duplicate-internal.s +++ b/test/ELF/duplicate-internal.s @@ -3,7 +3,7 @@ # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o # RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s -# CHECK: duplicate symbol: _gp in (internal) and {{.*}} +# CHECK: duplicate symbol: _gp in {{.*}} and (internal) # REQUIRES: mips diff --git a/test/ELF/duplicated-plt-entry.s b/test/ELF/duplicated-plt-entry.s new file mode 100644 index 000000000000..4644bed0ca8b --- /dev/null +++ b/test/ELF/duplicated-plt-entry.s @@ -0,0 +1,17 @@ +// REQUIRES: x86 + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/duplicated-plt-entry.s -o %t.o +// RUN: ld.lld -shared %t.o -o %t.so + +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o +// RUN: ld.lld %t2.o %t.so -o %t2.so -shared + +// RUN: llvm-readobj -r %t2.so | FileCheck %s +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.plt { +// CHECK-NEXT: R_X86_64_JUMP_SLOT bar 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] + +callq bar@PLT +callq bar@PLT diff --git a/test/ELF/dynamic-list.s b/test/ELF/dynamic-list.s new file mode 100644 index 000000000000..5e257b31d1f3 --- /dev/null +++ b/test/ELF/dynamic-list.s @@ -0,0 +1,110 @@ +## There is some bad quoting interaction between lit's internal shell, which is +## implemented in Python, and the Cygwin implementations of the Unix utilities. +## Avoid running these tests on Windows for now by requiring a real shell. + +# REQUIRES: shell + +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o +# RUN: ld.lld -shared %t2.o -soname shared -o %t2.so +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Check exporting only one symbol. +# RUN: echo "{ foo1; };" > %t.list +# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe +# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s + +## And now using quoted strings (the output is the same since it does +## use any wildcard character). +# RUN: echo "{ \"foo1\"; };" > %t.list +# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe +# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s + +## And now using --export-dynamic-symbol. +# RUN: ld.lld --export-dynamic-symbol foo1 %t %t2.so -o %t.exe +# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s +# RUN: ld.lld --export-dynamic-symbol=foo1 %t %t2.so -o %t.exe +# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: @ (0) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo1@ (1) +# CHECK-NEXT: Value: 0x11000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text (0x4) +# CHECK-NEXT: } +# CHECK-NEXT: ] + + +## Now export all the foo1, foo2, and foo31 symbols +# RUN: echo "{ foo1; foo2; foo31; };" > %t.list +# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe +# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s + +# CHECK2: DynamicSymbols [ +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: @ (0) +# CHECK2-NEXT: Value: 0x0 +# CHECK2-NEXT: Size: 0 +# CHECK2-NEXT: Binding: Local +# CHECK2-NEXT: Type: None +# CHECK2-NEXT: Other: 0 +# CHECK2-NEXT: Section: Undefined +# CHECK2-NEXT: } +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: foo1@ (1) +# CHECK2-NEXT: Value: 0x11000 +# CHECK2-NEXT: Size: 0 +# CHECK2-NEXT: Binding: Global (0x1) +# CHECK2-NEXT: Type: None (0x0) +# CHECK2-NEXT: Other: 0 +# CHECK2-NEXT: Section: .text (0x4) +# CHECK2-NEXT: } +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: foo2@ (6) +# CHECK2-NEXT: Value: 0x11001 +# CHECK2-NEXT: Size: 0 +# CHECK2-NEXT: Binding: Global (0x1) +# CHECK2-NEXT: Type: None (0x0) +# CHECK2-NEXT: Other: 0 +# CHECK2-NEXT: Section: .text (0x4) +# CHECK2-NEXT: } +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: foo31@ (11) +# CHECK2-NEXT: Value: 0x11002 +# CHECK2-NEXT: Size: 0 +# CHECK2-NEXT: Binding: Global (0x1) +# CHECK2-NEXT: Type: None (0x0) +# CHECK2-NEXT: Other: 0 +# CHECK2-NEXT: Section: .text (0x4) +# CHECK2-NEXT: } +# CHECK2-NEXT: ] + +.globl foo1 +foo1: + ret + +.globl foo2 +foo2: + ret + +.globl foo31 +foo31: + ret + +.globl _start +_start: + retq diff --git a/test/ELF/dynamic-reloc-in-ro.s b/test/ELF/dynamic-reloc-in-ro.s new file mode 100644 index 000000000000..2ef36f695fb6 --- /dev/null +++ b/test/ELF/dynamic-reloc-in-ro.s @@ -0,0 +1,8 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s + +foo: +.quad foo + +// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment diff --git a/test/ELF/dynamic-reloc-weak.s b/test/ELF/dynamic-reloc-weak.s index fe1b7eedb6d7..b4da2e552e11 100644 --- a/test/ELF/dynamic-reloc-weak.s +++ b/test/ELF/dynamic-reloc-weak.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc-weak.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld %t.o %t2.so -o %t // RUN: llvm-readobj -r %t | FileCheck %s @@ -19,9 +19,12 @@ _start: .weak sym3 .quad sym3 -// Both gold and bfd ld will produce a relocation for sym1 and sym2 only. That -// That seems odd. If the dynamic linker must get a chance to resolve sym1 -// and sym2, that should also be the case for sym3. + .type sym4,@function + .weak sym4 + .quad sym4 + +// Test that we produce dynamic relocation for every weak undefined symbol +// we found. // CHECK: Relocations [ // CHECK-NEXT: Section ({{.*}}) .rela.dyn { @@ -29,5 +32,6 @@ _start: // CHECK-NEXT: } // CHECK-NEXT: Section ({{.*}}) .rela.plt { // CHECK-NEXT: 0x{{.*}} R_X86_64_JUMP_SLOT sym2 0x0 +// CHECK-NEXT: 0x{{.*}} R_X86_64_JUMP_SLOT sym3 0x0 // CHECK-NEXT: } -// CHECK-NEXT: ]
\ No newline at end of file +// CHECK-NEXT: ] diff --git a/test/ELF/dynamic-reloc.s b/test/ELF/dynamic-reloc.s index 295396006543..5e23ba93d5a9 100644 --- a/test/ELF/dynamic-reloc.s +++ b/test/ELF/dynamic-reloc.s @@ -43,6 +43,7 @@ // CHECK: DynamicSection [ // CHECK-NEXT: Tag Type Name/Value +// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so) // CHECK-NEXT: 0x0000000000000017 JMPREL // CHECK-NEXT: 0x0000000000000002 PLTRELSZ 24 (bytes) // CHECK-NEXT: 0x0000000000000003 PLTGOT @@ -52,7 +53,6 @@ // CHECK-NEXT: 0x0000000000000005 STRTAB // CHECK-NEXT: 0x000000000000000A STRSZ // CHECK-NEXT: 0x0000000000000004 HASH -// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so) // CHECK-NEXT: 0x0000000000000015 DEBUG 0x0 // CHECK-NEXT: 0x0000000000000000 NULL 0x0 // CHECK-NEXT: ] diff --git a/test/ELF/dynamic.s b/test/ELF/dynamic.s new file mode 100644 index 000000000000..2efd2990c52c --- /dev/null +++ b/test/ELF/dynamic.s @@ -0,0 +1,44 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t.o + +## Check that _DYNAMIC symbol is created when creating dynamic output, +## and has hidden visibility and address equal to .dynamic section. +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-readobj -sections -symbols %t.so | FileCheck %s +# CHECK: Section { +# CHECK: Index: 5 +# CHECK: Name: .dynamic +# CHECK-NEXT: Type: SHT_DYNAMIC +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x[[ADDR:.*]] +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK: Symbols [ +# CHECK: Symbol { +# CHECK: Name: _DYNAMIC +# CHECK-NEXT: Value: 0x[[ADDR]] +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other [ (0x2) +# CHECK-NEXT: STV_HIDDEN +# CHECK-NEXT: ] +# CHECK-NEXT: Section: .dynamic +# CHECK-NEXT: } + +# RUN: ld.lld %t.o -o %t.o +# RUN: llvm-readobj -sections -symbols %t.o | FileCheck -check-prefix=NODYN %s +# NODYN: Symbols [ +# NODYN-NOT: Name: _DYNAMIC +# NODYN: ] + +.globl _start +_start: diff --git a/test/ELF/dynsym-pie.s b/test/ELF/dynsym-pie.s new file mode 100644 index 000000000000..9d3a9ffe304f --- /dev/null +++ b/test/ELF/dynsym-pie.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +# RUN: ld.lld -pie %t -o %t.out +# RUN: llvm-readobj -t -dyn-symbols %t.out | FileCheck %s + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: @ +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.text +.globl _start +_start: + +.global default +default: + +.global protected +protected: + +.global hidden +hidden: + +.global internal +internal: + +.global protected_with_hidden +.protected +protected_with_hidden: diff --git a/test/ELF/edata-etext.s b/test/ELF/edata-etext.s new file mode 100644 index 000000000000..e0538d690d7c --- /dev/null +++ b/test/ELF/edata-etext.s @@ -0,0 +1,117 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-readobj -sections -symbols %t | FileCheck %s + +## This checks that: +## 1) Address of _etext is the first location after the last read-only loadable segment. +## 2) Address of _edata points to the end of the last non SHT_NOBITS section. +## That is how gold/bfd do. At the same time specs says: "If the address of _edata is +## greater than the address of _etext, the address of _end is same as the address +## of _edata." (https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html). +## 3) Address of _end is different from _edata because of 2. +# CHECK: Section { +# CHECK: Index: 1 +# CHECK: Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_EXECINSTR +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x11000 +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Size: 1 +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .data +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x12000 +# CHECK-NEXT: Offset: 0x2000 +# CHECK-NEXT: Size: 2 +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Name: .bss +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x12004 +# CHECK-NEXT: Offset: 0x2002 +# CHECK-NEXT: Size: 6 +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK: Symbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _start +# CHECK-NEXT: Value: 0x11000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _edata +# CHECK-NEXT: Value: 0x12002 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Absolute +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _end +# CHECK-NEXT: Value: 0x1200A +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Absolute +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _etext +# CHECK-NEXT: Value: 0x11001 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Absolute +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.global _start,_end,_etext,_edata +.text +_start: + nop +.data + .word 1 +.bss + .align 4 + .space 6 diff --git a/test/ELF/eh-frame-dyn-rel.s b/test/ELF/eh-frame-dyn-rel.s new file mode 100644 index 000000000000..62d56951b2cf --- /dev/null +++ b/test/ELF/eh-frame-dyn-rel.s @@ -0,0 +1,10 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: not ld.lld %t.o %t.o -o %t -shared 2>&1 | FileCheck %s + + .section bar,"axG",@progbits,foo,comdat + .cfi_startproc + .cfi_personality 0x8c, foo + .cfi_endproc + +// CHECK: can't create dynamic relocation R_X86_64_64 against readonly segment diff --git a/test/ELF/eh-frame-gc.s b/test/ELF/eh-frame-gc.s new file mode 100644 index 000000000000..b2e21f497f41 --- /dev/null +++ b/test/ELF/eh-frame-gc.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o +# RUN: ld.lld -shared --gc-sections %t.o -o %t +# RUN: llvm-readobj -s %t | FileCheck %s + +## Check that section containing personality is +## not garbage collected. +# CHECK: Sections [ +# CHECK: Name: .test_personality_section + +.text +.globl foo +.type foo,@function +foo: + .cfi_startproc + .cfi_personality 155, DW.ref.__gxx_personality_v0 + .cfi_endproc + +.section .test_personality_section +DW.ref.__gxx_personality_v0: diff --git a/test/ELF/eh-frame-hdr-abs-fde.s b/test/ELF/eh-frame-hdr-abs-fde.s new file mode 100644 index 000000000000..37705d6ad818 --- /dev/null +++ b/test/ELF/eh-frame-hdr-abs-fde.s @@ -0,0 +1,33 @@ +# Check reading PC values of FDEs and writing lookup table in the .eh_frame_hdr +# if CIE augmentation string has 'L' token and PC values are encoded using +# absolute (not relative) format. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld --eh-frame-hdr %t.o -o %t +# RUN: llvm-objdump -s -dwarf=frames %t | FileCheck %s + +# REQUIRES: mips + +# CHECK: Contents of section .eh_frame_hdr: +# CHECK-NEXT: 10178 011b033b ffffffcc 00000001 0000fe88 +# ^-- 0x20000 - 0x10178 +# .text - .eh_frame_hdr +# CHECK-NEXT: 10188 ffffffe8 +# CHECK-NEXT: Contents of section .text: +# CHECK-NEXT: 20000 00000000 + +# CHECK: Augmentation: "zLR" +# CHECK: Augmentation data: 00 0B +# ^-- DW_EH_PE_udata4 | DW_EH_PE_signed + + .text + .globl __start +__start: + .cfi_startproc + .cfi_lsda 0, _ex + nop + .cfi_endproc + + .data +_ex: + .word 0 diff --git a/test/ELF/eh-frame-hdr-augmentation.s b/test/ELF/eh-frame-hdr-augmentation.s new file mode 100644 index 000000000000..91e6a9cc1ccb --- /dev/null +++ b/test/ELF/eh-frame-hdr-augmentation.s @@ -0,0 +1,38 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld --eh-frame-hdr %t.o -o %t -shared +// RUN: llvm-objdump --dwarf=frames %t | FileCheck %s + +// CHECK: .eh_frame contents: + +// CHECK: 00000000 0000001c ffffffff CIE +// CHECK-NEXT: Version: 1 +// CHECK-NEXT: Augmentation: "zPLR" +// CHECK-NEXT: Code alignment factor: 1 +// CHECK-NEXT: Data alignment factor: -8 +// CHECK-NEXT: Return address column: 16 +// CHECK-NEXT: Augmentation data: + +// CHECK: DW_CFA_def_cfa: reg7 +8 +// CHECK-NEXT: DW_CFA_offset: reg16 -8 +// CHECK-NEXT: DW_CFA_nop: +// CHECK-NEXT: DW_CFA_nop: + +// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000dd8...00000dd8 +// CHECK-NEXT: DW_CFA_nop: +// CHECK-NEXT: DW_CFA_nop: +// CHECK-NEXT: DW_CFA_nop: + + .cfi_startproc + .cfi_personality 0x9b, g + .cfi_lsda 0x1b, h + .cfi_endproc + + .global g + .hidden g +g: + + .global h + .hidden h +h: + diff --git a/test/ELF/eh-frame-hdr-icf.s b/test/ELF/eh-frame-hdr-icf.s new file mode 100644 index 000000000000..2e7b335fb46d --- /dev/null +++ b/test/ELF/eh-frame-hdr-icf.s @@ -0,0 +1,27 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 --icf=all --eh-frame-hdr +# RUN: llvm-objdump -s %t2 | FileCheck %s + +# CHECK: Contents of section .eh_frame_hdr: +# CHECK-NEXT: 101a0 011b033b b4ffffff 01000000 600e0000 +# ^ FDE count +# CHECK-NEXT: 101b0 d0ffffff 00000000 00000000 +# ^ FDE for f2 + +.globl _start, f1, f2 +_start: + ret + +.section .text.f1, "ax" +f1: + .cfi_startproc + ret + .cfi_endproc + +.section .text.f2, "ax" +f2: + .cfi_startproc + ret + .cfi_endproc diff --git a/test/ELF/eh-frame-hdr-no-out.s b/test/ELF/eh-frame-hdr-no-out.s new file mode 100644 index 000000000000..edbafad07247 --- /dev/null +++ b/test/ELF/eh-frame-hdr-no-out.s @@ -0,0 +1,6 @@ +// REQUIRES: x86 +// RUN: not ld.lld --eh-frame-hdr %p/Inputs/invalid-cie-version2.elf -o %t >& %t.log +// RUN: FileCheck %s < %t.log + +// invalid-cie-version2.elf contains unsupported version of CIE = 2. +// CHECK: FDE version 1 or 3 expected, but got 2 diff --git a/test/ELF/eh-frame-hdr-no-out2.s b/test/ELF/eh-frame-hdr-no-out2.s new file mode 100644 index 000000000000..0eeb0ea5548d --- /dev/null +++ b/test/ELF/eh-frame-hdr-no-out2.s @@ -0,0 +1,19 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld --eh-frame-hdr %t.o -o %t +// RUN: llvm-readobj -s -program-headers %t | FileCheck %s --check-prefix=NOHDR + +.section foo,"ax",@progbits + nop + +.text +.globl _start +_start: + +// There is no .eh_frame section, +// therefore .eh_frame_hdr also not created. +// NOHDR: Sections [ +// NOHDR-NOT: Name: .eh_frame +// NOHDR-NOT: Name: .eh_frame_hdr +// NOHDR: ProgramHeaders [ +// NOHDR-NOT: PT_GNU_EH_FRAME diff --git a/test/ELF/eh-frame-hdr.s b/test/ELF/eh-frame-hdr.s new file mode 100644 index 000000000000..16fb49ac8e9f --- /dev/null +++ b/test/ELF/eh-frame-hdr.s @@ -0,0 +1,127 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t +// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t | FileCheck %s --check-prefix=NOHDR +// RUN: ld.lld --eh-frame-hdr %t.o -o %t +// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t | FileCheck %s --check-prefix=HDR +// RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=HDRDISASM + +.section foo,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.section bar,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.section dah,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.text +.globl _start +_start: + +// NOHDR: Sections [ +// NOHDR-NOT: Name: .eh_frame_hdr +// NOHDR: ProgramHeaders [ +// NOHDR-NOT: PT_GNU_EH_FRAME + +//HDRDISASM: Disassembly of section foo: +//HDRDISASM-NEXT: foo: +//HDRDISASM-NEXT: 11000: 90 nop +//HDRDISASM-NEXT: Disassembly of section bar: +//HDRDISASM-NEXT: bar: +//HDRDISASM-NEXT: 11001: 90 nop +//HDRDISASM-NEXT: Disassembly of section dah: +//HDRDISASM-NEXT: dah: +//HDRDISASM-NEXT: 11002: 90 nop + +// HDR: Sections [ +// HDR: Section { +// HDR: Index: 1 +// HDR-NEXT: Name: .eh_frame +// HDR-NEXT: Type: SHT_PROGBITS +// HDR-NEXT: Flags [ +// HDR-NEXT: SHF_ALLOC +// HDR-NEXT: ] +// HDR-NEXT: Address: 0x10158 +// HDR-NEXT: Offset: 0x158 +// HDR-NEXT: Size: 96 +// HDR-NEXT: Link: 0 +// HDR-NEXT: Info: 0 +// HDR-NEXT: AddressAlignment: 8 +// HDR-NEXT: EntrySize: 0 +// HDR-NEXT: SectionData ( +// HDR-NEXT: 0000: 14000000 00000000 017A5200 01781001 | +// HDR-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 | +// HDR-NEXT: 0020: 880E0000 01000000 00000000 00000000 | +// HDR-NEXT: 0030: 14000000 34000000 710E0000 01000000 | +// HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000 | +// HDR-NEXT: 0050: 5A0E0000 01000000 00000000 00000000 | +// CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000 +// FDE(1): 14000000 1C000000 880E0000 01000000 00000000 00000000 +// address of data (starts with 0x880E0000) = 0x10158 + 0x0020 = 0x10178 +// The starting address to which this FDE applies = 0xE88 + 0x10178 = 0x11000 +// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 +// FDE(2): 14000000 34000000 710E0000 01000000 00000000 00000000 +// address of data (starts with 0x710E0000) = 0x10158 + 0x0038 = 0x10190 +// The starting address to which this FDE applies = 0xE71 + 0x10190 = 0x11001 +// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 +// FDE(3): 14000000 4C000000 5A0E0000 01000000 00000000 00000000 +// address of data (starts with 0x5A0E0000) = 0x10158 + 0x0050 = 0x101A8 +// The starting address to which this FDE applies = 0xE5A + 0x101A8 = 0x11002 +// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1 +// HDR-NEXT: ) +// HDR-NEXT: } +// HDR-NEXT: Section { +// HDR-NEXT: Index: 2 +// HDR-NEXT: Name: .eh_frame_hdr +// HDR-NEXT: Type: SHT_PROGBITS +// HDR-NEXT: Flags [ +// HDR-NEXT: SHF_ALLOC +// HDR-NEXT: ] +// HDR-NEXT: Address: 0x101B8 +// HDR-NEXT: Offset: 0x1B8 +// HDR-NEXT: Size: 36 +// HDR-NEXT: Link: 0 +// HDR-NEXT: Info: 0 +// HDR-NEXT: AddressAlignment: 1 +// HDR-NEXT: EntrySize: 0 +// HDR-NEXT: SectionData ( +// HDR-NEXT: 0000: 011B033B 9CFFFFFF 03000000 480E0000 | +// HDR-NEXT: 0010: B8FFFFFF 490E0000 D0FFFFFF 4A0E0000 | +// HDR-NEXT: 0020: E8FFFFFF | +// Header (always 4 bytes): 0x011B033B +// 9CFFFFFF = .eh_frame(0x10158) - .eh_frame_hdr(0x101B8) - 4 +// 03000000 = 3 = the number of FDE pointers in the table. +// Entry(1): 480E0000 B8FFFFFF +// 480E0000 = 0x11000 - .eh_frame_hdr(0x101B8) = 0xE48 +// B8FFFFFF = address of FDE(1) - .eh_frame_hdr(0x101B8) = +// = .eh_frame(0x10158) + 24 - 0x101B8 = 0xFFFFFFB8 +// Entry(2): 490E0000 D0FFFFFF +// 490E0000 = 0x11001 - .eh_frame_hdr(0x101B8) = 0xE49 +// D0FFFFFF = address of FDE(2) - .eh_frame_hdr(0x101B8) = +// = .eh_frame(0x10158) + 24 + 24 - 0x101B8 = 0xFFFFFFD0 +// Entry(3): 4A0E0000 E8FFFFFF +// 4A0E0000 = 0x11002 - .eh_frame_hdr(0x101B8) = 0xE4A +// E8FFFFFF = address of FDE(2) - .eh_frame_hdr(0x101B8) = +// = .eh_frame(0x10158) + 24 + 24 - 0x101B8 = 0xFFFFFFE8 +// HDR-NEXT: ) +// HDR-NEXT: } +// HDR: ProgramHeaders [ +// HDR: ProgramHeader { +// HDR: Type: PT_GNU_EH_FRAME +// HDR-NEXT: Offset: 0x1B8 +// HDR-NEXT: VirtualAddress: 0x101B8 +// HDR-NEXT: PhysicalAddress: 0x101B8 +// HDR-NEXT: FileSize: 36 +// HDR-NEXT: MemSize: 36 +// HDR-NEXT: Flags [ +// HDR-NEXT: PF_R +// HDR-NEXT: ] +// HDR-NEXT: Alignment: 1 +// HDR-NEXT: } diff --git a/test/ELF/eh-frame-marker.s b/test/ELF/eh-frame-marker.s new file mode 100644 index 000000000000..a5de2a7c3d40 --- /dev/null +++ b/test/ELF/eh-frame-marker.s @@ -0,0 +1,6 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared +// We used to crash on this. + .section .eh_frame +foo: + .long 0 diff --git a/test/ELF/eh-frame-merge.s b/test/ELF/eh-frame-merge.s index 2b0e4a52822d..2610d4d4d2de 100644 --- a/test/ELF/eh-frame-merge.s +++ b/test/ELF/eh-frame-merge.s @@ -21,7 +21,7 @@ // * There is only one copy of the second FDE // CHECK: Name: .eh_frame -// CHECK-NEXT: Type: SHT_X86_64_UNWIND +// CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] diff --git a/test/ELF/eh-frame-multilpe-cie.s b/test/ELF/eh-frame-multilpe-cie.s new file mode 100644 index 000000000000..12781ff5b6e9 --- /dev/null +++ b/test/ELF/eh-frame-multilpe-cie.s @@ -0,0 +1,12 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared +// We would fail to parse multiple cies in the same file. + + .cfi_startproc + .cfi_personality 0x9b, foo + .cfi_endproc + + .cfi_startproc + .cfi_endproc + +foo: diff --git a/test/ELF/eh-frame-type.test b/test/ELF/eh-frame-type.test index f59ab116d7dd..756299739e16 100644 --- a/test/ELF/eh-frame-type.test +++ b/test/ELF/eh-frame-type.test @@ -1,10 +1,11 @@ -# RUN: yaml2obj -format elf %s -o %t.o +# RUN: yaml2obj %s -o %t.o # RUN: ld.lld %t.o -o %t -shared # RUN: llvm-readobj -s %t | FileCheck %s # CHECK: Name: .eh_frame -# CHECK-NEXT: Type: SHT_X86_64_UNWIND +# CHECK-NEXT: Type: SHT_PROGBITS +!ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB diff --git a/test/ELF/ehframe-relocation.s b/test/ELF/ehframe-relocation.s index f952ebc60865..8d5e14919e92 100644 --- a/test/ELF/ehframe-relocation.s +++ b/test/ELF/ehframe-relocation.s @@ -1,17 +1,19 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: ld.lld %t.o -o %t +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/ehframe-relocation.s -o %t2.o +// RUN: ld.lld %t.o %t2.o -o %t // RUN: llvm-readobj -s %t | FileCheck %s // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s // CHECK: Name: .eh_frame -// CHECK-NEXT: Type: SHT_X86_64_UNWIND +// CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x10120 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Size: 48 +// CHECK-NOT: .eh_frame // 0x10120 = 65824 // 0x10120 + 5 = 65829 diff --git a/test/ELF/empty-ver.s b/test/ELF/empty-ver.s new file mode 100644 index 000000000000..f200d2876e09 --- /dev/null +++ b/test/ELF/empty-ver.s @@ -0,0 +1,25 @@ +// REQUIRES: x86 +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared -version-script %p/Inputs/empty-ver.ver +// RUN: llvm-readobj -version-info %t.so | FileCheck %s + +// CHECK: Version symbols { +// CHECK-NEXT: Section Name: +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Link: +// CHECK-NEXT: Symbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Version: 0 +// CHECK-NEXT: Name: @ +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Version: 2 +// CHECK-NEXT: Name: foo@ver +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + + +.global foo@ver +foo@ver: diff --git a/test/ELF/emulation.s b/test/ELF/emulation.s index a8a8f398c42c..7cc764fc6c18 100644 --- a/test/ELF/emulation.s +++ b/test/ELF/emulation.s @@ -29,6 +29,37 @@ # X86-64-NEXT: StringTableSectionIndex: # X86-64-NEXT: } +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnux32 %s -o %tx32 +# RUN: ld.lld -m elf32_x86_64 %tx32 -o %t2x32 +# RUN: llvm-readobj -file-headers %t2x32 | FileCheck --check-prefix=X32 %s +# RUN: ld.lld %tx32 -o %t3x32 +# RUN: llvm-readobj -file-headers %t3x32 | FileCheck --check-prefix=X32 %s +# X32: ElfHeader { +# X32-NEXT: Ident { +# X32-NEXT: Magic: (7F 45 4C 46) +# X32-NEXT: Class: 32-bit (0x1) +# X32-NEXT: DataEncoding: LittleEndian (0x1) +# X32-NEXT: FileVersion: 1 +# X32-NEXT: OS/ABI: SystemV (0x0) +# X32-NEXT: ABIVersion: 0 +# X32-NEXT: Unused: (00 00 00 00 00 00 00) +# X32-NEXT: } +# X32-NEXT: Type: Executable (0x2) +# X32-NEXT: Machine: EM_X86_64 (0x3E) +# X32-NEXT: Version: 1 +# X32-NEXT: Entry: +# X32-NEXT: ProgramHeaderOffset: 0x34 +# X32-NEXT: SectionHeaderOffset: +# X32-NEXT: Flags [ (0x0) +# X32-NEXT: ] +# X32-NEXT: HeaderSize: 52 +# X32-NEXT: ProgramHeaderEntrySize: 32 +# X32-NEXT: ProgramHeaderCount: +# X32-NEXT: SectionHeaderEntrySize: 40 +# X32-NEXT: SectionHeaderCount: +# X32-NEXT: StringTableSectionIndex: +# X32-NEXT: } + # RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tx86 # RUN: ld.lld -m elf_i386 %tx86 -o %t2x86 # RUN: llvm-readobj -file-headers %t2x86 | FileCheck --check-prefix=X86 %s @@ -60,6 +91,37 @@ # X86-NEXT: StringTableSectionIndex: # X86-NEXT: } +# RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd +# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd +# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s +# RUN: ld.lld %tx86fbsd -o %t3x86fbsd +# RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s +# X86FBSD: ElfHeader { +# X86FBSD-NEXT: Ident { +# X86FBSD-NEXT: Magic: (7F 45 4C 46) +# X86FBSD-NEXT: Class: 32-bit (0x1) +# X86FBSD-NEXT: DataEncoding: LittleEndian (0x1) +# X86FBSD-NEXT: FileVersion: 1 +# X86FBSD-NEXT: OS/ABI: FreeBSD (0x9) +# X86FBSD-NEXT: ABIVersion: 0 +# X86FBSD-NEXT: Unused: (00 00 00 00 00 00 00) +# X86FBSD-NEXT: } +# X86FBSD-NEXT: Type: Executable (0x2) +# X86FBSD-NEXT: Machine: EM_386 (0x3) +# X86FBSD-NEXT: Version: 1 +# X86FBSD-NEXT: Entry: +# X86FBSD-NEXT: ProgramHeaderOffset: 0x34 +# X86FBSD-NEXT: SectionHeaderOffset: +# X86FBSD-NEXT: Flags [ (0x0) +# X86FBSD-NEXT: ] +# X86FBSD-NEXT: HeaderSize: 52 +# X86FBSD-NEXT: ProgramHeaderEntrySize: 32 +# X86FBSD-NEXT: ProgramHeaderCount: +# X86FBSD-NEXT: SectionHeaderEntrySize: 40 +# X86FBSD-NEXT: SectionHeaderCount: +# X86FBSD-NEXT: StringTableSectionIndex: +# X86FBSD-NEXT: } + # RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %tppc64 # RUN: ld.lld -m elf64ppc %tppc64 -o %t2ppc64 # RUN: llvm-readobj -file-headers %t2ppc64 | FileCheck --check-prefix=PPC64 %s @@ -147,6 +209,60 @@ # MIPSEL-NEXT: EF_MIPS_CPIC # MIPSEL-NEXT: ] +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %tmips64 +# RUN: ld.lld -m elf64btsmip -e _start %tmips64 -o %t2mips64 +# RUN: llvm-readobj -file-headers %t2mips64 | FileCheck --check-prefix=MIPS64 %s +# RUN: ld.lld %tmips64 -e _start -o %t3mips64 +# RUN: llvm-readobj -file-headers %t3mips64 | FileCheck --check-prefix=MIPS64 %s +# MIPS64: ElfHeader { +# MIPS64-NEXT: Ident { +# MIPS64-NEXT: Magic: (7F 45 4C 46) +# MIPS64-NEXT: Class: 64-bit (0x2) +# MIPS64-NEXT: DataEncoding: BigEndian (0x2) +# MIPS64-NEXT: FileVersion: 1 +# MIPS64-NEXT: OS/ABI: SystemV (0x0) +# MIPS64-NEXT: ABIVersion: 0 +# MIPS64-NEXT: Unused: (00 00 00 00 00 00 00) +# MIPS64-NEXT: } +# MIPS64-NEXT: Type: Executable (0x2) +# MIPS64-NEXT: Machine: EM_MIPS (0x8) +# MIPS64-NEXT: Version: 1 +# MIPS64-NEXT: Entry: +# MIPS64-NEXT: ProgramHeaderOffset: 0x40 +# MIPS64-NEXT: SectionHeaderOffset: +# MIPS64-NEXT: Flags [ +# MIPS64-NEXT: EF_MIPS_ARCH_64R2 +# MIPS64-NEXT: EF_MIPS_CPIC +# MIPS64-NEXT: EF_MIPS_PIC +# MIPS64-NEXT: ] + +# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux %s -o %tmips64el +# RUN: ld.lld -m elf64ltsmip -e _start %tmips64el -o %t2mips64el +# RUN: llvm-readobj -file-headers %t2mips64el | FileCheck --check-prefix=MIPS64EL %s +# RUN: ld.lld %tmips64el -e _start -o %t3mips64el +# RUN: llvm-readobj -file-headers %t3mips64el | FileCheck --check-prefix=MIPS64EL %s +# MIPS64EL: ElfHeader { +# MIPS64EL-NEXT: Ident { +# MIPS64EL-NEXT: Magic: (7F 45 4C 46) +# MIPS64EL-NEXT: Class: 64-bit (0x2) +# MIPS64EL-NEXT: DataEncoding: LittleEndian (0x1) +# MIPS64EL-NEXT: FileVersion: 1 +# MIPS64EL-NEXT: OS/ABI: SystemV (0x0) +# MIPS64EL-NEXT: ABIVersion: 0 +# MIPS64EL-NEXT: Unused: (00 00 00 00 00 00 00) +# MIPS64EL-NEXT: } +# MIPS64EL-NEXT: Type: Executable (0x2) +# MIPS64EL-NEXT: Machine: EM_MIPS (0x8) +# MIPS64EL-NEXT: Version: 1 +# MIPS64EL-NEXT: Entry: +# MIPS64EL-NEXT: ProgramHeaderOffset: 0x40 +# MIPS64EL-NEXT: SectionHeaderOffset: +# MIPS64EL-NEXT: Flags [ +# MIPS64EL-NEXT: EF_MIPS_ARCH_64R2 +# MIPS64EL-NEXT: EF_MIPS_CPIC +# MIPS64EL-NEXT: EF_MIPS_PIC +# MIPS64EL-NEXT: ] + # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64 # RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64 # RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s @@ -173,5 +289,5 @@ # REQUIRES: x86,ppc,mips,aarch64 -.globl _start; +.globl _start _start: diff --git a/test/ELF/end.s b/test/ELF/end.s index 390e4445e2d8..689157f82070 100644 --- a/test/ELF/end.s +++ b/test/ELF/end.s @@ -36,13 +36,13 @@ // NOBSS-NEXT: SHF_ALLOC // NOBSS-NEXT: SHF_WRITE // NOBSS-NEXT: ] -// NOBSS-NEXT: Address: 0x12000 +// NOBSS-NEXT: Address: 0x159 // NOBSS-NEXT: Offset: // NOBSS-NEXT: Size: 2 // NOBSS: ] // NOBSS: Symbols [ // NOBSS: Name: _end -// NOBSS-NEXT: Value: 0x12002 +// NOBSS-NEXT: Value: 0x15B // NOBSS: ] // If the layout of the sections is changed, "_end" should point to the end of allocated address space. @@ -60,13 +60,13 @@ // TEXTATEND-NEXT: SHF_ALLOC // TEXTATEND-NEXT: SHF_EXECINSTR // TEXTATEND-NEXT: ] -// TEXTATEND-NEXT: Address: 0x12000 +// TEXTATEND-NEXT: Address: 0x160 // TEXTATEND-NEXT: Offset: // TEXTATEND-NEXT: Size: 1 // TEXTATEND: ] // TEXTATEND: Symbols [ // TEXTATEND: Name: _end -// TEXTATEND-NEXT: Value: 0x12001 +// TEXTATEND-NEXT: Value: 0x161 // TEXTATEND: ] .global _start,_end diff --git a/test/ELF/entry.s b/test/ELF/entry.s index c8758ece69eb..6175c7623a34 100644 --- a/test/ELF/entry.s +++ b/test/ELF/entry.s @@ -4,9 +4,9 @@ # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=SYM %s # RUN: ld.lld %t1 -shared -o %t2 -e entry # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DSO %s -# RUN: ld.lld %t1 -o %t2 -e 4096 +# RUN: ld.lld %t1 -o %t2 --entry=4096 # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DEC %s -# RUN: ld.lld %t1 -o %t2 -e 0xcafe +# RUN: ld.lld %t1 -o %t2 --entry 0xcafe # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=HEX %s # RUN: ld.lld %t1 -o %t2 -e 0777 # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s diff --git a/test/ELF/fatal-warnings.s b/test/ELF/fatal-warnings.s new file mode 100644 index 000000000000..0bc2a2b44476 --- /dev/null +++ b/test/ELF/fatal-warnings.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common.s -o %t2.o + +# RUN: ld.lld --warn-common %t1.o %t2.o -o %t1.out 2>&1 | \ +# RUN: FileCheck -check-prefix=ERR %s +# ERR: multiple common of + +# RUN: not ld.lld --warn-common --fatal-warnings %t1.o %t2.o -o %t2.out 2>&1 | \ +# RUN: FileCheck -check-prefix=ERR %s + +.globl _start +_start: + +.type arr,@object +.comm arr,4,4 diff --git a/test/ELF/file-sym.s b/test/ELF/file-sym.s new file mode 100644 index 000000000000..eddb461490c6 --- /dev/null +++ b/test/ELF/file-sym.s @@ -0,0 +1,12 @@ +# Check that we do not keep STT_FILE symbols in the symbol table + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -shared -o %t.so +# RUN: llvm-readobj -symbols %t.so | FileCheck %s + +# REQUIRES: x86 + +# CHECK-NOT: xxx + +.file "xxx" +.file "" diff --git a/test/ELF/gc-merge-local-sym.s b/test/ELF/gc-merge-local-sym.s new file mode 100644 index 000000000000..b02a3a4e4762 --- /dev/null +++ b/test/ELF/gc-merge-local-sym.s @@ -0,0 +1,34 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared -O3 --gc-sections +// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s + +// CHECK: Name: .rodata +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: SHF_STRINGS +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x1C8 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 1 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 61626300 |abc.| +// CHECK-NEXT: ) + +// CHECK: Symbols [ +// CHECK: Symbol { +// CHECK-NOT: Name: bar + + .global foo +foo: + leaq .L.str(%rip), %rsi + .section .rodata.str1.1,"aMS",@progbits,1 +.L.str: + .asciz "abc" +bar: + .asciz "def" diff --git a/test/ELF/gc-sections-eh.s b/test/ELF/gc-sections-eh.s index 042b68ebdfe2..88c3dd0d9ca4 100644 --- a/test/ELF/gc-sections-eh.s +++ b/test/ELF/gc-sections-eh.s @@ -1,10 +1,23 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + # RUN: ld.lld %t -o %t2 --gc-sections # RUN: llvm-readobj -t %t2 | FileCheck %s +# RUN: llvm-objdump --dwarf=frames %t2 | FileCheck --check-prefix=EH %s + +# RUN: ld.lld %t -o %t3 +# RUN: llvm-readobj -t %t3 | FileCheck --check-prefix=NOGC %s +# RUN: llvm-objdump --dwarf=frames %t3 | FileCheck --check-prefix=EHNOGC %s # CHECK-NOT: foo +# NOGC: foo + +# EH: FDE cie={{.*}} pc= +# EH-NOT: FDE + +# EHNOGC: FDE cie={{.*}} pc= +# EHNOGC: FDE cie={{.*}} pc= .section .text,"ax",@progbits,unique,0 .globl foo diff --git a/test/ELF/gc-sections-local-sym.s b/test/ELF/gc-sections-local-sym.s new file mode 100644 index 000000000000..89121e289cc2 --- /dev/null +++ b/test/ELF/gc-sections-local-sym.s @@ -0,0 +1,57 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: ld.lld %t -o %t2 -shared --gc-sections +// RUN: llvm-readobj -t -s -section-data %t2 | FileCheck %s +// REQUIRES: x86 + +.global foo +foo: + +.section .bar,"a" +zed: + +// CHECK: Name: .strtab +// CHECK-NEXT: Type: SHT_STRTAB +// CHECK-NEXT: Flags [ +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00666F6F 005F4459 4E414D49 4300 |.foo._DYNAMIC.| +// CHECK-NEXT: ) + +// CHECK: Symbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: (0) +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x1000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: foo +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/gc-sections-lsda.s b/test/ELF/gc-sections-lsda.s new file mode 100644 index 000000000000..b5bed8f0c816 --- /dev/null +++ b/test/ELF/gc-sections-lsda.s @@ -0,0 +1,21 @@ +// REQUIRES: x86 + +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld -shared --gc-sections %t.o -o %t + +// Test that we handle .eh_frame keeping sections alive. We could be more +// precise and gc the entire contents of this file, but test that at least +// we are consistent: if we keep .abc, we have to keep .foo + +// RUN: llvm-readobj -s %t | FileCheck %s +// CHECK: Name: .abc +// CHECK: Name: .foo (38) + + .cfi_startproc + .cfi_lsda 0x1b,zed + .cfi_endproc + .section .abc,"a" +zed: + .long bar-. + .section .foo,"ax" +bar: diff --git a/test/ELF/gc-sections-merge-addend.s b/test/ELF/gc-sections-merge-addend.s new file mode 100644 index 000000000000..8595f5802be5 --- /dev/null +++ b/test/ELF/gc-sections-merge-addend.s @@ -0,0 +1,39 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared --gc-sections +// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s + + +// CHECK: Name: .rodata +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: SHF_STRINGS +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 1 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 62617200 |bar.| +// CHECK-NEXT: ) + + .section .data.f,"aw",@progbits + .globl f +f: + .quad .rodata.str1.1 + 4 + + .section .data.g,"aw",@progbits + .hidden g + .globl g +g: + .quad .rodata.str1.1 + + .section .rodata.str1.1,"aMS",@progbits,1 +.L.str: + .asciz "foo" +.L.str.1: + .asciz "bar" diff --git a/test/ELF/gc-sections-merge-implicit-addend.s b/test/ELF/gc-sections-merge-implicit-addend.s new file mode 100644 index 000000000000..8a7c804a830a --- /dev/null +++ b/test/ELF/gc-sections-merge-implicit-addend.s @@ -0,0 +1,39 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared --gc-sections +// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s + + +// CHECK: Name: .rodata +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: SHF_STRINGS +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 1 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 62617200 |bar.| +// CHECK-NEXT: ) + + .section .data.f,"aw",@progbits + .globl f +f: + .long .rodata.str1.1 + 4 + + .section .data.g,"aw",@progbits + .hidden g + .globl g +g: + .long .rodata.str1.1 + + .section .rodata.str1.1,"aMS",@progbits,1 +.L.str: + .asciz "foo" +.L.str.1: + .asciz "bar" diff --git a/test/ELF/gc-sections-merge.s b/test/ELF/gc-sections-merge.s new file mode 100644 index 000000000000..ef2688659871 --- /dev/null +++ b/test/ELF/gc-sections-merge.s @@ -0,0 +1,61 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: ld.lld %t.o -o %t.gc.so -shared --gc-sections +// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s +// RUN: llvm-readobj -s -section-data %t.gc.so | FileCheck --check-prefix=GC %s + + +// CHECK: Name: .rodata +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: SHF_STRINGS +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 1 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 666F6F00 62617200 |foo.bar.| +// CHECK-NEXT: ) + +// GC: Name: .rodata +// GC-NEXT: Type: SHT_PROGBITS +// GC-NEXT: Flags [ +// GC-NEXT: SHF_ALLOC +// GC-NEXT: SHF_MERGE +// GC-NEXT: SHF_STRINGS +// GC-NEXT: ] +// GC-NEXT: Address: +// GC-NEXT: Offset: +// GC-NEXT: Size: 4 +// GC-NEXT: Link: 0 +// GC-NEXT: Info: 0 +// GC-NEXT: AddressAlignment: 1 +// GC-NEXT: EntrySize: 1 +// GC-NEXT: SectionData ( +// GC-NEXT: 0000: 666F6F00 |foo.| +// GC-NEXT: ) + + .section .text.f,"ax",@progbits + .globl f +f: + leaq .L.str(%rip), %rax + retq + + .section .text.g,"ax",@progbits + .hidden g + .globl g +g: + leaq .L.str.1(%rip), %rax + retq + + .section .rodata.str1.1,"aMS",@progbits,1 +.L.str: + .asciz "foo" +.L.str.1: + .asciz "bar" diff --git a/test/ELF/gc-sections-protected.s b/test/ELF/gc-sections-protected.s new file mode 100644 index 000000000000..9f1efed5938a --- /dev/null +++ b/test/ELF/gc-sections-protected.s @@ -0,0 +1,18 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared --gc-sections +// RUN: llvm-readobj -s %t.so | FileCheck %s + +// CHECK: Name: .text +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 1 + +.protected g +.globl g +g: +retq diff --git a/test/ELF/gc-sections-shared.s b/test/ELF/gc-sections-shared.s new file mode 100644 index 000000000000..d52eae2177b2 --- /dev/null +++ b/test/ELF/gc-sections-shared.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t2.so +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t %t.o --as-needed %t2.so +# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s + +# This test the property that we have a needed line for every undefined. +# It would also be OK to drop bar2 and the need for the .so + + +# CHECK: Name: bar +# CHECK: Name: bar2 +# CHECK: Name: foo +# CHECK: NEEDED SharedLibrary ({{.*}}.so) + + +.section .text.foo, "ax" +.globl foo +foo: +call bar + +.section .text.bar, "ax" +.globl bar +bar: +ret + +.section .text._start, "ax" +.globl _start +_start: +ret + +.section .text.unused, "ax" +call bar2 diff --git a/test/ELF/gc-sections-weak.s b/test/ELF/gc-sections-weak.s new file mode 100644 index 000000000000..625b613843ba --- /dev/null +++ b/test/ELF/gc-sections-weak.s @@ -0,0 +1,24 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gc-sections-weak.s -o %t2.o +// RUN: ld.lld %t.o %t2.o -o %t.so -shared --gc-sections +// RUN: llvm-readobj -s %t.so | FileCheck %s + +.global foo +foo: +nop + +.data +.global bar1 +bar1: +.quad foo + +// CHECK: Name: .text +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 1 diff --git a/test/ELF/global_offset_table_shared.s b/test/ELF/global_offset_table_shared.s new file mode 100644 index 000000000000..7935925ae2b3 --- /dev/null +++ b/test/ELF/global_offset_table_shared.s @@ -0,0 +1,9 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +// RUN: ld.lld -shared %t -o %t2 +// RUN: llvm-readobj -t %t2 | FileCheck %s +.long _GLOBAL_OFFSET_TABLE_ + +// CHECK: Name: _GLOBAL_OFFSET_TABLE_ +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local diff --git a/test/ELF/gnu-ifunc-gotpcrel.s b/test/ELF/gnu-ifunc-gotpcrel.s new file mode 100644 index 000000000000..08aa0af37a1b --- /dev/null +++ b/test/ELF/gnu-ifunc-gotpcrel.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-gotpcrel.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t2.so +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o %t2.so -o %t +# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s + +# CHECK: Dynamic Relocations { +# CHECK-NEXT: 0x120B0 R_X86_64_GLOB_DAT foo 0x0 +# CHECK-NEXT: } + +.globl _start +_start: +mov foo@gotpcrel(%rip), %rax diff --git a/test/ELF/gnu-ifunc-i386.s b/test/ELF/gnu-ifunc-i386.s index 6dcdf256d70c..bc2d0f9610b3 100644 --- a/test/ELF/gnu-ifunc-i386.s +++ b/test/ELF/gnu-ifunc-i386.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o // RUN: ld.lld -static %t.o -o %tout // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM -// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s --check-prefix=CHECK +// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s // REQUIRES: x86 // CHECK: Sections [ @@ -43,8 +43,10 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rel.plt // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: __rel_iplt_start @@ -52,8 +54,10 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rel.plt // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start @@ -112,13 +116,11 @@ .text .type foo STT_GNU_IFUNC .globl foo -.type foo, @function foo: ret .type bar STT_GNU_IFUNC .globl bar -.type bar, @function bar: ret diff --git a/test/ELF/gnu-ifunc-nosym-i386.s b/test/ELF/gnu-ifunc-nosym-i386.s index 1101b6d763d5..d22cedbfe6de 100644 --- a/test/ELF/gnu-ifunc-nosym-i386.s +++ b/test/ELF/gnu-ifunc-nosym-i386.s @@ -6,20 +6,18 @@ // Check that no __rel_iplt_end/__rel_iplt_start // appear in symtab if there is no references to them. // CHECK: Symbols [ -// CHECK-NEXT-NOT: __rel_iplt_end -// CHECK-NEXT-NOT: __rel_iplt_start +// CHECK-NOT: __rel_iplt_end +// CHECK-NOT: __rel_iplt_start // CHECK: ] .text .type foo STT_GNU_IFUNC .globl foo -.type foo, @function foo: ret .type bar STT_GNU_IFUNC .globl bar -.type bar, @function bar: ret diff --git a/test/ELF/gnu-ifunc-nosym.s b/test/ELF/gnu-ifunc-nosym.s index c97fd749c02b..08e498e97c19 100644 --- a/test/ELF/gnu-ifunc-nosym.s +++ b/test/ELF/gnu-ifunc-nosym.s @@ -6,20 +6,18 @@ // Check that no __rela_iplt_end/__rela_iplt_start // appear in symtab if there is no references to them. // CHECK: Symbols [ -// CHECK-NEXT-NOT: __rela_iplt_end -// CHECK-NEXT-NOT: __rela_iplt_start +// CHECK-NOT: __rela_iplt_end +// CHECK-NOT: __rela_iplt_start // CHECK: ] .text .type foo STT_GNU_IFUNC .globl foo -.type foo, @function foo: ret .type bar STT_GNU_IFUNC .globl bar -.type bar, @function bar: ret diff --git a/test/ELF/gnu-ifunc-relative.s b/test/ELF/gnu-ifunc-relative.s new file mode 100644 index 000000000000..dc35102c5787 --- /dev/null +++ b/test/ELF/gnu-ifunc-relative.s @@ -0,0 +1,23 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld -static %t.o -o %tout +// RUN: llvm-readobj -r -t %tout | FileCheck %s +// REQUIRES: x86 + +.type foo STT_GNU_IFUNC +.globl foo +foo: + ret + +.globl _start +_start: + call foo + +// CHECK: Section ({{.*}}) .rela.plt { +// CHECK-NEXT: R_X86_64_IRELATIVE - 0x[[ADDR:.*]] +// CHECK-NEXT: } + +// CHECK: Name: foo +// CHECK-NEXT: Value: 0x[[ADDR]] +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: GNU_IFunc diff --git a/test/ELF/gnu-ifunc.s b/test/ELF/gnu-ifunc.s index b04f2758e22c..5336c89a563b 100644 --- a/test/ELF/gnu-ifunc.s +++ b/test/ELF/gnu-ifunc.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld -static %t.o -o %tout // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM -// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s --check-prefix=CHECK +// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s // REQUIRES: x86 // CHECK: Sections [ @@ -42,8 +42,10 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rela.plt // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: __rela_iplt_start @@ -51,8 +53,10 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: Absolute +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rela.plt // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start @@ -93,6 +97,7 @@ // DISASM-NEXT: 11007: e8 34 00 00 00 callq 52 // DISASM-NEXT: 1100c: ba 58 01 01 00 movl $65880, %edx // DISASM-NEXT: 11011: ba 88 01 01 00 movl $65928, %edx +// DISASM-NEXT: 11016: ba 89 01 01 00 movl $65929, %edx // DISASM-NEXT: Disassembly of section .plt: // DISASM-NEXT: .plt: // DISASM-NEXT: 11020: ff 35 e2 0f 00 00 pushq 4066(%rip) @@ -108,13 +113,11 @@ .text .type foo STT_GNU_IFUNC .globl foo -.type foo, @function foo: ret .type bar STT_GNU_IFUNC .globl bar -.type bar, @function bar: ret @@ -124,3 +127,4 @@ _start: call bar movl $__rela_iplt_start,%edx movl $__rela_iplt_end,%edx + movl $__rela_iplt_end + 1,%edx diff --git a/test/ELF/gnu-unique.s b/test/ELF/gnu-unique.s index f7206cf8c97f..afc0da27063d 100644 --- a/test/ELF/gnu-unique.s +++ b/test/ELF/gnu-unique.s @@ -1,7 +1,11 @@ +// REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +// // RUN: ld.lld %t -shared -o %tout.so -// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck %s -// REQUIRES: x86 +// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=GNU %s +// +// RUN: ld.lld %t -shared -o %tout.so --no-gnu-unique +// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=NO %s // Check that STB_GNU_UNIQUE is treated as a global and ends up in the dynamic // symbol table as STB_GNU_UNIQUE. @@ -14,11 +18,20 @@ _start: .type symb, @gnu_unique_object symb: -# CHECK: Name: symb@ -# CHECK-NEXT: Value: -# CHECK-NEXT: Size: 0 -# CHECK-NEXT: Binding: Unique -# CHECK-NEXT: Type: Object -# CHECK-NEXT: Other: 0 -# CHECK-NEXT: Section: .data -# CHECK-NEXT: } +# GNU: Name: symb@ +# GNU-NEXT: Value: +# GNU-NEXT: Size: 0 +# GNU-NEXT: Binding: Unique +# GNU-NEXT: Type: Object +# GNU-NEXT: Other: 0 +# GNU-NEXT: Section: .data +# GNU-NEXT: } + +# NO: Name: symb@ +# NO-NEXT: Value: +# NO-NEXT: Size: 0 +# NO-NEXT: Binding: Global +# NO-NEXT: Type: Object +# NO-NEXT: Other: 0 +# NO-NEXT: Section: .data +# NO-NEXT: } diff --git a/test/ELF/got-plt-header.s b/test/ELF/got-plt-header.s new file mode 100644 index 000000000000..691516d1a348 --- /dev/null +++ b/test/ELF/got-plt-header.s @@ -0,0 +1,30 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s + + call foo@plt + +// Check that the first .got.plt entry has the address of the dynamic table. + +// CHECK: Type: SHT_DYNAMIC +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2000 + +// CHECK: Name: .got.plt +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x3000 +// CHECK-NEXT: Offset: 0x3000 +// CHECK-NEXT: Size: 32 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 8 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00200000 00000000 00000000 00000000 diff --git a/test/ELF/gotpc-relax-nopic.s b/test/ELF/gotpc-relax-nopic.s new file mode 100644 index 000000000000..278173557837 --- /dev/null +++ b/test/ELF/gotpc-relax-nopic.s @@ -0,0 +1,81 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t1 +# RUN: llvm-readobj -symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s +# RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s + +## There is no relocations. +# SYMRELOC: Relocations [ +# SYMRELOC-NEXT: ] +# SYMRELOC: Symbols [ +# SYMRELOC: Symbol { +# SYMRELOC: Name: bar +# SYMRELOC-NEXT: Value: 0x12000 + +## 73728 = 0x12000 (bar) +# DISASM: Disassembly of section .text: +# DISASM-NEXT: _start: +# DISASM-NEXT: 11000: 48 81 d0 00 20 01 00 adcq $73728, %rax +# DISASM-NEXT: 11007: 48 81 c3 00 20 01 00 addq $73728, %rbx +# DISASM-NEXT: 1100e: 48 81 e1 00 20 01 00 andq $73728, %rcx +# DISASM-NEXT: 11015: 48 81 fa 00 20 01 00 cmpq $73728, %rdx +# DISASM-NEXT: 1101c: 48 81 cf 00 20 01 00 orq $73728, %rdi +# DISASM-NEXT: 11023: 48 81 de 00 20 01 00 sbbq $73728, %rsi +# DISASM-NEXT: 1102a: 48 81 ed 00 20 01 00 subq $73728, %rbp +# DISASM-NEXT: 11031: 49 81 f0 00 20 01 00 xorq $73728, %r8 +# DISASM-NEXT: 11038: 49 f7 c7 00 20 01 00 testq $73728, %r15 + +# RUN: ld.lld -shared %t.o -o %t2 +# RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=SEC-PIC %s +# RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM-PIC %s +# SEC-PIC: Section { +# SEC-PIC: Index: +# SEC-PIC: Name: .got +# SEC-PIC-NEXT: Type: SHT_PROGBITS +# SEC-PIC-NEXT: Flags [ +# SEC-PIC-NEXT: SHF_ALLOC +# SEC-PIC-NEXT: SHF_WRITE +# SEC-PIC-NEXT: ] +# SEC-PIC-NEXT: Address: 0x2090 +# SEC-PIC-NEXT: Offset: 0x2090 +# SEC-PIC-NEXT: Size: 8 +# SEC-PIC-NEXT: Link: +# SEC-PIC-NEXT: Info: +# SEC-PIC-NEXT: AddressAlignment: +# SEC-PIC-NEXT: EntrySize: +# SEC-PIC-NEXT: } + +## Check that there was no relaxation performed. All values refer to got entry. +## Ex: 0x1000 + 4233 + 7 = 0x2090 +## 0x102a + 4191 + 7 = 0x2090 +# DISASM-PIC: Disassembly of section .text: +# DISASM-PIC-NEXT: _start: +# DISASM-PIC-NEXT: 1000: 48 13 05 89 10 00 00 adcq 4233(%rip), %rax +# DISASM-PIC-NEXT: 1007: 48 03 1d 82 10 00 00 addq 4226(%rip), %rbx +# DISASM-PIC-NEXT: 100e: 48 23 0d 7b 10 00 00 andq 4219(%rip), %rcx +# DISASM-PIC-NEXT: 1015: 48 3b 15 74 10 00 00 cmpq 4212(%rip), %rdx +# DISASM-PIC-NEXT: 101c: 48 0b 3d 6d 10 00 00 orq 4205(%rip), %rdi +# DISASM-PIC-NEXT: 1023: 48 1b 35 66 10 00 00 sbbq 4198(%rip), %rsi +# DISASM-PIC-NEXT: 102a: 48 2b 2d 5f 10 00 00 subq 4191(%rip), %rbp +# DISASM-PIC-NEXT: 1031: 4c 33 05 58 10 00 00 xorq 4184(%rip), %r8 +# DISASM-PIC-NEXT: 1038: 4c 85 3d 51 10 00 00 testq 4177(%rip), %r15 + +.data +.type bar, @object +bar: + .byte 1 + .size bar, .-bar + +.text +.globl _start +.type _start, @function +_start: + adcq bar@GOTPCREL(%rip), %rax + addq bar@GOTPCREL(%rip), %rbx + andq bar@GOTPCREL(%rip), %rcx + cmpq bar@GOTPCREL(%rip), %rdx + orq bar@GOTPCREL(%rip), %rdi + sbbq bar@GOTPCREL(%rip), %rsi + subq bar@GOTPCREL(%rip), %rbp + xorq bar@GOTPCREL(%rip), %r8 + testq %r15, bar@GOTPCREL(%rip) diff --git a/test/ELF/gotpc-relax-und-dso.s b/test/ELF/gotpc-relax-und-dso.s new file mode 100644 index 000000000000..ed6c4bc9bb15 --- /dev/null +++ b/test/ELF/gotpc-relax-und-dso.s @@ -0,0 +1,72 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %S/Inputs/gotpc-relax-und-dso.s -o %tdso.o +# RUN: ld.lld -shared %tdso.o -o %t.so +# RUN: ld.lld -shared %t.o %t.so -o %tout +# RUN: llvm-readobj -r -s %tout | FileCheck --check-prefix=RELOC %s +# RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s + +# RELOC: Relocations [ +# RELOC-NEXT: Section ({{.*}}) .rela.dyn { +# RELOC-NEXT: R_X86_64_GLOB_DAT dsofoo 0x0 +# RELOC-NEXT: R_X86_64_GLOB_DAT foo 0x0 +# RELOC-NEXT: R_X86_64_GLOB_DAT und 0x0 +# RELOC-NEXT: } +# RELOC-NEXT: ] + +# 0x101e + 7 - 36 = 0x1001 +# 0x1025 + 7 - 43 = 0x1001 +# DISASM: Disassembly of section .text: +# DISASM-NEXT: foo: +# DISASM-NEXT: nop +# DISASM: hid: +# DISASM-NEXT: nop +# DISASM: _start: +# DISASM-NEXT: movq 4247(%rip), %rax +# DISASM-NEXT: movq 4240(%rip), %rax +# DISASM-NEXT: movq 4241(%rip), %rax +# DISASM-NEXT: movq 4234(%rip), %rax +# DISASM-NEXT: leaq -36(%rip), %rax +# DISASM-NEXT: leaq -43(%rip), %rax +# DISASM-NEXT: movq 4221(%rip), %rax +# DISASM-NEXT: movq 4214(%rip), %rax +# DISASM-NEXT: movq 4191(%rip), %rax +# DISASM-NEXT: movq 4184(%rip), %rax +# DISASM-NEXT: movq 4185(%rip), %rax +# DISASM-NEXT: movq 4178(%rip), %rax +# DISASM-NEXT: leaq -92(%rip), %rax +# DISASM-NEXT: leaq -99(%rip), %rax +# DISASM-NEXT: movq 4165(%rip), %rax +# DISASM-NEXT: movq 4158(%rip), %rax + +.text +.globl foo +.type foo, @function +foo: + nop + +.globl hid +.hidden hid +.type hid, @function +hid: + nop + +.globl _start +.type _start, @function +_start: + movq und@GOTPCREL(%rip), %rax + movq und@GOTPCREL(%rip), %rax + movq dsofoo@GOTPCREL(%rip), %rax + movq dsofoo@GOTPCREL(%rip), %rax + movq hid@GOTPCREL(%rip), %rax + movq hid@GOTPCREL(%rip), %rax + movq foo@GOTPCREL(%rip), %rax + movq foo@GOTPCREL(%rip), %rax + movq und@GOTPCREL(%rip), %rax + movq und@GOTPCREL(%rip), %rax + movq dsofoo@GOTPCREL(%rip), %rax + movq dsofoo@GOTPCREL(%rip), %rax + movq hid@GOTPCREL(%rip), %rax + movq hid@GOTPCREL(%rip), %rax + movq foo@GOTPCREL(%rip), %rax + movq foo@GOTPCREL(%rip), %rax diff --git a/test/ELF/gotpc-relax.s b/test/ELF/gotpc-relax.s new file mode 100644 index 000000000000..422e10439d00 --- /dev/null +++ b/test/ELF/gotpc-relax.s @@ -0,0 +1,98 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t1 +# RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s +# RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s + +## There is no relocations. +# RELOC: Relocations [ +# RELOC: ] + +# 0x11003 + 7 - 10 = 0x11000 +# 0x1100a + 7 - 17 = 0x11000 +# 0x11011 + 7 - 23 = 0x11001 +# 0x11018 + 7 - 30 = 0x11001 +# DISASM: Disassembly of section .text: +# DISASM-NEXT: foo: +# DISASM-NEXT: 11000: 90 nop +# DISASM: hid: +# DISASM-NEXT: 11001: 90 nop +# DISASM: ifunc: +# DISASM-NEXT: 11002: c3 retq +# DISASM: _start: +# DISASM-NEXT: leaq -10(%rip), %rax +# DISASM-NEXT: leaq -17(%rip), %rax +# DISASM-NEXT: leaq -23(%rip), %rax +# DISASM-NEXT: leaq -30(%rip), %rax +# DISASM-NEXT: movq 4058(%rip), %rax +# DISASM-NEXT: movq 4051(%rip), %rax +# DISASM-NEXT: leaq -52(%rip), %rax +# DISASM-NEXT: leaq -59(%rip), %rax +# DISASM-NEXT: leaq -65(%rip), %rax +# DISASM-NEXT: leaq -72(%rip), %rax +# DISASM-NEXT: movq 4016(%rip), %rax +# DISASM-NEXT: movq 4009(%rip), %rax +# DISASM-NEXT: callq -93 <foo> +# DISASM-NEXT: callq -99 <foo> +# DISASM-NEXT: callq -104 <hid> +# DISASM-NEXT: callq -110 <hid> +# DISASM-NEXT: callq *3979(%rip) +# DISASM-NEXT: callq *3973(%rip) +# DISASM-NEXT: jmp -128 <foo> +# DISASM-NEXT: nop +# DISASM-NEXT: jmp -134 <foo> +# DISASM-NEXT: nop +# DISASM-NEXT: jmp -139 <hid> +# DISASM-NEXT: nop +# DISASM-NEXT: jmp -145 <hid> +# DISASM-NEXT: nop +# DISASM-NEXT: jmpq *3943(%rip) +# DISASM-NEXT: jmpq *3937(%rip) + +.text +.globl foo +.type foo, @function +foo: + nop + +.globl hid +.hidden hid +.type hid, @function +hid: + nop + +.text +.type ifunc STT_GNU_IFUNC +.globl ifunc +.type ifunc, @function +ifunc: + ret + +.globl _start +.type _start, @function +_start: + movq foo@GOTPCREL(%rip), %rax + movq foo@GOTPCREL(%rip), %rax + movq hid@GOTPCREL(%rip), %rax + movq hid@GOTPCREL(%rip), %rax + movq ifunc@GOTPCREL(%rip), %rax + movq ifunc@GOTPCREL(%rip), %rax + movq foo@GOTPCREL(%rip), %rax + movq foo@GOTPCREL(%rip), %rax + movq hid@GOTPCREL(%rip), %rax + movq hid@GOTPCREL(%rip), %rax + movq ifunc@GOTPCREL(%rip), %rax + movq ifunc@GOTPCREL(%rip), %rax + + call *foo@GOTPCREL(%rip) + call *foo@GOTPCREL(%rip) + call *hid@GOTPCREL(%rip) + call *hid@GOTPCREL(%rip) + call *ifunc@GOTPCREL(%rip) + call *ifunc@GOTPCREL(%rip) + jmp *foo@GOTPCREL(%rip) + jmp *foo@GOTPCREL(%rip) + jmp *hid@GOTPCREL(%rip) + jmp *hid@GOTPCREL(%rip) + jmp *ifunc@GOTPCREL(%rip) + jmp *ifunc@GOTPCREL(%rip) diff --git a/test/ELF/gotpcrelx.s b/test/ELF/gotpcrelx.s new file mode 100644 index 000000000000..95dbf663ffe8 --- /dev/null +++ b/test/ELF/gotpcrelx.s @@ -0,0 +1,30 @@ +// RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux-gnu \ +// RUN: %s -o %t.o +// RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELS %s +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -s -r %t.so | FileCheck %s + +movq foo@GOTPCREL(%rip), %rax +movq bar@GOTPCREL(%rip), %rax + +// RELS: Relocations [ +// RELS-NEXT: Section ({{.*}}) .rela.text { +// RELS-NEXT: R_X86_64_REX_GOTPCRELX foo 0xFFFFFFFFFFFFFFFC +// RELS-NEXT: R_X86_64_REX_GOTPCRELX bar 0xFFFFFFFFFFFFFFFC +// RELS-NEXT: } +// RELS-NEXT: ] + +// CHECK: Name: .got +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2090 + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x2098 R_X86_64_GLOB_DAT bar 0x0 +// CHECK-NEXT: 0x2090 R_X86_64_GLOB_DAT foo 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/i386-got-and-copy.s b/test/ELF/i386-got-and-copy.s new file mode 100644 index 000000000000..f5b0b8ec5bb8 --- /dev/null +++ b/test/ELF/i386-got-and-copy.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 + +# If there are two relocations such that the first one requires +# dynamic COPY relocation, the second one requires GOT entry +# creation, linker should create both - dynamic relocation +# and GOT entry. + +# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux \ +# RUN: %S/Inputs/copy-in-shared.s -o %t.so.o +# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o +# RUN: ld.lld %t.so.o -shared -o %t.so +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-readobj -r %t.exe | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section (4) .rel.dyn { +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_COPY foo +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .text + .global _start +_start: + movl $foo, (%esp) # R_386_32 - requires R_386_COPY relocation + movl foo@GOT, %eax # R_386_GOT32 - requires GOT entry diff --git a/test/ELF/i386-gotpc.s b/test/ELF/i386-gotpc.s new file mode 100644 index 000000000000..14c2fcbec064 --- /dev/null +++ b/test/ELF/i386-gotpc.s @@ -0,0 +1,20 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -s %t.so | FileCheck %s +// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s + +movl $_GLOBAL_OFFSET_TABLE_, %eax + +// CHECK: Name: .got (38) +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2030 + +// DISASM: Disassembly of section .text: +// DISASM-NEXT: .text: +// DISASM-NEXT: 1000: {{.*}} movl $4144, %eax +// 0x2030 - 0x1000 = 4144 diff --git a/test/ELF/i386-merge.s b/test/ELF/i386-merge.s new file mode 100644 index 000000000000..5d48d4d07f08 --- /dev/null +++ b/test/ELF/i386-merge.s @@ -0,0 +1,50 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t -shared +// RUN: llvm-readobj -s -section-data %t | FileCheck %s + +// CHECK: Name: .mysec +// CHECK-NEXT: Type: +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x114 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 42000000 | +// CHECK-NEXT: ) + + +// CHECK: Name: .data +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2000 +// CHECK-NEXT: Offset: 0x2000 +// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 14010000 | +// CHECK-NEXT: ) + +// The content of .data should be the address of .mysec. 14010000 is 0x114 in +// little endian. + + .data + .long .mysec+4 + + .section .mysec,"aM",@progbits,4 + .align 4 + .long 0x42 + .long 0x42 diff --git a/test/ELF/i386-relative.s b/test/ELF/i386-relative.s new file mode 100644 index 000000000000..d814b5b6786a --- /dev/null +++ b/test/ELF/i386-relative.s @@ -0,0 +1,14 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o +// RUN: ld.lld -shared %t.o -o %t.so +// RUN: llvm-readobj -r %t.so | FileCheck %s + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rel.dyn { +// CHECK-NEXT: R_386_RELATIVE - 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] + + .data +foo: + .long foo diff --git a/test/ELF/i386-relax-reloc.s b/test/ELF/i386-relax-reloc.s new file mode 100644 index 000000000000..a7fdc404ceca --- /dev/null +++ b/test/ELF/i386-relax-reloc.s @@ -0,0 +1,12 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o -relax-relocations +// RUN: ld.lld -shared %t.o -o %t.so +// RUN: llvm-objdump -d %t.so | FileCheck %s + +foo: + movl bar@GOT(%ebx), %eax + movl bar+8@GOT(%ebx), %eax + +// CHECK: foo: +// CHECK-NEXT: movl -4(%ebx), %eax +// CHECK-NEXT: movl 4(%ebx), %eax diff --git a/test/ELF/i386-tls-ie-shared.s b/test/ELF/i386-tls-ie-shared.s new file mode 100644 index 000000000000..a2c25e2d2f81 --- /dev/null +++ b/test/ELF/i386-tls-ie-shared.s @@ -0,0 +1,110 @@ +// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o +// RUN: ld.lld -shared %tso.o -o %tso +// RUN: ld.lld -shared %t.o %tso -o %t1 +// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTRELSHARED %s +// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s + +// GOTRELSHARED: Section { +// GOTRELSHARED: Index: 8 +// GOTRELSHARED: Name: .got +// GOTRELSHARED-NEXT: Type: SHT_PROGBITS +// GOTRELSHARED-NEXT: Flags [ +// GOTRELSHARED-NEXT: SHF_ALLOC +// GOTRELSHARED-NEXT: SHF_WRITE +// GOTRELSHARED-NEXT: ] +// GOTRELSHARED-NEXT: Address: 0x1050 +// GOTRELSHARED-NEXT: Offset: 0x1050 +// GOTRELSHARED-NEXT: Size: 16 +// GOTRELSHARED-NEXT: Link: 0 +// GOTRELSHARED-NEXT: Info: 0 +// GOTRELSHARED-NEXT: AddressAlignment: 4 +// GOTRELSHARED-NEXT: EntrySize: 0 +// GOTRELSHARED-NEXT: } +// GOTRELSHARED: Relocations [ +// GOTRELSHARED-NEXT: Section ({{.*}}) .rel.dyn { +// GOTRELSHARED-NEXT: 0x2002 R_386_RELATIVE - 0x0 +// GOTRELSHARED-NEXT: 0x200A R_386_RELATIVE - 0x0 +// GOTRELSHARED-NEXT: 0x2013 R_386_RELATIVE - 0x0 +// GOTRELSHARED-NEXT: 0x201C R_386_RELATIVE - 0x0 +// GOTRELSHARED-NEXT: 0x2024 R_386_RELATIVE - 0x0 +// GOTRELSHARED-NEXT: 0x202D R_386_RELATIVE - 0x0 +// GOTRELSHARED-NEXT: 0x2036 R_386_RELATIVE - 0x0 +// GOTRELSHARED-NEXT: 0x203F R_386_RELATIVE - 0x0 +// GOTRELSHARED-NEXT: 0x1050 R_386_TLS_TPOFF tlslocal0 0x0 +// GOTRELSHARED-NEXT: 0x1054 R_386_TLS_TPOFF tlslocal1 0x0 +// GOTRELSHARED-NEXT: 0x1058 R_386_TLS_TPOFF tlsshared0 0x0 +// GOTRELSHARED-NEXT: 0x105C R_386_TLS_TPOFF tlsshared1 0x0 +// GOTRELSHARED-NEXT: } +// GOTRELSHARED-NEXT: ] + +// DISASMSHARED: Disassembly of section test: +// DISASMSHARED-NEXT: _start: +// (.got)[0] = 0x2050 = 8272 +// (.got)[1] = 0x2054 = 8276 +// (.got)[2] = 0x2058 = 8280 +// (.got)[3] = 0x205C = 8284 +// DISASMSHARED-NEXT: 2000: 8b 0d 50 10 00 00 movl 4176, %ecx +// DISASMSHARED-NEXT: 2006: 65 8b 01 movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 2009: a1 50 10 00 00 movl 4176, %eax +// DISASMSHARED-NEXT: 200e: 65 8b 00 movl %gs:(%eax), %eax +// DISASMSHARED-NEXT: 2011: 03 0d 50 10 00 00 addl 4176, %ecx +// DISASMSHARED-NEXT: 2017: 65 8b 01 movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 201a: 8b 0d 54 10 00 00 movl 4180, %ecx +// DISASMSHARED-NEXT: 2020: 65 8b 01 movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 2023: a1 54 10 00 00 movl 4180, %eax +// DISASMSHARED-NEXT: 2028: 65 8b 00 movl %gs:(%eax), %eax +// DISASMSHARED-NEXT: 202b: 03 0d 54 10 00 00 addl 4180, %ecx +// DISASMSHARED-NEXT: 2031: 65 8b 01 movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 2034: 8b 0d 58 10 00 00 movl 4184, %ecx +// DISASMSHARED-NEXT: 203a: 65 8b 01 movl %gs:(%ecx), %eax +// DISASMSHARED-NEXT: 203d: 03 0d 5c 10 00 00 addl 4188, %ecx +// DISASMSHARED-NEXT: 2043: 65 8b 01 movl %gs:(%ecx), %eax + +.type tlslocal0,@object +.section .tbss,"awT",@nobits +.globl tlslocal0 +.align 4 +tlslocal0: + .long 0 + .size tlslocal0, 4 + +.type tlslocal1,@object +.section .tbss,"awT",@nobits +.globl tlslocal1 +.align 4 +tlslocal1: + .long 0 + .size tlslocal1, 4 + +.section .text +.globl ___tls_get_addr +.type ___tls_get_addr,@function +___tls_get_addr: + +.section test, "axw" +.globl _start +_start: +movl tlslocal0@indntpoff,%ecx +movl %gs:(%ecx),%eax + +movl tlslocal0@indntpoff,%eax +movl %gs:(%eax),%eax + +addl tlslocal0@indntpoff,%ecx +movl %gs:(%ecx),%eax + +movl tlslocal1@indntpoff,%ecx +movl %gs:(%ecx),%eax + +movl tlslocal1@indntpoff,%eax +movl %gs:(%eax),%eax + +addl tlslocal1@indntpoff,%ecx +movl %gs:(%ecx),%eax + +movl tlsshared0@indntpoff,%ecx +movl %gs:(%ecx),%eax + +addl tlsshared1@indntpoff,%ecx +movl %gs:(%ecx),%eax diff --git a/test/ELF/icf1.s b/test/ELF/icf1.s new file mode 100644 index 000000000000..bb060078476e --- /dev/null +++ b/test/ELF/icf1.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s + +# CHECK: selected .text.f1 +# CHECK: removed .text.f2 + +.globl _start, f1, f2 +_start: + ret + +.section .text.f1, "ax" +f1: + mov $60, %rax + mov $42, %rdi + syscall + +.section .text.f2, "ax" +f2: + mov $60, %rax + mov $42, %rdi + syscall diff --git a/test/ELF/icf2.s b/test/ELF/icf2.s new file mode 100644 index 000000000000..be595112b7e7 --- /dev/null +++ b/test/ELF/icf2.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2 +# RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose | FileCheck %s + +# CHECK: selected .text.f1 +# CHECK: removed .text.f2 + +.globl _start, f1, f2 +_start: + ret + +.section .text.f1, "ax" +f1: + mov $60, %rdi + call f2 diff --git a/test/ELF/icf3.s b/test/ELF/icf3.s new file mode 100644 index 000000000000..9f39ff6c7477 --- /dev/null +++ b/test/ELF/icf3.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2 +# RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose | FileCheck %s + +# CHECK-NOT: Selected .text.f1 +# CHECK-NOT: Selected .text.f2 + +.globl _start, f1, f2 +_start: + ret + +# This section is not mergeable because the content is different from f2. +.section .text.f1, "ax" +f1: + mov $60, %rdi + call f2 + mov $0, %rax diff --git a/test/ELF/icf4.s b/test/ELF/icf4.s new file mode 100644 index 000000000000..ad16d48775d6 --- /dev/null +++ b/test/ELF/icf4.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t --icf=all --verbose | FileCheck %s + +# CHECK-NOT: Selected .text.f1 +# CHECK-NOT: Selected .text.f2 + +.globl _start, f1, f2 +_start: + ret + +.section .text.f1, "ax" +f1: + mov $1, %rax + +.section .text.f2, "ax" +f2: + mov $0, %rax diff --git a/test/ELF/icf5.s b/test/ELF/icf5.s new file mode 100644 index 000000000000..cf466585c581 --- /dev/null +++ b/test/ELF/icf5.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t --icf=all --verbose | FileCheck %s + +# CHECK-NOT: Selected .text.f1 +# CHECK-NOT: Selected .text.f2 + +.globl _start, f1, f2 +_start: + ret + +.section .text.f1, "ax" +f1: + mov $0, %rax + +.section .text.f2, "awx" +f2: + mov $0, %rax diff --git a/test/ELF/icf6.s b/test/ELF/icf6.s new file mode 100644 index 000000000000..ecb62fee2a0c --- /dev/null +++ b/test/ELF/icf6.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s + +# CHECK-NOT: Selected .text.f1 +# CHECK-NOT: Selected .text.f2 + +.globl _start, f1, f2 +_start: + ret + +.section .init, "ax" +f1: + mov $60, %rax + mov $42, %rdi + syscall + +.section .fini, "ax" +f2: + mov $60, %rax + mov $42, %rdi + syscall diff --git a/test/ELF/icf7.s b/test/ELF/icf7.s new file mode 100644 index 000000000000..f1fca5b2f2d5 --- /dev/null +++ b/test/ELF/icf7.s @@ -0,0 +1,29 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s +# RUN: llvm-objdump -t %t2 | FileCheck -check-prefix=ALIGN %s + +# CHECK: selected .text.f1 +# CHECK: removed .text.f2 + +# ALIGN: 0000000000011000 .text 00000000 _start +# ALIGN: 0000000000011100 .text 00000000 f1 + +.globl _start, f1, f2 +_start: + ret + +.section .text.f1, "ax" + .align 1 +f1: + mov $60, %rax + mov $42, %rdi + syscall + +.section .text.f2, "ax" + .align 256 +f2: + mov $60, %rax + mov $42, %rdi + syscall diff --git a/test/ELF/image-base.s b/test/ELF/image-base.s new file mode 100644 index 000000000000..0be5059dcad8 --- /dev/null +++ b/test/ELF/image-base.s @@ -0,0 +1,60 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld -image-base=0x1000000 %t -o %t1 +# RUN: llvm-readobj -program-headers %t1 | FileCheck %s + +.global _start +_start: + nop + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0x1000040 +# CHECK-NEXT: PhysicalAddress: 0x1000040 +# CHECK-NEXT: FileSize: 224 +# CHECK-NEXT: MemSize: 224 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x1000000 +# CHECK-NEXT: PhysicalAddress: 0x1000000 +# CHECK-NEXT: FileSize: 288 +# CHECK-NEXT: MemSize: 288 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1001000 +# CHECK-NEXT: PhysicalAddress: 0x1001000 +# CHECK-NEXT: FileSize: 1 +# CHECK-NEXT: MemSize: 1 +# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_X (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x0 +# CHECK-NEXT: PhysicalAddress: 0x0 +# CHECK-NEXT: FileSize: 0 +# CHECK-NEXT: MemSize: 0 +# CHECK-NEXT: Flags [ (0x6) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_W (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 0 +# CHECK-NEXT: } diff --git a/test/ELF/incompatible.s b/test/ELF/incompatible.s index 1696d83de7ac..82055b7a104a 100644 --- a/test/ELF/incompatible.s +++ b/test/ELF/incompatible.s @@ -53,6 +53,7 @@ // ARCHIVE: a.o is incompatible with {{.*}}b.o .global _start _start: +.data .long foo // REQUIRES: x86,aarch64 diff --git a/test/ELF/init-fini.s b/test/ELF/init-fini.s index d2b24088d1e1..400679066636 100644 --- a/test/ELF/init-fini.s +++ b/test/ELF/init-fini.s @@ -35,7 +35,7 @@ // NOENTRY-NOT: FINI // NOENTRY: ] -.global _start,_init,_fini,_foo,_bar,_undef; +.global _start,_init,_fini,_foo,_bar,_undef _start: _init = 0x11010 _fini = 0x11020 diff --git a/test/ELF/init_fini_priority.s b/test/ELF/init_fini_priority.s new file mode 100644 index 000000000000..84e5dc35e9d2 --- /dev/null +++ b/test/ELF/init_fini_priority.s @@ -0,0 +1,37 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: ld.lld %t -o %t.exe +// RUN: llvm-objdump -s %t.exe | FileCheck %s +// REQUIRES: x86 + +.globl _start +_start: + nop + +.section .init_array, "aw", @init_array + .align 8 + .byte 1 +.section .init_array.100, "aw", @init_array + .long 2 +.section .init_array.5, "aw", @init_array + .byte 3 +.section .init_array, "aw", @init_array + .byte 4 +.section .init_array, "aw", @init_array + .byte 5 + +.section .fini_array, "aw", @fini_array + .align 8 + .byte 0x11 +.section .fini_array.100, "aw", @fini_array + .long 0x12 +.section .fini_array.5, "aw", @fini_array + .byte 0x13 +.section .fini_array, "aw", @fini_array + .byte 0x14 +.section .fini_array, "aw", @fini_array + .byte 0x15 + +// CHECK: Contents of section .init_array: +// CHECK-NEXT: 03020000 00000000 010405 +// CHECK: Contents of section .fini_array: +// CHECK-NEXT: 13120000 00000000 111415 diff --git a/test/ELF/invalid-cie-length.s b/test/ELF/invalid-cie-length.s index 36d1e03fb567..e9ad3ca8ba82 100644 --- a/test/ELF/invalid-cie-length.s +++ b/test/ELF/invalid-cie-length.s @@ -6,4 +6,4 @@ .section .eh_frame .byte 0 -// CHECK: Truncated CIE/FDE length +// CHECK: CIE/FDE too small diff --git a/test/ELF/invalid-cie-length3.s b/test/ELF/invalid-cie-length3.s index 8f3ab1cf29d0..665fc80a24b4 100644 --- a/test/ELF/invalid-cie-length3.s +++ b/test/ELF/invalid-cie-length3.s @@ -6,4 +6,4 @@ .section .eh_frame .long 0xFFFFFFFC -// CHECK: CIE/FIE size is too large +// CHECK: CIE/FIE ends past the end of the section diff --git a/test/ELF/invalid-cie-length4.s b/test/ELF/invalid-cie-length4.s index 4a51ca1f812d..daa20d196811 100644 --- a/test/ELF/invalid-cie-length4.s +++ b/test/ELF/invalid-cie-length4.s @@ -7,4 +7,4 @@ .long 0xFFFFFFFF .byte 0 -// CHECK: Truncated CIE/FDE length +// CHECK: CIE/FDE too large diff --git a/test/ELF/invalid-cie-length5.s b/test/ELF/invalid-cie-length5.s index 14054a2dee84..bfa35edf7db5 100644 --- a/test/ELF/invalid-cie-length5.s +++ b/test/ELF/invalid-cie-length5.s @@ -7,4 +7,4 @@ .long 0xFFFFFFFF .quad 0xFFFFFFFFFFFFFFF4 -// CHECK: CIE/FIE size is too large +// CHECK: CIE/FDE too large diff --git a/test/ELF/invalid-cie-reference.s b/test/ELF/invalid-cie-reference.s index 1b099d19b7e1..fba2467e216a 100644 --- a/test/ELF/invalid-cie-reference.s +++ b/test/ELF/invalid-cie-reference.s @@ -29,4 +29,4 @@ .long 0x0 .long 0x0 -// CHECK: Invalid CIE reference +// CHECK: invalid CIE reference diff --git a/test/ELF/invalid-dynamic-list.test b/test/ELF/invalid-dynamic-list.test new file mode 100644 index 000000000000..0e7c820f563e --- /dev/null +++ b/test/ELF/invalid-dynamic-list.test @@ -0,0 +1,37 @@ +## Different "echo" commands on Windows interpret quoted strings and +## wildcards in similar but different way (On Windows, ARGV tokenization +## and wildcard expansion are not done by the shell but by each command.) +## Because of that reason, this test fails on some Windows environment. +## We can't write quoted strings that are interpreted the same way +## by all echo commands. So, we don't want to run this on Windows. + +# REQUIRES: shell + +# RUN: mkdir -p %t.dir + +# RUN: echo foobar > %t1 +# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR1 %s +# ERR1: line 1: { expected, but got foobar + +# RUN: echo "{ foobar;" > %t1 +# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR2 %s +# ERR2: line 1: unexpected EOF + +## Missing ';' before '}' +# RUN: echo "{ foobar }" > %t1 +# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR3 %s +# ERR3: line 1: ; expected, but got } + +## Missing final ';' +# RUN: echo "{ foobar; }" > %t1 +# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR4 %s +# ERR4: line 1: unexpected EOF + +## Missing \" in foobar definition +# RUN echo "{ \"foobar; };" > %t1 +# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR5 %s +# ERR5: line 1: unexpected EOF + +# RUN: echo "{ extern \"BOGUS\" { test }; };" > %t1 +# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR6 %s +# ERR6: line 1: ; expected, but got BOGUS diff --git a/test/ELF/invalid-elf.test b/test/ELF/invalid-elf.test index 05e95cab0d27..c3a97d37ffa9 100644 --- a/test/ELF/invalid-elf.test +++ b/test/ELF/invalid-elf.test @@ -2,26 +2,27 @@ # RUN: not ld.lld %t %p/Inputs/invalid-data-encoding.a -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-DATA-ENC %s -# INVALID-DATA-ENC: Invalid data encoding: test.o +# INVALID-DATA-ENC: invalid data encoding: test.o # RUN: not ld.lld %t %p/Inputs/invalid-file-class.a -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-FILE-CLASS %s -# INVALID-FILE-CLASS: Invalid file class: test.o +# INVALID-FILE-CLASS: invalid file class: test.o # RUN: not ld.lld %p/Inputs/invalid-symtab-sh_info.elf -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s -# INVALID-SYMTAB-SHINFO: Invalid sh_info in symbol table +# INVALID-SYMTAB-SHINFO: invalid sh_info in symbol table # RUN: not ld.lld %p/Inputs/invalid-binding.elf -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-BINDING %s # INVALID-BINDING: unexpected binding # RUN: not ld.lld %p/Inputs/invalid-section-index.elf -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX %s -# INVALID-SECTION-INDEX: Invalid section index +# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s +# INVALID-SECTION-INDEX-LLD: invalid section index # RUN: not ld.lld %p/Inputs/invalid-shstrndx.so -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX %s +# INVALID-SECTION-INDEX: Invalid section index # RUN: not ld.lld %p/Inputs/invalid-shentsize-zero.elf -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-SHENTSIZE-ZERO %s @@ -29,6 +30,6 @@ # RUN: not ld.lld %p/Inputs/invalid-multiple-eh-relocs.elf -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-EH-RELOCS %s -# INVALID-EH-RELOCS: Multiple relocation sections to .eh_frame are not supported +# INVALID-EH-RELOCS: multiple relocation sections to .eh_frame are not supported .long foo diff --git a/test/ELF/invalid-linkerscript.test b/test/ELF/invalid-linkerscript.test new file mode 100644 index 000000000000..e0881662b962 --- /dev/null +++ b/test/ELF/invalid-linkerscript.test @@ -0,0 +1,54 @@ +## Different "echo" commands on Windows interpret quoted strings and +## wildcards in similar but different way (On Windows, ARGV tokenization +## and wildcard expansion are not done by the shell but by each command.) +## Because of that reason, this test fails on some Windows environment. +## We can't write quoted strings that are interpreted the same way +## by all echo commands. So, we don't want to run this on Windows. + +# REQUIRES: shell + +# RUN: mkdir -p %t.dir + +## Note that we are using "cannot open no-such-file: " as a marker that the +## linker keep going when it found an error. That specific error message is not +## related to the linker script tests. + +# RUN: echo foobar > %t1 +# RUN: not ld.lld %t1 no-such-file 2>&1 | FileCheck -check-prefix=ERR1 %s +# ERR1: unknown directive: foobar +# ERR1: cannot open no-such-file: + +# RUN: echo "foo \"bar" > %t2 +# RUN: not ld.lld %t2 no-such-file 2>&1 | FileCheck -check-prefix=ERR2 %s +# ERR2: unclosed quote +# ERR2: cannot open no-such-file: + +# RUN: echo "/*" > %t3 +# RUN: not ld.lld %t3 no-such-file 2>&1 | FileCheck -check-prefix=ERR3 %s +# ERR3: unclosed comment +# ERR3: cannot open no-such-file: + +# RUN: echo "EXTERN (" > %t4 +# RUN: not ld.lld %t4 no-such-file 2>&1 | FileCheck -check-prefix=ERR4 %s +# ERR4: unexpected EOF +# ERR4: cannot open no-such-file: + +# RUN: echo "EXTERN (" > %t5 +# RUN: not ld.lld %t5 no-such-file 2>&1 | FileCheck -check-prefix=ERR5 %s +# ERR5: unexpected EOF +# ERR5: cannot open no-such-file: + +# RUN: echo "EXTERN xyz" > %t6 +# RUN: not ld.lld %t6 no-such-file 2>&1 | FileCheck -check-prefix=ERR6 %s +# ERR6: ( expected, but got xyz +# ERR6: cannot open no-such-file: + +# RUN: echo "INCLUDE /no/such/file" > %t7 +# RUN: not ld.lld %t7 no-such-file 2>&1 | FileCheck -check-prefix=ERR7 %s +# ERR7: cannot open /no/such/file +# ERR7: cannot open no-such-file: + +# RUN: echo "OUTPUT_FORMAT(x y z)" > %t8 +# RUN: not ld.lld %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s +# ERR8: unexpected token: y +# ERR8: cannot open no-such-file: diff --git a/test/ELF/invalid-relocations.test b/test/ELF/invalid-relocations.test index 2b4a6c4a4210..cfeb44b03c67 100644 --- a/test/ELF/invalid-relocations.test +++ b/test/ELF/invalid-relocations.test @@ -1,6 +1,7 @@ -# RUN: yaml2obj -format elf %s -o %t +# RUN: yaml2obj %s -o %t # RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s +!ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB @@ -19,4 +20,4 @@ Symbols: Global: - Name: lulz -# CHECK: Invalid relocated section index +# CHECK: invalid relocated section index diff --git a/test/ELF/libsearch.s b/test/ELF/libsearch.s index c965b9ba91fc..782d755f7341 100644 --- a/test/ELF/libsearch.s +++ b/test/ELF/libsearch.s @@ -23,7 +23,7 @@ // Should fail if cannot find specified library (without -L switch) // RUN: not ld.lld -o %t3 %t.o -lls 2>&1 \ // RUN: | FileCheck --check-prefix=NOLIB %s -// NOLIB: Unable to find library -lls +// NOLIB: unable to find library -lls // Should use explicitly specified static library // Also ensure that we accept -L <arg> @@ -44,6 +44,12 @@ // RUN: ld.lld -o %t3 %t.o -L%t.dir -lls // RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s +// Check for library search order +// RUN: mkdir -p %t.dir2 +// RUN: cp %t.dir/libls.a %t.dir2 +// RUN: ld.lld -o %t3 %t.o -L%t.dir2 -L%t.dir -lls +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s + // -L can be placed after -l // RUN: ld.lld -o %t3 %t.o -lls -L%t.dir @@ -55,7 +61,7 @@ // RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s // RUN: not ld.lld -o %t3 %t.o -L%t.dir -Bstatic -lls2 2>&1 \ // RUN: | FileCheck --check-prefix=NOLIB2 %s -// NOLIB2: Unable to find library -lls2 +// NOLIB2: unable to find library -lls2 // -Bdynamic should restore default behaviour // RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -Bdynamic -lls @@ -79,5 +85,5 @@ // RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -call_shared -lls // RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s -.globl _start,_bar; +.globl _start,_bar _start: diff --git a/test/ELF/linkerscript-align.s b/test/ELF/linkerscript-align.s new file mode 100644 index 000000000000..5f6e6f770766 --- /dev/null +++ b/test/ELF/linkerscript-align.s @@ -0,0 +1,41 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { \ +# RUN: . = 0x10000; \ +# RUN: .aaa : \ +# RUN: { \ +# RUN: *(.aaa) \ +# RUN: } \ +# RUN: . = ALIGN(4096); \ +# RUN: .bbb : \ +# RUN: { \ +# RUN: *(.bbb) \ +# RUN: } \ +# RUN: . = ALIGN(4096 * 4); \ +# RUN: .ccc : \ +# RUN: { \ +# RUN: *(.ccc) \ +# RUN: } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA +# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA +# CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA + +.global _start +_start: + nop + +.section .aaa, "a" +.quad 0 + +.section .bbb, "a" +.quad 0 + +.section .ccc, "a" +.quad 0 diff --git a/test/ELF/linkerscript-diagnostic.s b/test/ELF/linkerscript-diagnostic.s new file mode 100644 index 000000000000..f42cbe82cf38 --- /dev/null +++ b/test/ELF/linkerscript-diagnostic.s @@ -0,0 +1,66 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Take some valid script with multiline comments +## and check it actually works: +# RUN: echo "SECTIONS {" > %t.script +# RUN: echo ".text : { *(.text) }" >> %t.script +# RUN: echo ".keep : { *(.keep) } /*" >> %t.script +# RUN: echo "comment line 1" >> %t.script +# RUN: echo "comment line 2 */" >> %t.script +# RUN: echo ".temp : { *(.temp) } }" >> %t.script +# RUN: ld.lld -shared %t -o %t1 --script %t.script + +## Change ":" to "+" at line 2, check that error +## message starts from correct line number: +# RUN: echo "SECTIONS {" > %t.script +# RUN: echo ".text + { *(.text) }" >> %t.script +# RUN: echo ".keep : { *(.keep) } /*" >> %t.script +# RUN: echo "comment line 1" >> %t.script +# RUN: echo "comment line 2 */" >> %t.script +# RUN: echo ".temp : { *(.temp) } }" >> %t.script +# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR1 %s +# ERR1: line 2: + +## Change ":" to "+" at line 3 now, check correct error line number: +# RUN: echo "SECTIONS {" > %t.script +# RUN: echo ".text : { *(.text) }" >> %t.script +# RUN: echo ".keep + { *(.keep) } /*" >> %t.script +# RUN: echo "comment line 1" >> %t.script +# RUN: echo "comment line 2 */" >> %t.script +# RUN: echo ".temp : { *(.temp) } }" >> %t.script +# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR2 %s +# ERR2: line 3: + +## Change ":" to "+" at line 6, after multiline comment, +## check correct error line number: +# RUN: echo "SECTIONS {" > %t.script +# RUN: echo ".text : { *(.text) }" >> %t.script +# RUN: echo ".keep : { *(.keep) } /*" >> %t.script +# RUN: echo "comment line 1" >> %t.script +# RUN: echo "comment line 2 */" >> %t.script +# RUN: echo ".temp + { *(.temp) } }" >> %t.script +# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR5 %s +# ERR5: line 6: + +## Check that text of lines and pointer to 'bad' token are working ok. +# RUN: echo "UNKNOWN_TAG {" > %t.script +# RUN: echo ".text : { *(.text) }" >> %t.script +# RUN: echo ".keep : { *(.keep) }" >> %t.script +# RUN: echo ".temp : { *(.temp) } }" >> %t.script +# RUN: not ld.lld -shared %t -o %t1 --script %t.script > %t.log 2>&1 +# RUN: FileCheck -check-prefix=ERR6 %s < %t.log +# ERR6: line 1: +# ERR6-NEXT: UNKNOWN_TAG { +# RUN: grep '^^' %t.log + +## One more check that text of lines and pointer to 'bad' token are working ok. +# RUN: echo "SECTIONS {" > %t.script +# RUN: echo ".text : { *(.text) }" >> %t.script +# RUN: echo ".keep : { *(.keep) }" >> %t.script +# RUN: echo "boom .temp : { *(.temp) } }" >> %t.script +# RUN: not ld.lld -shared %t -o %t1 --script %t.script > %t.log 2>&1 +# RUN: FileCheck -check-prefix=ERR7 %s < %t.log +# ERR7: line 4: : expected, but got .temp +# ERR7-NEXT: boom .temp : { *(.temp) } } +# RUN: grep '^ ^' %t.log diff --git a/test/ELF/linkerscript-locationcounter.s b/test/ELF/linkerscript-locationcounter.s new file mode 100644 index 000000000000..c6e8e7ef8ea8 --- /dev/null +++ b/test/ELF/linkerscript-locationcounter.s @@ -0,0 +1,340 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: . = 0xFFF0; \ +# RUN: . = . + 0x10; \ +# RUN: .plus : { *(.plus) } \ +# RUN: . = 0x11010 - 0x10; \ +# RUN: .minus : { *(.minus) } \ +# RUN: . = 0x24000 / 0x2; \ +# RUN: .div : { *(.div) } \ +# RUN: . = 0x11000 + 0x1000 * 0x2; \ +# RUN: .mul : { *(.mul) } \ +# RUN: . = 0x10000 + (0x1000 + 0x1000) * 0x2; \ +# RUN: .bracket : { *(.bracket) } \ +# RUN: . = 0x17000 & 0x15000; \ +# RUN: .and : { *(.and) } \ +# RUN: . = 0x1 ? 0x16000 : 0x999999; \ +# RUN: .ternary1 : { *(.ternary1) } \ +# RUN: . = 0x0 ? 0x999999 : 0x17000; \ +# RUN: .ternary2 : { *(.ternary2) } \ +# RUN: . = 0x0 < 0x1 ? 0x18000 : 0x999999; \ +# RUN: .less : { *(.less) } \ +# RUN: . = 0x1 <= 0x1 ? 0x19000 : 0x999999; \ +# RUN: .lesseq : { *(.lesseq) } \ +# RUN: . = 0x1 > 0x0 ? 0x20000 : 0x999999; \ +# RUN: .great : { *(.great) } \ +# RUN: . = 0x1 >= 0x1 ? 0x21000 : 0x999999; \ +# RUN: .greateq : { *(.greateq) } \ +# RUN: . = 0x1 == 0x1 ? 0x22000 : 0x999999; \ +# RUN: .eq : { *(.eq) } \ +# RUN: . = 0x2 != 0x1 ? 0x23000 : 0x999999; \ +# RUN: .neq : { *(.neq) } \ +# RUN: }" > %t.script +# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-readobj -s %t2 | FileCheck %s + +# CHECK: Section { +# CHECK: Index: 1 +# CHECK: Name: .plus +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .minus +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x11000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Name: .div +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x12000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 4 +# CHECK-NEXT: Name: .mul +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x13000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 5 +# CHECK-NEXT: Name: .bracket +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x14000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .and +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x15000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .ternary1 +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x16000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .ternary2 +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x17000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .less +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x18000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .lesseq +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x19000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .great +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x20000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .greateq +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x21000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .eq +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x22000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: +# CHECK-NEXT: Name: .neq +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x23000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: } + +## Mailformed number error. +# RUN: echo "SECTIONS { \ +# RUN: . = 0x12Q41; \ +# RUN: }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=NUMERR %s +# NUMERR: malformed number: 0x12Q41 + +## Missing closing bracket. +# RUN: echo "SECTIONS { \ +# RUN: . = 0x10000 + (0x1000 + 0x1000 * 0x2; \ +# RUN: }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=BRACKETERR %s +# BRACKETERR: unexpected EOF + +## Missing opening bracket. +# RUN: echo "SECTIONS { \ +# RUN: . = 0x10000 + 0x1000 + 0x1000) * 0x2; \ +# RUN: }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=BRACKETERR2 %s +# BRACKETERR2: stray token: ) + +## Empty expression. +# RUN: echo "SECTIONS { \ +# RUN: . = ; \ +# RUN: }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=ERREXPR %s +# ERREXPR: error in location counter expression + +## Div by zero error. +# RUN: echo "SECTIONS { \ +# RUN: . = 0x10000 / 0x0; \ +# RUN: }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=DIVZERO %s +# DIVZERO: division by zero + +## Broken ternary operator expression. +# RUN: echo "SECTIONS { \ +# RUN: . = 0x1 ? 0x2; \ +# RUN: }" > %t.script +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck --check-prefix=TERNERR %s +# TERNERR: unexpected EOF + +.globl _start +_start: +nop + +.section .plus, "a" +.quad 0 + +.section .minus, "a" +.quad 0 + +.section .div, "a" +.quad 0 + +.section .mul, "a" +.quad 0 + +.section .bracket, "a" +.quad 0 + +.section .and, "a" +.quad 0 + +.section .ternary1, "a" +.quad 0 + +.section .ternary2, "a" +.quad 0 + +.section .less, "a" +.quad 0 + +.section .lesseq, "a" +.quad 0 + +.section .great, "a" +.quad 0 + +.section .greateq, "a" +.quad 0 + +.section .eq, "a" +.quad 0 + +.section .neq, "a" +.quad 0 diff --git a/test/ELF/linkerscript-orphans.s b/test/ELF/linkerscript-orphans.s new file mode 100644 index 000000000000..fa7d30bf7f7c --- /dev/null +++ b/test/ELF/linkerscript-orphans.s @@ -0,0 +1,31 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { .writable : { *(.writable) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=TEXTORPHAN %s + +# RUN: echo "SECTIONS { .text : { *(.text) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=WRITABLEORPHAN %s + +# TEXTORPHAN: Sections: +# TEXTORPHAN-NEXT: Idx Name +# TEXTORPHAN-NEXT: 0 +# TEXTORPHAN-NEXT: 1 .writable +# TEXTORPHAN-NEXT: 2 .text + +# WRITABLEORPHAN: Sections: +# WRITABLEORPHAN-NEXT: Idx Name +# WRITABLEORPHAN-NEXT: 0 +# WRITABLEORPHAN-NEXT: 1 .text +# WRITABLEORPHAN-NEXT: 2 .writable + +.global _start +_start: + nop + +.section .writable,"aw" + .zero 4 diff --git a/test/ELF/linkerscript-phdr-check.s b/test/ELF/linkerscript-phdr-check.s new file mode 100644 index 000000000000..c7229ed3312c --- /dev/null +++ b/test/ELF/linkerscript-phdr-check.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS { . = 0x10000000; .text : {*(.text.*)} }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-readobj -program-headers %t1 | FileCheck %s +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0xFFFF040 + +.global _start +_start: + nop diff --git a/test/ELF/linkerscript-repsection-va.s b/test/ELF/linkerscript-repsection-va.s new file mode 100644 index 000000000000..4feeaa0e1c38 --- /dev/null +++ b/test/ELF/linkerscript-repsection-va.s @@ -0,0 +1,24 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS {.foo : {*(.foo.*)} }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .foo 00000004 0000000000000158 DATA +# CHECK-NEXT: 2 .foo 00000004 000000000000015c DATA +# CHECK-NEXT: 3 .text 00000001 0000000000000160 TEXT DATA + +.global _start +_start: + nop + +.section .foo.1,"a" +foo1: + .long 0 + +.section .foo.2,"aw" +foo2: + .long 0 diff --git a/test/ELF/linkerscript-sections-keep.s b/test/ELF/linkerscript-sections-keep.s new file mode 100644 index 000000000000..fae6383ca499 --- /dev/null +++ b/test/ELF/linkerscript-sections-keep.s @@ -0,0 +1,80 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## First check that section "keep" is garbage collected without using KEEP +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.text) } \ +# RUN: .keep : { *(.keep) } \ +# RUN: .temp : { *(.temp) }}" > %t.script +# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | \ +# RUN: FileCheck -check-prefix=SECGC %s +# SECGC: Sections: +# SECGC-NEXT: Idx Name Size Address Type +# SECGC-NEXT: 0 00000000 0000000000000000 +# SECGC-NEXT: 1 .text 00000007 0000000000000158 TEXT DATA +# SECGC-NEXT: 2 .temp 00000004 000000000000015f DATA + +## Now apply KEEP command to preserve the section. +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.text) } \ +# RUN: .keep : { KEEP(*(.keep)) } \ +# RUN: .temp : { *(.temp) }}" > %t.script +# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | \ +# RUN: FileCheck -check-prefix=SECNOGC %s +# SECNOGC: Sections: +# SECNOGC-NEXT: Idx Name Size Address Type +# SECNOGC-NEXT: 0 00000000 0000000000000000 +# SECNOGC-NEXT: 1 .text 00000007 0000000000000158 TEXT DATA +# SECNOGC-NEXT: 2 .keep 00000004 000000000000015f DATA +# SECNOGC-NEXT: 3 .temp 00000004 0000000000000163 DATA + +## A section name matches two entries in the SECTIONS directive. The +## first one doesn't have KEEP, the second one does. If section that have +## KEEP is the first in order then section is NOT collected. +# RUN: echo "SECTIONS { \ +# RUN: .keep : { KEEP(*(.keep)) } \ +# RUN: .nokeep : { *(.keep) }}" > %t.script +# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED1 %s +# MIXED1: Sections: +# MIXED1-NEXT: Idx Name Size Address Type +# MIXED1-NEXT: 0 00000000 0000000000000000 +# MIXED1-NEXT: 1 .keep 00000004 0000000000000120 DATA +# MIXED1-NEXT: 2 .temp 00000004 0000000000000124 DATA +# MIXED1-NEXT: 3 .text 00000007 0000000000000128 TEXT DATA +# MIXED1-NEXT: 4 .symtab 00000060 0000000000000000 +# MIXED1-NEXT: 5 .shstrtab 0000002d 0000000000000000 +# MIXED1-NEXT: 6 .strtab 00000012 0000000000000000 + +## The same, but now section without KEEP is at first place. +## gold and bfd linkers disagree here. gold collects .keep while +## bfd keeps it. Our current behavior is compatible with bfd although +## we can choose either way. +# RUN: echo "SECTIONS { \ +# RUN: .nokeep : { *(.keep) } \ +# RUN: .keep : { KEEP(*(.keep)) }}" > %t.script +# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED2 %s +# MIXED2: Sections: +# MIXED2-NEXT: Idx Name Size Address Type +# MIXED2-NEXT: 0 00000000 0000000000000000 +# MIXED2-NEXT: 1 .nokeep 00000004 0000000000000120 DATA +# MIXED2-NEXT: 2 .temp 00000004 0000000000000124 DATA +# MIXED2-NEXT: 3 .text 00000007 0000000000000128 TEXT DATA +# MIXED2-NEXT: 4 .symtab 00000060 0000000000000000 +# MIXED2-NEXT: 5 .shstrtab 0000002f 0000000000000000 +# MIXED2-NEXT: 6 .strtab 00000012 0000000000000000 + +.global _start +_start: + mov temp, %eax + +.section .keep, "a" +keep: + .long 1 + +.section .temp, "a" +temp: + .long 2 diff --git a/test/ELF/linkerscript-sections-padding.s b/test/ELF/linkerscript-sections-padding.s new file mode 100644 index 000000000000..545739efe5a8 --- /dev/null +++ b/test/ELF/linkerscript-sections-padding.s @@ -0,0 +1,44 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Check that padding value works: +# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x112233445566778899 }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: hexdump -C %t.out | FileCheck -check-prefix=YES %s +# YES: 00000120 66 22 33 44 55 66 77 88 99 11 22 33 44 55 66 77 + +## Confirming that address was correct: +# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x998877665544332211 }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: hexdump -C %t.out | FileCheck -check-prefix=YES2 %s +# YES2: 00000120 66 88 77 66 55 44 33 22 11 99 88 77 66 55 44 + +## Default padding value is 0x00: +# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: hexdump -C %t.out | FileCheck -check-prefix=NO %s +# NO: 00000120 66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + +## Filler should be a hex value (1): +# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =99 }" > %t.script +# RUN: not ld.lld -o %t.out --script %t.script %t 2>&1 \ +# RUN: | FileCheck --check-prefix=ERR %s +# ERR: filler should be a hexadecimal value + +## Filler should be a hex value (2): +# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99XX }" > %t.script +# RUN: not ld.lld -o %t.out --script %t.script %t 2>&1 \ +# RUN: | FileCheck --check-prefix=ERR2 %s +# ERR2: not a hexadecimal value: XX + +.section .mysec.1,"a" +.align 16 +.byte 0x66 + +.section .mysec.2,"a" +.align 16 +.byte 0x66 + +.globl _start +_start: + nop diff --git a/test/ELF/linkerscript-sections.s b/test/ELF/linkerscript-sections.s index 165ec335ec13..b68dac765a77 100644 --- a/test/ELF/linkerscript-sections.s +++ b/test/ELF/linkerscript-sections.s @@ -22,7 +22,7 @@ # SEC-DEFAULT: 4 .bss 00000002 {{[0-9a-f]*}} BSS # SEC-DEFAULT: 5 .shstrtab 00000002 {{[0-9a-f]*}} # SEC-DEFAULT: 6 .symtab 00000030 {{[0-9a-f]*}} -# SEC-DEFAULT: 7 .shstrtab 0000003c {{[0-9a-f]*}} +# SEC-DEFAULT: 7 .shstrtab 00000032 {{[0-9a-f]*}} # SEC-DEFAULT: 8 .strtab 00000008 {{[0-9a-f]*}} # Sections are put in order specified in linker script. @@ -42,7 +42,7 @@ # SEC-ORDER: 1 .bss 00000002 {{[0-9a-f]*}} BSS # SEC-ORDER: 2 other 00000003 {{[0-9a-f]*}} DATA # SEC-ORDER: 3 .shstrtab 00000002 {{[0-9a-f]*}} -# SEC-ORDER: 4 .shstrtab 0000003c {{[0-9a-f]*}} +# SEC-ORDER: 4 .shstrtab 00000032 {{[0-9a-f]*}} # SEC-ORDER: 5 .symtab 00000030 {{[0-9a-f]*}} # SEC-ORDER: 6 .strtab 00000008 {{[0-9a-f]*}} # SEC-ORDER: 7 .data 00000020 {{[0-9a-f]*}} DATA @@ -63,7 +63,7 @@ # SEC-SWAP-NAMES: 4 .bss 00000002 {{[0-9a-f]*}} BSS # SEC-SWAP-NAMES: 5 .shstrtab 00000002 {{[0-9a-f]*}} # SEC-SWAP-NAMES: 6 .symtab 00000030 {{[0-9a-f]*}} -# SEC-SWAP-NAMES: 7 .shstrtab 0000003c {{[0-9a-f]*}} +# SEC-SWAP-NAMES: 7 .shstrtab 00000032 {{[0-9a-f]*}} # SEC-SWAP-NAMES: 8 .strtab 00000008 {{[0-9a-f]*}} # .shstrtab from the input object file is discarded. @@ -100,10 +100,10 @@ # SEC-MULTI: 3 .bss 00000002 {{[0-9a-f]*}} BSS # SEC-MULTI: 4 .shstrtab 00000002 {{[0-9a-f]*}} # SEC-MULTI: 5 .symtab 00000030 {{[0-9a-f]*}} -# SEC-MULTI: 6 .shstrtab 00000036 {{[0-9a-f]*}} +# SEC-MULTI: 6 .shstrtab 0000002c {{[0-9a-f]*}} # SEC-MULTI: 7 .strtab 00000008 {{[0-9a-f]*}} -.globl _start; +.globl _start _start: mov $60, %rax mov $42, %rdi diff --git a/test/ELF/linkerscript-symbol-conflict.s b/test/ELF/linkerscript-symbol-conflict.s new file mode 100644 index 000000000000..30186ed5cb87 --- /dev/null +++ b/test/ELF/linkerscript-symbol-conflict.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS {.text : {*(.text.*)} end = .;}" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck %s +# CHECK: 0000000000000121 *ABS* 00000000 end + +.global _start +_start: + nop diff --git a/test/ELF/linkerscript-symbols.s b/test/ELF/linkerscript-symbols.s new file mode 100644 index 000000000000..1fcd4e8a8481 --- /dev/null +++ b/test/ELF/linkerscript-symbols.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS {.text : {*(.text.*)} text_end = .;}" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck %s +# CHECK: 0000000000000121 *ABS* 00000000 text_end + +.global _start +_start: + nop diff --git a/test/ELF/linkerscript-va.s b/test/ELF/linkerscript-va.s new file mode 100644 index 000000000000..25d0bd2268c0 --- /dev/null +++ b/test/ELF/linkerscript-va.s @@ -0,0 +1,24 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "SECTIONS {}" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s +# CHECK: Sections: +# CHECK-NEXT: Idx Name Size Address Type +# CHECK-NEXT: 0 00000000 0000000000000000 +# CHECK-NEXT: 1 .foo 00000004 0000000000000120 DATA +# CHECK-NEXT: 2 .boo 00000004 0000000000000124 DATA +# CHECK-NEXT: 3 .text 00000001 0000000000000128 TEXT DATA + +.global _start +_start: + nop + +.section .foo, "a" +foo: + .long 0 + +.section .boo, "a" +boo: + .long 0 diff --git a/test/ELF/linkerscript.s b/test/ELF/linkerscript.s index bff285b97612..4ee7416a4b84 100644 --- a/test/ELF/linkerscript.s +++ b/test/ELF/linkerscript.s @@ -1,3 +1,9 @@ +# There is some bad quoting interaction between lit's internal shell, which is +# implemented in Python, and the Cygwin implementations of the Unix utilities. +# Avoid running these tests on Windows for now by requiring a real shell. + +# REQUIRES: shell + # REQUIRES: x86 # RUN: mkdir -p %t.dir # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t @@ -10,43 +16,43 @@ # RUN: ld.lld %t -o %t2 %t.script # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "GROUP(" %t ")" > %t.script +# RUN: echo "GROUP(\"%t\")" > %t.script # RUN: ld.lld -o %t2 %t.script # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "INPUT(" %t ")" > %t.script +# RUN: echo "INPUT(\"%t\")" > %t.script # RUN: ld.lld -o %t2 %t.script # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "GROUP(" %t libxyz.a ")" > %t.script +# RUN: echo "GROUP(\"%t\" libxyz.a )" > %t.script # RUN: not ld.lld -o %t2 %t.script # RUN: ld.lld -o %t2 %t.script -L%t.dir # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "GROUP(" %t =libxyz.a ")" > %t.script +# RUN: echo "GROUP(\"%t\" =libxyz.a )" > %t.script # RUN: not ld.lld -o %t2 %t.script # RUN: ld.lld -o %t2 %t.script --sysroot=%t.dir # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "GROUP(" %t -lxyz ")" > %t.script +# RUN: echo "GROUP(\"%t\" -lxyz )" > %t.script # RUN: not ld.lld -o %t2 %t.script # RUN: ld.lld -o %t2 %t.script -L%t.dir # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "GROUP(" %t libxyz.a ")" > %t.script +# RUN: echo "GROUP(\"%t\" libxyz.a )" > %t.script # RUN: not ld.lld -o %t2 %t.script # RUN: ld.lld -o %t2 %t.script -L%t.dir # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "GROUP(" %t /libxyz.a ")" > %t.script -# RUN: echo "GROUP(" %t /libxyz.a ")" > %t.dir/xyz.script +# RUN: echo "GROUP(\"%t\" /libxyz.a )" > %t.script +# RUN: echo "GROUP(\"%t\" /libxyz.a )" > %t.dir/xyz.script # RUN: not ld.lld -o %t2 %t.script # RUN: not ld.lld -o %t2 %t.script --sysroot=%t.dir # RUN: ld.lld -o %t2 %t.dir/xyz.script --sysroot=%t.dir # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "GROUP(" %t.script2 ")" > %t.script1 -# RUN: echo "GROUP(" %t ")" > %t.script2 +# RUN: echo "GROUP(\"%t.script2\")" > %t.script1 +# RUN: echo "GROUP(\"%t\")" > %t.script2 # RUN: ld.lld -o %t2 %t.script1 # RUN: llvm-readobj %t2 > /dev/null @@ -70,16 +76,16 @@ # ENTRY-OVERLOAD: Name: _start # ENTRY-OVERLOAD-NEXT: Value: [[ENTRY]] -# RUN: echo "OUTPUT_FORMAT(\"elf64-x86-64\") /*/*/ GROUP(" %t ")" > %t.script +# RUN: echo "OUTPUT_FORMAT(elf64-x86-64) /*/*/ GROUP(\"%t\" )" > %t.script # RUN: ld.lld -o %t2 %t.script # RUN: llvm-readobj %t2 > /dev/null -# RUN: echo "GROUP(AS_NEEDED(" %t "))" > %t.script +# RUN: echo "GROUP(AS_NEEDED(\"%t\"))" > %t.script # RUN: ld.lld -o %t2 %t.script # RUN: llvm-readobj %t2 > /dev/null # RUN: rm -f %t.out -# RUN: echo "OUTPUT(" %t.out ")" > %t.script +# RUN: echo "OUTPUT(\"%t.out\")" > %t.script # RUN: ld.lld %t.script %t # RUN: llvm-readobj %t.out > /dev/null @@ -95,8 +101,8 @@ # RUN: ld.lld %t.script %t # RUN: llvm-readobj %t.out > /dev/null -# RUN: echo "INCLUDE " %t.script2 "OUTPUT(" %t.out ")" > %t.script1 -# RUN: echo "GROUP(" %t ")" > %t.script2 +# RUN: echo "INCLUDE \"%t.script2\" OUTPUT(\"%t.out\")" > %t.script1 +# RUN: echo "GROUP(\"%t\")" > %t.script2 # RUN: ld.lld %t.script1 # RUN: llvm-readobj %t2 > /dev/null @@ -106,7 +112,7 @@ # ERR1: unknown directive: FOO -.globl _start, _label; +.globl _start, _label _start: mov $60, %rax mov $42, %rdi diff --git a/test/ELF/linkerscript2.s b/test/ELF/linkerscript2.s index f83198f759fd..6ecd9e7ea975 100644 --- a/test/ELF/linkerscript2.s +++ b/test/ELF/linkerscript2.s @@ -1,10 +1,16 @@ +# There is some bad quoting interaction between lit's internal shell, which is +# implemented in Python, and the Cygwin implementations of the Unix utilities. +# Avoid running these tests on Windows for now by requiring a real shell. + +# REQUIRES: shell + # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd \ # RUN: %p/Inputs/libsearch-dyn.s -o %tdyn.o # RUN: mkdir -p %t.dir # RUN: ld.lld -shared %tdyn.o -o %t.dir/libls.so -# RUN: echo "SEARCH_DIR(" %t.dir ")" > %t.script +# RUN: echo "SEARCH_DIR(\"%t.dir\")" > %t.script # RUN: ld.lld -o %t2 --script %t.script -lls %t .globl _start,_bar diff --git a/test/ELF/lit.local.cfg b/test/ELF/lit.local.cfg index 0011e796e5f4..b93a36d2b50b 100644 --- a/test/ELF/lit.local.cfg +++ b/test/ELF/lit.local.cfg @@ -1,2 +1,2 @@ -config.suffixes = ['.test', '.s'] +config.suffixes = ['.test', '.s', '.ll'] diff --git a/test/ELF/llvm33-rela-outside-group.s b/test/ELF/llvm33-rela-outside-group.s new file mode 100644 index 000000000000..8e7e7c4e6a4d --- /dev/null +++ b/test/ELF/llvm33-rela-outside-group.s @@ -0,0 +1,11 @@ +// Input file generated with: +// llvm33/llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %S/Inputs/llvm33-rela-outside-group.o +// +// RUN: ld.lld -shared %S/Inputs/llvm33-rela-outside-group.o %S/Inputs/llvm33-rela-outside-group.o + + .global bar + .weak _Z3fooIiEvv + + .section .text._Z3fooIiEvv,"axG",@progbits,_Z3fooIiEvv,comdat +_Z3fooIiEvv: + callq bar@PLT diff --git a/test/ELF/local-dynamic.s b/test/ELF/local-dynamic.s index 162c58cb57ed..436516a91190 100644 --- a/test/ELF/local-dynamic.s +++ b/test/ELF/local-dynamic.s @@ -42,6 +42,17 @@ // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x1000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start // CHECK-NEXT: Value: 0x1000 // CHECK-NEXT: Size: 0 diff --git a/test/ELF/local-got-pie.s b/test/ELF/local-got-pie.s new file mode 100644 index 000000000000..e846bd454445 --- /dev/null +++ b/test/ELF/local-got-pie.s @@ -0,0 +1,36 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t -pie +// RUN: llvm-readobj -s -r %t | FileCheck %s +// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s + +.globl _start +_start: + call foo@gotpcrel + + .hidden foo + .global foo +foo: + nop + +// 0x20A0 - 1001 - 5 = 4250 +// DISASM: Disassembly of section .text: +// DISASM-NEXT: _start: +// DISASM-NEXT: 1000: {{.*}} callq 4251 +// DISASM: foo: +// DISASM-NEXT: 1005: {{.*}} nop + +// CHECK: Name: .got +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x20A0 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x20A0 R_X86_64_RELATIVE - 0x1005 +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/local-undefined-symbol.s b/test/ELF/local-undefined-symbol.s new file mode 100644 index 000000000000..34ef847180ae --- /dev/null +++ b/test/ELF/local-undefined-symbol.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t1 +# RUN: llvm-readobj -t %t1 | FileCheck %s + +# CHECK: Symbols [ +# CHECK-NOT: Name: foo + +.global _start +_start: + jmp foo + +.local foo diff --git a/test/ELF/lto/Inputs/archive-2.ll b/test/ELF/lto/Inputs/archive-2.ll new file mode 100644 index 000000000000..8236cfe5cd84 --- /dev/null +++ b/test/ELF/lto/Inputs/archive-2.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @_start() { + ret void +} diff --git a/test/ELF/lto/Inputs/archive-3.ll b/test/ELF/lto/Inputs/archive-3.ll new file mode 100644 index 000000000000..ad8fb1e33ef2 --- /dev/null +++ b/test/ELF/lto/Inputs/archive-3.ll @@ -0,0 +1,5 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +define void @foo() { + ret void +} diff --git a/test/ELF/lto/Inputs/archive.ll b/test/ELF/lto/Inputs/archive.ll new file mode 100644 index 000000000000..71c1e4f35600 --- /dev/null +++ b/test/ELF/lto/Inputs/archive.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @f() { + ret void +} diff --git a/test/ELF/lto/Inputs/available-externally.ll b/test/ELF/lto/Inputs/available-externally.ll new file mode 100644 index 000000000000..b8583eab829d --- /dev/null +++ b/test/ELF/lto/Inputs/available-externally.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @zed() { + ret void +} diff --git a/test/ELF/lto/Inputs/comdat.s b/test/ELF/lto/Inputs/comdat.s new file mode 100644 index 000000000000..6f6e5ae1d9df --- /dev/null +++ b/test/ELF/lto/Inputs/comdat.s @@ -0,0 +1,5 @@ + .section .text.f,"axG",@progbits,c,comdat + .globl foo + +foo: + retq diff --git a/test/ELF/lto/Inputs/common.s b/test/ELF/lto/Inputs/common.s new file mode 100644 index 000000000000..e2cd9e6d50c3 --- /dev/null +++ b/test/ELF/lto/Inputs/common.s @@ -0,0 +1 @@ + .comm a,8,4 diff --git a/test/ELF/lto/Inputs/drop-debug-info.bc b/test/ELF/lto/Inputs/drop-debug-info.bc Binary files differnew file mode 100644 index 000000000000..f9c471f8e0d1 --- /dev/null +++ b/test/ELF/lto/Inputs/drop-debug-info.bc diff --git a/test/ELF/lto/Inputs/drop-linkage.ll b/test/ELF/lto/Inputs/drop-linkage.ll new file mode 100644 index 000000000000..0e3dc7a41421 --- /dev/null +++ b/test/ELF/lto/Inputs/drop-linkage.ll @@ -0,0 +1,12 @@ +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +$foo = comdat any +define linkonce void @foo() comdat { + ret void +} + +define void @bar() { + call void @foo() + ret void +} diff --git a/test/ELF/lto/Inputs/dynsym.s b/test/ELF/lto/Inputs/dynsym.s new file mode 100644 index 000000000000..a69f870a1b60 --- /dev/null +++ b/test/ELF/lto/Inputs/dynsym.s @@ -0,0 +1,3 @@ +.globl foo +foo: +ret diff --git a/test/ELF/lto/Inputs/internalize-exportdyn.ll b/test/ELF/lto/Inputs/internalize-exportdyn.ll new file mode 100644 index 000000000000..21ac3580762c --- /dev/null +++ b/test/ELF/lto/Inputs/internalize-exportdyn.ll @@ -0,0 +1,6 @@ +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define weak_odr void @bah() { + ret void +} diff --git a/test/ELF/lto/Inputs/internalize-undef.ll b/test/ELF/lto/Inputs/internalize-undef.ll new file mode 100644 index 000000000000..71c1e4f35600 --- /dev/null +++ b/test/ELF/lto/Inputs/internalize-undef.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @f() { + ret void +} diff --git a/test/ELF/lto/Inputs/irmover-error.ll b/test/ELF/lto/Inputs/irmover-error.ll new file mode 100644 index 000000000000..86ed259b2a00 --- /dev/null +++ b/test/ELF/lto/Inputs/irmover-error.ll @@ -0,0 +1,6 @@ +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +!0 = !{ i32 1, !"foo", i32 2 } + +!llvm.module.flags = !{ !0 } diff --git a/test/ELF/lto/Inputs/linkonce-odr.ll b/test/ELF/lto/Inputs/linkonce-odr.ll new file mode 100644 index 000000000000..0b3828846eb5 --- /dev/null +++ b/test/ELF/lto/Inputs/linkonce-odr.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define linkonce_odr void @f() { + ret void +} diff --git a/test/ELF/lto/Inputs/linkonce.ll b/test/ELF/lto/Inputs/linkonce.ll new file mode 100644 index 000000000000..a6738b3ad71e --- /dev/null +++ b/test/ELF/lto/Inputs/linkonce.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define linkonce void @f() { + ret void +} diff --git a/test/ELF/lto/Inputs/resolution.s b/test/ELF/lto/Inputs/resolution.s new file mode 100644 index 000000000000..60b7870efbf4 --- /dev/null +++ b/test/ELF/lto/Inputs/resolution.s @@ -0,0 +1,4 @@ + .data + .global a +a: + .long 9 diff --git a/test/ELF/lto/Inputs/save-temps.ll b/test/ELF/lto/Inputs/save-temps.ll new file mode 100644 index 000000000000..d6e6eb661f33 --- /dev/null +++ b/test/ELF/lto/Inputs/save-temps.ll @@ -0,0 +1,6 @@ +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @bar() { + ret void +} diff --git a/test/ELF/lto/Inputs/shared.s b/test/ELF/lto/Inputs/shared.s new file mode 100644 index 000000000000..ab79ed131c3f --- /dev/null +++ b/test/ELF/lto/Inputs/shared.s @@ -0,0 +1,7 @@ +.globl printf +.type printf, @function +printf: + +.globl puts +.type puts, @function +puts: diff --git a/test/ELF/lto/Inputs/start-lib1.ll b/test/ELF/lto/Inputs/start-lib1.ll new file mode 100644 index 000000000000..9f42e6afff0f --- /dev/null +++ b/test/ELF/lto/Inputs/start-lib1.ll @@ -0,0 +1,8 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @bar() + +define void @foo() { + ret void +} diff --git a/test/ELF/lto/Inputs/start-lib2.ll b/test/ELF/lto/Inputs/start-lib2.ll new file mode 100644 index 000000000000..68b3c8362808 --- /dev/null +++ b/test/ELF/lto/Inputs/start-lib2.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @bar() { + ret void +} diff --git a/test/ELF/lto/Inputs/tls-mixed.s b/test/ELF/lto/Inputs/tls-mixed.s new file mode 100644 index 000000000000..b31ae3dd54d1 --- /dev/null +++ b/test/ELF/lto/Inputs/tls-mixed.s @@ -0,0 +1,4 @@ +.globl foo +.section .tbss,"awT",@nobits +foo: +.long 0 diff --git a/test/ELF/lto/Inputs/type-merge.ll b/test/ELF/lto/Inputs/type-merge.ll new file mode 100644 index 000000000000..c31642105f3a --- /dev/null +++ b/test/ELF/lto/Inputs/type-merge.ll @@ -0,0 +1,8 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @zed() { + call void @bar() + ret void +} +declare void @bar() diff --git a/test/ELF/lto/Inputs/type-merge2.ll b/test/ELF/lto/Inputs/type-merge2.ll new file mode 100644 index 000000000000..79fd1f886306 --- /dev/null +++ b/test/ELF/lto/Inputs/type-merge2.ll @@ -0,0 +1,8 @@ +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +%zed = type { i16 } +define void @bar(%zed* %this) { + store %zed* %this, %zed** null + ret void +} diff --git a/test/ELF/lto/Inputs/undef-mixed.s b/test/ELF/lto/Inputs/undef-mixed.s new file mode 100644 index 000000000000..2e4b7e114bb5 --- /dev/null +++ b/test/ELF/lto/Inputs/undef-mixed.s @@ -0,0 +1,3 @@ + .globl bar +bar: + retq diff --git a/test/ELF/lto/Inputs/unnamed-addr-lib.s b/test/ELF/lto/Inputs/unnamed-addr-lib.s new file mode 100644 index 000000000000..e6ebce024f05 --- /dev/null +++ b/test/ELF/lto/Inputs/unnamed-addr-lib.s @@ -0,0 +1,6 @@ + .protected foo + .global foo +foo: + + .global bar +bar: diff --git a/test/ELF/lto/Inputs/visibility.s b/test/ELF/lto/Inputs/visibility.s new file mode 100644 index 000000000000..db1379cc441f --- /dev/null +++ b/test/ELF/lto/Inputs/visibility.s @@ -0,0 +1,8 @@ + .global g +g: + ret + + .data + .global a +a: + .long 41 diff --git a/test/ELF/lto/archive-2.ll b/test/ELF/lto/archive-2.ll new file mode 100644 index 000000000000..6712d60c11e3 --- /dev/null +++ b/test/ELF/lto/archive-2.ll @@ -0,0 +1,28 @@ +; REQUIRES: x86 +; RUN: llvm-as %S/Inputs/archive-2.ll -o %t1.o +; RUN: rm -f %t.a +; RUN: llvm-ar rcs %t.a %t1.o +; RUN: llvm-as %s -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3 +; RUN: llvm-readobj -t %t3 | FileCheck %s +; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared +; RUN: llvm-readobj -t %t3 | FileCheck %s + +; CHECK: Name: _start ( +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @g() { + call void @_start() + ret void +} + +declare void @_start() + diff --git a/test/ELF/lto/archive-3.ll b/test/ELF/lto/archive-3.ll new file mode 100644 index 000000000000..350c8929c9df --- /dev/null +++ b/test/ELF/lto/archive-3.ll @@ -0,0 +1,19 @@ +; REQUIRES: x86 +; RUN: llvm-as %S/Inputs/archive-3.ll -o %t1.o +; RUN: llvm-as %s -o %t2.o + +; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps +; RUN: llvm-dis %t3.lto.bc -o - | FileCheck %s + +; RUN: rm -f %t.a +; RUN: llvm-ar rcs %t.a %t1.o +; RUN: ld.lld -m elf_x86_64 %t.a %t1.o %t2.o -o %t3 -save-temps +; RUN: llvm-dis %t3.lto.bc -o - | FileCheck %s + +; CHECK: define internal void @foo() { + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +define void @_start() { + ret void +} diff --git a/test/ELF/lto/archive.ll b/test/ELF/lto/archive.ll new file mode 100644 index 000000000000..b3f69fb9920f --- /dev/null +++ b/test/ELF/lto/archive.ll @@ -0,0 +1,37 @@ +; REQUIRES: x86 +; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o +; RUN: rm -f %t.a +; RUN: llvm-ar rcs %t.a %t1.o +; RUN: llvm-as %s -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3 -shared +; RUN: llvm-readobj -t %t3 | FileCheck %s +; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared +; RUN: llvm-readobj -t %t3 | FileCheck %s + + +; CHECK: Name: g ( +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text + +; CHECK: Name: f ( +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @g() { + call void @f() + ret void +} + +declare void @f() + diff --git a/test/ELF/lto/asmundef.ll b/test/ELF/lto/asmundef.ll new file mode 100644 index 000000000000..d76e418fce81 --- /dev/null +++ b/test/ELF/lto/asmundef.ll @@ -0,0 +1,25 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t -save-temps +; RUN: llvm-dis %t.lto.bc -o - | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +module asm ".weak patatino" +module asm ".equ patatino, foo" + +declare void @patatino() + +define void @foo() { + ret void +} + +define void @_start() { + call void @patatino() + ret void +} + +; CHECK: @llvm.compiler.used = appending global [1 x i8*] [i8* bitcast (void ()* @foo to i8*)], section "llvm.metadata" +; CHECK: define internal void @foo + diff --git a/test/ELF/lto/available-externally.ll b/test/ELF/lto/available-externally.ll new file mode 100644 index 000000000000..74aa86002c9e --- /dev/null +++ b/test/ELF/lto/available-externally.ll @@ -0,0 +1,22 @@ +; RUN: llvm-as %s -o %t1.o +; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o +; RUN: ld.lld %t1.o %t2.o -m elf_x86_64 -o %t.so -shared -save-temps +; RUN: llvm-dis < %t.so.lto.bc | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @foo() { + call void @bar() + call void @zed() + ret void +} +define available_externally void @bar() { + ret void +} +define available_externally void @zed() { + ret void +} + +; CHECK: define available_externally void @bar() { +; CHECK: define void @zed() { diff --git a/test/ELF/lto/combined-lto-object-name.ll b/test/ELF/lto/combined-lto-object-name.ll new file mode 100644 index 000000000000..f5b7e3ae40e6 --- /dev/null +++ b/test/ELF/lto/combined-lto-object-name.ll @@ -0,0 +1,14 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2 2>&1 | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +declare void @foo() +define void @_start() { + call void @foo() + ret void +} + +; CHECK: undefined symbol: foo in {{.*}}combined-lto-object-name.ll.tmp.o diff --git a/test/ELF/lto/comdat.ll b/test/ELF/lto/comdat.ll new file mode 100644 index 000000000000..e1384d0abd23 --- /dev/null +++ b/test/ELF/lto/comdat.ll @@ -0,0 +1,21 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared +; RUN: llvm-readobj -t %t.so | FileCheck %s + +; CHECK: Name: foo +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: 1 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +$foo = comdat any +define void @foo() comdat { + ret void +} + diff --git a/test/ELF/lto/comdat2.ll b/test/ELF/lto/comdat2.ll new file mode 100644 index 000000000000..1509585f1553 --- /dev/null +++ b/test/ELF/lto/comdat2.ll @@ -0,0 +1,40 @@ +; RUN: llvm-as %s -o %t.o +; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj +; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared +; RUN: llvm-readobj -t %t.so | FileCheck %s +; RUN: ld.lld -m elf_x86_64 %t2.o %t.o -o %t2.so -shared +; RUN: llvm-readobj -t %t2.so | FileCheck %s --check-prefix=OTHER + + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +$c = comdat any + +define protected void @foo() comdat($c) { + ret void +} + +; CHECK: Symbol { +; CHECK: Name: foo +; CHECK-NEXT: Value: 0x1000 +; CHECK-NEXT: Size: 1 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other [ +; CHECK-NEXT: STV_PROTECTED +; CHECK-NEXT: ] +; CHECK-NEXT: Section: .text +; CHECK-NEXT: } + +; OTHER: Symbol { +; OTHER: Name: foo +; OTHER-NEXT: Value: 0x1000 +; OTHER-NEXT: Size: 0 +; OTHER-NEXT: Binding: Global +; OTHER-NEXT: Type: None +; OTHER-NEXT: Other [ +; OTHER-NEXT: STV_PROTECTED +; OTHER-NEXT: ] +; OTHER-NEXT: Section: .text +; OTHER-NEXT: } diff --git a/test/ELF/lto/common.ll b/test/ELF/lto/common.ll new file mode 100644 index 000000000000..b02002431320 --- /dev/null +++ b/test/ELF/lto/common.ll @@ -0,0 +1,31 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2.o -filetype=obj +; RUN: ld.lld %t1.o %t2.o -o %t.so -shared +; RUN: llvm-readobj -s -t %t.so | FileCheck %s + +; CHECK: Name: .bss +; CHECK-NEXT: Type: SHT_NOBITS +; CHECK-NEXT: Flags [ +; CHECK-NEXT: SHF_ALLOC +; CHECK-NEXT: SHF_WRITE +; CHECK-NEXT: ] +; CHECK-NEXT: Address: +; CHECK-NEXT: Offset: +; CHECK-NEXT: Size: 8 +; CHECK-NEXT: Link: 0 +; CHECK-NEXT: Info: 0 +; CHECK-NEXT: AddressAlignment: 8 + +; CHECK: Name: a +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: 8 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Object +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .bss + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@a = common global i32 0, align 8 diff --git a/test/ELF/lto/common2.ll b/test/ELF/lto/common2.ll new file mode 100644 index 000000000000..59a2676e4fc9 --- /dev/null +++ b/test/ELF/lto/common2.ll @@ -0,0 +1,24 @@ +; RUN: llvm-as %s -o %t1.o +; RUN: ld.lld -m elf_x86_64 %t1.o -o %t -shared -save-temps +; RUN: llvm-dis < %t.lto.bc | FileCheck %s +; RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SHARED + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@a = common global i8 0, align 8 + +; Shared library case, we ensure that the bitcode generated file +; has not the a symbol but is appears in the final shared library +; produced. +; CHECK-NOT: @a = common global i8 0, align 8 + +; SHARED: Symbol { +; SHARED: Name: a +; SHARED-NEXT: Value: 0x2000 +; SHARED-NEXT: Size: 1 +; SHARED-NEXT: Binding: Global +; SHARED-NEXT: Type: Object +; SHARED-NEXT: Other: 0 +; SHARED-NEXT: Section: .bss +; SHARED-NEXT: } diff --git a/test/ELF/lto/ctors.ll b/test/ELF/lto/ctors.ll new file mode 100644 index 000000000000..7fce645f28f6 --- /dev/null +++ b/test/ELF/lto/ctors.ll @@ -0,0 +1,18 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared +; RUN: llvm-readobj -sections %t.so | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }] +define void @ctor() { + call void asm "nop", ""() + ret void +} + +; The llvm.global_ctors should end up producing constructors. +; On x86-64 (linux) we should always emit .init_array and never .ctors. +; CHECK: Name: .init_array +; CHECK-NOT: Name: .ctors diff --git a/test/ELF/lto/discard-value-names.ll b/test/ELF/lto/discard-value-names.ll new file mode 100644 index 000000000000..c6cd94fd2e18 --- /dev/null +++ b/test/ELF/lto/discard-value-names.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as %s -o %t.o + +; RUN: ld.lld -m elf_x86_64 -shared -save-temps %t.o -o %t2.o +; RUN: llvm-dis < %t2.o.lto.bc | FileCheck %s + +; CHECK: @GlobalValueName +; CHECK: @foo(i32 %in) +; CHECK: somelabel: +; CHECK: %GV = load i32, i32* @GlobalValueName +; CHECK: %add = add i32 %in, %GV +; CHECK: ret i32 %add + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@GlobalValueName = global i32 0 + +define i32 @foo(i32 %in) { +somelabel: + %GV = load i32, i32* @GlobalValueName + %add = add i32 %in, %GV + ret i32 %add +} diff --git a/test/ELF/lto/drop-debug-info.ll b/test/ELF/lto/drop-debug-info.ll new file mode 100644 index 000000000000..7a7ed5ea41d1 --- /dev/null +++ b/test/ELF/lto/drop-debug-info.ll @@ -0,0 +1,9 @@ +; REQUIRES: x86 +; +; drop-debug-info.bc was created from "void f(void) {}" with clang 3.5 and +; -gline-tables-only, so it contains old debug info. +; +; RUN: ld.lld -m elf_x86_64 -shared %p/Inputs/drop-debug-info.bc \ +; RUN: -disable-verify 2>&1 | FileCheck %s +; CHECK: warning: ignoring debug info with an invalid version (1) in {{.*}}drop-debug-info.bc + diff --git a/test/ELF/lto/drop-linkage.ll b/test/ELF/lto/drop-linkage.ll new file mode 100644 index 000000000000..fd111c18bd13 --- /dev/null +++ b/test/ELF/lto/drop-linkage.ll @@ -0,0 +1,14 @@ +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; REQUIRES: x86 +; RUN: llc %s -o %t.o -filetype=obj +; RUN: llvm-as %p/Inputs/drop-linkage.ll -o %t2.o +; RUN: ld.lld %t.o %t2.o -o %t.so -save-temps -shared +; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s + +define void @foo() { + ret void +} + +; CHECK: declare void @foo() diff --git a/test/ELF/lto/duplicated.ll b/test/ELF/lto/duplicated.ll new file mode 100644 index 000000000000..6ef6772c5f20 --- /dev/null +++ b/test/ELF/lto/duplicated.ll @@ -0,0 +1,10 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: not ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared 2>&1 | FileCheck %s +; CHECK: duplicate symbol: f in {{.*}}.o and {{.*}}.o +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f() { + ret void +} diff --git a/test/ELF/lto/dynamic-list.ll b/test/ELF/lto/dynamic-list.ll new file mode 100644 index 000000000000..0e950b3c83fd --- /dev/null +++ b/test/ELF/lto/dynamic-list.ll @@ -0,0 +1,25 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: echo "{ foo; };" > %t.list +; RUN: ld.lld -m elf_x86_64 -o %t --dynamic-list %t.list -pie %t.o +; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s + +; CHECK: Name: foo@ +; CHECK-NEXT: Value: 0x1010 +; CHECK-NEXT: Size: 1 +; CHECK-NEXT: Binding: Global (0x1) +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text +; CHECK-NEXT: } + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { + ret void +} + +define void @foo() { + ret void +} diff --git a/test/ELF/lto/dynsym.ll b/test/ELF/lto/dynsym.ll new file mode 100644 index 000000000000..5885960c7bc3 --- /dev/null +++ b/test/ELF/lto/dynsym.ll @@ -0,0 +1,25 @@ +; REQUIRES: x86 +; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t.o %p/Inputs/dynsym.s +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared +; RUN: llvm-as %s -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t2.o %t.so -o %t +; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @_start() { + call void @foo() + ret void +} + +; CHECK: Name: foo +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: +; CHECK-NEXT: Binding: +; CHECK-NEXT: Type: +; CHECK-NEXT: Other: +; CHECK-NEXT: Section: .text +define void @foo() { + ret void +} diff --git a/test/ELF/lto/inline-asm.ll b/test/ELF/lto/inline-asm.ll new file mode 100644 index 000000000000..b6af6a5a5cbb --- /dev/null +++ b/test/ELF/lto/inline-asm.ll @@ -0,0 +1,11 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @foo() { + call void asm "nop", ""() + ret void +} diff --git a/test/ELF/lto/internalize-basic.ll b/test/ELF/lto/internalize-basic.ll new file mode 100644 index 000000000000..396b9cb60f17 --- /dev/null +++ b/test/ELF/lto/internalize-basic.ll @@ -0,0 +1,21 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps +; RUN: llvm-dis < %t2.lto.bc | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { + ret void +} + +define hidden void @foo() { + ret void +} + +; Check that _start is not internalized. +; CHECK: define void @_start() + +; Check that foo function is correctly internalized. +; CHECK: define internal void @foo() diff --git a/test/ELF/lto/internalize-exportdyn.ll b/test/ELF/lto/internalize-exportdyn.ll new file mode 100644 index 000000000000..bee9a1e6a1ee --- /dev/null +++ b/test/ELF/lto/internalize-exportdyn.ll @@ -0,0 +1,47 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: llvm-as %p/Inputs/internalize-exportdyn.ll -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t2 --export-dynamic -save-temps +; RUN: llvm-dis < %t2.lto.bc | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { + ret void +} + +define void @foo() { + ret void +} + +define hidden void @bar() { + ret void +} + +define linkonce_odr void @zed() local_unnamed_addr { + ret void +} + +define linkonce_odr void @zed2() unnamed_addr { + ret void +} + +define linkonce_odr void @bah() { + ret void +} + +define linkonce_odr void @baz() { + ret void +} + +@use_baz = global void ()* @baz + +; Check what gets internalized. +; CHECK: define void @_start() +; CHECK: define void @foo() +; CHECK: define internal void @bar() +; CHECK: define internal void @zed() +; CHECK: define internal void @zed2() +; CHECK: define weak_odr void @bah() +; CHECK: define weak_odr void @baz() diff --git a/test/ELF/lto/internalize-llvmused.ll b/test/ELF/lto/internalize-llvmused.ll new file mode 100644 index 000000000000..46c90a65ff72 --- /dev/null +++ b/test/ELF/lto/internalize-llvmused.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps +; RUN: llvm-dis < %t2.lto.bc | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { + ret void +} + +define hidden void @f() { + ret void +} + +@llvm.used = appending global [1 x i8*] [ i8* bitcast (void ()* @f to i8*)] + +; Check that f is not internalized. +; CHECK: define hidden void @f() diff --git a/test/ELF/lto/internalize-undef.ll b/test/ELF/lto/internalize-undef.ll new file mode 100644 index 000000000000..5d74c31eee8b --- /dev/null +++ b/test/ELF/lto/internalize-undef.ll @@ -0,0 +1,16 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: llvm-as %p/Inputs/internalize-undef.ll -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -save-temps +; RUN: llvm-dis < %t.lto.bc | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @f() +define void @_start() { + call void @f() + ret void +} + +; CHECK: define internal void @f() diff --git a/test/ELF/lto/internalize-version-script.ll b/test/ELF/lto/internalize-version-script.ll new file mode 100644 index 000000000000..c25328fb56e2 --- /dev/null +++ b/test/ELF/lto/internalize-version-script.ll @@ -0,0 +1,22 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: echo "{ global: foo; local: *; };" > %t.script +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps +; RUN: llvm-dis < %t2.lto.bc | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @foo() { + ret void +} + +define void @bar() { + ret void +} + +; Check that foo is not internalized. +; CHECK: define void @foo() + +; Check that bar is correctly internalized. +; CHECK: define internal void @bar() diff --git a/test/ELF/lto/invalid-bitcode.ll b/test/ELF/lto/invalid-bitcode.ll new file mode 100644 index 000000000000..eceffb10d8ad --- /dev/null +++ b/test/ELF/lto/invalid-bitcode.ll @@ -0,0 +1,12 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: not ld.lld -m elf_x86_64 %t.o 2>&1 | FileCheck %s + +; CHECK: invalid bitcode file: + +; This bitcode file has no datalayout. +target triple = "x86_64-unknown-linux-gnu" + +define void @_start() { + ret void +} diff --git a/test/ELF/lto/irmover-error.ll b/test/ELF/lto/irmover-error.ll new file mode 100644 index 000000000000..aee411441c47 --- /dev/null +++ b/test/ELF/lto/irmover-error.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as -o %t1.bc %s +; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-error.ll +; RUN: not ld.lld -m elf_x86_64 %t1.bc %t2.bc -o %t 2>&1 | FileCheck %s + +; CHECK: failed to link module {{.*}}2.bc: linking module flags 'foo': IDs have conflicting values + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +!0 = !{ i32 1, !"foo", i32 1 } + +!llvm.module.flags = !{ !0 } diff --git a/test/ELF/lto/linkage.ll b/test/ELF/lto/linkage.ll new file mode 100644 index 000000000000..5af9b321eeec --- /dev/null +++ b/test/ELF/lto/linkage.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared +; RUN: llvm-nm %t.so | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Should not encounter a duplicate symbol error for @.str +@.str = private unnamed_addr constant [4 x i8] c"Hey\00", align 1 + +; Should not encounter a duplicate symbol error for @llvm.global_ctors +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }] +define internal void @ctor() { + ret void +} + +; Should not try to merge a declaration into the combined module. +declare i32 @llvm.ctpop.i32(i32) +; CHECK-NOT: llvm.ctpop.i32 diff --git a/test/ELF/lto/linkonce-odr.ll b/test/ELF/lto/linkonce-odr.ll new file mode 100644 index 000000000000..569e27154545 --- /dev/null +++ b/test/ELF/lto/linkonce-odr.ll @@ -0,0 +1,17 @@ +; REQUIRES: x86 +; RUN: llvm-as %p/Inputs/linkonce-odr.ll -o %t1.o +; RUN: llc -relocation-model=pic %s -o %t2.o -filetype=obj +; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps +; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +declare void @f() + +define void @g() { + call void @f() + ret void +} + +; Be sure that 'f' is kept and has weak_odr linkage. +; CHECK: define weak_odr void @f() diff --git a/test/ELF/lto/linkonce.ll b/test/ELF/lto/linkonce.ll new file mode 100644 index 000000000000..f980eff887b1 --- /dev/null +++ b/test/ELF/lto/linkonce.ll @@ -0,0 +1,17 @@ +; REQUIRES: x86 +; RUN: llvm-as %p/Inputs/linkonce.ll -o %t1.o +; RUN: llc -relocation-model=pic %s -o %t2.o -filetype=obj +; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps +; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +declare void @f() + +define void @g() { + call void @f() + ret void +} + +; Be sure that 'f' is kept and has weak linkage. +; CHECK: define weak void @f() diff --git a/test/ELF/lto/lto-start.ll b/test/ELF/lto/lto-start.ll new file mode 100644 index 000000000000..e93eecfbf033 --- /dev/null +++ b/test/ELF/lto/lto-start.ll @@ -0,0 +1,23 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 +; RUN: llvm-readobj -t %t2 | FileCheck %s + +; CHECK: Format: ELF64-x86-64 +; CHECK-NEXT: Arch: x86_64 +; CHECK-NEXT: AddressSize: 64bit + +; CHECK: Name: _start +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: 1 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: +; CHECK-NEXT: Section: .text + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { + ret void +} diff --git a/test/ELF/lto/ltopasses-basic.ll b/test/ELF/lto/ltopasses-basic.ll new file mode 100644 index 000000000000..5bd5f4122fd0 --- /dev/null +++ b/test/ELF/lto/ltopasses-basic.ll @@ -0,0 +1,18 @@ +; REQUIRES: x86 +; RUN: rm -f %t.so.lto.bc %t.so.lto.opt.bc %t.so.lto.o +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -mllvm -debug-pass=Arguments -shared 2>&1 | FileCheck %s --check-prefix=MLLVM +; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }] +define void @ctor() { + ret void +} + +; `@ctor` doesn't do anything and so the optimizer should kill it, leaving no ctors +; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer + +; MLLVM: Pass Arguments: diff --git a/test/ELF/lto/ltopasses-custom.ll b/test/ELF/lto/ltopasses-custom.ll new file mode 100644 index 000000000000..3e982e079fb1 --- /dev/null +++ b/test/ELF/lto/ltopasses-custom.ll @@ -0,0 +1,30 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps --lto-aa-pipeline=basic-aa \ +; RUN: --lto-newpm-passes=ipsccp -shared +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2.so -save-temps --lto-newpm-passes=loweratomic -shared +; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s +; RUN: llvm-dis %t2.so.lto.opt.bc -o - | FileCheck %s --check-prefix=ATOMIC + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @barrier() { + fence seq_cst + ret void +} + +; IPSCCP won't remove the fence. +; CHECK: define void @barrier() { +; CHECK-NEXT: fence seq_cst +; CHECK-NEXT: ret void + +; LowerAtomic will remove the fence. +; ATOMIC: define void @barrier() { +; ATOMIC-NEXT: ret void + +; Check that invalid passes are rejected gracefully. +; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \ +; RUN: --lto-newpm-passes=iamnotapass -shared 2>&1 | \ +; RUN: FileCheck %s --check-prefix=INVALID +; INVALID: unable to parse pass pipeline description: iamnotapass diff --git a/test/ELF/lto/metadata.ll b/test/ELF/lto/metadata.ll new file mode 100644 index 000000000000..3e73de5aab47 --- /dev/null +++ b/test/ELF/lto/metadata.ll @@ -0,0 +1,13 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define weak void @foo(i32* %p) { + store i32 5, i32* %p, align 4, !tbaa !0 + ret void +} + +!0 = !{!"Simple C/C++ TBAA"} diff --git a/test/ELF/lto/mix-platforms.ll b/test/ELF/lto/mix-platforms.ll new file mode 100644 index 000000000000..3478caa5cff6 --- /dev/null +++ b/test/ELF/lto/mix-platforms.ll @@ -0,0 +1,10 @@ +; REQUIRES: x86 +; RUN: llvm-mc %p/Inputs/shared.s -o %t386.o -filetype=obj -triple=i386-pc-linux +; RUN: ld.lld %t386.o -o %ti386.so -shared +; RUN: llvm-as %s -o %tx64.o +; RUN: not ld.lld %ti386.so %tx64.o -o %t 2>&1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK: {{.*}}x64.o is incompatible with {{.*}}i386.so diff --git a/test/ELF/lto/module-asm.ll b/test/ELF/lto/module-asm.ll new file mode 100644 index 000000000000..1389b9f5472e --- /dev/null +++ b/test/ELF/lto/module-asm.ll @@ -0,0 +1,19 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t +; RUN: llvm-nm %t | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +module asm ".text" +module asm ".globl foo" +; CHECK: T foo +module asm "foo: ret" + +declare void @foo() + +define void @_start() { + call void @foo() + ret void +} diff --git a/test/ELF/lto/opt-level.ll b/test/ELF/lto/opt-level.ll new file mode 100644 index 000000000000..934bf01b6c32 --- /dev/null +++ b/test/ELF/lto/opt-level.ll @@ -0,0 +1,29 @@ +; RUN: llvm-as -o %t.o %s +; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o +; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s +; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --lto-O2 %t.o +; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s +; RUN: ld.lld -o %t2a -m elf_x86_64 -e main %t.o +; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s + +; Reject invalid optimization levels. +; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O6 %t.o 2>&1 | \ +; RUN: FileCheck --check-prefix=INVALID %s +; INVALID: invalid optimization level for LTO: 6 +; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \ +; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s +; INVALIDNEGATIVE: invalid optimization level for LTO: -1 + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK-O0: foo +; CHECK-O2-NOT: foo +define internal void @foo() { + ret void +} + +define void @main() { + call void @foo() + ret void +} diff --git a/test/ELF/lto/parallel-internalize.ll b/test/ELF/lto/parallel-internalize.ll new file mode 100644 index 000000000000..58ed50eab894 --- /dev/null +++ b/test/ELF/lto/parallel-internalize.ll @@ -0,0 +1,57 @@ +; REQUIRES: x86 +; RUN: llvm-as -o %t.bc %s +; RUN: ld.lld -m elf_x86_64 --lto-jobs=2 -save-temps -o %t %t.bc -e foo --lto-O0 +; RUN: llvm-readobj -t -dyn-symbols %t | FileCheck %s +; RUN: llvm-nm %t0.lto.o | FileCheck --check-prefix=CHECK0 %s +; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s + +; CHECK: Symbols [ +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: (0) +; CHECK-NEXT: Value: 0x0 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: Binding: Local (0x0) +; CHECK-NEXT: Type: None (0x0) +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: Undefined (0x0) +; CHECK-NEXT: } +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: bar (5) +; CHECK-NEXT: Value: 0x11010 +; CHECK-NEXT: Size: 8 +; CHECK-NEXT: Binding: Local (0x0) +; CHECK-NEXT: Type: Function (0x2) +; CHECK-NEXT: Other [ (0x2) +; CHECK-NEXT: STV_HIDDEN (0x2) +; CHECK-NEXT: ] +; CHECK-NEXT: Section: .text (0x2) +; CHECK-NEXT: } +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: foo (1) +; CHECK-NEXT: Value: 0x11000 +; CHECK-NEXT: Size: 8 +; CHECK-NEXT: Binding: Global (0x1) +; CHECK-NEXT: Type: Function (0x2) +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text (0x2) +; CHECK-NEXT: } +; CHECK-NEXT: ] +; CHECK-NEXT: DynamicSymbols [ +; CHECK-NEXT: ] + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK0: U bar +; CHECK0: T foo +define void @foo() { + call void @bar() + ret void +} + +; CHECK1: T bar +; CHECK1: U foo +define void @bar() { + call void @foo() + ret void +} diff --git a/test/ELF/lto/parallel.ll b/test/ELF/lto/parallel.ll new file mode 100644 index 000000000000..8ea62ef3ae08 --- /dev/null +++ b/test/ELF/lto/parallel.ll @@ -0,0 +1,24 @@ +; REQUIRES: x86 +; RUN: llvm-as -o %t.bc %s +; RUN: ld.lld -m elf_x86_64 --lto-jobs=2 -save-temps -o %t %t.bc -shared +; RUN: llvm-nm %t0.lto.o | FileCheck --check-prefix=CHECK0 %s +; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; CHECK0-NOT: bar +; CHECK0: T foo +; CHECK0-NOT: bar +define void @foo() { + call void @bar() + ret void +} + +; CHECK1-NOT: foo +; CHECK1: T bar +; CHECK1-NOT: foo +define void @bar() { + call void @foo() + ret void +} diff --git a/test/ELF/lto/pic.ll b/test/ELF/lto/pic.ll new file mode 100644 index 000000000000..abc514d7ca3d --- /dev/null +++ b/test/ELF/lto/pic.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86 + +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld %t.o -o %t.so -shared +; RUN: llvm-readobj -r %t.so | FileCheck %s + +; CHECK: Relocations [ +; CHECK-NEXT: Section ({{.*}}) .rela.plt { +; CHECK-NEXT: R_X86_64_JUMP_SLOT bar 0x0 +; CHECK-NEXT: } +; CHECK-NEXT: ] + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @bar() +define void @foo() { + call void @bar() + ret void +} diff --git a/test/ELF/lto/relax-relocs.ll b/test/ELF/lto/relax-relocs.ll new file mode 100644 index 000000000000..929e124b2d8e --- /dev/null +++ b/test/ELF/lto/relax-relocs.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 -save-temps -shared %t.o -o %t.so +; RUN: llvm-readobj -r %t.so.lto.o | FileCheck %s + +; Test that we produce R_X86_64_REX_GOTPCRELX instead of R_X86_64_GOTPCREL +; CHECK: R_X86_64_REX_GOTPCRELX foo + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@foo = external global i32 +define i32 @bar() { + %t = load i32, i32* @foo + ret i32 %t +} diff --git a/test/ELF/lto/resolution.ll b/test/ELF/lto/resolution.ll new file mode 100644 index 000000000000..b3fcf1db3a1b --- /dev/null +++ b/test/ELF/lto/resolution.ll @@ -0,0 +1,27 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2.o -filetype=obj +; RUN: ld.lld %t1.o %t2.o -o %t.so -shared +; RUN: llvm-readobj -s --section-data %t.so | FileCheck %s + +; CHECK: Name: .data +; CHECK-NEXT: Type: SHT_PROGBITS +; CHECK-NEXT: Flags [ +; CHECK-NEXT: SHF_ALLOC +; CHECK-NEXT: SHF_WRITE +; CHECK-NEXT: ] +; CHECK-NEXT: Address: +; CHECK-NEXT: Offset: +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: Link: 0 +; CHECK-NEXT: Info: 0 +; CHECK-NEXT: AddressAlignment: 1 +; CHECK-NEXT: EntrySize: 0 +; CHECK-NEXT: SectionData ( +; CHECK-NEXT: 0000: 09000000 |{{.*}}| +; CHECK-NEXT: ) + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@a = weak global i32 8 diff --git a/test/ELF/lto/save-temps.ll b/test/ELF/lto/save-temps.ll new file mode 100644 index 000000000000..0b0f939c53f1 --- /dev/null +++ b/test/ELF/lto/save-temps.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86 +; RUN: cd %T +; RUN: rm -f a.out a.out.lto.bc a.out.lto.o +; RUN: llvm-as %s -o %t.o +; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o +; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o -save-temps +; RUN: llvm-nm a.out | FileCheck %s +; RUN: llvm-nm a.out.lto.bc | FileCheck %s +; RUN: llvm-nm a.out.lto.o | FileCheck %s +; RUN: llvm-dis a.out.lto.bc + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @foo() { + ret void +} + +; CHECK: T bar +; CHECK: T foo diff --git a/test/ELF/lto/shlib-undefined.ll b/test/ELF/lto/shlib-undefined.ll new file mode 100644 index 000000000000..db60de8e21b2 --- /dev/null +++ b/test/ELF/lto/shlib-undefined.ll @@ -0,0 +1,27 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: echo .global __progname > %t2.s +; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o +; RUN: ld.lld -shared %t2.o -o %t2.so +; RUN: ld.lld -o %t %t.o %t2.so +; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s + +; CHECK: Name: __progname@ +; CHECK-NEXT: Value: 0x11010 +; CHECK-NEXT: Size: 1 +; CHECK-NEXT: Binding: Global (0x1) +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text +; CHECK-NEXT: } + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { + ret void +} + +define void @__progname() { + ret void +} diff --git a/test/ELF/lto/start-lib.ll b/test/ELF/lto/start-lib.ll new file mode 100644 index 000000000000..ec73954a80ca --- /dev/null +++ b/test/ELF/lto/start-lib.ll @@ -0,0 +1,27 @@ +; REQUIRES: x86 +; +; RUN: llvm-as %s -o %t1.o +; RUN: llvm-as %p/Inputs/start-lib1.ll -o %t2.o +; RUN: llvm-as %p/Inputs/start-lib2.ll -o %t3.o +; +; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o %t2.o %t3.o +; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s +; TEST1: Name: bar +; TEST1: Name: foo +; +; RUN: ld.lld -m elf_x86_64 -shared -o %t3 -u bar %t1.o --start-lib %t2.o %t3.o +; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s +; TEST2: Name: bar +; TEST2-NOT: Name: foo +; +; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o --start-lib %t2.o %t3.o +; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s +; TEST3-NOT: Name: bar +; TEST3-NOT: Name: foo + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @_start() { + ret void +} diff --git a/test/ELF/lto/tls-mixed.ll b/test/ELF/lto/tls-mixed.ll new file mode 100644 index 000000000000..524bb4fb44a3 --- /dev/null +++ b/test/ELF/lto/tls-mixed.ll @@ -0,0 +1,10 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: llvm-mc %p/Inputs/tls-mixed.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -shared + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Should not encounter TLS-ness mismatch for @foo +@foo = external thread_local global i32, align 4 diff --git a/test/ELF/lto/tls-preserve.ll b/test/ELF/lto/tls-preserve.ll new file mode 100644 index 000000000000..8aebcb783f48 --- /dev/null +++ b/test/ELF/lto/tls-preserve.ll @@ -0,0 +1,25 @@ +; TLS attribute needs to be preserved. +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: ld.lld -shared %t1.o -m elf_x86_64 -o %t1 +; RUN: llvm-readobj -t %t1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@tsp_int = thread_local global i32 1 + +define void @_start() { + %val = load i32, i32* @tsp_int + ret void +} + +; CHECK: Symbol { +; CHECK: Name: tsp_int +; CHECK-NEXT: Value: 0x0 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: TLS +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .tdata +; CHECK-NEXT: } diff --git a/test/ELF/lto/type-merge.ll b/test/ELF/lto/type-merge.ll new file mode 100644 index 000000000000..98db53970b0c --- /dev/null +++ b/test/ELF/lto/type-merge.ll @@ -0,0 +1,26 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: llvm-as %p/Inputs/type-merge.ll -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -shared -save-temps +; RUN: llvm-dis < %t.lto.bc | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @foo() { + call void @bar(i8* null) + ret void +} +declare void @bar(i8*) + +; CHECK: define void @foo() { +; CHECK-NEXT: call void @bar(i8* null) +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; CHECK: declare void @bar(i8*) + +; CHECK: define void @zed() { +; CHECK-NEXT: call void bitcast (void (i8*)* @bar to void ()*)() +; CHECK-NEXT: ret void +; CHECK-NEXT: } diff --git a/test/ELF/lto/type-merge2.ll b/test/ELF/lto/type-merge2.ll new file mode 100644 index 000000000000..f0931ddc9d5e --- /dev/null +++ b/test/ELF/lto/type-merge2.ll @@ -0,0 +1,27 @@ +; RUN: llvm-as %s -o %t.o +; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared -save-temps +; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +%zed = type { i8 } +define void @foo() { + call void @bar(%zed* null) + ret void +} +declare void @bar(%zed*) + +; CHECK: %zed = type { i8 } +; CHECK-NEXT: %zed.0 = type { i16 } + +; CHECK: define void @foo() { +; CHECK-NEXT: call void bitcast (void (%zed.0*)* @bar to void (%zed*)*)(%zed* null) +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; CHECK: define void @bar(%zed.0* %this) { +; CHECK-NEXT: store %zed.0* %this, %zed.0** null +; CHECK-NEXT: ret void +; CHECK-NEXT: } diff --git a/test/ELF/lto/undef-mixed.ll b/test/ELF/lto/undef-mixed.ll new file mode 100644 index 000000000000..0fff5781020c --- /dev/null +++ b/test/ELF/lto/undef-mixed.ll @@ -0,0 +1,22 @@ +; REQUIRES: x86 +; RUN: llvm-mc %p/Inputs/undef-mixed.s -o %t.o -filetype=obj -triple=x86_64-pc-linux +; RUN: llvm-as %s -o %t2.o +; RUN: ld.lld %t2.o %t.o -o %t.so -shared +; RUN: llvm-readobj -t %t.so | FileCheck %s + +; CHECK: Name: bar +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: None +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @bar() +define void @foo() { + call void @bar() + ret void +} diff --git a/test/ELF/lto/undef-weak.ll b/test/ELF/lto/undef-weak.ll new file mode 100644 index 000000000000..215978a73df0 --- /dev/null +++ b/test/ELF/lto/undef-weak.ll @@ -0,0 +1,29 @@ +; REQUIRES: x86 + +; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o +; RUN: rm -f %t.a +; RUN: llvm-ar rcs %t.a %t1.o + + +; RUN: llvm-as %s -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t2.o -o %t2.so %t.a -shared +; RUN: llvm-readobj -t %t2.so | FileCheck %s +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +declare extern_weak void @f() +define void @foo() { + call void @f() + ret void +} + +; We should not fetch the archive member. + +; CHECK: Name: f ({{.*}}) +; CHECK-NEXT: Value: 0x0 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: Binding: Weak +; CHECK-NEXT: Type: None +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: Undefined + diff --git a/test/ELF/lto/undef.ll b/test/ELF/lto/undef.ll new file mode 100644 index 000000000000..41da61052290 --- /dev/null +++ b/test/ELF/lto/undef.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared +; RUN: llvm-readobj -t %t.so | FileCheck %s +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +declare void @bar() +define void @foo() { + call void @bar() + ret void +} + +; CHECK: Name: bar +; CHECK-NEXT: Value: 0x0 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: None +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: Undefined diff --git a/test/ELF/lto/undefined-puts.ll b/test/ELF/lto/undefined-puts.ll new file mode 100644 index 000000000000..54fb32cef4a2 --- /dev/null +++ b/test/ELF/lto/undefined-puts.ll @@ -0,0 +1,28 @@ +; REQUIRES: x86 +; RUN: llvm-mc %p/Inputs/shared.s -o %t1.o -filetype=obj -triple=x86_64-unknown-linux +; RUN: ld.lld %t1.o -o %t1.so -shared +; RUN: llvm-as %s -o %t2.o +; RUN: ld.lld %t1.so %t2.o -m elf_x86_64 -o %t +; RUN: llvm-readobj -dyn-symbols -dyn-relocations %t | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@.str = private unnamed_addr constant [6 x i8] c"blah\0A\00", align 1 + +define i32 @_start() { + %str = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0)) + ret i32 0 +} + +declare i32 @printf(i8*, ...) + +; Check that puts symbol is present in the dynamic symbol table and +; there's a relocation for it. +; CHECK: Dynamic Relocations { +; CHECK-NEXT: 0x13018 R_X86_64_JUMP_SLOT puts 0x0 +; CHECK-NEXT: } + +; CHECK: DynamicSymbols [ +; CHECK: Symbol { +; CHECK: Name: puts@ diff --git a/test/ELF/lto/unnamed-addr-comdat.ll b/test/ELF/lto/unnamed-addr-comdat.ll new file mode 100644 index 000000000000..c8c36de88d4c --- /dev/null +++ b/test/ELF/lto/unnamed-addr-comdat.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -save-temps -shared +; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +$foo = comdat any +@foo = linkonce_odr unnamed_addr constant i32 42, comdat + +; CHECK: @foo = internal unnamed_addr constant i32 42, comdat diff --git a/test/ELF/lto/unnamed-addr-lib.ll b/test/ELF/lto/unnamed-addr-lib.ll new file mode 100644 index 000000000000..c1c31f84bc8e --- /dev/null +++ b/test/ELF/lto/unnamed-addr-lib.ll @@ -0,0 +1,21 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: llvm-mc %p/Inputs/unnamed-addr-lib.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +; RUN: ld.lld %t2.o -shared -o %t2.so +; RUN: ld.lld -m elf_x86_64 %t.o %t2.so -o %t.so -save-temps -shared +; RUN: llvm-dis %t.so.lto.bc -o - | FileCheck %s + +; This documents a small limitation of lld's internalization logic. We decide +; that bar should be in the symbol table because if it is it will preempt the +; one in the shared library. +; We could add one extra bit for ODR so that we know that preemption is not +; necessary, but that is probably not worth it. + +; CHECK: @foo = internal unnamed_addr constant i8 42 +; CHECK: @bar = weak_odr unnamed_addr constant i8 42 + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@foo = linkonce_odr unnamed_addr constant i8 42 +@bar = linkonce_odr unnamed_addr constant i8 42 diff --git a/test/ELF/lto/unnamed-addr.ll b/test/ELF/lto/unnamed-addr.ll new file mode 100644 index 000000000000..a2c0105fd85f --- /dev/null +++ b/test/ELF/lto/unnamed-addr.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -shared +; RUN: llvm-dis %t.so.lto.opt.bc -o - | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +@a = internal unnamed_addr constant i8 42 + +define i8* @f() { + ret i8* @a +} + +; CHECK: @a = internal unnamed_addr constant i8 42 diff --git a/test/ELF/lto/verify-invalid.ll b/test/ELF/lto/verify-invalid.ll new file mode 100644 index 000000000000..16d6a3e54f12 --- /dev/null +++ b/test/ELF/lto/verify-invalid.ll @@ -0,0 +1,17 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ +; RUN: 2>&1 | FileCheck -check-prefix=DEFAULT %s +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ +; RUN: -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { + ret void +} + +; -disable-verify should disable the verification of bitcode. +; DEFAULT: Pass Arguments: {{.*}} -verify {{.*}} -verify +; DISABLE-NOT: Pass Arguments: {{.*}} -verify {{.*}} -verify diff --git a/test/ELF/lto/version-script.ll b/test/ELF/lto/version-script.ll new file mode 100644 index 000000000000..11a7f073ab51 --- /dev/null +++ b/test/ELF/lto/version-script.ll @@ -0,0 +1,50 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: echo "VERSION_1.0{ global: foo; local: *; }; VERSION_2.0{ global: bar; local: *; };" > %t.script +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps +; RUN: llvm-dis < %t2.lto.bc | FileCheck %s +; RUN: llvm-readobj -V -dyn-symbols %t2 | FileCheck --check-prefix=DSO %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @foo() { + ret void +} + +define void @bar() { + ret void +} + +; CHECK: define void @foo() +; CHECK: define void @bar() + +; DSO: DynamicSymbols [ +; DSO: Symbol { +; DSO: Name: @ (0) +; DSO: Value: 0x0 +; DSO: Size: 0 +; DSO: Binding: Local +; DSO: Type: None +; DSO: Other: 0 +; DSO: Section: Undefined +; DSO: } +; DSO: Symbol { +; DSO: Name: foo@@VERSION_1.0 +; DSO: Value: 0x1000 +; DSO: Size: 1 +; DSO: Binding: Global +; DSO: Type: Function +; DSO: Other: 0 +; DSO: Section: .text +; DSO: } +; DSO: Symbol { +; DSO: Name: bar@@VERSION_2.0 +; DSO: Value: 0x1010 +; DSO: Size: 1 +; DSO: Binding: Global +; DSO: Type: Function +; DSO: Other: 0 +; DSO: Section: .text +; DSO: } +; DSO: ] diff --git a/test/ELF/lto/visibility.ll b/test/ELF/lto/visibility.ll new file mode 100644 index 000000000000..718cc5b06986 --- /dev/null +++ b/test/ELF/lto/visibility.ll @@ -0,0 +1,35 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2.o -filetype=obj +; RUN: ld.lld %t1.o %t2.o -o %t.so -shared +; RUN: llvm-readobj -t %t.so | FileCheck %s + +; CHECK: Name: g +; CHECK-NEXT: Value: 0x1000 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: Binding: Local +; CHECK-NEXT: Type: None +; CHECK-NEXT: Other [ (0x2) +; CHECK-NEXT: STV_HIDDEN +; CHECK-NEXT: ] +; CHECK-NEXT: Section: .text + +; CHECK: Name: a +; CHECK-NEXT: Value: 0x3000 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: Binding: Local +; CHECK-NEXT: Type: None +; CHECK-NEXT: Other [ (0x2) +; CHECK-NEXT: STV_HIDDEN +; CHECK-NEXT: ] +; CHECK-NEXT: Section: .data + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare hidden void @g() +define void @f() { + call void @g() + ret void +} +@a = weak hidden global i32 42 diff --git a/test/ELF/lto/weak.ll b/test/ELF/lto/weak.ll new file mode 100644 index 000000000000..381ef7a1a347 --- /dev/null +++ b/test/ELF/lto/weak.ll @@ -0,0 +1,16 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared +; RUN: llvm-readobj -t %t.so | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define weak void @f() { + ret void +} + +; CHECK: Name: f +; CHECK-NEXT: Value: 0x1000 +; CHECK-NEXT: Size: 1 +; CHECK-NEXT: Binding: Weak diff --git a/test/ELF/merge-shared-str.s b/test/ELF/merge-shared-str.s new file mode 100644 index 000000000000..2ab03a4d66ab --- /dev/null +++ b/test/ELF/merge-shared-str.s @@ -0,0 +1,28 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared -O3 +// RUN: llvm-readobj -r -s %t.so | FileCheck %s + + + .section foo,"aMS",@progbits,1 + .asciz "bar" + .asciz "ar" + + .data + .quad foo + 4 + + +// CHECK: Name: foo +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: SHF_STRINGS +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x1C8 + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x1C9 +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/merge-shared.s b/test/ELF/merge-shared.s index 702a4e195f32..4c1d7c06a0ba 100644 --- a/test/ELF/merge-shared.s +++ b/test/ELF/merge-shared.s @@ -7,7 +7,7 @@ .long 42 .long 42 - .text + .data .quad foo + 6 diff --git a/test/ELF/merge-string-align.s b/test/ELF/merge-string-align.s index b06920ac0af8..0cb1afc8ba7d 100644 --- a/test/ELF/merge-string-align.s +++ b/test/ELF/merge-string-align.s @@ -1,15 +1,20 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld %t.o -o %t.so -shared -// RUN: llvm-readobj -s %t.so | FileCheck %s +// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s - .section .rodata.str1.16,"aMS",@progbits,1 + .section .rodata.foo,"aMS",@progbits,1 .align 16 .asciz "foo" - .section .rodata.str1.1,"aMS",@progbits,1 + .section .rodata.foo2,"aMS",@progbits,1 + .align 16 .asciz "foo" + .section .rodata.bar,"aMS",@progbits,1 + .align 16 + .asciz "bar" + // CHECK: Name: .rodata // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ @@ -19,10 +24,18 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 4 +// CHECK-NEXT: Size: 20 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 16 +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 666F6F00 00000000 00000000 00000000 |foo.............| +// CHECK-NEXT: 0010: 62617200 |bar.| +// CHECK-NEXT: ) + + .section .rodata.str1.1,"aMS",@progbits,1 + .asciz "foo" // CHECK: Name: .rodata // CHECK-NEXT: Type: SHT_PROGBITS @@ -37,3 +50,7 @@ // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 666F6F00 |foo.| +// CHECK-NEXT: ) diff --git a/test/ELF/merge-string-error.s b/test/ELF/merge-string-error.s index 58a624329ed9..c5088acf63b6 100644 --- a/test/ELF/merge-string-error.s +++ b/test/ELF/merge-string-error.s @@ -5,7 +5,7 @@ .section .rodata.str1.1,"aMS",@progbits,1 .asciz "abc" - .text + .data .long .rodata.str1.1 + 4 -// CHECK: Entry is past the end of the section +// CHECK: entry is past the end of the section diff --git a/test/ELF/merge-string-no-null.s b/test/ELF/merge-string-no-null.s index 70d6bbbc32e8..fd3f5073810a 100644 --- a/test/ELF/merge-string-no-null.s +++ b/test/ELF/merge-string-no-null.s @@ -5,4 +5,4 @@ .section .rodata.str1.1,"aMS",@progbits,1 .ascii "abc" -// CHECK: String is not null terminated +// CHECK: string is not null terminated diff --git a/test/ELF/merge-string.s b/test/ELF/merge-string.s index 40cc4415f956..2ad8afa53d6e 100644 --- a/test/ELF/merge-string.s +++ b/test/ELF/merge-string.s @@ -4,6 +4,8 @@ // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s // RUN: ld.lld -O1 %t.o -o %t.so -shared // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOTAIL %s +// RUN: ld.lld -O0 %t.o -o %t.so -shared +// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOMERGE %s .section .rodata.str1.1,"aMS",@progbits,1 .asciz "abc" @@ -32,7 +34,7 @@ zed: // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 -// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: EntrySize: 1 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 61626300 |abc.| // CHECK-NEXT: ) @@ -50,11 +52,29 @@ zed: // NOTAIL-NEXT: Link: 0 // NOTAIL-NEXT: Info: 0 // NOTAIL-NEXT: AddressAlignment: 1 -// NOTAIL-NEXT: EntrySize: 0 +// NOTAIL-NEXT: EntrySize: 1 // NOTAIL-NEXT: SectionData ( // NOTAIL-NEXT: 0000: 61626300 626300 |abc.bc.| // NOTAIL-NEXT: ) +// NOMERGE: Name: .rodata +// NOMERGE-NEXT: Type: SHT_PROGBITS +// NOMERGE-NEXT: Flags [ +// NOMERGE-NEXT: SHF_ALLOC +// NOMERGE-NEXT: SHF_MERGE +// NOMERGE-NEXT: SHF_STRINGS +// NOMERGE-NEXT: ] +// NOMERGE-NEXT: Address: 0x1C8 +// NOMERGE-NEXT: Offset: 0x1C8 +// NOMERGE-NEXT: Size: 16 +// NOMERGE-NEXT: Link: 0 +// NOMERGE-NEXT: Info: 0 +// NOMERGE-NEXT: AddressAlignment: 2 +// NOMERGE-NEXT: EntrySize: 0 +// NOMERGE-NEXT: SectionData ( +// NOMERGE-NEXT: 0000: 61626300 61626300 62630000 14000000 |abc.abc.bc......| +// NOMERGE-NEXT: ) + // CHECK: Name: .rodata // CHECK-NEXT: Type: SHT_PROGBITS // CHECK-NEXT: Flags [ @@ -68,7 +88,7 @@ zed: // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 2 -// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: EntrySize: 2 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 14000000 |....| // CHECK-NEXT: ) diff --git a/test/ELF/merge.s b/test/ELF/merge.s index 9cead642fa8c..5039ec2251c0 100644 --- a/test/ELF/merge.s +++ b/test/ELF/merge.s @@ -29,7 +29,7 @@ zed: // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 4 -// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: EntrySize: 4 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 10000000 42000000 // CHECK-NEXT: ) @@ -61,7 +61,9 @@ zed: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .mysec // CHECK: ] diff --git a/test/ELF/mips-26.s b/test/ELF/mips-26.s new file mode 100644 index 000000000000..b463c1ac2127 --- /dev/null +++ b/test/ELF/mips-26.s @@ -0,0 +1,95 @@ +# Check R_MIPS_26 relocation handling. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t2.o +# RUN: ld.lld %t2.o -shared -o %t.so +# RUN: ld.lld %t1.o %t.so -o %t.exe +# RUN: llvm-objdump -d %t.exe | FileCheck %s +# RUN: llvm-readobj -dynamic-table -s -r -mips-plt-got %t.exe \ +# RUN: | FileCheck -check-prefix=REL %s + +# REQUIRES: mips + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: bar: +# CHECK-NEXT: 20000: 0c 00 80 06 jal 131096 <loc> +# CHECK-NEXT: 20004: 00 00 00 00 nop +# +# CHECK: __start: +# CHECK-NEXT: 20008: 0c 00 80 00 jal 131072 <bar> +# CHECK-NEXT: 2000c: 00 00 00 00 nop +# CHECK-NEXT: 20010: 0c 00 80 10 jal 131136 +# ^-- 0x20040 gotplt[foo0] +# CHECK-NEXT: 20014: 00 00 00 00 nop +# +# CHECK: loc: +# CHECK-NEXT: 20018: 00 00 00 00 nop +# CHECK-NEXT: Disassembly of section .plt: +# CHECK-NEXT: .plt: +# CHECK-NEXT: 20020: 3c 1c 00 04 lui $gp, 4 +# CHECK-NEXT: 20024: 8f 99 00 04 lw $25, 4($gp) +# CHECK-NEXT: 20028: 27 9c 00 04 addiu $gp, $gp, 4 +# CHECK-NEXT: 2002c: 03 1c c0 23 subu $24, $24, $gp +# CHECK-NEXT: 20030: 03 e0 78 25 move $15, $ra +# CHECK-NEXT: 20034: 00 18 c0 82 srl $24, $24, 2 +# CHECK-NEXT: 20038: 03 20 f8 09 jalr $25 +# CHECK-NEXT: 2003c: 27 18 ff fe addiu $24, $24, -2 +# CHECK-NEXT: 20040: 3c 0f 00 04 lui $15, 4 +# CHECK-NEXT: 20044: 8d f9 00 0c lw $25, 12($15) +# CHECK-NEXT: 20048: 03 20 00 08 jr $25 +# CHECK-NEXT: 2004c: 25 f8 00 0c addiu $24, $15, 12 + +# REL: Name: .plt +# REL-NEXT: Type: SHT_PROGBITS +# REL-NEXT: Flags [ (0x6) +# REL-NEXT: SHF_ALLOC +# REL-NEXT: SHF_EXECINSTR +# REL-NEXT: ] +# REL-NEXT: Address: 0x[[PLTADDR:[0-9A-F]+]] + +# REL: Name: .got.plt +# REL-NEXT: Type: SHT_PROGBITS +# REL-NEXT: Flags [ (0x3) +# REL-NEXT: SHF_ALLOC +# REL-NEXT: SHF_WRITE +# REL-NEXT: ] +# REL-NEXT: Address: 0x[[GOTPLTADDR:[0-9A-F]+]] + +# REL: Relocations [ +# REL-NEXT: Section (7) .rel.plt { +# REL-NEXT: 0x[[PLTSLOT:[0-9A-F]+]] R_MIPS_JUMP_SLOT foo0 0x0 +# REL-NEXT: } +# REL-NEXT: ] + +# REL: 0x70000032 MIPS_PLTGOT 0x[[GOTPLTADDR]] + +# REL: Primary GOT { +# REL: Local entries [ +# REL-NEXT: ] +# REL-NEXT: Global entries [ +# REL-NEXT: ] +# REL: PLT GOT { +# REL: Entries [ +# REL-NEXT: Entry { +# REL-NEXT: Address: 0x[[PLTSLOT]] +# REL-NEXT: Initial: 0x[[PLTADDR]] +# REL-NEXT: Value: 0x0 +# REL-NEXT: Type: Function +# REL-NEXT: Section: Undefined +# REL-NEXT: Name: foo0 +# REL-NEXT: } +# REL-NEXT: ] + + .text + .globl bar +bar: + jal loc # R_MIPS_26 against .text + offset + + .globl __start +__start: + jal bar # R_MIPS_26 against global 'bar' from object file + jal foo0 # R_MIPS_26 against 'foo0' from DSO + +loc: + nop diff --git a/test/ELF/mips-32.s b/test/ELF/mips-32.s new file mode 100644 index 000000000000..7875c48d64d7 --- /dev/null +++ b/test/ELF/mips-32.s @@ -0,0 +1,78 @@ +# Check R_MIPS_32 relocation calculation. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o +# RUN: ld.lld -shared %t-be.o -o %t-be.so +# RUN: llvm-objdump -t -s %t-be.so \ +# RUN: | FileCheck -check-prefix=SYM -check-prefix=BE %s +# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-be.so \ +# RUN: | FileCheck -check-prefix=REL %s + +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o +# RUN: ld.lld -shared %t-el.o -o %t-el.so +# RUN: llvm-objdump -t -s %t-el.so \ +# RUN: | FileCheck -check-prefix=SYM -check-prefix=EL %s +# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-el.so \ +# RUN: | FileCheck -check-prefix=REL %s + +# REQUIRES: mips + + .globl __start +__start: + nop + + .data + .type v1,@object + .size v1,4 +v1: + .word 0 + + .globl v2 + .type v2,@object + .size v2,8 +v2: + .word v2+4 # R_MIPS_32 target v2 addend 4 + .word v1 # R_MIPS_32 target v1 addend 0 + +# BE: Contents of section .data: +# BE-NEXT: 30000 00000000 00000004 00030000 +# ^-- v2+4 ^-- v1 + +# EL: Contents of section .data: +# EL-NEXT: 30000 00000000 04000000 00000300 +# ^-- v2+4 ^-- v1 + +# SYM: SYMBOL TABLE: +# SYM: 00030000 l .data 00000004 v1 +# SYM: 00030004 g .data 00000008 v2 + +# REL: Relocations [ +# REL-NEXT: Section (7) .rel.dyn { +# REL-NEXT: 0x30008 R_MIPS_REL32 - 0x0 +# REL-NEXT: 0x30004 R_MIPS_REL32 v2 0x0 +# REL-NEXT: } +# REL-NEXT: ] + +# REL: DynamicSection [ +# REL: Tag Type Name/Value +# REL: 0x00000012 RELSZ 16 (bytes) +# REL: 0x00000013 RELENT 8 (bytes) + +# REL: Primary GOT { +# REL-NEXT: Canonical gp value: +# REL-NEXT: Reserved entries [ +# REL: ] +# REL-NEXT: Local entries [ +# REL-NEXT: ] +# REL-NEXT: Global entries [ +# REL-NEXT: Entry { +# REL-NEXT: Address: +# REL-NEXT: Access: +# REL-NEXT: Initial: 0x30004 +# REL-NEXT: Value: 0x30004 +# REL-NEXT: Type: Object +# REL-NEXT: Section: .data +# REL-NEXT: Name: v2 +# REL-NEXT: } +# REL-NEXT: ] +# REL-NEXT: Number of TLS and multi-GOT entries: 0 +# REL-NEXT: } diff --git a/test/ELF/mips-64-disp.s b/test/ELF/mips-64-disp.s new file mode 100644 index 000000000000..1c66ba4fb9a1 --- /dev/null +++ b/test/ELF/mips-64-disp.s @@ -0,0 +1,89 @@ +# Check R_MIPS_GOT_DISP relocations against various kind of symbols. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ +# RUN: %p/Inputs/mips-pic.s -o %t.so.o +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.exe.o +# RUN: ld.lld %t.so.o -shared -o %t.so +# RUN: ld.lld %t.exe.o %t.so -o %t.exe +# RUN: llvm-objdump -d -t %t.exe | FileCheck %s +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s + +# REQUIRES: mips + +# CHECK: __start: +# CHECK-NEXT: 20000: 24 42 80 40 addiu $2, $2, -32704 +# CHECK-NEXT: 20004: 24 42 80 20 addiu $2, $2, -32736 +# CHECK-NEXT: 20008: 24 42 80 28 addiu $2, $2, -32728 +# CHECK-NEXT: 2000c: 24 42 80 30 addiu $2, $2, -32720 +# CHECK-NEXT: 20010: 24 42 80 38 addiu $2, $2, -32712 + +# CHECK: 0000000000020014 .text 00000000 foo +# CHECK: 0000000000037ff0 .got 00000000 .hidden _gp +# CHECK: 0000000000020000 .text 00000000 __start +# CHECK: 0000000000000000 g F *UND* 00000000 foo1a + +# GOT: Relocations [ +# GOT-NEXT: ] +# GOT-NEXT: Primary GOT { +# GOT-NEXT: Canonical gp value: 0x37FF0 +# GOT-NEXT: Reserved entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30000 +# GOT-NEXT: Access: -32752 +# GOT-NEXT: Initial: 0x0 +# GOT-NEXT: Purpose: Lazy resolver +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30008 +# GOT-NEXT: Access: -32744 +# GOT-NEXT: Initial: 0x8000000000000000 +# GOT-NEXT: Purpose: Module pointer (GNU extension) +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Local entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30010 +# GOT-NEXT: Access: -32736 +# GOT-NEXT: Initial: 0x20014 +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30018 +# GOT-NEXT: Access: -32728 +# GOT-NEXT: Initial: 0x20004 +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30020 +# GOT-NEXT: Access: -32720 +# GOT-NEXT: Initial: 0x20008 +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30028 +# GOT-NEXT: Access: -32712 +# GOT-NEXT: Initial: 0x2000C +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Global entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30030 +# GOT-NEXT: Access: -32704 +# GOT-NEXT: Initial: 0x0 +# GOT-NEXT: Value: 0x0 +# GOT-NEXT: Type: Function +# GOT-NEXT: Section: Undefined +# GOT-NEXT: Name: foo1a +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Number of TLS and multi-GOT entries: 0 +# GOT-NEXT: } + + .text + .global __start +__start: + addiu $v0,$v0,%got_disp(foo1a) # R_MIPS_GOT_DISP + addiu $v0,$v0,%got_disp(foo) # R_MIPS_GOT_DISP + addiu $v0,$v0,%got_disp(.text+4) # R_MIPS_GOT_DISP + addiu $v0,$v0,%got_disp(.text+8) # R_MIPS_GOT_DISP + addiu $v0,$v0,%got_disp(.text+12) # R_MIPS_GOT_DISP + +foo: + nop diff --git a/test/ELF/mips-64-got.s b/test/ELF/mips-64-got.s new file mode 100644 index 000000000000..52ce6fb4d351 --- /dev/null +++ b/test/ELF/mips-64-got.s @@ -0,0 +1,87 @@ +# Check MIPS N64 ABI GOT relocations + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ +# RUN: %p/Inputs/mips-pic.s -o %t.so.o +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.exe.o +# RUN: ld.lld %t.so.o -shared -o %t.so +# RUN: ld.lld %t.exe.o %t.so -o %t.exe +# RUN: llvm-objdump -d -t %t.exe | FileCheck %s +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s + +# REQUIRES: mips + +# CHECK: __start: + +# CHECK-NEXT: 20000: df 82 80 20 ld $2, -32736($gp) +# CHECK-NEXT: 20004: 64 42 00 18 daddiu $2, $2, 24 +# CHECK-NEXT: 20008: 24 42 80 38 addiu $2, $2, -32712 +# CHECK-NEXT: 2000c: 24 42 80 28 addiu $2, $2, -32728 +# CHECK-NEXT: 20010: 24 42 80 30 addiu $2, $2, -32720 + +# CHECK: 0000000000020018 .text 00000000 foo +# CHECK: 0000000000037ff0 .got 00000000 .hidden _gp +# CHECK: 0000000000020000 .text 00000000 __start +# CHECK: 0000000000020014 .text 00000000 bar + +# GOT: Relocations [ +# GOT-NEXT: ] +# GOT-NEXT: Primary GOT { +# GOT-NEXT: Canonical gp value: 0x37FF0 +# GOT-NEXT: Reserved entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30000 +# GOT-NEXT: Access: -32752 +# GOT-NEXT: Initial: 0x0 +# GOT-NEXT: Purpose: Lazy resolver +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30008 +# GOT-NEXT: Access: -32744 +# GOT-NEXT: Initial: 0x8000000000000000 +# GOT-NEXT: Purpose: Module pointer (GNU extension) +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Local entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30010 +# GOT-NEXT: Access: -32736 +# GOT-NEXT: Initial: 0x20000 +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30018 +# GOT-NEXT: Access: -32728 +# GOT-NEXT: Initial: 0x20014 +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30020 +# GOT-NEXT: Access: -32720 +# GOT-NEXT: Initial: 0x20018 +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Global entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x30028 +# GOT-NEXT: Access: -32712 +# GOT-NEXT: Initial: 0x0 +# GOT-NEXT: Value: 0x0 +# GOT-NEXT: Type: Function +# GOT-NEXT: Section: Undefined +# GOT-NEXT: Name: foo1a +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Number of TLS and multi-GOT entries: 0 +# GOT-NEXT: } + + .text + .global __start, bar +__start: + ld $v0,%got_page(foo)($gp) # R_MIPS_GOT_PAGE + daddiu $v0,$v0,%got_ofst(foo) # R_MIPS_GOT_OFST + addiu $v0,$v0,%got_disp(foo1a) # R_MIPS_GOT_DISP + addiu $v0,$v0,%got_disp(bar) # R_MIPS_GOT_DISP + addiu $v0,$v0,%got_disp(foo) # R_MIPS_GOT_DISP + +bar: + nop +foo: + nop diff --git a/test/ELF/mips-64-gprel-so.s b/test/ELF/mips-64-gprel-so.s new file mode 100644 index 000000000000..437238ef5f26 --- /dev/null +++ b/test/ELF/mips-64-gprel-so.s @@ -0,0 +1,23 @@ +# Check setup of GP relative offsets in a function's prologue. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -shared -o %t.so +# RUN: llvm-objdump -d -t %t.so | FileCheck %s + +# REQUIRES: mips + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: foo: +# CHECK-NEXT: 10000: 3c 1c 00 01 lui $gp, 1 +# CHECK-NEXT: 10004: 03 99 e0 2d daddu $gp, $gp, $25 +# CHECK-NEXT: 10008: 67 9c 7f f0 daddiu $gp, $gp, 32752 + +# CHECK: 0000000000027ff0 .got 00000000 .hidden _gp +# CHECK: 0000000000010000 .text 00000000 foo + + .text + .global foo +foo: + lui $gp,%hi(%neg(%gp_rel(foo))) + daddu $gp,$gp,$t9 + daddiu $gp,$gp,%lo(%neg(%gp_rel(foo))) diff --git a/test/ELF/mips-64-rels.s b/test/ELF/mips-64-rels.s new file mode 100644 index 000000000000..7126afc1e595 --- /dev/null +++ b/test/ELF/mips-64-rels.s @@ -0,0 +1,46 @@ +# Check handling multiple MIPS N64 ABI relocations packed +# into the single relocation record. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t.exe +# RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s +# RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s + +# REQUIRES: mips + +# CHECK: __start: +# CHECK-NEXT: 20000: 3c 1c 00 01 lui $gp, 1 +# ^-- 0x20000 - 0x37ff0 +# ^-- 0 - 0xfffffffffffe8010 +# ^-- %hi(0x17ff0) +# CHECK: loc: +# CHECK-NEXT: 20004: 67 9c 7f f0 daddiu $gp, $gp, 32752 +# ^-- 0x20000 - 0x37ff0 +# ^-- 0 - 0xfffffffffffe8010 +# ^-- %lo(0x17ff0) + +# CHECK: Contents of section .rodata: +# CHECK-NEXT: 10190 ffffffff fffe8014 +# ^-- 0x20004 - 0x37ff0 = 0xfffffffffffe8014 + +# CHECK: 0000000000020004 .text 00000000 loc +# CHECK: 0000000000037ff0 .got 00000000 .hidden _gp +# CHECK: 0000000000020000 .text 00000000 __start + +# REL: Relocations [ +# REL-NEXT: ] + + .text + .global __start +__start: + lui $gp,%hi(%neg(%gp_rel(__start))) # R_MIPS_GPREL16 + # R_MIPS_SUB + # R_MIPS_HI16 +loc: + daddiu $gp,$gp,%lo(%neg(%gp_rel(__start))) # R_MIPS_GPREL16 + # R_MIPS_SUB + # R_MIPS_LO16 + + .section .rodata,"a",@progbits + .gpdword(loc) # R_MIPS_GPREL32 + # R_MIPS_64 diff --git a/test/ELF/mips-64.s b/test/ELF/mips-64.s new file mode 100644 index 000000000000..689669e4b09f --- /dev/null +++ b/test/ELF/mips-64.s @@ -0,0 +1,63 @@ +# Check R_MIPS_64 relocation calculation. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-objdump -t %t.so | FileCheck -check-prefix=SYM %s +# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t.so | FileCheck %s + +# REQUIRES: mips + + .global __start +__start: + nop + + .data + .type v1,@object + .size v1,4 +v1: + .quad 0 + + .globl v2 + .type v2,@object + .size v2,8 +v2: + .quad v2+8 # R_MIPS_64 target v2 addend 8 + .quad v1 # R_MIPS_64 target v1 addend 0 + + +# SYM: SYMBOL TABLE: +# SYM: 00030000 l .data 00000004 v1 +# SYM: 00030008 g .data 00000008 v2 + +# CHECK: Relocations [ +# CHECK-NEXT: Section (7) .rela.dyn { +# CHECK-NEXT: 0x30010 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x30000 +# ^-- v1 +# CHECK-NEXT: 0x30008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE v2 0x8 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +# CHECK: DynamicSection [ +# CHECK: Tag Type Name/Value +# CHECK: 0x0000000000000008 RELASZ 48 (bytes) +# CHECK: 0x0000000000000009 RELAENT 24 (bytes) + +# CHECK: Primary GOT { +# CHECK-NEXT: Canonical gp value: +# CHECK-NEXT: Reserved entries [ +# CHECK: ] +# CHECK-NEXT: Local entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: +# CHECK-NEXT: Initial: 0x30008 +# CHECK-NEXT: Value: 0x30008 +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Section: .data +# CHECK-NEXT: Name: v2 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Number of TLS and multi-GOT entries: 0 +# CHECK-NEXT: } diff --git a/test/ELF/mips-align-err.s b/test/ELF/mips-align-err.s new file mode 100644 index 000000000000..28b192ac29f3 --- /dev/null +++ b/test/ELF/mips-align-err.s @@ -0,0 +1,12 @@ +# REQUIRES: mips +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o \ +# RUN: -mcpu=mips32r6 +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mcpu=mips32r6 %S/Inputs/mips-align-err.s -o %t2.o +# RUN: not ld.lld %t.o %t2.o -o %t.exe 2>&1 | FileCheck %s +# CHECK: improper alignment for relocation R_MIPS_PC16 + + .globl __start +__start: +.zero 1 + beqc $5, $6, _foo # R_MIPS_PC16 diff --git a/test/ELF/mips-dynamic.s b/test/ELF/mips-dynamic.s index 626a3556d361..3cb5c63a49f2 100644 --- a/test/ELF/mips-dynamic.s +++ b/test/ELF/mips-dynamic.s @@ -8,6 +8,10 @@ # RUN: llvm-readobj -sections -dynamic-table %t.exe \ # RUN: | FileCheck -check-prefix=EXE %s +# RUN: ld.lld %t.o --image-base=0x123000 %td.so -o %t.exe +# RUN: llvm-readobj -sections -dynamic-table %t.exe \ +# RUN: | FileCheck -check-prefix=IMAGE_BASE %s + # RUN: ld.lld -shared %t.o %td.so -o %t.so # RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \ # RUN: | FileCheck -check-prefix=DSO %s @@ -24,6 +28,7 @@ # EXE-NEXT: Type: SHT_PROGBITS # EXE-NEXT: Flags [ (0x10000003) # EXE-NEXT: SHF_ALLOC +# EXE-NEXT: SHF_MIPS_GPREL # EXE-NEXT: SHF_WRITE # EXE-NEXT: ] # EXE-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]] @@ -44,13 +49,15 @@ # EXE-DAG: 0x00000003 PLTGOT [[GOTADDR]] # EXE-DAG: 0x70000001 MIPS_RLD_VERSION 1 # EXE-DAG: 0x70000005 MIPS_FLAGS NOTPOT -# EXE-DAG: 0x70000006 MIPS_BASE_ADDRESS +# EXE-DAG: 0x70000006 MIPS_BASE_ADDRESS 0x10000 # EXE-DAG: 0x7000000A MIPS_LOCAL_GOTNO 2 -# EXE-DAG: 0x70000011 MIPS_SYMTABNO 1 -# EXE-DAG: 0x70000013 MIPS_GOTSYM 0x1 +# EXE-DAG: 0x70000011 MIPS_SYMTABNO 2 +# EXE-DAG: 0x70000013 MIPS_GOTSYM 0x2 # EXE-DAG: 0x70000016 MIPS_RLD_MAP [[RLDMAPADDR]] # EXE: ] +# IMAGE_BASE: 0x70000006 MIPS_BASE_ADDRESS 0x123000 + # DSO: Sections [ # DSO: Name: .dynamic # DSO-NEXT: Type: SHT_DYNAMIC @@ -61,6 +68,7 @@ # DSO-NEXT: Type: SHT_PROGBITS # DSO-NEXT: Flags [ (0x10000003) # DSO-NEXT: SHF_ALLOC +# DSO-NEXT: SHF_MIPS_GPREL # DSO-NEXT: SHF_WRITE # DSO-NEXT: ] # DSO-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]] @@ -69,7 +77,6 @@ # DSO: ] # DSO: DynamicSymbols [ # DSO: Name: @ -# DSO: Name: _gp@ # DSO: Name: __start@ # DSO: Name: _foo@ # DSO: ] @@ -80,8 +87,8 @@ # DSO-DAG: 0x70000005 MIPS_FLAGS NOTPOT # DSO-DAG: 0x70000006 MIPS_BASE_ADDRESS 0x0 # DSO-DAG: 0x7000000A MIPS_LOCAL_GOTNO 2 -# DSO-DAG: 0x70000011 MIPS_SYMTABNO 4 -# DSO-DAG: 0x70000013 MIPS_GOTSYM 0x4 +# DSO-DAG: 0x70000011 MIPS_SYMTABNO 3 +# DSO-DAG: 0x70000013 MIPS_GOTSYM 0x3 # DSO: ] .text diff --git a/test/ELF/mips-gnu-hash.s b/test/ELF/mips-gnu-hash.s index 4b11f213518c..288d54043fc1 100644 --- a/test/ELF/mips-gnu-hash.s +++ b/test/ELF/mips-gnu-hash.s @@ -6,7 +6,7 @@ # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o # RUN: not ld.lld -shared -hash-style=gnu %t-el.o -o %t-el.so 2>&1 | FileCheck %s -# CHECK: The .gnu.hash section is not compatible with the MIPS target. +# CHECK: the .gnu.hash section is not compatible with the MIPS target. # REQUIRES: mips diff --git a/test/ELF/mips-got-and-copy.s b/test/ELF/mips-got-and-copy.s new file mode 100644 index 000000000000..453b8c957b56 --- /dev/null +++ b/test/ELF/mips-got-and-copy.s @@ -0,0 +1,57 @@ +# REQUIRES: mips + +# If there are two relocations such that the first one requires +# dynamic COPY relocation, the second one requires GOT entry +# creation, linker should create both - dynamic relocation +# and GOT entry. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.so.o -shared -o %t.so +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section (7) .rel.dyn { +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data1 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Primary GOT { +# CHECK-NEXT: Canonical gp value: 0x37FF0 +# CHECK-NEXT: Reserved entries [ +# CHECK: ] +# CHECK-NEXT: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x30008 +# CHECK-NEXT: Access: -32744 +# CHECK-NEXT: Initial: 0x40010 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x3000C +# CHECK-NEXT: Access: -32740 +# CHECK-NEXT: Initial: 0x40014 +# CHECK-NEXT: Value: 0x40014 +# CHECK-NEXT: Type: Object (0x1) +# CHECK-NEXT: Section: .bss (0xD) +# CHECK-NEXT: Name: data1@ (7) +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Number of TLS and multi-GOT entries: 0 +# CHECK-NEXT: } + + .text + .global __start +__start: + # Case A: 'got' relocation goes before 'copy' relocation + lui $t0,%hi(data0) # R_MIPS_HI16 - requires R_MISP_COPY relocation + addi $t0,$t0,%lo(data0) + lw $t0,%got(data0)($gp) # R_MIPS_GOT16 - requires GOT entry + + # Case B: 'copy' relocation goes before 'got' relocation + lw $t0,%got(data1)($gp) # R_MIPS_GOT16 - requires GOT entry + lui $t0,%hi(data1) # R_MIPS_HI16 - requires R_MISP_COPY relocation + addi $t0,$t0,%lo(data1) diff --git a/test/ELF/mips-got-extsym.s b/test/ELF/mips-got-extsym.s new file mode 100644 index 000000000000..1cf99aeed49b --- /dev/null +++ b/test/ELF/mips-got-extsym.s @@ -0,0 +1,59 @@ +# Check creation of GOT entries for global symbols in case of executable +# file linking. Symbols defined in DSO should get entries in the global part +# of the GOT. Symbols defined in the executable itself should get local GOT +# entries and does not need a row in .dynsym table. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o +# RUN: ld.lld -shared %t.so.o -o %t.so +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-readobj -dt -t -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Symbols [ +# CHECK: Symbol { +# CHECK: Name: _foo +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global + +# CHECK: Symbol { +# CHECK: Name: bar +# CHECK-NEXT: Value: 0x20008 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global + +# CHECK: DynamicSymbols [ +# CHECK-NOT: Name: bar + +# CHECK: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x30008 +# CHECK-NEXT: Access: -32744 +# CHECK-NEXT: Initial: 0x20008 +# ^-- bar +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x3000C +# CHECK-NEXT: Access: -32740 +# CHECK-NEXT: Initial: 0x0 +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Type: None +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: _foo@ +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .text + .globl __start +__start: + lw $t0,%got(bar)($gp) + lw $t0,%got(_foo)($gp) + +.global bar +bar: + .word 0 diff --git a/test/ELF/mips-got-redundant.s b/test/ELF/mips-got-redundant.s new file mode 100644 index 000000000000..07c3c249f4fa --- /dev/null +++ b/test/ELF/mips-got-redundant.s @@ -0,0 +1,58 @@ +# Check number of redundant entries in the local part of MIPS GOT. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -shared -o %t.so +# RUN: llvm-readobj -mips-plt-got %t.so | FileCheck %s + +# REQUIRES: mips + +# CHECK: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x20008 +# CHECK-NEXT: Access: -32744 +# CHECK-NEXT: Initial: 0x30000 +# ^-- loc1 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x2000C +# CHECK-NEXT: Access: -32740 +# CHECK-NEXT: Initial: 0x40000 +# ^-- loc2, loc3, loc4 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x20010 +# CHECK-NEXT: Access: -32736 +# CHECK-NEXT: Initial: 0x40008 +# ^-- glb1 +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .text + .globl foo +foo: + lw $t0, %got(loc1)($gp) + addi $t0, $t0, %lo(loc1) + lw $t0, %got(loc2)($gp) + addi $t0, $t0, %lo(loc2) + lw $t0, %got(loc3)($gp) + addi $t0, $t0, %lo(loc3) + lw $t0, %got(loc4)($gp) + addi $t0, $t0, %lo(loc4) + lw $t0, %got(glb1)($gp) + lw $t0, %got(glb1)($gp) + + .section .data.1,"aw",%progbits +loc1: + .space 0x10000 +loc2: + .word 0 +loc3: + .word 0 + .global glb1 + .hidden glb1 +glb1: + .word 0 + + .section .data.2,"aw",%progbits +loc4: + .word 0 diff --git a/test/ELF/mips-got-relocs.s b/test/ELF/mips-got-relocs.s index 27180fbf82ea..c44cf90b7be3 100644 --- a/test/ELF/mips-got-relocs.s +++ b/test/ELF/mips-got-relocs.s @@ -47,10 +47,11 @@ v1: # EXE_SYM: Sections: # EXE_SYM: .got 0000000c 0000000000030000 DATA # EXE_SYM: SYMBOL TABLE: -# EXE_SYM: 00037ff0 *ABS* 00000000 _gp +# EXE_SYM: 00037ff0 .got 00000000 .hidden _gp # ^-- .got + GP offset (0x7ff0) # EXE_SYM: 00040000 g .data 00000004 v1 + # EXE_GOT_BE: Contents of section .got: # EXE_GOT_BE: 30000 00000000 80000000 00040000 # ^ ^ ^-- v1 (0x40000) @@ -70,7 +71,7 @@ v1: # DSO_SYM: Sections: # DSO_SYM: .got 0000000c 0000000000020000 DATA # DSO_SYM: SYMBOL TABLE: -# DSO_SYM: 00027ff0 *ABS* 00000000 _gp +# DSO_SYM: 00027ff0 .got 00000000 .hidden _gp # ^-- .got + GP offset (0x7ff0) # DSO_SYM: 00030000 g .data 00000004 v1 diff --git a/test/ELF/mips-got-weak.s b/test/ELF/mips-got-weak.s new file mode 100644 index 000000000000..a77924692a10 --- /dev/null +++ b/test/ELF/mips-got-weak.s @@ -0,0 +1,172 @@ +# Check R_MIPS_GOT16 relocation against weak symbols. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -shared -o %t1.so +# RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t1.so \ +# RUN: | FileCheck -check-prefix=NOSYM %s +# RUN: ld.lld %t.o -shared -Bsymbolic -o %t2.so +# RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t2.so \ +# RUN: | FileCheck -check-prefix=SYM %s + +# REQUIRES: mips + +# NOSYM: Relocations [ +# NOSYM-NEXT: ] + +# NOSYM: Symbol { +# NOSYM: Name: foo +# NOSYM-NEXT: Value: 0x30000 +# NOSYM-NEXT: Size: 0 +# NOSYM-NEXT: Binding: Weak +# NOSYM-NEXT: Type: None +# NOSYM-NEXT: Other: 0 +# NOSYM-NEXT: Section: .data +# NOSYM-NEXT: } +# NOSYM-NEXT: Symbol { +# NOSYM-NEXT: Name: bar +# NOSYM-NEXT: Value: 0x0 +# NOSYM-NEXT: Size: 0 +# NOSYM-NEXT: Binding: Weak +# NOSYM-NEXT: Type: None +# NOSYM-NEXT: Other: 0 +# NOSYM-NEXT: Section: Undefined +# NOSYM-NEXT: } +# NOSYM-NEXT: Symbol { +# NOSYM-NEXT: Name: sym +# NOSYM-NEXT: Value: 0x30004 +# NOSYM-NEXT: Size: 0 +# NOSYM-NEXT: Binding: Global +# NOSYM-NEXT: Type: None +# NOSYM-NEXT: Other: 0 +# NOSYM-NEXT: Section: .data +# NOSYM-NEXT: } +# NOSYM-NEXT: ] + +# NOSYM: 0x70000011 MIPS_SYMTABNO 4 +# NOSYM-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 2 +# NOSYM-NEXT: 0x70000013 MIPS_GOTSYM 0x1 + +# NOSYM: Primary GOT { +# NOSYM-NEXT: Canonical gp value: 0x27FF0 +# NOSYM-NEXT: Reserved entries [ +# NOSYM-NEXT: Entry { +# NOSYM-NEXT: Address: 0x20000 +# NOSYM-NEXT: Access: -32752 +# NOSYM-NEXT: Initial: 0x0 +# NOSYM-NEXT: Purpose: Lazy resolver +# NOSYM-NEXT: } +# NOSYM-NEXT: Entry { +# NOSYM-NEXT: Address: 0x20004 +# NOSYM-NEXT: Access: -32748 +# NOSYM-NEXT: Initial: 0x80000000 +# NOSYM-NEXT: Purpose: Module pointer (GNU extension) +# NOSYM-NEXT: } +# NOSYM-NEXT: ] +# NOSYM-NEXT: Local entries [ +# NOSYM-NEXT: ] +# NOSYM-NEXT: Global entries [ +# NOSYM-NEXT: Entry { +# NOSYM-NEXT: Address: 0x20008 +# NOSYM-NEXT: Access: -32744 +# NOSYM-NEXT: Initial: 0x30000 +# NOSYM-NEXT: Value: 0x30000 +# NOSYM-NEXT: Type: None +# NOSYM-NEXT: Section: .data +# NOSYM-NEXT: Name: foo +# NOSYM-NEXT: } +# NOSYM-NEXT: Entry { +# NOSYM-NEXT: Address: 0x2000C +# NOSYM-NEXT: Access: -32740 +# NOSYM-NEXT: Initial: 0x0 +# NOSYM-NEXT: Value: 0x0 +# NOSYM-NEXT: Type: None +# NOSYM-NEXT: Section: Undefined +# NOSYM-NEXT: Name: bar +# NOSYM-NEXT: } +# NOSYM-NEXT: Entry { +# NOSYM-NEXT: Address: 0x20010 +# NOSYM-NEXT: Access: -32736 +# NOSYM-NEXT: Initial: 0x30004 +# NOSYM-NEXT: Value: 0x30004 +# NOSYM-NEXT: Type: None +# NOSYM-NEXT: Section: .data +# NOSYM-NEXT: Name: sym +# NOSYM-NEXT: } +# NOSYM-NEXT: ] +# NOSYM-NEXT: Number of TLS and multi-GOT entries: 0 +# NOSYM-NEXT: } + +# SYM: Relocations [ +# SYM-NEXT: ] + +# SYM: Symbol { +# SYM: Name: bar +# SYM-NEXT: Value: 0x0 +# SYM-NEXT: Size: 0 +# SYM-NEXT: Binding: Weak +# SYM-NEXT: Type: None +# SYM-NEXT: Other: 0 +# SYM-NEXT: Section: Undefined +# SYM-NEXT: } +# SYM-NEXT: ] + +# SYM: 0x70000011 MIPS_SYMTABNO 4 +# SYM-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 4 +# SYM-NEXT: 0x70000013 MIPS_GOTSYM 0x3 + +# SYM: Primary GOT { +# SYM-NEXT: Canonical gp value: 0x27FF0 +# SYM-NEXT: Reserved entries [ +# SYM-NEXT: Entry { +# SYM-NEXT: Address: 0x20000 +# SYM-NEXT: Access: -32752 +# SYM-NEXT: Initial: 0x0 +# SYM-NEXT: Purpose: Lazy resolver +# SYM-NEXT: } +# SYM-NEXT: Entry { +# SYM-NEXT: Address: 0x20004 +# SYM-NEXT: Access: -32748 +# SYM-NEXT: Initial: 0x80000000 +# SYM-NEXT: Purpose: Module pointer (GNU extension) +# SYM-NEXT: } +# SYM-NEXT: ] +# SYM-NEXT: Local entries [ +# SYM-NEXT: Entry { +# SYM-NEXT: Address: 0x20008 +# SYM-NEXT: Access: -32744 +# SYM-NEXT: Initial: 0x30000 +# SYM-NEXT: } +# SYM-NEXT: Entry { +# SYM-NEXT: Address: 0x2000C +# SYM-NEXT: Access: -32740 +# SYM-NEXT: Initial: 0x30004 +# SYM-NEXT: } +# SYM-NEXT: ] +# SYM-NEXT: Global entries [ +# SYM-NEXT: Entry { +# SYM-NEXT: Address: 0x20010 +# SYM-NEXT: Access: -32736 +# SYM-NEXT: Initial: 0x0 +# SYM-NEXT: Value: 0x0 +# SYM-NEXT: Type: None +# SYM-NEXT: Section: Undefined +# SYM-NEXT: Name: bar +# SYM-NEXT: } +# SYM-NEXT: ] +# SYM-NEXT: Number of TLS and multi-GOT entries: 0 +# SYM-NEXT: } + + .text + .global sym + .weak foo,bar +func: + lw $t0,%got(foo)($gp) + lw $t0,%got(bar)($gp) + lw $t0,%got(sym)($gp) + + .data + .weak foo +foo: + .word 0 +sym: + .word 0 diff --git a/test/ELF/mips-got16.s b/test/ELF/mips-got16.s new file mode 100644 index 000000000000..ef80418ef032 --- /dev/null +++ b/test/ELF/mips-got16.s @@ -0,0 +1,120 @@ +# Check R_MIPS_GOT16 relocation calculation. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -shared -o %t.so +# RUN: llvm-objdump -d -t %t.so | FileCheck %s +# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s + +# REQUIRES: mips + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: __start: +# CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744($gp) +# CHECK-NEXT: 10004: 21 08 00 2c addi $8, $8, 44 +# CHECK-NEXT: 10008: 8f 88 80 1c lw $8, -32740($gp) +# CHECK-NEXT: 1000c: 21 08 90 00 addi $8, $8, -28672 +# CHECK-NEXT: 10010: 8f 88 80 20 lw $8, -32736($gp) +# CHECK-NEXT: 10014: 21 08 90 04 addi $8, $8, -28668 +# CHECK-NEXT: 10018: 8f 88 80 20 lw $8, -32736($gp) +# CHECK-NEXT: 1001c: 21 08 10 04 addi $8, $8, 4100 +# CHECK-NEXT: 10020: 8f 88 80 28 lw $8, -32728($gp) +# CHECK-NEXT: 10024: 21 08 10 08 addi $8, $8, 4104 +# CHECK-NEXT: 10028: 8f 88 80 2c lw $8, -32724($gp) +# +# CHECK: SYMBOL TABLE: +# CHECK: 00051008 .data 00000000 .hidden bar +# CHECK: 00000000 *UND* 00000000 foo + +# GOT: Relocations [ +# GOT-NEXT: ] + +# GOT: Primary GOT { +# GOT-NEXT: Canonical gp value: 0x27FF0 +# GOT-NEXT: Reserved entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x20000 +# GOT-NEXT: Access: -32752 +# GOT-NEXT: Initial: 0x0 +# GOT-NEXT: Purpose: Lazy resolver +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x20004 +# GOT-NEXT: Access: -32748 +# GOT-NEXT: Initial: 0x80000000 +# GOT-NEXT: Purpose: Module pointer (GNU extension) +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Local entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x20008 +# GOT-NEXT: Access: -32744 +# GOT-NEXT: Initial: 0x10000 +# ^-- (0x1002c + 0x8000) & ~0xffff +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x2000C +# GOT-NEXT: Access: -32740 +# GOT-NEXT: Initial: 0x40000 +# ^-- (0x39000 + 0x8000) & ~0xffff +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x20010 +# GOT-NEXT: Access: -32736 +# GOT-NEXT: Initial: 0x50000 +# ^-- (0x39000 + 0x10004 + 0x8000) & ~0xffff +# ^-- (0x39000 + 0x18004 + 0x8000) & ~0xffff +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x20014 +# GOT-NEXT: Access: -32732 +# GOT-NEXT: Initial: 0x0 +# ^-- redundant unused entry +# GOT-NEXT: } +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x20018 +# GOT-NEXT: Access: -327 +# GOT-NEXT: Initial: 0x51008 +# ^-- 'bar' address +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Global entries [ +# GOT-NEXT: Entry { +# GOT-NEXT: Address: 0x2001C +# GOT-NEXT: Access: -32724 +# GOT-NEXT: Initial: 0x0 +# GOT-NEXT: Value: 0x0 +# GOT-NEXT: Type: None +# GOT-NEXT: Section: Undefined +# GOT-NEXT: Name: foo@ +# GOT-NEXT: } +# GOT-NEXT: ] +# GOT-NEXT: Number of TLS and multi-GOT entries: 0 +# GOT-NEXT: } + + .text + .globl __start +__start: + lw $t0,%got($LC0)($gp) + addi $t0,$t0,%lo($LC0) + lw $t0,%got($LC1)($gp) + addi $t0,$t0,%lo($LC1) + lw $t0,%got($LC1+0x10004)($gp) + addi $t0,$t0,%lo($LC1+0x10004) + lw $t0,%got($LC1+0x18004)($gp) + addi $t0,$t0,%lo($LC1+0x18004) + lw $t0,%got(bar)($gp) + addi $t0,$t0,%lo(bar) + lw $t0,%got(foo)($gp) +$LC0: + nop + + .data + .space 0x9000 +$LC1: + .word 0 + .space 0x18000 + .word 0 +.global bar +.hidden bar +bar: + .word 0 diff --git a/test/ELF/mips-gp-disp.s b/test/ELF/mips-gp-disp.s index a08829c18bd4..7a0fd6409d18 100644 --- a/test/ELF/mips-gp-disp.s +++ b/test/ELF/mips-gp-disp.s @@ -11,17 +11,20 @@ # REQUIRES: mips -# INT-SO-NOT: Name: _gp_disp +# INT-SO: Name: _gp_disp +# INT-SO-NEXT: Value: +# INT-SO-NEXT: Size: +# INT-SO-NEXT: Binding: Local # EXT-SO: Name: _gp_disp -# EXT-SO-NEXT: Value: 0x20010 +# EXT-SO-NEXT: Value: 0x20000 # DIS: Disassembly of section .text: # DIS-NEXT: __start: # DIS-NEXT: 10000: 3c 08 00 01 lui $8, 1 # DIS-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752 # ^-- 0x37ff0 & 0xffff -# DIS: 00027ff0 *ABS* 00000000 _gp +# DIS: 00027ff0 .got 00000000 .hidden _gp # REL: Relocations [ # REL-NEXT: ] diff --git a/test/ELF/mips-gp-local.s b/test/ELF/mips-gp-local.s new file mode 100644 index 000000000000..8bb3c236edf0 --- /dev/null +++ b/test/ELF/mips-gp-local.s @@ -0,0 +1,20 @@ +# Check handling of relocations against __gnu_local_gp symbol. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld -o %t.exe %t.o +# RUN: llvm-objdump -d -t %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: __start: +# CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 +# CHECK-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752 + +# CHECK: 00037ff0 .got 00000000 .hidden _gp + + .text + .globl __start +__start: + lui $t0,%hi(__gnu_local_gp) + addi $t0,$t0,%lo(__gnu_local_gp) diff --git a/test/ELF/mips-gprel32-relocs-gp0.test b/test/ELF/mips-gprel32-relocs-gp0.test new file mode 100644 index 000000000000..6cc837ef7889 --- /dev/null +++ b/test/ELF/mips-gprel32-relocs-gp0.test @@ -0,0 +1,31 @@ +# Check R_MIPS_GPREL32 relocation calculation if input file conatins +# non-zero GP0 value in the .reginfo section. +# FIXME: The only way to get an object file with non-zero GP0 value +# is to link multiple object files with GOT relocations using '-r' +# option. LLD does not calculate and generate GP0 correctly so we +# use a binary input in this test. The input object file is a result +# of linking two object files with R_MIPS_GPREL32 relocations. + +# RUN: ld.lld -shared -o %t.so %S/Inputs/mips-gprel32-gp0.o +# RUN: llvm-objdump -s %S/Inputs/mips-gprel32-gp0.o \ +# RUN: | FileCheck -check-prefix=OBJ %s +# RUN: llvm-objdump -s -t %t.so | FileCheck %s + +# OBJ: Contents of section .reginfo: +# OBJ-NEXT: 0000 00000001 00000000 00000000 00000000 +# OBJ-NEXT: 0010 00000000 00007fef +# ^-- GP0 value +# OBJ: Contents of section .rodata: +# OBJ-NEXT: 0000 ffff8011 ffff8011 +# ^-- foo addend +# ^-- bar addend + +# CHECK: Contents of section .rodata: +# CHECK: 012c fffe8010 fffe8020 +# ^ 0x10000 + 0xffff8011 + 0x7fef - 0x27ff0 +# ^ 0x10010 + 0xffff8011 + 0x7fef - 0x27ff0 + +# CHECK: SYMBOL TABLE: +# CHECK: 00010000 .text 00000000 foo +# CHECK: 00010010 .text 00000000 bar +# CHECK: 00027ff0 .got 00000000 .hidden _gp diff --git a/test/ELF/mips-gprel32-relocs.s b/test/ELF/mips-gprel32-relocs.s index 4f93d50363c0..fa1c5cfe9956 100644 --- a/test/ELF/mips-gprel32-relocs.s +++ b/test/ELF/mips-gprel32-relocs.s @@ -28,4 +28,4 @@ v1: # CHECK: SYMBOL TABLE: # CHECK: 00010008 .text 00000000 bar # CHECK: 00010004 .text 00000000 foo -# CHECK: 00027ff0 *ABS* 00000000 _gp +# CHECK: 00027ff0 .got 00000000 .hidden _gp diff --git a/test/ELF/mips-hilo-gp-disp.s b/test/ELF/mips-hilo-gp-disp.s index e2e9ae7bc2e2..37cf90d9728b 100644 --- a/test/ELF/mips-hilo-gp-disp.s +++ b/test/ELF/mips-hilo-gp-disp.s @@ -16,6 +16,9 @@ __start: lui $t0,%hi(_gp_disp) addi $t0,$t0,%lo(_gp_disp) lw $v0,%call16(_foo)($gp) +bar: + lui $t0,%hi(_gp_disp) + addi $t0,$t0,%lo(_gp_disp) # EXE: Disassembly of section .text: # EXE-NEXT: __start: @@ -23,11 +26,16 @@ __start: # ^-- %hi(0x37ff0-0x20000) # EXE-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752 # ^-- %lo(0x37ff0-0x20004+4) +# EXE: bar: +# EXE-NEXT: 2000c: 3c 08 00 01 lui $8, 1 +# ^-- %hi(0x37ff0-0x2000c) +# EXE-NEXT: 20010: 21 08 7f e4 addi $8, $8, 32740 +# ^-- %lo(0x37ff0-0x20010+4) # EXE: SYMBOL TABLE: -# EXE: 00037ff0 *ABS* 00000000 _gp +# EXE: 0002000c .text 00000000 bar +# EXE: 00037ff0 .got 00000000 .hidden _gp # EXE: 00020000 .text 00000000 __start -# EXE: 00020010 .text 00000000 _foo # SO: Disassembly of section .text: # SO-NEXT: __start: @@ -35,8 +43,13 @@ __start: # ^-- %hi(0x27ff0-0x10000) # SO-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752 # ^-- %lo(0x27ff0-0x10004+4) +# SO: bar: +# SO-NEXT: 1000c: 3c 08 00 01 lui $8, 1 +# ^-- %hi(0x27ff0-0x1000c) +# SO-NEXT: 10010: 21 08 7f e4 addi $8, $8, 32740 +# ^-- %lo(0x27ff0-0x10010+4) # SO: SYMBOL TABLE: -# SO: 00027ff0 *ABS* 00000000 _gp +# SO: 0001000c .text 00000000 bar +# SO: 00027ff0 .got 00000000 .hidden _gp # SO: 00010000 .text 00000000 __start -# SO: 00010010 .text 00000000 _foo diff --git a/test/ELF/mips-hilo-hi-only.s b/test/ELF/mips-hilo-hi-only.s index ad18a9f9161a..97808b515da5 100644 --- a/test/ELF/mips-hilo-hi-only.s +++ b/test/ELF/mips-hilo-hi-only.s @@ -14,7 +14,7 @@ __start: _label: nop -# WARN: Can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16 +# WARN: can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16 # CHECK: Disassembly of section .text: # CHECK-NEXT: __start: diff --git a/test/ELF/mips-hilo.s b/test/ELF/mips-hilo.s index d5de9422c427..4f1452831ae6 100644 --- a/test/ELF/mips-hilo.s +++ b/test/ELF/mips-hilo.s @@ -34,20 +34,20 @@ g1: # CHECK-NEXT: __start: # CHECK-NEXT: 20000: 3c 08 00 02 lui $8, 2 # ^-- %hi(__start+4) -# CHECK-NEXT: 20004: 3c 09 00 03 lui $9, 3 +# CHECK-NEXT: 20004: 3c 09 00 04 lui $9, 4 # ^-- %hi(g1+8) # CHECK-NEXT: 20008: 21 08 00 04 addi $8, $8, 4 # ^-- %lo(__start+4) # CHECK-NEXT: 2000c: 21 08 00 0c addi $8, $8, 12 # ^-- %lo(g1+8) -# CHECK-NEXT: 20010: 3c 08 00 04 lui $8, 4 +# CHECK-NEXT: 20010: 3c 08 00 05 lui $8, 5 # ^-- %hi(l1+0x10000-4) -# CHECK-NEXT: 20014: 3c 09 00 05 lui $9, 5 +# CHECK-NEXT: 20014: 3c 09 00 06 lui $9, 6 # ^-- %hi(l1+0x20000-4) # CHECK-NEXT: 20018: 21 08 ff fc addi $8, $8, -4 # ^-- %lo(l1-4) # CHECK: SYMBOL TABLE: -# CHECK: 0030000 l .data 00000004 l1 +# CHECK: 0040000 l .data 00000004 l1 # CHECK: 0020000 .text 00000000 __start -# CHECK: 0030004 g .data 00000004 g1 +# CHECK: 0040004 g .data 00000004 g1 diff --git a/test/ELF/mips-jalr.test b/test/ELF/mips-jalr.test index 4bdf8b6e7f00..c1b119c701b6 100644 --- a/test/ELF/mips-jalr.test +++ b/test/ELF/mips-jalr.test @@ -1,13 +1,18 @@ # Check that lld ignores R_MIPS_JALR relocation for now. -# RUN: yaml2obj -format elf %s -o %t.o +# RUN: yaml2obj %s -o %t.o # RUN: ld.lld %t.o -o %t.so -shared # RUN: llvm-objdump -d %t.so | FileCheck %s +# RUN: llvm-readobj -relocations %t.so | FileCheck -check-prefix=REL %s # REQUIRES: mips # CHECK: 10000: 09 f8 20 03 jalr $25 +# REL: Relocations [ +# REL-NEXT: ] + +!ELF FileHeader: Class: ELFCLASS32 Data: ELFDATA2LSB diff --git a/test/ELF/mips-lo16-not-relative.s b/test/ELF/mips-lo16-not-relative.s new file mode 100644 index 000000000000..614e6396cc92 --- /dev/null +++ b/test/ELF/mips-lo16-not-relative.s @@ -0,0 +1,23 @@ +# Check that R_MIPS_LO16 relocation is handled as non-relative, +# and if a target symbol is a DSO data symbol, LLD create a copy +# relocation. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o +# RUN: ld.lld %t.so.o -shared -o %t.so +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-readobj -r %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Relocations [ +# CHECK-NEXT: Section (7) .rel.dyn { +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .text + .global __start +__start: + addi $t0, $t0, %lo(data0) diff --git a/test/ELF/mips-nonalloc.s b/test/ELF/mips-nonalloc.s new file mode 100644 index 000000000000..7b0aa9469f9f --- /dev/null +++ b/test/ELF/mips-nonalloc.s @@ -0,0 +1,21 @@ +# Check reading addends for relocations in non-allocatable sections. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-nonalloc.s -o %t2.o +# RUN: ld.lld %t1.o %t2.o -o %t.exe +# RUN: llvm-objdump -s %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Contents of section .debug_info: +# CHECK-NEXT: 0000 ffffffff 00020000 00020000 +# ^--------^-- __start + + .global __start +__start: + nop + +.section .debug_info + .word 0xffffffff + .word __start diff --git a/test/ELF/mips-npic-call-pic.s b/test/ELF/mips-npic-call-pic.s new file mode 100644 index 000000000000..dbf053570bd9 --- /dev/null +++ b/test/ELF/mips-npic-call-pic.s @@ -0,0 +1,144 @@ +# REQUIRES: mips +# Check LA25 stubs creation. This stub code is necessary when +# non-PIC code calls PIC function. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %p/Inputs/mips-pic.s -o %t-pic.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o +# RUN: ld.lld %t-npic.o %t-pic.o %p/Inputs/mips-sto-pic.o -o %t.exe +# RUN: llvm-objdump -d %t.exe | FileCheck %s + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: __start: +# CHECK-NEXT: 20000: 0c 00 80 0e jal 131128 <foo1b+0x4> +# ^-- .pic.foo1a +# CHECK-NEXT: 20004: 00 00 00 00 nop +# CHECK-NEXT: 20008: 0c 00 80 19 jal 131172 <foo2+0x4> +# ^-- .pic.foo2 +# CHECK-NEXT: 2000c: 00 00 00 00 nop +# CHECK-NEXT: 20010: 0c 00 80 12 jal 131144 <foo1b+0x14> +# ^-- .pic.foo1b +# CHECK-NEXT: 20014: 00 00 00 00 nop +# CHECK-NEXT: 20018: 0c 00 80 19 jal 131172 <foo2+0x4> +# ^-- .pic.foo2 +# CHECK-NEXT: 2001c: 00 00 00 00 nop +# CHECK-NEXT: 20020: 0c 00 80 28 jal 131232 <fnpic+0x10> +# ^-- .pic.fpic +# CHECK-NEXT: 20024: 00 00 00 00 nop +# CHECK-NEXT: 20028: 0c 00 80 24 jal 131216 <fnpic> +# CHECK-NEXT: 2002c: 00 00 00 00 nop +# +# CHECK: foo1a: +# CHECK-NEXT: 20030: 00 00 00 00 nop +# +# CHECK: foo1b: +# CHECK-NEXT: 20034: 00 00 00 00 nop +# +# CHECK-NEXT: 20038: 3c 19 00 02 lui $25, 2 +# CHECK-NEXT: 2003c: 08 00 80 0c j 131120 <foo1a> +# CHECK-NEXT: 20040: 27 39 00 30 addiu $25, $25, 48 +# CHECK-NEXT: 20044: 00 00 00 00 nop +# CHECK-NEXT: 20048: 3c 19 00 02 lui $25, 2 +# CHECK-NEXT: 2004c: 08 00 80 0d j 131124 <foo1b> +# CHECK-NEXT: 20050: 27 39 00 34 addiu $25, $25, 52 +# CHECK-NEXT: 20054: 00 00 00 00 nop +# CHECK-NEXT: 20058: 00 00 00 00 nop +# CHECK-NEXT: 2005c: 00 00 00 00 nop +# +# CHECK: foo2: +# CHECK-NEXT: 20060: 00 00 00 00 nop +# +# CHECK-NEXT: 20064: 3c 19 00 02 lui $25, 2 +# CHECK-NEXT: 20068: 08 00 80 18 j 131168 <foo2> +# CHECK-NEXT: 2006c: 27 39 00 60 addiu $25, $25, 96 +# CHECK-NEXT: 20070: 00 00 00 00 nop +# CHECK-NEXT: 20074: 00 00 00 00 nop +# CHECK-NEXT: 20078: 00 00 00 00 nop +# CHECK-NEXT: 2007c: 00 00 00 00 nop +# +# CHECK: fpic: +# CHECK-NEXT: 20080: 00 00 00 00 nop +# CHECK-NEXT: 20084: 00 00 00 00 nop +# CHECK-NEXT: 20088: 00 00 00 00 nop +# CHECK-NEXT: 2008c: 00 00 00 00 nop +# +# CHECK: fnpic: +# CHECK-NEXT: 20090: 00 00 00 00 nop +# CHECK-NEXT: 20094: 00 00 00 00 nop +# CHECK-NEXT: 20098: 00 00 00 00 nop +# CHECK-NEXT: 2009c: 00 00 00 00 nop +# CHECK-NEXT: 200a0: 3c 19 00 02 lui $25, 2 +# CHECK-NEXT: 200a4: 08 00 80 20 j 131200 <fpic> +# CHECK-NEXT: 200a8: 27 39 00 80 addiu $25, $25, 128 + +# Make sure tha thunks are created properly no matter how +# objects are laid out. +# +# RUN: ld.lld %t-pic.o %t-npic.o %p/Inputs/mips-sto-pic.o -o %t.exe +# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s + +# REVERSE: foo1a: +# REVERSE-NEXT: 20000: 00 00 00 00 nop +# +# REVERSE: foo1b: +# REVERSE-NEXT: 20004: 00 00 00 00 nop +# REVERSE-NEXT: 20008: 3c 19 00 02 lui $25, 2 +# REVERSE-NEXT: 2000c: 08 00 80 00 j 131072 <foo1a> +# REVERSE-NEXT: 20010: 27 39 00 00 addiu $25, $25, 0 +# REVERSE-NEXT: 20014: 00 00 00 00 nop +# REVERSE-NEXT: 20018: 3c 19 00 02 lui $25, 2 +# REVERSE-NEXT: 2001c: 08 00 80 01 j 131076 <foo1b> +# REVERSE-NEXT: 20020: 27 39 00 04 addiu $25, $25, 4 +# REVERSE-NEXT: 20024: 00 00 00 00 nop +# REVERSE-NEXT: 20028: 00 00 00 00 nop +# REVERSE-NEXT: 2002c: 00 00 00 00 nop +# +# REVERSE: foo2: +# REVERSE-NEXT: 20030: 00 00 00 00 nop +# REVERSE-NEXT: 20034: 3c 19 00 02 lui $25, 2 +# REVERSE-NEXT: 20038: 08 00 80 0c j 131120 <foo2> +# REVERSE-NEXT: 2003c: 27 39 00 30 addiu $25, $25, 48 +# REVERSE-NEXT: 20040: 00 00 00 00 nop +# REVERSE-NEXT: 20044: 00 00 00 00 nop +# REVERSE-NEXT: 20048: 00 00 00 00 nop +# REVERSE-NEXT: 2004c: 00 00 00 00 nop +# +# REVERSE: __start: +# REVERSE-NEXT: 20050: 0c 00 80 02 jal 131080 <foo1b+0x4> +# REVERSE-NEXT: 20054: 00 00 00 00 nop +# REVERSE-NEXT: 20058: 0c 00 80 0d jal 131124 <foo2+0x4> +# REVERSE-NEXT: 2005c: 00 00 00 00 nop +# REVERSE-NEXT: 20060: 0c 00 80 06 jal 131096 <foo1b+0x14> +# REVERSE-NEXT: 20064: 00 00 00 00 nop +# REVERSE-NEXT: 20068: 0c 00 80 0d jal 131124 <foo2+0x4> +# REVERSE-NEXT: 2006c: 00 00 00 00 nop +# REVERSE-NEXT: 20070: 0c 00 80 28 jal 131232 <fnpic+0x10> +# REVERSE-NEXT: 20074: 00 00 00 00 nop +# REVERSE-NEXT: 20078: 0c 00 80 24 jal 131216 <fnpic> +# REVERSE-NEXT: 2007c: 00 00 00 00 nop +# +# REVERSE: fpic: +# REVERSE-NEXT: 20080: 00 00 00 00 nop +# REVERSE-NEXT: 20084: 00 00 00 00 nop +# REVERSE-NEXT: 20088: 00 00 00 00 nop +# REVERSE-NEXT: 2008c: 00 00 00 00 nop +# +# REVERSE: fnpic: +# REVERSE-NEXT: 20090: 00 00 00 00 nop +# REVERSE-NEXT: 20094: 00 00 00 00 nop +# REVERSE-NEXT: 20098: 00 00 00 00 nop +# REVERSE-NEXT: 2009c: 00 00 00 00 nop +# REVERSE-NEXT: 200a0: 3c 19 00 02 lui $25, 2 +# REVERSE-NEXT: 200a4: 08 00 80 20 j 131200 <fpic> +# REVERSE-NEXT: 200a8: 27 39 00 80 addiu $25, $25, 128 +# REVERSE-NEXT: 200ac: 00 00 00 00 nop + + .text + .globl __start +__start: + jal foo1a + jal foo2 + jal foo1b + jal foo2 + jal fpic + jal fnpic diff --git a/test/ELF/mips-options-r.test b/test/ELF/mips-options-r.test new file mode 100644 index 000000000000..c4144057e9ad --- /dev/null +++ b/test/ELF/mips-options-r.test @@ -0,0 +1,19 @@ +# Check that if input file contains .MIPS.options section and symbol +# points to the section and the linker generates a relocatable output, +# LLD does not crash and write section symbols point to the output +# .MIPS.options section. +# +# PR 27878 +# +# Input object file created using the following script: +# % cat t.s +# .text +# nop +# % as -mabi=64 -mips64r2 t.s + +# RUN: ld.lld -r %p/Inputs/mips-options.o -o %t.o +# RUN: llvm-readobj -t %t.o | FileCheck %s + +# REQUIRES: mips + +# CHECK: Section: .MIPS.options diff --git a/test/ELF/mips-options.s b/test/ELF/mips-options.s new file mode 100644 index 000000000000..30381ae55af7 --- /dev/null +++ b/test/ELF/mips-options.s @@ -0,0 +1,28 @@ +# Check MIPS .MIPS.options section generation. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t2.o +# RUN: ld.lld %t1.o %t2.o -shared -o %t.so +# RUN: llvm-readobj -symbols -mips-options %t.so | FileCheck %s + +# REQUIRES: mips + + .text + .globl __start +__start: + lw $t0,%call16(g1)($gp) + +# CHECK: Name: _gp +# CHECK-NEXT: Value: 0x[[GP:[0-9A-F]+]] + +# CHECK: MIPS Options { +# CHECK-NEXT: ODK_REGINFO { +# CHECK-NEXT: GP: 0x[[GP]] +# CHECK-NEXT: General Mask: 0x10001001 +# CHECK-NEXT: Co-Proc Mask0: 0x0 +# CHECK-NEXT: Co-Proc Mask1: 0x0 +# CHECK-NEXT: Co-Proc Mask2: 0x0 +# CHECK-NEXT: Co-Proc Mask3: 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: } diff --git a/test/ELF/mips-pc-relocs.s b/test/ELF/mips-pc-relocs.s index 631dd433925a..209d7d2971f5 100644 --- a/test/ELF/mips-pc-relocs.s +++ b/test/ELF/mips-pc-relocs.s @@ -5,7 +5,7 @@ # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ # RUN: -mcpu=mips32r6 %S/Inputs/mips-dynamic.s -o %t2.o # RUN: ld.lld %t1.o %t2.o -o %t.exe -# RUN: llvm-objdump -mcpu=mips32r6 -d -t %t.exe | FileCheck %s +# RUN: llvm-objdump -mcpu=mips32r6 -d -t -s %t.exe | FileCheck %s # REQUIRES: mips @@ -19,20 +19,27 @@ __start: aluipc $2, %pcrel_hi(_foo) # R_MIPS_PCHI16 addiu $2, $2, %pcrel_lo(_foo) # R_MIPS_PCLO16 + .data + .word _foo+8-. # R_MIPS_PC32 + # CHECK: Disassembly of section .text: # CHECK-NEXT: __start: # CHECK-NEXT: 20000: ec c8 00 08 lwpc $6, 32 # ^-- (0x20020-0x20000)>>2 -# CHECK-NEXT: 20004: 20 a6 00 06 beqc $5, $6, 24 +# CHECK-NEXT: 20004: 20 a6 00 06 beqc $5, $6, 28 # ^-- (0x20020-4-0x20004)>>2 -# CHECK-NEXT: 20008: d9 20 00 05 beqzc $9, 20 +# CHECK-NEXT: 20008: d9 20 00 05 beqzc $9, 24 # ^-- (0x20020-4-0x20008)>>2 -# CHECK-NEXT: 2000c: c8 00 00 04 bc 16 +# CHECK-NEXT: 2000c: c8 00 00 04 bc 20 # ^-- (0x20020-4-0x2000c)>>2 # CHECK-NEXT: 20010: ec 5f 00 00 aluipc $2, 0 # ^-- %hi(0x20020-0x20010) # CHECK-NEXT: 20014: 24 42 00 0c addiu $2, $2, 12 # ^-- %lo(0x20020-0x20014) +# CHECK: Contents of section .data: +# CHECK-NEXT: 40000 fffe0028 00000000 00000000 00000000 +# ^-- 0x20020 + 8 - 0x40000 + # CHECK: 00020000 .text 00000000 __start # CHECK: 00020020 .text 00000000 _foo diff --git a/test/ELF/mips-plt-copy.s b/test/ELF/mips-plt-copy.s new file mode 100644 index 000000000000..58883d884563 --- /dev/null +++ b/test/ELF/mips-plt-copy.s @@ -0,0 +1,85 @@ +# Check creating of R_MIPS_COPY and R_MIPS_JUMP_SLOT dynamic relocations +# and corresponding PLT entries. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o +# RUN: ld.lld %t.so.o -shared -o %t.so +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rel.dyn { +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0 +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data1 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: Section ({{.*}}) .rel.plt { +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo0 0x0 +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo1 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +# CHECK: Primary GOT { +# CHECK: Local entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Number of TLS and multi-GOT entries: 0 +# CHECK-NEXT: } + +# CHECK: PLT GOT { +# CHECK: Entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x{{[0-9A-F]+}} +# CHECK-NEXT: Initial: 0x{{[0-9A-F]+}} +# CHECK-NEXT: Value: 0x{{[0-9A-F]+}} +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: foo0 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x{{[0-9A-F]+}} +# CHECK-NEXT: Initial: 0x{{[0-9A-F]+}} +# CHECK-NEXT: Value: 0x{{[0-9A-F]+}} +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: foo1 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } + + .text + .globl __start +__start: + lui $t0,%hi(foo0) # R_MIPS_HI16 requires JUMP_SLOT/PLT entry + # for DSO defined func. + addi $t0,$t0,%lo(foo0) + lui $t0,%hi(bar) # Does not require PLT for locally defined func. + addi $t0,$t0,%lo(bar) + lui $t0,%hi(loc) # Does not require PLT for local func. + addi $t0,$t0,%lo(loc) + + lui $t0,%hi(data0) # R_MIPS_HI16 requires COPY rel for DSO defined data. + addi $t0,$t0,%lo(data0) + lui $t0,%hi(gd) # Does not require COPY rel for locally defined data. + addi $t0,$t0,%lo(gd) + lui $t0,%hi(ld) # Does not require COPY rel for local data. + addi $t0,$t0,%lo(ld) + + .globl bar + .type bar, @function +bar: + nop +loc: + nop + + .rodata + .globl gd +gd: + .word 0 +ld: + .word data1+8 # R_MIPS_32 requires REL32 dnamic relocation + # for DSO defined data. For now we generate COPY one. + .word foo1+8 # R_MIPS_32 requires PLT entry for DSO defined func. diff --git a/test/ELF/mips-relocs.s b/test/ELF/mips-relocs.s deleted file mode 100644 index c05b8fd3bdd1..000000000000 --- a/test/ELF/mips-relocs.s +++ /dev/null @@ -1,42 +0,0 @@ -# Check R_MIPS_32 relocation calculation. - -# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o -# RUN: ld.lld %t-be.o -o %t-be.exe -# RUN: llvm-objdump -t %t-be.exe | FileCheck %s -# RUN: llvm-objdump -s %t-be.exe | FileCheck -check-prefix=BE %s - -# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o -# RUN: ld.lld %t-el.o -o %t-el.exe -# RUN: llvm-objdump -t %t-el.exe | FileCheck %s -# RUN: llvm-objdump -s %t-el.exe | FileCheck -check-prefix=EL %s - -# REQUIRES: mips - - .globl __start -__start: - nop - - .data - .type v1,@object - .size v1,4 -v1: - .word 0 - - .globl v2 - .type v2,@object - .size v2,8 -v2: - .word v2+4 # R_MIPS_32 target v2 addend 4 - .word v1 # R_MIPS_32 target v1 addend 0 - -# CHECK: SYMBOL TABLE: -# CHECK: 00030000 l .data 00000004 v1 -# CHECK: 00030004 g .data 00000008 v2 - -# BE: Contents of section .data: -# BE-NEXT: 30000 00000000 00030008 00030000 -# ^-- v2+4 ^-- v1 - -# EL: Contents of section .data: -# EL-NEXT: 30000 00000000 08000300 00000300 -# ^-- v2+4 ^-- v1 diff --git a/test/ELF/mips-sto-plt.s b/test/ELF/mips-sto-plt.s new file mode 100644 index 000000000000..bd8de416680a --- /dev/null +++ b/test/ELF/mips-sto-plt.s @@ -0,0 +1,66 @@ +# Check assigning STO_MIPS_PLT flag to symbol needs a pointer equality. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o +# RUN: ld.lld %t.so.o -shared -o %t.so +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Symbol { +# CHECK: Name: foo0@ +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: foo1@ +# CHECK-NEXT: Value: 0x20050 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other [ (0x8) +# CHECK-NEXT: STO_MIPS_PLT +# CHECK-NEXT: ] +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } + +# CHECK: Primary GOT { +# CHECK: Local entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: ] +# CHECK: PLT GOT { +# CHECK: Entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Initial: +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: foo0 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Initial: +# CHECK-NEXT: Value: 0x20050 +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: foo1 +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .text + .globl __start +__start: + jal foo0 # R_MIPS_26 against 'foo0' from DSO + lui $t0,%hi(foo1) # R_MIPS_HI16/LO16 against 'foo1' from DSO + addi $t0,$t0,%lo(foo1) + +loc: + nop diff --git a/test/ELF/mips-tls-64.s b/test/ELF/mips-tls-64.s new file mode 100644 index 000000000000..9c05e940b1c1 --- /dev/null +++ b/test/ELF/mips-tls-64.s @@ -0,0 +1,86 @@ +# Check MIPS TLS 64-bit relocations handling. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \ +# RUN: %p/Inputs/mips-dynamic.s -o %t.so.o +# RUN: ld.lld -shared %t.so.o -o %t.so +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-objdump -d -s -t %t.exe | FileCheck -check-prefix=DIS %s +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# DIS: __start: +# DIS-NEXT: 20000: 24 62 80 28 addiu $2, $3, -32728 +# DIS-NEXT: 20004: 24 62 80 38 addiu $2, $3, -32712 +# DIS-NEXT: 20008: 8f 82 80 20 lw $2, -32736($gp) +# DIS-NEXT: 2000c: 24 62 80 48 addiu $2, $3, -32696 + +# DIS: Contents of section .got: +# DIS_NEXT: 30008 00000000 00000000 80000000 00000000 +# DIS_NEXT: 30018 00000000 00020000 00000000 00000000 +# DIS_NEXT: 30028 00000000 00000004 00000000 00000000 +# DIS_NEXT: 30038 00000000 00000000 00000000 00000004 + +# DIS: 0000000000030000 l .tdata 00000000 .tdata +# DIS: 0000000000030000 l .tdata 00000000 loc +# DIS: 0000000000000004 g .tdata 00000000 foo + +# CHECK: Relocations [ +# CHECK-NEXT: Section (7) .rela.dyn { +# CHECK-NEXT: 0x30020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0 +# CHECK-NEXT: 0x30028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE - 0x0 +# CHECK-NEXT: 0x30030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0 +# CHECK-NEXT: 0x30040 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE - 0x4 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Primary GOT { +# CHECK-NEXT: Canonical gp value: 0x37FF8 +# CHECK-NEXT: Reserved entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x30008 +# CHECK-NEXT: Access: -32752 +# CHECK-NEXT: Initial: 0x0 +# CHECK-NEXT: Purpose: Lazy resolver +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x30010 +# CHECK-NEXT: Access: -32744 +# CHECK-NEXT: Initial: 0x80000000 +# CHECK-NEXT: Purpose: Module pointer (GNU extension) +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Local entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x30018 +# CHECK-NEXT: Access: -32736 +# CHECK-NEXT: Initial: 0x0 +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: foo0 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Number of TLS and multi-GOT entries: 5 +# ^-- 0x30020 / -32728 - R_MIPS_TLS_GD - R_MIPS_TLS_DTPMOD32 foo +# ^-- 0x30028 / -32720 - R_MIPS_TLS_DTPREL32 foo +# ^-- 0x30030 / -32712 - R_MIPS_TLS_LDM - R_MIPS_TLS_DTPMOD32 loc +# ^-- 0x30038 / -32704 +# ^-- 0x30040 / -32696 - R_MIPS_TLS_GOTTPREL - R_MIPS_TLS_TPREL32 + + .text + .global __start +__start: + addiu $2, $3, %tlsgd(foo) # R_MIPS_TLS_GD + addiu $2, $3, %tlsldm(loc) # R_MIPS_TLS_LDM + lw $2, %got(foo0)($gp) + addiu $2, $3, %gottprel(foo) # R_MIPS_TLS_GOTTPREL + + .section .tdata,"awT",%progbits + .global foo +loc: + .word 0 +foo: + .word 0 diff --git a/test/ELF/mips-tls-hilo.s b/test/ELF/mips-tls-hilo.s new file mode 100644 index 000000000000..7628cb3a6ec6 --- /dev/null +++ b/test/ELF/mips-tls-hilo.s @@ -0,0 +1,52 @@ +# Check MIPS R_MIPS_TLS_DTPREL_HI16/LO16 and R_MIPS_TLS_TPREL_HI16/LO16 +# relocations handling. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t.exe +# RUN: llvm-objdump -d -t %t.exe | FileCheck -check-prefix=DIS %s +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s + +# RUN: ld.lld %t.o -shared -o %t.so +# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=SO %s + +# REQUIRES: mips + +# DIS: __start: +# DIS-NEXT: 20000: 24 62 00 00 addiu $2, $3, 0 +# %hi(loc0 - .tdata - 0x8000) --^ +# DIS-NEXT: 20004: 24 62 80 00 addiu $2, $3, -32768 +# %lo(loc0 - .tdata - 0x8000) --^ +# DIS-NEXT: 20008: 24 62 00 00 addiu $2, $3, 0 +# %hi(loc0 - .tdata - 0x7000) --^ +# DIS-NEXT: 2000c: 24 62 90 00 addiu $2, $3, -28672 +# %lo(loc0 - .tdata - 0x7000) --^ + +# DIS: 00030000 l .tdata 00000000 .tdata +# DIS: 00030000 l .tdata 00000000 loc0 + +# CHECK: Relocations [ +# CHECK-NEXT: ] +# CHECK-NOT: Primary GOT + +# SO: Relocations [ +# SO-NEXT: ] +# SO: Primary GOT { +# SO: Local entries [ +# SO-NEXT: ] +# SO-NEXT: Global entries [ +# SO-NEXT: ] +# SO-NEXT: Number of TLS and multi-GOT entries: 0 +# SO-NEXT: } + + .text + .globl __start + .type __start,@function +__start: + addiu $2, $3, %dtprel_hi(loc0) # R_MIPS_TLS_DTPREL_HI16 + addiu $2, $3, %dtprel_lo(loc0) # R_MIPS_TLS_DTPREL_LO16 + addiu $2, $3, %tprel_hi(loc0) # R_MIPS_TLS_TPREL_HI16 + addiu $2, $3, %tprel_lo(loc0) # R_MIPS_TLS_TPREL_LO16 + + .section .tdata,"awT",%progbits +loc0: + .word 0 diff --git a/test/ELF/mips-tls.s b/test/ELF/mips-tls.s new file mode 100644 index 000000000000..9635558c2d95 --- /dev/null +++ b/test/ELF/mips-tls.s @@ -0,0 +1,77 @@ +# Check MIPS TLS relocations handling. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %p/Inputs/mips-tls.s -o %t.so.o +# RUN: ld.lld -shared %t.so.o -o %t.so +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-objdump -d -s -t %t.exe | FileCheck -check-prefix=DIS %s +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# DIS: __start: +# DIS-NEXT: 20000: 24 62 80 1c addiu $2, $3, -32740 +# DIS-NEXT: 20004: 24 62 80 24 addiu $2, $3, -32732 +# DIS-NEXT: 20008: 8f 82 80 18 lw $2, -32744($gp) +# DIS-NEXT: 2000c: 24 62 80 2c addiu $2, $3, -32724 + +# DIS: Contents of section .got: +# DIS_NEXT: 30004 00000000 80000000 00020000 00000000 +# DIS_NEXT: 30014 00000000 00000000 00000000 00000000 + +# DIS: 00030000 l .tdata 00000000 .tdata +# DIS: 00030000 l .tdata 00000000 loc +# DIS: 00000000 g *UND* 00000000 foo + +# CHECK: Relocations [ +# CHECK-NEXT: Section (7) .rel.dyn { +# CHECK-NEXT: 0x30018 R_MIPS_TLS_DTPMOD32 - 0x0 +# CHECK-NEXT: 0x30010 R_MIPS_TLS_DTPMOD32 foo 0x0 +# CHECK-NEXT: 0x30014 R_MIPS_TLS_DTPREL32 foo 0x0 +# CHECK-NEXT: 0x30020 R_MIPS_TLS_TPREL32 foo 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Primary GOT { +# CHECK-NEXT: Canonical gp value: 0x37FF4 +# CHECK-NEXT: Reserved entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x30004 +# CHECK-NEXT: Access: -32752 +# CHECK-NEXT: Initial: 0x0 +# CHECK-NEXT: Purpose: Lazy resolver +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x30008 +# CHECK-NEXT: Access: -32748 +# CHECK-NEXT: Initial: 0x80000000 +# CHECK-NEXT: Purpose: Module pointer (GNU extension) +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x3000C +# CHECK-NEXT: Access: -32744 +# CHECK-NEXT: Initial: 0x20000 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Number of TLS and multi-GOT entries: 5 +# ^-- 0x30010 / -32740 - R_MIPS_TLS_GD - R_MIPS_TLS_DTPMOD32 foo +# ^-- 0x30018 / -32736 - R_MIPS_TLS_DTPREL32 foo +# ^-- 0x3001C / -32732 - R_MIPS_TLS_LDM - R_MIPS_TLS_DTPMOD32 loc +# ^-- 0x30020 / -32728 +# ^-- 0x30024 / -32724 - R_MIPS_TLS_GOTTPREL - R_MIPS_TLS_TPREL32 + + .text + .global __start +__start: + addiu $2, $3, %tlsgd(foo) # R_MIPS_TLS_GD + addiu $2, $3, %tlsldm(loc) # R_MIPS_TLS_LDM + lw $2, %got(__start)($gp) + addiu $2, $3, %gottprel(foo) # R_MIPS_TLS_GOTTPREL + + .section .tdata,"awT",%progbits +loc: + .word 0 diff --git a/test/ELF/no-augmentation.s b/test/ELF/no-augmentation.s new file mode 100644 index 000000000000..31cd92e39b1c --- /dev/null +++ b/test/ELF/no-augmentation.s @@ -0,0 +1,19 @@ +// RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o +// RUN: ld.lld --eh-frame-hdr %t.o -o %t | FileCheck -allow-empty %s + +// REQUIRES: mips + +// CHECK-NOT: corrupted or unsupported CIE information +// CHECK-NOT: corrupted CIE + +.global __start +__start: + +.section .eh_frame,"aw",@progbits + .4byte 9 + .4byte 0x0 + .byte 0x1 + .string "" + .uleb128 0x1 + .sleb128 -4 + .byte 0x1f diff --git a/test/ELF/no-inhibit-exec.s b/test/ELF/no-inhibit-exec.s index fe2240b731fe..31638fd92cc9 100644 --- a/test/ELF/no-inhibit-exec.s +++ b/test/ELF/no-inhibit-exec.s @@ -6,10 +6,10 @@ # CHECK: Disassembly of section .text: # CHECK-NEXT: _start -# CHECK-NEXT: 11000: e8 fb ef fe ff callq -69637 +# CHECK-NEXT: 11000: e8 fb ef fe ff callq -69637 # next code will not link without noinhibit-exec flag # because of undefined symbol _bar -.globl _start; +.globl _start _start: call _bar diff --git a/test/ELF/no-plt-shared.s b/test/ELF/no-plt-shared.s new file mode 100644 index 000000000000..ac45ed502c38 --- /dev/null +++ b/test/ELF/no-plt-shared.s @@ -0,0 +1,17 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o +// RUN: ld.lld %t2.o %t.so -o %t2.so -shared +// RUN: llvm-readobj -r %t2.so | FileCheck %s + + .data +fp: + .quad bar + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: R_X86_64_64 bar 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/no-undefined.s b/test/ELF/no-undefined.s index 94378bde40a2..fa4d5e928763 100644 --- a/test/ELF/no-undefined.s +++ b/test/ELF/no-undefined.s @@ -4,4 +4,4 @@ .globl _shared _shared: - call _unresolved + callq _unresolved@PLT diff --git a/test/ELF/noplt-pie.s b/test/ELF/noplt-pie.s new file mode 100644 index 000000000000..1eb84934184e --- /dev/null +++ b/test/ELF/noplt-pie.s @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t2.so +# RUN: ld.lld %t1.o %t2.so -o %t.out +# RUN: llvm-readobj -s -r %t.out | FileCheck %s + +# CHECK: Section { +# CHECK-NOT: Name: .plt + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.dyn { +# CHECK-NEXT: 0x120B0 R_X86_64_GLOB_DAT bar 0x0 +# CHECK-NEXT: 0x120B8 R_X86_64_GLOB_DAT zed 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.global _start +_start: + movq bar@GOTPCREL(%rip), %rcx + movq zed@GOTPCREL(%rip), %rcx diff --git a/test/ELF/note.s b/test/ELF/note.s new file mode 100644 index 000000000000..a383b95c9907 --- /dev/null +++ b/test/ELF/note.s @@ -0,0 +1,18 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t -shared +// RUN: llvm-readobj -program-headers %t | FileCheck %s + +// CHECK: Type: PT_NOTE +// CHECK-NEXT: Offset: +// CHECK-NEXT: VirtualAddress: +// CHECK-NEXT: PhysicalAddress: +// CHECK-NEXT: FileSize: 8 +// CHECK-NEXT: MemSize: 8 +// CHECK-NEXT: Flags [ +// CHECK-NEXT: PF_R +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 1 + + .section .note.test,"a",@note + .quad 42 diff --git a/test/ELF/phdr-align.s b/test/ELF/phdr-align.s new file mode 100644 index 000000000000..58d537b46840 --- /dev/null +++ b/test/ELF/phdr-align.s @@ -0,0 +1,82 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o + +# RUN: echo "SECTIONS { \ +# RUN: .bss : { *(.bss) } \ +# RUN: .data : { *(.data) } \ +# RUN: .text : { *(.text) } }" > %t.script +# RUN: ld.lld %t.o --script %t.script -o %t +# RUN: llvm-readobj -sections -symbols %t | FileCheck %s + +# CHECK: Sections [ +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 0 +# CHECK-NEXT: Name: (0) +# CHECK-NEXT: Type: SHT_NULL +# CHECK-NEXT: Flags [ +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 0 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 1 +# CHECK-NEXT: Name: .bss +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x158 +# CHECK-NEXT: Offset: 0x158 +# CHECK-NEXT: Size: 6 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .data +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x15E +# CHECK-NEXT: Offset: 0x15E +# CHECK-NEXT: Size: 2 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_EXECINSTR +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x160 +# CHECK-NEXT: Offset: 0x160 +# CHECK-NEXT: Size: 1 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } + +.global _start +.text +_start: + nop +.data + .word 1 +.bss + .space 6 diff --git a/test/ELF/pie-weak.s b/test/ELF/pie-weak.s new file mode 100644 index 000000000000..e74bcdfc09c0 --- /dev/null +++ b/test/ELF/pie-weak.s @@ -0,0 +1,16 @@ +# RUN: llvm-mc -filetype=obj -relax-relocations=false -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -pie %t.o -o %t +# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s +# RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s + +# RELOCS: Relocations [ +# RELOCS-NEXT: ] + +.weak foo + +.globl _start +_start: +# DISASM: _start: +# DISASM-NEXT: 1000: 48 8b 05 69 10 00 00 movq 4201(%rip), %rax +# ^ .got - (.text + 7) +mov foo@gotpcrel(%rip), %rax diff --git a/test/ELF/pie.s b/test/ELF/pie.s new file mode 100644 index 000000000000..4cf1743ee736 --- /dev/null +++ b/test/ELF/pie.s @@ -0,0 +1,102 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: ld.lld -pie %t1.o -o %t +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s + +## Test --pic-executable alias +# RUN: ld.lld --pic-executable %t1.o -o %t +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s + +# CHECK: ElfHeader { +# CHECK-NEXT: Ident { +# CHECK-NEXT: Magic: (7F 45 4C 46) +# CHECK-NEXT: Class: 64-bit +# CHECK-NEXT: DataEncoding: LittleEndian +# CHECK-NEXT: FileVersion: 1 +# CHECK-NEXT: OS/ABI: SystemV +# CHECK-NEXT: ABIVersion: 0 +# CHECK-NEXT: Unused: (00 00 00 00 00 00 00) +# CHECK-NEXT: } +# CHECK-NEXT: Type: SharedObject +# CHECK-NEXT: Machine: EM_X86_64 +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: Entry: 0x1000 +# CHECK-NEXT: ProgramHeaderOffset: 0x40 +# CHECK-NEXT: SectionHeaderOffset: 0x1110 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: ] +# CHECK-NEXT: HeaderSize: 64 +# CHECK-NEXT: ProgramHeaderEntrySize: 56 +# CHECK-NEXT: ProgramHeaderCount: 7 +# CHECK-NEXT: SectionHeaderEntrySize: 64 +# CHECK-NEXT: SectionHeaderCount: 9 +# CHECK-NEXT: StringTableSectionIndex: 7 +# CHECK-NEXT: } + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0x40 +# CHECK-NEXT: PhysicalAddress: 0x40 +# CHECK-NEXT: FileSize: 392 +# CHECK-NEXT: MemSize: 392 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x0 +# CHECK-NEXT: PhysicalAddress: 0x0 +# CHECK-NEXT: FileSize: 497 +# CHECK-NEXT: MemSize: 497 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0x1000 +# CHECK-NEXT: FileSize: 0 +# CHECK-NEXT: MemSize: 0 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_X +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0x1000 +# CHECK-NEXT: FileSize: 112 +# CHECK-NEXT: MemSize: 112 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_W +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_DYNAMIC +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0x1000 +# CHECK-NEXT: FileSize: 112 +# CHECK-NEXT: MemSize: 112 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_W +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } + +.globl _start +_start: diff --git a/test/ELF/plt-aarch64.s b/test/ELF/plt-aarch64.s index 6ea732ec7c68..3f124b0af49c 100644 --- a/test/ELF/plt-aarch64.s +++ b/test/ELF/plt-aarch64.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o -// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/shared.s -o %t2.o +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/plt-aarch64.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld -shared %t.o %t2.so -o %t.so // RUN: ld.lld %t.o %t2.so -o %t.exe diff --git a/test/ELF/plt-i686.s b/test/ELF/plt-i686.s index 4947e0e734fd..bf07fede7989 100644 --- a/test/ELF/plt-i686.s +++ b/test/ELF/plt-i686.s @@ -2,12 +2,13 @@ // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld %t.o %t2.so -o %t -// RUN: llvm-readobj -s -r %t | FileCheck --check-prefix=CHECK %s +// RUN: llvm-readobj -s -r %t | FileCheck %s // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s // RUN: ld.lld -shared %t.o %t2.so -o %t // RUN: llvm-readobj -s -r %t | FileCheck --check-prefix=CHECKSHARED %s // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMSHARED %s - +// RUN: ld.lld -pie %t.o %t2.so -o %t +// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMPIE %s // REQUIRES: x86 // CHECK: Name: .plt @@ -147,6 +148,21 @@ // DISASMSHARED-NEXT: 1046: 68 08 00 00 00 pushl $8 // DISASMSHARED-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt> +// DISASMPIE: Disassembly of section .plt: +// DISASMPIE-NEXT: .plt: +// DISASMPIE-NEXT: 1020: ff b3 04 00 00 00 pushl 4(%ebx) +// DISASMPIE-NEXT: 1026: ff a3 08 00 00 00 jmpl *8(%ebx) +// DISASMPIE-NEXT: 102c: 90 nop +// DISASMPIE-NEXT: 102d: 90 nop +// DISASMPIE-NEXT: 102e: 90 nop +// DISASMPIE-NEXT: 102f: 90 nop +// DISASMPIE-NEXT: 1030: ff a3 0c 30 00 00 jmpl *12300(%ebx) +// DISASMPIE-NEXT: 1036: 68 00 00 00 00 pushl $0 +// DISASMPIE-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt> +// DISASMPIE-NEXT: 1040: ff a3 10 30 00 00 jmpl *12304(%ebx) +// DISASMPIE-NEXT: 1046: 68 08 00 00 00 pushl $8 +// DISASMPIE-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt> + local: .long 0 diff --git a/test/ELF/plt.s b/test/ELF/plt.s index 1183d32c3ccc..60268a68195a 100644 --- a/test/ELF/plt.s +++ b/test/ELF/plt.s @@ -109,7 +109,7 @@ // DISASM2-NEXT: 11040: ff 25 da 1f 00 00 jmpq *8154(%rip) // DISASM2-NEXT: 11046: 68 01 00 00 00 pushq $1 // DISASM2-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt> -// DISASM2-NEXT-NOT: 110C0 +// DISASM2-NOT: 110C0 .global _start _start: diff --git a/test/ELF/ppc64-addr16-error.s b/test/ELF/ppc64-addr16-error.s index 57a919a9b338..2bc8ef2ae4d7 100644 --- a/test/ELF/ppc64-addr16-error.s +++ b/test/ELF/ppc64-addr16-error.s @@ -1,7 +1,8 @@ // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t -// RUN: not ld.lld -shared %t -o %t2 2>&1 | FileCheck %s +// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2 +// RUN: not ld.lld -shared %t %t2 -o %t3 2>&1 | FileCheck %s // REQUIRES: ppc .short sym+65539 -// CHECK: Relocation R_PPC64_ADDR16 out of range +// CHECK: relocation R_PPC64_ADDR16 out of range diff --git a/test/ELF/ppc64-relocs.s b/test/ELF/ppc64-relocs.s index 61f9a1eb3ce3..28902aed26df 100644 --- a/test/ELF/ppc64-relocs.s +++ b/test/ELF/ppc64-relocs.s @@ -43,7 +43,7 @@ _start: # CHECK: Disassembly of section .R_PPC64_TOC16_HI: # CHECK: .FR_PPC64_TOC16_HI: -# CHECK: 10010014: 3c 22 10 01 addis 1, 2, 4097 +# CHECK: 10010014: 3c 22 ff ff addis 1, 2, -1 .section .R_PPC64_TOC16_HA,"ax",@progbits .globl .FR_PPC64_TOC16_HA @@ -52,7 +52,7 @@ _start: # CHECK: Disassembly of section .R_PPC64_TOC16_HA: # CHECK: .FR_PPC64_TOC16_HA: -# CHECK: 10010018: 3c 22 10 02 addis 1, 2, 4098 +# CHECK: 10010018: 3c 22 00 00 addis 1, 2, 0 .section .R_PPC64_REL24,"ax",@progbits .globl .FR_PPC64_REL24 diff --git a/test/ELF/ppc64-toc-restore.s b/test/ELF/ppc64-toc-restore.s index cee105b35e64..dbfeaece7db4 100644 --- a/test/ELF/ppc64-toc-restore.s +++ b/test/ELF/ppc64-toc-restore.s @@ -53,8 +53,8 @@ last: // CHECK: Disassembly of section .plt: // CHECK: .plt: // CHECK: 10010020: f8 41 00 28 std 2, 40(1) -// CHECK: 10010024: 3d 62 00 00 addis 11, 2, 0 -// CHECK: 10010028: e9 8b 80 00 ld 12, -32768(11) +// CHECK: 10010024: 3d 62 10 03 addis 11, 2, 4099 +// CHECK: 10010028: e9 8b 80 18 ld 12, -32744(11) // CHECK: 1001002c: e9 6c 00 00 ld 11, 0(12) // CHECK: 10010030: 7d 69 03 a6 mtctr 11 // CHECK: 10010034: e8 4c 00 08 ld 2, 8(12) diff --git a/test/ELF/pre_init_fini_array.s b/test/ELF/pre_init_fini_array.s index bf32283d2579..4ddcb6947e5b 100644 --- a/test/ELF/pre_init_fini_array.s +++ b/test/ELF/pre_init_fini_array.s @@ -67,7 +67,9 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .fini_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -76,7 +78,9 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .fini_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -85,7 +89,9 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .init_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -94,7 +100,9 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .init_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -103,7 +111,9 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .preinit_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -112,7 +122,9 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other [ +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .preinit_array // CHECK-NEXT: } diff --git a/test/ELF/progname.s b/test/ELF/progname.s index 5712b95d276d..10cbf177c69b 100644 --- a/test/ELF/progname.s +++ b/test/ELF/progname.s @@ -1,10 +1,29 @@ // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o -// RUN: echo '.global __progname' > %t2.s +// RUN: echo .global __progname > %t2.s // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %t2.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld -o %t %t.o %t2.so // RUN: llvm-readobj -dyn-symbols %t | FileCheck %s + +// Inputs/progname-ver.so consists of the assembly file +// +// .global bar +// bar: +// .quad __progname +// +// linked into a library with the version script +// +// VER_1 { +// global: +// bar; +// }; +// +// We should create it with lld itself once we it supports that. + +// RUN: ld.lld -o %t %t.o %p/Inputs/progname-ver.so +// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s + // CHECK: Name: __progname@ // CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 diff --git a/test/ELF/protected-shared.s b/test/ELF/protected-shared.s new file mode 100644 index 000000000000..e69b10899dae --- /dev/null +++ b/test/ELF/protected-shared.s @@ -0,0 +1,52 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/protected-shared.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t2.so +// RUN: ld.lld %t.o %t2.so -o %t +// RUN: llvm-readobj -t --dyn-symbols %t | FileCheck %s + + .global _start +_start: + + .global bar +bar: + + .data + .quad foo + +// CHECK: Name: bar +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text + +// CHECK: Name: foo +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined + +// CHECK: DynamicSymbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: @ +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local (0x0) +// CHECK-NEXT: Type: None (0x0) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined (0x0) +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: foo@ +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/rel-offset.s b/test/ELF/rel-offset.s new file mode 100644 index 000000000000..6f35bcebc4b0 --- /dev/null +++ b/test/ELF/rel-offset.s @@ -0,0 +1,15 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t -shared +// RUN: llvm-readobj -r %t | FileCheck %s + + .section .data.foo,"aw",@progbits + .quad foo + + .section .data.zed,"aw",@progbits + .quad foo + +// CHECK: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x2000 R_X86_64_64 foo 0x0 +// CHECK-NEXT: 0x2008 R_X86_64_64 foo 0x0 +// CHECK-NEXT: } diff --git a/test/ELF/relative-dynamic-reloc-pie.s b/test/ELF/relative-dynamic-reloc-pie.s new file mode 100644 index 000000000000..d9967af52eb6 --- /dev/null +++ b/test/ELF/relative-dynamic-reloc-pie.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -pie %t.o -o %t.pie +# RUN: llvm-readobj -r -dyn-symbols %t.pie | FileCheck %s + +## Test that we create R_X86_64_RELATIVE relocations with -pie. +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.dyn { +# CHECK-NEXT: 0x3000 R_X86_64_RELATIVE - 0x3000 +# CHECK-NEXT: 0x3008 R_X86_64_RELATIVE - 0x3008 +# CHECK-NEXT: 0x3010 R_X86_64_RELATIVE - 0x3009 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.globl _start +_start: +nop + + .data +foo: + .quad foo + +.hidden bar +.global bar +bar: + .quad bar + .quad bar + 1 diff --git a/test/ELF/relative-dynamic-reloc-ppc64.s b/test/ELF/relative-dynamic-reloc-ppc64.s index b22b33f9f469..81a7a7027bb8 100644 --- a/test/ELF/relative-dynamic-reloc-ppc64.s +++ b/test/ELF/relative-dynamic-reloc-ppc64.s @@ -10,10 +10,10 @@ // CHECK-NEXT: Section ({{.*}}) .rela.dyn { // CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_PPC64_RELATIVE - 0x[[FOO_ADDR]] // CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_PPC64_RELATIVE - 0x[[BAR_ADDR]] -// CHECK-NEXT: 0x10010 R_PPC64_RELATIVE - 0x10009 +// CHECK-NEXT: 0x20010 R_PPC64_RELATIVE - 0x20009 // CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[ZED_ADDR:.*]] // CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[FOO_ADDR]] -// CHECK-NEXT: 0x1D0 R_PPC64_ADDR64 external 0x0 +// CHECK-NEXT: 0x20028 R_PPC64_ADDR64 external 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] @@ -47,6 +47,7 @@ // CHECK-NEXT: } // CHECK-NEXT: ] + .data foo: .quad foo @@ -60,7 +61,7 @@ bar: .comm zed,1 .quad zed - .section abc,"a" + .section abc,"aw" .quad foo .quad external diff --git a/test/ELF/relative-dynamic-reloc.s b/test/ELF/relative-dynamic-reloc.s index 41fcd8a6a556..aac55669bb17 100644 --- a/test/ELF/relative-dynamic-reloc.s +++ b/test/ELF/relative-dynamic-reloc.s @@ -9,10 +9,10 @@ // CHECK-NEXT: Section ({{.*}}) .rela.dyn { // CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_X86_64_RELATIVE - 0x[[FOO_ADDR]] // CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_X86_64_RELATIVE - 0x[[BAR_ADDR]] -// CHECK-NEXT: 0x1010 R_X86_64_RELATIVE - 0x1009 +// CHECK-NEXT: 0x2010 R_X86_64_RELATIVE - 0x2009 // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[ZED_ADDR:.*]] // CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[FOO_ADDR]] -// CHECK-NEXT: 0x1D0 R_X86_64_64 external 0x0 +// CHECK-NEXT: 0x2028 R_X86_64_64 external 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] @@ -46,6 +46,7 @@ // CHECK-NEXT: } // CHECK-NEXT: ] + .data foo: .quad foo @@ -59,7 +60,7 @@ bar: .comm zed,1 .quad zed - .section abc,"a" + .section abc,"aw" .quad foo .quad external diff --git a/test/ELF/relocatable-bss.s b/test/ELF/relocatable-bss.s new file mode 100644 index 000000000000..0411bf339c43 --- /dev/null +++ b/test/ELF/relocatable-bss.s @@ -0,0 +1,40 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: ld.lld -r %t1.o -o %t +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s + +## We check here that .bss does not occupy the space in file. +## If it would, the SectionHeaderOffset would have offset about 5 megabytes. +# CHECK: ElfHeader { +# CHECK-NEXT: Ident { +# CHECK-NEXT: Magic: (7F 45 4C 46) +# CHECK-NEXT: Class: 64-bit +# CHECK-NEXT: DataEncoding: LittleEndian +# CHECK-NEXT: FileVersion: 1 +# CHECK-NEXT: OS/ABI: SystemV +# CHECK-NEXT: ABIVersion: 0 +# CHECK-NEXT: Unused: (00 00 00 00 00 00 00) +# CHECK-NEXT: } +# CHECK-NEXT: Type: Relocatable +# CHECK-NEXT: Machine: EM_X86_64 +# CHECK-NEXT: Version: +# CHECK-NEXT: Entry: +# CHECK-NEXT: ProgramHeaderOffset: +# CHECK-NEXT: SectionHeaderOffset: 0xA8 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: ] +# CHECK-NEXT: HeaderSize: +# CHECK-NEXT: ProgramHeaderEntrySize: +# CHECK-NEXT: ProgramHeaderCount: +# CHECK-NEXT: SectionHeaderEntrySize: +# CHECK-NEXT: SectionHeaderCount: +# CHECK-NEXT: StringTableSectionIndex: +# CHECK-NEXT: } + +.text +.globl _start +_start: + nop + +.bss + .space 5242880 diff --git a/test/ELF/relocatable-ehframe.s b/test/ELF/relocatable-ehframe.s new file mode 100644 index 000000000000..d48402099c36 --- /dev/null +++ b/test/ELF/relocatable-ehframe.s @@ -0,0 +1,51 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable-ehframe.s -o %t2.o +# RUN: ld.lld -r %t1.o %t2.o -o %t +# RUN: llvm-readobj -r -s -section-data %t | FileCheck %s + +# CHECK: Name: .strtab +# CHECK-NEXT: Type: SHT_STRTAB +# CHECK-NEXT: Flags [ +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset +# CHECK-NEXT: Size: 9 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 00005F73 74617274 00 |.._start.| +# CHECK-NEXT: ) + +# CHECK: Relocations [ +# CHECK-NEXT: Section {{.*}} .rela.eh_frame { +# CHECK-NEXT: 0x20 R_X86_64_PC32 foo 0x0 +# CHECK-NEXT: 0x34 R_X86_64_PC32 bar 0x0 +# CHECK-NEXT: 0x48 R_X86_64_PC32 dah 0x0 +# CHECK-NEXT: 0x78 R_X86_64_PC32 foo1 0x0 +# CHECK-NEXT: 0x8C R_X86_64_PC32 bar1 0x0 +# CHECK-NEXT: 0xA0 R_X86_64_PC32 dah1 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.section foo,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.section bar,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.section dah,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.text +.globl _start +_start: + nop diff --git a/test/ELF/relocatable-reloc.s b/test/ELF/relocatable-reloc.s new file mode 100644 index 000000000000..c576073a7510 --- /dev/null +++ b/test/ELF/relocatable-reloc.s @@ -0,0 +1,14 @@ +// RUN: llvm-mc -filetype=obj %s -o %t.o -triple=x86_64-pc-linux +// RUN: ld.lld %t.o %t.o -r -o %t2.o +// RUN: llvm-readobj -r %t2.o | FileCheck %s + +.weak foo +foo: +.quad foo + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.text { +// CHECK-NEXT: 0x0 R_X86_64_64 foo 0x0 +// CHECK-NEXT: 0x8 R_X86_64_64 foo 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/relocatable-symbols.s b/test/ELF/relocatable-symbols.s new file mode 100644 index 000000000000..75ed17ec5f6f --- /dev/null +++ b/test/ELF/relocatable-symbols.s @@ -0,0 +1,183 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld -r %t -o %tout +# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s +# RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s + +# DISASM: _start: +# DISASM-NEXT: 0: {{.*}} callq 0 +# DISASM-NEXT: 5: {{.*}} callq 0 +# DISASM-NEXT: a: {{.*}} callq 0 +# DISASM-NEXT: f: {{.*}} callq 0 +# DISASM-NEXT: 14: {{.*}} callq 0 +# DISASM-NEXT: 19: {{.*}} callq 0 +# DISASM-NEXT: 1e: {{.*}} callq 0 +# DISASM-NEXT: 23: {{.*}} callq 0 +# DISASM-NEXT: 28: {{.*}} callq 0 +# DISASM-NEXT: 2d: {{.*}} callq 0 +# DISASM-NEXT: 32: {{.*}} callq 0 +# DISASM-NEXT: 37: {{.*}} callq 0 +# DISASM-NEXT: Disassembly of section foo: +# DISASM-NEXT: foo: +# DISASM-NEXT: 0: 90 nop +# DISASM-NEXT: 1: 90 nop +# DISASM-NEXT: 2: 90 nop +# DISASM-NEXT: Disassembly of section bar: +# DISASM-NEXT: bar: +# DISASM-NEXT: 0: 90 nop +# DISASM-NEXT: 1: 90 nop +# DISASM-NEXT: 2: 90 nop + +# SYMBOL: Relocations [ +# SYMBOL-NEXT: Section ({{.*}}) .rela.text { +# SYMBOL-NEXT: 0x1 R_X86_64_PC32 __start_foo 0x0 +# SYMBOL-NEXT: 0x6 R_X86_64_PC32 __stop_foo 0x0 +# SYMBOL-NEXT: 0xB R_X86_64_PC32 __start_bar 0x0 +# SYMBOL-NEXT: 0x10 R_X86_64_PC32 __stop_bar 0x0 +# SYMBOL-NEXT: 0x15 R_X86_64_PC32 __start_doo 0x0 +# SYMBOL-NEXT: 0x1A R_X86_64_PC32 __stop_doo 0x0 +# SYMBOL-NEXT: 0x1F R_X86_64_PC32 __preinit_array_start 0x0 +# SYMBOL-NEXT: 0x24 R_X86_64_PC32 __preinit_array_end 0x0 +# SYMBOL-NEXT: 0x29 R_X86_64_PC32 __init_array_start 0x0 +# SYMBOL-NEXT: 0x2E R_X86_64_PC32 __init_array_end 0x0 +# SYMBOL-NEXT: 0x33 R_X86_64_PC32 __fini_array_start 0x0 +# SYMBOL-NEXT: 0x38 R_X86_64_PC32 __fini_array_end 0x0 +# SYMBOL-NEXT: } +# SYMBOL-NEXT: ] +# SYMBOL: Symbol { +# SYMBOL: Name: __fini_array_end +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __fini_array_start +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __init_array_end +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __init_array_start +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __preinit_array_end +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __preinit_array_start +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __start_bar +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __start_doo +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __start_foo +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __stop_bar +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __stop_doo +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } +# SYMBOL-NEXT: Symbol { +# SYMBOL-NEXT: Name: __stop_foo +# SYMBOL-NEXT: Value: 0x0 +# SYMBOL-NEXT: Size: 0 +# SYMBOL-NEXT: Binding: Global +# SYMBOL-NEXT: Type: None +# SYMBOL-NEXT: Other: 0 +# SYMBOL-NEXT: Section: Undefined +# SYMBOL-NEXT: } + +.global _start +.text +_start: + call __start_foo + call __stop_foo + + call __start_bar + call __stop_bar + + call __start_doo + call __stop_doo + + call __preinit_array_start + call __preinit_array_end + call __init_array_start + call __init_array_end + call __fini_array_start + call __fini_array_end + +.section foo,"ax" + nop + nop + nop + +.section bar,"ax" + nop + nop + nop diff --git a/test/ELF/relocatable.s b/test/ELF/relocatable.s index 9fb171d4ed50..032cb6336c08 100644 --- a/test/ELF/relocatable.s +++ b/test/ELF/relocatable.s @@ -1,9 +1,120 @@ # REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable.s -o %t2.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable2.s -o %t3.o +# RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s +# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: not ld.lld -r %t -o %t2 2>&1 | FileCheck %s +## Test --relocatable alias +# RUN: ld.lld --relocatable %t1.o %t2.o %t3.o -o %t +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s +# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s -# CHECK: -r option is not supported. Use 'ar' command instead. +## Verify that we can use our relocation output as input to produce executable +# RUN: ld.lld -e main %t -o %texec +# RUN: llvm-readobj -file-headers %texec | FileCheck -check-prefix=CHECKEXE %s -.globl _start; -_start: +# CHECK: ElfHeader { +# CHECK-NEXT: Ident { +# CHECK-NEXT: Magic: (7F 45 4C 46) +# CHECK-NEXT: Class: 64-bit +# CHECK-NEXT: DataEncoding: LittleEndian +# CHECK-NEXT: FileVersion: 1 +# CHECK-NEXT: OS/ABI: SystemV +# CHECK-NEXT: ABIVersion: 0 +# CHECK-NEXT: Unused: (00 00 00 00 00 00 00) +# CHECK-NEXT: } +# CHECK-NEXT: Type: Relocatable +# CHECK-NEXT: Machine: EM_X86_64 +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: Entry: 0x0 +# CHECK-NEXT: ProgramHeaderOffset: 0x0 +# CHECK-NEXT: SectionHeaderOffset: 0x2C0 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: ] +# CHECK-NEXT: HeaderSize: 64 +# CHECK-NEXT: ProgramHeaderEntrySize: 0 +# CHECK-NEXT: ProgramHeaderCount: 0 +# CHECK-NEXT: SectionHeaderEntrySize: 64 +# CHECK-NEXT: SectionHeaderCount: 7 +# CHECK-NEXT: StringTableSectionIndex: 5 +# CHECK-NEXT: } + +# CHECK: Relocations [ +# CHECK-NEXT: Section (3) .rela.text { +# CHECK-NEXT: 0x3 R_X86_64_32S x 0x0 +# CHECK-NEXT: 0xE R_X86_64_32S y 0x0 +# CHECK-NEXT: 0x23 R_X86_64_32S xx 0x0 +# CHECK-NEXT: 0x2E R_X86_64_32S yy 0x0 +# CHECK-NEXT: 0x43 R_X86_64_32S xxx 0x0 +# CHECK-NEXT: 0x4E R_X86_64_32S yyy 0x0 +# CHECK-NEXT: } + +# CHECKTEXT: Disassembly of section .text: +# CHECKTEXT-NEXT: main: +# CHECKTEXT-NEXT: 0: c7 04 25 00 00 00 00 05 00 00 00 movl $5, 0 +# CHECKTEXT-NEXT: b: c7 04 25 00 00 00 00 07 00 00 00 movl $7, 0 +# CHECKTEXT: foo: +# CHECKTEXT-NEXT: 20: c7 04 25 00 00 00 00 01 00 00 00 movl $1, 0 +# CHECKTEXT-NEXT: 2b: c7 04 25 00 00 00 00 02 00 00 00 movl $2, 0 +# CHECKTEXT: bar: +# CHECKTEXT-NEXT: 40: c7 04 25 00 00 00 00 08 00 00 00 movl $8, 0 +# CHECKTEXT-NEXT: 4b: c7 04 25 00 00 00 00 09 00 00 00 movl $9, 0 + +# CHECKEXE: Format: ELF64-x86-64 +# CHECKEXE-NEXT: Arch: x86_64 +# CHECKEXE-NEXT: AddressSize: 64bit +# CHECKEXE-NEXT: LoadName: +# CHECKEXE-NEXT: ElfHeader { +# CHECKEXE-NEXT: Ident { +# CHECKEXE-NEXT: Magic: (7F 45 4C 46) +# CHECKEXE-NEXT: Class: 64-bit +# CHECKEXE-NEXT: DataEncoding: LittleEndian +# CHECKEXE-NEXT: FileVersion: 1 +# CHECKEXE-NEXT: OS/ABI: SystemV (0x0) +# CHECKEXE-NEXT: ABIVersion: 0 +# CHECKEXE-NEXT: Unused: (00 00 00 00 00 00 00) +# CHECKEXE-NEXT: } +# CHECKEXE-NEXT: Type: Executable +# CHECKEXE-NEXT: Machine: EM_X86_64 +# CHECKEXE-NEXT: Version: 1 +# CHECKEXE-NEXT: Entry: 0x11000 +# CHECKEXE-NEXT: ProgramHeaderOffset: 0x40 +# CHECKEXE-NEXT: SectionHeaderOffset: 0x11E8 +# CHECKEXE-NEXT: Flags [ +# CHECKEXE-NEXT: ] +# CHECKEXE-NEXT: HeaderSize: 64 +# CHECKEXE-NEXT: ProgramHeaderEntrySize: 56 +# CHECKEXE-NEXT: ProgramHeaderCount: 5 +# CHECKEXE-NEXT: SectionHeaderEntrySize: 64 +# CHECKEXE-NEXT: SectionHeaderCount: 6 +# CHECKEXE-NEXT: StringTableSectionIndex: 4 +# CHECKEXE-NEXT: } + +.text +.type x,@object +.bss +.globl x +.align 4 +x: +.long 0 +.size x, 4 +.type y,@object +.globl y +.align 4 +y: +.long 0 +.size y, 4 + +.text +.globl main +.align 16, 0x90 +.type main,@function +main: +movl $5, x +movl $7, y + +blah: +goo: +abs = 42 diff --git a/test/ELF/relocation-copy-alias.s b/test/ELF/relocation-copy-alias.s new file mode 100644 index 000000000000..15712e39bc93 --- /dev/null +++ b/test/ELF/relocation-copy-alias.s @@ -0,0 +1,67 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-alias.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t.so +// RUN: ld.lld %t.o %t.so -o %t3 +// RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t3 | FileCheck %s + +.global _start +_start: +movl $5, a1 +movl $5, b1 +movl $5, b2 + +// CHECK: .rela.dyn { +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: +// CHECK-NEXT: Type: R_X86_64_COPY +// CHECK-NEXT: Symbol: a1 +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Relocation { +// CHECK-NEXT: Offset: +// CHECK-NEXT: Type: R_X86_64_COPY +// CHECK-NEXT: Symbol: b1 +// CHECK-NEXT: Addend: 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: Name: a1 +// CHECK-NEXT: Value: [[A:.*]] +// CHECK-NEXT: Size: 1 +// CHECK-NEXT: Binding: Global (0x1) +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .bss (0x7) + +// CHECK: Name: b1 +// CHECK-NEXT: Value: [[B:.*]] +// CHECK-NEXT: Size: 1 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .bss + +// CHECK: Name: b2 +// CHECK-NEXT: Value: [[B]] +// CHECK-NEXT: Size: 1 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .bss + +// CHECK: Name: a2 +// CHECK-NEXT: Value: [[A]] +// CHECK-NEXT: Size: 1 +// CHECK-NEXT: Binding: Weak +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .bss + +// CHECK: Name: b3 +// CHECK-NEXT: Value: [[B]] +// CHECK-NEXT: Size: 1 +// CHECK-NEXT: Binding: Weak +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .bss diff --git a/test/ELF/relocation-copy-flags.s b/test/ELF/relocation-copy-flags.s new file mode 100644 index 000000000000..50b4b15267e6 --- /dev/null +++ b/test/ELF/relocation-copy-flags.s @@ -0,0 +1,73 @@ +// REQUIRES: x86 + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t.exe +// RUN: llvm-readobj -s -section-data -r %t.exe | FileCheck %s + + .global _start +_start: + .quad x + + .section foo + .quad y + + .section bar, "aw" + .quad z + +// CHECK: Name: .text +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x11000 +// CHECK-NEXT: Offset: 0x1000 +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 4 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 10300100 +// CHECK-NEXT: ) + +// CHECK: Name: bar +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x13000 +// CHECK-NEXT: Offset: 0x3000 +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00000000 +// CHECK-NEXT: ) + +// CHECK: Name: foo +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x0 +// CHECK-NEXT: Offset: 0x3008 +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00000000 +// CHECK-NEXT: ) + +// CHECK: Relocations [ +// CHECK-NEXT: Section (4) .rela.dyn { +// CHECK-NEXT: 0x13010 R_X86_64_COPY x 0x0 +// CHECK-NEXT: 0x13000 R_X86_64_64 z 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/relocation-copy-i686.s b/test/ELF/relocation-copy-i686.s index d61f84783cb6..f9ee32e2b35e 100644 --- a/test/ELF/relocation-copy-i686.s +++ b/test/ELF/relocation-copy-i686.s @@ -22,7 +22,7 @@ movl $9, z // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x13000 -// CHECK-NEXT: Offset: 0x3000 +// CHECK-NEXT: Offset: // CHECK-NEXT: Size: 24 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 diff --git a/test/ELF/relocation-copy.s b/test/ELF/relocation-copy.s index 2e958ad5e955..9d13241f5496 100644 --- a/test/ELF/relocation-copy.s +++ b/test/ELF/relocation-copy.s @@ -23,7 +23,7 @@ movl $z, %edx // CHECK-NEXT: SHF_WRITE (0x1) // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x13000 -// CHECK-NEXT: Offset: 0x3000 +// CHECK-NEXT: Offset: // CHECK-NEXT: Size: 24 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 diff --git a/test/ELF/relocation-i686.s b/test/ELF/relocation-i686.s index 529a35765f9e..96d760601127 100644 --- a/test/ELF/relocation-i686.s +++ b/test/ELF/relocation-i686.s @@ -45,8 +45,8 @@ movl bar@GOT, %eax // ADDR-NEXT: SHF_ALLOC // ADDR-NEXT: SHF_EXECINSTR // ADDR-NEXT: ] -// ADDR-NEXT: Address: 0x11030 -// ADDR-NEXT: Offset: 0x1030 +// ADDR-NEXT: Address: 0x11040 +// ADDR-NEXT: Offset: 0x1040 // ADDR-NEXT: Size: 32 // ADDR: Name: .got @@ -69,16 +69,26 @@ R_386_GOTPC: .section .dynamic_reloc, "ax",@progbits call bar -// 0x11030 - (0x11019 + 5) = 18 +// addr(.plt) + 16 - (0x11019 + 5) = 50 // CHECK: Disassembly of section .dynamic_reloc: // CHECK-NEXT: .dynamic_reloc: -// CHECK-NEXT: 11019: e8 22 00 00 00 calll 34 +// CHECK-NEXT: 11019: e8 32 00 00 00 calll 50 .section .R_386_GOT32,"ax",@progbits .global R_386_GOT32 R_386_GOT32: - movl zed@GOT, %eax -// This is the second symbol in the got, so the offset is 4. + movl bar@GOT, %eax + movl zed@GOT, %eax + movl bar+8@GOT, %eax + movl zed+4@GOT, %eax + +// 4294967288 = 0xFFFFFFF8 = got[0](0x12070) - .got(0x12070) - sizeof(.got)(8) +// 4294967292 = 0xFFFFFFFC = got[1](0x12074) - .got(0x12070) - sizeof(.got)(8) +// 0xFFFFFFF8 + 8 = 0 +// 0xFFFFFFFC + 4 = 0 // CHECK: Disassembly of section .R_386_GOT32: // CHECK-NEXT: R_386_GOT32: -// CHECK-NEXT: 1101e: {{.*}} movl 4, %eax +// CHECK-NEXT: 1101e: a1 f8 ff ff ff movl 4294967288, %eax +// CHECK-NEXT: 11023: a1 fc ff ff ff movl 4294967292, %eax +// CHECK-NEXT: 11028: a1 00 00 00 00 movl 0, %eax +// CHECK-NEXT: 1102d: a1 00 00 00 00 movl 0, %eax diff --git a/test/ELF/relocation-in-merge.s b/test/ELF/relocation-in-merge.s index 820208a2cafe..9ce2e4f79150 100644 --- a/test/ELF/relocation-in-merge.s +++ b/test/ELF/relocation-in-merge.s @@ -1,7 +1,7 @@ // REQUIRES: x86 // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux // RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s -// CHECK: Relocations pointing to SHF_MERGE are not supported +// CHECK: relocations pointing to SHF_MERGE are not supported .section .foo,"aM",@progbits,4 .long bar diff --git a/test/ELF/relocation-non-alloc.s b/test/ELF/relocation-non-alloc.s new file mode 100644 index 000000000000..43f6f5ff1e4b --- /dev/null +++ b/test/ELF/relocation-non-alloc.s @@ -0,0 +1,60 @@ +// REQUIRES: x86 + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +// RUN: ld.lld %t -o %t2 -shared +// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck %s + +// CHECK: Name: .data +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2000 +// CHECK-NEXT: Offset: 0x2000 +// CHECK-NEXT: Size: 16 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 +// CHECK-NEXT: ) + +// CHECK: Name: foo +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x0 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 32 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00200000 00000000 00200000 00000000 +// CHECK-NEXT: 0010: 00200000 00000000 00200000 00000000 +// CHECK-NEXT: ) + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.}}) .rela.dyn { +// CHECK-NEXT: 0x2000 R_X86_64_RELATIVE - 0x2000 +// CHECK-NEXT: 0x2008 R_X86_64_64 zed 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] + +.data + .global zed +zed: +bar: + .quad bar + .quad zed + + .section foo + .quad bar + .quad zed + + .section foo + .quad bar + .quad zed diff --git a/test/ELF/relocation-past-merge-end.s b/test/ELF/relocation-past-merge-end.s index 4dadea1e7acd..993b071f62d2 100644 --- a/test/ELF/relocation-past-merge-end.s +++ b/test/ELF/relocation-past-merge-end.s @@ -1,7 +1,8 @@ // REQUIRES: x86 // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux // RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s -// CHECK: Entry is past the end of the section +// CHECK: entry is past the end of the section + .data .long .foo + 1 .section .foo,"aM",@progbits,4 diff --git a/test/ELF/relocation-relative-absolute.s b/test/ELF/relocation-relative-absolute.s new file mode 100644 index 000000000000..5253191331cc --- /dev/null +++ b/test/ELF/relocation-relative-absolute.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s + +.globl _start +_start: + +# CHECK: relocation R_X86_64_PLT32 cannot refer to absolute symbol answer +call answer@PLT + +.globl answer +answer = 42 diff --git a/test/ELF/relocation-relative-synthetic.s b/test/ELF/relocation-relative-synthetic.s new file mode 100644 index 000000000000..f4d449b844e4 --- /dev/null +++ b/test/ELF/relocation-relative-synthetic.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t -pie +# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s + +# CHECK: Dynamic Relocations { +# CHECK-NEXT: } + +.globl _start +_start: +call __init_array_start@PLT diff --git a/test/ELF/relocation-relative-weak.s b/test/ELF/relocation-relative-weak.s new file mode 100644 index 000000000000..c525012acf67 --- /dev/null +++ b/test/ELF/relocation-relative-weak.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t -pie +# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s + +# CHECK: Dynamic Relocations { +# CHECK-NEXT: } + +.globl _start +_start: + +.globl w +.weak w +call w@PLT diff --git a/test/ELF/relocation-shared.s b/test/ELF/relocation-shared.s new file mode 100644 index 000000000000..e1850944c459 --- /dev/null +++ b/test/ELF/relocation-shared.s @@ -0,0 +1,35 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -shared -o %t.so +// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s + +// CHECK: Name: foo +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x1C8 +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 380E0000 00000000 +// 0x1000 - 0x1C8 = 0xE38 +// CHECK-NEXT: ) + +// CHECK: Name: .text +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x1000 + +// CHECK: Relocations [ +// CHECK-NEXT: ] + +bar: + .section foo,"a",@progbits + .quad bar - . diff --git a/test/ELF/relocation-size-shared.s b/test/ELF/relocation-size-shared.s index 1b52e77b7d5f..d6274e9ae12e 100644 --- a/test/ELF/relocation-size-shared.s +++ b/test/ELF/relocation-size-shared.s @@ -7,48 +7,48 @@ // RELOCSHARED: Relocations [ // RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn { -// RELOCSHARED-NEXT: 0x11018 R_X86_64_SIZE64 fooshared 0xFFFFFFFFFFFFFFFF -// RELOCSHARED-NEXT: 0x11020 R_X86_64_SIZE64 fooshared 0x0 -// RELOCSHARED-NEXT: 0x11028 R_X86_64_SIZE64 fooshared 0x1 -// RELOCSHARED-NEXT: 0x11048 R_X86_64_SIZE32 fooshared 0xFFFFFFFFFFFFFFFF -// RELOCSHARED-NEXT: 0x1104F R_X86_64_SIZE32 fooshared 0x0 -// RELOCSHARED-NEXT: 0x11056 R_X86_64_SIZE32 fooshared 0x1 +// RELOCSHARED-NEXT: 0x13018 R_X86_64_SIZE64 fooshared 0xFFFFFFFFFFFFFFFF +// RELOCSHARED-NEXT: 0x13020 R_X86_64_SIZE64 fooshared 0x0 +// RELOCSHARED-NEXT: 0x13028 R_X86_64_SIZE64 fooshared 0x1 +// RELOCSHARED-NEXT: 0x13048 R_X86_64_SIZE32 fooshared 0xFFFFFFFFFFFFFFFF +// RELOCSHARED-NEXT: 0x1304F R_X86_64_SIZE32 fooshared 0x0 +// RELOCSHARED-NEXT: 0x13056 R_X86_64_SIZE32 fooshared 0x1 // RELOCSHARED-NEXT: } // RELOCSHARED-NEXT:] -// DISASM: Disassembly of section .text: +// DISASM: Disassembly of section test // DISASM: _data: -// DISASM-NEXT: 11000: 19 00 -// DISASM-NEXT: 11002: 00 00 -// DISASM-NEXT: 11004: 00 00 -// DISASM-NEXT: 11006: 00 00 -// DISASM-NEXT: 11008: 1a 00 -// DISASM-NEXT: 1100a: 00 00 -// DISASM-NEXT: 1100c: 00 00 -// DISASM-NEXT: 1100e: 00 00 -// DISASM-NEXT: 11010: 1b 00 -// DISASM-NEXT: 11012: 00 00 -// DISASM-NEXT: 11014: 00 00 -// DISASM-NEXT: 11016: 00 00 -// DISASM-NEXT: 11018: 00 00 -// DISASM-NEXT: 1101a: 00 00 -// DISASM-NEXT: 1101c: 00 00 -// DISASM-NEXT: 1101e: 00 00 -// DISASM-NEXT: 11020: 00 00 -// DISASM-NEXT: 11022: 00 00 -// DISASM-NEXT: 11024: 00 00 -// DISASM-NEXT: 11026: 00 00 -// DISASM-NEXT: 11028: 00 00 -// DISASM-NEXT: 1102a: 00 00 -// DISASM-NEXT: 1102c: 00 00 -// DISASM-NEXT: 1102e: 00 00 +// DISASM-NEXT: 13000: 19 00 +// DISASM-NEXT: 13002: 00 00 +// DISASM-NEXT: 13004: 00 00 +// DISASM-NEXT: 13006: 00 00 +// DISASM-NEXT: 13008: 1a 00 +// DISASM-NEXT: 1300a: 00 00 +// DISASM-NEXT: 1300c: 00 00 +// DISASM-NEXT: 1300e: 00 00 +// DISASM-NEXT: 13010: 1b 00 +// DISASM-NEXT: 13012: 00 00 +// DISASM-NEXT: 13014: 00 00 +// DISASM-NEXT: 13016: 00 00 +// DISASM-NEXT: 13018: 00 00 +// DISASM-NEXT: 1301a: 00 00 +// DISASM-NEXT: 1301c: 00 00 +// DISASM-NEXT: 1301e: 00 00 +// DISASM-NEXT: 13020: 00 00 +// DISASM-NEXT: 13022: 00 00 +// DISASM-NEXT: 13024: 00 00 +// DISASM-NEXT: 13026: 00 00 +// DISASM-NEXT: 13028: 00 00 +// DISASM-NEXT: 1302a: 00 00 +// DISASM-NEXT: 1302c: 00 00 +// DISASM-NEXT: 1302e: 00 00 // DISASM: _start: -// DISASM-NEXT: 11030: 8b 04 25 19 00 00 00 movl 25, %eax -// DISASM-NEXT: 11037: 8b 04 25 1a 00 00 00 movl 26, %eax -// DISASM-NEXT: 1103e: 8b 04 25 1b 00 00 00 movl 27, %eax -// DISASM-NEXT: 11045: 8b 04 25 00 00 00 00 movl 0, %eax -// DISASM-NEXT: 1104c: 8b 04 25 00 00 00 00 movl 0, %eax -// DISASM-NEXT: 11053: 8b 04 25 00 00 00 00 movl 0, %eax +// DISASM-NEXT: 13030: 8b 04 25 19 00 00 00 movl 25, %eax +// DISASM-NEXT: 13037: 8b 04 25 1a 00 00 00 movl 26, %eax +// DISASM-NEXT: 1303e: 8b 04 25 1b 00 00 00 movl 27, %eax +// DISASM-NEXT: 13045: 8b 04 25 00 00 00 00 movl 0, %eax +// DISASM-NEXT: 1304c: 8b 04 25 00 00 00 00 movl 0, %eax +// DISASM-NEXT: 13053: 8b 04 25 00 00 00 00 movl 0, %eax .data .global foo @@ -57,7 +57,7 @@ foo: .zero 26 -.text +.section test, "awx" _data: // R_X86_64_SIZE64: .quad foo@SIZE-1 diff --git a/test/ELF/relocation-size.s b/test/ELF/relocation-size.s index aea3dafea071..58604dbcb4e4 100644 --- a/test/ELF/relocation-size.s +++ b/test/ELF/relocation-size.s @@ -9,84 +9,84 @@ // NORELOC: Relocations [ // NORELOC-NEXT: ] -// DISASM: Disassembly of section .text: +// DISASM: Disassembly of section test: // DISASM-NEXT: _data: -// DISASM-NEXT: 11000: 19 00 -// DISASM-NEXT: 11002: 00 00 -// DISASM-NEXT: 11004: 00 00 -// DISASM-NEXT: 11006: 00 00 -// DISASM-NEXT: 11008: 1a 00 -// DISASM-NEXT: 1100a: 00 00 -// DISASM-NEXT: 1100c: 00 00 -// DISASM-NEXT: 1100e: 00 00 -// DISASM-NEXT: 11010: 1b 00 -// DISASM-NEXT: 11012: 00 00 -// DISASM-NEXT: 11014: 00 00 -// DISASM-NEXT: 11016: 00 00 -// DISASM-NEXT: 11018: 19 00 -// DISASM-NEXT: 1101a: 00 00 -// DISASM-NEXT: 1101c: 00 00 -// DISASM-NEXT: 1101e: 00 00 -// DISASM-NEXT: 11020: 1a 00 -// DISASM-NEXT: 11022: 00 00 -// DISASM-NEXT: 11024: 00 00 -// DISASM-NEXT: 11026: 00 00 -// DISASM-NEXT: 11028: 1b 00 -// DISASM-NEXT: 1102a: 00 00 -// DISASM-NEXT: 1102c: 00 00 -// DISASM-NEXT: 1102e: 00 00 +// DISASM-NEXT: 12000: 19 00 +// DISASM-NEXT: 12002: 00 00 +// DISASM-NEXT: 12004: 00 00 +// DISASM-NEXT: 12006: 00 00 +// DISASM-NEXT: 12008: 1a 00 +// DISASM-NEXT: 1200a: 00 00 +// DISASM-NEXT: 1200c: 00 00 +// DISASM-NEXT: 1200e: 00 00 +// DISASM-NEXT: 12010: 1b 00 +// DISASM-NEXT: 12012: 00 00 +// DISASM-NEXT: 12014: 00 00 +// DISASM-NEXT: 12016: 00 00 +// DISASM-NEXT: 12018: 19 00 +// DISASM-NEXT: 1201a: 00 00 +// DISASM-NEXT: 1201c: 00 00 +// DISASM-NEXT: 1201e: 00 00 +// DISASM-NEXT: 12020: 1a 00 +// DISASM-NEXT: 12022: 00 00 +// DISASM-NEXT: 12024: 00 00 +// DISASM-NEXT: 12026: 00 00 +// DISASM-NEXT: 12028: 1b 00 +// DISASM-NEXT: 1202a: 00 00 +// DISASM-NEXT: 1202c: 00 00 +// DISASM-NEXT: 1202e: 00 00 // DISASM: _start: -// DISASM-NEXT: 11030: 8b 04 25 19 00 00 00 movl 25, %eax -// DISASM-NEXT: 11037: 8b 04 25 1a 00 00 00 movl 26, %eax -// DISASM-NEXT: 1103e: 8b 04 25 1b 00 00 00 movl 27, %eax -// DISASM-NEXT: 11045: 8b 04 25 19 00 00 00 movl 25, %eax -// DISASM-NEXT: 1104c: 8b 04 25 1a 00 00 00 movl 26, %eax -// DISASM-NEXT: 11053: 8b 04 25 1b 00 00 00 movl 27, %eax +// DISASM-NEXT: 12030: 8b 04 25 19 00 00 00 movl 25, %eax +// DISASM-NEXT: 12037: 8b 04 25 1a 00 00 00 movl 26, %eax +// DISASM-NEXT: 1203e: 8b 04 25 1b 00 00 00 movl 27, %eax +// DISASM-NEXT: 12045: 8b 04 25 19 00 00 00 movl 25, %eax +// DISASM-NEXT: 1204c: 8b 04 25 1a 00 00 00 movl 26, %eax +// DISASM-NEXT: 12053: 8b 04 25 1b 00 00 00 movl 27, %eax // RELOCSHARED: Relocations [ // RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn { -// RELOCSHARED-NEXT: 0x1000 R_X86_64_SIZE64 foo 0xFFFFFFFFFFFFFFFF -// RELOCSHARED-NEXT: 0x1008 R_X86_64_SIZE64 foo 0x0 -// RELOCSHARED-NEXT: 0x1010 R_X86_64_SIZE64 foo 0x1 -// RELOCSHARED-NEXT: 0x1033 R_X86_64_SIZE32 foo 0xFFFFFFFFFFFFFFFF -// RELOCSHARED-NEXT: 0x103A R_X86_64_SIZE32 foo 0x0 -// RELOCSHARED-NEXT: 0x1041 R_X86_64_SIZE32 foo 0x1 +// RELOCSHARED-NEXT: 0x3000 R_X86_64_SIZE64 foo 0xFFFFFFFFFFFFFFFF +// RELOCSHARED-NEXT: 0x3008 R_X86_64_SIZE64 foo 0x0 +// RELOCSHARED-NEXT: 0x3010 R_X86_64_SIZE64 foo 0x1 +// RELOCSHARED-NEXT: 0x3033 R_X86_64_SIZE32 foo 0xFFFFFFFFFFFFFFFF +// RELOCSHARED-NEXT: 0x303A R_X86_64_SIZE32 foo 0x0 +// RELOCSHARED-NEXT: 0x3041 R_X86_64_SIZE32 foo 0x1 // RELOCSHARED-NEXT: } // RELOCSHARED-NEXT: ] -// DISASMSHARED: Disassembly of section .text: +// DISASMSHARED: Disassembly of section test: // DISASMSHARED-NEXT: _data: -// DISASMSHARED-NEXT: 1000: 00 00 -// DISASMSHARED-NEXT: 1002: 00 00 -// DISASMSHARED-NEXT: 1004: 00 00 -// DISASMSHARED-NEXT: 1006: 00 00 -// DISASMSHARED-NEXT: 1008: 00 00 -// DISASMSHARED-NEXT: 100a: 00 00 -// DISASMSHARED-NEXT: 100c: 00 00 -// DISASMSHARED-NEXT: 100e: 00 00 -// DISASMSHARED-NEXT: 1010: 00 00 -// DISASMSHARED-NEXT: 1012: 00 00 -// DISASMSHARED-NEXT: 1014: 00 00 -// DISASMSHARED-NEXT: 1016: 00 00 -// DISASMSHARED-NEXT: 1018: 19 00 -// DISASMSHARED-NEXT: 101a: 00 00 -// DISASMSHARED-NEXT: 101c: 00 00 -// DISASMSHARED-NEXT: 101e: 00 00 -// DISASMSHARED-NEXT: 1020: 1a 00 -// DISASMSHARED-NEXT: 1022: 00 00 -// DISASMSHARED-NEXT: 1024: 00 00 -// DISASMSHARED-NEXT: 1026: 00 00 -// DISASMSHARED-NEXT: 1028: 1b 00 -// DISASMSHARED-NEXT: 102a: 00 00 -// DISASMSHARED-NEXT: 102c: 00 00 -// DISASMSHARED-NEXT: 102e: 00 00 +// DISASMSHARED-NEXT: 3000: 00 00 +// DISASMSHARED-NEXT: 3002: 00 00 +// DISASMSHARED-NEXT: 3004: 00 00 +// DISASMSHARED-NEXT: 3006: 00 00 +// DISASMSHARED-NEXT: 3008: 00 00 +// DISASMSHARED-NEXT: 300a: 00 00 +// DISASMSHARED-NEXT: 300c: 00 00 +// DISASMSHARED-NEXT: 300e: 00 00 +// DISASMSHARED-NEXT: 3010: 00 00 +// DISASMSHARED-NEXT: 3012: 00 00 +// DISASMSHARED-NEXT: 3014: 00 00 +// DISASMSHARED-NEXT: 3016: 00 00 +// DISASMSHARED-NEXT: 3018: 19 00 +// DISASMSHARED-NEXT: 301a: 00 00 +// DISASMSHARED-NEXT: 301c: 00 00 +// DISASMSHARED-NEXT: 301e: 00 00 +// DISASMSHARED-NEXT: 3020: 1a 00 +// DISASMSHARED-NEXT: 3022: 00 00 +// DISASMSHARED-NEXT: 3024: 00 00 +// DISASMSHARED-NEXT: 3026: 00 00 +// DISASMSHARED-NEXT: 3028: 1b 00 +// DISASMSHARED-NEXT: 302a: 00 00 +// DISASMSHARED-NEXT: 302c: 00 00 +// DISASMSHARED-NEXT: 302e: 00 00 // DISASMSHARED: _start: -// DISASMSHARED-NEXT: 1030: 8b 04 25 00 00 00 00 movl 0, %eax -// DISASMSHARED-NEXT: 1037: 8b 04 25 00 00 00 00 movl 0, %eax -// DISASMSHARED-NEXT: 103e: 8b 04 25 00 00 00 00 movl 0, %eax -// DISASMSHARED-NEXT: 1045: 8b 04 25 19 00 00 00 movl 25, %eax -// DISASMSHARED-NEXT: 104c: 8b 04 25 1a 00 00 00 movl 26, %eax -// DISASMSHARED-NEXT: 1053: 8b 04 25 1b 00 00 00 movl 27, %eax +// DISASMSHARED-NEXT: 3030: 8b 04 25 00 00 00 00 movl 0, %eax +// DISASMSHARED-NEXT: 3037: 8b 04 25 00 00 00 00 movl 0, %eax +// DISASMSHARED-NEXT: 303e: 8b 04 25 00 00 00 00 movl 0, %eax +// DISASMSHARED-NEXT: 3045: 8b 04 25 19 00 00 00 movl 25, %eax +// DISASMSHARED-NEXT: 304c: 8b 04 25 1a 00 00 00 movl 26, %eax +// DISASMSHARED-NEXT: 3053: 8b 04 25 1b 00 00 00 movl 27, %eax .data .global foo @@ -103,7 +103,7 @@ foo: foohidden: .zero 26 -.text +.section test,"axw" _data: // R_X86_64_SIZE64: .quad foo@SIZE-1 diff --git a/test/ELF/relocation.s b/test/ELF/relocation.s index 33b0e23ee972..11832683d9be 100644 --- a/test/ELF/relocation.s +++ b/test/ELF/relocation.s @@ -14,7 +14,7 @@ // SEC-NEXT: ] // SEC-NEXT: Address: 0x11030 // SEC-NEXT: Offset: 0x1030 -// SEC-NEXT: Size: 32 +// SEC-NEXT: Size: 48 // SEC: Name: .got // SEC-NEXT: Type: SHT_PROGBITS @@ -39,7 +39,7 @@ // SEC-NEXT: ] // SEC-NEXT: Address: 0x13000 // SEC-NEXT: Offset: 0x3000 -// SEC-NEXT: Size: 32 +// SEC-NEXT: Size: 40 // SEC-NEXT: Link: 0 // SEC-NEXT: Info: 0 // SEC-NEXT: AddressAlignment: 8 @@ -98,6 +98,15 @@ R_X86_64_PC32: // CHECK-NEXT: 11017: {{.*}} callq 36 // CHECK-NEXT: 1101c: {{.*}} movl $69696, %eax +.section .R_X86_64_32S_2,"ax",@progbits +.global R_X86_64_32S_2 +R_X86_64_32S_2: + mov bar2, %eax +// plt is at 0x11030. The second plt entry is at 0x11050 == 69712 +// CHECK: Disassembly of section .R_X86_64_32S_2: +// CHECK-NEXT: R_X86_64_32S_2: +// CHECK-NEXT: 11021: {{.*}} movl 69712, %eax + .section .R_X86_64_64,"a",@progbits .global R_X86_64_64 R_X86_64_64: @@ -115,3 +124,11 @@ R_X86_64_GOTPCREL: // 7952 = 0x101f0000 in little endian // CHECK: Contents of section .R_X86_64_GOTPCREL // CHECK-NEXT: 101d0 201f0000 + +.section .R_X86_64_GOT32,"a",@progbits +.global R_X86_64_GOT32 +R_X86_64_GOT32: + .long zed@got + +// CHECK: Contents of section .R_X86_64_GOT32: +// CHECK-NEXT: f8ffffff diff --git a/test/ELF/relro-tls.s b/test/ELF/relro-tls.s new file mode 100644 index 000000000000..0ee5b6d328c2 --- /dev/null +++ b/test/ELF/relro-tls.s @@ -0,0 +1,23 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: ld.lld %t -o %tout +// RUN: llvm-readobj -program-headers %tout | FileCheck %s + +// CHECK: Type: PT_GNU_RELRO +// CHECK-NEXT: Offset: +// CHECK-NEXT: VirtualAddress: +// CHECK-NEXT: PhysicalAddress: +// CHECK-NEXT: FileSize: 4 +// CHECK-NEXT: MemSize: 4 +// CHECK-NEXT: Flags [ +// CHECK-NEXT: PF_R +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 1 + +.global _start +_start: + +.global d +.section .foo,"awT",@progbits +d: +.long 2 diff --git a/test/ELF/relro.s b/test/ELF/relro.s index 692d6b271cf8..d35548740001 100644 --- a/test/ELF/relro.s +++ b/test/ELF/relro.s @@ -232,7 +232,7 @@ .global _start _start: .long bar - jmp *bar@GOTPCREL(%rip) + jmp *bar2@GOTPCREL(%rip) .section .data,"aw" .quad 0 diff --git a/test/ELF/reproduce-error.s b/test/ELF/reproduce-error.s new file mode 100644 index 000000000000..c66132c4bd01 --- /dev/null +++ b/test/ELF/reproduce-error.s @@ -0,0 +1,15 @@ +# Extracting the cpio archive can get over the path limit on windows. +# REQUIRES: shell + +# RUN: rm -rf %t.dir +# RUN: mkdir -p %t.dir +# RUN: cd %t.dir + +# RUN: not ld.lld --reproduce repro abc -o t 2>&1 | FileCheck %s +# CHECK: cannot open abc: {{N|n}}o such file or directory + +# RUN: grep TRAILER repro.cpio +# RUN: cpio -id < repro.cpio +# RUN: FileCheck --check-prefix=RSP %s < repro/response.txt +# RSP: abc +# RSP: -o t diff --git a/test/ELF/reproduce-linkerscript.s b/test/ELF/reproduce-linkerscript.s new file mode 100644 index 000000000000..a020fcc9a4f1 --- /dev/null +++ b/test/ELF/reproduce-linkerscript.s @@ -0,0 +1,17 @@ +# REQUIRES: x86, shell + +# RUN: rm -rf %t.dir +# RUN: mkdir -p %t.dir/build +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build/foo.o +# RUN: echo "INPUT(\"%t.dir/build/foo.o\")" > %t.dir/build/foo.script +# RUN: cd %t.dir +# RUN: ld.lld build/foo.script -o bar --reproduce repro +# RUN: cpio -id < repro.cpio +# RUN: diff build/foo.script repro/%:t.dir/build/foo.script +# RUN: diff build/foo.o repro/%:t.dir/build/foo.o + +.globl _start +_start: + mov $60, %rax + mov $42, %rdi + syscall diff --git a/test/ELF/reproduce-thin-archive.s b/test/ELF/reproduce-thin-archive.s new file mode 100644 index 000000000000..0797b6c67e9c --- /dev/null +++ b/test/ELF/reproduce-thin-archive.s @@ -0,0 +1,15 @@ +# REQUIRES: x86, shell + +# RUN: rm -rf %t.dir +# RUN: mkdir -p %t.dir +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.dir/foo.o +# RUN: cd %t.dir +# RUN: llvm-ar --format=gnu rcT foo.a foo.o +# RUN: ld.lld -m elf_x86_64 foo.a -o bar --reproduce repro +# RUN: cpio -id < repro.cpio +# RUN: diff foo.a repro/%:t.dir/foo.a +# RUN: diff foo.o repro/%:t.dir/foo.o + +.globl _start +_start: + nop diff --git a/test/ELF/reproduce-windows.s b/test/ELF/reproduce-windows.s new file mode 100644 index 000000000000..464b27098694 --- /dev/null +++ b/test/ELF/reproduce-windows.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 + +# Test that a repro archive always uses / instead of \. +# RUN: rm -rf %t.dir +# RUN: mkdir -p %t.dir/build +# RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux +# RUN: cd %t.dir +# RUN: not ld.lld build/foo.o --reproduce repro +# RUN: cpio -t < repro.cpio | FileCheck %s + +# CHECK: repro/response.txt +# CHECK: repro/{{.*}}/build/foo.o diff --git a/test/ELF/reproduce.s b/test/ELF/reproduce.s new file mode 100644 index 000000000000..9d256c12d827 --- /dev/null +++ b/test/ELF/reproduce.s @@ -0,0 +1,67 @@ +# REQUIRES: x86 + +# Extracting the cpio archive can get over the path limit on windows. +# REQUIRES: shell + +# RUN: rm -rf %t.dir +# RUN: mkdir -p %t.dir/build1 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build1/foo.o +# RUN: cd %t.dir +# RUN: ld.lld --hash-style=gnu build1/foo.o -o bar -shared --as-needed --reproduce repro +# RUN: cpio -id < repro.cpio +# RUN: diff build1/foo.o repro/%:t.dir/build1/foo.o + +# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt +# RSP: {{^}}--hash-style gnu{{$}} +# RSP-NOT: repro{{[/\\]}} +# RSP-NEXT: {{[/\\]}}foo.o +# RSP-NEXT: -o bar +# RSP-NEXT: -shared +# RSP-NEXT: --as-needed + +# RUN: FileCheck %s --check-prefix=VERSION < repro/version.txt +# VERSION: LLD + +# RUN: mkdir -p %t.dir/build2/a/b/c +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build2/foo.o +# RUN: cd %t.dir/build2/a/b/c +# RUN: env LLD_REPRODUCE=repro ld.lld ./../../../foo.o -o bar -shared --as-needed +# RUN: cpio -id < repro.cpio +# RUN: diff %t.dir/build2/foo.o repro/%:t.dir/build2/foo.o + +# RUN: echo "{ local: *; };" > ver +# RUN: echo > dyn +# RUN: echo > file +# RUN: echo > file2 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o 'foo bar' +# RUN: ld.lld --reproduce repro2 'foo bar' -L"foo bar" -Lfile -Tfile2 \ +# RUN: --dynamic-list dyn -rpath file --script file --version-script ver \ +# RUN: --dynamic-linker "some unusual/path" -soname 'foo bar' -soname='foo bar' +# RUN: cpio -id < repro2.cpio +# RUN: FileCheck %s --check-prefix=RSP2 < repro2/response.txt +# RSP2: "{{.*}}foo bar" +# RSP2-NEXT: -L "{{.*}}foo bar" +# RSP2-NEXT: -L {{.+}}file +# RSP2-NEXT: --script {{.+}}file2 +# RSP2-NEXT: --dynamic-list {{.+}}dyn +# RSP2-NEXT: -rpath {{.+}}file +# RSP2-NEXT: --script {{.+}}file +# RSP2-NEXT: --version-script [[PATH:.*]]ver +# RSP2-NEXT: --dynamic-linker "some unusual/path" +# RSP2-NEXT: -soname="foo bar" +# RSP2-NEXT: -soname="foo bar" + +# RUN: cpio -t < repro2.cpio | FileCheck %s +# CHECK: repro2/response.txt +# CHECK-NEXT: repro2/version.txt +# CHECK-NEXT: repro2/{{.*}}/dyn +# CHECK-NEXT: repro2/{{.*}}/ver +# CHECK-NEXT: repro2/{{.*}}/foo bar +# CHECK-NEXT: repro2/{{.*}}/file2 +# CHECK-NEXT: repro2/{{.*}}/file + +.globl _start +_start: + mov $60, %rax + mov $42, %rdi + syscall diff --git a/test/ELF/resolution-shared.s b/test/ELF/resolution-shared.s new file mode 100644 index 000000000000..e1eac070e5af --- /dev/null +++ b/test/ELF/resolution-shared.s @@ -0,0 +1,15 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-shared.s -o %t2.o +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t3 -shared +// RUN: llvm-readobj -t %t3 | FileCheck %s +// REQUIRES: x86 + + .weak foo +foo: + +// CHECK: Symbol { +// CHECK: Name: foo +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Weak diff --git a/test/ELF/resolution.s b/test/ELF/resolution.s index ce275c2934a4..5596212b3bac 100644 --- a/test/ELF/resolution.s +++ b/test/ELF/resolution.s @@ -309,7 +309,7 @@ // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: UndefWeak_with_UndefWeak // CHECK-NEXT: Value: 0x0 -// CHECK-NEXT: Size: 15 +// CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Weak // CHECK-NEXT: Type: None // CHECK-NEXT: Other: 0 diff --git a/test/ELF/section-align-0.test b/test/ELF/section-align-0.test index fc27ee95fd4b..35783f5a894b 100644 --- a/test/ELF/section-align-0.test +++ b/test/ELF/section-align-0.test @@ -1,8 +1,9 @@ -# RUN: yaml2obj -format elf %s -o %t +# RUN: yaml2obj %s -o %t # RUN: ld.lld %t -o %tout # Verify that lld can handle sections with an alignment of zero. +!ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB diff --git a/test/ELF/section-name.s b/test/ELF/section-name.s index 2d7ed4e63717..f470c48c6a37 100644 --- a/test/ELF/section-name.s +++ b/test/ELF/section-name.s @@ -21,11 +21,17 @@ _start: .section .data.rel.ro.a,"aw",%progbits .section .data.rel.ro.local,"aw",%progbits .section .data.rel.ro.local.a,"aw",%progbits +.section .tbss.foo,"aGwT",@nobits,foo,comdat +.section .gcc_except_table.foo,"aG",@progbits,foo,comdat +.section .tdata.foo,"aGwT",@progbits,foo,comdat // CHECK-NOT: Name: .rodata.a // CHECK: Name: .rodata +// CHECK: Name: .gcc_except_table ({{.*}}) // CHECK-NOT: Name: .text.a // CHECK: Name: .text +// CHECK: Name: .tdata ({{.*}}) +// CHECK: Name: .tbss ({{.*}}) // CHECK-NOT: Name: .data.rel.ro.a // CHECK-NOT: Name: .data.rel.ro.local.a // CHECK: Name: .data.rel.ro diff --git a/test/ELF/section-symbol.s b/test/ELF/section-symbol.s index 5f04606914fb..5cf71aceec72 100644 --- a/test/ELF/section-symbol.s +++ b/test/ELF/section-symbol.s @@ -23,7 +23,18 @@ // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .text // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } // CHECK-NEXT: ] foo: - .quad foo + .quad foo - . diff --git a/test/ELF/shared-be.s b/test/ELF/shared-be.s index 0f57a4b7f0c3..12eb3131050a 100644 --- a/test/ELF/shared-be.s +++ b/test/ELF/shared-be.s @@ -20,17 +20,18 @@ // CHECK: DynamicSection [ // CHECK-NEXT: Tag Type Name/Value +// CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar +// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so) // CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]] // CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes) // CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes) -// CHECK: 0x000000000000001D RUNPATH foo:bar -// CHECK-NEXT: 0x0000000000000001 NEEDED SharedLibrary ({{.*}}2.so) -// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0 +// CHECK: 0x0000000000000015 DEBUG 0x0 // CHECK-NEXT: 0x0000000000000000 NULL 0x0 // CHECK-NEXT: ] .global _start _start: +.data .long bar .long zed diff --git a/test/ELF/shared.s b/test/ELF/shared.s index 1bf5bd1795bc..a81a09370999 100644 --- a/test/ELF/shared.s +++ b/test/ELF/shared.s @@ -144,6 +144,17 @@ // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: 0x12000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: _start // CHECK-NEXT: Value: 0x11000 // CHECK-NEXT: Size: 0 @@ -243,6 +254,8 @@ // CHECK: DynamicSection [ // CHECK-NEXT: Tag Type Name/Value +// CHECK-NEXT: 0x0000001D RUNPATH foo:bar +// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so) // CHECK-NEXT: 0x00000011 REL [[RELADDR]] // CHECK-NEXT: 0x00000012 RELSZ [[RELSIZE]] (bytes) // CHECK-NEXT: 0x00000013 RELENT [[RELENT]] (bytes) @@ -251,8 +264,6 @@ // CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]] // CHECK-NEXT: 0x0000000A STRSZ // CHECK-NEXT: 0x00000004 HASH [[HASHADDR]] -// CHECK-NEXT: 0x0000001D RUNPATH foo:bar -// CHECK-NEXT: 0x00000001 NEEDED SharedLibrary ({{.*}}2.so) // CHECK-NEXT: 0x00000015 DEBUG 0x0 // CHECK-NEXT: 0x00000000 NULL 0x0 // CHECK-NEXT: ] @@ -291,5 +302,5 @@ .global _start _start: -.long bar -.long zed +.long bar@GOT +.long zed@GOT diff --git a/test/ELF/soname.s b/test/ELF/soname.s index 9d6fe7681dac..65e95ce85add 100644 --- a/test/ELF/soname.s +++ b/test/ELF/soname.s @@ -1,6 +1,6 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: ld.lld %t.o -shared -soname=bar -o %t.so -// RUN: ld.lld %t.o -shared -soname=bar -o %t2.so +// RUN: ld.lld %t.o -shared --soname=bar -o %t2.so // RUN: ld.lld %t.o %t.so %t2.so -o %t // RUN: llvm-readobj --dynamic-table %t | FileCheck %s diff --git a/test/ELF/splitstacks.s b/test/ELF/splitstacks.s new file mode 100644 index 000000000000..6506b48a2513 --- /dev/null +++ b/test/ELF/splitstacks.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o + +# RUN: not ld.lld %t1.o -o %t 2>&1 | FileCheck %s +# CHECK: objects using splitstacks are not supported + +.globl _start +_start: + nop + +.section .note.GNU-split-stack,"",@progbits diff --git a/test/ELF/start-lib-comdat.s b/test/ELF/start-lib-comdat.s new file mode 100644 index 000000000000..ce03959fd74b --- /dev/null +++ b/test/ELF/start-lib-comdat.s @@ -0,0 +1,23 @@ +// REQUIRES: x86 + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \ +// RUN: %p/Inputs/start-lib-comdat.s -o %t2.o +// RUN: ld.lld -shared -o %t3 %t1.o --start-lib %t2.o --end-lib +// RUN: llvm-readobj -t %t3 | FileCheck %s +// RUN: ld.lld -shared -o %t3 --start-lib %t2.o --end-lib %t1.o +// RUN: llvm-readobj -t %t3 | FileCheck %s + +// CHECK: Name: zed +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: Undefined + + call bar@plt +// The other file also has a section in the zed comdat, but it defines the +// symbol zed. That means that we will have a lazy symbol zed, but when adding +// the actual file zed will be undefined. + .section .sec,"aG",@progbits,zed,comdat diff --git a/test/ELF/start-lib.s b/test/ELF/start-lib.s new file mode 100644 index 000000000000..013a2b206a1f --- /dev/null +++ b/test/ELF/start-lib.s @@ -0,0 +1,25 @@ +// REQUIRES: x86 + +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +// RUN: %p/Inputs/start-lib1.s -o %t2.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +// RUN: %p/Inputs/start-lib2.s -o %t3.o + +// RUN: ld.lld -o %t3 %t1.o %t2.o %t3.o +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s +// TEST1: Name: bar +// TEST1: Name: foo + +// RUN: ld.lld -o %t3 %t1.o -u bar --start-lib %t2.o %t3.o +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s +// TEST2: Name: bar +// TEST2-NOT: Name: foo + +// RUN: ld.lld -o %t3 %t1.o --start-lib %t2.o %t3.o +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s +// TEST3-NOT: Name: bar +// TEST3-NOT: Name: foo + +.globl _start +_start: diff --git a/test/ELF/startstop-gccollect.s b/test/ELF/startstop-gccollect.s new file mode 100644 index 000000000000..b0cd41337e34 --- /dev/null +++ b/test/ELF/startstop-gccollect.s @@ -0,0 +1,32 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Default run: sections foo and bar exist in output +# RUN: ld.lld %t -o %tout +# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s + +## Check that foo and bar sections are not garbage collected, +## we do not want to reclaim sections if they can be referred +## by __start_* and __stop_* symbols. +# RUN: ld.lld %t --gc-sections -o %tout +# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s + +# DISASM: _start: +# DISASM-NEXT: 11000: 90 nop +# DISASM-NEXT: Disassembly of section foo: +# DISASM-NEXT: foo: +# DISASM-NEXT: 11001: 90 nop +# DISASM-NEXT: Disassembly of section bar: +# DISASM-NEXT: bar: +# DISASM-NEXT: 11002: 90 nop + +.global _start +.text +_start: + nop + +.section foo,"ax" + nop + +.section bar,"ax" + nop diff --git a/test/ELF/startstop-shared.s b/test/ELF/startstop-shared.s index 108184648f97..77411f3f25c9 100644 --- a/test/ELF/startstop-shared.s +++ b/test/ELF/startstop-shared.s @@ -3,16 +3,24 @@ // RUN: ld.lld %t.o -o %t.so -shared // RUN: llvm-readobj -r -t %t.so | FileCheck %s + .data .quad __start_foo - .section foo,"a" -// By default the symbol is visible and we need a dynamic reloc. -// CHECK: R_X86_64_64 __start_foo 0x0 + .section foo,"aw" +// By default the symbol is hidden. +// CHECK: R_X86_64_RELATIVE - 0x[[ADDR1:.*]] .hidden __start_bar .quad __start_bar .section bar,"a" -// Test that we are able to hide the symbol. -// CHECK: R_X86_64_RELATIVE - 0x[[ADDR:.*]] +// References do not affect the visibility. +// CHECK: R_X86_64_RELATIVE - 0x[[ADDR2:.*]] // CHECK: Name: __start_bar -// CHECK-NEXT: Value: 0x[[ADDR]] +// CHECK-NEXT: Value: 0x[[ADDR2]] +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Local + +// CHECK: Name: __start_foo +// CHECK-NEXT: Value: 0x[[ADDR1]] +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: Local diff --git a/test/ELF/startstop.s b/test/ELF/startstop.s index d0e88df4e7eb..a7b2e43e6a5f 100644 --- a/test/ELF/startstop.s +++ b/test/ELF/startstop.s @@ -20,7 +20,13 @@ // DISASM: 1014: 90 nop -// SYMBOL: Relocations [ +// SYMBOL: Relocations [ +// SYMBOL-NEXT: Section ({{.*}}) .rela.dyn { +// SYMBOL-NEXT: 0x3000 R_X86_64_RELATIVE - 0x3020 +// SYMBOL-NEXT: 0x3008 R_X86_64_RELATIVE - 0x3021 +// SYMBOL-NEXT: 0x3010 R_X86_64_RELATIVE - 0x3010 +// SYMBOL-NEXT: 0x3018 R_X86_64_RELATIVE - 0x3011 +// SYMBOL-NEXT: } // SYMBOL-NEXT: ] // SYMBOL: Symbol { @@ -59,3 +65,11 @@ _start: nop nop nop + +.section zed1, "aw" + .quad __stop_zed2 + .quad __stop_zed2 + 1 + +.section zed2, "aw" + .quad __stop_zed1 + .quad __stop_zed1 + 1 diff --git a/test/ELF/string-gc.s b/test/ELF/string-gc.s new file mode 100644 index 000000000000..e7f86a1c6077 --- /dev/null +++ b/test/ELF/string-gc.s @@ -0,0 +1,73 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t --gc-sections +// RUN: llvm-readobj -symbols %t | FileCheck %s + +// CHECK: Symbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: (0) +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local (0x0) +// CHECK-NEXT: Type: None (0x0) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined (0x0) +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: s3 +// CHECK-NEXT: Value: 0x10125 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local (0x0) +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .rodata (0x1) +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: s1 +// CHECK-NEXT: Value: 0x10120 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local (0x0) +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN (0x2) +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .rodata (0x1) +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _start +// CHECK-NEXT: Value: 0x11000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global (0x1) +// CHECK-NEXT: Type: Function (0x2) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text (0x2) +// CHECK-NEXT: } +// CHECK-NEXT: ] + +.text +.globl _start +.type _start,@function +_start: +movl $s1, %eax +movl $s3, %eax + +.hidden s1 +.type s1,@object +.section .rodata.str1.1,"aMS",@progbits,1 +.globl s1 +s1: +.asciz "abcd" + +.hidden s2 +.type s2,@object +.globl s2 +s2: +.asciz "efgh" + +.type s3,@object +s3: +.asciz "ijkl" + +.type s4,@object +.globl s4 +s4: +.asciz "mnop" diff --git a/test/ELF/string-table.s b/test/ELF/string-table.s index 8393d6de6cc5..892c348f6fd0 100644 --- a/test/ELF/string-table.s +++ b/test/ELF/string-table.s @@ -59,9 +59,8 @@ _start: // CHECK-NEXT: EntrySize: 0 // CHECK-NEXT: SectionData ( // CHECK-NEXT: 0000: 00626172 002E7465 78740066 6F6F6261 |.bar..text.fooba| -// CHECK-NEXT: 0010: 7200666F 6F626172 00666F6F 62617200 |r.foobar.foobar.| -// CHECK-NEXT: 0020: 2E73796D 74616200 2E736873 74727461 |.symtab..shstrta| -// CHECK-NEXT: 0030: 62002E73 74727461 6200 |b..strtab.| +// CHECK-NEXT: 0010: 72002E73 796D7461 62002E73 68737472 |r..symtab..shstr| +// CHECK-NEXT: 0020: 74616200 2E737472 74616200 |tab..strtab.| // CHECK-NEXT: ) // CHECK-NEXT:} // CHECK: Name: .strtab diff --git a/test/ELF/strip-all.s b/test/ELF/strip-all.s index 6d18431668ae..f322119b0dbb 100644 --- a/test/ELF/strip-all.s +++ b/test/ELF/strip-all.s @@ -13,12 +13,16 @@ #AFTER: .shstrtab #AFTER-NOT: .strtab +# Ignore --strip-all if -r is specified +#RUN: ld.lld %t.o --strip-all -r -o %t1 +#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix BEFORE + # Test alias -s #RUN: ld.lld %t.o -s -o %t1 #RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix AFTER # exits with return code 42 on linux -.globl _start; +.globl _start _start: mov $60, %rax mov $42, %rdi diff --git a/test/ELF/strip-debug.s b/test/ELF/strip-debug.s new file mode 100644 index 000000000000..81f7572aa7c5 --- /dev/null +++ b/test/ELF/strip-debug.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -g %s -o %t +# RUN: ld.lld %t -o %t2 +# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=DEFAULT %s +# RUN: ld.lld %t -o %t2 --strip-debug +# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s +# RUN: ld.lld %t -o %t2 -S +# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s +# RUN: ld.lld %t -o %t2 --strip-all +# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s + +# DEFAULT: Name: .debug_info +# DEFAULT: Name: .debug_abbrev +# DEFAULT: Name: .debug_aranges +# DEFAULT: Name: .debug_line + +# STRIP-NOT: Name: .debug_info +# STRIP-NOT: Name: .debug_abbrev +# STRIP-NOT: Name: .debug_aranges +# STRIP-NOT: Name: .debug_line + +.globl _start +_start: + ret diff --git a/test/ELF/symbol-override.s b/test/ELF/symbol-override.s new file mode 100644 index 000000000000..487885b75b36 --- /dev/null +++ b/test/ELF/symbol-override.s @@ -0,0 +1,46 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/symbol-override.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t2.so +// RUN: ld.lld %t1.o %t2.so -o %t +// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s + +// CHECK: DynamicSymbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: do +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Function +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: foo +// CHECK-NEXT: Value: 0x11000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Function +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text +// CHECK-NEXT: } +// CHECK-NEXT: ] + +.text +.globl foo +.type foo,@function +foo: +nop + +.text +.globl _start +_start: +callq do@plt diff --git a/test/ELF/symbols.s b/test/ELF/symbols.s index ccf83afdf567..a6c838cf0b74 100644 --- a/test/ELF/symbols.s +++ b/test/ELF/symbols.s @@ -67,7 +67,7 @@ internal: // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x12000 -// CHECK-NEXT: Offset: 0x2000 +// CHECK-NEXT: Offset: // CHECK-NEXT: Size: 4 // CHECK: Symbols [ @@ -86,7 +86,9 @@ internal: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: foobar // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -95,7 +97,9 @@ internal: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 1 +// CHECK-NEXT: Other [ (0x1) +// CHECK-NEXT: STV_INTERNAL +// CHECK-NEXT: ] // CHECK-NEXT: Section: foobar // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -149,7 +153,9 @@ internal: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 3 +// CHECK-NEXT: Other [ (0x3) +// CHECK-NEXT: STV_PROTECTED +// CHECK-NEXT: ] // CHECK-NEXT: Section: foobar // CHECK-NEXT: } // CHECK-NEXT: Symbol { diff --git a/test/ELF/sysroot.s b/test/ELF/sysroot.s index 35154be125a3..38fd8cdde402 100644 --- a/test/ELF/sysroot.s +++ b/test/ELF/sysroot.s @@ -14,7 +14,7 @@ // We need to be sure that there is no suitable library in the /lib directory // RUN: not ld.lld -o %t/r %t/m.o -L/lib -l:libls.a 2>&1 \ // RUN: | FileCheck --check-prefix=NOLIB %s -// NOLIB: Unable to find library -l:libls.a +// NOLIB: unable to find library -l:libls.a // Should just remove the '=' symbol if --sysroot is not specified. // Case 1: relative path @@ -32,5 +32,5 @@ // RUN: not ld.lld -o %t/r %r/m.o --sysroot=%t -Llib -l:libls.a // RUN: not ld.lld -o %t/r %r/m.o --sysroot=%t -L/lib -l:libls.a -.globl _start,_bar; +.globl _start,_bar _start: diff --git a/test/ELF/tail-merge-string-align.s b/test/ELF/tail-merge-string-align.s new file mode 100644 index 000000000000..a5d4603b6f8b --- /dev/null +++ b/test/ELF/tail-merge-string-align.s @@ -0,0 +1,35 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared -O3 +// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s + + .section .rodata.4a,"aMS",@progbits,1 + .align 4 + .asciz "abcdef" + + .section .rodata.4b,"aMS",@progbits,1 + .align 4 + .asciz "ef" + + .section .rodata.4c,"aMS",@progbits,1 + .align 4 + .asciz "f" + + +// CHECK: Name: .rodata +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: SHF_STRINGS +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 1 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 4 +// CHECK-NEXT: EntrySize: +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 61626364 65660000 6600 |abcdef..f.| +// CHECK-NEXT: ) diff --git a/test/ELF/tls-archive.s b/test/ELF/tls-archive.s new file mode 100644 index 000000000000..9a88fddffd36 --- /dev/null +++ b/test/ELF/tls-archive.s @@ -0,0 +1,10 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2 +// RUN: rm -f %t.a +// RUN: llvm-ar cru %t.a %t2 +// RUN: ld.lld %t.a %t -o %t3 + +.globl _start,tlsvar +_start: + movq tlsvar@GOTTPOFF(%rip),%rdx diff --git a/test/ELF/tls-dynamic-i686.s b/test/ELF/tls-dynamic-i686.s index b2620d048864..4db6278ca21b 100644 --- a/test/ELF/tls-dynamic-i686.s +++ b/test/ELF/tls-dynamic-i686.s @@ -19,6 +19,14 @@ tls1: .long 0 .size tls1, 4 +.type tls2,@object +.globl tls2 +.hidden tls2 +.align 4 +tls2: + .long 0 + .size tls2, 4 + .section .text .globl _start _start: @@ -28,13 +36,13 @@ call __tls_get_addr@plt leal tls1@tlsgd(,%ebx,1),%eax call __tls_get_addr@plt -leal tls0@tlsldm(%ebx),%eax +leal tls2@tlsldm(%ebx),%eax call __tls_get_addr@plt -leal tls0@dtpoff(%eax),%edx +leal tls2@dtpoff(%eax),%edx -leal tls1@tlsldm(%ebx),%eax +leal tls2@tlsldm(%ebx),%eax call __tls_get_addr@plt -leal tls1@dtpoff(%eax),%edx +leal tls2@dtpoff(%eax),%edx movl %gs:0,%eax addl tls0@gotntpoff(%ebx),%eax @@ -59,12 +67,12 @@ addl tls1@gotntpoff(%ebx),%eax // CHECK: Relocations [ // CHECK: Section ({{.+}}) .rel.dyn { +// CHECK-NEXT: 0x2078 R_386_TLS_DTPMOD32 - 0x0 // CHECK-NEXT: 0x2068 R_386_TLS_DTPMOD32 tls0 0x0 // CHECK-NEXT: 0x206C R_386_TLS_DTPOFF32 tls0 0x0 +// CHECK-NEXT: 0x2080 R_386_TLS_TPOFF tls0 0x0 // CHECK-NEXT: 0x2070 R_386_TLS_DTPMOD32 tls1 0x0 // CHECK-NEXT: 0x2074 R_386_TLS_DTPOFF32 tls1 0x0 -// CHECK-NEXT: 0x2078 R_386_TLS_DTPMOD32 - 0x0 -// CHECK-NEXT: 0x2080 R_386_TLS_TPOFF tls0 0x0 // CHECK-NEXT: 0x2084 R_386_TLS_TPOFF tls1 0x0 // CHECK-NEXT: } @@ -81,10 +89,10 @@ addl tls1@gotntpoff(%ebx),%eax // -16 is a local module tls index offset. // DIS-NEXT: 1018: 8d 83 f0 ff ff ff leal -16(%ebx), %eax // DIS-NEXT: 101e: e8 4d 00 00 00 calll 77 -// DIS-NEXT: 1023: 8d 90 00 00 00 00 leal (%eax), %edx +// DIS-NEXT: 1023: 8d 90 08 00 00 00 leal 8(%eax), %edx // DIS-NEXT: 1029: 8d 83 f0 ff ff ff leal -16(%ebx), %eax // DIS-NEXT: 102f: e8 3c 00 00 00 calll 60 -// DIS-NEXT: 1034: 8d 90 04 00 00 00 leal 4(%eax), %edx +// DIS-NEXT: 1034: 8d 90 08 00 00 00 leal 8(%eax), %edx // Initial exec model: // DIS-NEXT: 103a: 65 a1 00 00 00 00 movl %gs:0, %eax // DIS-NEXT: 1040: 03 83 f8 ff ff ff addl -8(%ebx), %eax diff --git a/test/ELF/tls-dynamic.s b/test/ELF/tls-dynamic.s index b6ae6da61bb2..b627977e3c6f 100644 --- a/test/ELF/tls-dynamic.s +++ b/test/ELF/tls-dynamic.s @@ -14,10 +14,13 @@ leaq c@tlsgd(%rip), %rdi rex64 callq __tls_get_addr@PLT - leaq c@dtpoff(%rax), %rcx + leaq a@dtpoff(%rax), %rcx // Initial Exec Model Code Sequence, II movq c@gottpoff(%rip),%rax movq %fs:(%rax),%rax + movabs $a@dtpoff, %rax + movabs $b@dtpoff, %rax + movabs $a@dtpoff, %rax .global a .hidden a @@ -76,6 +79,9 @@ c: // DIS-NEXT: 102c: 00 00 // DIS-NEXT: 102e: {{.+}} leaq 4267(%rip), %rdi // DIS-NEXT: 1035: {{.+}} callq -// DIS-NEXT: 103b: {{.+}} leaq 8(%rax), %rcx +// DIS-NEXT: 103b: {{.+}} leaq (%rax), %rcx // DIS-NEXT: 1042: {{.+}} movq 4263(%rip), %rax // DIS-NEXT: 1049: {{.+}} movq %fs:(%rax), %rax +// DIS-NEXT: 104d: {{.+}} movabsq $0, %rax +// DIS-NEXT: 1057: {{.+}} movabsq $4, %rax +// DIS-NEXT: 1061: {{.+}} movabsq $0, %rax diff --git a/test/ELF/tls-got-entry.s b/test/ELF/tls-got-entry.s new file mode 100644 index 000000000000..c7b96697ab30 --- /dev/null +++ b/test/ELF/tls-got-entry.s @@ -0,0 +1,25 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got-entry.s -o %tso.o +// RUN: ld.lld -shared %tso.o -o %t.so +// RUN: ld.lld %t.o %t.so -o %t1 +// RUN: llvm-readobj -r %t1 | FileCheck %s + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: R_X86_64_TPOFF64 tlsshared0 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] + +.globl _start +_start: + .byte 0x66 + leaq tlsshared0@tlsgd(%rip),%rdi + .word 0x6666 + rex64 + call __tls_get_addr@plt + .byte 0x66 + leaq tlsshared0@tlsgd(%rip),%rdi + .word 0x6666 + rex64 + call __tls_get_addr@plt diff --git a/test/ELF/tls-got.s b/test/ELF/tls-got.s index aa024519a64a..f36d94e40cb1 100644 --- a/test/ELF/tls-got.s +++ b/test/ELF/tls-got.s @@ -24,8 +24,8 @@ // CHECK: Relocations [ // CHECK-NEXT: Section (4) .rela.dyn { -// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0 // CHECK-NEXT: 0x120B8 R_X86_64_TPOFF64 tls0 0x0 +// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0 // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/test/ELF/tls-i686.s b/test/ELF/tls-i686.s index 62940d6cd164..e0a1007fde16 100644 --- a/test/ELF/tls-i686.s +++ b/test/ELF/tls-i686.s @@ -15,7 +15,7 @@ var: var1: .long 1 -.text +.section test, "awx" .global _start _start: movl $var@tpoff, %edx @@ -30,40 +30,40 @@ _start: movl %gs:0, %ecx leal var1@ntpoff(%ecx), %eax -// DIS: Disassembly of section .text: +// DIS: Disassembly of section test: // DIS-NEXT: _start: -// DIS-NEXT: 11000: ba 08 00 00 00 movl $8, %edx -// DIS-NEXT: 11005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx -// DIS-NEXT: 1100c: 29 d0 subl %edx, %eax -// DIS-NEXT: 1100e: ba 04 00 00 00 movl $4, %edx -// DIS-NEXT: 11013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx -// DIS-NEXT: 1101a: 29 d0 subl %edx, %eax -// DIS-NEXT: 1101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx -// DIS-NEXT: 11023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax -// DIS-NEXT: 11029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx -// DIS-NEXT: 11030: 8d 81 fc ff ff ff leal -4(%ecx), %eax +// DIS-NEXT: 12000: ba 08 00 00 00 movl $8, %edx +// DIS-NEXT: 12005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx +// DIS-NEXT: 1200c: 29 d0 subl %edx, %eax +// DIS-NEXT: 1200e: ba 04 00 00 00 movl $4, %edx +// DIS-NEXT: 12013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx +// DIS-NEXT: 1201a: 29 d0 subl %edx, %eax +// DIS-NEXT: 1201c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx +// DIS-NEXT: 12023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax +// DIS-NEXT: 12029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx +// DIS-NEXT: 12030: 8d 81 fc ff ff ff leal -4(%ecx), %eax // RELOC: Relocations [ // RELOC-NEXT: ] -// DISSHARED: Disassembly of section .text: +// DISSHARED: Disassembly of section test: // DISSHARED-NEXT: _start: -// DISSHARED-NEXT: 1000: ba 00 00 00 00 movl $0, %edx -// DISSHARED-NEXT: 1005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx -// DISSHARED-NEXT: 100c: 29 d0 subl %edx, %eax -// DISSHARED-NEXT: 100e: ba 00 00 00 00 movl $0, %edx -// DISSHARED-NEXT: 1013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx -// DISSHARED-NEXT: 101a: 29 d0 subl %edx, %eax -// DISSHARED-NEXT: 101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx -// DISSHARED-NEXT: 1023: 8d 81 00 00 00 00 leal (%ecx), %eax -// DISSHARED-NEXT: 1029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx -// DISSHARED-NEXT: 1030: 8d 81 00 00 00 00 leal (%ecx), %eax +// DISSHARED-NEXT: 2000: ba 00 00 00 00 movl $0, %edx +// DISSHARED-NEXT: 2005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx +// DISSHARED-NEXT: 200c: 29 d0 subl %edx, %eax +// DISSHARED-NEXT: 200e: ba 00 00 00 00 movl $0, %edx +// DISSHARED-NEXT: 2013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx +// DISSHARED-NEXT: 201a: 29 d0 subl %edx, %eax +// DISSHARED-NEXT: 201c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx +// DISSHARED-NEXT: 2023: 8d 81 00 00 00 00 leal (%ecx), %eax +// DISSHARED-NEXT: 2029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx +// DISSHARED-NEXT: 2030: 8d 81 00 00 00 00 leal (%ecx), %eax // RELOCSHARED: Relocations [ // RELOCSHARED-NEXT: Section (4) .rel.dyn { -// RELOCSHARED-NEXT: 0x1001 R_386_TLS_TPOFF32 var 0x0 -// RELOCSHARED-NEXT: 0x100F R_386_TLS_TPOFF32 var1 0x0 -// RELOCSHARED-NEXT: 0x1025 R_386_TLS_TPOFF var 0x0 -// RELOCSHARED-NEXT: 0x1032 R_386_TLS_TPOFF var1 0x0 +// RELOCSHARED-NEXT: 0x2001 R_386_TLS_TPOFF32 var 0x0 +// RELOCSHARED-NEXT: 0x2025 R_386_TLS_TPOFF var 0x0 +// RELOCSHARED-NEXT: 0x200F R_386_TLS_TPOFF32 var1 0x0 +// RELOCSHARED-NEXT: 0x2032 R_386_TLS_TPOFF var1 0x0 // RELOCSHARED-NEXT: } // RELOCSHARED-NEXT: ] diff --git a/test/ELF/tls-in-archive.s b/test/ELF/tls-in-archive.s new file mode 100644 index 000000000000..71f60e380f33 --- /dev/null +++ b/test/ELF/tls-in-archive.s @@ -0,0 +1,11 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-in-archive.s -o %t1.o +// RUN: llvm-ar cru %t.a %t1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o +// RUN: ld.lld %t2.o %t.a -o %tout + + .globl _start +_start: + movq foo@gottpoff(%rip), %rax + .section .tbss,"awT",@nobits + .weak foo diff --git a/test/ELF/tls-initial-exec-local.s b/test/ELF/tls-initial-exec-local.s new file mode 100644 index 000000000000..0aef3c8237b6 --- /dev/null +++ b/test/ELF/tls-initial-exec-local.s @@ -0,0 +1,36 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld -shared %t.o -o %t +// RUN: llvm-readobj -r -s %t | FileCheck %s +// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s + +// CHECK: Name: .got +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC (0x2) +// CHECK-NEXT: SHF_WRITE (0x1) +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x2090 + +// CHECK: Relocations [ +// CHECK-NEXT: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x2090 R_X86_64_TPOFF64 - 0x0 +// CHECK-NEXT: 0x2098 R_X86_64_TPOFF64 - 0x4 +// CHECK-NEXT: } +// CHECK-NEXT: ] + +// 0x1007 + 4233 = 0x2090 +// 0x100e + 4234 = 0x2098 +// DISASM: Disassembly of section .text: +// DISASM-NEXT: .text: +// DISASM-NEXT: 1000: {{.*}} addq 4233(%rip), %rax +// DISASM-NEXT: 1007: {{.*}} addq 4234(%rip), %rax + + addq foo@GOTTPOFF(%rip), %rax + addq bar@GOTTPOFF(%rip), %rax + + .section .tbss,"awT",@nobits +foo: + .long 0 +bar: + .long 0 diff --git a/test/ELF/tls-offset.s b/test/ELF/tls-offset.s new file mode 100644 index 000000000000..8f5a46d988da --- /dev/null +++ b/test/ELF/tls-offset.s @@ -0,0 +1,56 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: ld.lld %t -o %tout +// RUN: llvm-readobj -s %tout | FileCheck %s + + .global _start +_start: + retq + + .section .tdata,"awT",@progbits + .align 4 + .long 42 + + .section .tbss,"awT",@nobits + .align 16 + .zero 16 + + .data + .long 1 + + +// Test that .tbss doesn't show up in the offset or in the address. If this +// gets out of sync what we get a runtime is different from what the section +// table says. + +// CHECK: Name: .tdata +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_TLS +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x12000 +// CHECK-NEXT: Offset: 0x2000 +// CHECK-NEXT: Size: 4 + +// CHECK: Name: .tbss +// CHECK-NEXT: Type: SHT_NOBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_TLS +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x12010 +// CHECK-NEXT: Offset: 0x2004 +// CHECK-NEXT: Size: 16 + +// CHECK: Name: .data +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x12004 +// CHECK-NEXT: Offset: 0x2004 +// CHECK-NEXT: Size: 4 diff --git a/test/ELF/tls-opt-gdie.s b/test/ELF/tls-opt-gdie.s index 3f83157086e7..6ed370e3f0b2 100644 --- a/test/ELF/tls-opt-gdie.s +++ b/test/ELF/tls-opt-gdie.s @@ -6,15 +6,15 @@ // RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s //RELOC: Section { -//RELOC: Index: 9 -//RELOC-NEXT: Name: .got +//RELOC: Index: +//RELOC: Name: .got //RELOC-NEXT: Type: SHT_PROGBITS //RELOC-NEXT: Flags [ //RELOC-NEXT: SHF_ALLOC //RELOC-NEXT: SHF_WRITE //RELOC-NEXT: ] -//RELOC-NEXT: Address: 0x120F0 -//RELOC-NEXT: Offset: 0x20F0 +//RELOC-NEXT: Address: 0x120B0 +//RELOC-NEXT: Offset: 0x20B0 //RELOC-NEXT: Size: 16 //RELOC-NEXT: Link: 0 //RELOC-NEXT: Info: 0 @@ -23,22 +23,19 @@ //RELOC-NEXT: } //RELOC: Relocations [ //RELOC-NEXT: Section (4) .rela.dyn { -//RELOC-NEXT: 0x120F0 R_X86_64_TPOFF64 tlsshared0 0x0 -//RELOC-NEXT: 0x120F8 R_X86_64_TPOFF64 tlsshared1 0x0 -//RELOC-NEXT: } -//RELOC-NEXT: Section (5) .rela.plt { -//RELOC-NEXT: 0x13018 R_X86_64_JUMP_SLOT __tls_get_addr 0x0 +//RELOC-NEXT: 0x120B0 R_X86_64_TPOFF64 tlsshared0 0x0 +//RELOC-NEXT: 0x120B8 R_X86_64_TPOFF64 tlsshared1 0x0 //RELOC-NEXT: } //RELOC-NEXT: ] -//0x11009 + (4304 + 7) = 0x120F0 -//0x11019 + (4296 + 7) = 0x120F8 +//0x11009 + (4256 + 7) = 0x120B0 +//0x11019 + (4248 + 7) = 0x120B8 // DISASM: Disassembly of section .text: // DISASM-NEXT: _start: -// DISASM-NEXT: 11000: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax -// DISASM-NEXT: 11009: 48 03 05 e0 10 00 00 addq 4320(%rip), %rax -// DISASM-NEXT: 11010: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax -// DISASM-NEXT: 11019: 48 03 05 d8 10 00 00 addq 4312(%rip), %rax +// DISASM-NEXT: 11000: {{.*}} movq %fs:0, %rax +// DISASM-NEXT: 11009: {{.*}} addq 4256(%rip), %rax +// DISASM-NEXT: 11010: {{.*}} movq %fs:0, %rax +// DISASM-NEXT: 11019: {{.*}} addq 4248(%rip), %rax .section .text .globl _start diff --git a/test/ELF/tls-opt-iele-i686-nopic.s b/test/ELF/tls-opt-iele-i686-nopic.s index 50ade0fc76cc..b6608c16551c 100644 --- a/test/ELF/tls-opt-iele-i686-nopic.s +++ b/test/ELF/tls-opt-iele-i686-nopic.s @@ -4,9 +4,6 @@ // RUN: ld.lld %t.o %tso -o %t1 // RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTREL %s // RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s -// RUN: ld.lld -shared %t.o %tso -o %t1 -// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTRELSHARED %s -// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s // GOTREL: Section { // GOTREL: Index: @@ -54,62 +51,6 @@ // DISASM-NEXT: 1103d: 03 0d 5c 20 01 00 addl 73820, %ecx // DISASM-NEXT: 11043: 65 8b 01 movl %gs:(%ecx), %eax -// GOTRELSHARED: Section { -// GOTRELSHARED: Index: 8 -// GOTRELSHARED: Name: .got -// GOTRELSHARED-NEXT: Type: SHT_PROGBITS -// GOTRELSHARED-NEXT: Flags [ -// GOTRELSHARED-NEXT: SHF_ALLOC -// GOTRELSHARED-NEXT: SHF_WRITE -// GOTRELSHARED-NEXT: ] -// GOTRELSHARED-NEXT: Address: 0x2050 -// GOTRELSHARED-NEXT: Offset: 0x2050 -// GOTRELSHARED-NEXT: Size: 16 -// GOTRELSHARED-NEXT: Link: 0 -// GOTRELSHARED-NEXT: Info: 0 -// GOTRELSHARED-NEXT: AddressAlignment: 4 -// GOTRELSHARED-NEXT: EntrySize: 0 -// GOTRELSHARED-NEXT: } -// GOTRELSHARED: Relocations [ -// GOTRELSHARED-NEXT: Section ({{.*}}) .rel.dyn { -// GOTRELSHARED-NEXT: 0x1002 R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x2050 R_386_TLS_TPOFF tlslocal0 0x0 -// GOTRELSHARED-NEXT: 0x100A R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x1013 R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x101C R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x2054 R_386_TLS_TPOFF tlslocal1 0x0 -// GOTRELSHARED-NEXT: 0x1024 R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x102D R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x1036 R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x2058 R_386_TLS_TPOFF tlsshared0 0x0 -// GOTRELSHARED-NEXT: 0x103F R_386_RELATIVE - 0x0 -// GOTRELSHARED-NEXT: 0x205C R_386_TLS_TPOFF tlsshared1 0x0 -// GOTRELSHARED-NEXT: } -// GOTRELSHARED-NEXT: ] - -// DISASMSHARED: Disassembly of section .text: -// DISASMSHARED-NEXT: _start: -// (.got)[0] = 0x2050 = 8272 -// (.got)[1] = 0x2054 = 8276 -// (.got)[2] = 0x2058 = 8280 -// (.got)[3] = 0x205C = 8284 -// DISASMSHARED-NEXT: 1000: 8b 0d 50 20 00 00 movl 8272, %ecx -// DISASMSHARED-NEXT: 1006: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 1009: a1 50 20 00 00 movl 8272, %eax -// DISASMSHARED-NEXT: 100e: 65 8b 00 movl %gs:(%eax), %eax -// DISASMSHARED-NEXT: 1011: 03 0d 50 20 00 00 addl 8272, %ecx -// DISASMSHARED-NEXT: 1017: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 101a: 8b 0d 54 20 00 00 movl 8276, %ecx -// DISASMSHARED-NEXT: 1020: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 1023: a1 54 20 00 00 movl 8276, %eax -// DISASMSHARED-NEXT: 1028: 65 8b 00 movl %gs:(%eax), %eax -// DISASMSHARED-NEXT: 102b: 03 0d 54 20 00 00 addl 8276, %ecx -// DISASMSHARED-NEXT: 1031: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 1034: 8b 0d 58 20 00 00 movl 8280, %ecx -// DISASMSHARED-NEXT: 103a: 65 8b 01 movl %gs:(%ecx), %eax -// DISASMSHARED-NEXT: 103d: 03 0d 5c 20 00 00 addl 8284, %ecx -// DISASMSHARED-NEXT: 1043: 65 8b 01 movl %gs:(%ecx), %eax - .type tlslocal0,@object .section .tbss,"awT",@nobits .globl tlslocal0 diff --git a/test/ELF/tls-opt-no-plt.s b/test/ELF/tls-opt-no-plt.s new file mode 100644 index 000000000000..53655d0934d5 --- /dev/null +++ b/test/ELF/tls-opt-no-plt.s @@ -0,0 +1,34 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-opt-gdie.s -o %t2.o +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t.exe +// RUN: llvm-readobj -s %t.exe | FileCheck %s + +// CHECK-NOT: .plt + + .global _start +_start: + data16 + leaq foo@TLSGD(%rip), %rdi + data16 + data16 + rex64 + callq __tls_get_addr@PLT + + leaq bar@TLSLD(%rip), %rdi + callq __tls_get_addr@PLT + leaq bar@DTPOFF(%rax), %rax + + .type bar,@object + .section .tdata,"awT",@progbits + .align 8 +bar: + .long 42 + + + .type foo,@object + .section .tdata,"awT",@progbits + .globl foo + .align 8 +foo: + .long 42 diff --git a/test/ELF/tls-opt.s b/test/ELF/tls-opt.s index 06577d7e1021..52468f16b09d 100644 --- a/test/ELF/tls-opt.s +++ b/test/ELF/tls-opt.s @@ -6,35 +6,37 @@ // NORELOC: Relocations [ // NORELOC-NEXT: ] -// DISASM: Disassembly of section .text: -// DISASM-NEXT: _start: -// DISASM-NEXT: 11000: 48 c7 c0 f8 ff ff ff movq $-8, %rax -// DISASM-NEXT: 11007: 49 c7 c7 f8 ff ff ff movq $-8, %r15 -// DISASM-NEXT: 1100e: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax -// DISASM-NEXT: 11015: 4d 8d bf f8 ff ff ff leaq -8(%r15), %r15 -// DISASM-NEXT: 1101c: 48 81 c4 f8 ff ff ff addq $-8, %rsp -// DISASM-NEXT: 11023: 49 81 c4 f8 ff ff ff addq $-8, %r12 -// DISASM-NEXT: 1102a: 48 c7 c0 fc ff ff ff movq $-4, %rax -// DISASM-NEXT: 11031: 49 c7 c7 fc ff ff ff movq $-4, %r15 -// DISASM-NEXT: 11038: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax -// DISASM-NEXT: 1103f: 4d 8d bf fc ff ff ff leaq -4(%r15), %r15 -// DISASM-NEXT: 11046: 48 81 c4 fc ff ff ff addq $-4, %rsp -// DISASM-NEXT: 1104d: 49 81 c4 fc ff ff ff addq $-4, %r12 -// Corrupred output: -// DISASM-NEXT: 11054: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax -// DISASM-NEXT: 1105b: 48 d1 81 c4 f8 ff ff rolq -1852(%rcx) -// DISASM-NEXT: 11062: ff 48 d1 decl -47(%rax) -// DISASM-NEXT: 11065: 81 c4 f8 ff ff ff addl $4294967288, %esp +// DISASM: _start: +// DISASM-NEXT: 11000: 48 c7 c0 f8 ff ff ff movq $-8, %rax +// DISASM-NEXT: 11007: 49 c7 c7 f8 ff ff ff movq $-8, %r15 +// DISASM-NEXT: 1100e: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax +// DISASM-NEXT: 11015: 4d 8d bf f8 ff ff ff leaq -8(%r15), %r15 +// DISASM-NEXT: 1101c: 48 81 c4 f8 ff ff ff addq $-8, %rsp +// DISASM-NEXT: 11023: 49 81 c4 f8 ff ff ff addq $-8, %r12 +// DISASM-NEXT: 1102a: 48 c7 c0 fc ff ff ff movq $-4, %rax +// DISASM-NEXT: 11031: 49 c7 c7 fc ff ff ff movq $-4, %r15 +// DISASM-NEXT: 11038: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax +// DISASM-NEXT: 1103f: 4d 8d bf fc ff ff ff leaq -4(%r15), %r15 +// DISASM-NEXT: 11046: 48 81 c4 fc ff ff ff addq $-4, %rsp +// DISASM-NEXT: 1104d: 49 81 c4 fc ff ff ff addq $-4, %r12 + // LD to LE: -// DISASM-NEXT: 1106b: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax -// DISASM-NEXT: 11077: 48 8d 88 f8 ff ff ff leaq -8(%rax), %rcx -// DISASM-NEXT: 1107e: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax -// DISASM-NEXT: 1108a: 48 8d 88 fc ff ff ff leaq -4(%rax), %rcx +// DISASM-NEXT: 11054: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 11060: 48 8d 88 f8 ff ff ff leaq -8(%rax), %rcx +// DISASM-NEXT: 11067: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 11073: 48 8d 88 fc ff ff ff leaq -4(%rax), %rcx + // GD to LE: -// DISASM-NEXT: 11091: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax -// DISASM-NEXT: 1109a: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax -// DISASM-NEXT: 110a1: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax -// DISASM-NEXT: 110aa: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax +// DISASM-NEXT: 1107a: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 11083: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax +// DISASM-NEXT: 1108a: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax +// DISASM-NEXT: 11093: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax + +// LD to LE: +// DISASM: _DTPOFF64_1: +// DISASM-NEXT: 1109a: f8 clc +// DISASM: _DTPOFF64_2: +// DISASM-NEXT: 110a3: fc cld .type tls0,@object .section .tbss,"awT",@nobits @@ -67,12 +69,7 @@ _start: addq tls1@GOTTPOFF(%rip), %rsp addq tls1@GOTTPOFF(%rip), %r12 - //Invalid input case: - xchgq tls0@gottpoff(%rip),%rax - shlq tls0@gottpoff - rolq tls0@gottpoff - - //LD to LE: + // LD to LE leaq tls0@tlsld(%rip), %rdi callq __tls_get_addr@PLT leaq tls0@dtpoff(%rax),%rcx @@ -80,7 +77,7 @@ _start: callq __tls_get_addr@PLT leaq tls1@dtpoff(%rax),%rcx - //GD to LE: + // GD to LE .byte 0x66 leaq tls0@tlsgd(%rip),%rdi .word 0x6666 @@ -91,3 +88,12 @@ _start: .word 0x6666 rex64 call __tls_get_addr@plt + + // LD to LE +_DTPOFF64_1: + .quad tls0@DTPOFF + nop + +_DTPOFF64_2: + .quad tls1@DTPOFF + nop diff --git a/test/ELF/tls-two-relocs.s b/test/ELF/tls-two-relocs.s new file mode 100644 index 000000000000..7c5d6abf77f4 --- /dev/null +++ b/test/ELF/tls-two-relocs.s @@ -0,0 +1,30 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: ld.lld %t -o %tout -shared +// RUN: llvm-readobj -r %tout | FileCheck %s + + data16 + leaq g_tls_s@TLSGD(%rip), %rdi + data16 + data16 + rex64 + callq __tls_get_addr@PLT + + data16 + leaq g_tls_s@TLSGD(%rip), %rdi + data16 + data16 + rex64 + callq __tls_get_addr@PLT + +// Check that we handle two gd relocations to the same symbol. + +// CHECK: Relocations [ +// CHECK-NEXT: Section (4) .rela.dyn { +// CHECK-NEXT: R_X86_64_DTPMOD64 g_tls_s 0x0 +// CHECK-NEXT: R_X86_64_DTPOFF64 g_tls_s 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Section (5) .rela.plt { +// CHECK-NEXT: R_X86_64_JUMP_SLOT __tls_get_addr 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/test/ELF/trace-ar.s b/test/ELF/trace-ar.s new file mode 100644 index 000000000000..1d178dc9dd37 --- /dev/null +++ b/test/ELF/trace-ar.s @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar1.s -o %t.obj1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar2.s -o %t.obj2.o +# RUN: llvm-ar rcs %t.boo.a %t.obj1.o %t.obj2.o + +## Check how -t works with achieves +# RUN: ld.lld %t.foo.o %t.boo.a -o %t.out -t 2>&1 | FileCheck %s +# CHECK: {{.*}}.foo.o +# CHECK-NEXT: {{.*}}.boo.a({{.*}}.obj1.o) +# CHECK-NOT: {{.*}}.boo.a({{.*}}.obj2.o) + +## Test output with --start-lib +# RUN: ld.lld %t.foo.o --start-lib %t.obj1.o %t.obj2.o -o %t.out -t 2>&1 | FileCheck --check-prefix=STARTLIB %s +# STARTLIB: {{.*}}.foo.o +# STARTLIB-NEXT: {{.*}}.obj1.o +# STARTLIB-NOT: {{.*}}.obj2.o + +.globl _start, _used +_start: + call _used diff --git a/test/ELF/trace-symbols.s b/test/ELF/trace-symbols.s new file mode 100644 index 000000000000..7f6bca8be216 --- /dev/null +++ b/test/ELF/trace-symbols.s @@ -0,0 +1,78 @@ +# Test -y symbol and -trace-symbol=symbol + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +# RUN: %p/Inputs/trace-symbols-foo-weak.s -o %t1 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +# RUN: %p/Inputs/trace-symbols-foo-strong.s -o %t2 +# RUN: ld.lld -shared %t1 -o %t1.so +# RUN: ld.lld -shared %t2 -o %t2.so +# RUN: llvm-ar rcs %t1.a %t1 +# RUN: llvm-ar rcs %t2.a %t2 + +# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \ +# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTRFOO %s +# OBJECTRFOO: trace-symbols.s.tmp: reference to foo + +# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \ +# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTDCOMMON %s +# OBJECTDCOMMON: trace-symbols.s.tmp1: common definition of common + +# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \ +# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD1FOO %s +# OBJECTD1FOO: trace-symbols.s.tmp: reference to foo +# OBJECTD1FOO: trace-symbols.s.tmp1: common definition of common +# OBJECTD1FOO: trace-symbols.s.tmp1: definition of foo +# OBJECTD1FOO: trace-symbols.s.tmp2: definition of foo + +# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \ +# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s +# RUN: ld.lld -y foo -y common --trace-symbol=hsymbol \ +# RUN: %t %t2 %t1 -o %t4 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s +# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \ +# RUN: FileCheck -check-prefix=OBJECTD2FOO %s +# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \ +# RUN: FileCheck -check-prefix=OBJECTD2FOO %s +# OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo + +# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \ +# RUN: FileCheck -check-prefix=SHLIBDCOMMON %s +# SHLIBDCOMMON: trace-symbols.s.tmp1.so: definition of common + +# RUN: ld.lld -y foo -y common %t %t2.so %t1.so -o %t3 2>&1 | \ +# RUN: FileCheck -check-prefix=SHLIBD2FOO %s +# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \ +# RUN: FileCheck -check-prefix=NO-SHLIBD2FOO %s +# SHLIBD2FOO: trace-symbols.s.tmp2.so: definition of foo +# NO-SHLIBD2FOO-NOT: trace-symbols.s.tmp2.so: definition of foo + +# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \ +# RUN: FileCheck -check-prefix=ARCHIVEDCOMMON %s +# ARCHIVEDCOMMON-NOT: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of \ +# common + +# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \ +# RUN: FileCheck -check-prefix=ARCHIVED1FOO %s +# ARCHIVED1FOO: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of foo + +# RUN: ld.lld -y foo %t %t1.a %t2.a -o %t3 | \ +# RUN: FileCheck -check-prefix=ARCHIVED2FOO %s +# ARCHIVED2FOO: trace-symbols.s.tmp2.a(trace-symbols.s.tmp2): definition of foo + +# RUN: ld.lld -y bar %t %t1.so %t2.so -o %t3 | \ +# RUN: FileCheck -check-prefix=SHLIBDBAR %s +# SHLIBDBAR: trace-symbols.s.tmp2.so: definition of bar + +# RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \ +# RUN: FileCheck -check-prefix=SHLIBRBAR %s +# SHLIBRBAR-NOT: trace-symbols.s.tmp1.so: reference to bar + +# RUN: ld.lld -y foo -y bar %t -u bar --start-lib %t1 %t2 --end-lib -o %t3 | \ +# RUN: FileCheck -check-prefix=STARTLIB %s +# STARTLIB: trace-symbols.s.tmp1: reference to bar + +.hidden hsymbol +.globl _start +.type _start, @function +_start: +call foo diff --git a/test/ELF/trace.s b/test/ELF/trace.s new file mode 100644 index 000000000000..4374d93da648 --- /dev/null +++ b/test/ELF/trace.s @@ -0,0 +1,9 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o + +## Check -t +# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s +# CHECK: {{.*}}.foo.o + +## Check --trace alias +# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s diff --git a/test/ELF/undef-shared.s b/test/ELF/undef-shared.s new file mode 100644 index 000000000000..ed9103571443 --- /dev/null +++ b/test/ELF/undef-shared.s @@ -0,0 +1,14 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s + +# CHECK: undefined symbol: hidden in {{.*}} +.global hidden +.hidden hidden + +# CHECK: undefined symbol: internal in {{.*}} +.global internal +.internal internal + +# CHECK: undefined symbol: protected in {{.*}} +.global protected +.protected protected diff --git a/test/ELF/undef-version-script.s b/test/ELF/undef-version-script.s new file mode 100644 index 000000000000..9f0a5a49e72e --- /dev/null +++ b/test/ELF/undef-version-script.s @@ -0,0 +1,40 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "{ local: *; };" > %t.script +# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s + +# This does not match gold's behavior because gold does not create undefined +# symbols in dynsym without an appropriate (e.g. PLT) relocation in the input. + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: @ (0) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local (0x0) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: bar@ (1) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Weak (0x2) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo@ (5) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.global foo +.weak bar diff --git a/test/ELF/undef-with-plt-addr-i686.s b/test/ELF/undef-with-plt-addr-i686.s new file mode 100644 index 000000000000..755f0daced2e --- /dev/null +++ b/test/ELF/undef-with-plt-addr-i686.s @@ -0,0 +1,23 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/undef-with-plt-addr.s -o %t2.o +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t3 +// RUN: llvm-readobj -t -s %t3 | FileCheck %s + +.globl _start +_start: +mov $set_data, %eax + +// Test that set_data has an address in the .plt + +// CHECK: Name: .plt +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x11010 + +// CHECK: Name: set_data +// CHECK-NEXT: Value: 0x11020 diff --git a/test/ELF/undef-with-plt-addr.s b/test/ELF/undef-with-plt-addr.s new file mode 100644 index 000000000000..792d85f3da61 --- /dev/null +++ b/test/ELF/undef-with-plt-addr.s @@ -0,0 +1,45 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/undef-with-plt-addr.s -o %t2.o +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t3 +// RUN: llvm-readobj -t -s -r %t3 | FileCheck %s + +.globl _start +_start: +movabsq $set_data, %rax + +.data +.quad foo +// Test that set_data has an address in the .plt, but foo is not + +// CHECK: Name: .plt +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_EXECINSTR +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x11010 + +// CHECK: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x13000 R_X86_64_64 foo 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Section ({{.*}}) .rela.plt { +// CHECK-NEXT: 0x13020 R_X86_64_JUMP_SLOT set_data 0x0 +// CHECK-NEXT: } + +// CHECK: Name: foo +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Function +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined + +// CHECK: Name: set_data +// CHECK-NEXT: Value: 0x11020 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global +// CHECK-NEXT: Type: Function +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined diff --git a/test/ELF/undef.s b/test/ELF/undef.s index 374c9c884d5f..c8211c73866f 100644 --- a/test/ELF/undef.s +++ b/test/ELF/undef.s @@ -1,8 +1,15 @@ -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s -# CHECK: undefined symbol: foo in {{.*}} # REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef.s -o %t2.o +# RUN: llvm-ar rc %t2.a %t2.o +# RUN: not ld.lld %t.o %t2.a -o %t.exe 2>&1 | FileCheck %s +# RUN: not ld.lld -pie %t.o %t2.a -o %t.exe 2>&1 | FileCheck %s +# CHECK: undefined symbol: bar in {{.*}} +# CHECK: undefined symbol: foo in {{.*}} +# CHECK: undefined symbol: zed2 in {{.*}}2.a({{.*}}.o) - .globl _start; + .globl _start _start: call foo + call bar + call zed1 diff --git a/test/ELF/undefined-opt.s b/test/ELF/undefined-opt.s index 97ab5a63490a..ddd34f49b748 100644 --- a/test/ELF/undefined-opt.s +++ b/test/ELF/undefined-opt.s @@ -51,5 +51,16 @@ # UNK-UNDEFINED-SO-NOT: Name: unknown # UNK-UNDEFINED-SO: ] -.globl _start; +# Added undefined symbols should appear in the dynamic table if necessary. +# RUN: ld.lld -shared -o %t5 %t.o -u export +# RUN: llvm-readobj --dyn-symbols %t5 | \ +# RUN: FileCheck --check-prefix=EXPORT-SO %s +# EXPORT-SO: DynamicSymbols [ +# EXPORT-SO: Name: export +# EXPORT-SO: ] + +.globl _start _start: + +.globl export +export: diff --git a/test/ELF/unresolved-symbols.s b/test/ELF/unresolved-symbols.s new file mode 100644 index 000000000000..2fa59cb0ffd7 --- /dev/null +++ b/test/ELF/unresolved-symbols.s @@ -0,0 +1,63 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/unresolved-symbols.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t.so + +## Check that %t2.o contains undefined symbol undef. +# RUN: not ld.lld %t1.o %t2.o -o %t 2>&1 | \ +# RUN: FileCheck -check-prefix=UNDCHECK %s +# UNDCHECK: undefined symbol: undef in {{.*}}2.o + +## Error out if unknown option value was set. +# RUN: not ld.lld %t1.o %t2.o -o %t --unresolved-symbols=xxx 2>&1 | \ +# RUN: FileCheck -check-prefix=ERR1 %s +# ERR1: unknown --unresolved-symbols value: xxx + +## Ignore all should not produce error for symbols from object except +## case when --no-undefined specified. +# RUN: ld.lld %t2.o -o %t1_1 --unresolved-symbols=ignore-all +# RUN: llvm-readobj %t1_1 > /dev/null 2>&1 +# RUN: not ld.lld %t2.o -o %t1_2 --unresolved-symbols=ignore-all --no-undefined 2>&1 | \ +# RUN: FileCheck -check-prefix=ERRUND %s +# ERRUND: undefined symbol: undef +## Also ignore all should not produce error for symbols from DSOs. +# RUN: ld.lld %t1.o %t.so -o %t1_3 --unresolved-symbols=ignore-all +# RUN: llvm-readobj %t1_3 > /dev/null 2>&1 + +## Ignoring undefines in objects should not produce error for symbol from object. +# RUN: ld.lld %t1.o %t2.o -o %t2 --unresolved-symbols=ignore-in-object-files +# RUN: llvm-readobj %t2 > /dev/null 2>&1 +## And still should not should produce for undefines from DSOs. +# RUN: ld.lld %t1.o %t.so -o %t2_1 --unresolved-symbols=ignore-in-object-files +# RUN: llvm-readobj %t2 > /dev/null 2>&1 + +## Ignoring undefines in shared should produce error for symbol from object. +# RUN: not ld.lld %t2.o -o %t3 --unresolved-symbols=ignore-in-shared-libs 2>&1 | \ +# RUN: FileCheck -check-prefix=ERRUND %s +## And should not produce errors for symbols from DSO. +# RUN: ld.lld %t1.o %t.so -o %t3_1 --unresolved-symbols=ignore-in-shared-libs +# RUN: llvm-readobj %t3_1 > /dev/null 2>&1 + +## Ignoring undefines in shared libs should not produce error for symbol from object +## if we are linking DSO. +# RUN: ld.lld -shared %t1.o -o %t4 --unresolved-symbols=ignore-in-shared-libs +# RUN: llvm-readobj %t4 > /dev/null 2>&1 + +## Do not report undefines if linking relocatable. +# RUN: ld.lld -r %t1.o %t2.o -o %t5 --unresolved-symbols=report-all +# RUN: llvm-readobj %t5 > /dev/null 2>&1 + +## report-all is the default one. Check that we do not report +## undefines from DSO and do report undefines from object. With +## report-all specified and without. +# RUN: ld.lld -shared %t1.o %t.so -o %t6 --unresolved-symbols=report-all +# RUN: llvm-readobj %t6 > /dev/null 2>&1 +# RUN: ld.lld -shared %t1.o %t.so -o %t6_1 +# RUN: llvm-readobj %t6_1 > /dev/null 2>&1 +# RUN: not ld.lld %t2.o -o %t7 --unresolved-symbols=report-all 2>&1 | \ +# RUN: FileCheck -check-prefix=ERRUND %s +# RUN: not ld.lld %t2.o -o %t7_1 2>&1 | \ +# RUN: FileCheck -check-prefix=ERRUND %s + +.globl _start +_start: diff --git a/test/ELF/user_def_init_array_start.s b/test/ELF/user_def_init_array_start.s new file mode 100644 index 000000000000..6c33166d1d4e --- /dev/null +++ b/test/ELF/user_def_init_array_start.s @@ -0,0 +1,10 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t2.so -shared +// Allow user defined __init_array_start. This is used by musl because of the +// the bfd linker not handling these properly. We always create them as +// hidden, musl should not have problems with lld. + + .hidden __init_array_start + .globl __init_array_start +__init_array_start: + .zero 8 diff --git a/test/ELF/valid-cie-length-dw64.s b/test/ELF/valid-cie-length-dw64.s deleted file mode 100644 index 65d6952448a2..000000000000 --- a/test/ELF/valid-cie-length-dw64.s +++ /dev/null @@ -1,13 +0,0 @@ -// REQUIRES: x86 - -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t -// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s - - .section .eh_frame - .long 0xFFFFFFFF - .quad 1 - nop - -// CHECK-NOT: Truncated CIE/FDE length -// CHECK-NOT: CIE/FIE size is too large -// CHECK-NOT: CIE/FIE ends past the end of the section diff --git a/test/ELF/verdef-defaultver.s b/test/ELF/verdef-defaultver.s new file mode 100644 index 000000000000..4d847344f996 --- /dev/null +++ b/test/ELF/verdef-defaultver.s @@ -0,0 +1,205 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/verdef-defaultver.s -o %t1 +# RUN: echo "LIBSAMPLE_1.0{ \ +# RUN: global: a; \ +# RUN: local: *; }; \ +# RUN: LIBSAMPLE_2.0{ \ +# RUN: global: b; c; \ +# RUN: }LIBSAMPLE_1.0;" > %t.script +# RUN: ld.lld -shared -soname shared %t1 --version-script %t.script -o %t.so +# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s + +# DSO: DynamicSymbols [ +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: @ +# DSO-NEXT: Value: 0x0 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Local +# DSO-NEXT: Type: None +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: Undefined +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: a@@LIBSAMPLE_1.0 +# DSO-NEXT: Value: 0x1000 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global +# DSO-NEXT: Type: Function +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: b@@LIBSAMPLE_2.0 +# DSO-NEXT: Value: 0x1002 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global +# DSO-NEXT: Type: Function +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: b@LIBSAMPLE_1.0 +# DSO-NEXT: Value: 0x1001 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global +# DSO-NEXT: Type: Function +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: c@@LIBSAMPLE_2.0 +# DSO-NEXT: Value: 0x1003 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global +# DSO-NEXT: Type: Function +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text +# DSO-NEXT: } +# DSO-NEXT: ] +# DSO-NEXT: Version symbols { +# DSO-NEXT: Section Name: .gnu.version +# DSO-NEXT: Address: 0x240 +# DSO-NEXT: Offset: 0x240 +# DSO-NEXT: Link: 1 +# DSO-NEXT: Symbols [ +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 0 +# DSO-NEXT: Name: @ +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 2 +# DSO-NEXT: Name: a@@LIBSAMPLE_1.0 +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 3 +# DSO-NEXT: Name: b@@LIBSAMPLE_2.0 +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 2 +# DSO-NEXT: Name: b@LIBSAMPLE_1.0 +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 3 +# DSO-NEXT: Name: c@@LIBSAMPLE_2.0 +# DSO-NEXT: } +# DSO-NEXT: ] +# DSO-NEXT: } +# DSO-NEXT: SHT_GNU_verdef { +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: Base +# DSO-NEXT: Index: 1 +# DSO-NEXT: Hash: 127830196 +# DSO-NEXT: Name: shared +# DSO-NEXT: } +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: 0x0 +# DSO-NEXT: Index: 2 +# DSO-NEXT: Hash: 98457184 +# DSO-NEXT: Name: LIBSAMPLE_1.0 +# DSO-NEXT: } +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: 0x0 +# DSO-NEXT: Index: 3 +# DSO-NEXT: Hash: 98456416 +# DSO-NEXT: Name: LIBSAMPLE_2.0 +# DSO-NEXT: } +# DSO-NEXT: } + +## Check that we can link against DSO produced. +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2 +# RUN: ld.lld %t2 %t.so -o %t3 +# RUN: llvm-readobj -V -dyn-symbols %t3 | FileCheck --check-prefix=EXE %s + +# EXE: DynamicSymbols [ +# EXE-NEXT: Symbol { +# EXE-NEXT: Name: @ +# EXE-NEXT: Value: 0x0 +# EXE-NEXT: Size: 0 +# EXE-NEXT: Binding: Local +# EXE-NEXT: Type: None +# EXE-NEXT: Other: 0 +# EXE-NEXT: Section: Undefined +# EXE-NEXT: } +# EXE-NEXT: Symbol { +# EXE-NEXT: Name: a@LIBSAMPLE_1.0 +# EXE-NEXT: Value: 0x11020 +# EXE-NEXT: Size: 0 +# EXE-NEXT: Binding: Global +# EXE-NEXT: Type: Function +# EXE-NEXT: Other: 0 +# EXE-NEXT: Section: Undefined +# EXE-NEXT: } +# EXE-NEXT: Symbol { +# EXE-NEXT: Name: b@LIBSAMPLE_2.0 +# EXE-NEXT: Value: 0x11030 +# EXE-NEXT: Size: 0 +# EXE-NEXT: Binding: Global +# EXE-NEXT: Type: Function +# EXE-NEXT: Other: 0 +# EXE-NEXT: Section: Undefined +# EXE-NEXT: } +# EXE-NEXT: Symbol { +# EXE-NEXT: Name: c@LIBSAMPLE_2.0 +# EXE-NEXT: Value: 0x11040 +# EXE-NEXT: Size: 0 +# EXE-NEXT: Binding: Global +# EXE-NEXT: Type: Function +# EXE-NEXT: Other: 0 +# EXE-NEXT: Section: Undefined +# EXE-NEXT: } +# EXE-NEXT: ] +# EXE-NEXT: Version symbols { +# EXE-NEXT: Section Name: .gnu.version +# EXE-NEXT: Address: 0x10228 +# EXE-NEXT: Offset: 0x228 +# EXE-NEXT: Link: 1 +# EXE-NEXT: Symbols [ +# EXE-NEXT: Symbol { +# EXE-NEXT: Version: 0 +# EXE-NEXT: Name: @ +# EXE-NEXT: } +# EXE-NEXT: Symbol { +# EXE-NEXT: Version: 2 +# EXE-NEXT: Name: a@LIBSAMPLE_1.0 +# EXE-NEXT: } +# EXE-NEXT: Symbol { +# EXE-NEXT: Version: 3 +# EXE-NEXT: Name: b@LIBSAMPLE_2.0 +# EXE-NEXT: } +# EXE-NEXT: Symbol { +# EXE-NEXT: Version: 3 +# EXE-NEXT: Name: c@LIBSAMPLE_2.0 +# EXE-NEXT: } +# EXE-NEXT: ] +# EXE-NEXT: } +# EXE-NEXT: SHT_GNU_verdef { +# EXE-NEXT: } +# EXE-NEXT: SHT_GNU_verneed { +# EXE-NEXT: Dependency { +# EXE-NEXT: Version: 1 +# EXE-NEXT: Count: 2 +# EXE-NEXT: FileName: shared +# EXE-NEXT: Entry { +# EXE-NEXT: Hash: 98457184 +# EXE-NEXT: Flags: 0x0 +# EXE-NEXT: Index: 2 +# EXE-NEXT: Name: LIBSAMPLE_1.0 +# EXE-NEXT: } +# EXE-NEXT: Entry { +# EXE-NEXT: Hash: 98456416 +# EXE-NEXT: Flags: 0x0 +# EXE-NEXT: Index: 3 +# EXE-NEXT: Name: LIBSAMPLE_2.0 +# EXE-NEXT: } +# EXE-NEXT: } +# EXE-NEXT: } + +.globl _start +_start: + callq a + callq b + callq c diff --git a/test/ELF/verdef-dependency.s b/test/ELF/verdef-dependency.s new file mode 100644 index 000000000000..92627ddc5c0f --- /dev/null +++ b/test/ELF/verdef-dependency.s @@ -0,0 +1,44 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "LIBSAMPLE_1.0{ \ +# RUN: global: a; \ +# RUN: local: *; }; \ +# RUN: LIBSAMPLE_2.0{ \ +# RUN: global: b; \ +# RUN: local: *; }LIBSAMPLE_1.0; \ +# RUN: LIBSAMPLE_3.0{ \ +# RUN: global: c; \ +# RUN: }LIBSAMPLE_2.0;" > %t.script +# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so +# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s + +# DSO: SHT_GNU_verdef { +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: Base +# DSO-NEXT: Index: 1 +# DSO-NEXT: Hash: 127830196 +# DSO-NEXT: Name: shared +# DSO-NEXT: } +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: 0x0 +# DSO-NEXT: Index: 2 +# DSO-NEXT: Hash: 98457184 +# DSO-NEXT: Name: LIBSAMPLE_1.0 +# DSO-NEXT: } +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: 0x0 +# DSO-NEXT: Index: 3 +# DSO-NEXT: Hash: 98456416 +# DSO-NEXT: Name: LIBSAMPLE_2.0 +# DSO-NEXT: } +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: 0x0 +# DSO-NEXT: Index: 4 +# DSO-NEXT: Hash: 98456672 +# DSO-NEXT: Name: LIBSAMPLE_3.0 +# DSO-NEXT: } +# DSO-NEXT: } diff --git a/test/ELF/verdef.s b/test/ELF/verdef.s new file mode 100644 index 000000000000..9463de0c0a0c --- /dev/null +++ b/test/ELF/verdef.s @@ -0,0 +1,117 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "LIBSAMPLE_1.0{ \ +# RUN: global: a; \ +# RUN: local: *; }; \ +# RUN: LIBSAMPLE_2.0{ \ +# RUN: global: b; \ +# RUN: local: *; }; \ +# RUN: LIBSAMPLE_3.0{ \ +# RUN: global: c; \ +# RUN: local: *; };" > %t.script +# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so +# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s + +# DSO: Version symbols { +# DSO-NEXT: Section Name: .gnu.version +# DSO-NEXT: Address: 0x228 +# DSO-NEXT: Offset: 0x228 +# DSO-NEXT: Link: 1 +# DSO-NEXT: Symbols [ +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 0 +# DSO-NEXT: Name: @ +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 2 +# DSO-NEXT: Name: a@@LIBSAMPLE_1.0 +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 3 +# DSO-NEXT: Name: b@@LIBSAMPLE_2.0 +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 4 +# DSO-NEXT: Name: c@@LIBSAMPLE_3.0 +# DSO-NEXT: } +# DSO-NEXT: ] +# DSO-NEXT: } +# DSO-NEXT: SHT_GNU_verdef { +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: Base +# DSO-NEXT: Index: 1 +# DSO-NEXT: Hash: 127830196 +# DSO-NEXT: Name: shared +# DSO-NEXT: } +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: 0x0 +# DSO-NEXT: Index: 2 +# DSO-NEXT: Hash: 98457184 +# DSO-NEXT: Name: LIBSAMPLE_1.0 +# DSO-NEXT: } +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: 0x0 +# DSO-NEXT: Index: 3 +# DSO-NEXT: Hash: 98456416 +# DSO-NEXT: Name: LIBSAMPLE_2.0 +# DSO-NEXT: } +# DSO-NEXT: Definition { +# DSO-NEXT: Version: 1 +# DSO-NEXT: Flags: 0x0 +# DSO-NEXT: Index: 4 +# DSO-NEXT: Hash: 98456672 +# DSO-NEXT: Name: LIBSAMPLE_3.0 +# DSO-NEXT: } +# DSO-NEXT: } +# DSO-NEXT: SHT_GNU_verneed { +# DSO-NEXT: } + +## Check that we can link agains DSO we produced. +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/verdef.s -o %tmain.o +# RUN: ld.lld %tmain.o %t.so -o %tout +# RUN: llvm-readobj -V %tout | FileCheck --check-prefix=MAIN %s + +# MAIN: Version symbols { +# MAIN-NEXT: Section Name: .gnu.version +# MAIN-NEXT: Address: 0x10228 +# MAIN-NEXT: Offset: 0x228 +# MAIN-NEXT: Link: 1 +# MAIN-NEXT: Symbols [ +# MAIN-NEXT: Symbol { +# MAIN-NEXT: Version: 0 +# MAIN-NEXT: Name: @ +# MAIN-NEXT: } +# MAIN-NEXT: Symbol { +# MAIN-NEXT: Version: 2 +# MAIN-NEXT: Name: a@LIBSAMPLE_1.0 +# MAIN-NEXT: } +# MAIN-NEXT: Symbol { +# MAIN-NEXT: Version: 3 +# MAIN-NEXT: Name: b@LIBSAMPLE_2.0 +# MAIN-NEXT: } +# MAIN-NEXT: Symbol { +# MAIN-NEXT: Version: 4 +# MAIN-NEXT: Name: c@LIBSAMPLE_3.0 +# MAIN-NEXT: } +# MAIN-NEXT: ] +# MAIN-NEXT: } +# MAIN-NEXT: SHT_GNU_verdef { +# MAIN-NEXT: } + +.globl a +.type a,@function +a: +retq + +.globl b +.type b,@function +b: +retq + +.globl c +.type c,@function +c: +retq diff --git a/test/ELF/verneed-as-needed-weak.s b/test/ELF/verneed-as-needed-weak.s new file mode 100644 index 000000000000..a8efdc42d6d4 --- /dev/null +++ b/test/ELF/verneed-as-needed-weak.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o --as-needed %S/Inputs/verneed1.so -o %t +# RUN: llvm-readobj -V %t | FileCheck %s + +# CHECK: SHT_GNU_verneed { +# CHECK-NEXT: } + +.weak f1 + +.globl _start +_start: +.data +.quad f1 diff --git a/test/ELF/verneed-local.s b/test/ELF/verneed-local.s new file mode 100644 index 000000000000..a50f670ed7bd --- /dev/null +++ b/test/ELF/verneed-local.s @@ -0,0 +1,8 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: not ld.lld %t.o %S/Inputs/verneed1.so -o %t 2>&1 | FileCheck %s + +# CHECK: undefined symbol: f3 in +.globl _start +_start: +call f3 diff --git a/test/ELF/verneed.s b/test/ELF/verneed.s new file mode 100644 index 000000000000..e9d7c53ba334 --- /dev/null +++ b/test/ELF/verneed.s @@ -0,0 +1,173 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o %S/Inputs/verneed1.so %S/Inputs/verneed2.so -o %t +# RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s + +# CHECK: Section { +# CHECK: Index: 1 +# CHECK-NEXT: Name: .dynsym (1) +# CHECK-NEXT: Type: SHT_DYNSYM (0xB) +# CHECK-NEXT: Flags [ (0x2) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x101C8 +# CHECK-NEXT: Offset: 0x1C8 +# CHECK-NEXT: Size: 96 +# CHECK-NEXT: Link: 5 +# CHECK-NEXT: Info: 1 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 24 +# CHECK: Section { +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .gnu.version (9) +# CHECK-NEXT: Type: SHT_GNU_versym (0x6FFFFFFF) +# CHECK-NEXT: Flags [ (0x2) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10228 +# CHECK-NEXT: Offset: 0x228 +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Link: 1 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 2 +# CHECK-NEXT: EntrySize: 2 +# CHECK: Section { +# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Name: .gnu.version_r (22) +# CHECK-NEXT: Type: SHT_GNU_verneed (0x6FFFFFFE) +# CHECK-NEXT: Flags [ (0x2) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10230 +# CHECK-NEXT: Offset: 0x230 +# CHECK-NEXT: Size: 80 +# CHECK-NEXT: Link: 5 +# CHECK-NEXT: Info: 2 +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: 0 +# CHECK: Section { +# CHECK: Index: 5 +# CHECK-NEXT: Name: .dynstr +# CHECK-NEXT: Type: SHT_STRTAB +# CHECK-NEXT: Flags [ (0x2) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x102A8 +# CHECK-NEXT: Offset: 0x2A8 +# CHECK-NEXT: Size: 47 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 00663100 7665726E 65656431 2E736F2E |.f1.verneed1.so.| +# CHECK-NEXT: 0010: 30007633 00663200 76320067 31007665 |0.v3.f2.v2.g1.ve| +# CHECK-NEXT: 0020: 726E6565 64322E73 6F2E3000 763100 |rneed2.so.0.v1.| +# CHECK-NEXT: ) +# CHECK-NEXT: } + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: @ (0) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local (0x0) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: f1@v3 (1) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: f2@v2 (21) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: g1@v1 (27) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: ] + +# CHECK: 0x000000006FFFFFF0 VERSYM 0x10228 +# CHECK-NEXT: 0x000000006FFFFFFE VERNEED 0x10230 +# CHECK-NEXT: 0x000000006FFFFFFF VERNEEDNUM 2 + +# CHECK: Version symbols { +# CHECK-NEXT: Section Name: .gnu.version +# CHECK-NEXT: Address: 0x10228 +# CHECK-NEXT: Offset: 0x228 +# CHECK-NEXT: Link: 1 +# CHECK-NEXT: Symbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 0 +# CHECK-NEXT: Name: @ +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 2 +# CHECK-NEXT: Name: f1@v3 +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 3 +# CHECK-NEXT: Name: f2@v2 +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Version: 4 +# CHECK-NEXT: Name: g1@v1 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: SHT_GNU_verdef { +# CHECK-NEXT: } +# CHECK-NEXT: SHT_GNU_verneed { +# CHECK-NEXT: Dependency { +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: Count: 2 +# CHECK-NEXT: FileName: verneed1.so.0 +# CHECK-NEXT: Entry { +# CHECK-NEXT: Hash: 1938 +# CHECK-NEXT: Flags: 0x0 +# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Name: v2 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Hash: 1939 +# CHECK-NEXT: Flags: 0x0 +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: v3 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: Dependency { +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: Count: 1 +# CHECK-NEXT: FileName: verneed2.so.0 +# CHECK-NEXT: Entry { +# CHECK-NEXT: Hash: 1937 +# CHECK-NEXT: Flags: 0x0 +# CHECK-NEXT: Index: 4 +# CHECK-NEXT: Name: v1 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } + +.globl _start +_start: +call f1@plt +call f2@plt +call g1@plt diff --git a/test/ELF/version-script-err.s b/test/ELF/version-script-err.s new file mode 100644 index 000000000000..15b69e98505b --- /dev/null +++ b/test/ELF/version-script-err.s @@ -0,0 +1,10 @@ +// REQUIRES: x86 + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: not ld.lld -shared %t.o -o %t.so --version-script %p/Inputs/version-script-err.script 2>&1 | FileCheck %s +// CHECK: ; expected, but got } + +// RUN: echo "\"" > %terr1.script +// RUN: not ld.lld --version-script %terr1.script -shared %t.o -o %t.so 2>&1 | \ +// RUN: FileCheck -check-prefix=ERR1 %s +// ERR1: unclosed quote diff --git a/test/ELF/version-script-extern.s b/test/ELF/version-script-extern.s new file mode 100644 index 000000000000..439653487bc0 --- /dev/null +++ b/test/ELF/version-script-extern.s @@ -0,0 +1,97 @@ +# REQUIRES: shell + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "LIBSAMPLE_1.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: \"foo(int)\"; \ +# RUN: \"zed(int)\"; \ +# RUN: }; \ +# RUN: }; \ +# RUN: LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: \"bar(int)\"; \ +# RUN: }; \ +# RUN: }; " > %t.script +# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so +# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s + +# DSO: DynamicSymbols [ +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: @ +# DSO-NEXT: Value: 0x0 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Local +# DSO-NEXT: Type: None +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: Undefined +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: _Z3bari@@LIBSAMPLE_2.0 +# DSO-NEXT: Value: 0x1001 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global +# DSO-NEXT: Type: Function +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: _Z3fooi@@LIBSAMPLE_1.0 +# DSO-NEXT: Value: 0x1000 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global +# DSO-NEXT: Type: Function +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: _Z3zedi@@LIBSAMPLE_1.0 +# DSO-NEXT: Value: 0x1002 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global (0x1) +# DSO-NEXT: Type: Function (0x2) +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text (0x6) +# DSO-NEXT: } +# DSO-NEXT: ] +# DSO-NEXT: Version symbols { +# DSO-NEXT: Section Name: .gnu.version +# DSO-NEXT: Address: 0x228 +# DSO-NEXT: Offset: 0x228 +# DSO-NEXT: Link: 1 +# DSO-NEXT: Symbols [ +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 0 +# DSO-NEXT: Name: @ +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 3 +# DSO-NEXT: Name: _Z3bari@@LIBSAMPLE_2.0 +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 2 +# DSO-NEXT: Name: _Z3fooi@@LIBSAMPLE_1.0 +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Version: 2 +# DSO-NEXT: Name: _Z3zedi@@LIBSAMPLE_1.0 +# DSO-NEXT: } +# DSO-NEXT: ] +# DSO-NEXT: } + +.text +.globl _Z3fooi +.type _Z3fooi,@function +_Z3fooi: +retq + +.globl _Z3bari +.type _Z3bari,@function +_Z3bari: +retq + +.globl _Z3zedi +.type _Z3zedi,@function +_Z3zedi: +retq diff --git a/test/ELF/version-script-noundef.s b/test/ELF/version-script-noundef.s new file mode 100644 index 000000000000..4a251d6172da --- /dev/null +++ b/test/ELF/version-script-noundef.s @@ -0,0 +1,22 @@ +# REQUIRES: x86 + +# RUN: echo "VERSION_1.0{ \ +# RUN: global: bar; \ +# RUN: };" > %t.script +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: not ld.lld --version-script %t.script -shared --no-undefined-version \ +# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR1 %s +# ERR1: version script assignment of VERSION_1.0 to symbol bar failed: symbol not defined + +# RUN: echo "VERSION_1.0{ \ +# RUN: global: und; \ +# RUN: };" > %t2.script +# RUN: not ld.lld --version-script %t2.script -shared --no-undefined-version \ +# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR2 %s +# ERR2: version script assignment of VERSION_1.0 to symbol und failed: symbol not defined + +.text +.globl foo +.type foo,@function +foo: +callq und@PLT diff --git a/test/ELF/version-script.s b/test/ELF/version-script.s new file mode 100644 index 000000000000..ba9c95a96fc3 --- /dev/null +++ b/test/ELF/version-script.s @@ -0,0 +1,274 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o +# RUN: ld.lld -shared %t2.o -soname shared -o %t2.so + +# RUN: echo "{ global: foo1; foo3; local: *; };" > %t.script +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s + +# RUN: echo "# comment" > %t3.script +# RUN: echo "{ local: *; # comment" >> %t3.script +# RUN: echo -n "}; # comment" >> %t3.script +# RUN: ld.lld --version-script %t3.script -shared %t.o %t2.so -o %t3.so +# RUN: llvm-readobj -dyn-symbols %t3.so | FileCheck --check-prefix=DSO2 %s + +# --version-script filters --dynamic-list. +# RUN: echo "{ foo1; foo2; };" > %t.list +# RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t +# RUN: llvm-readobj -dyn-symbols %t | FileCheck --check-prefix=EXE %s + +# RUN: echo "VERSION_1.0{ \ +# RUN: global: foo1; \ +# RUN: local: *; }; \ +# RUN: VERSION_2.0{ \ +# RUN: global: foo3; \ +# RUN: local: *; }; " > %t4.script +# RUN: ld.lld --version-script %t4.script -shared %t.o %t2.so -o %t4.so +# RUN: llvm-readobj -dyn-symbols %t4.so | FileCheck --check-prefix=VERDSO %s + +# RUN: echo "VERSION_1.0{ \ +# RUN: global: foo1; \ +# RUN: local: *; }; \ +# RUN: { \ +# RUN: global: foo3; \ +# RUN: local: *; }; " > %t5.script +# RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \ +# RUN: FileCheck -check-prefix=ERR %s +# ERR: anonymous version definition is used in combination with other version definitions + +# RUN: echo "{ \ +# RUN: global: foo1; \ +# RUN: local: *; }; \ +# RUN: VERSION_2.0 { \ +# RUN: global: foo3; \ +# RUN: local: *; }; " > %t5.script +# RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \ +# RUN: FileCheck -check-prefix=ERR %s + +# RUN: echo "VERSION_1.0{ \ +# RUN: global: foo1; \ +# RUN: local: *; }; \ +# RUN: VERSION_2.0 { \ +# RUN: global: foo1; \ +# RUN: local: *; }; " > %t6.script +# RUN: ld.lld --version-script %t6.script -shared %t.o %t2.so -o %t6.so 2>&1 | \ +# RUN: FileCheck -check-prefix=WARN2 %s +# WARN2: duplicate symbol foo1 in version script + +# RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2 +# RUN: llvm-readobj %t2 > /dev/null + +# DSO: DynamicSymbols [ +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: @ (0) +# DSO-NEXT: Value: 0x0 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Local (0x0) +# DSO-NEXT: Type: None (0x0) +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: Undefined (0x0) +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: bar@ (1) +# DSO-NEXT: Value: 0x0 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global (0x1) +# DSO-NEXT: Type: Function (0x2) +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: Undefined (0x0) +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: foo1@ (5) +# DSO-NEXT: Value: 0x1000 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global (0x1) +# DSO-NEXT: Type: None (0x0) +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text +# DSO-NEXT: } +# DSO-NEXT: Symbol { +# DSO-NEXT: Name: foo3@ (10) +# DSO-NEXT: Value: 0x1007 +# DSO-NEXT: Size: 0 +# DSO-NEXT: Binding: Global (0x1) +# DSO-NEXT: Type: None (0x0) +# DSO-NEXT: Other: 0 +# DSO-NEXT: Section: .text +# DSO-NEXT: } +# DSO-NEXT: ] + +# DSO2: DynamicSymbols [ +# DSO2-NEXT: Symbol { +# DSO2-NEXT: Name: @ (0) +# DSO2-NEXT: Value: 0x0 +# DSO2-NEXT: Size: 0 +# DSO2-NEXT: Binding: Local (0x0) +# DSO2-NEXT: Type: None (0x0) +# DSO2-NEXT: Other: 0 +# DSO2-NEXT: Section: Undefined (0x0) +# DSO2-NEXT: } +# DSO2-NEXT: Symbol { +# DSO2-NEXT: Name: bar@ (1) +# DSO2-NEXT: Value: 0x0 +# DSO2-NEXT: Size: 0 +# DSO2-NEXT: Binding: Global (0x1) +# DSO2-NEXT: Type: Function (0x2) +# DSO2-NEXT: Other: 0 +# DSO2-NEXT: Section: Undefined (0x0) +# DSO2-NEXT: } +# DSO2-NEXT: ] + +# EXE: DynamicSymbols [ +# EXE-NEXT: Symbol { +# EXE-NEXT: Name: @ (0) +# EXE-NEXT: Value: 0x0 +# EXE-NEXT: Size: 0 +# EXE-NEXT: Binding: Local (0x0) +# EXE-NEXT: Type: None (0x0) +# EXE-NEXT: Other: 0 +# EXE-NEXT: Section: Undefined (0x0) +# EXE-NEXT: } +# EXE-NEXT: Symbol { +# EXE-NEXT: Name: bar@ (1) +# EXE-NEXT: Value: 0x0 +# EXE-NEXT: Size: 0 +# EXE-NEXT: Binding: Global (0x1) +# EXE-NEXT: Type: Function (0x2) +# EXE-NEXT: Other: 0 +# EXE-NEXT: Section: Undefined (0x0) +# EXE-NEXT: } +# EXE-NEXT: Symbol { +# EXE-NEXT: Name: foo1@ (5) +# EXE-NEXT: Value: 0x11000 +# EXE-NEXT: Size: 0 +# EXE-NEXT: Binding: Global (0x1) +# EXE-NEXT: Type: None (0x0) +# EXE-NEXT: Other: 0 +# EXE-NEXT: Section: .text +# EXE-NEXT: } +# EXE-NEXT: ] + +# VERDSO: DynamicSymbols [ +# VERDSO-NEXT: Symbol { +# VERDSO-NEXT: Name: @ +# VERDSO-NEXT: Value: 0x0 +# VERDSO-NEXT: Size: 0 +# VERDSO-NEXT: Binding: Local +# VERDSO-NEXT: Type: None +# VERDSO-NEXT: Other: 0 +# VERDSO-NEXT: Section: Undefined +# VERDSO-NEXT: } +# VERDSO-NEXT: Symbol { +# VERDSO-NEXT: Name: bar@ +# VERDSO-NEXT: Value: 0x0 +# VERDSO-NEXT: Size: 0 +# VERDSO-NEXT: Binding: Global +# VERDSO-NEXT: Type: Function +# VERDSO-NEXT: Other: 0 +# VERDSO-NEXT: Section: Undefined +# VERDSO-NEXT: } +# VERDSO-NEXT: Symbol { +# VERDSO-NEXT: Name: foo1@@VERSION_1.0 +# VERDSO-NEXT: Value: 0x1000 +# VERDSO-NEXT: Size: 0 +# VERDSO-NEXT: Binding: Global +# VERDSO-NEXT: Type: None +# VERDSO-NEXT: Other: 0 +# VERDSO-NEXT: Section: .text +# VERDSO-NEXT: } +# VERDSO-NEXT: Symbol { +# VERDSO-NEXT: Name: foo3@@VERSION_2.0 +# VERDSO-NEXT: Value: 0x1007 +# VERDSO-NEXT: Size: 0 +# VERDSO-NEXT: Binding: Global +# VERDSO-NEXT: Type: None +# VERDSO-NEXT: Other: 0 +# VERDSO-NEXT: Section: .text +# VERDSO-NEXT: } +# VERDSO-NEXT: ] + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -shared %t.o %t2.so -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s + +# RUN: echo "{ global: foo1; foo3; };" > %t2.script +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld --version-script %t2.script -shared %t.o %t2.so -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s + +# ALL: DynamicSymbols [ +# ALL-NEXT: Symbol { +# ALL-NEXT: Name: @ +# ALL-NEXT: Value: 0x0 +# ALL-NEXT: Size: 0 +# ALL-NEXT: Binding: Local +# ALL-NEXT: Type: None +# ALL-NEXT: Other: 0 +# ALL-NEXT: Section: Undefined +# ALL-NEXT: } +# ALL-NEXT: Symbol { +# ALL-NEXT: Name: _start@ +# ALL-NEXT: Value: +# ALL-NEXT: Size: 0 +# ALL-NEXT: Binding: Global +# ALL-NEXT: Type: None +# ALL-NEXT: Other: 0 +# ALL-NEXT: Section: .text +# ALL-NEXT: } +# ALL-NEXT: Symbol { +# ALL-NEXT: Name: bar@ +# ALL-NEXT: Value: +# ALL-NEXT: Size: 0 +# ALL-NEXT: Binding: Global +# ALL-NEXT: Type: Function +# ALL-NEXT: Other: 0 +# ALL-NEXT: Section: Undefined +# ALL-NEXT: } +# ALL-NEXT: Symbol { +# ALL-NEXT: Name: foo1@ +# ALL-NEXT: Value: +# ALL-NEXT: Size: 0 +# ALL-NEXT: Binding: Global +# ALL-NEXT: Type: None +# ALL-NEXT: Other: 0 +# ALL-NEXT: Section: .text +# ALL-NEXT: } +# ALL-NEXT: Symbol { +# ALL-NEXT: Name: foo2@ +# ALL-NEXT: Value: +# ALL-NEXT: Size: 0 +# ALL-NEXT: Binding: Global +# ALL-NEXT: Type: None +# ALL-NEXT: Other: 0 +# ALL-NEXT: Section: .text +# ALL-NEXT: } +# ALL-NEXT: Symbol { +# ALL-NEXT: Name: foo3@ +# ALL-NEXT: Value: +# ALL-NEXT: Size: 0 +# ALL-NEXT: Binding: Global +# ALL-NEXT: Type: None +# ALL-NEXT: Other: 0 +# ALL-NEXT: Section: .text +# ALL-NEXT: } +# ALL-NEXT: ] + +.globl foo1 +foo1: + call bar@PLT + ret + +.globl foo2 +foo2: + ret + +.globl foo3 +foo3: + call foo2@PLT + ret + +.globl _start +_start: + ret diff --git a/test/ELF/version-undef-sym.s b/test/ELF/version-undef-sym.s new file mode 100644 index 000000000000..20e92e61f647 --- /dev/null +++ b/test/ELF/version-undef-sym.s @@ -0,0 +1,42 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-readobj --dyn-symbols %p/Inputs/version-undef-sym.so | FileCheck %s + + +// Inputs/version-undef-sym.so consists of the assembly file +// +// .global bar +// bar: +// .weak abc1 +// .weak abc2 +// .weak abc3 +// .weak abc4 +// .weak abc5 +// +// linked into a shared library with the version script +// +// VER_1 { +// global: +// bar; +// }; +// +// Assuming we can reproduce the desired property (a few undefined symbols +// before bar) we should create it with lld itself once it supports that. + + +// Show that the input .so has undefined symbols before bar. That is what would +// get our version parsing out of sync. + +// CHECK: Section: Undefined +// CHECK: Section: Undefined +// CHECK: Section: Undefined +// CHECK: Section: Undefined +// CHECK: Section: Undefined +// CHECK: Name: bar + +// But now we can successfully find bar. +// RUN: ld.lld %t.o %p/Inputs/version-undef-sym.so -o %t.exe + + .global _start +_start: + call bar@plt diff --git a/test/ELF/version-use.s b/test/ELF/version-use.s new file mode 100644 index 000000000000..7ef12bc04536 --- /dev/null +++ b/test/ELF/version-use.s @@ -0,0 +1,9 @@ +// REQUIRES: x86 +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o %p/Inputs/version-use.so -o %t.so -shared -z defs +// RUN: llvm-readobj -s %t.so | FileCheck %s + + + call bar@PLT + +// CHECK-NOT: SHT_GNU_versym diff --git a/test/ELF/version-wildcard.test b/test/ELF/version-wildcard.test new file mode 100644 index 000000000000..80cb9cadf159 --- /dev/null +++ b/test/ELF/version-wildcard.test @@ -0,0 +1,114 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "VERSION_1.0{ \ +# RUN: global: foo*; \ +# RUN: local: *; };" > %t.script +# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: @ +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo1@@VERSION_1.0 +# CHECK-NEXT: Value: 0x1000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo2@@VERSION_1.0 +# CHECK-NEXT: Value: 0x1001 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo3@@VERSION_1.0 +# CHECK-NEXT: Value: 0x1007 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK-NEXT: ] + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "VERSION_1.0{ \ +# RUN: global: foo2; \ +# RUN: local: *; }; \ +# RUN: VERSION_2.0{ \ +# RUN: global: foo*; \ +# RUN: }; " > %t2.script +# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so +# RUN: llvm-readobj -dyn-symbols %t2.so | FileCheck --check-prefix=MIX %s + +# MIX: DynamicSymbols [ +# MIX-NEXT: Symbol { +# MIX-NEXT: Name: @ +# MIX-NEXT: Value: 0x0 +# MIX-NEXT: Size: 0 +# MIX-NEXT: Binding: Local +# MIX-NEXT: Type: None +# MIX-NEXT: Other: 0 +# MIX-NEXT: Section: Undefined +# MIX-NEXT: } +# MIX-NEXT: Symbol { +# MIX-NEXT: Name: foo1@@VERSION_2.0 +# MIX-NEXT: Value: 0x1000 +# MIX-NEXT: Size: 0 +# MIX-NEXT: Binding: Global +# MIX-NEXT: Type: None +# MIX-NEXT: Other: 0 +# MIX-NEXT: Section: .text +# MIX-NEXT: } +# MIX-NEXT: Symbol { +# MIX-NEXT: Name: foo2@@VERSION_1.0 +# MIX-NEXT: Value: 0x1001 +# MIX-NEXT: Size: 0 +# MIX-NEXT: Binding: Global +# MIX-NEXT: Type: None +# MIX-NEXT: Other: 0 +# MIX-NEXT: Section: .text +# MIX-NEXT: } +# MIX-NEXT: Symbol { +# MIX-NEXT: Name: foo3@@VERSION_2.0 +# MIX-NEXT: Value: 0x1007 +# MIX-NEXT: Size: 0 +# MIX-NEXT: Binding: Global +# MIX-NEXT: Type: None +# MIX-NEXT: Other: 0 +# MIX-NEXT: Section: .text +# MIX-NEXT: } +# MIX-NEXT: ] + +.globl foo1 +foo1: + ret + +.globl foo2 +foo2: + call foo1@PLT + ret + +.globl foo3 +foo3: + call foo2@PLT + ret + +.globl _start +_start: + ret diff --git a/test/ELF/visibility.s b/test/ELF/visibility.s index d76ed0793eb1..2043894d3d3d 100644 --- a/test/ELF/visibility.s +++ b/test/ELF/visibility.s @@ -20,7 +20,9 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -29,7 +31,9 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 1 +// CHECK-NEXT: Other [ (0x1) +// CHECK-NEXT: STV_INTERNAL +// CHECK-NEXT: ] // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -38,10 +42,23 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _DYNAMIC +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Local +// CHECK-NEXT: Type: None +// CHECK-NEXT: Other [ (0x2) +// CHECK-NEXT: STV_HIDDEN +// CHECK-NEXT: ] +// CHECK-NEXT: Section: .dynamic +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: default // CHECK-NEXT: Value: // CHECK-NEXT: Size: 0 @@ -56,7 +73,9 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 3 +// CHECK-NEXT: Other [ (0x3) +// CHECK-NEXT: STV_PROTECTED +// CHECK-NEXT: ] // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: ] @@ -86,7 +105,9 @@ // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 3 +// CHECK-NEXT: Other [ (0x3) +// CHECK-NEXT: STV_PROTECTED +// CHECK-NEXT: ] // CHECK-NEXT: Section: .text // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/test/ELF/warn-common.s b/test/ELF/warn-common.s new file mode 100644 index 000000000000..783a9ab77b56 --- /dev/null +++ b/test/ELF/warn-common.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common.s -o %t2.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common2.s -o %t3.o + +## Report multiple commons if warn-common is specified +# RUN: ld.lld --warn-common %t1.o %t2.o -o %t.out 2>&1 | FileCheck %s --check-prefix=WARN +# WARN: multiple common of arr + +## no-warn-common is ignored +# RUN: ld.lld --no-warn-common %t1.o %t2.o -o %t.out +# RUN: llvm-readobj %t.out > /dev/null + +## Report if common is overridden +# RUN: ld.lld --warn-common %t1.o %t3.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER +# OVER: common arr is overridden + +## Report if common is overridden, but in different order +# RUN: ld.lld --warn-common %t3.o %t1.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER + +.globl _start +_start: + +.type arr,@object +.comm arr,4,4 diff --git a/test/ELF/weak-undef-hidden.s b/test/ELF/weak-undef-hidden.s new file mode 100644 index 000000000000..70b951bf0596 --- /dev/null +++ b/test/ELF/weak-undef-hidden.s @@ -0,0 +1,29 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s + +.data +.weak g +.hidden g +.quad g + +// CHECK: Name: .data +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_WRITE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 8 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 1 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00000000 00000000 +// CHECK-NEXT: ) + +// CHECK: Relocations [ +// CHECK-NEXT: ] diff --git a/test/ELF/weak-undef-shared.s b/test/ELF/weak-undef-shared.s new file mode 100644 index 000000000000..862a08632e26 --- /dev/null +++ b/test/ELF/weak-undef-shared.s @@ -0,0 +1,19 @@ +// REQUIRES: x86 +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: llvm-mc %p/Inputs/shared.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: ld.lld %t.o %t2.so -o %t.exe +// RUN: llvm-readobj -t %t.exe | FileCheck %s + +// CHECK: Name: bar +// CHECK-NEXT: Value: 0x11020 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Weak +// CHECK-NEXT: Type: Function +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: Undefined + +.global _start +_start: + .weak bar + .quad bar diff --git a/test/ELF/weak-undef.s b/test/ELF/weak-undef.s new file mode 100644 index 000000000000..02555535927e --- /dev/null +++ b/test/ELF/weak-undef.s @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t -pie +# RUN: llvm-readobj -dyn-symbols %t | FileCheck %s + +# CHECK: DynamicSymbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: @ (0) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local (0x0) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.weak foo + +.globl _start +_start: diff --git a/test/ELF/whole-archive.s b/test/ELF/whole-archive.s index 0a6b30fd171e..c65f116965f7 100644 --- a/test/ELF/whole-archive.s +++ b/test/ELF/whole-archive.s @@ -30,5 +30,11 @@ // RUN: ld.lld -o %t3 %t.o --whole-archive %t.a --no-whole-archive // RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s -.globl _start; +// --whole-archive should also work with thin archives +// RUN: rm -f %tthin.a +// RUN: llvm-ar --format=gnu rcsT %tthin.a %ta.o +// RUN: ld.lld -o %t3 %t.o --whole-archive %tthin.a +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s + +.globl _start _start: diff --git a/test/ELF/wildcards.s b/test/ELF/wildcards.s new file mode 100644 index 000000000000..2fe0f881bf46 --- /dev/null +++ b/test/ELF/wildcards.s @@ -0,0 +1,80 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +## Default case: abc and abx included in text. +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.abc .abx) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=SEC-DEFAULT %s +# SEC-DEFAULT: Sections: +# SEC-DEFAULT-NEXT: Idx Name Size Address Type +# SEC-DEFAULT-NEXT: 0 00000000 0000000000000000 +# SEC-DEFAULT-NEXT: 1 .text 00000008 0000000000000120 TEXT DATA +# SEC-DEFAULT-NEXT: 2 .abcd 00000004 0000000000000128 TEXT DATA +# SEC-DEFAULT-NEXT: 3 .ad 00000004 000000000000012c TEXT DATA +# SEC-DEFAULT-NEXT: 4 .ag 00000004 0000000000000130 TEXT DATA +# SEC-DEFAULT-NEXT: 5 .symtab 00000030 0000000000000000 +# SEC-DEFAULT-NEXT: 6 .shstrtab 0000002f 0000000000000000 +# SEC-DEFAULT-NEXT: 7 .strtab 00000008 0000000000000000 + +## Now replace the symbol with '?' and check that results are the same. +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.abc .ab?) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=SEC-DEFAULT %s + +## Now see how replacing '?' with '*' will consume whole abcd. +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.abc .ab*) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=SEC-ALL %s +# SEC-ALL: Sections: +# SEC-ALL-NEXT: Idx Name Size Address Type +# SEC-ALL-NEXT: 0 00000000 0000000000000000 +# SEC-ALL-NEXT: 1 .text 0000000c 0000000000000120 TEXT DATA +# SEC-ALL-NEXT: 2 .ad 00000004 000000000000012c TEXT DATA +# SEC-ALL-NEXT: 3 .ag 00000004 0000000000000130 TEXT DATA +# SEC-ALL-NEXT: 4 .symtab 00000030 0000000000000000 +# SEC-ALL-NEXT: 5 .shstrtab 00000029 0000000000000000 +# SEC-ALL-NEXT: 6 .strtab 00000008 0000000000000000 + +## All sections started with .a are merged. +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.a*) } }" > %t.script +# RUN: ld.lld -o %t.out --script %t.script %t +# RUN: llvm-objdump -section-headers %t.out | \ +# RUN: FileCheck -check-prefix=SEC-NO %s +# SEC-NO: Sections: +# SEC-NO-NEXT: Idx Name Size Address Type +# SEC-NO-NEXT: 0 00000000 0000000000000000 +# SEC-NO-NEXT: 1 .text 00000014 0000000000000120 TEXT DATA +# SEC-NO-NEXT: 2 .symtab 00000030 0000000000000000 +# SEC-NO-NEXT: 3 .shstrtab 00000021 0000000000000000 +# SEC-NO-NEXT: 4 .strtab 00000008 0000000000000000 + +.text +.section .abc,"ax",@progbits +.long 0 + +.text +.section .abx,"ax",@progbits +.long 0 + +.text +.section .abcd,"ax",@progbits +.long 0 + +.text +.section .ad,"ax",@progbits +.long 0 + +.text +.section .ag,"ax",@progbits +.long 0 + + +.globl _start +_start: diff --git a/test/ELF/writable-merge.s b/test/ELF/writable-merge.s index dd7b8538e57a..431cb6282d91 100644 --- a/test/ELF/writable-merge.s +++ b/test/ELF/writable-merge.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux // RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s -// CHECK: Writable SHF_MERGE sections are not supported +// CHECK: writable SHF_MERGE section is not supported - .section .foo,"awM",@progbits,4 +.section .foo,"awM",@progbits,4 diff --git a/test/ELF/x86-64-dyn-rel-error.s b/test/ELF/x86-64-dyn-rel-error.s new file mode 100644 index 000000000000..c814fbeb1d9a --- /dev/null +++ b/test/ELF/x86-64-dyn-rel-error.s @@ -0,0 +1,12 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o +// RUN: ld.lld %t2.o -shared -o %t2.so +// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s + + .global _start +_start: + .data + .long bar + +// CHECK: R_X86_64_32 cannot be used against shared object; recompile with -fPIC. diff --git a/test/ELF/x86-64-dyn-rel-error2.s b/test/ELF/x86-64-dyn-rel-error2.s new file mode 100644 index 000000000000..c1d3da3ae2ae --- /dev/null +++ b/test/ELF/x86-64-dyn-rel-error2.s @@ -0,0 +1,12 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o +// RUN: ld.lld %t2.o -shared -o %t2.so +// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s + + .global _start +_start: + .data + .long bar - . + +// CHECK: R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC. diff --git a/test/ELF/x86-64-rela.s b/test/ELF/x86-64-rela.s new file mode 100644 index 000000000000..41bdd76de4ca --- /dev/null +++ b/test/ELF/x86-64-rela.s @@ -0,0 +1,11 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -dynamic-table %t.so | FileCheck %s +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux-gnux32 %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -dynamic-table %t.so | FileCheck %s + + call foo@plt + +// CHECK: 0x{{0+}}14 PLTREL{{ +}}RELA diff --git a/test/ELF/x86-64-relax-offset.s b/test/ELF/x86-64-relax-offset.s new file mode 100644 index 000000000000..a7c7ce6f6271 --- /dev/null +++ b/test/ELF/x86-64-relax-offset.s @@ -0,0 +1,13 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %s \ +// RUN: -o %t.o +// RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux \ +// RUN: %p/Inputs/x86-64-relax-offset.s -o %t2.o +// RUN: ld.lld %t2.o %t.o -o %t.so -shared +// RUN: llvm-objdump -d %t.so | FileCheck %s + + mov foo@gotpcrel(%rip), %rax + nop + +// CHECK: 1004: {{.*}} leaq -11(%rip), %rax +// CHECK-NEXT: 100b: {{.*}} nop diff --git a/test/ELF/x86-64-reloc-32-fpic.s b/test/ELF/x86-64-reloc-32-fpic.s new file mode 100644 index 000000000000..0a0f1a09fda8 --- /dev/null +++ b/test/ELF/x86-64-reloc-32-fpic.s @@ -0,0 +1,7 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s +# CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC. + +.data +.long _shared diff --git a/test/ELF/x86-64-reloc-32S-error.s b/test/ELF/x86-64-reloc-32S-error.s deleted file mode 100644 index aa19c2c32e93..000000000000 --- a/test/ELF/x86-64-reloc-32S-error.s +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t -// RUN: not ld.lld -shared %t -o %t2 2>&1 | FileCheck %s -// REQUIRES: x86 - - movq _start - 0x1000000000000, %rdx - -#CHECK: R_X86_64_32S out of range diff --git a/test/ELF/x86-64-reloc-32-error.s b/test/ELF/x86-64-reloc-error.s index b5d476bcf082..9b7e17de793b 100644 --- a/test/ELF/x86-64-reloc-32-error.s +++ b/test/ELF/x86-64-reloc-error.s @@ -1,8 +1,10 @@ -// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/abs.s -o %tabs +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t // RUN: not ld.lld -shared %tabs %t -o %t2 2>&1 | FileCheck %s // REQUIRES: x86 movl $big, %edx + movq $foo - 0x1000000000000, %rdx -#CHECK: R_X86_64_32 out of range +# CHECK: R_X86_64_32 out of range +# CHECK: R_X86_64_32S out of range diff --git a/test/ELF/x86-64-reloc-pc32-fpic.s b/test/ELF/x86-64-reloc-pc32-fpic.s new file mode 100644 index 000000000000..ed9121583c18 --- /dev/null +++ b/test/ELF/x86-64-reloc-pc32-fpic.s @@ -0,0 +1,7 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s +# CHECK: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC. + +.data +call _shared diff --git a/test/ELF/x86-64-reloc-range.s b/test/ELF/x86-64-reloc-range.s new file mode 100644 index 000000000000..8319eaafa0ce --- /dev/null +++ b/test/ELF/x86-64-reloc-range.s @@ -0,0 +1,13 @@ +// RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj +// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s + +// CHECK: relocation R_X86_64_PC32 out of range +// CHECK-NOT: relocation + + lea foo(%rip), %rax + lea foo(%rip), %rax + + .hidden foo + .bss + .zero 0x7fffe007 +foo: diff --git a/test/ELF/x86-64-tls-gd-got.s b/test/ELF/x86-64-tls-gd-got.s new file mode 100644 index 000000000000..f86c3aa14f08 --- /dev/null +++ b/test/ELF/x86-64-tls-gd-got.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/x86-64-tls-gd-got.s -o %t2.o +# RUN: ld.lld %t1.o %t2.o -o %t +# RUN: llvm-objdump -d %t | FileCheck %s + + .globl _start +_start: + .byte 0x66 + leaq bar@tlsgd(%rip), %rdi + .byte 0x66 + rex64 + call *__tls_get_addr@GOTPCREL(%rip) + ret + +// CHECK: _start: +// CHECK-NEXT: movq %fs:0, %rax +// CHECK-NEXT: leaq -4(%rax), %rax +// CHECK-NEXT: retq diff --git a/test/ELF/x86-64-tls-gd-local.s b/test/ELF/x86-64-tls-gd-local.s new file mode 100644 index 000000000000..843b891be56b --- /dev/null +++ b/test/ELF/x86-64-tls-gd-local.s @@ -0,0 +1,52 @@ +// REQUIRES: x86 +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s + + .byte 0x66 + leaq foo@tlsgd(%rip), %rdi + .value 0x6666 + rex64 + call __tls_get_addr@PLT + + .byte 0x66 + leaq bar@tlsgd(%rip), %rdi + .value 0x6666 + rex64 + call __tls_get_addr@PLT + + .section .tbss,"awT",@nobits + + .hidden foo + .globl foo +foo: + .zero 4 + + .hidden bar + .globl bar +bar: + .zero 4 + + +// CHECK: Name: .got +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC (0x2) +// CHECK-NEXT: SHF_WRITE (0x1) +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x20D0 +// CHECK-NEXT: Offset: 0x20D0 +// CHECK-NEXT: Size: 32 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 8 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................| +// CHECK-NEXT: 0010: 00000000 00000000 04000000 00000000 |................| +// CHECK-NEXT: ) + +// CHECK: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x20D0 R_X86_64_DTPMOD64 - 0x0 +// CHECK-NEXT: 0x20E0 R_X86_64_DTPMOD64 - 0x0 +// CHECK-NEXT: } diff --git a/test/ELF/x86-64-tls-pie.s b/test/ELF/x86-64-tls-pie.s new file mode 100644 index 000000000000..5ef0f54f435d --- /dev/null +++ b/test/ELF/x86-64-tls-pie.s @@ -0,0 +1,26 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-cloudabi %s -o %t1.o +# RUN: ld.lld -pie %t1.o -o %t +# RUN: llvm-readobj -r %t | FileCheck %s + +# Bug 27174: R_X86_64_TPOFF32 and R_X86_64_GOTTPOFF relocations should +# be eliminated when building a PIE executable, as the static TLS layout +# is fixed. +# +# CHECK: Relocations [ +# CHECK-NEXT: ] + + .globl _start +_start: + movq %fs:0, %rax + movl $3, i@TPOFF(%rax) + + movq %fs:0, %rdx + movq i@GOTTPOFF(%rip), %rcx + movl $3, (%rdx,%rcx) + + .section .tbss.i,"awT",@nobits + .globl i +i: + .long 0 + .size i, 4 diff --git a/test/ELF/zdefs.s b/test/ELF/zdefs.s new file mode 100644 index 000000000000..410da1812db9 --- /dev/null +++ b/test/ELF/zdefs.s @@ -0,0 +1,7 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t1.so + +# RUN: not ld.lld -z defs -shared %t.o -o %t1.so 2>&1 | FileCheck -check-prefix=ERR %s +# ERR: undefined symbol: foo + +callq foo@PLT |