diff options
Diffstat (limited to 'test/ELF')
463 files changed, 9242 insertions, 854 deletions
diff --git a/test/ELF/Inputs/amdgpu-kernel-0.s b/test/ELF/Inputs/amdgpu-kernel-0.s new file mode 100644 index 000000000000..1567c3fda10f --- /dev/null +++ b/test/ELF/Inputs/amdgpu-kernel-0.s @@ -0,0 +1,6 @@ +.text +.globl kernel_0 +.align 64 +.amdgpu_hsa_kernel kernel_0 +kernel_0: + s_endpgm diff --git a/test/ELF/Inputs/amdgpu-kernel-1.s b/test/ELF/Inputs/amdgpu-kernel-1.s new file mode 100644 index 000000000000..7fb520bfbe32 --- /dev/null +++ b/test/ELF/Inputs/amdgpu-kernel-1.s @@ -0,0 +1,6 @@ +.text +.globl kernel_1 +.align 64 +.amdgpu_hsa_kernel kernel_1 +kernel_1: + s_endpgm diff --git a/test/ELF/Inputs/amdgpu-kernel-2.o b/test/ELF/Inputs/amdgpu-kernel-2.o Binary files differnew file mode 100644 index 000000000000..fa76151f8976 --- /dev/null +++ b/test/ELF/Inputs/amdgpu-kernel-2.o diff --git a/test/ELF/Inputs/copy-rel-abs.s b/test/ELF/Inputs/copy-rel-abs.s new file mode 100644 index 000000000000..66d08807b9c9 --- /dev/null +++ b/test/ELF/Inputs/copy-rel-abs.s @@ -0,0 +1,13 @@ + .global foo + .type foo, @object + .size foo, 4 +foo: + .weak bar + .type bar, @object + .size bar, 4 +bar: + .long 42 + + .weak zed + .type zed, @object + zed = 0x1000 diff --git a/test/ELF/Inputs/copy-rel-large.s b/test/ELF/Inputs/copy-rel-large.s new file mode 100644 index 000000000000..8786a2fa1a3f --- /dev/null +++ b/test/ELF/Inputs/copy-rel-large.s @@ -0,0 +1,4 @@ + .global foo + .type foo, @object +foo: + .size foo, 0x100000001 diff --git a/test/ELF/Inputs/copy-rel-pie.s b/test/ELF/Inputs/copy-rel-pie.s index 6dac01ddec62..b3345ceea672 100644 --- a/test/ELF/Inputs/copy-rel-pie.s +++ b/test/ELF/Inputs/copy-rel-pie.s @@ -9,3 +9,4 @@ foo: .global bar .type bar, @function bar: +retq diff --git a/test/ELF/Inputs/corrupt-version-reference.so b/test/ELF/Inputs/corrupt-version-reference.so Binary files differnew file mode 100644 index 000000000000..ef6adc6a026c --- /dev/null +++ b/test/ELF/Inputs/corrupt-version-reference.so diff --git a/test/ELF/Inputs/dynamic-list-weak-archive.s b/test/ELF/Inputs/dynamic-list-weak-archive.s new file mode 100644 index 000000000000..dd28fcbd5255 --- /dev/null +++ b/test/ELF/Inputs/dynamic-list-weak-archive.s @@ -0,0 +1,2 @@ +.globl foo +foo: diff --git a/test/ELF/Inputs/eh-frame.s b/test/ELF/Inputs/eh-frame.s new file mode 100644 index 000000000000..0aa4008b7b2c --- /dev/null +++ b/test/ELF/Inputs/eh-frame.s @@ -0,0 +1,3 @@ +.cfi_startproc +.cfi_def_cfa_offset 32 +.cfi_endproc diff --git a/test/ELF/Inputs/gc-sections-shared.s b/test/ELF/Inputs/gc-sections-shared.s new file mode 100644 index 000000000000..e7017f566411 --- /dev/null +++ b/test/ELF/Inputs/gc-sections-shared.s @@ -0,0 +1,3 @@ +.global baz +.type baz, @function +baz: diff --git a/test/ELF/Inputs/gc-sections-shared2.s b/test/ELF/Inputs/gc-sections-shared2.s new file mode 100644 index 000000000000..fb69c0e218fb --- /dev/null +++ b/test/ELF/Inputs/gc-sections-shared2.s @@ -0,0 +1,3 @@ +.global qux +.type qux, @function +qux: diff --git a/test/ELF/Inputs/local-symbol-in-dso.so b/test/ELF/Inputs/local-symbol-in-dso.so Binary files differnew file mode 100755 index 000000000000..5062a7aeead2 --- /dev/null +++ b/test/ELF/Inputs/local-symbol-in-dso.so diff --git a/test/ELF/Inputs/map-file5.s b/test/ELF/Inputs/map-file5.s new file mode 100644 index 000000000000..2a89b4c7f6f5 --- /dev/null +++ b/test/ELF/Inputs/map-file5.s @@ -0,0 +1,23 @@ +.bss +.type sharedFoo,@object +.globl sharedFoo +sharedFoo: +.long 0 +.size sharedFoo, 4 + +.type sharedBar,@object +.globl sharedBar +sharedBar: +.quad 0 +.size sharedBar, 8 + +.text +.globl sharedFunc1 +.type sharedFunc1,@function +sharedFunc1: + nop + +.globl sharedFunc2 +.type sharedFunc2,@function +sharedFunc2: + nop diff --git a/test/ELF/Inputs/mips-micro.s b/test/ELF/Inputs/mips-micro.s new file mode 100644 index 000000000000..0d0b11f6fdb2 --- /dev/null +++ b/test/ELF/Inputs/mips-micro.s @@ -0,0 +1,12 @@ + .text + .set micromips + .global foo + .type foo,@function +foo: + nop + + .set nomicromips + .global bar + .type bar,@function +bar: + nop diff --git a/test/ELF/Inputs/shared3.s b/test/ELF/Inputs/shared3.s index d1f6ffea1332..e7017f566411 100644 --- a/test/ELF/Inputs/shared3.s +++ b/test/ELF/Inputs/shared3.s @@ -1,3 +1,3 @@ .global baz -.type barz, @function +.type baz, @function baz: diff --git a/test/ELF/Inputs/undefined-error.s b/test/ELF/Inputs/undefined-error.s new file mode 100644 index 000000000000..84ac4f121361 --- /dev/null +++ b/test/ELF/Inputs/undefined-error.s @@ -0,0 +1 @@ +callq fmod@PLT diff --git a/test/ELF/Inputs/verdef-defaultver.s b/test/ELF/Inputs/verdef-defaultver.s index 6664d62c90f5..d9e7f3829f32 100644 --- a/test/ELF/Inputs/verdef-defaultver.s +++ b/test/ELF/Inputs/verdef-defaultver.s @@ -1,4 +1,7 @@ +.global b@V1 b@V1 = b_1 + +.global b@@V2 b@@V2 = b_2 .globl a diff --git a/test/ELF/Inputs/verneed.so.sh b/test/ELF/Inputs/verneed.so.sh deleted file mode 100755 index 3423f678e47a..000000000000 --- a/test/ELF/Inputs/verneed.so.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/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/verneed1.s b/test/ELF/Inputs/verneed1.s new file mode 100644 index 000000000000..a342d7dd797f --- /dev/null +++ b/test/ELF/Inputs/verneed1.s @@ -0,0 +1,32 @@ +.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 diff --git a/test/ELF/Inputs/verneed1.so b/test/ELF/Inputs/verneed1.so Binary files differdeleted file mode 100755 index 744852b9660a..000000000000 --- a/test/ELF/Inputs/verneed1.so +++ /dev/null diff --git a/test/ELF/Inputs/verneed2.s b/test/ELF/Inputs/verneed2.s new file mode 100644 index 000000000000..1b46de6880b1 --- /dev/null +++ b/test/ELF/Inputs/verneed2.s @@ -0,0 +1,5 @@ +.globl g1_v1 +g1_v1: +ret + +.symver g1_v1, g1@@v1 diff --git a/test/ELF/Inputs/verneed2.so b/test/ELF/Inputs/verneed2.so Binary files differdeleted file mode 100755 index ba6c05ee6b1c..000000000000 --- a/test/ELF/Inputs/verneed2.so +++ /dev/null diff --git a/test/ELF/Inputs/weak-undef-lazy.s b/test/ELF/Inputs/weak-undef-lazy.s new file mode 100644 index 000000000000..c77477315156 --- /dev/null +++ b/test/ELF/Inputs/weak-undef-lazy.s @@ -0,0 +1,3 @@ +.global foobar +foobar: + nop diff --git a/test/ELF/Inputs/wrap-no-real.s b/test/ELF/Inputs/wrap-no-real.s new file mode 100644 index 000000000000..2fd1bcc6bc29 --- /dev/null +++ b/test/ELF/Inputs/wrap-no-real.s @@ -0,0 +1,3 @@ +.globl foo, __wrap_foo +foo = 0x11000 +__wrap_foo = 0x11010 diff --git a/test/ELF/Inputs/wrap-no-real2.s b/test/ELF/Inputs/wrap-no-real2.s new file mode 100644 index 000000000000..dbcb0889b965 --- /dev/null +++ b/test/ELF/Inputs/wrap-no-real2.s @@ -0,0 +1,2 @@ +.globl __real_foo +__real_foo = 0x11020 diff --git a/test/ELF/Inputs/wrap.s b/test/ELF/Inputs/wrap.s index 584e27033d5c..e0765196606b 100644 --- a/test/ELF/Inputs/wrap.s +++ b/test/ELF/Inputs/wrap.s @@ -1,4 +1,7 @@ -.globl foo, __wrap_foo, __real_foo +.global foo +.weak __wrap_foo +.protected __wrap_foo +.global __real_foo foo = 0x11000 __wrap_foo = 0x11010 __real_foo = 0x11020 diff --git a/test/ELF/aarch64-abs16.s b/test/ELF/aarch64-abs16.s index c4f5b3e44b58..20a65b1cf4a8 100644 --- a/test/ELF/aarch64-abs16.s +++ b/test/ELF/aarch64-abs16.s @@ -24,4 +24,4 @@ _start: // | FileCheck %s --check-prefix=OVERFLOW // RUN: not ld.lld %t.o %t257.o -o %t2 // | FileCheck %s --check-prefix=OVERFLOW -// OVERFLOW: Relocation R_AARCH64_ABS16 out of range +// OVERFLOW: Relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535] diff --git a/test/ELF/aarch64-abs32.s b/test/ELF/aarch64-abs32.s index b051692374b1..b93f27a0bc4b 100644 --- a/test/ELF/aarch64-abs32.s +++ b/test/ELF/aarch64-abs32.s @@ -24,4 +24,4 @@ _start: // | FileCheck %s --check-prefix=OVERFLOW // RUN: not ld.lld %t.o %t257.o -o %t2 // | FileCheck %s --check-prefix=OVERFLOW -// OVERFLOW: Relocation R_AARCH64_ABS32 out of range +// OVERFLOW: Relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295] diff --git a/test/ELF/aarch64-call26-error.s b/test/ELF/aarch64-call26-error.s deleted file mode 100644 index 4b666c69011a..000000000000 --- a/test/ELF/aarch64-call26-error.s +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs -// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t -// RUN: not ld.lld %t %tabs -o %t2 2>&1 | FileCheck %s -// REQUIRES: aarch64 - -.text -.globl _start -_start: - bl big - -// CHECK: R_AARCH64_CALL26 out of range diff --git a/test/ELF/aarch64-call26-thunk.s b/test/ELF/aarch64-call26-thunk.s new file mode 100644 index 000000000000..0fe99cec974d --- /dev/null +++ b/test/ELF/aarch64-call26-thunk.s @@ -0,0 +1,21 @@ +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t +// RUN: ld.lld %t %tabs -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s +// REQUIRES: aarch64 + +.text +.globl _start +_start: + bl big + +// CHECK: Disassembly of section .text: +// CHECK-NEXT: _start: +// CHECK-NEXT: 20000: 02 00 00 94 bl #8 +// CHECK: __AArch64AbsLongThunk_big: +// CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #8 +// CHECK-NEXT: 2000c: 00 02 1f d6 br x16 +// CHECK: $d: +// CHECK-NEXT: 20010: 00 00 00 00 .word 0x00000000 +// CHECK-NEXT: 20014: 10 00 00 00 .word 0x00000010 + diff --git a/test/ELF/aarch64-cortex-a53-843419-address.s b/test/ELF/aarch64-cortex-a53-843419-address.s new file mode 100644 index 000000000000..e9f6ff4c38db --- /dev/null +++ b/test/ELF/aarch64-cortex-a53-843419-address.s @@ -0,0 +1,180 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: echo "SECTIONS { \ +// RUN: .text : { *(.text) *(.text.*) *(.newisd) } \ +// RUN: .text2 : { *.(newos) } \ +// RUN: .data : { *(.data) } }" > %t.script +// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix=CHECK-PRINT %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s + +// Test cases for Cortex-A53 Erratum 843419 that involve interactions +// between the generated patches and the address of sections. + +// See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf +// for full erratum details. +// In Summary +// 1.) +// ADRP (0xff8 or 0xffc). +// 2.) +// - load or store single register or either integer or vector registers. +// - STP or STNP of either vector or vector registers. +// - Advanced SIMD ST1 store instruction. +// - Must not write Rn. +// 3.) optional instruction, can't be a branch, must not write Rn, may read Rn. +// 4.) A load or store instruction from the Load/Store register unsigned +// immediate class using Rn as the base register. + +// An aarch64 section can contain ranges of literal data embedded within the +// code, these ranges are encoded with mapping symbols. This tests that we +// can match the erratum sequence in code, but not data. +// - We can handle more than one patch per code range (denoted by mapping +// symbols). +// - We can handle a patch in more than range of code, with literal data +// inbetween. +// - We can handle redundant mapping symbols (two or more consecutive mapping +// symbols with the same type). +// - We can ignore erratum sequences in multiple literal data ranges. + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at FF8 in unpatched output. +// CHECK: t3_ff8_ldr: +// CHECK-NEXT: ff8: 20 00 00 d0 adrp x0, #24576 +// CHECK-NEXT: ffc: 21 00 40 f9 ldr x1, [x1] +// CHECK-NEXT: 1000: f9 0f 00 14 b #16356 +// CHECK-NEXT: 1004: c0 03 5f d6 ret + .section .text.01, "ax", %progbits + .balign 4096 + .space 4096 - 8 + .globl t3_ff8_ldr + .type t3_ff8_ldr, %function +t3_ff8_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + // create a redundant mapping symbol as we are already in a $x range + // some object producers unconditionally generate a mapping symbol on + // every symbol so we need to handle the case of $x $x. + .local $x.999 +$x.999: +// CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 1FFC in unpatched output. +// CHECK: t3_ffc_ldrsimd: +// CHECK-NEXT: 1ffc: 20 00 00 b0 adrp x0, #20480 +// CHECK-NEXT: 2000: 21 00 40 bd ldr s1, [x1] +// CHECK-NEXT: 2004: fa 0b 00 14 b #12264 +// CHECK-NEXT: 2008: c0 03 5f d6 ret + .globl t3_ffc_ldrsimd + .type t3_ffc_ldrsimd, %function + .space 4096 - 12 +t3_ffc_ldrsimd: + adrp x0, dat + ldr s1, [x1, #0] + ldr x2, [x0, :got_lo12:dat] + ret + +// Inline data containing bit pattern of erratum sequence, expect no patch. + .globl t3_ffc_ldralldata + .type t3_ff8_ldralldata, %function + .space 4096 - 20 +t3_ff8_ldralldata: + // 0x90000000 = adrp x0, #0 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x90 + // 0xf9400021 = ldr x1, [x1] + .byte 0x21 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + // 0xf9400000 = ldr x0, [x0] + .byte 0x00 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + // Check that we can recognise the erratum sequence post literal data. + +// CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 3FF8 in unpatched output. +// CHECK: t3_ffc_ldr: +// CHECK-NEXT: 3ff8: 00 00 00 f0 adrp x0, #12288 +// CHECK-NEXT: 3ffc: 21 00 40 f9 ldr x1, [x1] +// CHECK-NEXT: 4000: fd 03 00 14 b #4084 +// CHECK-NEXT: 4004: c0 03 5f d6 ret + .space 4096 - 12 + .globl t3_ffc_ldr + .type t3_ffc_ldr, %function + t3_ffc_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + +// CHECK: __CortexA53843419_1000: +// CHECK-NEXT: 4fe4: 00 0c 40 f9 ldr x0, [x0, #24] +// CHECK-NEXT: 4fe8: 07 f0 ff 17 b #-16356 +// CHECK: __CortexA53843419_2004: +// CHECK-NEXT: 4fec: 02 0c 40 f9 ldr x2, [x0, #24] +// CHECK-NEXT: 4ff0: 06 f4 ff 17 b #-12264 +// CHECK: __CortexA53843419_4000: +// CHECK-NEXT: 4ff4: 00 0c 40 f9 ldr x0, [x0, #24] +// CHECK-NEXT: 4ff8: 03 fc ff 17 b #-4084 + + .section .text.02, "ax", %progbits + .space 4096 - 36 + + // Start a new InputSectionDescription (see Linker Script) so the + // start address will be affected by any patches added to previous + // InputSectionDescription. + +// CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 4FFC in unpatched output +// CHECK: t3_ffc_str: +// CHECK-NEXT: 4ffc: 00 00 00 d0 adrp x0, #8192 +// CHECK-NEXT: 5000: 21 00 00 f9 str x1, [x1] +// CHECK-NEXT: 5004: fb 03 00 14 b #4076 +// CHECK-NEXT: 5008: c0 03 5f d6 ret + + .section .newisd, "ax", %progbits + .globl t3_ffc_str + .type t3_ffc_str, %function +t3_ffc_str: + adrp x0, dat + str x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + .space 4096 - 28 + +// CHECK: __CortexA53843419_5004: +// CHECK-NEXT: 5ff0: 00 0c 40 f9 ldr x0, [x0, #24] +// CHECK-NEXT: 5ff4: 05 fc ff 17 b #-4076 + + // Start a new OutputSection (see Linker Script) so the + // start address will be affected by any patches added to previous + // InputSectionDescription. + +//CHECK-PRINT-NEXT: detected cortex-a53-843419 erratum sequence starting at 5FF8 in unpatched output +// CHECK: t3_ff8_str: +// CHECK-NEXT: 5ff8: 00 00 00 b0 adrp x0, #4096 +// CHECK-NEXT: 5ffc: 21 00 00 f9 str x1, [x1] +// CHECK-NEXT: 6000: 03 00 00 14 b #12 +// CHECK-NEXT: 6004: c0 03 5f d6 ret + + .section .newos, "ax", %progbits + .globl t3_ff8_str + .type t3_ff8_str, %function +t3_ff8_str: + adrp x0, dat + str x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + .globl _start + .type _start, %function +_start: + ret + +// CHECK: __CortexA53843419_6000: +// CHECK-NEXT: 600c: 00 0c 40 f9 ldr x0, [x0, #24] +// CHECK-NEXT: 6010: fd ff ff 17 b #-12 + + .data + .globl dat +dat: .word 0 diff --git a/test/ELF/aarch64-cortex-a53-843419-cli.s b/test/ELF/aarch64-cortex-a53-843419-cli.s new file mode 100644 index 000000000000..30abc8f06d20 --- /dev/null +++ b/test/ELF/aarch64-cortex-a53-843419-cli.s @@ -0,0 +1,10 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: not ld.lld %t -fix-cortex-a53-843419 -o %t2 2>&1 | FileCheck %s + +// CHECK: --fix-cortex-a53-843419 is only supported on AArch64 targets. +.globl entry +.text + .quad 0 +entry: + ret diff --git a/test/ELF/aarch64-cortex-a53-843419-large.s b/test/ELF/aarch64-cortex-a53-843419-large.s new file mode 100644 index 000000000000..00c92ebeb182 --- /dev/null +++ b/test/ELF/aarch64-cortex-a53-843419-large.s @@ -0,0 +1,115 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: ld.lld --fix-cortex-a53-843419 %t.o -o %t2 +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=131072 -stop-address=131084 | FileCheck --check-prefix=CHECK1 %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=135168 -stop-address=135172 | FileCheck --check-prefix=CHECK2 %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=139256 -stop-address=139272 | FileCheck --check-prefix=CHECK3 %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=67256312 -stop-address=67256328 | FileCheck --check-prefix=CHECK4 %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=100810760 -stop-address=100810776 | FileCheck --check-prefix=CHECK5 %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134352908 -stop-address=134352912 | FileCheck --check-prefix=CHECK6 %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 -start-address=134356988 -stop-address=134357012 | FileCheck --check-prefix=CHECK7 %s +// Test case for Cortex-A53 Erratum 843419 in an OutputSection exceeding +// the maximum branch range. Both range extension thunks and patches are +// required. + +// CHECK1: __AArch64AbsLongThunk_need_thunk_after_patch: +// CHECK1-NEXT: 20000: 50 00 00 58 ldr x16, #8 +// CHECK1-NEXT: 20004: 00 02 1f d6 br x16 +// CHECK1: $d: +// CHECK1-NEXT: 20008: 0c 10 02 08 .word 0x0802100c + + .section .text.01, "ax", %progbits + .balign 4096 + .globl _start + .type _start, %function +_start: + // Expect thunk on pass 2 + bl need_thunk_after_patch + .section .text.02, "ax", %progbits + .space 4096 - 12 + +// CHECK2: _start: +// CHECK2-NEXT: 21000: 00 fc ff 97 bl #-4096 + + // Expect patch on pass 1 + .section .text.03, "ax", %progbits + .globl t3_ff8_ldr + .type t3_ff8_ldr, %function +t3_ff8_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + +// CHECK3: t3_ff8_ldr: +// CHECK3-NEXT: 21ff8: 60 00 04 f0 adrp x0, #134279168 +// CHECK3-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1] +// CHECK3-NEXT: 22000: 02 08 80 15 b #100671496 +// CHECK3-NEXT: 22004: c0 03 5f d6 ret + + .section .text.04, "ax", %progbits + .space 64 * 1024 * 1024 + + // Expect patch on pass 1 + .section .text.05, "ax", %progbits + .balign 4096 + .space 4096 - 8 + .globl t3_ff8_str + .type t3_ff8_str, %function +t3_ff8_str: + adrp x0, dat + ldr x1, [x1, #0] + str x0, [x0, :got_lo12:dat] + ret + +// CHECK4: t3_ff8_str: +// CHECK4-NEXT: 4023ff8: 60 00 02 b0 adrp x0, #67162112 +// CHECK4-NEXT: 4023ffc: 21 00 40 f9 ldr x1, [x1] +// CHECK4-NEXT: 4024000: 04 00 80 14 b #33554448 +// CHECK4-NEXT: 4024004: c0 03 5f d6 ret + + .section .text.06, "ax", %progbits + .space 32 * 1024 * 1024 + +// CHECK5: __CortexA53843419_21000: +// CHECK5-NEXT: 6024008: 00 00 40 f9 ldr x0, [x0] +// CHECK5-NEXT: 602400c: fe f7 7f 16 b #-100671496 +// CHECK5: __CortexA53843419_4023000: +// CHECK5-NEXT: 6024010: 00 00 00 f9 str x0, [x0] +// CHECK5-NEXT: 6024014: fc ff 7f 17 b #-33554448 + + .section .text.07, "ax", %progbits + .space (32 * 1024 * 1024) - 12300 + + .section .text.08, "ax", %progbits + .globl need_thunk_after_patch + .type need_thunk_after_patch, %function +need_thunk_after_patch: + ret + +// CHECK6: need_thunk_after_patch: +// CHECK6-NEXT: 802100c: c0 03 5f d6 ret + + // Will need a patch on pass 2 + .section .text.09, "ax", %progbits + .space 4096 - 20 + .globl t3_ffc_ldr + .type t3_ffc_ldr, %function +t3_ffc_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + +// CHECK7: t3_ffc_ldr: +// CHECK7-NEXT: 8021ffc: 60 00 00 f0 adrp x0, #61440 +// CHECK7-NEXT: 8022000: 21 00 40 f9 ldr x1, [x1] +// CHECK7-NEXT: 8022004: 02 00 00 14 b #8 +// CHECK7-NEXT: 8022008: c0 03 5f d6 ret +// CHECK7: __CortexA53843419_8022004: +// CHECK7-NEXT: 802200c: 00 00 40 f9 ldr x0, [x0] +// CHECK7-NEXT: 8022010: fe ff ff 17 b #-8 + + .section .data + .globl dat +dat: .quad 0 diff --git a/test/ELF/aarch64-cortex-a53-843419-nopatch.s b/test/ELF/aarch64-cortex-a53-843419-nopatch.s new file mode 100644 index 000000000000..389bf4505735 --- /dev/null +++ b/test/ELF/aarch64-cortex-a53-843419-nopatch.s @@ -0,0 +1,338 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: ld.lld -fix-cortex-a53-843419 -verbose -t %t.o -o %t2 | FileCheck %s +// Test cases for Cortex-A53 Erratum 843419 that we don't expect to recognize +// as needing a patch as one or more of the conditions isn't satisfied. +// See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf +// for full erratum details. +// In Summary +// 1.) +// ADRP (0xff8 or 0xffc) +// 2.) +// - load or store single register or either integer or vector registers +// - STP or STNP of either vector or vector registers +// - Advanced SIMD ST1 store instruction +// Must not write Rn +// 3.) optional instruction, can't be a branch, must not write Rn, may read Rn +// 4.) A load or store instruction from the Load/Store register unsigned +// immediate class using Rn as the base register + +// Expect no patches detected. +// CHECK-NOT: detected cortex-a53-843419 erratum sequence + +// erratum sequence but adrp (address & 0xfff) is not 0xff8 or 0xffc + .section .text.01, "ax", %progbits + .balign 4096 + .globl t3_0_ldr + .type t3_ff8_ldr, %function +t3_0_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + .section .text.02, "ax", %progbits + .balign 4096 + .globl t3_ff4_ldr + .space 4096 - 12 + .type t3_ff4_ldr, %function +t3_ff4_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + +// Close matches for erratum sequence, with adrp at correct address but +// instruction 2 is a load or store but not one that matches the erratum +// conditions, but with a similar encoding to an instruction that does. + + // ldp is not part of sequence, although stp is. + .section .text.03, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldp + .type t3_ff8_ldp, %function + .space 4096 - 8 +t3_ff8_ldp: + adrp x16, dat + ldp x1,x2, [x3, #0] + ldr x13, [x16, :got_lo12:dat] + ret + + // st2 is not part of sequence although st1 is. + .section .text.04, "ax", %progbits + .balign 4096 + .globl t3_ffc_st2 + .type t3_ffc_st2, %function + .space 4096 - 4 +t3_ffc_st2: + adrp x16, dat + st2 { v0.16b, v1.16b }, [x1] + ldr x13, [x16, :got_lo12:dat] + ret + + // st3 is not part of sequence although st1 is. + .section .text.05, "ax", %progbits + .balign 4096 + .globl t3_ffc_st3 + .type t3_ffc_st3, %function + .space 4096 - 4 +t3_ffc_st3: + adrp x16, dat + st3 { v0.16b, v1.16b, v2.16b }, [x1], x2 + ldr x13, [x16, :got_lo12:dat] + ret + + // ld1 is not part of sequence although st1 is. + .section .text.06, "ax", %progbits + .balign 4096 + .globl t3_ffc_ld2 + .type t3_ffc_st3, %function + .space 4096 - 4 +t3_ffc_ld1: + adrp x16, dat + ld1 { v0.16b }, [x2], x3 + ldr x13, [x16, :got_lo12:dat] + ret + + // ldnp is not part of sequence although stnp is. + .section .text.07, "ax", %progbits + .balign 4096 + .globl t4_ff8_ldnp + .type t4_ff8_ldnp, %function + .space 4096 - 8 +t4_ff8_ldnp: + adrp x7, dat + ldnp x1,x2, [x3, #0] + nop + ldr x10, [x7, :got_lo12:dat] + ret + +// Close match for erratum sequence, with adrp at correct address but +// instruction 2 writes to Rn, with Rn as either destination or as the +// transfer register but with writeback. + + // ldr instruction writes to Rn + .section .text.08, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldr + .type t3_ff8_ldr, %function + .space 4096 - 8 +t3_ff8_ldr: + adrp x0, dat + ldr x0, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + // str instruction writes to Rn via writeback (pre index) + .section .text.09, "ax", %progbits + .balign 4096 + .globl t3_ff8_str + .type t3_ff8_str, %function + .space 4096 - 8 +t3_ff8_str: + adrp x0, dat + str x1, [x0, #4]! + ldr x0, [x0, :got_lo12:dat] + ret + + // ldr instruction writes to Rn via writeback (post index) + .section .text.09, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldr + .type t3_ffc_ldr, %function + .space 4096 - 8 +t3_ffc_ldr: + adrp x0, dat + ldr x1, [x0], 0x8 + ldr x0, [x0, :got_lo12:dat] + ret + + // stp writes to Rn via writeback (pre index) + .section .text.10, "ax", %progbits + .balign 4096 + .globl t4_ffc_stppre + .type t4_ffc_stppre, %function + .space 4096 - 4 +t4_ffc_stppre: + adrp x16, dat + stp x1,x2, [x16, #16]! + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + + // stp writes to Rn via writeback (post index) + .section .text.11, "ax", %progbits + .balign 4096 + .globl t4_ff8_stppost + .type t4_ff8_stppost, %function + .space 4096 - 8 +t4_ff8_stppost: + adrp x16, dat + stp x1,x2, [x16], #16 + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + + // st1 writes to Rn via writeback + .section .text.12, "ax", %progbits + .balign 4096 + .globl t3_ff8_st1 + .type t3_ff8_st1, %function + .space 4096 - 8 +t3_ff8_st1: + adrp x16, dat + st1 { v0.16b}, [x16], x2 + ldr x13, [x16, :got_lo12:dat] + ret + +// Close match for erratum sequence, but with optional instruction 3 a branch + + // function call via immediate + .section .text.13, "ax", %progbits + .balign 4096 + .globl t4_ffc_blimm + .type t4_ffc_blimm, %function + .space 4096 - 4 +t4_ffc_blimm: + adrp x7, dat + stnp x1,x2, [x3, #0] + bl t4_ffc_blimm + ldr x10, [x7, :got_lo12:dat] + ret + + // function call via register + .section .text.14, "ax", %progbits + .balign 4096 + .globl t4_ffc_blreg + .type t4_ffc_blreg, %function + .space 4096 - 4 +t4_ffc_blreg: + adrp x7, dat + stnp x1,x2, [x3, #0] + blr x4 + ldr x10, [x7, :got_lo12:dat] + ret + + // Unconditional branch immediate + .section .text.15, "ax", %progbits + .balign 4096 + .globl t4_ffc_branchimm + .type t4_ffc_branchimm, %function + .space 4096 - 4 +t4_ffc_branchimm: + adrp x7, dat + stnp x1,x2, [x3, #0] + b t4_ffc_branchimm + ldr x10, [x7, :got_lo12:dat] + ret + + // Unconditional branch register + .section .text.16, "ax", %progbits + .balign 4096 + .globl t4_ffc_branchreg + .type t4_ffc_branchreg, %function + .space 4096 - 4 +t4_ffc_branchreg: + adrp x7, dat + stnp x1,x2, [x3, #0] + br x4 + ldr x10, [x7, :got_lo12:dat] + ret + + // Conditional branch + .section .text.17, "ax", %progbits + .balign 4096 + .globl t4_ffc_branchcond + .type t4_ffc_branchcond, %function + .space 4096 - 4 +t4_ffc_branchcond: + adrp x7, dat + stnp x1,x2, [x3, #0] + cbz x5, t4_ffc_branchcond + ldr x10, [x7, :got_lo12:dat] + ret + + // Conditional branch immediate + .section .text.18, "ax", %progbits + .balign 4096 + .globl t4_ffc_branchcondimm + .type t4_ffc_branchcondimm, %function + .space 4096 - 4 +t4_ffc_branchcondimm: + adrp x7, dat + stnp x1,x2, [x3, #0] + beq t4_ffc_branchcondimm + ldr x10, [x7, :got_lo12:dat] + ret + +// Bitpattern matches erratum sequence but either all or part of the sequence +// is in inline literal data + .section .text.19, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldrtraildata + .type t3_ff8_ldrtraildata, %function + .space 4096 - 8 +t3_ff8_ldrtraildata: + adrp x0, dat + ldr x1, [x1, #0] + // 0xf9400000 = ldr x0, [x0] + .byte 0x00 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + ldr x0, [x0, :got_lo12:dat] + ret + + .section .text.20, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldrpredata + .type t3_ff8_ldrpredata, %function + .space 4096 - 8 +t3_ff8_ldrpredata: + // 0x90000000 = adrp x0, #0 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x90 + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + + .section .text.21, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldralldata + .type t3_ff8_ldralldata, %function + .space 4096 - 8 +t3_ff8_ldralldata: + // 0x90000000 = adrp x0, #0 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x90 + // 0xf9400021 = ldr x1, [x1] + .byte 0x21 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + // 0xf9400000 = ldr x0, [x0] + .byte 0x00 + .byte 0x00 + .byte 0x40 + .byte 0xf9 + + ret + + .text + .globl _start + .type _start, %function +_start: + ret + + + + + +// Bitpattern matches erratum sequence but section is not executable + .data + .globl dat +dat: .word 0 diff --git a/test/ELF/aarch64-cortex-a53-843419-recognize.s b/test/ELF/aarch64-cortex-a53-843419-recognize.s new file mode 100644 index 000000000000..3674dd2744da --- /dev/null +++ b/test/ELF/aarch64-cortex-a53-843419-recognize.s @@ -0,0 +1,563 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: ld.lld -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix CHECK-PRINT %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s -check-prefixes=CHECK,CHECK-FIX +// RUN: ld.lld -verbose %t.o -o %t3 +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t3 | FileCheck %s -check-prefixes=CHECK,CHECK-NOFIX +// Test cases for Cortex-A53 Erratum 843419 +// See ARM-EPM-048406 Cortex_A53_MPCore_Software_Developers_Errata_Notice.pdf +// for full erratum details. +// In Summary +// 1.) +// ADRP (0xff8 or 0xffc). +// 2.) +// - load or store single register or either integer or vector registers. +// - STP or STNP of either vector or vector registers. +// - Advanced SIMD ST1 store instruction. +// - Must not write Rn. +// 3.) optional instruction, can't be a branch, must not write Rn, may read Rn. +// 4.) A load or store instruction from the Load/Store register unsigned +// immediate class using Rn as the base register. + +// Each section contains a sequence of instructions that should be recognized +// as erratum 843419. The test cases cover the major variations such as: +// - adrp starts at 0xfff8 or 0xfffc. +// - Variations in instruction class for instruction 2. +// - Optional instruction 3 present or not. +// - Load or store for instruction 4. + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 21FF8 in unpatched output. +// CHECK: t3_ff8_ldr: +// CHECK-NEXT: 21ff8: e0 01 00 f0 adrp x0, #258048 +// CHECK-NEXT: 21ffc: 21 00 40 f9 ldr x1, [x1] +// CHECK-FIX: 22000: 03 b8 00 14 b #188428 +// CHECK-NOFIX: 22000: 00 00 40 f9 ldr x0, [x0] +// CHECK-NEXT: 22004: c0 03 5f d6 ret + .section .text.01, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldr + .type t3_ff8_ldr, %function + .space 4096 - 8 +t3_ff8_ldr: + adrp x0, dat1 + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 23FF8 in unpatched output. +// CHECK: t3_ff8_ldrsimd: +// CHECK-NEXT: 23ff8: e0 01 00 b0 adrp x0, #249856 +// CHECK-NEXT: 23ffc: 21 00 40 bd ldr s1, [x1] +// CHECK-FIX: 24000: 05 b0 00 14 b #180244 +// CHECK-NOFIX: 24000: 02 04 40 f9 ldr x2, [x0, #8] +// CHECK-NEXT: 24004: c0 03 5f d6 ret + .section .text.02, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldrsimd + .type t3_ff8_ldrsimd, %function + .space 4096 - 8 +t3_ff8_ldrsimd: + adrp x0, dat2 + ldr s1, [x1, #0] + ldr x2, [x0, :got_lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 25FFC in unpatched output. +// CHECK: t3_ffc_ldrpost: +// CHECK-NEXT: 25ffc: c0 01 00 f0 adrp x0, #241664 +// CHECK-NEXT: 26000: 21 84 40 bc ldr s1, [x1], #8 +// CHECK-FIX: 26004: 06 a8 00 14 b #172056 +// CHECK-NOFIX: 26004: 03 08 40 f9 ldr x3, [x0, #16] +// CHECK-NEXT: 26008: c0 03 5f d6 ret + .section .text.03, "ax", %progbits + .balign 4096 + .globl t3_ffc_ldrpost + .type t3_ffc_ldrpost, %function + .space 4096 - 4 +t3_ffc_ldrpost: + adrp x0, dat3 + ldr s1, [x1], #8 + ldr x3, [x0, :got_lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 27FF8 in unpatched output. +// CHECK: t3_ff8_strpre: +// CHECK-NEXT: 27ff8: c0 01 00 b0 adrp x0, #233472 +// CHECK-NEXT: 27ffc: 21 8c 00 bc str s1, [x1, #8]! +// CHECK-FIX: 28000: 09 a0 00 14 b #163876 +// CHECK-NOFIX: 28000: 02 00 40 f9 ldr x2, [x0] +// CHECK-NEXT: 28004: c0 03 5f d6 ret + .section .text.04, "ax", %progbits + .balign 4096 + .globl t3_ff8_strpre + .type t3_ff8_strpre, %function + .space 4096 - 8 +t3_ff8_strpre: + adrp x0, dat1 + str s1, [x1, #8]! + ldr x2, [x0, :lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 29FFC in unpatched output. +// CHECK: t3_ffc_str: +// CHECK-NEXT: 29ffc: bc 01 00 f0 adrp x28, #225280 +// CHECK-NEXT: 2a000: 42 00 00 f9 str x2, [x2] +// CHECK-FIX: 2a004: 0a 98 00 14 b #155688 +// CHECK-NOFIX: 2a004: 9c 07 00 f9 str x28, [x28, #8] +// CHECK-NEXT: 2a008: c0 03 5f d6 ret + .section .text.05, "ax", %progbits + .balign 4096 + .globl t3_ffc_str + .type t3_ffc_str, %function + .space 4096 - 4 +t3_ffc_str: + adrp x28, dat2 + str x2, [x2, #0] + str x28, [x28, :lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2BFFC in unpatched output. +// CHECK: t3_ffc_strsimd: +// CHECK-NEXT: 2bffc: bc 01 00 b0 adrp x28, #217088 +// CHECK-NEXT: 2c000: 44 00 00 b9 str w4, [x2] +// CHECK-FIX: 2c004: 0c 90 00 14 b #147504 +// CHECK-NOFIX: 2c004: 84 0b 00 f9 str x4, [x28, #16] +// CHECK-NEXT: 2c008: c0 03 5f d6 ret + .section .text.06, "ax", %progbits + .balign 4096 + .globl t3_ffc_strsimd + .type t3_ffc_strsimd, %function + .space 4096 - 4 +t3_ffc_strsimd: + adrp x28, dat3 + str w4, [x2, #0] + str x4, [x28, :lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2DFF8 in unpatched output. +// CHECK: t3_ff8_ldrunpriv: +// CHECK-NEXT: 2dff8: 9d 01 00 f0 adrp x29, #208896 +// CHECK-NEXT: 2dffc: 41 08 40 38 ldtrb w1, [x2] +// CHECK-FIX: 2e000: 0f 88 00 14 b #139324 +// CHECK-NOFIX: 2e000: bd 03 40 f9 ldr x29, [x29] +// CHECK-NEXT: 2e004: c0 03 5f d6 ret + .section .text.07, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldrunpriv + .type t3_ff8_ldrunpriv, %function + .space 4096 - 8 +t3_ff8_ldrunpriv: + adrp x29, dat1 + ldtrb w1, [x2, #0] + ldr x29, [x29, :got_lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 2FFFC in unpatched output. +// CHECK: t3_ffc_ldur: +// CHECK-NEXT: 2fffc: 9d 01 00 b0 adrp x29, #200704 +// CHECK-NEXT: 30000: 42 40 40 b8 ldur w2, [x2, #4] +// CHECK-FIX: 30004: 10 80 00 14 b #131136 +// CHECK-NOFIX: 30004: bd 07 40 f9 ldr x29, [x29, #8] +// CHECK-NEXT: 30008: c0 03 5f d6 ret + .balign 4096 + .globl t3_ffc_ldur + .type t3_ffc_ldur, %function + .space 4096 - 4 +t3_ffc_ldur: + adrp x29, dat2 + ldur w2, [x2, #4] + ldr x29, [x29, :got_lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 31FFC in unpatched output. +// CHECK: t3_ffc_sturh: +// CHECK-NEXT: 31ffc: 72 01 00 f0 adrp x18, #192512 +// CHECK-NEXT: 32000: 43 40 00 78 sturh w3, [x2, #4] +// CHECK-FIX: 32004: 12 78 00 14 b #122952 +// CHECK-NOFIX: 32004: 41 0a 40 f9 ldr x1, [x18, #16] +// CHECK-NEXT: 32008: c0 03 5f d6 ret + .section .text.09, "ax", %progbits + .balign 4096 + .globl t3_ffc_sturh + .type t3_ffc_sturh, %function + .space 4096 - 4 +t3_ffc_sturh: + adrp x18, dat3 + sturh w3, [x2, #4] + ldr x1, [x18, :got_lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 33FF8 in unpatched output. +// CHECK: t3_ff8_literal: +// CHECK-NEXT: 33ff8: 72 01 00 b0 adrp x18, #184320 +// CHECK-NEXT: 33ffc: e3 ff ff 58 ldr x3, #-4 +// CHECK-FIX: 34000: 15 70 00 14 b #114772 +// CHECK-NOFIX: 34000: 52 02 40 f9 ldr x18, [x18] +// CHECK-NEXT: 34004: c0 03 5f d6 ret + .section .text.10, "ax", %progbits + .balign 4096 + .globl t3_ff8_literal + .type t3_ff8_literal, %function + .space 4096 - 8 +t3_ff8_literal: + adrp x18, dat1 + ldr x3, t3_ff8_literal + ldr x18, [x18, :lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 35FFC in unpatched output. +// CHECK: t3_ffc_register: +// CHECK-NEXT: 35ffc: 4f 01 00 f0 adrp x15, #176128 +// CHECK-NEXT: 36000: 43 68 61 f8 ldr x3, [x2, x1] +// CHECK-FIX: 36004: 16 68 00 14 b #106584 +// CHECK-NOFIX: 36004: ea 05 40 f9 ldr x10, [x15, #8] +// CHECK-NEXT: 36008: c0 03 5f d6 ret + .section .text.11, "ax", %progbits + .balign 4096 + .globl t3_ffc_register + .type t3_ffc_register, %function + .space 4096 - 4 +t3_ffc_register: + adrp x15, dat2 + ldr x3, [x2, x1] + ldr x10, [x15, :lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 37FF8 in unpatched output. +// CHECK: t3_ff8_stp: +// CHECK-NEXT: 37ff8: 50 01 00 b0 adrp x16, #167936 +// CHECK-NEXT: 37ffc: 61 08 00 a9 stp x1, x2, [x3] +// CHECK-FIX: 38000: 19 60 00 14 b #98404 +// CHECK-NOFIX: 38000: 0d 0a 40 f9 ldr x13, [x16, #16] +// CHECK-NEXT: 38004: c0 03 5f d6 ret + .section .text.12, "ax", %progbits + .balign 4096 + .globl t3_ff8_stp + .type t3_ff8_stp, %function + .space 4096 - 8 +t3_ff8_stp: + adrp x16, dat3 + stp x1,x2, [x3, #0] + ldr x13, [x16, :lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 39FFC in unpatched output. +// CHECK: t3_ffc_stnp: +// CHECK-NEXT: 39ffc: 27 01 00 f0 adrp x7, #159744 +// CHECK-NEXT: 3a000: 61 08 00 a8 stnp x1, x2, [x3] +// CHECK-FIX: 3a004: 1a 58 00 14 b #90216 +// CHECK-NOFIX: 3a004: e9 00 40 f9 ldr x9, [x7] +// CHECK-NEXT: 3a008: c0 03 5f d6 ret + .section .text.13, "ax", %progbits + .balign 4096 + .globl t3_ffc_stnp + .type t3_ffc_stnp, %function + .space 4096 - 4 +t3_ffc_stnp: + adrp x7, dat1 + stnp x1,x2, [x3, #0] + ldr x9, [x7, :lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3BFFC in unpatched output. +// CHECK: t3_ffc_st1singlepost: +// CHECK-NEXT: 3bffc: 37 01 00 b0 adrp x23, #151552 +// CHECK-NEXT: 3c000: 20 70 82 4c st1 { v0.16b }, [x1], x2 +// CHECK-FIX: 3c004: 1c 50 00 14 b #82032 +// CHECK-NOFIX: 3c004: f6 06 40 f9 ldr x22, [x23, #8] +// CHECK-NEXT: 3c008: c0 03 5f d6 ret + .section .text.14, "ax", %progbits + .balign 4096 + .globl t3_ffc_st1singlepost + .type t3_ffc_st1singlepost, %function + .space 4096 - 4 +t3_ffc_st1singlepost: + adrp x23, dat2 + st1 { v0.16b }, [x1], x2 + ldr x22, [x23, :lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3DFF8 in unpatched output. +// CHECK: t3_ff8_st1multiple: +// CHECK-NEXT: 3dff8: 17 01 00 f0 adrp x23, #143360 +// CHECK-NEXT: 3dffc: 20 a0 00 4c st1 { v0.16b, v1.16b }, [x1] +// CHECK-FIX: 3e000: 1f 48 00 14 b #73852 +// CHECK-NOFIX: 3e000: f8 0a 40 f9 ldr x24, [x23, #16] +// CHECK-NEXT: 3e004: c0 03 5f d6 ret + .section .text.15, "ax", %progbits + .balign 4096 + .globl t3_ff8_st1multiple + .type t3_ff8_st1muliple, %function + .space 4096 - 8 +t3_ff8_st1multiple: + adrp x23, dat3 + st1 { v0.16b, v1.16b }, [x1] + ldr x24, [x23, :lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 3FFF8 in unpatched output. +// CHECK: t4_ff8_ldr: +// CHECK-NEXT: 3fff8: 00 01 00 b0 adrp x0, #135168 +// CHECK-NEXT: 3fffc: 21 00 40 f9 ldr x1, [x1] +// CHECK-NEXT: 40000: 42 00 00 8b add x2, x2, x0 +// CHECK-FIX: 40004: 20 40 00 14 b #65664 +// CHECK-NOFIX: 40004: 02 00 40 f9 ldr x2, [x0] +// CHECK-NEXT: 40008: c0 03 5f d6 ret + .section .text.16, "ax", %progbits + .balign 4096 + .globl t4_ff8_ldr + .type t4_ff8_ldr, %function + .space 4096 - 8 +t4_ff8_ldr: + adrp x0, dat1 + ldr x1, [x1, #0] + add x2, x2, x0 + ldr x2, [x0, :got_lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 41FFC in unpatched output. +// CHECK: t4_ffc_str: +// CHECK-NEXT: 41ffc: fc 00 00 f0 adrp x28, #126976 +// CHECK-NEXT: 42000: 42 00 00 f9 str x2, [x2] +// CHECK-NEXT: 42004: 20 00 02 cb sub x0, x1, x2 +// CHECK-FIX: 42008: 21 38 00 14 b #57476 +// CHECK-NOFIX: 42008: 9b 07 00 f9 str x27, [x28, #8] +// CHECK-NEXT: 4200c: c0 03 5f d6 ret + .section .text.17, "ax", %progbits + .balign 4096 + .globl t4_ffc_str + .type t4_ffc_str, %function + .space 4096 - 4 +t4_ffc_str: + adrp x28, dat2 + str x2, [x2, #0] + sub x0, x1, x2 + str x27, [x28, :got_lo12:dat2] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 43FF8 in unpatched output. +// CHECK: t4_ff8_stp: +// CHECK-NEXT: 43ff8: f0 00 00 b0 adrp x16, #118784 +// CHECK-NEXT: 43ffc: 61 08 00 a9 stp x1, x2, [x3] +// CHECK-NEXT: 44000: 03 7e 10 9b mul x3, x16, x16 +// CHECK-FIX: 44004: 24 30 00 14 b #49296 +// CHECK-NOFIX: 44004: 0e 0a 40 f9 ldr x14, [x16, #16] +// CHECK-NEXT: 44008: c0 03 5f d6 ret + .section .text.18, "ax", %progbits + .balign 4096 + .globl t4_ff8_stp + .type t4_ff8_stp, %function + .space 4096 - 8 +t4_ff8_stp: + adrp x16, dat3 + stp x1,x2, [x3, #0] + mul x3, x16, x16 + ldr x14, [x16, :got_lo12:dat3] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 45FF8 in unpatched output. +// CHECK: t4_ff8_stppre: +// CHECK-NEXT: 45ff8: d0 00 00 f0 adrp x16, #110592 +// CHECK-NEXT: 45ffc: 61 08 81 a9 stp x1, x2, [x3, #16]! +// CHECK-NEXT: 46000: 03 7e 10 9b mul x3, x16, x16 +// CHECK-FIX: 46004: 26 28 00 14 b #41112 +// CHECK-NOFIX: 46004: 0e 06 40 f9 ldr x14, [x16, #8] +// CHECK-NEXT: 46008: c0 03 5f d6 ret + .section .text.19, "ax", %progbits + .balign 4096 + .globl t4_ff8_stppre + .type t4_ff8_stppre, %function + .space 4096 - 8 +t4_ff8_stppre: + adrp x16, dat1 + stp x1,x2, [x3, #16]! + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 47FF8 in unpatched output. +// CHECK: t4_ff8_stppost: +// CHECK-NEXT: 47ff8: d0 00 00 b0 adrp x16, #102400 +// CHECK-NEXT: 47ffc: 61 08 81 a8 stp x1, x2, [x3], #16 +// CHECK-NEXT: 48000: 03 7e 10 9b mul x3, x16, x16 +// CHECK-FIX: 48004: 28 20 00 14 b #32928 +// CHECK-NOFIX: 48004: 0e 06 40 f9 ldr x14, [x16, #8] +// CHECK-NEXT: 48008: c0 03 5f d6 ret + .section .text.20, "ax", %progbits + .balign 4096 + .globl t4_ff8_stppost + .type t4_ff8_stppost, %function + .space 4096 - 8 +t4_ff8_stppost: + adrp x16, dat2 + stp x1,x2, [x3], #16 + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 49FFC in unpatched output. +// CHECK: t4_ffc_stpsimd: +// CHECK-NEXT: 49ffc: b0 00 00 f0 adrp x16, #94208 +// CHECK-NEXT: 4a000: 61 08 00 ad stp q1, q2, [x3] +// CHECK-NEXT: 4a004: 03 7e 10 9b mul x3, x16, x16 +// CHECK-FIX: 4a008: 29 18 00 14 b #24740 +// CHECK-NOFIX: 4a008: 0e 06 40 f9 ldr x14, [x16, #8] +// CHECK-NEXT: 4a00c: c0 03 5f d6 ret + .section .text.21, "ax", %progbits + .balign 4096 + .globl t4_ffc_stpsimd + .type t4_ffc_stpsimd, %function + .space 4096 - 4 +t4_ffc_stpsimd: + adrp x16, dat3 + stp q1,q2, [x3, #0] + mul x3, x16, x16 + ldr x14, [x16, #8] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4BFFC in unpatched output. +// CHECK: t4_ffc_stnp: +// CHECK-NEXT: 4bffc: a7 00 00 b0 adrp x7, #86016 +// CHECK-NEXT: 4c000: 61 08 00 a8 stnp x1, x2, [x3] +// CHECK-NEXT: 4c004: 1f 20 03 d5 nop +// CHECK-FIX: 4c008: 2b 10 00 14 b #16556 +// CHECK-NOFIX: 4c008: ea 00 40 f9 ldr x10, [x7] +// CHECK-NEXT: 4c00c: c0 03 5f d6 ret + .section .text.22, "ax", %progbits + .balign 4096 + .globl t4_ffc_stnp + .type t4_ffc_stnp, %function + .space 4096 - 4 +t4_ffc_stnp: + adrp x7, dat1 + stnp x1,x2, [x3, #0] + nop + ldr x10, [x7, :got_lo12:dat1] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4DFFC in unpatched output. +// CHECK: t4_ffc_st1: +// CHECK-NEXT: 4dffc: 98 00 00 f0 adrp x24, #77824 +// CHECK-NEXT: 4e000: 20 70 00 4c st1 { v0.16b }, [x1] +// CHECK-NEXT: 4e004: f6 06 40 f9 ldr x22, [x23, #8] +// CHECK-FIX: 4e008: 2d 08 00 14 b #8372 +// CHECK-NOFIX: 4e008: 18 ff 3f f9 str x24, [x24, #32760] +// CHECK-NEXT: 4e00c: c0 03 5f d6 ret + .section .text.23, "ax", %progbits + .balign 4096 + .globl t4_ffc_st1 + .type t4_ffc_st1, %function + .space 4096 - 4 +t4_ffc_st1: + adrp x24, dat2 + st1 { v0.16b }, [x1] + ldr x22, [x23, :got_lo12:dat2] + str x24, [x24, #32760] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 4FFF8 in unpatched output. +// CHECK: t3_ff8_ldr_once: +// CHECK-NEXT: 4fff8: 80 00 00 b0 adrp x0, #69632 +// CHECK-NEXT: 4fffc: 20 70 82 4c st1 { v0.16b }, [x1], x2 +// CHECK-FIX: 50000: 31 00 00 14 b #196 +// CHECK-NOFIX: 50000: 01 08 40 f9 ldr x1, [x0, #16] +// CHECK-NEXT: 50004: 02 08 40 f9 ldr x2, [x0, #16] +// CHECK-NEXT: 50008: c0 03 5f d6 ret + .section .text.24, "ax", %progbits + .balign 4096 + .globl t3_ff8_ldr_once + .type t3_ff8_ldr_once, %function + .space 4096 - 8 +t3_ff8_ldr_once: + adrp x0, dat3 + st1 { v0.16b }, [x1], x2 + ldr x1, [x0, #16] + ldr x2, [x0, #16] + ret + + .text + .globl _start + .type _start, %function +_start: + ret + +// CHECK-FIX: __CortexA53843419_22000: +// CHECK-FIX-NEXT: 5000c: 00 00 40 f9 ldr x0, [x0] +// CHECK-FIX-NEXT: 50010: fd 47 ff 17 b #-188428 +// CHECK-FIX: __CortexA53843419_24000: +// CHECK-FIX-NEXT: 50014: 02 04 40 f9 ldr x2, [x0, #8] +// CHECK-FIX-NEXT: 50018: fb 4f ff 17 b #-180244 +// CHECK-FIX: __CortexA53843419_26004: +// CHECK-FIX-NEXT: 5001c: 03 08 40 f9 ldr x3, [x0, #16] +// CHECK-FIX-NEXT: 50020: fa 57 ff 17 b #-172056 +// CHECK-FIX: __CortexA53843419_28000: +// CHECK-FIX-NEXT: 50024: 02 00 40 f9 ldr x2, [x0] +// CHECK-FIX-NEXT: 50028: f7 5f ff 17 b #-163876 +// CHECK-FIX: __CortexA53843419_2A004: +// CHECK-FIX-NEXT: 5002c: 9c 07 00 f9 str x28, [x28, #8] +// CHECK-FIX-NEXT: 50030: f6 67 ff 17 b #-155688 +// CHECK-FIX: __CortexA53843419_2C004: +// CHECK-FIX-NEXT: 50034: 84 0b 00 f9 str x4, [x28, #16] +// CHECK-FIX-NEXT: 50038: f4 6f ff 17 b #-147504 +// CHECK-FIX: __CortexA53843419_2E000: +// CHECK-FIX-NEXT: 5003c: bd 03 40 f9 ldr x29, [x29] +// CHECK-FIX-NEXT: 50040: f1 77 ff 17 b #-139324 +// CHECK-FIX: __CortexA53843419_30004: +// CHECK-FIX-NEXT: 50044: bd 07 40 f9 ldr x29, [x29, #8] +// CHECK-FIX-NEXT: 50048: f0 7f ff 17 b #-131136 +// CHECK-FIX: __CortexA53843419_32004: +// CHECK-FIX-NEXT: 5004c: 41 0a 40 f9 ldr x1, [x18, #16] +// CHECK-FIX-NEXT: 50050: ee 87 ff 17 b #-122952 +// CHECK-FIX: __CortexA53843419_34000: +// CHECK-FIX-NEXT: 50054: 52 02 40 f9 ldr x18, [x18] +// CHECK-FIX-NEXT: 50058: eb 8f ff 17 b #-114772 +// CHECK-FIX: __CortexA53843419_36004: +// CHECK-FIX-NEXT: 5005c: ea 05 40 f9 ldr x10, [x15, #8] +// CHECK-FIX-NEXT: 50060: ea 97 ff 17 b #-106584 +// CHECK-FIX: __CortexA53843419_38000: +// CHECK-FIX-NEXT: 50064: 0d 0a 40 f9 ldr x13, [x16, #16] +// CHECK-FIX-NEXT: 50068: e7 9f ff 17 b #-98404 +// CHECK-FIX: __CortexA53843419_3A004: +// CHECK-FIX-NEXT: 5006c: e9 00 40 f9 ldr x9, [x7] +// CHECK-FIX-NEXT: 50070: e6 a7 ff 17 b #-90216 +// CHECK-FIX: __CortexA53843419_3C004: +// CHECK-FIX-NEXT: 50074: f6 06 40 f9 ldr x22, [x23, #8] +// CHECK-FIX-NEXT: 50078: e4 af ff 17 b #-82032 +// CHECK-FIX: __CortexA53843419_3E000: +// CHECK-FIX-NEXT: 5007c: f8 0a 40 f9 ldr x24, [x23, #16] +// CHECK-FIX-NEXT: 50080: e1 b7 ff 17 b #-73852 +// CHECK-FIX: __CortexA53843419_40004: +// CHECK-FIX-NEXT: 50084: 02 00 40 f9 ldr x2, [x0] +// CHECK-FIX-NEXT: 50088: e0 bf ff 17 b #-65664 +// CHECK-FIX: __CortexA53843419_42008: +// CHECK-FIX-NEXT: 5008c: 9b 07 00 f9 str x27, [x28, #8] +// CHECK-FIX-NEXT: 50090: df c7 ff 17 b #-57476 +// CHECK-FIX: __CortexA53843419_44004: +// CHECK-FIX-NEXT: 50094: 0e 0a 40 f9 ldr x14, [x16, #16] +// CHECK-FIX-NEXT: 50098: dc cf ff 17 b #-49296 +// CHECK-FIX: __CortexA53843419_46004: +// CHECK-FIX-NEXT: 5009c: 0e 06 40 f9 ldr x14, [x16, #8] +// CHECK-FIX-NEXT: 500a0: da d7 ff 17 b #-41112 +// CHECK-FIX: __CortexA53843419_48004: +// CHECK-FIX-NEXT: 500a4: 0e 06 40 f9 ldr x14, [x16, #8] +// CHECK-FIX-NEXT: 500a8: d8 df ff 17 b #-32928 +// CHECK-FIX: __CortexA53843419_4A008: +// CHECK-FIX-NEXT: 500ac: 0e 06 40 f9 ldr x14, [x16, #8] +// CHECK-FIX-NEXT: 500b0: d7 e7 ff 17 b #-24740 +// CHECK-FIX: __CortexA53843419_4C008: +// CHECK-FIX-NEXT: 500b4: ea 00 40 f9 ldr x10, [x7] +// CHECK-FIX-NEXT: 500b8: d5 ef ff 17 b #-16556 +// CHECK-FIX: __CortexA53843419_4E008: +// CHECK-FIX-NEXT: 500bc: 18 ff 3f f9 str x24, [x24, #32760] +// CHECK-FIX-NEXT: 500c0: d3 f7 ff 17 b #-8372 +// CHECK-FIX: __CortexA53843419_50000: +// CHECK-FIX-NEXT: 500c4: 01 08 40 f9 ldr x1, [x0, #16] +// CHECK-FIX-NEXT: 500c8: cf ff ff 17 b #-196 + + .data + .globl dat + .globl dat2 + .globl dat3 +dat1: .quad 1 +dat2: .quad 2 +dat3: .quad 3 diff --git a/test/ELF/aarch64-cortex-a53-843419-thunk.s b/test/ELF/aarch64-cortex-a53-843419-thunk.s new file mode 100644 index 000000000000..4568095a2fa7 --- /dev/null +++ b/test/ELF/aarch64-cortex-a53-843419-thunk.s @@ -0,0 +1,57 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o +// RUN: echo "SECTIONS { \ +// RUN: .text1 0x10000 : { *(.text.01) *(.text.02) *(.text.03) } \ +// RUN: .text2 0x8010000 : { *(.text.04) } } " > %t.script +// RUN: ld.lld --script %t.script -fix-cortex-a53-843419 -verbose %t.o -o %t2 | FileCheck -check-prefix=CHECK-PRINT %s +// RUN: llvm-objdump -triple=aarch64-linux-gnu -d %t2 | FileCheck %s + +// %t2 is 128 Megabytes, so delete it early. +// RUN: rm %t2 + +// Test cases for Cortex-A53 Erratum 843419 that involve interactions with +// range extension thunks. Both erratum fixes and range extension thunks need +// precise address information and after creation alter address information. + + + .section .text.01, "ax", %progbits + .balign 4096 + .globl _start + .type _start, %function +_start: + bl far_away + // Thunk to far_away, size 16-bytes goes here. + + .section .text.02, "ax", %progbits + .space 4096 - 28 + + // Erratum sequence will only line up at address 0 modulo 0xffc when + // Thunk is inserted. + .section .text.03, "ax", %progbits + .globl t3_ff8_ldr + .type t3_ff8_ldr, %function +t3_ff8_ldr: + adrp x0, dat + ldr x1, [x1, #0] + ldr x0, [x0, :got_lo12:dat] + ret + +// CHECK-PRINT: detected cortex-a53-843419 erratum sequence starting at 10FFC in unpatched output. +// CHECK: t3_ff8_ldr: +// CHECK-NEXT: 10ffc: 00 00 04 90 adrp x0, #134217728 +// CHECK-NEXT: 11000: 21 00 40 f9 ldr x1, [x1] +// CHECK-NEXT: 11004: 02 00 00 14 b #8 +// CHECK-NEXT: 11008: c0 03 5f d6 ret +// CHECK: __CortexA53843419_11004: +// CHECK-NEXT: 1100c: 00 08 40 f9 ldr x0, [x0, #16] +// CHECK-NEXT: 11010: fe ff ff 17 b #-8 + + .section .text.04, "ax", %progbits + .globl far_away + .type far_away, function +far_away: + ret + + .section .data + .globl dat +dat: .quad 0 diff --git a/test/ELF/aarch64-gnu-ifunc-plt.s b/test/ELF/aarch64-gnu-ifunc-plt.s index be9a8a7e674a..5138675676d3 100644 --- a/test/ELF/aarch64-gnu-ifunc-plt.s +++ b/test/ELF/aarch64-gnu-ifunc-plt.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %S/Inputs/shared2.s -o %t1.o // RUN: ld.lld %t1.o --shared -o %t.so // RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o -// RUN: ld.lld %t.so %t.o -o %tout +// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s diff --git a/test/ELF/aarch64-gnu-ifunc.s b/test/ELF/aarch64-gnu-ifunc.s index 46f4a292d2ea..4e0dc328025d 100644 --- a/test/ELF/aarch64-gnu-ifunc.s +++ b/test/ELF/aarch64-gnu-ifunc.s @@ -15,7 +15,7 @@ // CHECK-NEXT: Address: [[RELA:.*]] // CHECK-NEXT: Offset: 0x158 // CHECK-NEXT: Size: 48 -// CHECK-NEXT: Link: 6 +// CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 8 // CHECK-NEXT: EntrySize: 24 diff --git a/test/ELF/aarch64-got-reloc.s b/test/ELF/aarch64-got-reloc.s index fec1ad6a1d22..1882dcd43a48 100644 --- a/test/ELF/aarch64-got-reloc.s +++ b/test/ELF/aarch64-got-reloc.s @@ -9,8 +9,8 @@ // CHECK-NEXT: SHF_ALLOC // CHECK-NEXT: SHF_WRITE // CHECK-NEXT: ] -// CHECK-NEXT: Address: 0x30000 -// CHECK-NEXT: Offset: 0x20000 +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: // CHECK-NEXT: Size: 8 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 diff --git a/test/ELF/aarch64-got-relocations.s b/test/ELF/aarch64-got-relocations.s index 13ee09a892e9..a7745b05904d 100644 --- a/test/ELF/aarch64-got-relocations.s +++ b/test/ELF/aarch64-got-relocations.s @@ -1,6 +1,6 @@ # REQUIRES: aarch64 # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t.o -# RUN: ld.lld -pie %t.o -o %t +# RUN: ld.lld --hash-style=sysv -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 diff --git a/test/ELF/aarch64-jump26-error.s b/test/ELF/aarch64-jump26-error.s deleted file mode 100644 index 81fbba1f4551..000000000000 --- a/test/ELF/aarch64-jump26-error.s +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs -// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t -// RUN: not ld.lld %t %tabs -o %t2 2>&1 | FileCheck %s -// REQUIRES: aarch64 - -.text -.globl _start -_start: - b big - -// CHECK: R_AARCH64_JUMP26 out of range diff --git a/test/ELF/aarch64-jump26-thunk.s b/test/ELF/aarch64-jump26-thunk.s new file mode 100644 index 000000000000..088ab3a9e1a5 --- /dev/null +++ b/test/ELF/aarch64-jump26-thunk.s @@ -0,0 +1,20 @@ +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs +// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t +// RUN: ld.lld %t %tabs -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=aarch64-pc-freebsd %t2 | FileCheck %s +// REQUIRES: aarch64 + +.text +.globl _start +_start: + b big + +// CHECK: Disassembly of section .text: +// CHECK-NEXT: _start: +// CHECK-NEXT: 20000: 02 00 00 14 b #8 +// CHECK: __AArch64AbsLongThunk_big: +// CHECK-NEXT: 20008: 50 00 00 58 ldr x16, #8 +// CHECK-NEXT: 2000c: 00 02 1f d6 br x16 +// CHECK: $d: +// CHECK-NEXT: 20010: 00 00 00 00 .word 0x00000000 +// CHECK-NEXT: 20014: 10 00 00 00 .word 0x00000010 diff --git a/test/ELF/aarch64-ldprel-lo19-invalid.s b/test/ELF/aarch64-ldprel-lo19-invalid.s new file mode 100644 index 000000000000..04df32e05904 --- /dev/null +++ b/test/ELF/aarch64-ldprel-lo19-invalid.s @@ -0,0 +1,11 @@ +# REQUIRES: aarch64 + +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o +# RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s + +# CHECK: relocation R_AARCH64_LD_PREL_LO19 out of range: 2065536 is not in [-1048576, 1048575] + + ldr x8, patatino + .data + .zero 2000000 +patatino: diff --git a/test/ELF/aarch64-lo12-alignment.s b/test/ELF/aarch64-lo12-alignment.s new file mode 100644 index 000000000000..2b30022658e6 --- /dev/null +++ b/test/ELF/aarch64-lo12-alignment.s @@ -0,0 +1,45 @@ +// REQUIRES: aarch64 +// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t +// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s + +// Test derived from a typical ODR violation where a global is declared +// extern int but defined as a half or byte sized type. + .section .text + .globl _start + .type _start, %function +// Access foo2 as if it were an aligned 32-bit int, expect an error as +// foo is not aligned + +_start: + ldrb w2, [x0, #:lo12:foo1] // Ok as no shift involved + ldrh w2, [x0, #:lo12:foo1] // Error foo1 is not 2-byte aligned + ldrh w2, [x0, #:lo12:foo2] // Ok as foo2 is 2-byte aligned + ldr w2, [x0, #:lo12:foo2] // Error foo2 is not 4-byte aligned + ldr w2, [x0, #:lo12:foo4] // Ok as foo4 is 4-byte aligned + ldr x3, [x0, #:lo12:foo4] // Error foo4 is not 8-byte aligned + ldr x3, [x0, #:lo12:foo8] // Ok as foo8 is 8-byte aligned + ldr q0, [x0, #:lo12:foo8] // Error foo8 is not 16-byte aligned + ldr q0, [x0, #:lo12:foo16] // Ok as foo16 is 16-byte aligned + + .section .data.bool, "a", @nobits + .balign 16 + .globl foo16 + .globl foo1 + .globl foo2 + .globl foo4 + .globl foo8 +foo16: + .space 1 +foo1: + .space 1 +foo2: + .space 2 +foo4: + .space 4 +foo8: + .space 8 + +// CHECK: improper alignment for relocation R_AARCH64_LDST16_ABS_LO12_NC: 0x30001 is not aligned to 2 bytes +// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST32_ABS_LO12_NC: 0x30002 is not aligned to 4 bytes +// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x30004 is not aligned to 8 bytes +// CHECK-NEXT: improper alignment for relocation R_AARCH64_LDST128_ABS_LO12_NC: 0x30008 is not aligned to 16 bytes diff --git a/test/ELF/aarch64-load-alignment.s b/test/ELF/aarch64-load-alignment.s new file mode 100644 index 000000000000..7b1129b7afa5 --- /dev/null +++ b/test/ELF/aarch64-load-alignment.s @@ -0,0 +1,11 @@ +# REQUIRES: aarch64 + +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o +# RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s + +# CHECK: improper alignment for relocation R_AARCH64_LD_PREL_LO19: 0x10005 is not aligned to 4 bytes + + ldr x8, patatino + .data + .zero 5 +patatino: diff --git a/test/ELF/aarch64-prel16.s b/test/ELF/aarch64-prel16.s index 4ae1f87e2081..fc34f010853c 100644 --- a/test/ELF/aarch64-prel16.s +++ b/test/ELF/aarch64-prel16.s @@ -28,4 +28,4 @@ _start: // | FileCheck %s --check-prefix=OVERFLOW // RUN: not ld.lld %t.o %t257.o -o %t2 // | FileCheck %s --check-prefix=OVERFLOW -// OVERFLOW: Relocation R_AARCH64_PREL16 out of range +// OVERFLOW: Relocation R_AARCH64_PREL16 out of range: -94209 is not in [-32768, 65535] diff --git a/test/ELF/aarch64-prel32.s b/test/ELF/aarch64-prel32.s index 302f4521f46b..7aa290382c53 100644 --- a/test/ELF/aarch64-prel32.s +++ b/test/ELF/aarch64-prel32.s @@ -28,4 +28,4 @@ _start: // | FileCheck %s --check-prefix=OVERFLOW // RUN: not ld.lld %t.o %t257.o -o %t2 // | FileCheck %s --check-prefix=OVERFLOW -// OVERFLOW: Relocation R_AARCH64_PREL32 out of range +// OVERFLOW: Relocation R_AARCH64_PREL32 out of range: 18446744071562006527 is not in [-2147483648, 4294967295] diff --git a/test/ELF/aarch64-thunk-pi.s b/test/ELF/aarch64-thunk-pi.s new file mode 100644 index 000000000000..91e2b7f0f3cd --- /dev/null +++ b/test/ELF/aarch64-thunk-pi.s @@ -0,0 +1,91 @@ +// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: .text_low : { *(.text_low) } \ +// RUN: .text_high 0x10000000 : { *(.text_high) } \ +// RUN: } " > %t.script +// RUN: ld.lld --script %t.script --shared %t -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s +// REQUIRES: aarch64 + +// Check that Position Independent thunks are generated for shared libraries. + .section .text_low, "ax", %progbits + .globl low_target + .type low_target, %function +low_target: + // Need thunk to high_target@plt + bl high_target + ret +// CHECK: low_target: +// CHECK-NEXT: 0: 04 00 00 94 bl #16 +// CHECK-NEXT: 4: c0 03 5f d6 ret + + .hidden low_target2 + .globl low_target2 + .type low_target2, %function +low_target2: + // Need thunk to high_target + bl high_target2 + ret +// CHECK: low_target2: +// CHECK-NEXT: 8: 05 00 00 94 bl #20 +// CHECK-NEXT: c: c0 03 5f d6 ret + +// Expect range extension thunks for .text_low +// adrp calculation is (PC + signed immediate) & (!0xfff) +// CHECK: __AArch64ADRPThunk_high_target: +// CHECK-NEXT: 10: 10 00 08 90 adrp x16, #268435456 +// CHECK-NEXT: 14: 10 82 04 91 add x16, x16, #288 +// CHECK-NEXT: 18: 00 02 1f d6 br x16 +// CHECK: __AArch64ADRPThunk_high_target2: +// CHECK-NEXT: 1c: 10 00 08 90 adrp x16, #268435456 +// CHECK-NEXT: 20: 10 22 00 91 add x16, x16, #8 +// CHECK-NEXT: 24: 00 02 1f d6 br x16 + + + .section .text_high, "ax", %progbits + .globl high_target + .type high_target, %function +high_target: + // No thunk needed as we can reach low_target@plt + bl low_target + ret +// CHECK: high_target: +// CHECK-NEXT: 10000000: 4c 00 00 94 bl #304 +// CHECK-NEXT: 10000004: c0 03 5f d6 ret + + .hidden high_target2 + .globl high_target2 + .type high_target2, %function +high_target2: + // Need thunk to low_target + bl low_target2 + ret +// CHECK: high_target2: +// CHECK-NEXT: 10000008: 02 00 00 94 bl #8 +// CHECK-NEXT: 1000000c: c0 03 5f d6 ret + +// Expect Thunk for .text.high + +// CHECK: __AArch64ADRPThunk_low_target2: +// CHECK-NEXT: 10000010: 10 00 f8 90 adrp x16, #-268435456 +// CHECK-NEXT: 10000014: 10 22 00 91 add x16, x16, #8 +// CHECK-NEXT: 10000018: 00 02 1f d6 br x16 + +// CHECK: Disassembly of section .plt: +// CHECK-NEXT: .plt: +// CHECK-NEXT: 10000100: f0 7b bf a9 stp x16, x30, [sp, #-16]! +// CHECK-NEXT: 10000104: 10 00 00 90 adrp x16, #0 +// CHECK-NEXT: 10000108: 11 aa 40 f9 ldr x17, [x16, #336] +// CHECK-NEXT: 1000010c: 10 42 05 91 add x16, x16, #336 +// CHECK-NEXT: 10000110: 20 02 1f d6 br x17 +// CHECK-NEXT: 10000114: 1f 20 03 d5 nop +// CHECK-NEXT: 10000118: 1f 20 03 d5 nop +// CHECK-NEXT: 1000011c: 1f 20 03 d5 nop +// CHECK-NEXT: 10000120: 10 00 00 90 adrp x16, #0 +// CHECK-NEXT: 10000124: 11 ae 40 f9 ldr x17, [x16, #344] +// CHECK-NEXT: 10000128: 10 62 05 91 add x16, x16, #344 +// CHECK-NEXT: 1000012c: 20 02 1f d6 br x17 +// CHECK-NEXT: 10000130: 10 00 00 90 adrp x16, #0 +// CHECK-NEXT: 10000134: 11 b2 40 f9 ldr x17, [x16, #352] +// CHECK-NEXT: 10000138: 10 82 05 91 add x16, x16, #352 +// CHECK-NEXT: 1000013c: 20 02 1f d6 br x17 diff --git a/test/ELF/aarch64-thunk-script.s b/test/ELF/aarch64-thunk-script.s new file mode 100644 index 000000000000..ebfaf72de5f4 --- /dev/null +++ b/test/ELF/aarch64-thunk-script.s @@ -0,0 +1,41 @@ +// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: .text_low 0x2000: { *(.text_low) } \ +// RUN: .text_high 0x8002000 : { *(.text_high) } \ +// RUN: } " > %t.script +// RUN: ld.lld --script %t.script %t -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=aarch64-linux-gnu %t2 | FileCheck %s +// REQUIRES: aarch64 + +// Check that we have the out of branch range calculation right. The immediate +// field is signed so we have a slightly higher negative displacement. + .section .text_low, "ax", %progbits + .globl _start + .type _start, %function +_start: + // Need thunk to high_target@plt + bl high_target + ret + + .section .text_high, "ax", %progbits + .globl high_target + .type high_target, %function +high_target: + // No Thunk needed as we are within signed immediate range + bl _start + ret + +// CHECK: Disassembly of section .text_low: +// CHECK-NEXT: _start: +// CHECK-NEXT: 2000: 02 00 00 94 bl #8 +// CHECK-NEXT: 2004: c0 03 5f d6 ret +// CHECK: __AArch64AbsLongThunk_high_target: +// CHECK-NEXT: 2008: 50 00 00 58 ldr x16, #8 +// CHECK-NEXT: 200c: 00 02 1f d6 br x16 +// CHECK: $d: +// CHECK-NEXT: 2010: 00 20 00 08 .word 0x08002000 +// CHECK-NEXT: 2014: 00 00 00 00 .word 0x00000000 +// CHECK: Disassembly of section .text_high: +// CHECK-NEXT: high_target: +// CHECK-NEXT: 8002000: 00 00 00 96 bl #-134217728 +// CHECK-NEXT: 8002004: c0 03 5f d6 ret diff --git a/test/ELF/aarch64-thunk-section-location.s b/test/ELF/aarch64-thunk-section-location.s new file mode 100644 index 000000000000..bf70b7c365ba --- /dev/null +++ b/test/ELF/aarch64-thunk-section-location.s @@ -0,0 +1,41 @@ +// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 +// RUN: llvm-objdump -d -start-address=134086664 -stop-address=134086676 -triple=aarch64-linux-gnu %t2 | FileCheck %s +// REQUIRES: aarch64 +// Check that the range extension thunks are dumped close to the aarch64 branch +// range of 128 MiB + .section .text.1, "ax", %progbits + .balign 0x1000 + .globl _start +_start: + bl high_target + ret + + .section .text.2, "ax", %progbits + .space 0x2000000 + + .section .text.2, "ax", %progbits + .space 0x2000000 + + .section .text.3, "ax", %progbits + .space 0x2000000 + + .section .text.4, "ax", %progbits + .space 0x2000000 - 0x40000 + + .section .text.5, "ax", %progbits + .space 0x40000 + + .section .text.6, "ax", %progbits + .balign 0x1000 + + .globl high_target + .type high_target, %function +high_target: + ret + +// CHECK: __AArch64AbsLongThunk_high_target: +// CHECK-NEXT: 7fe0008: 50 00 00 58 ldr x16, #8 +// CHECK-NEXT: 7fe000c: 00 02 1f d6 br x16 +// CHECK: $d: +// CHECK-NEXT: 7fe0010: 00 10 02 08 .word 0x08021000 diff --git a/test/ELF/aarch64-tls-gdie.s b/test/ELF/aarch64-tls-gdie.s index c66ea6cfcadb..ab7461ac2973 100644 --- a/test/ELF/aarch64-tls-gdie.s +++ b/test/ELF/aarch64-tls-gdie.s @@ -2,7 +2,7 @@ // 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: ld.lld --hash-style=sysv %t.o %t2.so -o %t // RUN: llvm-readobj -s %t | FileCheck --check-prefix=SEC %s // RUN: llvm-objdump -d %t | FileCheck %s diff --git a/test/ELF/aarch64-tls-ie.s b/test/ELF/aarch64-tls-ie.s index 81ca326aff54..8b7431093a26 100644 --- a/test/ELF/aarch64-tls-ie.s +++ b/test/ELF/aarch64-tls-ie.s @@ -2,7 +2,7 @@ # 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 -# RUN: ld.lld %tmain.o %tdso.so -o %tout +# RUN: ld.lld --hash-style=sysv %tmain.o %tdso.so -o %tout # RUN: llvm-objdump -d %tout | FileCheck %s # RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s # REQUIRES: aarch64 diff --git a/test/ELF/aarch64-tls-static.s b/test/ELF/aarch64-tls-static.s index 24306d5d7ee3..309a2e9f56ca 100644 --- a/test/ELF/aarch64-tls-static.s +++ b/test/ELF/aarch64-tls-static.s @@ -1,6 +1,6 @@ // 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: ld.lld --hash-style=sysv %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 diff --git a/test/ELF/aarch64-tlsdesc.s b/test/ELF/aarch64-tlsdesc.s index 09dfd04d8ac9..b7c2e65a164f 100644 --- a/test/ELF/aarch64-tlsdesc.s +++ b/test/ELF/aarch64-tlsdesc.s @@ -1,6 +1,6 @@ // 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: ld.lld --hash-style=sysv -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 diff --git a/test/ELF/aarch64-undefined-weak.s b/test/ELF/aarch64-undefined-weak.s index 1c21213643ac..35f50417497e 100644 --- a/test/ELF/aarch64-undefined-weak.s +++ b/test/ELF/aarch64-undefined-weak.s @@ -30,9 +30,11 @@ _start: .xword target - . // R_AARCH64_PREL16 .hword target - . +// R_AARCH64_LD_PREL_LO19 + ldr x8, target // CHECK: Disassembly of section .text: -// 131076 = 0x20004 +// 131072 = 0x20000 // CHECK: 20000: {{.*}} b #4 // CHECK-NEXT: 20004: {{.*}} bl #4 // CHECK-NEXT: 20008: {{.*}} b.eq #4 @@ -43,3 +45,5 @@ _start: // CHECK-NEXT: 2001c: {{.*}} .word 0x00000000 // CHECK-NEXT: 20020: {{.*}} .word 0x00000000 // CHECK-NEXT: 20024: {{.*}} .short 0x0000 +// CHECK: $x.2: +// CHECK-NEXT: 20026: {{.*}} ldr x8, #0 diff --git a/test/ELF/abs-hidden.s b/test/ELF/abs-hidden.s index 5fad4cf6c40d..82d19cdc015a 100644 --- a/test/ELF/abs-hidden.s +++ b/test/ELF/abs-hidden.s @@ -1,7 +1,7 @@ // 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: ld.lld --hash-style=sysv %t.o %t2.o -o %t.so -shared // RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s .quad foo diff --git a/test/ELF/allow-multiple-definition.s b/test/ELF/allow-multiple-definition.s index e4637e1a5367..c54438d9f1e0 100644 --- a/test/ELF/allow-multiple-definition.s +++ b/test/ELF/allow-multiple-definition.s @@ -8,6 +8,11 @@ # RUN: llvm-objdump -d %t3 | FileCheck %s # RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s +# RUN: ld.lld -z muldefs %t1 %t2 -o %t3 +# RUN: ld.lld -z muldefs %t2 %t1 -o %t4 +# RUN: llvm-objdump -d %t3 | FileCheck %s +# RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s + # inputs contain different constants for instuction movl. # Tests below checks that order of files in command line # affects on what symbol will be used. diff --git a/test/ELF/amdgpu-elf-flags-err.s b/test/ELF/amdgpu-elf-flags-err.s new file mode 100644 index 000000000000..4c295b5b92e4 --- /dev/null +++ b/test/ELF/amdgpu-elf-flags-err.s @@ -0,0 +1,7 @@ +# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o +# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o +# RUN: not ld.lld -shared %t-0.o %t-1.o %S/Inputs/amdgpu-kernel-2.o -o %t.so 2>&1 | FileCheck %s + +# REQUIRES: amdgpu + +# CHECK: error: incompatible e_flags: {{.*}}amdgpu-kernel-2.o diff --git a/test/ELF/amdgpu-elf-flags.s b/test/ELF/amdgpu-elf-flags.s new file mode 100644 index 000000000000..85f891a98364 --- /dev/null +++ b/test/ELF/amdgpu-elf-flags.s @@ -0,0 +1,10 @@ +# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-0.s -o %t-0.o +# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj %S/Inputs/amdgpu-kernel-1.s -o %t-1.o +# RUN: ld.lld -shared %t-0.o %t-1.o -o %t.so +# RUN: llvm-readobj -file-headers %t.so | FileCheck %s + +# REQUIRES: amdgpu + +# CHECK: Flags [ (0x2) +# CHECK: EF_AMDGPU_ARCH_GCN (0x2) +# CHECK: ] diff --git a/test/ELF/amdgpu-relocs.s b/test/ELF/amdgpu-relocs.s index 1adb1faf20fd..8b5a61ed21f4 100644 --- a/test/ELF/amdgpu-relocs.s +++ b/test/ELF/amdgpu-relocs.s @@ -1,5 +1,5 @@ # RUN: llvm-mc -filetype=obj -triple=amdgcn--amdhsa -mcpu=fiji %s -o %t.o -# RUN: ld.lld -shared %t.o -o %t.so +# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so # RUN: llvm-readobj -r %t.so | FileCheck %s # RUN: llvm-objdump -s %t.so | FileCheck %s --check-prefix=OBJDUMP @@ -65,10 +65,23 @@ ptr: .quad temp .size ptr, 8 +# R_AMDGPU_RELATIVE64: + .type temp2, @object + .local temp2 + .size temp2, 4 + + .type ptr2, @object + .globl ptr2 + .size ptr2, 8 + .p2align 3 +ptr2: + .quad temp2 + # The relocation for local_var{0, 1, 2} and var should be resolved by the # linker. # CHECK: Relocations [ # CHECK: .rela.dyn { +# CHECK-NEXT: R_AMDGPU_RELATIVE64 - 0x0 # CHECK-NEXT: R_AMDGPU_ABS64 common_var0 0x0 # CHECK-NEXT: R_AMDGPU_ABS64 common_var1 0x0 # CHECK-NEXT: R_AMDGPU_ABS64 common_var2 0x0 diff --git a/test/ELF/arm-bl-v6.s b/test/ELF/arm-bl-v6.s new file mode 100644 index 000000000000..6317aa433d6c --- /dev/null +++ b/test/ELF/arm-bl-v6.s @@ -0,0 +1,51 @@ +// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 | FileCheck %s +// REQUIRES: arm + +// On Arm v6 the range of a Thumb BL instruction is only 4 megabytes as the +// extended range encoding is not supported. The following example has a Thumb +// BL that is out of range on ARM v6 and requires a range extension thunk. +// As v6 does not support MOVT or MOVW instructions the Thunk must not +// use these instructions either. At present we don't support v6 so we give a +// warning for unsupported features. + +// CHECK: warning: lld uses extended branch encoding, no object with architecture supporting feature detected. +// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected. +// ARM v6 supports blx so we shouldn't see the blx not supported warning. +// CHECK-NOT: warning: lld uses blx instruction, no object with architecture supporting feature detected. + .text + .syntax unified + .cpu arm1176jzf-s + .eabi_attribute 6, 6 @ Tag_CPU_arch + .globl _start + .type _start,%function + .balign 0x1000 +_start: + bl thumbfunc + bx lr + + .thumb + .section .text.2, "ax", %progbits + .globl thumbfunc + .type thumbfunc,%function +thumbfunc: + bl farthumbfunc + +// 6 Megabytes, enough to make farthumbfunc out of range of caller on a v6 +// Arm, but not on a v7 Arm. + .section .text.3, "ax", %progbits + .space 0x200000 + + .section .text.4, "ax", %progbits + .space 0x200000 + + .section .text.5, "ax", %progbits + .space 0x200000 + + .thumb + .section .text.6, "ax", %progbits + .balign 0x1000 + .globl farthumbfunc + .type farthumbfunc,%function +farthumbfunc: + bx lr diff --git a/test/ELF/arm-blx-v4t.s b/test/ELF/arm-blx-v4t.s new file mode 100644 index 000000000000..858b93fd5891 --- /dev/null +++ b/test/ELF/arm-blx-v4t.s @@ -0,0 +1,30 @@ +// RUN: llvm-mc -filetype=obj -triple=arm-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 | FileCheck %s +// REQUIRES: arm + +// On Arm v4t there is no blx instruction so all interworking must go via +// a thunk. At present we don't support v4t so we give a warning for unsupported +// features. + +// CHECK: warning: lld uses blx instruction, no object with architecture supporting feature detected. +// CHECK-NEXT: warning: lld uses extended branch encoding, no object with architecture supporting feature detected. +// CHECK-NEXT: warning: lld may use movt/movw, no object with architecture supporting feature detected. + + .text + .syntax unified + .cpu arm7tdmi + .eabi_attribute 6, 2 @ Tag_CPU_arch + .arm + .globl _start + .type _start,%function + .p2align 2 +_start: + bl thumbfunc + bx lr + + .thumb + .section .text.2, "ax", %progbits + .globl thumbfunc + .type thumbfunc,%function +thumbfunc: + bx lr diff --git a/test/ELF/arm-branch-error.s b/test/ELF/arm-branch-error.s deleted file mode 100644 index f1a855d7373f..000000000000 --- a/test/ELF/arm-branch-error.s +++ /dev/null @@ -1,19 +0,0 @@ -// 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-rangethunk.s b/test/ELF/arm-branch-rangethunk.s new file mode 100644 index 000000000000..c61ec899adae --- /dev/null +++ b/test/ELF/arm-branch-rangethunk.s @@ -0,0 +1,34 @@ +// 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: ld.lld %t %tfar -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | 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: Disassembly of section .text: +// CHECK-NEXT: _start: +// CHECK-NEXT: 20000: 01 00 00 eb bl #4 <__ARMv7ABSLongThunk_too_far1> +// CHECK-NEXT: 20004: 03 00 00 ea b #12 <__ARMv7ABSLongThunk_too_far2> +// CHECK-NEXT: 20008: 05 00 00 0a beq #20 <__ARMv7ABSLongThunk_too_far3> +// CHECK: __ARMv7ABSLongThunk_too_far1: +// CHECK-NEXT: 2000c: 08 c0 00 e3 movw r12, #8 +// CHECK-NEXT: 20010: 02 c2 40 e3 movt r12, #514 +// CHECK-NEXT: 20014: 1c ff 2f e1 bx r12 +// CHECK: __ARMv7ABSLongThunk_too_far2: +// CHECK-NEXT: 20018: 0c c0 00 e3 movw r12, #12 +// CHECK-NEXT: 2001c: 02 c2 40 e3 movt r12, #514 +// CHECK-NEXT: 20020: 1c ff 2f e1 bx r12 +// CHECK: __ARMv7ABSLongThunk_too_far3: +// CHECK-NEXT: 20024: 10 c0 00 e3 movw r12, #16 +// CHECK-NEXT: 20028: 02 c2 40 e3 movt r12, #514 +// CHECK-NEXT: 2002c: 1c ff 2f e1 bx r12 diff --git a/test/ELF/arm-branch-undef-weak-plt-thunk.s b/test/ELF/arm-branch-undef-weak-plt-thunk.s new file mode 100644 index 000000000000..f95da0dcec21 --- /dev/null +++ b/test/ELF/arm-branch-undef-weak-plt-thunk.s @@ -0,0 +1,35 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-shared.s -o %t +// RUN: ld.lld %t --shared -o %t.so +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2 +// RUN: ld.lld %t2 %t.so -o %t3 +// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi -start-address=69632 -stop-address=69664 %t3 | FileCheck %s +// REQUIRES: arm + +// When we are dynamic linking, undefined weak references have a PLT entry so +// we must create a thunk for the branch to the PLT entry. + + .text + .globl bar2 + .weak undefined_weak_we_expect_a_plt_entry_for +_start: + .globl _start + .type _start, %function + b undefined_weak_we_expect_a_plt_entry_for + bl bar2 +// Create 32 Mb gap between the call to the weak reference and the PLT so that +// the b and bl need a range-extension thunk. + .section .text.1, "ax", %progbits + .space 32 * 1024 * 1024 + +// CHECK: Disassembly of section .text: +// CHECK-NEXT: _start: +// CHECK-NEXT: 11000: 00 00 00 ea b #0 <__ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for> +// CHECK-NEXT: 11004: 02 00 00 eb bl #8 <__ARMv7ABSLongThunk_bar2> +// CHECK: __ARMv7ABSLongThunk_undefined_weak_we_expect_a_plt_entry_for: +// CHECK-NEXT: 11008: 40 c0 01 e3 movw r12, #4160 +// CHECK-NEXT: 1100c: 01 c2 40 e3 movt r12, #513 +// CHECK-NEXT: 11010: 1c ff 2f e1 bx r12 +// CHECK: __ARMv7ABSLongThunk_bar2: +// CHECK-NEXT: 11014: 50 c0 01 e3 movw r12, #4176 +// CHECK-NEXT: 11018: 01 c2 40 e3 movt r12, #513 +// CHECK-NEXT: 1101c: 1c ff 2f e1 bx r12 diff --git a/test/ELF/arm-copy.s b/test/ELF/arm-copy.s index e5ce1577babd..dc9e3628de4f 100644 --- a/test/ELF/arm-copy.s +++ b/test/ELF/arm-copy.s @@ -2,7 +2,7 @@ // 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: ld.lld --hash-style=sysv %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 diff --git a/test/ELF/arm-exidx-dedup.s b/test/ELF/arm-exidx-dedup.s new file mode 100644 index 000000000000..1648f77152e9 --- /dev/null +++ b/test/ELF/arm-exidx-dedup.s @@ -0,0 +1,126 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t --no-merge-exidx-entries -o %t2 +// RUN: llvm-objdump -s %t2 | FileCheck --check-prefix CHECK-DUPS %s +// RUN: ld.lld %t -o %t3 +// RUN: llvm-objdump -s %t3 | FileCheck %s +// REQUIRES: arm +// Test that lld can at least remove duplicate .ARM.exidx sections. A more +// fine grained implementation will be able to remove duplicate entries within +// a .ARM.exidx section. + +// With duplicate entries +// CHECK-DUPS: Contents of section .ARM.exidx: +// CHECK-DUPS-NEXT: 100d4 2c0f0000 01000000 280f0000 01000000 +// CHECK-DUPS-NEXT: 100e4 240f0000 01000000 200f0000 01000000 +// CHECK-DUPS-NEXT: 100f4 1c0f0000 08849780 180f0000 08849780 +// CHECK-DUPS-NEXT: 10104 140f0000 08849780 100f0000 14000000 +// CHECK-DUPS-NEXT: 10114 0c0f0000 18000000 080f0000 01000000 +// CHECK-DUPS-NEXT: Contents of section .ARM.extab: + +// After duplicate entry removal +// CHECK: Contents of section .ARM.exidx: +// CHECK-NEXT: 100d4 2c0f0000 01000000 340f0000 08849780 +// CHECK-NEXT: 100e4 380f0000 14000000 340f0000 18000000 +// CHECK-NEXT: 100f4 300f0000 01000000 +// CHECK-NEXT: Contents of section .ARM.extab: + .syntax unified + + // Expect 1 EXIDX_CANTUNWIND entry. + .section .text.00, "ax", %progbits + .globl _start +_start: + .fnstart + bx lr + .cantunwind + .fnend + + // Expect .ARM.exidx.text.01 to be identical to .ARM.exidx.text.00 + .section .text.01, "ax", %progbits + .globl f1 +f1: + .fnstart + bx lr + .cantunwind + .fnend + + // Expect 2 EXIDX_CANTUNWIND entries, these can be duplicated into + // .ARM.exid.text.00 + .section .text.02, "ax", %progbits + .globl f2 +f2: + .fnstart + bx lr + .cantunwind + .fnend + + .globl f3 +f3: + .fnstart + bx lr + .cantunwind + .fnend + + // Expect inline unwind instructions, not a duplicate of previous entry. + .section .text.03, "ax", %progbits + .global f4 +f4: + .fnstart + bx lr + .save {r7, lr} + .setfp r7, sp, #0 + .fnend + + // Expect 2 inline unwind entries that are a duplicate of + // .ARM.exidx.text.03 + .section .text.04, "ax", %progbits + .global f5 +f5: + .fnstart + bx lr + .save {r7, lr} + .setfp r7, sp, #0 + .fnend + + .global f6 +f6: + .fnstart + bx lr + .save {r7, lr} + .setfp r7, sp, #0 + .fnend + + // Expect a section with a reference to an .ARM.extab. Not a duplicate + // of previous inline table entry. + .section .text.05, "ax",%progbits + .global f7 +f7: + .fnstart + bx lr + .personality __gxx_personality_v0 + .handlerdata + .long 0 + .fnend + + // Expect a reference to an identical .ARM.extab. We do not try to + // deduplicate references to .ARM.extab sections. + .section .text.06, "ax",%progbits + .global f8 +f8: + .fnstart + bx lr + .personality __gxx_personality_v0 + .handlerdata + .long 0 + .fnend + + // Dummy implementation of personality routines to satisfy reference from + // exception tables + .section .text.__gcc_personality_v0, "ax", %progbits + .global __gxx_personality_v0 +__gxx_personality_v0: + bx lr + + .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits + .global __aeabi_unwind_cpp_pr0 +__aeabi_unwind_cpp_pr0: + bx lr diff --git a/test/ELF/arm-exidx-gc.s b/test/ELF/arm-exidx-gc.s index 1336c256f7c1..34bd9dbe37b2 100644 --- a/test/ELF/arm-exidx-gc.s +++ b/test/ELF/arm-exidx-gc.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t -// RUN: ld.lld %t -o %t2 --gc-sections 2>&1 +// RUN: ld.lld %t --no-merge-exidx-entries -o %t2 --gc-sections 2>&1 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s // REQUIRES: arm diff --git a/test/ELF/arm-exidx-order.s b/test/ELF/arm-exidx-order.s index 951c71a4c33e..c988ad8a2cfe 100644 --- a/test/ELF/arm-exidx-order.s +++ b/test/ELF/arm-exidx-order.s @@ -1,6 +1,6 @@ // 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/arm-exidx-cantunwind.s -o %tcantunwind -// RUN: ld.lld %t %tcantunwind -o %t2 2>&1 +// RUN: ld.lld --no-merge-exidx-entries %t %tcantunwind -o %t2 2>&1 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s // RUN: llvm-readobj --program-headers --sections %t2 | FileCheck -check-prefix=CHECK-PT %s @@ -8,7 +8,7 @@ // RUN: echo "SECTIONS { \ // RUN: .text 0x11000 : { *(.text*) } \ // RUN: .ARM.exidx : { *(.ARM.exidx) } } " > %t.script -// RUN: ld.lld --script %t.script %tcantunwind %t -o %t3 2>&1 +// RUN: ld.lld --no-merge-exidx-entries --script %t.script %tcantunwind %t -o %t3 2>&1 // RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT %s // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT-EXIDX %s // REQUIRES: arm diff --git a/test/ELF/arm-exidx-sentinel-orphan.s b/test/ELF/arm-exidx-sentinel-orphan.s index c054fe940db6..0e68c245dd10 100644 --- a/test/ELF/arm-exidx-sentinel-orphan.s +++ b/test/ELF/arm-exidx-sentinel-orphan.s @@ -4,7 +4,7 @@ // RUN: echo "SECTIONS { \ // RUN: .text 0x11000 : { *(.text*) } \ // RUN: } " > %t.script -// RUN: ld.lld --script %t.script %t -o %t2 +// RUN: ld.lld --no-merge-exidx-entries --script %t.script %t -o %t2 // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/arm-exidx-shared.s b/test/ELF/arm-exidx-shared.s index e06733352a37..bf7c2dc383e7 100644 --- a/test/ELF/arm-exidx-shared.s +++ b/test/ELF/arm-exidx-shared.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t -// RUN: ld.lld %t --shared -o %t2 2>&1 +// RUN: ld.lld --hash-style=sysv %t --shared -o %t2 2>&1 // RUN: llvm-readobj --relocations %t2 | FileCheck %s // RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXTAB %s // REQUIRES: arm @@ -41,5 +41,5 @@ __aeabi_unwind_cpp_pr0: // CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0 // CHECK-EXTAB: Contents of section .ARM.extab: -// 014c + 0ed8 = 0x1024 = __gxx_personality_v0(PLT) -// CHECK-EXTAB-NEXT: 014c d80e0000 b0b0b000 00000000 +// 014c + 0ee4 = 0x1030 = __gxx_personality_v0(PLT) +// CHECK-EXTAB-NEXT: 014c e40e0000 b0b0b000 00000000 diff --git a/test/ELF/arm-gnu-ifunc-plt.s b/test/ELF/arm-gnu-ifunc-plt.s index efcaee1e9889..2ff2ec0a143d 100644 --- a/test/ELF/arm-gnu-ifunc-plt.s +++ b/test/ELF/arm-gnu-ifunc-plt.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %S/Inputs/arm-shared.s -o %t1.o // RUN: ld.lld %t1.o --shared -o %t.so // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t.o -// RUN: ld.lld %t.so %t.o -o %tout +// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout // RUN: llvm-objdump -triple=armv7a-linux-gnueabihf -d %tout | FileCheck %s --check-prefix=DISASM // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s @@ -33,49 +33,49 @@ // DISASM-NEXT: 11000: 1e ff 2f e1 bx lr // DISASM: bar: // DISASM-NEXT: 11004: 1e ff 2f e1 bx lr -// DISASM: _start: +// DISASM: _start: // DISASM-NEXT: 11008: 14 00 00 eb bl #80 // DISASM-NEXT: 1100c: 17 00 00 eb bl #92 -// DISASM: 11010: 00 00 00 00 .word 0x00000000 +// DISASM: $d.1: +// DISASM-NEXT: 11010: 00 00 00 00 .word 0x00000000 // DISASM-NEXT: 11014: 04 00 00 00 .word 0x00000004 -// DISASM: 11018: 05 00 00 eb bl #20 -// DISASM-NEXT: 1101c: 08 00 00 eb bl #32 +// DISASM: 11018: 08 00 00 eb bl #32 +// DISASM-NEXT: 1101c: 0b 00 00 eb bl #44 // DISASM-NEXT: Disassembly of section .plt: // DISASM-NEXT: $a: // 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]! +// DISASM-NEXT: 11024: 00 e6 8f e2 add lr, pc, #0, #12 +// DISASM-NEXT: 11028: 00 ea 8e e2 add lr, lr, #0, #20 +// DISASM-NEXT: 1102c: dc ff be e5 ldr pc, [lr, #4060]! // DISASM: $d: -// DISASM-NEXT: 11030: d0 0f 00 00 .word 0x00000fd0 +// DISASM-NEXT: 11030: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DISASM-NEXT: 11034: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DISASM-NEXT: 11038: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DISASM-NEXT: 1103c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DISASM: $a: -// 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] +// DISASM-NEXT: 11040: 00 c6 8f e2 add r12, pc, #0, #12 +// DISASM-NEXT: 11044: 00 ca 8c e2 add r12, r12, #0, #20 +// DISASM-NEXT: 11048: c4 ff bc e5 ldr pc, [r12, #4036]! // DISASM: $d: -// DISASM-NEXT: 11040: cc 0f 00 00 .word 0x00000fcc +// DISASM-NEXT: 1104c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DISASM: $a: -// 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] +// DISASM-NEXT: 11050: 00 c6 8f e2 add r12, pc, #0, #12 +// DISASM-NEXT: 11054: 00 ca 8c e2 add r12, r12, #0, #20 +// DISASM-NEXT: 11058: b8 ff bc e5 ldr pc, [r12, #4024]! // DISASM: $d: -// DISASM-NEXT: 11050: c0 0f 00 00 .word 0x00000fc0 -// Alignment to 16 byte boundary not strictly necessary on ARM, but harmless -// DISASM-NEXT: 11054: d4 d4 d4 d4 .word 0xd4d4d4d4 -// DISASM-NEXT: 11058: d4 d4 d4 d4 .word 0xd4d4d4d4 // DISASM-NEXT: 1105c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DISASM: $a: -// DISASM-NEXT: 11060: 04 c0 9f e5 ldr r12, [pc, #4] -// DISASM-NEXT: 11064: 0f c0 8c e0 add r12, r12, pc -// DISASM-NEXT: 11068: 00 f0 9c e5 ldr pc, [r12] +// DISASM-NEXT: 11060: 00 c6 8f e2 add r12, pc, #0, #12 +// DISASM-NEXT: 11064: 02 ca 8c e2 add r12, r12, #8192 +// DISASM-NEXT: 11068: 18 f0 bc e5 ldr pc, [r12, #24]! // DISASM: $d: -// DISASM-NEXT: 1106c: 14 20 00 00 .word 0x00002014 +// DISASM-NEXT: 1106c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DISASM: $a: -// DISASM-NEXT: 11070: 04 c0 9f e5 ldr r12, [pc, #4] -// DISASM-NEXT: 11074: 0f c0 8c e0 add r12, r12, pc -// DISASM-NEXT: 11078: 00 f0 9c e5 ldr pc, [r12] +// DISASM-NEXT: 11070: 00 c6 8f e2 add r12, pc, #0, #12 +// DISASM-NEXT: 11074: 02 ca 8c e2 add r12, r12, #8192 +// DISASM-NEXT: 11078: 0c f0 bc e5 ldr pc, [r12, #12]! // DISASM: $d: -// DISASM-NEXT: 1107c: 08 20 00 00 .word 0x00002008 +// DISASM-NEXT: 1107c: d4 d4 d4 d4 .word 0xd4d4d4d4 .syntax unified .text diff --git a/test/ELF/arm-gnu-ifunc.s b/test/ELF/arm-gnu-ifunc.s index 23c540310b3c..799b8b17f62b 100644 --- a/test/ELF/arm-gnu-ifunc.s +++ b/test/ELF/arm-gnu-ifunc.s @@ -111,30 +111,29 @@ _start: // 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: 04 00 00 eb bl #16 -// DISASM-NEXT: 1100c: 07 00 00 eb bl #28 +// 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: 04 00 00 eb bl #16 +// DISASM-NEXT: 1100c: 07 00 00 eb bl #28 // 1 * 65536 + 244 = 0x100f4 __rel_iplt_start -// DISASM-NEXT: 11010: f4 00 00 e3 movw r0, #244 -// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1 +// DISASM-NEXT: 11010: f4 00 00 e3 movw r0, #244 +// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1 // 1 * 65536 + 260 = 0x10104 __rel_iplt_end -// DISASM-NEXT: 11018: 04 01 00 e3 movw r0, #260 -// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1 +// DISASM-NEXT: 11018: 04 01 00 e3 movw r0, #260 +// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1 // DISASM-NEXT: Disassembly of section .plt: -// DISASM: $a: -// DISASM-NEXT: 11020: 04 c0 9f e5 ldr r12, [pc, #4] -// DISASM-NEXT: 11024: 0f c0 8c e0 add r12, r12, pc -// 11024 + 8 + fd4 = 0x12000 -// DISASM-NEXT: 11028: 00 f0 9c e5 ldr pc, [r12] +// DISASM-NEXT: $a: +// DISASM-NEXT: 11020: 00 c6 8f e2 add r12, pc, #0, #12 +// DISASM-NEXT: 11024: 00 ca 8c e2 add r12, r12, #0, #20 +// DISASM-NEXT: 11028: d8 ff bc e5 ldr pc, [r12, #4056]! // DISASM: $d: -// DISASM-NEXT: 1102c: d4 0f 00 00 .word 0x00000fd4 +// DISASM-NEXT: 1102c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DISASM: $a: -// DISASM-NEXT: 11030: 04 c0 9f e5 ldr r12, [pc, #4] -// DISASM-NEXT: 11034: 0f c0 8c e0 add r12, r12, pc -// 11034 + 8 + fc8 = 0x12004 -// DISASM-NEXT: 11038: 00 f0 9c e5 ldr pc, [r12] +// DISASM-NEXT: 11030: 00 c6 8f e2 add r12, pc, #0, #12 +// DISASM-NEXT: 11034: 00 ca 8c e2 add r12, r12, #0, #20 +// DISASM-NEXT: 11038: cc ff bc e5 ldr pc, [r12, #4044]! // DISASM: $d: -// DISASM-NEXT: 1103c: c8 0f 00 00 .word 0x00000fc8 +// DISASM-NEXT: 1103c: d4 d4 d4 d4 .word 0xd4d4d4d4 + diff --git a/test/ELF/arm-got-relative.s b/test/ELF/arm-got-relative.s index 46a3ca97d080..cf8b0a64a966 100644 --- a/test/ELF/arm-got-relative.s +++ b/test/ELF/arm-got-relative.s @@ -1,6 +1,6 @@ // 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: ld.lld --hash-style=sysv %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 diff --git a/test/ELF/arm-icf-exidx.s b/test/ELF/arm-icf-exidx.s index 6af30285db67..629505cb7ffa 100644 --- a/test/ELF/arm-icf-exidx.s +++ b/test/ELF/arm-icf-exidx.s @@ -23,7 +23,7 @@ __aeabi_unwind_cpp_pr0: bx lr // CHECK: Disassembly of section .text: -// CHECK-NEXT: f: +// CHECK-NEXT: g: // CHECK-NEXT: 11000: 1e ff 2f e1 bx lr // CHECK: __aeabi_unwind_cpp_pr0: // CHECK-NEXT: 11004: 00 f0 20 e3 nop diff --git a/test/ELF/arm-pie-relative.s b/test/ELF/arm-pie-relative.s index f965c24f4fa6..f225015eb5f3 100644 --- a/test/ELF/arm-pie-relative.s +++ b/test/ELF/arm-pie-relative.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t -// RUN: ld.lld %t --pie -o %t2 +// RUN: ld.lld --hash-style=sysv %t --pie -o %t2 // RUN: llvm-readobj -r %t2 | FileCheck %s // RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=GOT // REQUIRES: arm diff --git a/test/ELF/arm-plt-reloc.s b/test/ELF/arm-plt-reloc.s index 1588f745f22c..f8166d60ffcf 100644 --- a/test/ELF/arm-plt-reloc.s +++ b/test/ELF/arm-plt-reloc.s @@ -2,7 +2,7 @@ // 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: ld.lld --hash-style=sysv -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 @@ -32,51 +32,55 @@ _start: // CHECK-NEXT: 11014: fb ff ff 0a beq #-20 <func3> // Expect PLT entries as symbols can be preempted +// The .got.plt and .plt displacement is small so we can use small PLT entries. // DSO: Disassembly of section .text: // DSO-NEXT: func1: -// DSO-NEXT: 1000: 1e ff 2f e1 bx lr +// DSO-NEXT: 1000: 1e ff 2f e1 bx lr // DSO: func2: -// DSO-NEXT: 1004: 1e ff 2f e1 bx lr +// DSO-NEXT: 1004: 1e ff 2f e1 bx lr // DSO: func3: -// DSO-NEXT: 1008: 1e ff 2f e1 bx lr +// 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: +// S(0x1040) - P(0x100c) + A(-8) = 0x2c = 32 +// DSO-NEXT: 100c: 0b 00 00 ea b #44 +// S(0x1050) - P(0x1010) + A(-8) = 0x38 = 56 +// DSO-NEXT: 1010: 0e 00 00 eb bl #56 +// S(0x10160) - P(0x1014) + A(-8) = 0x44 = 68 +// DSO-NEXT: 1014: 11 00 00 0a beq #68 +// DSO-NEXT: Disassembly of section .plt: // DSO-NEXT: $a: // 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 + 0fd0 = 0x2000 +// (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfdc) = 0x2008 = .got.plt[3] +// DSO-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12 +// DSO-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20 +// DSO-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]! // DSO: $d: -// DSO-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0 +// DSO-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DSO-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DSO-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DSO-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DSO: $a: -// 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 + 0fcc = 0x200c +// (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfc4) = 0x200c +// DSO-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12 +// DSO-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20 +// DSO-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]! // DSO: $d: -// DSO-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc +// DSO-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DSO: $a: -// 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 + 0fc0 = 0x2010 +// (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfb8) = 0x2010 +// DSO-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12 +// DSO-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20 +// DSO-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]! // DSO: $d: -// DSO-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0 +// DSO-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DSO: $a: -// 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 + 0fb4 = 0x2014 +// (0x1060 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfac) = 0x2014 +// DSO-NEXT: 1060: 00 c6 8f e2 add r12, pc, #0, #12 +// DSO-NEXT: 1064: 00 ca 8c e2 add r12, r12, #0, #20 +// DSO-NEXT: 1068: ac ff bc e5 ldr pc, [r12, #4012]! // DSO: $d: -// DSO-NEXT: 1060: b4 0f 00 00 .word 0x00000fb4 +// DSO-NEXT: 106c: d4 d4 d4 d4 .word 0xd4d4d4d4 + // DSOREL: Name: .got.plt // DSOREL-NEXT: Type: SHT_PROGBITS @@ -96,3 +100,199 @@ _start: // DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0 // DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0 // DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0 + +// Test a large separation between the .plt and .got.plt +// The .got.plt and .plt displacement is large but still within the range +// of the short plt sequence. +// RUN: echo "SECTIONS { \ +// RUN: .text 0x1000 : { *(.text) } \ +// RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \ +// RUN: .got.plt 0x1100000 : { *(.got.plt) } \ +// RUN: }" > %t.script +// RUN: ld.lld --hash-style=sysv --script %t.script -shared %t1 %t2 -o %t4 +// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t4 | FileCheck --check-prefix=CHECKHIGH %s +// RUN: llvm-readobj -s -r %t4 | FileCheck --check-prefix=DSORELHIGH %s + +// CHECKHIGH: Disassembly of section .text: +// CHECKHIGH-NEXT: func1: +// CHECKHIGH-NEXT: 1000: 1e ff 2f e1 bx lr +// CHECKHIGH: func2: +// CHECKHIGH-NEXT: 1004: 1e ff 2f e1 bx lr +// CHECKHIGH: func3: +// CHECKHIGH-NEXT: 1008: 1e ff 2f e1 bx lr +// CHECKHIGH: _start: +// CHECKHIGH-NEXT: 100c: 03 04 00 ea b #4108 <$a> +// CHECKHIGH-NEXT: 1010: 06 04 00 eb bl #4120 <$a> +// CHECKHIGH-NEXT: 1014: 09 04 00 0a beq #4132 <$a> +// CHECKHIGH-NEXT: Disassembly of section .plt: +// CHECKHIGH-NEXT: $a: +// CHECKHIGH-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]! +// CHECKHIGH-NEXT: 2004: 10 e6 8f e2 add lr, pc, #16, #12 +// CHECKHIGH-NEXT: 2008: fd ea 8e e2 add lr, lr, #1036288 +// CHECKHIGH-NEXT: 200c: fc ff be e5 ldr pc, [lr, #4092]! +// CHECKHIGH: $d: +// CHECKHIGH-NEXT: 2010: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKHIGH-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKHIGH-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKHIGH-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKHIGH: $a: +// CHECKHIGH-NEXT: 2020: 10 c6 8f e2 add r12, pc, #16, #12 +// CHECKHIGH-NEXT: 2024: fd ca 8c e2 add r12, r12, #1036288 +// CHECKHIGH-NEXT: 2028: e4 ff bc e5 ldr pc, [r12, #4068]! +// CHECKHIGH: $d: +// CHECKHIGH-NEXT: 202c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKHIGH: $a: +// CHECKHIGH-NEXT: 2030: 10 c6 8f e2 add r12, pc, #16, #12 +// CHECKHIGH-NEXT: 2034: fd ca 8c e2 add r12, r12, #1036288 +// CHECKHIGH-NEXT: 2038: d8 ff bc e5 ldr pc, [r12, #4056]! +// CHECKHIGH: $d: +// CHECKHIGH-NEXT: 203c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKHIGH: $a: +// CHECKHIGH-NEXT: 2040: 10 c6 8f e2 add r12, pc, #16, #12 +// CHECKHIGH-NEXT: 2044: fd ca 8c e2 add r12, r12, #1036288 +// CHECKHIGH-NEXT: 2048: cc ff bc e5 ldr pc, [r12, #4044]! +// CHECKHIGH: $d: +// CHECKHIGH-NEXT: 204c: d4 d4 d4 d4 .word 0xd4d4d4d4 + +// DSORELHIGH: Name: .got.plt +// DSORELHIGH-NEXT: Type: SHT_PROGBITS +// DSORELHIGH-NEXT: Flags [ +// DSORELHIGH-NEXT: SHF_ALLOC +// DSORELHIGH-NEXT: SHF_WRITE +// DSORELHIGH-NEXT: ] +// DSORELHIGH-NEXT: Address: 0x1100000 +// DSORELHIGH: Relocations [ +// DSORELHIGH-NEXT: Section (6) .rel.plt { +// DSORELHIGH-NEXT: 0x110000C R_ARM_JUMP_SLOT func1 0x0 +// DSORELHIGH-NEXT: 0x1100010 R_ARM_JUMP_SLOT func2 0x0 +// DSORELHIGH-NEXT: 0x1100014 R_ARM_JUMP_SLOT func3 0x0 + +// Test a very large separation between the .plt and .got.plt so we must use +// large plt entries that do not have any range restriction. +// RUN: echo "SECTIONS { \ +// RUN: .text 0x1000 : { *(.text) } \ +// RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \ +// RUN: .got.plt 0x11111100 : { *(.got.plt) } \ +// RUN: }" > %t2.script +// RUN: ld.lld --hash-style=sysv --script %t2.script -shared %t1 %t2 -o %t5 +// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t5 | FileCheck --check-prefix=CHECKLONG %s +// RUN: llvm-readobj -s -r %t5 | FileCheck --check-prefix=DSORELLONG %s + +// CHECKLONG: Disassembly of section .text: +// CHECKLONG-NEXT: func1: +// CHECKLONG-NEXT: 1000: 1e ff 2f e1 bx lr +// CHECKLONG: func2: +// CHECKLONG-NEXT: 1004: 1e ff 2f e1 bx lr +// CHECKLONG: func3: +// CHECKLONG-NEXT: 1008: 1e ff 2f e1 bx lr +// CHECKLONG: _start: +// CHECKLONG-NEXT: 100c: 03 04 00 ea b #4108 <$a> +// CHECKLONG-NEXT: 1010: 06 04 00 eb bl #4120 <$a> +// CHECKLONG-NEXT: 1014: 09 04 00 0a beq #4132 <$a> +// CHECKLONG-NEXT: Disassembly of section .plt: +// CHECKLONG-NEXT: $a: +// CHECKLONG-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]! +// CHECKLONG-NEXT: 2004: 04 e0 9f e5 ldr lr, [pc, #4] +// CHECKLONG-NEXT: 2008: 0e e0 8f e0 add lr, pc, lr +// CHECKLONG-NEXT: 200c: 08 f0 be e5 ldr pc, [lr, #8]! +// CHECKLONG: $d: +// CHECKLONG-NEXT: 2010: f0 f0 10 11 .word 0x1110f0f0 +// CHECKLONG-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKLONG-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKLONG-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKLONG: $a: +// CHECKLONG-NEXT: 2020: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECKLONG-NEXT: 2024: 0f c0 8c e0 add r12, r12, pc +// CHECKLONG-NEXT: 2028: 00 f0 9c e5 ldr pc, [r12] +// CHECKLONG: $d: +// CHECKLONG-NEXT: 202c: e0 f0 10 11 .word 0x1110f0e0 +// CHECKLONG: $a: +// CHECKLONG-NEXT: 2030: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECKLONG-NEXT: 2034: 0f c0 8c e0 add r12, r12, pc +// CHECKLONG-NEXT: 2038: 00 f0 9c e5 ldr pc, [r12] +// CHECKLONG: $d: +// CHECKLONG-NEXT: 203c: d4 f0 10 11 .word 0x1110f0d4 +// CHECKLONG: $a: +// CHECKLONG-NEXT: 2040: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECKLONG-NEXT: 2044: 0f c0 8c e0 add r12, r12, pc +// CHECKLONG-NEXT: 2048: 00 f0 9c e5 ldr pc, [r12] +// CHECKLONG: $d: +// CHECKLONG-NEXT: 204c: c8 f0 10 11 .word 0x1110f0c8 + +// DSORELLONG: Name: .got.plt +// DSORELLONG-NEXT: Type: SHT_PROGBITS +// DSORELLONG-NEXT: Flags [ +// DSORELLONG-NEXT: SHF_ALLOC +// DSORELLONG-NEXT: SHF_WRITE +// DSORELLONG-NEXT: ] +// DSORELLONG-NEXT: Address: 0x11111100 +// DSORELLONG: Relocations [ +// DSORELLONG-NEXT: Section (6) .rel.plt { +// DSORELLONG-NEXT: 0x1111110C R_ARM_JUMP_SLOT func1 0x0 +// DSORELLONG-NEXT: 0x11111110 R_ARM_JUMP_SLOT func2 0x0 +// DSORELLONG-NEXT: 0x11111114 R_ARM_JUMP_SLOT func3 0x0 + +// Test a separation between the .plt and .got.plt that is part in range of +// short table entries and part needing long entries. We use the long entries +// only when we need to. +// RUN: echo "SECTIONS { \ +// RUN: .text 0x1000 : { *(.text) } \ +// RUN: .plt 0x2000 : { *(.plt) *(.plt.*) } \ +// RUN: .got.plt 0x8002020 : { *(.got.plt) } \ +// RUN: }" > %t3.script +// RUN: ld.lld --hash-style=sysv --script %t3.script -shared %t1 %t2 -o %t6 +// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t6 | FileCheck --check-prefix=CHECKMIX %s +// RUN: llvm-readobj -s -r %t6 | FileCheck --check-prefix=DSORELMIX %s + +// CHECKMIX: Disassembly of section .text: +// CHECKMIX-NEXT: func1: +// CHECKMIX-NEXT: 1000: 1e ff 2f e1 bx lr +// CHECKMIX: func2: +// CHECKMIX-NEXT: 1004: 1e ff 2f e1 bx lr +// CHECKMIX: func3: +// CHECKMIX-NEXT: 1008: 1e ff 2f e1 bx lr +// CHECKMIX: _start: +// CHECKMIX-NEXT: 100c: 03 04 00 ea b #4108 <$a> +// CHECKMIX-NEXT: 1010: 06 04 00 eb bl #4120 <$a> +// CHECKMIX-NEXT: 1014: 09 04 00 0a beq #4132 <$a> +// CHECKMIX-NEXT: Disassembly of section .plt: +// CHECKMIX-NEXT: $a: +// CHECKMIX-NEXT: 2000: 04 e0 2d e5 str lr, [sp, #-4]! +// CHECKMIX-NEXT: 2004: 04 e0 9f e5 ldr lr, [pc, #4] +// CHECKMIX-NEXT: 2008: 0e e0 8f e0 add lr, pc, lr +// CHECKMIX-NEXT: 200c: 08 f0 be e5 ldr pc, [lr, #8]! +// CHECKMIX: $d: +// CHECKMIX-NEXT: 2010: 10 00 00 08 .word 0x08000010 +// CHECKMIX-NEXT: 2014: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKMIX-NEXT: 2018: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKMIX-NEXT: 201c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKMIX: $a: +// CHECKMIX-NEXT: 2020: 04 c0 9f e5 ldr r12, [pc, #4] +// CHECKMIX-NEXT: 2024: 0f c0 8c e0 add r12, r12, pc +// CHECKMIX-NEXT: 2028: 00 f0 9c e5 ldr pc, [r12] +// CHECKMIX: $d: +// CHECKMIX-NEXT: 202c: 00 00 00 08 .word 0x08000000 +// CHECKMIX: $a: +// CHECKMIX-NEXT: 2030: 7f c6 8f e2 add r12, pc, #133169152 +// CHECKMIX-NEXT: 2034: ff ca 8c e2 add r12, r12, #1044480 +// CHECKMIX-NEXT: 2038: f8 ff bc e5 ldr pc, [r12, #4088]! +// CHECKMIX: $d: +// CHECKMIX-NEXT: 203c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECKMIX: $a: +// CHECKMIX-NEXT: 2040: 7f c6 8f e2 add r12, pc, #133169152 +// CHECKMIX-NEXT: 2044: ff ca 8c e2 add r12, r12, #1044480 +// CHECKMIX-NEXT: 2048: ec ff bc e5 ldr pc, [r12, #4076]! +// CHECKMIX: $d: +// CHECKMIX-NEXT: 204c: d4 d4 d4 d4 .word 0xd4d4d4d4 + +// DSORELMIX: Name: .got.plt +// DSORELMIX-NEXT: Type: SHT_PROGBITS +// DSORELMIX-NEXT: Flags [ +// DSORELMIX-NEXT: SHF_ALLOC +// DSORELMIX-NEXT: SHF_WRITE +// DSORELMIX-NEXT: ] +// DSORELMIX-NEXT: Address: 0x8002020 +// DSORELMIX: Section (6) .rel.plt { +// DSORELMIX-NEXT: 0x800202C R_ARM_JUMP_SLOT func1 0x0 +// DSORELMIX-NEXT: 0x8002030 R_ARM_JUMP_SLOT func2 0x0 +// DSORELMIX-NEXT: 0x8002034 R_ARM_JUMP_SLOT func3 0x0 diff --git a/test/ELF/arm-static-defines.s b/test/ELF/arm-static-defines.s index 0012841fb32c..815c20ca9451 100644 --- a/test/ELF/arm-static-defines.s +++ b/test/ELF/arm-static-defines.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t -// RUN: ld.lld %t --static -o %t2 2>&1 +// RUN: ld.lld --no-merge-exidx-entries %t --static -o %t2 2>&1 // RUN: llvm-readobj --symbols %t2 | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/arm-thumb-branch-error.s b/test/ELF/arm-thumb-branch-error.s deleted file mode 100644 index de6c1bc16c96..000000000000 --- a/test/ELF/arm-thumb-branch-error.s +++ /dev/null @@ -1,19 +0,0 @@ -// 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-rangethunk.s b/test/ELF/arm-thumb-branch-rangethunk.s new file mode 100644 index 000000000000..f83e64144d70 --- /dev/null +++ b/test/ELF/arm-thumb-branch-rangethunk.s @@ -0,0 +1,36 @@ +// 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: ld.lld %t %tfar -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 +// REQUIRES: arm + .syntax unified + .thumb + .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: Disassembly of section .text: +// CHECK-NEXT: _start: +// CHECK-NEXT: 20000: 00 f0 04 f8 bl #8 +// CHECK-NEXT: 20004: 00 f0 07 b8 b.w #14 <__Thumbv7ABSLongThunk_too_far2> +// CHECK-NEXT: 20008: 00 f0 0a 80 beq.w #20 <__Thumbv7ABSLongThunk_too_far3> +// CHECK: __Thumbv7ABSLongThunk_too_far1: +// CHECK-NEXT: 2000c: 40 f2 05 0c movw r12, #5 +// CHECK-NEXT: 20010: c0 f2 02 1c movt r12, #258 +// CHECK-NEXT: 20014: 60 47 bx r12 +// CHECK: __Thumbv7ABSLongThunk_too_far2: +// CHECK-NEXT: 20016: 40 f2 09 0c movw r12, #9 +// CHECK-NEXT: 2001a: c0 f2 02 1c movt r12, #258 +// CHECK-NEXT: 2001e: 60 47 bx r12 +// CHECK: __Thumbv7ABSLongThunk_too_far3: +// CHECK-NEXT: 20020: 40 f2 0d 0c movw r12, #13 +// CHECK-NEXT: 20024: c0 f2 12 0c movt r12, #18 +// CHECK-NEXT: 20028: 60 47 bx r12 +// CHECK-NEXT: 2002a: 00 00 movs r0, r0 diff --git a/test/ELF/arm-thumb-condbranch-thunk.s b/test/ELF/arm-thumb-condbranch-thunk.s new file mode 100644 index 000000000000..c527e5df297c --- /dev/null +++ b/test/ELF/arm-thumb-condbranch-thunk.s @@ -0,0 +1,117 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 +// The output file is large, most of it zeroes. We dissassemble only the +// parts we need to speed up the test and avoid a large output file +// RUN: llvm-objdump -d %t2 -start-address=524288 -stop-address=524316 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048584 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s +// RUN: llvm-objdump -d %t2 -start-address=1572864 -stop-address=1572872 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s +// RUN: llvm-objdump -d %t2 -start-address=5242884 -stop-address=5242894 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s +// RUN: llvm-objdump -d %t2 -start-address=5767168 -stop-address=5767174 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s +// RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777240 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s +// RUN: llvm-objdump -d %t2 -start-address=17825792 -stop-address=17825798 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s +// Test Range extension Thunks for the Thumb conditional branch instruction. +// This instruction only has a range of 1Mb whereas all the other Thumb wide +// Branch instructions have 16Mb range. We still place our pre-created Thunk +// Sections at 16Mb intervals as conditional branches to a target defined +// in a different section are rare. + .syntax unified +// Define a function aligned on a half megabyte boundary + .macro FUNCTION suff + .section .text.\suff\(), "ax", %progbits + .thumb + .balign 0x80000 + .globl tfunc\suff\() + .type tfunc\suff\(), %function +tfunc\suff\(): + bx lr + .endm + + .globl _start +_start: + FUNCTION 00 +// Long Range Thunk needed for 16Mb range branch, can reach pre-created Thunk +// Section + bl tfunc33 +// CHECK1: Disassembly of section .text: +// CHECK1-NEXT: tfunc00: +// CHECK1-NEXT: 80000: 70 47 bx lr +// CHECK1-NEXT: 80002: 7f f3 ff d7 bl #16252926 +// CHECK1: __Thumbv7ABSLongThunk_tfunc05: +// CHECK1-NEXT: 80008: 40 f2 01 0c movw r12, #1 +// CHECK1-NEXT: 8000c: c0 f2 30 0c movt r12, #48 +// CHECK1-NEXT: 80010: 60 47 bx r12 +// CHECK1: __Thumbv7ABSLongThunk_tfunc00: +// CHECK1-NEXT: 80012: 40 f2 01 0c movw r12, #1 +// CHECK1-NEXT: 80016: c0 f2 08 0c movt r12, #8 +// CHECK1-NEXT: 8001a: 60 47 bx r12 + FUNCTION 01 +// tfunc02 is within range of tfunc02 + beq.w tfunc02 +// tfunc05 is out of range, and we can't reach the pre-created Thunk Section +// create a new one. + bne.w tfunc05 +// CHECK2: tfunc01: +// CHECK2-NEXT: 100000: 70 47 bx lr +// CHECK2-NEXT: 100002: 3f f0 fd a7 beq.w #524282 <tfunc02> +// CHECK2-NEXT: 100006: 7f f4 ff a7 bne.w #-524290 <__Thumbv7ABSLongThunk_tfunc05> + FUNCTION 02 +// We can reach the Thunk Section created for bne.w tfunc05 + bne.w tfunc05 + beq.w tfunc00 +// CHECK3: 180000: 70 47 bx lr +// CHECK3-NEXT: 180002: 40 f4 01 80 bne.w #-1048574 <__Thumbv7ABSLongThunk_tfunc05> +// CHECK3-NEXT: 180006: 00 f4 04 80 beq.w #-1048568 <__Thumbv7ABSLongThunk_tfunc00> + FUNCTION 03 + FUNCTION 04 + FUNCTION 05 + FUNCTION 06 + FUNCTION 07 + FUNCTION 08 + FUNCTION 09 +// CHECK4: __Thumbv7ABSLongThunk_tfunc03: +// CHECK4-NEXT: 500004: 40 f2 01 0c movw r12, #1 +// CHECK4-NEXT: 500008: c0 f2 20 0c movt r12, #32 +// CHECK4-NEXT: 50000c: 60 47 bx r12 + FUNCTION 10 +// We can't reach any Thunk Section, create a new one + beq.w tfunc03 +// CHECK5: tfunc10: +// CHECK5-NEXT: 580000: 70 47 bx lr +// CHECK5-NEXT: 580002: 3f f4 ff a7 beq.w #-524290 <__Thumbv7ABSLongThunk_tfunc03> + FUNCTION 11 + FUNCTION 12 + FUNCTION 13 + FUNCTION 14 + FUNCTION 15 + FUNCTION 16 + FUNCTION 17 + FUNCTION 18 + FUNCTION 19 + FUNCTION 20 + FUNCTION 21 + FUNCTION 22 + FUNCTION 23 + FUNCTION 24 + FUNCTION 25 + FUNCTION 26 + FUNCTION 27 + FUNCTION 28 + FUNCTION 29 + FUNCTION 30 + FUNCTION 31 +// CHECK6: __Thumbv7ABSLongThunk_tfunc33: +// CHECK6-NEXT: 1000004: 40 f2 01 0c movw r12, #1 +// CHECK6-NEXT: 1000008: c0 f2 10 1c movt r12, #272 +// CHECK6-NEXT: 100000c: 60 47 bx r12 +// CHECK6: __Thumbv7ABSLongThunk_tfunc00: +// CHECK6-NEXT: 100000e: 40 f2 01 0c movw r12, #1 +// CHECK6-NEXT: 1000012: c0 f2 08 0c movt r12, #8 +// CHECK6-NEXT: 1000016: 60 47 bx r12 + FUNCTION 32 + FUNCTION 33 + // We should be able to reach an existing ThunkSection. + b.w tfunc00 +// CHECK7: tfunc33: +// CHECK7-NEXT: 1100000: 70 47 bx lr +// CHECK7-NEXT: 1100002: 00 f7 04 b8 b.w #-1048568 <__Thumbv7ABSLongThunk_tfunc00> diff --git a/test/ELF/arm-thumb-interwork-shared.s b/test/ELF/arm-thumb-interwork-shared.s index 8362ae26aed4..cadcd451ad67 100644 --- a/test/ELF/arm-thumb-interwork-shared.s +++ b/test/ELF/arm-thumb-interwork-shared.s @@ -19,34 +19,37 @@ sym1: // CHECK-NEXT: 1000: 00 f0 02 b8 b.w #4 <__ThumbV7PILongThunk_elsewhere> // CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12 <__ThumbV7PILongThunk_weakref> // CHECK: __ThumbV7PILongThunk_elsewhere: -// CHECK-NEXT: 1008: 40 f2 20 0c movw r12, #32 +// CHECK-NEXT: 1008: 40 f2 2c 0c movw r12, #44 // CHECK-NEXT: 100c: c0 f2 00 0c movt r12, #0 // CHECK-NEXT: 1010: fc 44 add r12, pc // CHECK-NEXT: 1012: 60 47 bx r12 - // CHECK: __ThumbV7PILongThunk_weakref: -// CHECK-NEXT: 1014: 40 f2 24 0c movw r12, #36 +// CHECK-NEXT: 1014: 40 f2 30 0c movw r12, #48 // CHECK-NEXT: 1018: c0 f2 00 0c movt r12, #0 // CHECK-NEXT: 101c: fc 44 add r12, pc // CHECK-NEXT: 101e: 60 47 bx r12 // PLT: Disassembly of section .plt: -// PLT: $a: -// PLT-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! -// PLT-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4] -// PLT-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr -// PLT-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]! +// PLT-NEXT: $a: +// PLT-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]! +// PLT-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12 +// PLT-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20 +// PLT-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]! // PLT: $d: -// PLT-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0 +// PLT-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4 +// PLT-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4 +// PLT-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4 +// PLT-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4 // PLT: $a: -// PLT-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4] -// PLT-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc -// PLT-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12] +// PLT-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12 +// PLT-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20 +// PLT-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]! // PLT: $d: -// PLT-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc +// PLT-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4 // PLT: $a: -// PLT-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4] -// PLT-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc -// PLT-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12] +// PLT-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12 +// PLT-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20 +// PLT-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]! // PLT: $d: -// PLT-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0 +// PLT-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4 + diff --git a/test/ELF/arm-thumb-mix-range-thunk-os.s b/test/ELF/arm-thumb-mix-range-thunk-os.s new file mode 100644 index 000000000000..beff4148b6ff --- /dev/null +++ b/test/ELF/arm-thumb-mix-range-thunk-os.s @@ -0,0 +1,195 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 +// The output file is large, most of it zeroes. We dissassemble only the +// parts we need to speed up the test and avoid a large output file +// RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048604 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t2 -start-address=2097152 -stop-address=2097162 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s +// RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777232 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s +// RUN: llvm-objdump -d %t2 -start-address=16777232 -stop-address=16777242 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s +// RUN: llvm-objdump -d %t2 -start-address=32505860 -stop-address=32505870 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s +// RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651590 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s +// RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700168 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s +// RUN: llvm-objdump -d %t2 -start-address=48234500 -stop-address=48234512 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s +// RUN: llvm-objdump -d %t2 -start-address=63963140 -stop-address=63963160 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s +// RUN: llvm-objdump -d %t2 -start-address=68157440 -stop-address=68157452 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s +// RUN: llvm-objdump -d %t2 -start-address=69206016 -stop-address=69206024 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK11 %s + +// Test the Range extension Thunks for ARM and Thumb when all the code is in a +// single OutputSection. The ARM branches and branch and link instructions +// have a range of 32Mb, the Thumb unconditional branch and +// branch and link instructions have . We create a series of Functions a +// megabyte apart. We expect range extension thunks to be created when a +// branch is out of range. Thunks will be reused whenever they are in range + .syntax unified + +// Define a function aligned on a megabyte boundary + .macro ARMFUNCTION suff + .section .text.\suff\(), "ax", %progbits + .arm + .balign 0x100000 + .globl afunc\suff\() + .type afunc\suff\(), %function +afunc\suff\(): + bx lr + .endm + +// Define a function aligned on a megabyte boundary + .macro THUMBFUNCTION suff + .section .text.\suff\(), "ax", %progbits + .thumb + .balign 0x100000 + .globl tfunc\suff\() + .type tfunc\suff\(), %function +tfunc\suff\(): + bx lr + .endm + + .section .text, "ax", %progbits + .thumb + .globl _start +_start: + + ARMFUNCTION 00 +// Expect ARM bl to be in range (can use blx to change state) + bl tfunc31 +// ARM b and beq are in range but need Thunk to change state to Thumb + b tfunc31 + beq tfunc31 +// afunc32 is out of range of ARM branch and branch and link + bl afunc32 + b afunc32 + bne afunc32 +// CHECK1: afunc00: +// CHECK1-NEXT: 100000: 1e ff 2f e1 bx lr +// CHECK1-NEXT: 100004: fd ff 7b fa blx #32505844 +// CHECK1-NEXT: 100008: fd ff 3b ea b #15728628 +// CHECK1-NEXT: 10000c: fc ff 3b 0a beq #15728624 +// CHECK1-NEXT: 100010: fa ff 7f eb bl #33554408 +// CHECK1-NEXT: 100014: f9 ff 7f ea b #33554404 +// CHECK1-NEXT: 100018: f8 ff 7f 1a bne #33554400 + THUMBFUNCTION 01 +// Expect Thumb bl to be in range (can use blx to change state) + bl afunc14 +// In range but need thunk to change state to Thumb + b.w afunc14 +// CHECK2: tfunc01: +// CHECK2-NEXT: 200000: 70 47 bx lr +// CHECK2-NEXT: 200002: ff f0 fe c7 blx #13631484 +// CHECK2-NEXT: 200006: 00 f2 03 90 b.w #14680070 <__Thumbv7ABSLongThunk_afunc14> + + ARMFUNCTION 02 + THUMBFUNCTION 03 + ARMFUNCTION 04 + THUMBFUNCTION 05 + ARMFUNCTION 06 + THUMBFUNCTION 07 + ARMFUNCTION 08 + THUMBFUNCTION 09 + ARMFUNCTION 10 + THUMBFUNCTION 11 + ARMFUNCTION 12 + THUMBFUNCTION 13 + ARMFUNCTION 14 +// CHECK3: __ARMv7ABSLongThunk_tfunc31: +// CHECK3-NEXT: 1000004: 01 c0 00 e3 movw r12, #1 +// CHECK3-NEXT: 1000008: 00 c2 40 e3 movt r12, #512 +// CHECK3-NEXT: 100000c: 1c ff 2f e1 bx r12 +// CHECK4: __Thumbv7ABSLongThunk_afunc14: +// CHECK4-NEXT: 1000010: 40 f2 00 0c movw r12, #0 +// CHECK4-NEXT: 1000014: c0 f2 f0 0c movt r12, #240 +// CHECK4-NEXT: 1000018: 60 47 bx r12 + THUMBFUNCTION 15 + ARMFUNCTION 16 + THUMBFUNCTION 17 + ARMFUNCTION 18 + THUMBFUNCTION 19 + ARMFUNCTION 20 + THUMBFUNCTION 21 + ARMFUNCTION 22 + THUMBFUNCTION 23 + ARMFUNCTION 24 + THUMBFUNCTION 25 + ARMFUNCTION 26 + THUMBFUNCTION 27 + ARMFUNCTION 28 + THUMBFUNCTION 29 + ARMFUNCTION 30 +// Expect precreated Thunk Section here +// CHECK5: __Thumbv7ABSLongThunk_afunc00: +// CHECK5-NEXT: 1f00004: 40 f2 00 0c movw r12, #0 +// CHECK5-NEXT: 1f00008: c0 f2 10 0c movt r12, #16 +// CHECK5-NEXT: 1f0000c: 60 47 bx r12 + THUMBFUNCTION 31 + ARMFUNCTION 32 + THUMBFUNCTION 33 +// Out of range, can only reach closest Thunk Section + bl afunc00 +// CHECK6: tfunc33: +// CHECK6-NEXT: 2200000: 70 47 bx lr +// CHECK6-NEXT: 2200002: ff f4 ff ff bl #-3145730 + ARMFUNCTION 34 +// Out of range, can reach earlier Thunk Section +// CHECK7: afunc34: +// CHECK7-NEXT: 2300000: 1e ff 2f e1 bx lr +// CHECK7-NEXT: 2300004: fe ff ef fa blx #-4194312 <__Thumbv7ABSLongThunk_afunc00 + bl afunc00 + THUMBFUNCTION 35 + ARMFUNCTION 36 + THUMBFUNCTION 37 + ARMFUNCTION 38 + THUMBFUNCTION 39 + ARMFUNCTION 40 + THUMBFUNCTION 41 + ARMFUNCTION 42 + THUMBFUNCTION 43 + ARMFUNCTION 44 + THUMBFUNCTION 45 +// Expect precreated Thunk Section here +// CHECK8: __ARMv7ABSLongThunk_tfunc35: +// CHECK8-NEXT: 2e00004: 01 c0 00 e3 movw r12, #1 +// CHECK8-NEXT: 2e00008: 40 c2 40 e3 movt r12, #576 +// CHECK8-NEXT: 2e0000c: 1c ff 2f e1 bx r12 + ARMFUNCTION 46 + THUMBFUNCTION 47 + ARMFUNCTION 48 + THUMBFUNCTION 49 + ARMFUNCTION 50 + THUMBFUNCTION 51 + ARMFUNCTION 52 + THUMBFUNCTION 53 + ARMFUNCTION 54 + THUMBFUNCTION 55 + ARMFUNCTION 56 + THUMBFUNCTION 57 + ARMFUNCTION 58 + THUMBFUNCTION 59 + ARMFUNCTION 60 +// Expect precreated Thunk Section here +// CHECK9: __Thumbv7ABSLongThunk_afunc34: +// CHECK9-NEXT: 3d00004: 40 f2 00 0c movw r12, #0 +// CHECK9-NEXT: 3d00008: c0 f2 30 2c movt r12, #560 +// CHECK9-NEXT: 3d0000c: 60 47 bx r12 +// CHECK9: __Thumbv7ABSLongThunk_tfunc35: +// CHECK9-NEXT: 3d0000e: 40 f2 01 0c movw r12, #1 +// CHECK9-NEXT: 3d00012: c0 f2 40 2c movt r12, #576 +// CHECK9-NEXT: 3d00016: 60 47 bx r12 + THUMBFUNCTION 61 + ARMFUNCTION 62 + THUMBFUNCTION 63 + ARMFUNCTION 64 +// afunc34 is in range, as is tfunc35 but a branch needs a state change Thunk + bl afunc34 + b tfunc35 +// CHECK10: afunc64: +// CHECK10-NEXT: 4100000: 1e ff 2f e1 bx lr +// CHECK10-NEXT: 4100004: fd ff 87 eb bl #-31457292 <afunc34> +// CHECK10-NEXT: 4100008: fd ff b3 ea b #-19922956 <__ARMv7ABSLongThunk_tfunc35> + THUMBFUNCTION 65 +// afunc34 and tfunc35 are both out of range + bl afunc34 + bl tfunc35 +// CHECK11: tfunc65: +// CHECK11: 4200000: 70 47 bx lr +// CHECK11-NEXT: 4200002: ff f6 ff f7 bl #-5242882 +// CHECK11-NEXT: 4200006: 00 f7 02 f0 bl #-5242876 diff --git a/test/ELF/arm-thumb-plt-range-thunk-os.s b/test/ELF/arm-thumb-plt-range-thunk-os.s new file mode 100644 index 000000000000..f412faa98eca --- /dev/null +++ b/test/ELF/arm-thumb-plt-range-thunk-os.s @@ -0,0 +1,92 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t --shared -o %t.so +// The output file is large, most of it zeroes. We dissassemble only the +// parts we need to speed up the test and avoid a large output file +// RUN: llvm-objdump -d %t.so -start-address=8388608 -stop-address=8388624 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t.so -start-address=16777216 -stop-address=16777256 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s +// RUN: llvm-objdump -d %t.so -start-address=25165824 -stop-address=25165828 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s +// RUN: llvm-objdump -d %t.so -start-address=25165828 -stop-address=25165924 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s + .syntax unified + .thumb + +// Make sure that we generate a range extension thunk to a PLT entry + .section ".text.1", "ax", %progbits + .global sym1 + .global elsewhere + .type elsewhere, %function + .global preemptible + .type preemptible, %function + .global far_preemptible + .type far_preemptible, %function +sym1: + bl elsewhere + bl preemptible + bx lr +preemptible: + bl far_preemptible + bx lr +// CHECK1: Disassembly of section .text: +// CHECK1-NEXT: sym1: +// CHECK1-NEXT: 800000: 00 f0 00 d8 bl #8388608 +// CHECK1-NEXT: 800004: 00 f0 04 d8 bl #8388616 +// CHECK1-NEXT: 800008: 70 47 bx lr +// CHECK1: preemptible: +// CHECK1-NEXT: 80000a: 00 f0 07 d8 bl #8388622 +// CHECK1-NEXT: 80000e: 70 47 bx lr + + .section .text.2, "ax", %progbits + .balign 0x0800000 + bx lr +// CHECK2: __ThumbV7PILongThunk_elsewhere: +// CHECK2-NEXT: 1000004: 40 f2 20 0c movw r12, #32 +// CHECK2-NEXT: 1000008: c0 f2 80 0c movt r12, #128 +// CHECK2-NEXT: 100000c: fc 44 add r12, pc +// CHECK2-NEXT: 100000e: 60 47 bx r12 +// CHECK2: __ThumbV7PILongThunk_preemptible: +// CHECK2-NEXT: 1000010: 40 f2 24 0c movw r12, #36 +// CHECK2-NEXT: 1000014: c0 f2 80 0c movt r12, #128 +// CHECK2-NEXT: 1000018: fc 44 add r12, pc +// CHECK2-NEXT: 100001a: 60 47 bx r12 +// CHECK2: __ThumbV7PILongThunk_far_preemptible: +// CHECK2-NEXT: 100001c: 40 f2 28 0c movw r12, #40 +// CHECK2-NEXT: 1000020: c0 f2 80 0c movt r12, #128 +// CHECK2-NEXT: 1000024: fc 44 add r12, pc +// CHECK2-NEXT: 1000026: 60 47 bx r12 + + .section .text.3, "ax", %progbits +.balign 0x0800000 +far_preemptible: + bl elsewhere +// CHECK3: far_preemptible: +// CHECK3: 1800000: 00 f0 16 e8 blx #44 + +// CHECK4: Disassembly of section .plt: +// CHECK4-NEXT: $a: +// CHECK4-NEXT: 1800010: 04 e0 2d e5 str lr, [sp, #-4]! +// CHECK4-NEXT: 1800014: 00 e6 8f e2 add lr, pc, #0, #12 +// CHECK4-NEXT: 1800018: 00 ea 8e e2 add lr, lr, #0, #20 +// CHECK4-NEXT: 180001c: ec ff be e5 ldr pc, [lr, #4076]! +// CHECK4: $d: +// CHECK4-NEXT: 1800020: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK4-NEXT: 1800024: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK4-NEXT: 1800028: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK4-NEXT: 180002c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK4: $a: +// CHECK4-NEXT: 1800030: 00 c6 8f e2 add r12, pc, #0, #12 +// CHECK4-NEXT: 1800034: 00 ca 8c e2 add r12, r12, #0, #20 +// CHECK4-NEXT: 1800038: d4 ff bc e5 ldr pc, [r12, #4052]! +// CHECK4: $d: +// CHECK4-NEXT: 180003c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK4: $a: +// CHECK4-NEXT: 1800040: 00 c6 8f e2 add r12, pc, #0, #12 +// CHECK4-NEXT: 1800044: 00 ca 8c e2 add r12, r12, #0, #20 +// CHECK4-NEXT: 1800048: c8 ff bc e5 ldr pc, [r12, #4040]! +// CHECK4: $d: +// CHECK4-NEXT: 180004c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK4: $a: +// CHECK4-NEXT: 1800050: 00 c6 8f e2 add r12, pc, #0, #12 +// CHECK4-NEXT: 1800054: 00 ca 8c e2 add r12, r12, #0, #20 +// CHECK4-NEXT: 1800058: bc ff bc e5 ldr pc, [r12, #4028]! +// CHECK4: $d: +// CHECK4-NEXT: 180005c: d4 d4 d4 d4 .word 0xd4d4d4d4 diff --git a/test/ELF/arm-thumb-plt-reloc.s b/test/ELF/arm-thumb-plt-reloc.s index f9afbb9c0ce1..dd8770edc3c1 100644 --- a/test/ELF/arm-thumb-plt-reloc.s +++ b/test/ELF/arm-thumb-plt-reloc.s @@ -2,7 +2,7 @@ // 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: ld.lld --hash-style=sysv -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 @@ -43,50 +43,54 @@ _start: // .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-NEXT: func1: +// DSOTHUMB-NEXT: 1000: 70 47 bx lr // DSOTHUMB: func2: -// DSOTHUMB-NEXT: 1002: 70 47 bx lr +// DSOTHUMB-NEXT: 1002: 70 47 bx lr // DSOTHUMB: func3: -// DSOTHUMB-NEXT: 1004: 70 47 bx lr -// DSOTHUMB-NEXT: 1006: d4 d4 +// DSOTHUMB-NEXT: 1004: 70 47 bx lr +// DSOTHUMB-NEXT: 1006: d4 d4 bmi #-88 // 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 +// 0x1008 + 0x34 + 4 = 0x1040 = PLT func1 +// DSOTHUMB-NEXT: 1008: 00 f0 1a e8 blx #52 +// 0x100c + 0x40 + 4 = 0x1050 = PLT func2 +// DSOTHUMB-NEXT: 100c: 00 f0 20 e8 blx #64 +// 0x1010 + 0x4C + 4 = 0x1060 = PLT func3 +// DSOTHUMB-NEXT: 1010: 00 f0 26 e8 blx #76 // DSOARM: Disassembly of section .plt: // DSOARM-NEXT: $a: -// 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: 1020: 04 e0 2d e5 str lr, [sp, #-4]! +// (0x1024 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfdc) = 0x2008 = .got.plt[3] +// DSOARM-NEXT: 1024: 00 e6 8f e2 add lr, pc, #0, #12 +// DSOARM-NEXT: 1028: 00 ea 8e e2 add lr, lr, #0, #20 +// DSOARM-NEXT: 102c: dc ff be e5 ldr pc, [lr, #4060]! // DSOARM: $d: -// DSOARM-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0 -// 0x1028 + 8 + 0fd0 = 0x2000 + +// DSOARM-NEXT: 1030: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DSOARM-NEXT: 1034: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DSOARM-NEXT: 1038: d4 d4 d4 d4 .word 0xd4d4d4d4 +// DSOARM-NEXT: 103c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DSOARM: $a: -// 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] +// (0x1040 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfc4) = 0x200c +// DSOARM-NEXT: 1040: 00 c6 8f e2 add r12, pc, #0, #12 +// DSOARM-NEXT: 1044: 00 ca 8c e2 add r12, r12, #0, #20 +// DSOARM-NEXT: 1048: c4 ff bc e5 ldr pc, [r12, #4036]! // DSOARM: $d: -// DSOARM-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc -// 0x1038 + 8 + 0fcc = 0x200c +// DSOARM-NEXT: 104c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DSOARM: $a: -// 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] +// (0x1050 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfb8) = 0x2010 +// DSOARM-NEXT: 1050: 00 c6 8f e2 add r12, pc, #0, #12 +// DSOARM-NEXT: 1054: 00 ca 8c e2 add r12, r12, #0, #20 +// DSOARM-NEXT: 1058: b8 ff bc e5 ldr pc, [r12, #4024]! // DSOARM: $d: -// DSOARM-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0 -// 0x1048 + 8 + 0fc0 = 0x2010 +// DSOARM-NEXT: 105c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DSOARM: $a: -// 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] +// (0x1060 + 8) + (0 RoR 12) + (0 RoR 20) + (0xfac) = 0x2014 +// DSOARM-NEXT: 1060: 00 c6 8f e2 add r12, pc, #0, #12 +// DSOARM-NEXT: 1064: 00 ca 8c e2 add r12, r12, #0, #20 +// DSOARM-NEXT: 1068: ac ff bc e5 ldr pc, [r12, #4012]! // DSOARM: $d: -// DSOARM-NEXT: 1060: b4 0f 00 00 .word 0x00000fb4 -// 0x1058 + 8 + 0fb4 = 0x2014 +// DSOARM-NEXT: 106c: d4 d4 d4 d4 .word 0xd4d4d4d4 // DSOREL: Name: .got.plt // DSOREL-NEXT: Type: SHT_PROGBITS diff --git a/test/ELF/arm-thumb-range-thunk-os.s b/test/ELF/arm-thumb-range-thunk-os.s new file mode 100644 index 000000000000..588539ddab8c --- /dev/null +++ b/test/ELF/arm-thumb-range-thunk-os.s @@ -0,0 +1,159 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 +// The output file is large, most of it zeroes. We dissassemble only the +// parts we need to speed up the test and avoid a large output file +// RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048588 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t2 -start-address=2097152 -stop-address=2097154 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s +// RUN: llvm-objdump -d %t2 -start-address=3145728 -stop-address=3145730 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s +// RUN: llvm-objdump -d %t2 -start-address=4194304 -stop-address=4194310 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s +// RUN: llvm-objdump -d %t2 -start-address=16777216 -stop-address=16777270 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s +// RUN: llvm-objdump -d %t2 -start-address=17825792 -stop-address=17825808 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s +// RUN: llvm-objdump -d %t2 -start-address=31457280 -stop-address=31457286 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s +// RUN: llvm-objdump -d %t2 -start-address=32505860 -stop-address=32505880 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s +// RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651594 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s +// RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700170 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s + +// Test the Range extension Thunks for Thumb when all the code is in a single +// OutputSection. The Thumb unconditional branch b.w and branch and link bl +// instructions have a range of 16Mb. We create a series of Functions a +// megabyte apart. We expect range extension thunks to be created when a +// branch is out of range. Thunks will be reused whenever they are in range + .syntax unified + +// Define a function aligned on a megabyte boundary + .macro FUNCTION suff + .section .text.\suff\(), "ax", %progbits + .thumb + .balign 0x100000 + .globl tfunc\suff\() + .type tfunc\suff\(), %function +tfunc\suff\(): + bx lr + .endm + + .section .text, "ax", %progbits + .thumb + .globl _start +_start: +// tfunc00 and tfunc15 are within 16Mb no Range Thunks expected + bl tfunc00 + bl tfunc15 +// tfunc16 is > 16Mb away, expect a Range Thunk to be generated, to go into +// the first of the pre-created ThunkSections. + bl tfunc16 +// CHECK1: Disassembly of section .text: +// CHECK1-NEXT: _start: +// CHECK1-NEXT: 100000: ff f0 fe ff bl #1048572 +// CHECK1-NEXT: 100004: ff f3 fc d7 bl #16777208 +// CHECK1-NEXT: 100008: ff f2 fc d7 bl #15728632 + + FUNCTION 00 +// CHECK2: tfunc00: +// CHECK2-NEXT: 200000: 70 47 bx lr + FUNCTION 01 +// CHECK3: tfunc01: +// CHECK3-NEXT: 300000: 70 47 bx lr + FUNCTION 02 +// tfunc28 is > 16Mb away, expect a Range Thunk to be generated, to go into +// the first of the pre-created ThunkSections. + b.w tfunc28 +// CHECK4: tfunc02: +// CHECK4-NEXT: 400000: 70 47 bx lr +// CHECK4-NEXT: 400002: 00 f0 04 90 b.w #12582920 <__Thumbv7ABSLongThunk_tfunc28> + FUNCTION 03 + FUNCTION 04 + FUNCTION 05 + FUNCTION 06 + FUNCTION 07 + FUNCTION 08 + FUNCTION 09 + FUNCTION 10 + FUNCTION 11 + FUNCTION 12 + FUNCTION 13 + FUNCTION 14 +// Expect precreated ThunkSection here +// CHECK5: __Thumbv7ABSLongThunk_tfunc16: +// CHECK5-NEXT: 1000004: 40 f2 01 0c movw r12, #1 +// CHECK5-NEXT: 1000008: c0 f2 20 1c movt r12, #288 +// CHECK5-NEXT: 100000c: 60 47 bx r12 +// CHECK5: __Thumbv7ABSLongThunk_tfunc28: +// CHECK5-NEXT: 100000e: 40 f2 01 0c movw r12, #1 +// CHECK5-NEXT: 1000012: c0 f2 e0 1c movt r12, #480 +// CHECK5-NEXT: 1000016: 60 47 bx r12 +// CHECK5: __Thumbv7ABSLongThunk_tfunc32: +// CHECK5-NEXT: 1000018: 40 f2 01 0c movw r12, #1 +// CHECK5-NEXT: 100001c: c0 f2 20 2c movt r12, #544 +// CHECK5-NEXT: 1000020: 60 47 bx r12 +// CHECK5: __Thumbv7ABSLongThunk_tfunc33: +// CHECK5-NEXT: 1000022: 40 f2 01 0c movw r12, #1 +// CHECK5-NEXT: 1000026: c0 f2 30 2c movt r12, #560 +// CHECK5-NEXT: 100002a: 60 47 bx r12 +// CHECK5: __Thumbv7ABSLongThunk_tfunc02: +// CHECK5-NEXT: 100002c: 40 f2 01 0c movw r12, #1 +// CHECK5-NEXT: 1000030: c0 f2 40 0c movt r12, #64 +// CHECK5-NEXT: 1000034: 60 47 bx r12 + FUNCTION 15 +// tfunc00 and tfunc01 are < 16Mb away, expect no range extension thunks + bl tfunc00 + bl tfunc01 +// tfunc32 and tfunc33 are > 16Mb away, expect range extension thunks in the +// precreated thunk section + bl tfunc32 + bl tfunc33 +// CHECK6: tfunc15: +// CHECK6-NEXT: 1100000: 70 47 bx lr +// CHECK6-NEXT: 1100002: ff f4 fd d7 bl #-15728646 +// CHECK6-NEXT: 1100006: ff f5 fb d7 bl #-14680074 +// CHECK6-NEXT: 110000a: 00 f7 05 f8 bl #-1048566 +// CHECK6-NEXT: 110000e: 00 f7 08 f8 bl #-1048560 + FUNCTION 16 + FUNCTION 17 + FUNCTION 18 + FUNCTION 19 + FUNCTION 20 + FUNCTION 21 + FUNCTION 22 + FUNCTION 23 + FUNCTION 24 + FUNCTION 25 + FUNCTION 26 + FUNCTION 27 + FUNCTION 28 +// tfunc02 is > 16Mb away, expect range extension thunks in precreated thunk +// section +// CHECK7: tfunc28: +// CHECK7-NEXT: 1e00000: 70 47 bx lr +// CHECK7-NEXT: 1e00002: 00 f6 13 90 b.w #-14680026 <__Thumbv7ABSLongThunk_tfunc02> + + b.w tfunc02 + FUNCTION 29 +// Expect another precreated thunk section here +// CHECK8: __Thumbv7ABSLongThunk_tfunc15: +// CHECK8-NEXT: 1f00004: 40 f2 01 0c movw r12, #1 +// CHECK8-NEXT: 1f00008: c0 f2 10 1c movt r12, #272 +// CHECK8-NEXT: 1f0000c: 60 47 bx r12 +// CHECK8: __Thumbv7ABSLongThunk_tfunc16: +// CHECK8-NEXT: 1f0000e: 40 f2 01 0c movw r12, #1 +// CHECK8-NEXT: 1f00012: c0 f2 20 1c movt r12, #288 +// CHECK8-NEXT: 1f00016: 60 47 bx r12 + FUNCTION 30 + FUNCTION 31 + FUNCTION 32 + // tfunc15 and tfunc16 are > 16 Mb away expect Thunks in the nearest + // precreated thunk section. + bl tfunc15 + bl tfunc16 +// CHECK9: tfunc32: +// CHECK9: 2200000: 70 47 bx lr +// CHECK9-NEXT: 2200002: ff f4 ff ff bl #-3145730 +// CHECK9-NEXT: 2200006: 00 f5 02 f8 bl #-3145724 + + FUNCTION 33 + bl tfunc15 + bl tfunc16 +// CHECK10: tfunc33: +// CHECK10: 2300000: 70 47 bx lr +// CHECK10-NEXT: 2300002: ff f7 ff f7 bl #-4194306 +// CHECK10-NEXT: 2300006: 00 f4 02 f8 bl #-4194300 diff --git a/test/ELF/arm-thumb-thunk-empty-pass.s b/test/ELF/arm-thumb-thunk-empty-pass.s new file mode 100644 index 000000000000..9ff6ed6a7807 --- /dev/null +++ b/test/ELF/arm-thumb-thunk-empty-pass.s @@ -0,0 +1,32 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 +// RUN: llvm-objdump -d %t2 -start-address=69632 -stop-address=69646 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t2 -start-address=16846860 -stop-address=16846874 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s + .syntax unified + .global _start, foo + .type _start, %function + .section .text.start,"ax",%progbits +_start: + bl _start + .section .text.dummy1,"ax",%progbits + .space 0xfffffe + .section .text.foo,"ax",%progbits + .type foo, %function +foo: + bl _start + +// CHECK1: Disassembly of section .text: +// CHECK1-NEXT: _start: +// CHECK1-NEXT: 11000: ff f7 fe ff bl #-4 +// CHECK1: __Thumbv7ABSLongThunk__start: +// CHECK1-NEXT: 11004: 41 f2 01 0c movw r12, #4097 +// CHECK1-NEXT: 11008: c0 f2 01 0c movt r12, #1 +// CHECK1-NEXT: 1100c: 60 47 bx r12 + +// CHECK2: __Thumbv7ABSLongThunk__start: +// CHECK2: 101100c: 41 f2 01 0c movw r12, #4097 +// CHECK2-NEXT: 1011010: c0 f2 01 0c movt r12, #1 +// CHECK2-NEXT: 1011014: 60 47 bx r12 +// CHECK2: foo: +// CHECK2-NEXT: 1011016: ff f7 f9 ff bl #-14 diff --git a/test/ELF/arm-thumb-thunk-symbols.s b/test/ELF/arm-thumb-thunk-symbols.s index 42046f802f96..faa39fec0218 100644 --- a/test/ELF/arm-thumb-thunk-symbols.s +++ b/test/ELF/arm-thumb-thunk-symbols.s @@ -25,18 +25,18 @@ arm_fn: b thumb_fn // CHECK: Name: __Thumbv7ABSLongThunk_arm_fn -// CHECK-NEXT: Value: 0x11005 +// CHECK-NEXT: Value: 0x12005 // CHECK-NEXT: Size: 10 // CHECK-NEXT: Binding: Local (0x0) // CHECK-NEXT: Type: Function (0x2) // CHECK: Name: __ARMv7ABSLongThunk_thumb_fn -// CHECK-NEXT: Value: 0x11010 +// CHECK-NEXT: Value: 0x12010 // CHECK-NEXT: Size: 12 // CHECK-NEXT: Binding: Local (0x0) // CHECK-NEXT: Type: Function (0x2) // CHECK-PI: Name: __ThumbV7PILongThunk_arm_fn -// CHECK-PI-NEXT: Value: 0x1005 +// CHECK-PI-NEXT: Value: 0x2005 // CHECK-PI-NEXT: Size: 12 // CHECK-PI-NEXT: Binding: Local (0x0) // CHECK-PI-NEXT: Type: Function (0x2) diff --git a/test/ELF/arm-thunk-edgecase.s b/test/ELF/arm-thunk-edgecase.s new file mode 100644 index 000000000000..81837c7b3284 --- /dev/null +++ b/test/ELF/arm-thunk-edgecase.s @@ -0,0 +1,37 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +// RUN: echo "SECTIONS { \ +// RUN: .text_armfunc 0x1000 : { *(.text_armfunc) } \ +// RUN: .text_thumbfunc 0x11010 : { *(.text_thumbfunc) } \ +// RUN: }" > %tarm_to_thumb.script +// RUN: echo "SECTIONS { \ +// RUN: .text_thumbfunc 0x1000 : { *(.text_thumbfunc) } \ +// RUN: .text_armfunc 0x1100c : { *(.text_armfunc) } \ +// RUN: }" > %tthumb_to_arm.script +// RUN: ld.lld -shared -Bsymbolic -script %tarm_to_thumb.script %t.o -o %tarm_to_thumb.so +// RUN: ld.lld -shared -Bsymbolic -script %tthumb_to_arm.script %t.o -o %tthumb_to_arm.so +// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %tarm_to_thumb.so | FileCheck -check-prefix=ARM-TO-THUMB %s +// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %tthumb_to_arm.so | FileCheck -check-prefix=THUMB-TO-ARM %s + +.syntax unified + +.arm +.section .text_armfunc, "ax", %progbits +.globl armfunc +armfunc: + b thumbfunc + +.thumb +.section .text_thumbfunc, "ax", %progbits +.globl thumbfunc +.thumb_func +thumbfunc: + b.w armfunc + +// ARM-TO-THUMB: __ARMV7PILongThunk_thumbfunc: +// ARM-TO-THUMB-NEXT: 1004: fd cf 0f e3 movw r12, #65533 +// ARM-TO-THUMB-NEXT: 1008: 00 c0 40 e3 movt r12, #0 + +// THUMB-TO-ARM: __ThumbV7PILongThunk_armfunc: +// THUMB-TO-ARM-NEXT: 1004: 4f f6 fc 7c movw r12, #65532 +// THUMB-TO-ARM-NEXT: 1008: c0 f2 00 0c movt r12, #0 diff --git a/test/ELF/arm-thunk-largesection.s b/test/ELF/arm-thunk-largesection.s new file mode 100644 index 000000000000..950f789764a6 --- /dev/null +++ b/test/ELF/arm-thunk-largesection.s @@ -0,0 +1,42 @@ +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=69632 -stop-address=69636 %t2 | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=73732 -stop-address=73742 %t2 | FileCheck -check-prefix=CHECK2 %s +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=16850944 -stop-address=16850948 %t2 | FileCheck -check-prefix=CHECK3 %s +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=33628160 -stop-address=33628164 %t2 | FileCheck -check-prefix=CHECK4 %s +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi -start-address=50405364 -stop-address=50405376 %t2 | FileCheck -check-prefix=CHECK5 %s +// REQUIRES: arm + .syntax unified + .balign 0x1000 + .thumb + .text + .globl _start + .type _start, %function +_start: + bx lr + .space 0x1000 +// CHECK1: Disassembly of section .text: +// CHECK1-NEXT: _start: +// CHECK1-NEXT: 11000: 70 47 bx lr +// CHECK1-NEXT: 11002: 00 00 movs r0, r0 + +// CHECK2: __Thumbv7ABSLongThunk__start: +// CHECK2-NEXT: 12004: 41 f2 01 0c movw r12, #4097 +// CHECK2-NEXT: 12008: c0 f2 01 0c movt r12, #1 +// CHECK2-NEXT: 1200c: 60 47 bx r12 + +// Gigantic section where we need a ThunkSection either side of it + .section .text.large1, "ax", %progbits + .balign 4 + .space (16 * 1024 * 1024) - 16 + bl _start + .space (16 * 1024 * 1024) - 4 + bl _start + .space (16 * 1024 * 1024) - 16 +// CHECK3: 1012000: 00 f4 00 d0 bl #-16777216 +// CHECK4: 2012000: ff f3 f8 d7 bl #16777200 + +// CHECK5: __Thumbv7ABSLongThunk__start: +// CHECK5-NEXT: 3011ff4: 41 f2 01 0c movw r12, #4097 +// CHECK5-NEXT: 3011ff8: c0 f2 01 0c movt r12, #1 +// CHECK5-NEXT: 3011ffc: 60 47 bx r12 diff --git a/test/ELF/arm-thunk-linkerscript-dotexpr.s b/test/ELF/arm-thunk-linkerscript-dotexpr.s new file mode 100644 index 000000000000..bd0e9a293102 --- /dev/null +++ b/test/ELF/arm-thunk-linkerscript-dotexpr.s @@ -0,0 +1,77 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: . = SIZEOF_HEADERS; \ +// RUN: .text_low : { *(.text_low) *(.text_low2) . = . + 0x2000000 ; *(.text_high) *(.text_high2) } \ +// RUN: } " > %t.script +// RUN: ld.lld --script %t.script %t -o %t2 2>&1 +// RUN: llvm-objdump -d %t2 -start-address=148 -stop-address=188 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t2 -start-address=33554620 -stop-address=33554654 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s +// REQUIRES: arm +// Test that range extension thunks can handle location expressions within +// a Section Description + .syntax unified + .section .text_low, "ax", %progbits + .thumb + .globl _start +_start: bx lr + .globl low_target + .type low_target, %function +low_target: + bl high_target + bl high_target2 + + .section .text_low2, "ax", %progbits + .thumb + .globl low_target2 + .type low_target2, %function +low_target2: + bl high_target + bl high_target2 +// CHECK1: Disassembly of section .text_low: +// CHECK1-NEXT: _start: +// CHECK1-NEXT: 94: 70 47 bx lr +// CHECK1: low_target: +// CHECK1-NEXT: 96: 00 f0 03 f8 bl #6 +// CHECK1-NEXT: 9a: 00 f0 06 f8 bl #12 +// CHECK1: __Thumbv7ABSLongThunk_high_target: +// CHECK1-NEXT: a0: 40 f2 bd 0c movw r12, #189 +// CHECK1-NEXT: a4: c0 f2 00 2c movt r12, #512 +// CHECK1-NEXT: a8: 60 47 bx r12 +// CHECK1: __Thumbv7ABSLongThunk_high_target2: +// CHECK1-NEXT: aa: 40 f2 d9 0c movw r12, #217 +// CHECK1-NEXT: ae: c0 f2 00 2c movt r12, #512 +// CHECK1-NEXT: b2: 60 47 bx r12 +// CHECK1: low_target2: +// CHECK1-NEXT: b4: ff f7 f4 ff bl #-24 +// CHECK1-NEXT: b8: ff f7 f7 ff bl #-18 + + .section .text_high, "ax", %progbits + .thumb + .globl high_target + .type high_target, %function +high_target: + bl low_target + bl low_target2 + + .section .text_high2, "ax", %progbits + .thumb + .globl high_target2 + .type high_target2, %function +high_target2: + bl low_target + bl low_target2 + +// CHECK2: high_target: +// CHECK2-NEXT: 20000bc: 00 f0 02 f8 bl #4 +// CHECK2-NEXT: 20000c0: 00 f0 05 f8 bl #10 +// CHECK2: __Thumbv7ABSLongThunk_low_target: +// CHECK2-NEXT: 20000c4: 40 f2 97 0c movw r12, #151 +// CHECK2-NEXT: 20000c8: c0 f2 00 0c movt r12, #0 +// CHECK2-NEXT: 20000cc: 60 47 bx r12 +// CHECK2: __Thumbv7ABSLongThunk_low_target2: +// CHECK2-NEXT: 20000ce: 40 f2 b5 0c movw r12, #181 +// CHECK2-NEXT: 20000d2: c0 f2 00 0c movt r12, #0 +// CHECK2-NEXT: 20000d6: 60 47 bx r12 +// CHECK2: high_target2: +// CHECK2-NEXT: 20000d8: ff f7 f4 ff bl #-24 +// CHECK2-NEXT: 20000dc: ff f7 f7 ff bl #-18 diff --git a/test/ELF/arm-thunk-linkerscript-large.s b/test/ELF/arm-thunk-linkerscript-large.s new file mode 100644 index 000000000000..07cd1dd87976 --- /dev/null +++ b/test/ELF/arm-thunk-linkerscript-large.s @@ -0,0 +1,176 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: .text 0x100000 : { *(.text) } \ +// RUN: .textl : { *(.text_l0*) *(.text_l1*) *(.text_l2*) *(.text_l3*) } \ +// RUN: .texth : { *(.text_h0*) *(.text_h1*) *(.text_h2*) *(.text_h3*) } \ +// RUN: }" > %t.script +// RUN: ld.lld --script %t.script %t -o %t2 2>&1 +// The output file is large, most of it zeroes. We dissassemble only the +// parts we need to speed up the test and avoid a large output file +// RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048594 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t2 -start-address=2097152 -stop-address=2097160 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK2 %s +// RUN: llvm-objdump -d %t2 -start-address=11534340 -stop-address=11534350 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK3 %s +// RUN: llvm-objdump -d %t2 -start-address=34603008 -stop-address=34603034 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK4 %s +// RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651598 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK5 %s +// RUN: llvm-objdump -d %t2 -start-address=68157440 -stop-address=68157472 -triple=thumbv7a-linux-gnueabihf | FileCheck --check-prefix=CHECK6 %s + +// Test the range extensions in a linker script where there are several +// OutputSections requiring range extension Thunks. We should be able to reuse +// Thunks between OutputSections but our placement of new Thunks is done on a +// per OutputSection basis + .syntax unified + +// Define a function that we can match with .text_l* aligned on a megabyte // boundary + .macro FUNCTIONL suff + .section .text_l\suff\(), "ax", %progbits + .thumb + .balign 0x100000 + .globl tfuncl\suff\() + .type tfuncl\suff\(), %function +tfuncl\suff\(): + bx lr + .endm + +// Define a function that we can match with .text_h* aligned on a megabyte +// boundary + .macro FUNCTIONH suff + .section .text_h\suff\(), "ax", %progbits + .thumb + .balign 0x100000 + .globl tfunch\suff\() + .type tfunch\suff\(), %function +tfunch\suff\(): + bx lr + .endm + + .section .text, "ax", %progbits + .thumb + .globl _start +_start: + bl tfuncl00 + // Expect a range extension thunk in .text OutputSection + bl tfunch31 +// CHECK1: Disassembly of section .text: +// CHECK1-NEXT: _start: +// CHECK1-NEXT: 100000: ff f0 fe ff bl #1048572 +// CHECK1-NEXT: 100004: 00 f0 00 f8 bl #0 +// CHECK1: __Thumbv7ABSLongThunk_tfunch31: +// CHECK1-NEXT: 100008: 40 f2 01 0c movw r12, #1 +// CHECK1-NEXT: 10000c: c0 f2 10 4c movt r12, #1040 +// CHECK1-NEXT: 100010: 60 47 bx r12 + FUNCTIONL 00 + // Create a range extension thunk in .textl + bl tfuncl24 + // We can reuse existing thunk in .text + bl tfunch31 +// CHECK2: Disassembly of section .textl: +// CHECK2-NEXT: tfuncl00: +// CHECK2-NEXT: 200000: 70 47 bx lr +// CHECK2-NEXT: 200002: ff f0 ff df bl #9437182 +// CHECK2-NEXT: 200006: ff f6 ff ff bl #-1048578 + FUNCTIONL 01 + FUNCTIONL 02 + FUNCTIONL 03 + FUNCTIONL 04 + FUNCTIONL 05 + FUNCTIONL 06 + FUNCTIONL 07 + FUNCTIONL 08 + FUNCTIONL 09 +// CHECK3: __Thumbv7ABSLongThunk_tfuncl24: +// CHECK3-NEXT: b00004: 40 f2 01 0c movw r12, #1 +// CHECK3-NEXT: b00008: c0 f2 a0 1c movt r12, #416 +// CHECK3-NEXT: b0000c: 60 47 bx r12 + FUNCTIONL 10 + FUNCTIONL 11 + FUNCTIONL 12 + FUNCTIONL 13 + FUNCTIONL 14 + FUNCTIONL 15 + FUNCTIONL 16 + FUNCTIONL 17 + FUNCTIONL 18 + FUNCTIONL 19 + FUNCTIONL 20 + FUNCTIONL 21 + FUNCTIONL 22 + FUNCTIONL 23 + FUNCTIONL 24 + FUNCTIONL 25 + FUNCTIONL 26 + FUNCTIONL 27 + FUNCTIONL 28 + FUNCTIONL 29 + FUNCTIONL 30 + FUNCTIONL 31 + // Create range extension thunks in .textl + bl tfuncl00 + bl tfuncl24 + // Shouldn't need a thunk + bl tfunch00 +// CHECK4: 2100002: 00 f0 05 f8 bl #10 +// CHECK4-NEXT: 2100006: ff f4 fb f7 bl #-7340042 +// CHECK4-NEXT: 210000a: ff f0 f9 ff bl #1048562 +// CHECK4: __Thumbv7ABSLongThunk_tfuncl00: +// CHECK4-NEXT: 2100010: 40 f2 01 0c movw r12, #1 +// CHECK4-NEXT: 2100014: c0 f2 20 0c movt r12, #32 +// CHECK4-NEXT: 2100018: 60 47 bx r12 + FUNCTIONH 00 + // Can reuse existing thunks in .textl + bl tfuncl00 + bl tfuncl24 + // Shouldn't need a thunk + bl tfuncl31 +// CHECK5: Disassembly of section .texth: +// CHECK5-NEXT: tfunch00: +// CHECK5-NEXT: 2200000: 70 47 bx lr +// CHECK5-NEXT: 2200002: 00 f7 05 f8 bl #-1048566 +// CHECK5-NEXT: 2200006: ff f7 fb df bl #-8388618 +// CHECK5-NEXT: 220000a: ff f6 f9 ff bl #-1048590 + FUNCTIONH 01 + FUNCTIONH 02 + FUNCTIONH 03 + FUNCTIONH 04 + FUNCTIONH 05 + FUNCTIONH 06 + FUNCTIONH 07 + FUNCTIONH 08 + FUNCTIONH 09 + FUNCTIONH 10 + FUNCTIONH 11 + FUNCTIONH 12 + FUNCTIONH 13 + FUNCTIONH 14 + FUNCTIONH 15 + FUNCTIONH 16 + FUNCTIONH 17 + FUNCTIONH 18 + FUNCTIONH 19 + FUNCTIONH 20 + FUNCTIONH 21 + FUNCTIONH 22 + FUNCTIONH 23 + FUNCTIONH 24 + FUNCTIONH 25 + FUNCTIONH 26 + FUNCTIONH 27 + FUNCTIONH 28 + FUNCTIONH 29 + FUNCTIONH 30 + FUNCTIONH 31 +// expect Thunks in .texth + bl tfuncl00 + bl tfunch00 +// CHECK6: tfunch31: +// CHECK6-NEXT: 4100000: 70 47 bx lr +// CHECK6-NEXT: 4100002: 00 f0 03 f8 bl #6 +// CHECK6-NEXT: 4100006: 00 f0 06 f8 bl #12 +// CHECK6: __Thumbv7ABSLongThunk_tfuncl00: +// CHECK6-NEXT: 410000c: 40 f2 01 0c movw r12, #1 +// CHECK6-NEXT: 4100010: c0 f2 20 0c movt r12, #32 +// CHECK6-NEXT: 4100014: 60 47 bx r12 +// CHECK6: __Thumbv7ABSLongThunk_tfunch00: +// CHECK6-NEXT: 4100016: 40 f2 01 0c movw r12, #1 +// CHECK6-NEXT: 410001a: c0 f2 20 2c movt r12, #544 +// CHECK6-NEXT: 410001e: 60 47 bx r12 diff --git a/test/ELF/arm-thunk-linkerscript-orphan.s b/test/ELF/arm-thunk-linkerscript-orphan.s new file mode 100644 index 000000000000..f05cc0de9069 --- /dev/null +++ b/test/ELF/arm-thunk-linkerscript-orphan.s @@ -0,0 +1,63 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: .text_low 0x100000 : { *(.text_low) } \ +// RUN: .text_high 0x2000000 : { *(.text_high) } \ +// RUN: .data : { *(.data) } \ +// RUN: }" > %t.script +// RUN: ld.lld --script %t.script %t -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s + .syntax unified + .section .text_low, "ax", %progbits + .thumb + .globl _start +_start: bx lr + .globl low_target + .type low_target, %function +low_target: + bl high_target + bl orphan_target +// CHECK: Disassembly of section .text_low: +// CHECK-NEXT: _start: +// CHECK-NEXT: 100000: 70 47 bx lr +// CHECK: low_target: +// CHECK-NEXT: 100002: 00 f0 03 f8 bl #6 +// CHECK-NEXT: 100006: 00 f0 06 f8 bl #12 +// CHECK: __Thumbv7ABSLongThunk_high_target: +// CHECK-NEXT: 10000c: 40 f2 01 0c movw r12, #1 +// CHECK-NEXT: 100010: c0 f2 00 2c movt r12, #512 +// CHECK-NEXT: 100014: 60 47 bx r12 +// CHECK: __Thumbv7ABSLongThunk_orphan_target: +// CHECK-NEXT: 100016: 40 f2 15 0c movw r12, #21 +// CHECK-NEXT: 10001a: c0 f2 00 2c movt r12, #512 +// CHECK-NEXT: 10001e: 60 47 bx r12 + .section .text_high, "ax", %progbits + .thumb + .globl high_target + .type high_target, %function +high_target: + bl low_target + bl orphan_target +// CHECK: Disassembly of section .text_high: +// CHECK-NEXT: high_target: +// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4 +// CHECK-NEXT: 2000004: 00 f0 06 f8 bl #12 +// CHECK: __Thumbv7ABSLongThunk_low_target: +// CHECK-NEXT: 2000008: 40 f2 03 0c movw r12, #3 +// CHECK-NEXT: 200000c: c0 f2 10 0c movt r12, #16 +// CHECK-NEXT: 2000010: 60 47 bx r12 + + .section orphan, "ax", %progbits + .thumb + .globl orphan_target + .type orphan_target, %function +orphan_target: + bl low_target + bl high_target +// CHECK: Disassembly of section orphan: +// CHECK-NEXT: orphan_target: +// CHECK-NEXT: 2000014: ff f7 f8 ff bl #-16 +// CHECK-NEXT: 2000018: ff f7 f2 ff bl #-28 + + .data + .word 10 diff --git a/test/ELF/arm-thunk-linkerscript-sort.s b/test/ELF/arm-thunk-linkerscript-sort.s new file mode 100644 index 000000000000..69d176765780 --- /dev/null +++ b/test/ELF/arm-thunk-linkerscript-sort.s @@ -0,0 +1,71 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: .text 0x100000 : { *(SORT_BY_NAME(.text.*)) } \ +// RUN: }" > %t.script +// RUN: ld.lld --script %t.script %t -o %t2 2>&1 +// RUN: llvm-objdump -d %t2 -start-address=1048576 -stop-address=1048584 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t2 -start-address=16777220 -stop-address=16777230 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s + + .syntax unified + +// Test that linkerscript sorting does not apply to Thunks, we expect that the +// sort will reverse the order of sections presented here. + +// Define a function aligned on a megabyte boundary + .macro FUNCTION suff + .section .text.\suff\(), "ax", %progbits + .thumb + .balign 0x100000 + .globl tfunc\suff\() + .type tfunc\suff\(), %function +tfunc\suff\(): + bx lr + .endm + + FUNCTION 31 + FUNCTION 30 + FUNCTION 29 + FUNCTION 28 + FUNCTION 27 + FUNCTION 26 + FUNCTION 25 + FUNCTION 24 + FUNCTION 23 + FUNCTION 22 + FUNCTION 21 + FUNCTION 20 + FUNCTION 19 + FUNCTION 18 + FUNCTION 17 + FUNCTION 16 + FUNCTION 15 +// CHECK2: __Thumbv7ABSLongThunk_tfunc31: +// CHECK2-NEXT: 1000004: 40 f2 01 0c movw r12, #1 +// CHECK2-NEXT: 1000008: c0 f2 00 2c movt r12, #512 +// CHECK2-NEXT: 100000c: 60 47 bx r12 + FUNCTION 14 + FUNCTION 13 + FUNCTION 12 + FUNCTION 11 + FUNCTION 10 + FUNCTION 09 + FUNCTION 08 + FUNCTION 07 + FUNCTION 06 + FUNCTION 05 + FUNCTION 04 + FUNCTION 03 + FUNCTION 02 + FUNCTION 01 + .section .text.00, "ax", %progbits + .thumb + .globl _start +_start: +// Expect no range extension needed for tfunc01 and an extension needed for +// tfunc31 + bl tfunc01 + bl tfunc31 +// CHECK1: _start: +// CHECK1-NEXT: 100000: ff f0 fe ff bl #1048572 +// CHECK1-NEXT: 100004: ff f2 fe d7 bl #15728636 diff --git a/test/ELF/arm-thunk-linkerscript.s b/test/ELF/arm-thunk-linkerscript.s new file mode 100644 index 000000000000..9aaa29237cbe --- /dev/null +++ b/test/ELF/arm-thunk-linkerscript.s @@ -0,0 +1,78 @@ +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: echo "SECTIONS { \ +// RUN: . = SIZEOF_HEADERS; \ +// RUN: .text_low : { *(.text_low) *(.text_low2) } \ +// RUN: .text_high 0x2000000 : { *(.text_high) *(.text_high2) } \ +// RUN: } " > %t.script +// RUN: ld.lld --script %t.script %t -o %t2 2>&1 +// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s +// REQUIRES: arm +// Simple test that we can support range extension thunks with linker scripts + .syntax unified + .section .text_low, "ax", %progbits + .thumb + .globl _start +_start: bx lr + .globl low_target + .type low_target, %function +low_target: + bl high_target + bl high_target2 + + .section .text_low2, "ax", %progbits + .thumb + .globl low_target2 + .type low_target2, %function +low_target2: + bl high_target + bl high_target2 + +// CHECK: Disassembly of section .text_low: +// CHECK-NEXT: _start: +// CHECK-NEXT: 94: 70 47 bx lr +// CHECK: low_target: +// CHECK-NEXT: 96: 00 f0 03 f8 bl #6 +// CHECK-NEXT: 9a: 00 f0 06 f8 bl #12 +// CHECK: __Thumbv7ABSLongThunk_high_target: +// CHECK-NEXT: a0: 40 f2 01 0c movw r12, #1 +// CHECK-NEXT: a4: c0 f2 00 2c movt r12, #512 +// CHECK-NEXT: a8: 60 47 bx r12 +// CHECK: __Thumbv7ABSLongThunk_high_target2: +// CHECK-NEXT: aa: 40 f2 1d 0c movw r12, #29 +// CHECK-NEXT: ae: c0 f2 00 2c movt r12, #512 +// CHECK-NEXT: b2: 60 47 bx r12 +// CHECK: low_target2: +// CHECK-NEXT: b4: ff f7 f4 ff bl #-24 +// CHECK-NEXT: b8: ff f7 f7 ff bl #-18 + + .section .text_high, "ax", %progbits + .thumb + .globl high_target + .type high_target, %function +high_target: + bl low_target + bl low_target2 + + .section .text_high2, "ax", %progbits + .thumb + .globl high_target2 + .type high_target2, %function +high_target2: + bl low_target + bl low_target2 + +// CHECK: Disassembly of section .text_high: +// CHECK-NEXT: high_target: +// CHECK-NEXT: 2000000: 00 f0 02 f8 bl #4 +// CHECK-NEXT: 2000004: 00 f0 05 f8 bl #10 +// CHECK: __Thumbv7ABSLongThunk_low_target: +// CHECK-NEXT: 2000008: 40 f2 97 0c movw r12, #151 +// CHECK-NEXT: 200000c: c0 f2 00 0c movt r12, #0 +// CHECK-NEXT: 2000010: 60 47 bx r12 +// CHECK: __Thumbv7ABSLongThunk_low_target2: +// CHECK-NEXT: 2000012: 40 f2 b5 0c movw r12, #181 +// CHECK-NEXT: 2000016: c0 f2 00 0c movt r12, #0 +// CHECK-NEXT: 200001a: 60 47 bx r12 +// CHECK: high_target2: +// CHECK-NEXT: 200001c: ff f7 f4 ff bl #-24 +// CHECK-NEXT: 2000020: ff f7 f7 ff bl #-18 diff --git a/test/ELF/arm-thunk-multipass.s b/test/ELF/arm-thunk-multipass.s new file mode 100644 index 000000000000..25bf5235f755 --- /dev/null +++ b/test/ELF/arm-thunk-multipass.s @@ -0,0 +1,96 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t -o %t2 2>&1 +// The output file is large, most of it zeroes. We dissassemble only the +// parts we need to speed up the test and avoid a large output file +// RUN: llvm-objdump -d %t2 -start-address=1048578 -stop-address=1048586 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t2 -start-address=16777224 -stop-address=16777254 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s +// RUN: llvm-objdump -d %t2 -start-address=17825818 -stop-address=17825828 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s +// In this test case a branch that is in range and does not need its range +// extended can be pushed out of range by another Thunk, necessitating another +// pass + + .macro FUNCTION suff + .section .text.\suff\(), "ax", %progbits + .thumb + .balign 0x100000 + .globl tfunc\suff\() + .type tfunc\suff\(), %function +tfunc\suff\(): + bx lr + .endm + + FUNCTION 00 + .globl _start +_start: + bl target + b.w arm_target +// arm_target is in range but needs an interworking thunk +// CHECK1: _start: +// CHECK1-NEXT: 100002: 00 f3 06 d0 bl #15728652 +// CHECK1-NEXT: 100006: ff f2 ff 97 b.w #15728638 <__Thumbv7ABSLongThunk_arm_target> + nop + nop + nop + .globl target2 + .type target2, %function + nop + +target2: + FUNCTION 01 + FUNCTION 02 + FUNCTION 03 + FUNCTION 04 + FUNCTION 05 + FUNCTION 06 + FUNCTION 07 + FUNCTION 08 + FUNCTION 09 + FUNCTION 10 + FUNCTION 11 + FUNCTION 12 + FUNCTION 13 + FUNCTION 14 + FUNCTION 15 + + .section .text.16, "ax", %progbits + .arm + .globl arm_target + .type arm_target, %function +arm_target: + bx lr +// CHECK2: __Thumbv7ABSLongThunk_arm_target: +// CHECK2-NEXT: 1000008: 40 f2 02 0c movw r12, #2 +// CHECK2-NEXT: 100000c: c0 f2 00 1c movt r12, #256 +// CHECK2-NEXT: 1000010: 60 47 bx r12 +// CHECK2: __Thumbv7ABSLongThunk_target: +// CHECK2-NEXT: 1000012: 40 f2 1b 0c movw r12, #27 +// CHECK2-NEXT: 1000016: c0 f2 10 1c movt r12, #272 +// CHECK2-NEXT: 100001a: 60 47 bx r12 +// CHECK2: __Thumbv7ABSLongThunk_target2: +// CHECK2-NEXT: 100001c: 40 f2 13 0c movw r12, #19 +// CHECK2-NEXT: 1000020: c0 f2 10 0c movt r12, #16 +// CHECK2-NEXT: 1000024: 60 47 bx r12 + + .section .text.17, "ax", %progbits +// Just enough space so that bl target is in range if no extension thunks are +// generated. + + .space 0x100000 - 12 + + .section .text.18, "ax", %progbits + .thumb + .globl target + .type target, %function +// target is at maximum ARM branch range away from caller. +target: +// Similar case in the backwards direction + bl target2 + nop + nop + bx lr +// CHECK3: target: +// CHECK3-NEXT: 110001a: ff f6 ff ff bl #-1048578 +// CHECK3-NEXT: 110001e: 00 bf nop +// CHECK3-NEXT: 1100020: 00 bf nop +// CHECK3-NEXT: 1100022: 70 47 bx lr diff --git a/test/ELF/arm-thunk-re-add.s b/test/ELF/arm-thunk-re-add.s new file mode 100644 index 000000000000..760e18f57313 --- /dev/null +++ b/test/ELF/arm-thunk-re-add.s @@ -0,0 +1,123 @@ +// REQUIRES: arm +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: ld.lld %t --shared -o %t.so +// The output file is large, most of it zeroes. We dissassemble only the +// parts we need to speed up the test and avoid a large output file +// RUN: llvm-objdump -d %t.so -start-address=16777220 -stop-address=16777244 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK1 %s +// RUN: llvm-objdump -d %t.so -start-address=17825800 -stop-address=17825826 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK2 %s +// RUN: llvm-objdump -d %t.so -start-address=17825824 -stop-address=17825892 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK3 %s + +// A branch to a Thunk that we create on pass N, can drift out of range if +// other Thunks are added in between. In this case we must create a new Thunk +// for the branch that is in range. We also need to make sure that if the +// destination of the Thunk is in the PLT the new Thunk also targets the PLT + .syntax unified + .thumb + + .macro FUNCTION suff + .section .text.\suff\(), "ax", %progbits + .thumb + .balign 0x80000 + .globl tfunc\suff\() + .type tfunc\suff\(), %function +tfunc\suff\(): + bx lr + .endm + + .globl imported + .type imported, %function + .globl imported2 + .type imported2, %function + .globl imported3 + .type imported3, %function +.globl imported4 + .type imported4, %function + FUNCTION 00 + FUNCTION 01 + FUNCTION 02 + FUNCTION 03 + FUNCTION 04 + FUNCTION 05 + FUNCTION 06 + FUNCTION 07 + FUNCTION 08 + FUNCTION 09 + FUNCTION 10 + FUNCTION 11 + FUNCTION 12 + FUNCTION 13 + FUNCTION 14 + FUNCTION 15 + FUNCTION 16 + FUNCTION 17 + FUNCTION 18 + FUNCTION 19 + FUNCTION 20 + FUNCTION 21 + FUNCTION 22 + FUNCTION 23 + FUNCTION 24 + FUNCTION 25 + FUNCTION 26 + FUNCTION 27 + FUNCTION 28 + FUNCTION 29 + FUNCTION 30 + FUNCTION 31 +// Precreated Thunk Pool goes here +// CHECK1: __ThumbV7PILongThunk_imported: +// CHECK1-NEXT: 1000004: 40 f2 30 0c movw r12, #48 +// CHECK1-NEXT: 1000008: c0 f2 10 0c movt r12, #16 +// CHECK1-NEXT: 100000c: fc 44 add r12, pc +// CHECK1-NEXT: 100000e: 60 47 bx r12 +// CHECK1: __ThumbV7PILongThunk_imported2: +// CHECK1-NEXT: 1000010: 40 f2 34 0c movw r12, #52 +// CHECK1-NEXT: 1000014: c0 f2 10 0c movt r12, #16 +// CHECK1-NEXT: 1000018: fc 44 add r12, pc +// CHECK1-NEXT: 100001a: 60 47 bx r12 + + .section .text.32, "ax", %progbits + .space 0x80000 + .section .text.33, "ax", %progbits + .space 0x80000 - 0x14 + .section .text.34, "ax", %progbits + // Need a Thunk to the PLT entry, can use precreated ThunkSection + .globl callers + .type callers, %function +callers: + b.w imported + beq.w imported + b.w imported2 +// CHECK2: __ThumbV7PILongThunk_imported: +// CHECK2-NEXT: 1100008: 40 f2 2c 0c movw r12, #44 +// CHECK2-NEXT: 110000c: c0 f2 00 0c movt r12, #0 +// CHECK2-NEXT: 1100010: fc 44 add r12, pc +// CHECK2-NEXT: 1100012: 60 47 bx r12 +// CHECK2: callers: +// CHECK2-NEXT: 1100014: ff f6 f6 bf b.w #-1048596 <__ThumbV7PILongThunk_imported> +// CHECK2-NEXT: 1100018: 3f f4 f6 af beq.w #-20 <__ThumbV7PILongThunk_imported> +// CHECK2-NEXT: 110001c: ff f6 f8 bf b.w #-1048592 <__ThumbV7PILongThunk_imported2> + +// CHECK3: Disassembly of section .plt: +// CHECK3-NEXT: $a: +// CHECK3-NEXT: 1100020: 04 e0 2d e5 str lr, [sp, #-4]! +// CHECK3-NEXT: 1100024: 00 e6 8f e2 add lr, pc, #0, #12 +// CHECK3-NEXT: 1100028: 00 ea 8e e2 add lr, lr, #0, #20 +// CHECK3-NEXT: 110002c: dc ff be e5 ldr pc, [lr, #4060]! +// CHECK3: $d: +// CHECK3-NEXT: 1100030: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK3-NEXT: 1100034: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK3-NEXT: 1100038: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK3-NEXT: 110003c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK3: $a: +// CHECK3-NEXT: 1100040: 00 c6 8f e2 add r12, pc, #0, #12 +// CHECK3-NEXT: 1100044: 00 ca 8c e2 add r12, r12, #0, #20 +// CHECK3-NEXT: 1100048: c4 ff bc e5 ldr pc, [r12, #4036]! +// CHECK3: $d: +// CHECK3-NEXT: 110004c: d4 d4 d4 d4 .word 0xd4d4d4d4 +// CHECK3: $a: +// CHECK3-NEXT: 1100050: 00 c6 8f e2 add r12, pc, #0, #12 +// CHECK3-NEXT: 1100054: 00 ca 8c e2 add r12, r12, #0, #20 +// CHECK3-NEXT: 1100058: b8 ff bc e5 ldr pc, [r12, #4024]! +// CHECK3: $d: +// CHECK3-NEXT: 110005c: d4 d4 d4 d4 .word 0xd4d4d4d4 diff --git a/test/ELF/arm-thunk-toolargesection.s b/test/ELF/arm-thunk-toolargesection.s new file mode 100644 index 000000000000..28fb94a8ccfd --- /dev/null +++ b/test/ELF/arm-thunk-toolargesection.s @@ -0,0 +1,19 @@ +// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t +// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s +// REQUIRES: arm + .syntax unified + .balign 0x1000 + .thumb + .text + .globl _start + .type _start, %function +_start: + bx lr + + .section .text.large1, "ax", %progbits + .balign 4 +.space (17 * 1024 * 1024) + bl _start +.space (17 * 1024 * 1024) + +// CHECK: error: InputSection too large for range extension thunk {{.*}}.text.large1 diff --git a/test/ELF/arm-tls-gd-nonpreemptible.s b/test/ELF/arm-tls-gd-nonpreemptible.s index 650c00800269..ebaad4788c76 100644 --- a/test/ELF/arm-tls-gd-nonpreemptible.s +++ b/test/ELF/arm-tls-gd-nonpreemptible.s @@ -2,7 +2,7 @@ // RUN: ld.lld %t -o %t2 // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi // RUN: llvm-objdump -s %t2 | FileCheck %s -// RUN: ld.lld %t --shared -o %t3.so +// RUN: ld.lld --hash-style=sysv %t --shared -o %t3.so // RUN: llvm-objdump -s %t3.so | FileCheck -check-prefix=CHECK-SHARED %s // REQUIRES: arm diff --git a/test/ELF/arm-tls-gd32.s b/test/ELF/arm-tls-gd32.s index 206b65d05af9..a32e26f2aeb9 100644 --- a/test/ELF/arm-tls-gd32.s +++ b/test/ELF/arm-tls-gd32.s @@ -1,5 +1,5 @@ // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi -// RUN: ld.lld %t.o -o %t.so -shared +// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared // RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/arm-tls-ie32.s b/test/ELF/arm-tls-ie32.s index 48120fa682da..26e1265568c8 100644 --- a/test/ELF/arm-tls-ie32.s +++ b/test/ELF/arm-tls-ie32.s @@ -1,5 +1,5 @@ // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi -// RUN: ld.lld %t.o -o %t.so -shared +// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared // RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/arm-tls-ldm32.s b/test/ELF/arm-tls-ldm32.s index 47e879102707..629dcd038899 100644 --- a/test/ELF/arm-tls-ldm32.s +++ b/test/ELF/arm-tls-ldm32.s @@ -1,5 +1,5 @@ // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi -// RUN: ld.lld %t.o -o %t.so -shared +// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared // RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s // RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/arm-tls-norelax-gd-ie.s b/test/ELF/arm-tls-norelax-gd-ie.s index 2617089b4080..bcee56165958 100644 --- a/test/ELF/arm-tls-norelax-gd-ie.s +++ b/test/ELF/arm-tls-norelax-gd-ie.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 // RUN: ld.lld %t1 --shared -o %t1.so // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi -// RUN: ld.lld %t1.so %t.o -o %t +// RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t // RUN: llvm-readobj -s -dyn-relocations %t | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/arm-tls-norelax-gd-le.s b/test/ELF/arm-tls-norelax-gd-le.s index 41df72494f8b..788c845b3f8b 100644 --- a/test/ELF/arm-tls-norelax-gd-le.s +++ b/test/ELF/arm-tls-norelax-gd-le.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 // RUN: ld.lld %t1 --shared -o %t1.so // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi -// RUN: ld.lld %t1.so %t.o -o %t +// RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t // RUN: llvm-objdump -s %t | FileCheck %s // REQUIRES: arm @@ -35,3 +35,7 @@ x: // Module index is always 1 for executable // CHECK-NEXT: 13060 01000000 00000000 + +// Without any definition of __tls_get_addr we get an error +// RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck --check-prefix=ERR %s +// ERR: error: undefined symbol: __tls_get_addr diff --git a/test/ELF/arm-tls-norelax-ie-le.s b/test/ELF/arm-tls-norelax-ie-le.s index e8c528b401ca..eb96aa0fad57 100644 --- a/test/ELF/arm-tls-norelax-ie-le.s +++ b/test/ELF/arm-tls-norelax-ie-le.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 // RUN: ld.lld %t1 --shared -o %t1.so // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi -// RUN: ld.lld %t1.so %t.o -o %t +// RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t // RUN: llvm-objdump -s -triple=armv7a-linux-gnueabi %t | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/arm-tls-norelax-ld-le.s b/test/ELF/arm-tls-norelax-ld-le.s index 9fd822aefef7..fc5b72b80f9c 100644 --- a/test/ELF/arm-tls-norelax-ld-le.s +++ b/test/ELF/arm-tls-norelax-ld-le.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1 // RUN: ld.lld %t1 --shared -o %t1.so // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi -// RUN: ld.lld %t1.so %t.o -o %t +// RUN: ld.lld --hash-style=sysv %t1.so %t.o -o %t // RUN: llvm-objdump -s %t | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/as-needed.s b/test/ELF/as-needed.s index 37c6103b0ed0..bcfa32d01f66 100644 --- a/test/ELF/as-needed.s +++ b/test/ELF/as-needed.s @@ -15,6 +15,10 @@ // RUN: ld.lld --as-needed %t.o %t2.so %t3.so %t4.so -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s +// Test with the .o last +// RUN: ld.lld --as-needed %t2.so %t3.so %t4.so %t.o -o %t2 +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s + // RUN: ld.lld --as-needed %t.o %t2.so --no-as-needed %t3.so %t4.so -o %t2 // RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s diff --git a/test/ELF/assignment-archive.s b/test/ELF/assignment-archive.s new file mode 100644 index 000000000000..11753a692130 --- /dev/null +++ b/test/ELF/assignment-archive.s @@ -0,0 +1,27 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %ta.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t.o < /dev/null +# RUN: rm -f %tar.a +# RUN: llvm-ar rcs %tar.a %ta.o + +# RUN: echo "SECTIONS { foo = 1; }" > %t1.script +# RUN: ld.lld -o %t1.exe --script %t1.script %tar.a %t.o +# RUN: llvm-readobj -symbols %t1.exe | FileCheck %s +# CHECK-NOT: bar +# CHECK: foo +# CHECK-NOT: bar + +# RUN: echo "SECTIONS { zed = foo; }" > %t2.script +# RUN: ld.lld -o %t2.exe --script %t2.script %tar.a %t.o +# RUN: llvm-readobj -symbols %t2.exe | FileCheck %s --check-prefix=SYMS +# SYMS: bar +# SYMS: foo + +.text +.globl foo +foo: + nop + +.globl bar +bar: + nop diff --git a/test/ELF/avoid-empty-program-headers.s b/test/ELF/avoid-empty-program-headers.s index 271d1a303850..731ecce67cbc 100644 --- a/test/ELF/avoid-empty-program-headers.s +++ b/test/ELF/avoid-empty-program-headers.s @@ -42,8 +42,8 @@ _start: // CHECK-NEXT: Offset: 0x1000 // CHECK-NEXT: VirtualAddress: 0x201000 // CHECK-NEXT: PhysicalAddress: 0x201000 -// CHECK-NEXT: FileSize: 1 -// CHECK-NEXT: MemSize: 1 +// CHECK-NEXT: FileSize: 4096 +// CHECK-NEXT: MemSize: 4096 // CHECK-NEXT: Flags [ (0x5) // CHECK-NEXT: PF_R (0x4) // CHECK-NEXT: PF_X (0x1) @@ -52,7 +52,7 @@ _start: // CHECK-NEXT: } // CHECK-NEXT: ProgramHeader { // CHECK-NEXT: Type: PT_TLS (0x7) -// CHECK-NEXT: Offset: 0x1001 +// CHECK-NEXT: Offset: 0x2000 // CHECK-NEXT: VirtualAddress: 0x201001 // CHECK-NEXT: PhysicalAddress: 0x201001 // CHECK-NEXT: FileSize: 0 diff --git a/test/ELF/basic-aarch64.s b/test/ELF/basic-aarch64.s index 144fe6aee41b..6527d3dc0def 100644 --- a/test/ELF/basic-aarch64.s +++ b/test/ELF/basic-aarch64.s @@ -26,7 +26,7 @@ _start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]] # CHECK-NEXT: ProgramHeaderOffset: 0x40 -# CHECK-NEXT: SectionHeaderOffset: 0x10098 +# CHECK-NEXT: SectionHeaderOffset: 0x11088 # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 @@ -76,12 +76,12 @@ _start: # CHECK-NEXT: SHF_STRINGS (0x20) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1000C +# CHECK-NEXT: Offset: 0x11000 # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 -# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: EntrySize: 1 # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 3 @@ -90,7 +90,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x10018 +# CHECK-NEXT: Offset: 0x11008 # CHECK-NEXT: Size: 72 # CHECK-NEXT: Link: 5 # CHECK-NEXT: Info: 2 @@ -104,7 +104,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x10060 +# CHECK-NEXT: Offset: 0x11050 # CHECK-NEXT: Size: 42 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -118,7 +118,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1008A +# CHECK-NEXT: Offset: 0x1107A # CHECK-NEXT: Size: 13 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -185,8 +185,8 @@ _start: # CHECK-NEXT: Offset: 0x1000 # CHECK-NEXT: VirtualAddress: 0x20000 # CHECK-NEXT: PhysicalAddress: 0x20000 -# CHECK-NEXT: FileSize: 12 -# CHECK-NEXT: MemSize: 12 +# CHECK-NEXT: FileSize: 4096 +# CHECK-NEXT: MemSize: 4096 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) diff --git a/test/ELF/basic-mips.s b/test/ELF/basic-mips.s index 4c7a66cf0050..a193529b3487 100644 --- a/test/ELF/basic-mips.s +++ b/test/ELF/basic-mips.s @@ -164,7 +164,7 @@ __start: # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 -# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: EntrySize: 1 # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 8 @@ -228,7 +228,7 @@ __start: # CHECK-NEXT: Other [ (0x2) # CHECK-NEXT: STV_HIDDEN (0x2) # CHECK-NEXT: ] -# CHECK-NEXT: Section: Absolute +# CHECK-NEXT: Section: .got # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: __start diff --git a/test/ELF/basic-ppc.s b/test/ELF/basic-ppc.s index 4a36af99ed72..cda32245fd2b 100644 --- a/test/ELF/basic-ppc.s +++ b/test/ELF/basic-ppc.s @@ -1,5 +1,5 @@ # RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t -# RUN: ld.lld -discard-all -shared %t -o %t2 +# RUN: ld.lld --hash-style=sysv -discard-all -shared %t -o %t2 # RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s # REQUIRES: ppc @@ -163,7 +163,7 @@ // 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: 4C4C4420 312E3000 |LLD 1.0.| // CHECK-NEXT: ) diff --git a/test/ELF/basic-sparcv9.s b/test/ELF/basic-sparcv9.s index 983224c52913..75c20476a43b 100644 --- a/test/ELF/basic-sparcv9.s +++ b/test/ELF/basic-sparcv9.s @@ -26,7 +26,7 @@ _start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]] # CHECK-NEXT: ProgramHeaderOffset: 0x40 -# CHECK-NEXT: SectionHeaderOffset: 0x100080 +# CHECK-NEXT: SectionHeaderOffset: 0x102070 # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 @@ -76,12 +76,12 @@ _start: # CHECK-NEXT: SHF_STRINGS (0x20) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x10000C +# CHECK-NEXT: Offset: 0x102000 # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 -# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: EntrySize: 1 # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 3 @@ -90,7 +90,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x100018 +# CHECK-NEXT: Offset: 0x102008 # CHECK-NEXT: Size: 48 # CHECK-NEXT: Link: 5 # CHECK-NEXT: Info: 1 @@ -104,7 +104,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x100048 +# CHECK-NEXT: Offset: 0x102038 # CHECK-NEXT: Size: 42 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -118,7 +118,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x100072 +# CHECK-NEXT: Offset: 0x102062 # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -176,8 +176,8 @@ _start: # CHECK-NEXT: Offset: 0x100000 # CHECK-NEXT: VirtualAddress: 0x200000 # CHECK-NEXT: PhysicalAddress: 0x200000 -# CHECK-NEXT: FileSize: 12 -# CHECK-NEXT: MemSize: 12 +# CHECK-NEXT: FileSize: 8192 +# CHECK-NEXT: MemSize: 8192 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) diff --git a/test/ELF/basic.s b/test/ELF/basic.s index c62a516c1bf6..a62f3dc0e853 100644 --- a/test/ELF/basic.s +++ b/test/ELF/basic.s @@ -28,7 +28,7 @@ _start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]] # CHECK-NEXT: ProgramHeaderOffset: 0x40 -# CHECK-NEXT: SectionHeaderOffset: 0x1080 +# CHECK-NEXT: SectionHeaderOffset: 0x2070 # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 64 @@ -78,12 +78,12 @@ _start: # CHECK-NEXT: SHF_STRINGS (0x20) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1010 +# CHECK-NEXT: Offset: 0x2000 # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 -# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: EntrySize: 1 # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 3 @@ -92,7 +92,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1018 +# CHECK-NEXT: Offset: 0x2008 # CHECK-NEXT: Size: 48 # CHECK-NEXT: Link: 5 # CHECK-NEXT: Info: 1 @@ -106,7 +106,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1048 +# CHECK-NEXT: Offset: 0x2038 # CHECK-NEXT: Size: 42 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -120,7 +120,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1072 +# CHECK-NEXT: Offset: 0x2062 # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -178,8 +178,8 @@ _start: # CHECK-NEXT: Offset: 0x1000 # CHECK-NEXT: VirtualAddress: 0x201000 # CHECK-NEXT: PhysicalAddress: 0x201000 -# CHECK-NEXT: FileSize: 16 -# CHECK-NEXT: MemSize: 16 +# CHECK-NEXT: FileSize: 4096 +# CHECK-NEXT: MemSize: 4096 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) @@ -246,7 +246,9 @@ _start: # UNKNOWN_EMUL: unknown emulation: wrong_emul_fbsd # RUN: not ld.lld %t --lto-partitions=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s +# RUN: not ld.lld %t --plugin-opt=lto-partitions=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s # NOTHREADS: --lto-partitions: number of threads must be > 0 # RUN: not ld.lld %t --thinlto-jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s +# RUN: not ld.lld %t --plugin-opt=jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s # NOTHREADSTHIN: --thinlto-jobs: number of threads must be > 0 diff --git a/test/ELF/basic32.s b/test/ELF/basic32.s index cbf67eec8b7d..071a06332f0a 100644 --- a/test/ELF/basic32.s +++ b/test/ELF/basic32.s @@ -25,7 +25,7 @@ _start: # CHECK-NEXT: Version: 1 # CHECK-NEXT: Entry: 0x11000 # CHECK-NEXT: ProgramHeaderOffset: 0x34 -# CHECK-NEXT: SectionHeaderOffset: 0x1068 +# CHECK-NEXT: SectionHeaderOffset: 0x205C # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 52 @@ -75,12 +75,12 @@ _start: # CHECK-NEXT: SHF_STRINGS (0x20) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x100C +# CHECK-NEXT: Offset: 0x2000 # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 1 -# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: EntrySize: 1 # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 3 @@ -89,7 +89,7 @@ _start: # CHECK-NEXT: Flags [ # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1014 +# CHECK-NEXT: Offset: 0x2008 # CHECK-NEXT: Size: 32 # CHECK-NEXT: Link: 5 # CHECK-NEXT: Info: 1 @@ -103,7 +103,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x1034 +# CHECK-NEXT: Offset: 0x2028 # CHECK-NEXT: Size: 42 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -117,7 +117,7 @@ _start: # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x0 -# CHECK-NEXT: Offset: 0x105E +# CHECK-NEXT: Offset: 0x2052 # CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -155,8 +155,8 @@ _start: # CHECK-NEXT: Offset: 0x1000 # CHECK-NEXT: VirtualAddress: 0x11000 # CHECK-NEXT: PhysicalAddress: 0x11000 -# CHECK-NEXT: FileSize: 12 -# CHECK-NEXT: MemSize: 12 +# CHECK-NEXT: FileSize: 4096 +# CHECK-NEXT: MemSize: 4096 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) diff --git a/test/ELF/basic64be.s b/test/ELF/basic64be.s index c39669bfd547..d16f4a074175 100644 --- a/test/ELF/basic64be.s +++ b/test/ELF/basic64be.s @@ -175,7 +175,7 @@ _start: # 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: 4C4C4420 312E3000 |LLD 1.0.| # CHECK-NEXT: ) diff --git a/test/ELF/build-id.s b/test/ELF/build-id.s index 2d193478df71..9447a14d4e8a 100644 --- a/test/ELF/build-id.s +++ b/test/ELF/build-id.s @@ -2,6 +2,9 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld --build-id %t -o %t2 +# RUN: llvm-readobj -s %t2 | FileCheck -check-prefix=ALIGN %s + # RUN: ld.lld --build-id %t -o %t2 -threads # RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s # RUN: ld.lld --build-id %t -o %t2 -no-threads @@ -45,18 +48,30 @@ _start: .section .note.test, "a", @note .quad 42 +# ALIGN: Name: .note.gnu.build-id +# ALIGN-NEXT: Type: SHT_NOTE +# ALIGN-NEXT: Flags [ +# ALIGN-NEXT: SHF_ALLOC +# ALIGN-NEXT: ] +# ALIGN-NEXT: Address: +# ALIGN-NEXT: Offset: [[_:0x[0-9A-Z]*(0|4|8|C)$]] +# ALIGN-NEXT: Size: +# ALIGN-NEXT: Link: +# ALIGN-NEXT: Info: +# ALIGN-NEXT: AddressAlignment: 4 + # DEFAULT: Contents of section .note.test: # DEFAULT: Contents of section .note.gnu.build-id: # DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU. -# DEFAULT-NEXT: fd36edb1 f6ff02af +# DEFAULT-NEXT: 894c04e8 fbf5556b # MD5: Contents of section .note.gnu.build-id: # MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU. -# MD5-NEXT: fc +# MD5-NEXT: 6a51bbd7 9e8ee3f9 2e02d213 711cfec9 # SHA1: Contents of section .note.gnu.build-id: # SHA1-NEXT: 04000000 14000000 03000000 474e5500 ............GNU. -# SHA1-NEXT: 55b1eedb 03b588e1 09987d1d e9a79be7 +# SHA1-NEXT: 9a8618b1 d6fd0e5c eda73dd8 76de5596 # UUID: Contents of section .note.gnu.build-id: # UUID-NEXT: 04000000 10000000 03000000 474e5500 ............GNU. diff --git a/test/ELF/chroot.s b/test/ELF/chroot.s new file mode 100644 index 000000000000..8c97e99af4dc --- /dev/null +++ b/test/ELF/chroot.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: rm -rf %t.dir +# RUN: mkdir %t.dir +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/chroot.o +# RUN: ld.lld --chroot %t.dir -o %t.exe /chroot.o + +# RUN: echo 'INPUT(/chroot.o)' > %t.dir/scr +# RUN: ld.lld --chroot %t.dir -o %t.exe /scr + +.globl _start +_start: + ret diff --git a/test/ELF/comment-gc.s b/test/ELF/comment-gc.s index 8018ff89bbf9..44c08fe9cef9 100644 --- a/test/ELF/comment-gc.s +++ b/test/ELF/comment-gc.s @@ -5,8 +5,7 @@ # RUN: llvm-objdump -s %t1 | FileCheck %s # CHECK: Contents of section .comment: -# CHECK-NEXT: 0000 00666f6f 00626172 004c4c44 20312e30 .foo.bar.LLD 1.0 -# CHECK-NEXT: 0010 00 . +# CHECK-NEXT: foo..LLD 1.0.bar .ident "foo" diff --git a/test/ELF/common-gc.s b/test/ELF/common-gc.s new file mode 100644 index 000000000000..99fde9ea3c39 --- /dev/null +++ b/test/ELF/common-gc.s @@ -0,0 +1,41 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t + +# RUN: ld.lld %t -o %t2 +# RUN: llvm-readobj -sections -symbols %t2 | FileCheck %s --check-prefix=NOGC + +# NOGC: Name: .bss +# NOGC-NEXT: Type: +# NOGC-NEXT: Flags [ +# NOGC-NEXT: SHF_ALLOC +# NOGC-NEXT: SHF_WRITE +# NOGC-NEXT: ] +# NOGC-NEXT: Address: +# NOGC-NEXT: Offset: +# NOGC-NEXT: Size: 8 + +# NOGC: Name: bar +# NOGC: Name: foo + +# RUN: ld.lld -gc-sections %t -o %t1 +# RUN: llvm-readobj -sections -symbols %t1 | FileCheck %s --check-prefix=GC + +# GC: Name: .bss +# GC-NEXT: Type: +# GC-NEXT: Flags [ +# GC-NEXT: SHF_ALLOC +# GC-NEXT: SHF_WRITE +# GC-NEXT: ] +# GC-NEXT: Address: +# GC-NEXT: Offset: +# GC-NEXT: Size: 4 + +# GC-NOT: Name: bar + +.comm foo,4,4 +.comm bar,4,4 + +.text +.globl _start +_start: + .quad foo diff --git a/test/ELF/common-gc2.s b/test/ELF/common-gc2.s new file mode 100644 index 000000000000..165bf625394e --- /dev/null +++ b/test/ELF/common-gc2.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +# RUN: ld.lld -gc-sections -export-dynamic %t -o %t1 +# RUN: llvm-readobj --dyn-symbols %t1 | FileCheck %s + +# CHECK: Name: bar@ +# CHECK: Name: foo@ + +.comm foo,4,4 +.comm bar,4,4 + +.text +.globl _start +_start: + .quad foo diff --git a/test/ELF/common-gc3.s b/test/ELF/common-gc3.s new file mode 100644 index 000000000000..e161a635c077 --- /dev/null +++ b/test/ELF/common-gc3.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t1 --gc-sections +# RUN: llvm-objdump -s %t1 | FileCheck %s + +# CHECK: Contents of section .noalloc: +# 0000 00000000 00000000 ........ + + .section .text._start,"ax",@progbits + .globl _start +_start: + retq + + .type unused,@object + .comm unused,4,4 + + .section .noalloc,"",@progbits + .quad unused diff --git a/test/ELF/common.s b/test/ELF/common.s index c8011a0a5088..7f241ee4d65b 100644 --- a/test/ELF/common.s +++ b/test/ELF/common.s @@ -12,13 +12,13 @@ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x201000 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 22 +// CHECK-NEXT: Size: 36 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 16 // CHECK: Name: sym1 -// CHECK-NEXT: Value: 0x201004 +// CHECK-NEXT: Value: 0x201000 // CHECK-NEXT: Size: 8 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -26,7 +26,7 @@ // CHECK-NEXT: Section: .bss // CHECK: Name: sym2 -// CHECK-NEXT: Value: 0x20100C +// CHECK-NEXT: Value: 0x201008 // CHECK-NEXT: Size: 8 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -34,7 +34,7 @@ // CHECK-NEXT: Section: .bss // CHECK: Name: sym3 -// CHECK-NEXT: Value: 0x201014 +// CHECK-NEXT: Value: 0x201010 // CHECK-NEXT: Size: 2 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object @@ -42,7 +42,7 @@ // CHECK-NEXT: Section: .bss // CHECK: Name: sym4 -// CHECK-NEXT: Value: 0x201000 +// CHECK-NEXT: Value: 0x201020 // CHECK-NEXT: Size: 4 // CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object diff --git a/test/ELF/compress-debug-sections.s b/test/ELF/compress-debug-sections.s index 5fb7ee515dcb..a7933e130b77 100644 --- a/test/ELF/compress-debug-sections.s +++ b/test/ELF/compress-debug-sections.s @@ -15,12 +15,17 @@ # ZLIBFLAGS-NEXT: Flags [ # ZLIBFLAGS-NEXT: SHF_COMPRESSED -# RUN: llvm-dwarfdump %t1 -debug-dump=str | \ +# RUN: llvm-dwarfdump %t1 -debug-str | \ # RUN: FileCheck %s --check-prefix=DEBUGSTR # DEBUGSTR: .debug_str contents: # DEBUGSTR-NEXT: AAAAAAAAAAAAAAAAAAAAAAAAAAA # DEBUGSTR-NEXT: BBBBBBBBBBBBBBBBBBBBBBBBBBB +## Test alias. +# RUN: ld.lld %t.o -o %t2 --compress-debug-sections zlib +# RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=ZLIBCONTENT +# RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS + # RUN: not ld.lld %t.o -o %t1 --compress-debug-sections=zlib-gabi 2>&1 | \ # RUN: FileCheck -check-prefix=ERR %s # ERR: unknown --compress-debug-sections value: zlib-gabi diff --git a/test/ELF/compressed-debug-conflict.s b/test/ELF/compressed-debug-conflict.s new file mode 100644 index 000000000000..c67bc9201803 --- /dev/null +++ b/test/ELF/compressed-debug-conflict.s @@ -0,0 +1,29 @@ +# REQUIRES: x86, zlib +# RUN: llvm-mc -filetype=obj -triple i686-linux-gnu -compress-debug-sections=zlib %s -o %t.o +# RUN: llvm-readobj -sections %t.o | FileCheck -check-prefix=OBJ %s +# RUN: not ld.lld %t.o %t.o -o %tout 2>&1 | FileCheck -check-prefix=ERROR %s + +# OBJ: Sections [ +# OBJ: Section { +# OBJ: Index: 3 +# OBJ-NEXT: Name: .debug_line (16) +# OBJ-NEXT: Type: SHT_PROGBITS (0x1) +# OBJ-NEXT: Flags [ (0x800) +# OBJ-NEXT: SHF_COMPRESSED (0x800) +# OBJ-NEXT: ] + +# ERROR: error: duplicate symbol: main +# ERROR-NEXT: >>> defined at reduced.c:2 (/tmp/reduced.c:2) +# ERROR-NEXT: >>> +# ERROR-NEXT: >>> defined at reduced.c:2 (/tmp/reduced.c:2) +# ERROR-NEXT: >>> + + .text + .file "reduced.c" + .globl main +main: + .file 1 "/tmp" "reduced.c" + .loc 1 2 0 + xorl %eax, %eax + retl + .file 2 "/tmp/repeat/repeat/repeat/repeat" "repeat.h" diff --git a/test/ELF/compressed-debug-input.s b/test/ELF/compressed-debug-input.s index d96ebdcb30b4..aad8cd02b3b1 100644 --- a/test/ELF/compressed-debug-input.s +++ b/test/ELF/compressed-debug-input.s @@ -39,10 +39,10 @@ # GNU-NEXT: EntrySize: 1 # GNU-NEXT: } -# RUN: ld.lld %t -o %t.so -shared +# RUN: ld.lld --hash-style=sysv %t -o %t.so -shared # RUN: llvm-readobj -sections -section-data %t.so | FileCheck -check-prefix=DATA %s -# RUN: ld.lld %t2 -o %t2.so -shared +# RUN: ld.lld --hash-style=sysv %t2 -o %t2.so -shared # RUN: llvm-readobj -sections -section-data %t2.so | FileCheck -check-prefix=DATA %s # DATA: Section { @@ -59,13 +59,13 @@ # DATA-NEXT: Link: 0 # DATA-NEXT: Info: 0 # DATA-NEXT: AddressAlignment: 1 -# DATA-NEXT: EntrySize: 0 +# DATA-NEXT: EntrySize: 1 # DATA-NEXT: SectionData ( -# DATA-NEXT: 0000: 73686F72 7420756E 7369676E 65642069 |short unsigned i| -# DATA-NEXT: 0010: 6E740075 6E736967 6E656420 696E7400 |nt.unsigned int.| -# DATA-NEXT: 0020: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in| -# DATA-NEXT: 0030: 74006368 61720075 6E736967 6E656420 |t.char.unsigned | -# DATA-NEXT: 0040: 63686172 00 |char.| +# DATA-NEXT: 0000: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in| +# DATA-NEXT: 0010: 7400756E 7369676E 65642063 68617200 |t.unsigned char.| +# DATA-NEXT: 0020: 756E7369 676E6564 20696E74 00636861 |unsigned int.cha| +# DATA-NEXT: 0030: 72007368 6F727420 756E7369 676E6564 |r.short unsigned| +# DATA-NEXT: 0040: 20696E74 00 | int.| # DATA-NEXT: ) # DATA-NEXT: } diff --git a/test/ELF/conflict-debug-variable.s b/test/ELF/conflict-debug-variable.s new file mode 100644 index 000000000000..297ed4bbe1ea --- /dev/null +++ b/test/ELF/conflict-debug-variable.s @@ -0,0 +1,144 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: llvm-dwarfdump %t.o | FileCheck -check-prefix=INPUT %s +# RUN: not ld.lld %t.o %t.o -o %t 2>&1 | FileCheck %s + +# INPUT: .debug_info contents: +# INPUT: DW_TAG_variable +# INPUT-NEXT: DW_AT_name ("foo") +# INPUT-NEXT: DW_AT_decl_file ("1.c") +# INPUT-NEXT: DW_AT_decl_line (1) +# INPUT-NEXT: DW_AT_type (cu + 0x0032 "int") +# INPUT-NEXT: DW_AT_external (true) +# INPUT-NEXT: DW_AT_location (DW_OP_addr 0x0) +# INPUT: DW_TAG_variable +# INPUT-NEXT: DW_AT_name ("bar") +# INPUT-NEXT: DW_AT_decl_file ("1.c") +# INPUT-NEXT: DW_AT_decl_line (2) +# INPUT-NEXT: DW_AT_type (cu + 0x0032 "int") +# INPUT-NEXT: DW_AT_external (true) +# INPUT-NEXT: DW_AT_location (DW_OP_addr 0x0) + +## Check we use information from .debug_info in messages. +# CHECK: duplicate symbol: bar +# CHECK-NEXT: >>> defined at 1.c:2 +# CHECK-NEXT: >>> {{.*}}:(bar) +# CHECK-NEXT: >>> defined at 1.c:2 +# CHECK-NEXT: >>> {{.*}}:(.data+0x0) +# CHECK: duplicate symbol: foo +# CHECK-NEXT: >>> defined at 1.c:1 +# CHECK-NEXT: >>> {{.*}}:(foo) +# CHECK-NEXT: >>> defined at 1.c:1 +# CHECK-NEXT: >>> {{.*}}:(.bss+0x0) + +## Check that stripping debug sections does not break error reporting. +# RUN: not ld.lld --strip-debug %t.o %t.o -o %t 2>&1 | FileCheck %s + +# Used reduced output from following code and gcc 7.1.0 +# to produce this input file: +# Source (1.c): +# int foo = 0; +# int bar = 1; +# Invocation: g++ -g -S 1.c + +.bss +.globl foo +.type foo, @object +.size foo, 4 +foo: + +.data +.globl bar +.type bar, @object +.size bar, 4 +bar: + +.text +.file 1 "1.c" + +.section .debug_info,"",@progbits + .long 0x4b # Compile Unit: length = 0x0000004b) + .value 0x4 # version = 0x0004 + .long 0 # abbr_offset = 0x0 + .byte 0x8 # addr_size = 0x08 + + .uleb128 0x1 # DW_TAG_compile_unit [1] * + .long 0 # DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000000] = ) + .byte 0x4 # DW_AT_language [DW_FORM_data1] (DW_LANG_C_plus_plus) + .string "1.c" # DW_AT_name [DW_FORM_string] ("1.c") + .long 0 # DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000000] = ) + .long 0 # DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000) + + .uleb128 0x2 # DW_TAG_variable [2] + .string "foo" # DW_AT_name [DW_FORM_string] ("foo") + .byte 0x1 # DW_AT_decl_file [DW_FORM_data1] ("1.c") + .byte 0x1 # DW_AT_decl_line [DW_FORM_data1] (1) + .long 0x32 # DW_AT_type [DW_FORM_ref4] (cu + 0x0032 => {0x00000032}) + .uleb128 0x9 # DW_AT_external [DW_FORM_flag_present] (true) + .byte 0x3 + .quad foo # DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) + + .uleb128 0x3 # DW_TAG_base_type [3] + .byte 0x4 # DW_AT_byte_size [DW_FORM_data1] (0x04) + .byte 0x5 # DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed) + .string "int" # DW_AT_name [DW_FORM_string] ("int") + + .uleb128 0x2 # DW_TAG_variable [2] + .string "bar" # DW_AT_name [DW_FORM_string] ("bar") + .byte 0x1 # DW_AT_decl_file [DW_FORM_data1] ("1.c") + .byte 0x2 # DW_AT_decl_line [DW_FORM_data1] (2) + .long 0x32 # DW_AT_type [DW_FORM_ref4] (cu + 0x0032 => {0x00000032}) + .uleb128 0x9 # DW_AT_external [DW_FORM_flag_present] (true) + .byte 0x3 + .quad bar # DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) + .byte 0 # END + + +.section .debug_abbrev,"",@progbits + .uleb128 0x1 # Abbreviation code. + .uleb128 0x11 # DW_TAG_compile_unit + + .byte 0x1 # ID + .uleb128 0x25 # DW_AT_producer, DW_FORM_strp + .uleb128 0xe + .uleb128 0x13 # DW_AT_language, DW_FORM_data1 + .uleb128 0xb + .uleb128 0x3 # DW_AT_name, DW_FORM_string + .uleb128 0x8 + .uleb128 0x1b # DW_AT_comp_dir, DW_FORM_strp + .uleb128 0xe + .uleb128 0x10 # DW_AT_stmt_list, DW_FORM_sec_offset + .uleb128 0x17 + .byte 0 + .byte 0 + + .uleb128 0x2 # ID + .uleb128 0x34 # DW_TAG_variable, DW_CHILDREN_no + .byte 0 + .uleb128 0x3 # DW_AT_name, DW_FORM_string + .uleb128 0x8 + .uleb128 0x3a # DW_AT_decl_file, DW_FORM_data1 + .uleb128 0xb + .uleb128 0x3b # DW_AT_decl_line, DW_FORM_data1 + .uleb128 0xb + .uleb128 0x49 # DW_AT_type, DW_FORM_ref4 + .uleb128 0x13 + .uleb128 0x3f # DW_AT_external, DW_FORM_flag_present + .uleb128 0x19 + .uleb128 0x2 # DW_AT_location, DW_FORM_exprloc + .uleb128 0x18 + .byte 0 + .byte 0 + + .uleb128 0x3 # ID + .uleb128 0x24 # DW_TAG_base_type, DW_CHILDREN_no + .byte 0 + .uleb128 0xb # DW_AT_byte_size, DW_FORM_data1 + .uleb128 0xb + .uleb128 0x3e # DW_AT_encoding, DW_FORM_data1 + .uleb128 0xb + .uleb128 0x3 # DW_AT_name, DW_FORM_string + .uleb128 0x8 + .byte 0 + .byte 0 + .byte 0 + diff --git a/test/ELF/conflict-debug-variable2.s b/test/ELF/conflict-debug-variable2.s new file mode 100644 index 000000000000..1fb9b09443b4 --- /dev/null +++ b/test/ELF/conflict-debug-variable2.s @@ -0,0 +1,160 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: llvm-dwarfdump -v %t.o | FileCheck -check-prefix=INPUT %s +# INPUT: .debug_info contents: +# INPUT: DW_TAG_variable +# INPUT-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000027] = "foo") +# INPUT-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x0033 => {0x00000033} "int") +# INPUT-NEXT: DW_AT_external [DW_FORM_flag_present] (true) +# INPUT-NEXT: DW_AT_decl_file [DW_FORM_data1] ("/home/path/test.c") +# INPUT-NEXT: DW_AT_decl_line [DW_FORM_data1] (1) +# INPUT-NEXT: DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) +# INPUT: DW_TAG_variable +# INPUT-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000002f] = "bar") +# INPUT-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x0033 => {0x00000033} "int") +# INPUT-NEXT: DW_AT_external [DW_FORM_flag_present] (true) +# INPUT-NEXT: DW_AT_decl_file [DW_FORM_data1] ("/home/path/test.c") +# INPUT-NEXT: DW_AT_decl_line [DW_FORM_data1] (2) +# INPUT-NEXT: DW_AT_location [DW_FORM_exprloc] (DW_OP_addr 0x0) + +## Check we use information from .debug_info in messages. +# RUN: not ld.lld %t.o %t.o -o %t 2>&1 | FileCheck %s +# CHECK: duplicate symbol: bar +# CHECK-NEXT: >>> defined at test.c:2 +# CHECK-NEXT: >>> {{.*}}:(bar) +# CHECK-NEXT: >>> defined at test.c:2 +# CHECK-NEXT: >>> {{.*}}:(.data+0x0) +# CHECK: duplicate symbol: foo +# CHECK-NEXT: >>> defined at test.c:1 +# CHECK-NEXT: >>> {{.*}}:(foo) +# CHECK-NEXT: >>> defined at test.c:1 +# CHECK-NEXT: >>> {{.*}}:(.bss+0x0) + +# Used reduced output from following code and clang +# version 6.0.0 (trunk 316661) to produce this input file: +# Source (test.c): +# int foo = 0; +# int bar = 1; +# Invocation: clang -g -S test.c + +.text +.file "test.c" +.file 1 "test.c" + +.type foo,@object +.bss +.globl foo +.p2align 2 +foo: + .long 0 + .size foo, 4 + +.type bar,@object +.data +.globl bar +.p2align 2 +bar: + .long 1 + .size bar, 4 + +.section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 6.0.0" +.Linfo_string1: + .asciz "test.c" +.Linfo_string2: + .asciz "/home/path/" +.Linfo_string3: + .asciz "foo" +.Linfo_string4: + .asciz "int" +.Linfo_string5: + .asciz "bar" + +.section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\264B" # DW_AT_GNU_pubnames + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + +.section .debug_info,"",@progbits +.Lcu_begin0: + .long 76 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + + .byte 1 # Abbrev [1] 0xb:0x45 DW_TAG_compile_unit + .long .Linfo_string0 # DW_AT_producer + .short 12 # DW_AT_language + .long .Linfo_string1 # DW_AT_name + .long 0 # DW_AT_stmt_list + .long .Linfo_string2 # DW_AT_comp_dir + + .byte 2 # Abbrev [2] 0x1e:0x15 DW_TAG_variable + .long .Linfo_string3 # DW_AT_name + .long 51 # DW_AT_type + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 9 # DW_AT_location + .byte 3 + .quad foo + + .byte 3 # Abbrev [3] 0x33:0x7 DW_TAG_base_type + .long .Linfo_string4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + + .byte 2 # Abbrev [2] 0x3a:0x15 DW_TAG_variable + .long .Linfo_string5 # DW_AT_name + .long 51 # DW_AT_type + .byte 1 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 9 # DW_AT_location + .byte 3 + .quad bar + .byte 0 # End Of Children Mark diff --git a/test/ELF/copy-errors.s b/test/ELF/copy-errors.s index d0d6abdf68da..0af4638120d1 100644 --- a/test/ELF/copy-errors.s +++ b/test/ELF/copy-errors.s @@ -9,6 +9,9 @@ // CHECK: >>> referenced by {{.*}}.o:(.text+0x1) // CHECK: symbol 'zed' defined in {{.*}}.so has no type +// RUN: not ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s --check-prefix=NOINHIBIT +// NOINHIBIT: warning: symbol 'zed' defined in {{.*}}.so has no type + .global _start _start: call bar diff --git a/test/ELF/copy-rel-abs.s b/test/ELF/copy-rel-abs.s new file mode 100644 index 000000000000..37a2c4323819 --- /dev/null +++ b/test/ELF/copy-rel-abs.s @@ -0,0 +1,47 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-abs.s -o %t1.o +// RUN: ld.lld --hash-style=gnu -shared %t1.o -o %t1.so +// RUN: llvm-readelf --dyn-symbols %t1.so | FileCheck --check-prefix=SYMS %s + +// The symbols have the same st_value, but one is ABS. +// SYMS: 0000000000001000 {{.*}} 4 bar +// SYMS: 0000000000001000 {{.*}} 4 foo +// SYMS: 0000000000001000 {{.*}} ABS zed + +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o +// RUN: ld.lld %t2.o %t1.so -o %t2 +// RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s + +// CHECK: DynamicSymbols [ +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: +// CHECK-NEXT: Type: +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: foo +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: +// CHECK-NEXT: Type: +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .bss.rel.ro +// CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: bar +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: +// CHECK-NEXT: Binding: +// CHECK-NEXT: Type: +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .bss.rel.ro +// CHECK-NEXT: } +// CHECK-NEXT: ] + +.global _start +_start: +.quad foo diff --git a/test/ELF/copy-rel-large.s b/test/ELF/copy-rel-large.s new file mode 100644 index 000000000000..035eca3bf10d --- /dev/null +++ b/test/ELF/copy-rel-large.s @@ -0,0 +1,20 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-rel-large.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: ld.lld %t2.o %t1.so -o %t2 +// RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s + + .global _start +_start: + .quad foo + +// CHECK: Symbol { +// CHECK: Name: foo +// CHECK-NEXT: Value: +// CHECK-NEXT: Size: 4294967297 +// CHECK-NEXT: Binding: +// CHECK-NEXT: Type: +// CHECK-NEXT: Other: +// CHECK-NEXT: Section: .bss.rel.ro +// CHECK-NEXT: } diff --git a/test/ELF/copy-rel-pie.s b/test/ELF/copy-rel-pie.s index 769a2431d850..dcccf8e30b1d 100644 --- a/test/ELF/copy-rel-pie.s +++ b/test/ELF/copy-rel-pie.s @@ -1,7 +1,7 @@ // 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: ld.lld --hash-style=sysv %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 diff --git a/test/ELF/corrupted-version-reference.s b/test/ELF/corrupted-version-reference.s new file mode 100644 index 000000000000..d37f272f445d --- /dev/null +++ b/test/ELF/corrupted-version-reference.s @@ -0,0 +1,14 @@ +# RUN: llvm-mc -triple=mips64-unknown-freebsd %s -filetype=obj -o %t.o +# RUN: not ld.lld %t.o %S/Inputs/corrupt-version-reference.so -o %t.exe 2>&1 | FileCheck %s +# REQUIRES: mips + +# CHECK: error: corrupt input file: version definition index 9 for symbol __cxa_finalize is out of bounds +# CHECK: >>> defined in {{.+}}/corrupt-version-reference.so + +# CHECK: error: corrupt input file: version definition index 0 for symbol _Jv_RegisterClasses is out of bounds +# CHECK-NEXT: >>> defined in {{.*}}/corrupt-version-reference.so + +.globl __start +__start: + dla $a0, __cxa_finalize + nop diff --git a/test/ELF/debug-gc.s b/test/ELF/debug-gc.s index 8bcfde16a7b7..5ec43f67829e 100644 --- a/test/ELF/debug-gc.s +++ b/test/ELF/debug-gc.s @@ -4,11 +4,11 @@ # RUN: llvm-objdump -s %t1 | FileCheck %s # CHECK: Contents of section .debug_str: -# CHECK-NEXT: 0000 41414100 42424200 43434300 AAA.BBB.CCC. +# CHECK-NEXT: 0000 41414100 43434300 42424200 AAA.CCC.BBB. # CHECK: Contents of section .foo: # CHECK-NEXT: 0000 2a000000 # CHECK: Contents of section .debug_info: -# CHECK-NEXT: 0000 00000000 04000000 +# CHECK-NEXT: 0000 00000000 08000000 .globl _start _start: diff --git a/test/ELF/defsym-dynamic.s b/test/ELF/defsym-dynamic.s new file mode 100644 index 000000000000..f69e835af34c --- /dev/null +++ b/test/ELF/defsym-dynamic.s @@ -0,0 +1,10 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -o %t.so -shared %t.o --defsym=foo2=foo1 +# RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s + +# CHECK: Name: foo1 +# CHECK: Name: foo2 + +.globl foo1 + foo1 = 0x123 diff --git a/test/ELF/defsym.s b/test/ELF/defsym.s index b821484261b2..2abc08f99dfc 100644 --- a/test/ELF/defsym.s +++ b/test/ELF/defsym.s @@ -19,7 +19,7 @@ # CHECK-NEXT: Section: Absolute # CHECK-NEXT: } # CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: foo1 +# CHECK-NEXT: Name: foo2 # CHECK-NEXT: Value: 0x123 # CHECK-NEXT: Size: # CHECK-NEXT: Binding: Global @@ -33,11 +33,43 @@ # USE-NEXT: _start: # USE-NEXT: movl $0x123, %edx -# RUN: not ld.lld -o %t %t.o --defsym=foo2=1 2>&1 | FileCheck %s -check-prefix=ERR1 -# ERR1: error: --defsym: symbol name expected, but got 1 +# RUN: ld.lld -o %t %t.o --defsym=foo2=1 +# RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=ABS -# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR2 -# ERR2: error: -defsym: undefined symbol: und +# ABS: Symbol { +# ABS: Name: foo2 +# ABS-NEXT: Value: 0x1 +# ABS-NEXT: Size: +# ABS-NEXT: Binding: Global +# ABS-NEXT: Type: +# ABS-NEXT: Other: +# ABS-NEXT: Section: Absolute +# ABS-NEXT: } + +# RUN: ld.lld -o %t %t.o --defsym=foo2=foo1+5 +# RUN: llvm-readobj -t -s %t | FileCheck %s --check-prefix=EXPR + +# EXPR: Symbol { +# EXPR: Name: foo1 +# EXPR-NEXT: Value: 0x123 +# EXPR-NEXT: Size: +# EXPR-NEXT: Binding: Global +# EXPR-NEXT: Type: +# EXPR-NEXT: Other: +# EXPR-NEXT: Section: Absolute +# EXPR-NEXT: } +# EXPR-NEXT: Symbol { +# EXPR-NEXT: Name: foo2 +# EXPR-NEXT: Value: 0x128 +# EXPR-NEXT: Size: +# EXPR-NEXT: Binding: Global +# EXPR-NEXT: Type: +# EXPR-NEXT: Other: +# EXPR-NEXT: Section: Absolute +# EXPR-NEXT: } + +# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR +# ERR: error: -defsym:1: symbol not found: und .globl foo1 foo1 = 0x123 diff --git a/test/ELF/driver-access.test b/test/ELF/driver-access.test index 5209483ae480..46b87c1f7e5d 100644 --- a/test/ELF/driver-access.test +++ b/test/ELF/driver-access.test @@ -7,7 +7,7 @@ # RUN: mkdir -p %t.dir # RUN: chmod 100 %t.dir # RUN: cd %t.dir -# RUN: ld.lld %t.o -o %t.exe +# RUN: ld.lld %t.o -o %t.exe -M # RUN: chmod 755 %t.dir .globl _start diff --git a/test/ELF/driver.test b/test/ELF/driver.test index d876218130c3..ac324cbaac45 100644 --- a/test/ELF/driver.test +++ b/test/ELF/driver.test @@ -18,10 +18,10 @@ # HELP: : supported targets:{{.*}} elf # RUN: ld.lld --version 2>&1 | FileCheck -check-prefix=VERSION %s +# RUN: ld.lld -v 2>&1 | FileCheck -check-prefix=VERSION %s +# RUN: not ld.lld -v xyz 2>&1 | FileCheck -check-prefix=VERSION %s # VERSION: LLD {{.*}} (compatible with GNU linkers) -# RUN: not ld.lld -v 2>&1 | FileCheck -check-prefix=VERSION %s - ## 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 diff --git a/test/ELF/duplicated-synthetic-sym.s b/test/ELF/duplicated-synthetic-sym.s index cfd8642d2d17..92de33ec6278 100644 --- a/test/ELF/duplicated-synthetic-sym.s +++ b/test/ELF/duplicated-synthetic-sym.s @@ -1,9 +1,10 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o // RUN: cd %S // RUN: not ld.lld %t.o --format=binary duplicated-synthetic-sym.s -o %t.elf 2>&1 | FileCheck %s +// RUN: not ld.lld %t.o --format binary duplicated-synthetic-sym.s -o %t.elf 2>&1 | FileCheck %s // CHECK: duplicate symbol: _binary_duplicated_synthetic_sym_s_start -// CHECK: defined at (internal):(.data+0x0) +// CHECK: defined at <internal>:(.data+0x0) .globl _binary_duplicated_synthetic_sym_s_start _binary_duplicated_synthetic_sym_s_start: diff --git a/test/ELF/dynamic-got.s b/test/ELF/dynamic-got.s index c50c9022329a..385394b9d342 100644 --- a/test/ELF/dynamic-got.s +++ b/test/ELF/dynamic-got.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o -// RUN: ld.lld %t.o -o %t.so -shared +// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared // RUN: llvm-readobj -s -l -section-data -r %t.so | FileCheck %s // CHECK: Name: .got diff --git a/test/ELF/dynamic-list-empty.s b/test/ELF/dynamic-list-empty.s new file mode 100644 index 000000000000..5686ce0c431b --- /dev/null +++ b/test/ELF/dynamic-list-empty.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 + +# BFD reports a parse error on empty lists, but it is clear how to +# handle it. + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "{ };" > %t.list +# RUN: ld.lld -dynamic-list %t.list -shared %t.o -o %t.so +# RUN: llvm-readobj -r %t.so | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: ] + + .globl foo +foo: + ret + + call foo@PLT diff --git a/test/ELF/dynamic-list-preempt.s b/test/ELF/dynamic-list-preempt.s new file mode 100644 index 000000000000..2bb10a3ed0a6 --- /dev/null +++ b/test/ELF/dynamic-list-preempt.s @@ -0,0 +1,76 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "{ foo; zed; };" > %t.list +# RUN: echo "{ global: foo; bar; local: *; };" > %t.vers +# RUN: ld.lld --hash-style=sysv -fatal-warnings -dynamic-list %t.list -version-script %t.vers -shared %t.o -o %t.so +# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOCS %s +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=DYNSYMS %s + +# RELOCS: Relocations [ +# RELOCS-NEXT: Section ({{.*}}) .rela.plt { +# RELOCS-NEXT: R_X86_64_JUMP_SLOT foo 0x0 +# RELOCS-NEXT: R_X86_64_JUMP_SLOT ext 0x0 +# RELOCS-NEXT: } +# RELOCS-NEXT: ] + +# DYNSYMS: DynamicSymbols [ +# DYNSYMS-NEXT: Symbol { +# DYNSYMS-NEXT: Name: @ (0) +# DYNSYMS-NEXT: Value: 0x0 +# DYNSYMS-NEXT: Size: 0 +# DYNSYMS-NEXT: Binding: Local +# DYNSYMS-NEXT: Type: None +# DYNSYMS-NEXT: Other: 0 +# DYNSYMS-NEXT: Section: Undefined +# DYNSYMS-NEXT: } +# DYNSYMS-NEXT: Symbol { +# DYNSYMS-NEXT: Name: bar@ +# DYNSYMS-NEXT: Value: +# DYNSYMS-NEXT: Size: +# DYNSYMS-NEXT: Binding: Global +# DYNSYMS-NEXT: Type: +# DYNSYMS-NEXT: Other: +# DYNSYMS-NEXT: Section: +# DYNSYMS-NEXT: } +# DYNSYMS-NEXT: Symbol { +# DYNSYMS-NEXT: Name: ext@ +# DYNSYMS-NEXT: Value: +# DYNSYMS-NEXT: Size: +# DYNSYMS-NEXT: Binding: Global +# DYNSYMS-NEXT: Type: +# DYNSYMS-NEXT: Other: +# DYNSYMS-NEXT: Section: +# DYNSYMS-NEXT: } +# DYNSYMS-NEXT: Symbol { +# DYNSYMS-NEXT: Name: foo@ +# DYNSYMS-NEXT: Value: +# DYNSYMS-NEXT: Size: +# DYNSYMS-NEXT: Binding: Global +# DYNSYMS-NEXT: Type: +# DYNSYMS-NEXT: Other: +# DYNSYMS-NEXT: Section: +# DYNSYMS-NEXT: } +# DYNSYMS-NEXT: ] + + .globl foo +foo: + ret + + .globl bar +bar: + ret + + .globl baz +baz: + ret + + .globl zed +zed: + ret + + call foo@PLT + call bar@PLT + call baz@PLT + call zed@PLT + call ext@PLT diff --git a/test/ELF/dynamic-list-weak-archive.s b/test/ELF/dynamic-list-weak-archive.s new file mode 100644 index 000000000000..f7f72afd0c3b --- /dev/null +++ b/test/ELF/dynamic-list-weak-archive.s @@ -0,0 +1,18 @@ +# 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 %S/Inputs/dynamic-list-weak-archive.s -o %t2.o +# RUN: rm -f %t.a +# RUN: llvm-ar rcs %t.a %t2.o +# RUN: echo "{ zed; };" > %t.list +# RUN: ld.lld -shared --dynamic-list %t.list %t1.o %t.a -o %t.so +# RUN: llvm-readobj -r %t.so | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.plt { +# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo +# CHECK-NEXT: } +# CHECK-NEXT: ] + +callq foo@PLT +.weak foo diff --git a/test/ELF/dynamic-list-wildcard.s b/test/ELF/dynamic-list-wildcard.s new file mode 100644 index 000000000000..cd7ed71771ae --- /dev/null +++ b/test/ELF/dynamic-list-wildcard.s @@ -0,0 +1,53 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + +# RUN: echo "{ foo1*; };" > %t.list +# RUN: ld.lld --hash-style=sysv -pie --dynamic-list %t.list %t -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 (0x0) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: foo1@ (1) +# CHECK-NEXT: Value: 0x1000 +# 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: Symbol { +# CHECK-NEXT: Name: foo11@ (6) +# CHECK-NEXT: Value: 0x1001 +# 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: ] + +.globl foo1 +foo1: + ret + +.globl foo11 +foo11: + ret + +.globl foo2 +foo2: + ret + +.globl _start +_start: + retq diff --git a/test/ELF/dynamic-list.s b/test/ELF/dynamic-list.s index 7cd587380e59..888508e270a7 100644 --- a/test/ELF/dynamic-list.s +++ b/test/ELF/dynamic-list.s @@ -1,28 +1,24 @@ -## 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: 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: ld.lld --hash-style=sysv -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: ld.lld --hash-style=sysv --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: ld.lld --hash-style=sysv --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: ld.lld --hash-style=sysv --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: ld.lld --hash-style=sysv --export-dynamic-symbol=foo1 %t %t2.so -o %t.exe # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s # CHECK: DynamicSymbols [ @@ -49,11 +45,11 @@ ## 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: ld.lld --hash-style=sysv --dynamic-list %t.list %t %t2.so -o %t.exe # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s # RUN: echo "{ foo1; foo2; };" > %t1.list # RUN: echo "{ foo31; };" > %t2.list -# RUN: ld.lld --dynamic-list %t1.list --dynamic-list %t2.list %t %t2.so -o %t.exe +# RUN: ld.lld --hash-style=sysv --dynamic-list %t1.list --dynamic-list %t2.list %t %t2.so -o %t.exe # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s # CHECK2: DynamicSymbols [ @@ -99,11 +95,11 @@ ## --export-dynamic overrides --dynamic-list, i.e. --export-dynamic with an ## incomplete dynamic-list still exports everything. # RUN: echo "{ foo2; };" > %t.list -# RUN: ld.lld --dynamic-list %t.list --export-dynamic %t %t2.so -o %t.exe +# RUN: ld.lld --hash-style=sysv --dynamic-list %t.list --export-dynamic %t %t2.so -o %t.exe # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK3 %s ## The same with --export-dynamic-symbol. -# RUN: ld.lld --export-dynamic-symbol=foo2 --export-dynamic %t %t2.so -o %t.exe +# RUN: ld.lld --hash-style=sysv --export-dynamic-symbol=foo2 --export-dynamic %t %t2.so -o %t.exe # RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK3 %s # CHECK3: DynamicSymbols [ diff --git a/test/ELF/dynamic-no-rosegment.s b/test/ELF/dynamic-no-rosegment.s new file mode 100644 index 000000000000..e5ad26e3fa44 --- /dev/null +++ b/test/ELF/dynamic-no-rosegment.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -shared --no-rosegment -z rodynamic -o %t %t.o +# RUN: llvm-readobj -dynamic-table -s %t | FileCheck %s + +# CHECK: DynamicSection [ (7 entries) +# CHECK-NEXT: Tag Type Name/Value +# CHECK-NEXT: 0x0000000000000006 SYMTAB 0x120 +# CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes) +# CHECK-NEXT: 0x0000000000000005 STRTAB 0x1D0 +# CHECK-NEXT: 0x000000000000000A STRSZ 1 (bytes) +# CHECK-NEXT: 0x000000006FFFFEF5 GNU_HASH 0x138 +# CHECK-NEXT: 0x0000000000000004 HASH 0x150 +# CHECK-NEXT: 0x0000000000000000 NULL 0x0 +# CHECK-NEXT: ] diff --git a/test/ELF/dynamic-reloc-in-ro.s b/test/ELF/dynamic-reloc-in-ro.s index 23b068ff839f..ecdbfeb6658e 100644 --- a/test/ELF/dynamic-reloc-in-ro.s +++ b/test/ELF/dynamic-reloc-in-ro.s @@ -2,9 +2,9 @@ // 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 -// CHECK: can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment -// CHECK: >>> defined in {{.*}}.o -// CHECK: >>> referenced by {{.*}}.o:(.text+0x0) +// CHECK: can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment; recompile object files with -fPIC +// CHECK-NEXT: >>> defined in {{.*}}.o +// CHECK-NEXT: >>> referenced by {{.*}}.o:(.text+0x0) foo: .quad foo diff --git a/test/ELF/dynamic-reloc.s b/test/ELF/dynamic-reloc.s index 939093c17b41..4d95e41fb803 100644 --- a/test/ELF/dynamic-reloc.s +++ b/test/ELF/dynamic-reloc.s @@ -2,7 +2,7 @@ // 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.s -o %t3.o // RUN: ld.lld -shared %t2.o -o %t2.so -// RUN: ld.lld %t.o %t3.o %t2.so -o %t +// RUN: ld.lld --hash-style=sysv %t.o %t3.o %t2.so -o %t // RUN: llvm-readobj -dynamic-table -r --expand-relocs -s %t | FileCheck %s // REQUIRES: x86 diff --git a/test/ELF/dynstr-no-rosegment.s b/test/ELF/dynstr-no-rosegment.s new file mode 100644 index 000000000000..0e12721dac44 --- /dev/null +++ b/test/ELF/dynstr-no-rosegment.s @@ -0,0 +1,12 @@ +# Verify that a .dynstr in the .text segment has null byte terminators + +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -no-rosegment -o %t.so -shared +# RUN: llvm-objdump %t.so -s -j .dynstr | FileCheck %s + +# CHECK: 00666f6f 00 .foo. + +.globl foo +foo: + ret diff --git a/test/ELF/dynsym-no-rosegment.s b/test/ELF/dynsym-no-rosegment.s new file mode 100644 index 000000000000..947f526e0575 --- /dev/null +++ b/test/ELF/dynsym-no-rosegment.s @@ -0,0 +1,27 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -shared --no-rosegment -o %t %t.o +# RUN: llvm-readobj -dyn-symbols -s %t | 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: undef@ +# 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: ] + +callq undef@PLT diff --git a/test/ELF/dynsym-pie.s b/test/ELF/dynsym-pie.s index 9d3a9ffe304f..b162d27335ac 100644 --- a/test/ELF/dynsym-pie.s +++ b/test/ELF/dynsym-pie.s @@ -3,6 +3,51 @@ # RUN: ld.lld -pie %t -o %t.out # RUN: llvm-readobj -t -dyn-symbols %t.out | FileCheck %s +# CHECK: Symbols [ +# CHECK: Symbol { +# CHECK: Name: hidden +# CHECK-NEXT: Value: 0x1000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other [ +# CHECK-NEXT: STV_HIDDEN +# CHECK-NEXT: ] +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: internal +# CHECK-NEXT: Value: 0x1000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other [ +# CHECK-NEXT: STV_INTERNAL +# CHECK-NEXT: ] +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: default +# 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: Symbol { +# CHECK: Name: protected +# CHECK-NEXT: Value: 0x1000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other [ +# CHECK-NEXT: STV_PROTECTED +# CHECK-NEXT: ] +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK-NEXT: ] + # CHECK: DynamicSymbols [ # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: @ @@ -23,14 +68,13 @@ _start: default: .global protected +.protected protected protected: .global hidden +.hidden hidden hidden: .global internal +.internal internal internal: - -.global protected_with_hidden -.protected -protected_with_hidden: diff --git a/test/ELF/edata-etext.s b/test/ELF/edata-etext.s index 3b0ba49ad1af..2358399857de 100644 --- a/test/ELF/edata-etext.s +++ b/test/ELF/edata-etext.s @@ -19,7 +19,7 @@ # CHECK: SYMBOL TABLE: # CHECK-NEXT: 0000000000000000 *UND* 00000000 # CHECK-NEXT: 0000000000202002 .data 00000000 _edata -# CHECK-NEXT: 000000000020200a .data 00000000 _end +# CHECK-NEXT: 000000000020200a .bss 00000000 _end # CHECK-NEXT: 0000000000201001 .text 00000000 _etext # CHECK-NEXT: 0000000000201000 .text 00000000 _start diff --git a/test/ELF/edata-no-bss.s b/test/ELF/edata-no-bss.s new file mode 100644 index 000000000000..5127c4710fa9 --- /dev/null +++ b/test/ELF/edata-no-bss.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 --gc-sections +# RUN: llvm-objdump -t -section-headers %t | FileCheck %s + +# CHECK: .data 00000008 0000000000202000 DATA + +# CHECK: 0000000000202008 .data 00000000 _edata + +.text +.globl _start +_start: +.long .data - . + +.data +.quad 0 + +.globl _edata diff --git a/test/ELF/eh-align-cie.s b/test/ELF/eh-align-cie.s index 343dea5004f0..9e6ac2dc17be 100644 --- a/test/ELF/eh-align-cie.s +++ b/test/ELF/eh-align-cie.s @@ -31,7 +31,7 @@ bar: // OBJ-NEXT: ) -// RUN: ld.lld %t.o -o %t -shared +// RUN: ld.lld --hash-style=sysv %t.o -o %t -shared // RUN: llvm-readobj -s -section-data %t | FileCheck %s // Check that the size of the CIE was changed to (0x1C + 4) and the FDE one was diff --git a/test/ELF/eh-frame-hdr-augmentation.s b/test/ELF/eh-frame-hdr-augmentation.s index 618f5e1a9d7d..135f8119662a 100644 --- a/test/ELF/eh-frame-hdr-augmentation.s +++ b/test/ELF/eh-frame-hdr-augmentation.s @@ -1,6 +1,6 @@ // 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: ld.lld --hash-style=sysv --eh-frame-hdr %t.o -o %t -shared // RUN: llvm-objdump --dwarf=frames %t | FileCheck %s // CHECK: .eh_frame contents: diff --git a/test/ELF/eh-frame-hdr-icf-fde.s b/test/ELF/eh-frame-hdr-icf-fde.s new file mode 100644 index 000000000000..54c2cd8bf8c9 --- /dev/null +++ b/test/ELF/eh-frame-hdr-icf-fde.s @@ -0,0 +1,95 @@ +# REQUIRES: x86 + +## Testcase checks that we correctly deduplicate FDEs when ICF +## merges two sections. + +# 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-readobj -r %t | FileCheck %s --check-prefix=OBJ +# RUN: llvm-readobj -s -section-data %t2 | FileCheck %s + +# OBJ: Relocations [ +# OBJ-NEXT: Section {{.*}} .rela.eh_frame { +# OBJ-NEXT: 0x20 R_X86_64_PC32 .text.f1 0x0 +# OBJ-NEXT: 0x34 R_X86_64_PC32 .text.f1 0x2 +# OBJ-NEXT: 0x48 R_X86_64_PC32 .text.f2 0x0 +# OBJ-NEXT: 0x5C R_X86_64_PC32 .text.f2 0x2 +# OBJ-NEXT: } +# OBJ-NEXT: ] + +# CHECK: Section { +# CHECK: Index: 1 +# CHECK: Name: .eh_frame_hdr +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x200158 +# CHECK-NEXT: Offset: 0x158 +# CHECK-NEXT: Size: 28 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 011B033B 1C000000 02000000 A80E0000 +## ^ ^-- FDE(1) PC +## ^-- Number of FDEs +# CHECK-NEXT: 0010: 38000000 AA0E0000 50000000 +## ^-- FDE(2) PC +# CHECK-NEXT: ) +# CHECK-NEXT: } +## FDE(1) == 0x201000 - .eh_frame_hdr(0x200158) = 0xEA8 +## FDE(2) == 0x201000 - .eh_frame_hdr(0x200158) + 2(relocation addend) = 0xEAA + +## Check .eh_frame contains CIE and two FDEs remaining after ICF. +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .eh_frame +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x200178 +# CHECK-NEXT: Offset: 0x178 +# CHECK-NEXT: Size: 72 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001 +# CHECK-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 +# CHECK-NEXT: 0020: 680E0000 01000000 00000000 00000000 +# CHECK-NEXT: 0030: 14000000 34000000 520E0000 01000000 +# CHECK-NEXT: 0040: 00000000 00000000 +# CHECK-NEXT: ) +# CHECK-NEXT: } + +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_EXECINSTR +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x201000 + +.section .text.f1, "ax" +.cfi_startproc +nop +.cfi_endproc +nop +.cfi_startproc +ret +.cfi_endproc + +.section .text.f2, "ax" +.cfi_startproc +nop +.cfi_endproc +nop +.cfi_startproc +ret +.cfi_endproc diff --git a/test/ELF/eh-frame-hdr-icf.s b/test/ELF/eh-frame-hdr-icf.s index 1b42285f5d32..0ef3f97de8d3 100644 --- a/test/ELF/eh-frame-hdr-icf.s +++ b/test/ELF/eh-frame-hdr-icf.s @@ -2,17 +2,18 @@ # 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 +# RUN: llvm-objdump -s -section-headers %t2 | FileCheck %s + +## Check .eh_frame_hdr contains single FDE and no garbage data at tail. +# CHECK: Sections: +# CHECK: Idx Name Size +# CHECK: .eh_frame_hdr 00000014 # CHECK: Contents of section .eh_frame_hdr: -# CHECK-NEXT: 200158 011b033b 1c000000 01000000 a80e0000 +# CHECK-NEXT: 200158 011b033b 14000000 01000000 # ^ FDE count -# CHECK-NEXT: 200168 38000000 00000000 00000000 -# ^ FDE for f2 -.globl _start, f1, f2 -_start: - ret +.globl f1, f2 .section .text.f1, "ax" f1: diff --git a/test/ELF/eh-frame-hdr.s b/test/ELF/eh-frame-hdr.s index 35c14a4b65dd..4498d7d30eaa 100644 --- a/test/ELF/eh-frame-hdr.s +++ b/test/ELF/eh-frame-hdr.s @@ -1,9 +1,17 @@ // 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: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t \ +// RUN: | FileCheck %s --check-prefix=NOHDR + +// RUN: ld.lld -eh-frame-hdr -no-eh-frame-hdr %t.o -o %t +// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t \ +// RUN: | 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-readobj -file-headers -s -section-data -program-headers -symbols %t \ +// RUN: | FileCheck %s --check-prefix=HDR // RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=HDRDISASM .section foo,"ax",@progbits diff --git a/test/ELF/eh-frame-merge.s b/test/ELF/eh-frame-merge.s index addbb3f857fe..4b54c173c699 100644 --- a/test/ELF/eh-frame-merge.s +++ b/test/ELF/eh-frame-merge.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: ld.lld %t.o %t.o -o %t -shared +// RUN: ld.lld --hash-style=sysv %t.o %t.o -o %t -shared // RUN: llvm-readobj -s -section-data %t | FileCheck %s .section foo,"ax",@progbits diff --git a/test/ELF/eh-frame-padding-no-rosegment.s b/test/ELF/eh-frame-padding-no-rosegment.s index 951fed0a56e9..e106f2989d4b 100644 --- a/test/ELF/eh-frame-padding-no-rosegment.s +++ b/test/ELF/eh-frame-padding-no-rosegment.s @@ -31,7 +31,7 @@ bar: // OBJ-NEXT: 0020: 20000000 00000000 00000000 00000000 // OBJ-NEXT: ) -// RUN: ld.lld %t.o -no-rosegment -o %t -shared +// RUN: ld.lld --hash-style=sysv %t.o -no-rosegment -o %t -shared // Check that .eh_frame is in the same segment as .text // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=PHDR %s diff --git a/test/ELF/eh-frame.s b/test/ELF/eh-frame.s new file mode 100644 index 000000000000..a07d242add15 --- /dev/null +++ b/test/ELF/eh-frame.s @@ -0,0 +1,12 @@ +// 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 %S/Inputs/eh-frame.s -o %t2.o +// RUN: ld.lld %t1.o %t2.o -o %t +// RUN: llvm-dwarfdump -eh-frame %t | FileCheck %s + +// CHECK: DW_CFA_def_cfa_offset: +64 +// CHECK: DW_CFA_def_cfa_offset: +32 + +.cfi_startproc +.cfi_def_cfa_offset 64 +.cfi_endproc diff --git a/test/ELF/emit-relocs-gc.s b/test/ELF/emit-relocs-gc.s new file mode 100644 index 000000000000..0741e78ab955 --- /dev/null +++ b/test/ELF/emit-relocs-gc.s @@ -0,0 +1,30 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +## Show that we emit .rela.bar and .rela.text when GC is disabled. +# RUN: ld.lld --emit-relocs %t.o -o %t +# RUN: llvm-objdump %t -section-headers | FileCheck %s --check-prefix=NOGC +# NOGC: .rela.text +# NOGC: .rela.bar + +## GC collects .bar section and we exclude .rela.bar from output. We keep +## .rela.text because we keep .text. +# RUN: ld.lld --gc-sections --emit-relocs --print-gc-sections %t.o -o %t \ +# RUN: | FileCheck --check-prefix=MSG %s +# MSG: removing unused section from '.bar' in file +# MSG: removing unused section from '.rela.bar' in file +# RUN: llvm-objdump %t -section-headers | FileCheck %s --check-prefix=GC +# GC-NOT: rela.bar +# GC: rela.text +# GC-NOT: rela.bar + +.section .bar,"a" +.quad .bar + +.text +relocs: +.quad _start + +.global _start +_start: + nop diff --git a/test/ELF/emit-relocs-merge.s b/test/ELF/emit-relocs-merge.s index c700c337e334..3fecca23b735 100644 --- a/test/ELF/emit-relocs-merge.s +++ b/test/ELF/emit-relocs-merge.s @@ -8,7 +8,7 @@ # CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0 # CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0 # CHECK-NEXT: } -# CHECK-NEXT: Section ({{.*}}) .rela.data.foo { +# CHECK-NEXT: Section ({{.*}}) .rela.data { # CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0 # CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0 # CHECK-NEXT: } diff --git a/test/ELF/emit-relocs-mergeable-i386.s b/test/ELF/emit-relocs-mergeable-i386.s new file mode 100644 index 000000000000..1ddee8c1faf1 --- /dev/null +++ b/test/ELF/emit-relocs-mergeable-i386.s @@ -0,0 +1,66 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t1 +# RUN: ld.lld --emit-relocs %t1 -o %t2 +# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s + +## Check lf we produce proper relocations when doing merging of SHF_MERGE sections. + +## Check addends of relocations are: 0x0, 0x8, 0x8, 0x4 +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .foo +# 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: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 00000000 08000000 08000000 04000000 +# CHECK-NEXT: ) +# CHECK-NEXT: } + +## Check that offsets for AAA is 0x0, for BBB is 0x8 and CCC has offset 0x4. +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .strings +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_MERGE +# CHECK-NEXT: SHF_STRINGS +# 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: |AAA.CCC.BBB.| +# CHECK-NEXT: ) +# CHECK-NEXT: } + +.section .strings,"MS",@progbits,1,unique,10 +.Linfo_string0: + .asciz "AAA" +.Linfo_string1: + .asciz "BBB" + +.section .strings,"MS",@progbits,1,unique,20 +.Linfo_string2: + .asciz "BBB" +.Linfo_string3: + .asciz "CCC" + +.section .foo,"ax",@progbits +.long .Linfo_string0 +.long .Linfo_string1 +.long .Linfo_string2 +.long .Linfo_string3 diff --git a/test/ELF/emit-relocs-mergeable.s b/test/ELF/emit-relocs-mergeable.s new file mode 100644 index 000000000000..1553cb616012 --- /dev/null +++ b/test/ELF/emit-relocs-mergeable.s @@ -0,0 +1,53 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 +# RUN: ld.lld --emit-relocs %t1 -o %t2 +# RUN: llvm-readobj -sections -section-data -r %t2 | FileCheck %s + +## Check if we produce proper relocations when doing merging of SHF_MERGE sections. + +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .strings +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_MERGE +# CHECK-NEXT: SHF_STRINGS +# CHECK-NEXT: ] +# CHECK-NEXT: Address: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: 12 +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 41414100 43434300 42424200 |AAA.CCC.BBB.| +# CHECK-NEXT: ) +# CHECK-NEXT: } + +# CHECK: Relocations [ +# CHECK-NEXT: Section {{.*}} .rela.foo { +# CHECK-NEXT: 0x201000 R_X86_64_64 .strings 0x0 +# CHECK-NEXT: 0x201008 R_X86_64_64 .strings 0x8 +# CHECK-NEXT: 0x201010 R_X86_64_64 .strings 0x8 +# CHECK-NEXT: 0x201018 R_X86_64_64 .strings 0x4 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.section .strings,"MS",@progbits,1,unique,10 +.Linfo_string0: + .asciz "AAA" +.Linfo_string1: + .asciz "BBB" + +.section .strings,"MS",@progbits,1,unique,20 +.Linfo_string2: + .asciz "BBB" +.Linfo_string3: + .asciz "CCC" + +.section .foo,"ax",@progbits +.quad .Linfo_string0 +.quad .Linfo_string1 +.quad .Linfo_string2 +.quad .Linfo_string3 diff --git a/test/ELF/emit-relocs-shared.s b/test/ELF/emit-relocs-shared.s index 7a0d7911831b..65a12c15ee2e 100644 --- a/test/ELF/emit-relocs-shared.s +++ b/test/ELF/emit-relocs-shared.s @@ -1,6 +1,6 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld --emit-relocs %t.o -o %t.so -shared +# RUN: ld.lld --hash-style=sysv --emit-relocs %t.o -o %t.so -shared # RUN: llvm-readobj -r %t.so | FileCheck %s .data diff --git a/test/ELF/emit-relocs.s b/test/ELF/emit-relocs.s index fd9722f13ab0..95e70d80acf5 100644 --- a/test/ELF/emit-relocs.s +++ b/test/ELF/emit-relocs.s @@ -64,6 +64,15 @@ # CHECK-NEXT: Section: .text # CHECK-NEXT: } # CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: Section +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .comment +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { # CHECK-NEXT: Name: fn # CHECK-NEXT: Value: 0x201000 # CHECK-NEXT: Size: 0 @@ -83,7 +92,7 @@ # CHECK-NEXT: } # CHECK-NEXT: ] -.section .text,"ax",@progbits,unique,0 +.section .text.fn,"ax",@progbits,unique,0 .globl fn .type fn,@function fn: @@ -94,7 +103,7 @@ bar: callq fn@PLT nop -.section .text,"ax",@progbits,unique,1 +.section .text.fn2,"ax",@progbits,unique,1 .globl fn2 .type fn2,@function fn2: diff --git a/test/ELF/exclude-libs.s b/test/ELF/exclude-libs.s index c36081f40e54..dc7530068586 100644 --- a/test/ELF/exclude-libs.s +++ b/test/ELF/exclude-libs.s @@ -22,6 +22,12 @@ // RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL // RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s +// RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a +// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s + +// RUN: ld.lld -shared --whole-archive %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL +// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s + // DEFAULT: Name: fn // EXCLUDE-NOT: Name: fn diff --git a/test/ELF/executable-undefined-ignoreall.s b/test/ELF/executable-undefined-ignoreall.s new file mode 100644 index 000000000000..44f83a687ee2 --- /dev/null +++ b/test/ELF/executable-undefined-ignoreall.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 %tout --unresolved-symbols=ignore-all -pie +# RUN: llvm-readobj -r %tout | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.plt { +# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +_start: +callq foo@PLT diff --git a/test/ELF/executable-undefined-protected-ignoreall.s b/test/ELF/executable-undefined-protected-ignoreall.s new file mode 100644 index 000000000000..37911791e124 --- /dev/null +++ b/test/ELF/executable-undefined-protected-ignoreall.s @@ -0,0 +1,8 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: not ld.lld %t -o %tout --unresolved-symbols=ignore-all -pie 2>&1 | FileCheck %s +# CHECK: error: undefined symbol: foo + +.protected foo +_start: +callq foo@PLT diff --git a/test/ELF/file-access.s b/test/ELF/file-access.s new file mode 100644 index 000000000000..5a9e53b11140 --- /dev/null +++ b/test/ELF/file-access.s @@ -0,0 +1,13 @@ +# REQUIRES: x86, shell + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld -r %t.o -o %t1.o +# RUN: [ ! -x %t1.o ] +# RUN: ld.lld -shared %t.o -o %t2.so +# RUN: [ -x %t2.so ] +# RUN: ld.lld %t.o -o %t3 +# RUN: [ -x %t3 ] + +.global _start +_start: + nop diff --git a/test/ELF/fill-trap.s b/test/ELF/fill-trap.s new file mode 100644 index 000000000000..001b904a7790 --- /dev/null +++ b/test/ELF/fill-trap.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t2 +# RUN: llvm-readobj -program-headers %t2 | FileCheck %s +# RUN: od -Ax -x -N16 -j0x1ff0 %t2 | FileCheck %s -check-prefix=FILL + +# CHECK: ProgramHeader { +# CHECK: Type: PT_LOAD +# CHECK: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: +# CHECK-NEXT: PhysicalAddress: +# CHECK-NEXT: FileSize: 4096 +# CHECK-NEXT: MemSize: +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_X +# CHECK-NEXT: ] + +## Check that executable page is filled with traps at its end. +# FILL: 001ff0 cccc cccc cccc cccc cccc cccc cccc cccc + +.globl _start +_start: + nop diff --git a/test/ELF/filter.s b/test/ELF/filter.s index fa8e5267b18b..4c9104a32510 100644 --- a/test/ELF/filter.s +++ b/test/ELF/filter.s @@ -2,10 +2,14 @@ # RUN: ld.lld %t.o -shared -F foo.so -F boo.so -o %t1 # RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s -# Test alias. +# Test alias #1. # RUN: ld.lld %t.o -shared --filter=foo.so --filter=boo.so -o %t2 # RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s +# Test alias #2. +# RUN: ld.lld %t.o -shared --filter foo.so --filter boo.so -o %t3 +# RUN: llvm-readobj --dynamic-table %t3 | FileCheck %s + # CHECK: DynamicSection [ # CHECK-NEXT: Tag Type Name/Value # CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [foo.so] diff --git a/test/ELF/format-binary-non-ascii.s b/test/ELF/format-binary-non-ascii.s new file mode 100644 index 000000000000..5a3ad960c30e --- /dev/null +++ b/test/ELF/format-binary-non-ascii.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t£.o + +# RUN: ld.lld -o %t.elf %t£.o --format=binary %t£.o +# RUN: llvm-readobj -symbols %t.elf | FileCheck %s + +# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_start +# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_end +# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_non_ascii_s_tmp___o_size + +.text +.align 4 +.globl _start +_start: + nop diff --git a/test/ELF/gc-collect-undefined.s b/test/ELF/gc-collect-undefined.s new file mode 100644 index 000000000000..7ade554aef13 --- /dev/null +++ b/test/ELF/gc-collect-undefined.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 %tout --gc-sections -shared +# RUN: llvm-nm -D %tout | FileCheck %s + +# CHECK-NOT: qux +# CHECK: bar +# CHECK-NOT: qux + + .global foo,bar,qux + .local baz + + .section .data.foo,"aw",%progbits +foo: + .dc.a bar + + .section .bata.baz,"aw",%progbits +baz: + .dc.a qux diff --git a/test/ELF/gc-merge-local-sym.s b/test/ELF/gc-merge-local-sym.s index a4540af4d9cc..b02a3a4e4762 100644 --- a/test/ELF/gc-merge-local-sym.s +++ b/test/ELF/gc-merge-local-sym.s @@ -15,7 +15,7 @@ // 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: ) diff --git a/test/ELF/gc-sections-linker-defined-symbol.s b/test/ELF/gc-sections-linker-defined-symbol.s new file mode 100644 index 000000000000..796f7b363559 --- /dev/null +++ b/test/ELF/gc-sections-linker-defined-symbol.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.so --gc-sections -shared +# RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s + +# CHECK: Name: _end@ +# CHECK-NEXT: Value: +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: +# CHECK-NEXT: Section: .dynamic + + .data + .globl g + g: + .quad _end diff --git a/test/ELF/gc-sections-merge-addend.s b/test/ELF/gc-sections-merge-addend.s index 1c1f6ee2389b..8595f5802be5 100644 --- a/test/ELF/gc-sections-merge-addend.s +++ b/test/ELF/gc-sections-merge-addend.s @@ -16,7 +16,7 @@ // 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: 62617200 |bar.| // CHECK-NEXT: ) diff --git a/test/ELF/gc-sections-merge-implicit-addend.s b/test/ELF/gc-sections-merge-implicit-addend.s index c725e294a187..8a7c804a830a 100644 --- a/test/ELF/gc-sections-merge-implicit-addend.s +++ b/test/ELF/gc-sections-merge-implicit-addend.s @@ -16,7 +16,7 @@ // 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: 62617200 |bar.| // CHECK-NEXT: ) diff --git a/test/ELF/gc-sections-merge.s b/test/ELF/gc-sections-merge.s index d7b3eaeca751..ef2688659871 100644 --- a/test/ELF/gc-sections-merge.s +++ b/test/ELF/gc-sections-merge.s @@ -18,7 +18,7 @@ // 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: 666F6F00 62617200 |foo.bar.| // CHECK-NEXT: ) @@ -36,7 +36,7 @@ // GC-NEXT: Link: 0 // GC-NEXT: Info: 0 // GC-NEXT: AddressAlignment: 1 -// GC-NEXT: EntrySize: 0 +// GC-NEXT: EntrySize: 1 // GC-NEXT: SectionData ( // GC-NEXT: 0000: 666F6F00 |foo.| // GC-NEXT: ) diff --git a/test/ELF/gc-sections-print.s b/test/ELF/gc-sections-print.s index 59177a65367e..e05824177c1f 100644 --- a/test/ELF/gc-sections-print.s +++ b/test/ELF/gc-sections-print.s @@ -5,6 +5,12 @@ # PRINT: removing unused section from '.text.x' in file # PRINT-NEXT: removing unused section from '.text.y' in file +# RUN: ld.lld %t --gc-sections --print-gc-sections --no-print-gc-sections -o %t2 >& %t.log +# RUN: echo >> %t.log +# RUN: FileCheck -check-prefix=NOPRINT %s < %t.log + +# NOPRINT-NOT: removing + .globl _start .protected a, x, y _start: diff --git a/test/ELF/gc-sections-shared.s b/test/ELF/gc-sections-shared.s index efb21faee6bd..2976213e910a 100644 --- a/test/ELF/gc-sections-shared.s +++ b/test/ELF/gc-sections-shared.s @@ -1,12 +1,18 @@ # REQUIRES: x86 # 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/gc-sections-shared.s -o %t3.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/gc-sections-shared2.s -o %t4.o # RUN: ld.lld -shared %t2.o -o %t2.so +# RUN: ld.lld -shared %t3.o -o %t3.so +# RUN: ld.lld -shared %t4.o -o %t4.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: ld.lld --gc-sections --export-dynamic-symbol foo -o %t %t.o --as-needed %t2.so %t3.so %t4.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 +# It would also be OK to keep bar2 and the need for %t2.so +# At the same time, weak symbols should not cause adding DT_NEEDED; +# this case is checked with symbol qux and %t4.so. # CHECK: DynamicSymbols [ # CHECK-NEXT: Symbol { @@ -19,7 +25,16 @@ # CHECK-NEXT: Section: Undefined (0x0) # CHECK-NEXT: } # CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: bar2 +# CHECK-NEXT: Name: bar +# CHECK-NEXT: Value: +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: baz # CHECK-NEXT: Value: # CHECK-NEXT: Size: # CHECK-NEXT: Binding: Global @@ -36,9 +51,76 @@ # CHECK-NEXT: Other: # CHECK-NEXT: Section: .text # CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: qux +# CHECK-NEXT: Value: +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Weak +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } # CHECK-NEXT: ] -# CHECK: NEEDED Shared library: [{{.*}}.so] +# CHECK-NOT: NEEDED +# CHECK: NEEDED Shared library: [{{.*}}3.so] +# CHECK-NOT: NEEDED + +# Test with %t.o at the end too. +# RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t --as-needed %t2.so %t3.so %t4.so %t.o +# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck --check-prefix=CHECK2 %s + +# CHECK2: DynamicSymbols [ +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: +# CHECK2-NEXT: Value: +# CHECK2-NEXT: Size: +# CHECK2-NEXT: Binding: Local +# CHECK2-NEXT: Type: +# CHECK2-NEXT: Other: +# CHECK2-NEXT: Section: Undefined (0x0) +# CHECK2-NEXT: } +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: bar +# CHECK2-NEXT: Value: +# CHECK2-NEXT: Size: +# CHECK2-NEXT: Binding: Global +# CHECK2-NEXT: Type: +# CHECK2-NEXT: Other: +# CHECK2-NEXT: Section: .text +# CHECK2-NEXT: } +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: baz +# CHECK2-NEXT: Value: +# CHECK2-NEXT: Size: +# CHECK2-NEXT: Binding: Global +# CHECK2-NEXT: Type: +# CHECK2-NEXT: Other: +# CHECK2-NEXT: Section: Undefined +# CHECK2-NEXT: } +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: qux +# CHECK2-NEXT: Value: +# CHECK2-NEXT: Size: +# CHECK2-NEXT: Binding: Weak +# CHECK2-NEXT: Type: +# CHECK2-NEXT: Other: +# CHECK2-NEXT: Section: Undefined +# CHECK2-NEXT: } +# CHECK2-NEXT: Symbol { +# CHECK2-NEXT: Name: foo +# CHECK2-NEXT: Value: +# CHECK2-NEXT: Size: +# CHECK2-NEXT: Binding: Global +# CHECK2-NEXT: Type: +# CHECK2-NEXT: Other: +# CHECK2-NEXT: Section: .text +# CHECK2-NEXT: } +# CHECK2-NEXT: ] + +# CHECK2-NOT: NEEDED +# CHECK2: NEEDED Shared library: [{{.*}}3.so] +# CHECK2-NOT: NEEDED .section .text.foo, "ax" .globl foo @@ -52,7 +134,10 @@ ret .section .text._start, "ax" .globl _start +.weak qux _start: +call baz +call qux ret .section .text.unused, "ax" diff --git a/test/ELF/gc-sections-undefined.s b/test/ELF/gc-sections-undefined.s new file mode 100644 index 000000000000..e1ce9c739738 --- /dev/null +++ b/test/ELF/gc-sections-undefined.s @@ -0,0 +1,10 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %t1 --gc-sections --undefined=foo +# RUN: llvm-readobj -t %t1 | FileCheck %s + +# CHECK: foo + +.section .foo,"ax" +.global foo +foo: diff --git a/test/ELF/gdb-index-base-addr.s b/test/ELF/gdb-index-base-addr.s new file mode 100644 index 000000000000..3871f8fc92e9 --- /dev/null +++ b/test/ELF/gdb-index-base-addr.s @@ -0,0 +1,70 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +# RUN: ld.lld --gdb-index %t1.o -o %t +# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s + +# CHECK: .gnu_index contents: +# CHECK: Address area offset = 0x28, has 2 entries: +# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 +# CHECK-NEXT: Low/High address = [0x201003, 0x201006) (Size: 0x3), CU id = 0 + +.text +.globl foo +.type foo,@function +foo: +.Lfunc_begin0: + nop +.Ltmp0: + nop + nop +.Ltmp1: + nop + nop + nop +.Ltmp2: + +.section .debug_abbrev,"",@progbits +.byte 1 # Abbreviation Code +.byte 17 # DW_TAG_compile_unit +.byte 0 # DW_CHILDREN_no +.byte 37 # DW_AT_producer +.byte 14 # DW_FORM_strp +.byte 19 # DW_AT_language +.byte 5 # DW_FORM_data2 +.byte 3 # DW_AT_name +.byte 14 # DW_FORM_strp +.byte 16 # DW_AT_stmt_list +.byte 23 # DW_FORM_sec_offset +.byte 27 # DW_AT_comp_dir +.byte 14 # DW_FORM_strp +.byte 17 # DW_AT_low_pc +.byte 1 # DW_FORM_addr +.byte 85 # DW_AT_ranges +.byte 23 # DW_FORM_sec_offset +.byte 0 # EOM(1) +.byte 0 # EOM(2) +.byte 0 # EOM(3) + +.section .debug_info,"",@progbits +.Lcu_begin0: +.long 38 # Length of Unit +.short 4 # DWARF version number +.long .debug_abbrev # Offset Into Abbrev. Section +.byte 8 # Address Size (in bytes) +.byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit +.long 0 # DW_AT_producer +.short 4 # DW_AT_language +.long 0 # DW_AT_name +.long 0 # DW_AT_stmt_list +.long 0 # DW_AT_comp_dir +.quad .Lfunc_begin0 # DW_AT_low_pc +.long .Ldebug_ranges0 # DW_AT_ranges + +.section .debug_ranges,"",@progbits +.Ldebug_ranges0: + .quad .Lfunc_begin0-.Lfunc_begin0 + .quad .Ltmp0-.Lfunc_begin0 + .quad .Ltmp1-.Lfunc_begin0 + .quad .Ltmp2-.Lfunc_begin0 + .quad 0 + .quad 0 diff --git a/test/ELF/gdb-index-dup-types.s b/test/ELF/gdb-index-dup-types.s index e0bed33eed4d..f5df00c453cc 100644 --- a/test/ELF/gdb-index-dup-types.s +++ b/test/ELF/gdb-index-dup-types.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: ld.lld --gdb-index %t.o -o %t -# RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s +# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s ## Testcase is based on output produced by gcc version 5.4.1 20160904 ## it has duplicate entries in .debug_gnu_pubtypes which seems to be diff --git a/test/ELF/gdb-index-empty.s b/test/ELF/gdb-index-empty.s index 0158357c9bfd..b5b403636290 100644 --- a/test/ELF/gdb-index-empty.s +++ b/test/ELF/gdb-index-empty.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s # RUN: ld.lld --gdb-index --gc-sections -o %t2 %t -# RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s +# RUN: llvm-dwarfdump -gdb-index %t2 | FileCheck %s # CHECK: Address area offset = 0x28, has 0 entries: @@ -74,7 +74,7 @@ _start: .quad .Lfunc_begin0 # DW_AT_low_pc .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc .byte 1 # DW_AT_frame_base - .byte 87 + .byte 87 .long 0 # DW_AT_name .byte 1 # DW_AT_decl_file .byte 1 # DW_AT_decl_line diff --git a/test/ELF/gdb-index-gc-sections.s b/test/ELF/gdb-index-gc-sections.s index 58c47ae5e987..6016e9ccdd07 100644 --- a/test/ELF/gdb-index-gc-sections.s +++ b/test/ELF/gdb-index-gc-sections.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s # RUN: ld.lld --gdb-index --gc-sections -o %t2 %t -# RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s +# RUN: llvm-dwarfdump -gdb-index %t2 | FileCheck %s # CHECK: Address area offset = 0x28, has 1 entries: # CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 diff --git a/test/ELF/gdb-index-noranges.s b/test/ELF/gdb-index-noranges.s new file mode 100644 index 000000000000..29ba91eb5a75 --- /dev/null +++ b/test/ELF/gdb-index-noranges.s @@ -0,0 +1,49 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o + +## Input is reduced from following code and invocation: +## clang++ -gsplit-dwarf -c test.ii -o test.s -S +## clang version: 6.0.0 (trunk 318293) +## +## test.ii: +## int a; +## +## Debug information does not contain any address ranges. +## We crashed in that case. Check we don't. +# RUN: ld.lld --gdb-index %t1.o -o %t + +.section .debug_str,"MS",@progbits,1 +.Lskel_string0: + .asciz "t.dwo" +.Lskel_string1: + .asciz "path" + +.section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .ascii "\260B" # DW_AT_GNU_dwo_name + .byte 14 # DW_FORM_strp + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 + .ascii "\263B" # DW_AT_GNU_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + +.section .debug_info,"",@progbits + .long 32 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x19 DW_TAG_compile_unit + .long 0 # DW_AT_stmt_list + .long .Lskel_string0 # DW_AT_GNU_dwo_name + .long .Lskel_string1 # DW_AT_comp_dir + .quad -3824446529333676116 # DW_AT_GNU_dwo_id + .long 0 # DW_AT_GNU_addr_base diff --git a/test/ELF/gdb-index-ranges.s b/test/ELF/gdb-index-ranges.s index 2dd158ee4a0a..c41be114f005 100644 --- a/test/ELF/gdb-index-ranges.s +++ b/test/ELF/gdb-index-ranges.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: ld.lld --gdb-index -e main %t.o -o %t -# RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s +# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s # CHECK: .gnu_index contents: # CHECK: Address area offset = 0x28, has 2 entries: diff --git a/test/ELF/gdb-index-tls.s b/test/ELF/gdb-index-tls.s new file mode 100644 index 000000000000..0fd7b6115676 --- /dev/null +++ b/test/ELF/gdb-index-tls.s @@ -0,0 +1,91 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld --gdb-index -shared %t.o -o %t + +# This used to fail trying to compute R_X86_64_DTPOFF64 + + .section .tdata,"awT",@progbits +PrettyStackTraceHead: + .long 42 # 0x2a + + .section .debug_str,"MS",@progbits,1 + .asciz "" + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 14 # DW_FORM_strp + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 14 # DW_FORM_strp + .ascii "\264B" # DW_AT_GNU_pubnames + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_strp + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + + .section .debug_info,"",@progbits +.Lcu_begin0: + .long 56 # Length of Unit + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x31 DW_TAG_compile_unit + .long .debug_str # DW_AT_producer + .short 4 # DW_AT_language + .long .debug_str # DW_AT_name + .long .debug_line # DW_AT_stmt_list + .long .debug_str # DW_AT_comp_dir + # DW_AT_GNU_pubnames + .byte 2 # Abbrev [2] 0x1e:0x16 DW_TAG_variable + .long .debug_str # DW_AT_name + .long 52 # DW_AT_type + # DW_AT_external + .byte 1 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 10 # DW_AT_location + .byte 14 + .quad PrettyStackTraceHead@DTPOFF + .byte 224 + .byte 3 # Abbrev [3] 0x34:0x7 DW_TAG_base_type + .long .debug_str # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark + + .section .debug_line,"",@progbits diff --git a/test/ELF/gdb-index.s b/test/ELF/gdb-index.s index e04845e022c3..8fea83d145fa 100644 --- a/test/ELF/gdb-index.s +++ b/test/ELF/gdb-index.s @@ -1,12 +1,12 @@ # 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/gdb-index.s -o %t2.o -# RUN: ld.lld --gdb-index -e main %t1.o %t2.o -o %t -# RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s +# RUN: ld.lld --gdb-index %t1.o %t2.o -o %t +# RUN: llvm-dwarfdump -gdb-index %t | FileCheck %s # RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM # DISASM: Disassembly of section .text: -# DISASM: main: +# DISASM: entrypoint: # DISASM-CHECK: 201000: 90 nop # DISASM-CHECK: 201001: cc int3 # DISASM-CHECK: 201002: cc int3 @@ -24,25 +24,29 @@ # CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0 # CHECK-NEXT: Low/High address = [0x201004, 0x201006) (Size: 0x2), CU id = 1 # CHECK: Symbol table offset = 0x60, size = 1024, filled slots: -# CHECK-NEXT: 489: Name offset = 0x1d, CU vector offset = 0x0 -# CHECK-NEXT: String name: main, CU vector index: 0 -# CHECK-NEXT: 754: Name offset = 0x22, CU vector offset = 0x8 -# CHECK-NEXT: String name: int, CU vector index: 1 -# CHECK-NEXT: 956: Name offset = 0x26, CU vector offset = 0x14 +# CHECK-NEXT: 754: Name offset = 0x27, CU vector offset = 0x8 +# CHECK-NEXT: String name: int, CU vector index: 1 +# CHECK-NEXT: 822: Name offset = 0x1c, CU vector offset = 0x0 +# CHECK-NEXT: String name: entrypoint, CU vector index: 0 +# CHECK-NEXT: 956: Name offset = 0x2b, CU vector offset = 0x14 # CHECK-NEXT: String name: main2, CU vector index: 2 # CHECK: Constant pool offset = 0x2060, has 3 CU vectors: # CHECK-NEXT: 0(0x0): 0x30000000 # CHECK-NEXT: 1(0x8): 0x90000000 0x90000001 # CHECK-NEXT: 2(0x14): 0x30000001 +# RUN: ld.lld --gdb-index --no-gdb-index %t1.o %t2.o -o %t2 +# RUN: llvm-readobj -sections %t2 | FileCheck -check-prefix=NOGDB %s +# NOGDB-NOT: Name: .gdb_index + ## The following section contents are created by this using gcc 7.1.0: -## echo 'int main() { return 0; }' | gcc -gsplit-dwarf -xc++ -S -o- - +## echo 'int entrypoint() { return 0; }' | gcc -gsplit-dwarf -xc++ -S -o- - .text .Ltext0: -.globl main -.type main, @function -main: +.globl entrypoint +.type entrypoint, @function +entrypoint: nop .Letext0: @@ -98,7 +102,7 @@ main: .long 0x33 .long 0x18 .byte 0x30 -.string "main" +.string "entrypoint" .long 0 .section .debug_gnu_pubtypes,"",@progbits diff --git a/test/ELF/global-offset-table-position-aarch64.s b/test/ELF/global-offset-table-position-aarch64.s index 624e9b516fed..68bc4a4254ed 100644 --- a/test/ELF/global-offset-table-position-aarch64.s +++ b/test/ELF/global-offset-table-position-aarch64.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t -// RUN: ld.lld -shared %t -o %t2 +// RUN: ld.lld --hash-style=sysv -shared %t -o %t2 // RUN: llvm-readobj -t %t2 | FileCheck %s // REQUIRES: aarch64 .globl a diff --git a/test/ELF/global-offset-table-position-arm.s b/test/ELF/global-offset-table-position-arm.s index 781d8ce5222f..19619b2cc9e8 100644 --- a/test/ELF/global-offset-table-position-arm.s +++ b/test/ELF/global-offset-table-position-arm.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t -// RUN: ld.lld -shared %t -o %t2 +// RUN: ld.lld --hash-style=sysv -shared %t -o %t2 // RUN: llvm-readobj -t %t2 | FileCheck %s // REQUIRES: arm diff --git a/test/ELF/global-offset-table-position-i386.s b/test/ELF/global-offset-table-position-i386.s index 907105edcff0..9f778e1efb50 100644 --- a/test/ELF/global-offset-table-position-i386.s +++ b/test/ELF/global-offset-table-position-i386.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t -// RUN: ld.lld -shared %t -o %t2 +// RUN: ld.lld --hash-style=sysv -shared %t -o %t2 // RUN: llvm-readobj -t %t2 | FileCheck %s // REQUIRES: x86 diff --git a/test/ELF/global-offset-table-position.s b/test/ELF/global-offset-table-position.s index b3317c7edd8b..f1195b2cf674 100644 --- a/test/ELF/global-offset-table-position.s +++ b/test/ELF/global-offset-table-position.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t -// RUN: ld.lld -shared %t -o %t2 +// RUN: ld.lld --hash-style=sysv -shared %t -o %t2 // RUN: llvm-readobj -t %t2 | FileCheck %s // REQUIRES: x86 diff --git a/test/ELF/global_offset_table_shared.s b/test/ELF/global_offset_table_shared.s index 1ebc0110d4d7..03af02e5805e 100644 --- a/test/ELF/global_offset_table_shared.s +++ b/test/ELF/global_offset_table_shared.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t -// RUN: ld.lld -shared %t -o %t2 +// RUN: ld.lld --hash-style=sysv -shared %t -o %t2 // RUN: llvm-readobj -t %t2 | FileCheck %s .long _GLOBAL_OFFSET_TABLE_ - . diff --git a/test/ELF/gnu-hash-table-copy.s b/test/ELF/gnu-hash-table-copy.s new file mode 100644 index 000000000000..9d91163258ea --- /dev/null +++ b/test/ELF/gnu-hash-table-copy.s @@ -0,0 +1,30 @@ +# REQUIRES: x86 + +# RUN: echo ".global foo; .type foo, @object; .size foo, 4; foo:; .long 0" > %t.s +# RUN: echo ".global bar; .type bar, @object; .size bar, 4; bar:; .long 0" >> %t.s +# RUN: echo ".global zed; .type zed, @function; zed:" >> %t.s +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t1.o +# RUN: ld.lld %t1.o -o %t1.so -shared + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o +# RUN: ld.lld --hash-style=gnu %t2.o %t1.so -o %t2 + +# RUN: llvm-readelf --symbols --gnu-hash-table %t2 | FileCheck %s + +# CHECK: Symbol table '.dynsym' contains 4 entries: +# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name +# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND @ +# CHECK-NEXT: 1: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND foo@ +# CHECK-DAG: : {{.*}} 4 OBJECT GLOBAL DEFAULT {{.*}} bar@ +# CHECK-DAG: : {{.*}} 0 FUNC GLOBAL DEFAULT UND zed@ + +# CHECK: First Hashed Symbol Index: 2 + +.global _start +_start: + +.quad bar +.quad zed + +.data +.quad foo diff --git a/test/ELF/gnu-hash-table-many.s b/test/ELF/gnu-hash-table-many.s new file mode 100644 index 000000000000..ab35a07981e7 --- /dev/null +++ b/test/ELF/gnu-hash-table-many.s @@ -0,0 +1,55 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -hash-style=gnu %t.o -o %t.so -shared +# RUN: llvm-readelf --gnu-hash-table %t.so | FileCheck %s + +# CHECK: Num Buckets: 4 + +.global sym1 +sym1: + +.global sym2 +sym2: + +.global sym3 +sym3: + +.global sym4 +sym4: + +.global sym5 +sym5: + +.global sym6 +sym6: + +.global sym7 +sym7: + +.global sym8 +sym8: + +.global sym9 +sym9: + +.global sym10 +sym10: + +.global sym11 +sym11: + +.global sym12 +sym12: + +.global sym13 +sym13: + +.global sym14 +sym14: + +.global sym15 +sym15: + +.global sym16 +sym16: diff --git a/test/ELF/gnu-hash-table-rwsegment.s b/test/ELF/gnu-hash-table-rwsegment.s new file mode 100644 index 000000000000..b1a50fbde3a1 --- /dev/null +++ b/test/ELF/gnu-hash-table-rwsegment.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -shared -hash-style=gnu --no-rosegment -o %t.so %t.o +# RUN: llvm-readobj -gnu-hash-table %t.so | FileCheck %s + +# CHECK: GnuHashTable { +# CHECK-NEXT: Num Buckets: 1 +# CHECK-NEXT: First Hashed Symbol Index: 1 +# CHECK-NEXT: Num Mask Words: 1 +# CHECK-NEXT: Shift Count: 6 +# CHECK-NEXT: Bloom Filter: [0x400000000004204] +# CHECK-NEXT: Buckets: [1] +# CHECK-NEXT: Values: [0xB8860BA, 0xB887389] +# CHECK-NEXT: } + +.globl foo, bar +foo: +bar: + ret diff --git a/test/ELF/gnu-hash-table.s b/test/ELF/gnu-hash-table.s index 0e37574aaa7c..fa68ba250131 100644 --- a/test/ELF/gnu-hash-table.s +++ b/test/ELF/gnu-hash-table.s @@ -1,15 +1,34 @@ # REQUIRES: x86,ppc -# RUN: echo ".globl foo" > %te.s +# RUN: echo ".globl foo; .data; .dc.a foo" > %te.s # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %te.s -o %te-i386.o # RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t-i386.o # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t-x86_64.o # RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %s -o %t-ppc64.o +# RUN: echo ".global zed; zed:" > %t2.s +# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t2.s -o %t2-i386.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2-x86_64.o +# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t2.s -o %t2-ppc64.o + +# RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a +# RUN: llvm-ar rc %t2-i386.a %t2-i386.o +# RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o +# RUN: llvm-ar rc %t2-ppc64.a %t2-ppc64.o + +# RUN: echo ".global xyz; xyz:" > %t3.s +# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t3.s -o %t3-i386.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t3.s -o %t3-x86_64.o +# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t3.s -o %t3-ppc64.o + +# RUN: ld.lld -shared %t3-i386.o -o %t3-i386.so +# RUN: ld.lld -shared %t3-x86_64.o -o %t3-x86_64.so +# RUN: ld.lld -shared %t3-ppc64.o -o %t3-ppc64.so + # RUN: ld.lld -shared --hash-style=gnu -o %te-i386.so %te-i386.o -# RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o -# RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o -# RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o +# RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o %t2-i386.a %t3-i386.so +# RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o %t2-x86_64.a %t3-x86_64.so +# RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o %t2-ppc64.a %t3-ppc64.so # RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \ # RUN: | FileCheck %s -check-prefix=EMPTY @@ -70,6 +89,16 @@ # I386: Section: Undefined # I386: } # I386: Symbol { +# I386: Name: xyz@ +# I386: Binding: Global +# I386: Section: Undefined +# I386: } +# I386: Symbol { +# I386: Name: zed@ +# I386: Binding: Weak +# I386: Section: Undefined +# I386: } +# I386: Symbol { # I386: Name: bar@ # I386: Binding: Global # I386: Section: .text @@ -82,11 +111,11 @@ # I386: ] # I386: GnuHashTable { # I386-NEXT: Num Buckets: 1 -# I386-NEXT: First Hashed Symbol Index: 2 +# I386-NEXT: First Hashed Symbol Index: 4 # I386-NEXT: Num Mask Words: 1 # I386-NEXT: Shift Count: 5 # I386-NEXT: Bloom Filter: [0x14000220] -# I386-NEXT: Buckets: [2] +# I386-NEXT: Buckets: [4] # I386-NEXT: Values: [0xB8860BA, 0xB887389] # I386-NEXT: } @@ -120,6 +149,16 @@ # X86_64: Section: Undefined # X86_64: } # X86_64: Symbol { +# X86_64: Name: xyz@ +# X86_64: Binding: Global +# X86_64: Section: Undefined +# X86_64: } +# X86_64: Symbol { +# X86_64: Name: zed@ +# X86_64: Binding: Weak +# X86_64: Section: Undefined +# X86_64: } +# X86_64: Symbol { # X86_64: Name: bar@ # X86_64: Binding: Global # X86_64: Section: .text @@ -132,11 +171,11 @@ # X86_64: ] # X86_64: GnuHashTable { # X86_64-NEXT: Num Buckets: 1 -# X86_64-NEXT: First Hashed Symbol Index: 2 +# X86_64-NEXT: First Hashed Symbol Index: 4 # X86_64-NEXT: Num Mask Words: 1 # X86_64-NEXT: Shift Count: 6 # X86_64-NEXT: Bloom Filter: [0x400000000004204] -# X86_64-NEXT: Buckets: [2] +# X86_64-NEXT: Buckets: [4] # X86_64-NEXT: Values: [0xB8860BA, 0xB887389] # X86_64-NEXT: } @@ -149,10 +188,10 @@ # PPC64-NEXT: Flags [ # PPC64-NEXT: SHF_ALLOC # PPC64-NEXT: ] -# PPC64-NEXT: Address: 0x228 -# PPC64-NEXT: Offset: 0x228 +# PPC64-NEXT: Address: +# PPC64-NEXT: Offset: # PPC64-NEXT: Size: 36 -# PPC64-NEXT: Link: 1 +# PPC64-NEXT: Link: # PPC64-NEXT: Info: 0 # PPC64-NEXT: AddressAlignment: 8 # PPC64-NEXT: EntrySize: 0 @@ -170,6 +209,16 @@ # PPC64: Section: Undefined # PPC64: } # PPC64: Symbol { +# PPC64: Name: xyz@ +# PPC64: Binding: Global +# PPC64: Section: Undefined +# PPC64: } +# PPC64: Symbol { +# PPC64: Name: zed@ +# PPC64: Binding: Weak +# PPC64: Section: Undefined +# PPC64: } +# PPC64: Symbol { # PPC64: Name: bar@ # PPC64: Binding: Global # PPC64: Section: .text @@ -182,14 +231,18 @@ # PPC64: ] # PPC64: GnuHashTable { # PPC64-NEXT: Num Buckets: 1 -# PPC64-NEXT: First Hashed Symbol Index: 2 +# PPC64-NEXT: First Hashed Symbol Index: 4 # PPC64-NEXT: Num Mask Words: 1 # PPC64-NEXT: Shift Count: 6 # PPC64-NEXT: Bloom Filter: [0x400000000004204] -# PPC64-NEXT: Buckets: [2] +# PPC64-NEXT: Buckets: [4] # PPC64-NEXT: Values: [0xB8860BA, 0xB887389] # PPC64-NEXT: } .globl foo,bar,baz foo: bar: +.weak zed +.global xyz +.data + .dc.a baz diff --git a/test/ELF/gnu-ifunc-dynsym.s b/test/ELF/gnu-ifunc-dynsym.s new file mode 100644 index 000000000000..fca15462dcb1 --- /dev/null +++ b/test/ELF/gnu-ifunc-dynsym.s @@ -0,0 +1,19 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: ld.lld -static -export-dynamic %t.o -o %tout +// RUN: llvm-nm -U %tout | FileCheck %s +// REQUIRES: x86 + +// CHECK: __rela_iplt_end +// CHECK: __rela_iplt_start + +.text +.type foo STT_GNU_IFUNC +.globl foo +foo: + ret + +.globl _start +_start: + call foo + movl $__rela_iplt_start,%edx + movl $__rela_iplt_end,%edx diff --git a/test/ELF/gnu-ifunc-gotpcrel.s b/test/ELF/gnu-ifunc-gotpcrel.s index 2a5814a98bc2..b506ffa8c390 100644 --- a/test/ELF/gnu-ifunc-gotpcrel.s +++ b/test/ELF/gnu-ifunc-gotpcrel.s @@ -2,7 +2,7 @@ # 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: ld.lld --hash-style=sysv %t.o %t2.so -o %t # RUN: llvm-readobj -dyn-relocations %t | FileCheck %s # CHECK: Dynamic Relocations { diff --git a/test/ELF/gnu-ifunc-i386.s b/test/ELF/gnu-ifunc-i386.s index 21f1313a9b05..559e98a3e625 100644 --- a/test/ELF/gnu-ifunc-i386.s +++ b/test/ELF/gnu-ifunc-i386.s @@ -15,7 +15,7 @@ // CHECK-NEXT: Address: [[RELA:.*]] // CHECK-NEXT: Offset: 0xD4 // CHECK-NEXT: Size: 16 -// CHECK-NEXT: Link: 6 +// CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 4 // CHECK-NEXT: EntrySize: 8 diff --git a/test/ELF/gnu-ifunc-plt-i386.s b/test/ELF/gnu-ifunc-plt-i386.s index 50f10c5fe6ca..243eff62fcbf 100644 --- a/test/ELF/gnu-ifunc-plt-i386.s +++ b/test/ELF/gnu-ifunc-plt-i386.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o // RUN: ld.lld %t1.o --shared -o %t.so // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o -// RUN: ld.lld %t.so %t.o -o %tout +// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s diff --git a/test/ELF/gnu-ifunc-plt.s b/test/ELF/gnu-ifunc-plt.s index cf46380d3894..88a09931853c 100644 --- a/test/ELF/gnu-ifunc-plt.s +++ b/test/ELF/gnu-ifunc-plt.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o // RUN: ld.lld %t1.o --shared -o %t.so // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -// RUN: ld.lld %t.so %t.o -o %tout +// RUN: ld.lld --hash-style=sysv %t.so %t.o -o %tout // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM // RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT // RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s diff --git a/test/ELF/gnu-ifunc-shared.s b/test/ELF/gnu-ifunc-shared.s index aee870c28e11..bde6807e4b43 100644 --- a/test/ELF/gnu-ifunc-shared.s +++ b/test/ELF/gnu-ifunc-shared.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -// RUN: ld.lld --shared -o %t.so %t.o +// RUN: ld.lld --hash-style=sysv --shared -o %t.so %t.o // RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=DISASM // RUN: llvm-readobj -r %t.so | FileCheck %s diff --git a/test/ELF/gnu-ifunc.s b/test/ELF/gnu-ifunc.s index f86f0300baaf..17883a3209f5 100644 --- a/test/ELF/gnu-ifunc.s +++ b/test/ELF/gnu-ifunc.s @@ -15,7 +15,7 @@ // CHECK-NEXT: Address: [[RELA:.*]] // CHECK-NEXT: Offset: 0x158 // CHECK-NEXT: Size: 48 -// CHECK-NEXT: Link: 6 +// CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 8 // CHECK-NEXT: EntrySize: 24 diff --git a/test/ELF/got-aarch64.s b/test/ELF/got-aarch64.s index ef6943881edc..f46946c9f4aa 100644 --- a/test/ELF/got-aarch64.s +++ b/test/ELF/got-aarch64.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o -// RUN: ld.lld -shared %t.o -o %t.so +// RUN: ld.lld --hash-style=sysv -shared %t.o -o %t.so // RUN: llvm-readobj -s -r %t.so | FileCheck %s // RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s // REQUIRES: aarch64 diff --git a/test/ELF/got.s b/test/ELF/got.s index 57c1baddfd0c..f67ea13d3f4e 100644 --- a/test/ELF/got.s +++ b/test/ELF/got.s @@ -1,7 +1,7 @@ // 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: ld.lld -shared %t2.o -o %t2.so -// RUN: ld.lld %t.o %t2.so -o %t +// RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t // RUN: llvm-readobj -s -r %t | FileCheck %s // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s // REQUIRES: x86 diff --git a/test/ELF/got32-i386-pie-rw.s b/test/ELF/got32-i386-pie-rw.s new file mode 100644 index 000000000000..18b019c2cc9d --- /dev/null +++ b/test/ELF/got32-i386-pie-rw.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t -pie +# RUN: llvm-readelf -r -s %t | FileCheck %s + +# Unlike bfd and gold we accept this. + +# CHECK: .foobar PROGBITS 00001000 +# CHECK: .got PROGBITS [[GOT:[0-9a-z]*]] +# CHECK: [[GOT]] 00000008 R_386_RELATIVE +# CHECK: 00001002 00000008 R_386_RELATIVE +foo: + +.section .foobar, "awx" +.global _start +_start: + movl foo@GOT, %ebx diff --git a/test/ELF/got32-i386.s b/test/ELF/got32-i386.s index 468aaf1f0d53..00c7c0d6d553 100644 --- a/test/ELF/got32-i386.s +++ b/test/ELF/got32-i386.s @@ -20,4 +20,4 @@ _start: # CHECK: .got 00000004 0000000000012000 # RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR -# ERR: relocation R_386_GOT32 against 'foo' without base register can not be used when PIC enabled +# ERR: error: can't create dynamic relocation R_386_GOT32 against symbol: foo in readonly segment; recompile object files with -fPIC diff --git a/test/ELF/got32x-i386.s b/test/ELF/got32x-i386.s index 9a67d1997f2b..1311472cc061 100644 --- a/test/ELF/got32x-i386.s +++ b/test/ELF/got32x-i386.s @@ -43,5 +43,5 @@ # RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \ # RUN: FileCheck %s --check-prefix=ERR -# ERR: relocation R_386_GOT32X against 'foo' without base register can not be used when PIC enabled -# ERR: relocation R_386_GOT32X against 'foo' without base register can not be used when PIC enabled +# ERR: error: can't create dynamic relocation R_386_GOT32X against symbol: foo in readonly segment; recompile object files with -fPIC +# ERR: error: can't create dynamic relocation R_386_GOT32X against symbol: foo in readonly segment; recompile object files with -fPIC diff --git a/test/ELF/gotpc-relax-nopic.s b/test/ELF/gotpc-relax-nopic.s index dc7dcf2e91e7..e51b8bd9f4e9 100644 --- a/test/ELF/gotpc-relax-nopic.s +++ b/test/ELF/gotpc-relax-nopic.s @@ -1,6 +1,6 @@ # 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: ld.lld --hash-style=sysv %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 @@ -25,7 +25,7 @@ # DISASM-NEXT: 201031: {{.*}} xorq $2105344, %r8 # DISASM-NEXT: 201038: {{.*}} testq $2105344, %r15 -# RUN: ld.lld -shared %t.o -o %t2 +# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2 # RUN: llvm-readobj -s -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s # RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM-PIC %s # SEC-PIC: Section { @@ -64,7 +64,7 @@ # DISASM-PIC-NEXT: 1023: {{.*}} sbbq 8310(%rip), %rsi # DISASM-PIC-NEXT: 102a: {{.*}} subq 8303(%rip), %rbp # DISASM-PIC-NEXT: 1031: {{.*}} xorq 8296(%rip), %r8 -# DISASM-PIC-NEXT: 1038: {{.*}} testq 8289(%rip), %r15 +# DISASM-PIC-NEXT: 1038: {{.*}} testq %r15, 8289(%rip) .data .type bar, @object diff --git a/test/ELF/gotpc-relax-und-dso.s b/test/ELF/gotpc-relax-und-dso.s index ed6c4bc9bb15..3c5c8ba8c49b 100644 --- a/test/ELF/gotpc-relax-und-dso.s +++ b/test/ELF/gotpc-relax-und-dso.s @@ -2,7 +2,7 @@ # 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: ld.lld --hash-style=sysv -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 diff --git a/test/ELF/gotpcrelx.s b/test/ELF/gotpcrelx.s index 95dbf663ffe8..3ccbc56aba94 100644 --- a/test/ELF/gotpcrelx.s +++ b/test/ELF/gotpcrelx.s @@ -1,7 +1,7 @@ // 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: ld.lld --hash-style=sysv %t.o -o %t.so -shared // RUN: llvm-readobj -s -r %t.so | FileCheck %s movq foo@GOTPCREL(%rip), %rax diff --git a/test/ELF/help.s b/test/ELF/help.s new file mode 100644 index 000000000000..2554531532b3 --- /dev/null +++ b/test/ELF/help.s @@ -0,0 +1,5 @@ +# RUN: ld.lld --help 2>&1 | FileCheck %s +# CHECK: OPTIONS: +# CHECK: --output=<value> Path to file to write output +# CHECK: --output <value> Path to file to write output +# CHECK: -o <path> Path to file to write output diff --git a/test/ELF/i386-debug-noabs.test b/test/ELF/i386-debug-noabs.test new file mode 100644 index 000000000000..712d0a59cecc --- /dev/null +++ b/test/ELF/i386-debug-noabs.test @@ -0,0 +1,33 @@ +# REQUIRES: x86 + +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o -o %t.exe + +## This is for https://bugs.llvm.org//show_bug.cgi?id=34852. GCC 8.0 or +## earlier have a bug which creates non-absolute R_386_GOTPC relocations +## in non-allocated sections. It is illegal, but we want to make sure that +## lld skips them instead of reporting errors. + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_386 +Sections: + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x0000000000000001 + Content: 0000000000000000 + - Name: .rel.debug_info + Type: SHT_REL + Link: .symtab + AddressAlign: 0x0000000000000004 + Info: .debug_info + Relocations: + - Offset: 0x000000000000041F + Symbol: _GLOBAL_OFFSET_TABLE_ + Type: R_386_GOTPC +Symbols: + Global: + - Name: _GLOBAL_OFFSET_TABLE_ diff --git a/test/ELF/i386-got-and-copy.s b/test/ELF/i386-got-and-copy.s index f5b0b8ec5bb8..81bac22fd66a 100644 --- a/test/ELF/i386-got-and-copy.s +++ b/test/ELF/i386-got-and-copy.s @@ -9,7 +9,7 @@ # 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: ld.lld --hash-style=sysv %t.o %t.so -o %t.exe # RUN: llvm-readobj -r %t.exe | FileCheck %s # CHECK: Relocations [ diff --git a/test/ELF/i386-got-value.s b/test/ELF/i386-got-value.s new file mode 100644 index 000000000000..f42555b79272 --- /dev/null +++ b/test/ELF/i386-got-value.s @@ -0,0 +1,36 @@ +# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux +# RUN: ld.lld %t.o -o %t.so -shared +# RUN: llvm-readobj --relocations --symbols --sections --section-data %t.so | FileCheck %s + +# Check that the value of a preemptible symbol is written to the got +# entry when using Elf_Rel. It is not clear why that is required, but +# freebsd i386 seems to depend on it. + +# CHECK: Name: .got +# 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: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 00200000 +# CHECK-NEXT: ) + +# CHECK: R_386_GLOB_DAT bar 0x0 + +# CHECK: Name: bar +# CHECK-NEXT: Value: 0x2000 + + movl bar@GOT(%eax), %eax + + .data + .globl bar +bar: + .long 42 diff --git a/test/ELF/i386-gotoff-shared.s b/test/ELF/i386-gotoff-shared.s index 01242ad01c35..c22bd6dd5d78 100644 --- a/test/ELF/i386-gotoff-shared.s +++ b/test/ELF/i386-gotoff-shared.s @@ -1,6 +1,6 @@ // 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: ld.lld --hash-style=sysv %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 diff --git a/test/ELF/i386-gotpc-dynamic.s b/test/ELF/i386-gotpc-dynamic.s index da8a607d5753..0ec737e701a6 100644 --- a/test/ELF/i386-gotpc-dynamic.s +++ b/test/ELF/i386-gotpc-dynamic.s @@ -1,6 +1,6 @@ # 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: ld.lld --hash-style=sysv %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 diff --git a/test/ELF/i386-gotpc.s b/test/ELF/i386-gotpc.s index 8222effd6655..d2c5ef3d469c 100644 --- a/test/ELF/i386-gotpc.s +++ b/test/ELF/i386-gotpc.s @@ -1,6 +1,6 @@ // 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: ld.lld --hash-style=sysv %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 diff --git a/test/ELF/i386-pc8-pc16-addend.s b/test/ELF/i386-pc8-pc16-addend.s index 9d6424df3600..fc648b035509 100644 --- a/test/ELF/i386-pc8-pc16-addend.s +++ b/test/ELF/i386-pc8-pc16-addend.s @@ -4,7 +4,7 @@ # RUN: ld.lld %t1.o -o %t.out # RUN: llvm-objdump -s -t %t.out | FileCheck %s # CHECK: Contents of section .text: -# CHECK-NEXT: 11000 020000 +# CHECK-NEXT: 11000 020000 ## 0x11003 - 0x11000 + addend(-1) = 0x02 ## 0x11003 - 0x11001 + addend(-2) = 0x0000 # CHECK: SYMBOL TABLE: diff --git a/test/ELF/i386-reloc-16.s b/test/ELF/i386-reloc-16.s index db9dc0b36908..d69e6fbc49a7 100644 --- a/test/ELF/i386-reloc-16.s +++ b/test/ELF/i386-reloc-16.s @@ -9,6 +9,6 @@ // CHECK-NEXT: 200000 42 // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s -// ERROR: relocation R_386_16 out of range +// ERROR: relocation R_386_16 out of range: 65536 is not in [0, 65535] .short foo diff --git a/test/ELF/i386-reloc-8.s b/test/ELF/i386-reloc-8.s index b2e4426910e6..c6ae67120e22 100644 --- a/test/ELF/i386-reloc-8.s +++ b/test/ELF/i386-reloc-8.s @@ -9,6 +9,6 @@ // CHECK-NEXT: 200000 42 // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s -// ERROR: relocation R_386_8 out of range +// ERROR: relocation R_386_8 out of range: 256 is not in [0, 255] .byte foo diff --git a/test/ELF/i386-reloc-range.s b/test/ELF/i386-reloc-range.s index 4fb5325e5434..6f72f7af73c7 100644 --- a/test/ELF/i386-reloc-range.s +++ b/test/ELF/i386-reloc-range.s @@ -16,7 +16,7 @@ // RUN: not ld.lld -Ttext 0x200 %t.o %t2.o -o %t2 2>&1 | FileCheck --check-prefix=ERR %s -// ERR: {{.*}}:(.text+0x1): relocation R_386_PC16 out of range +// ERR: {{.*}}:(.text+0x1): relocation R_386_PC16 out of range: 65536 is not in [-65536, 65535] .global _start _start: diff --git a/test/ELF/i386-reloc8-reloc16-addend.s b/test/ELF/i386-reloc8-reloc16-addend.s index 42a57cedbca3..16b953e87ca9 100644 --- a/test/ELF/i386-reloc8-reloc16-addend.s +++ b/test/ELF/i386-reloc8-reloc16-addend.s @@ -4,7 +4,7 @@ # RUN: ld.lld -Ttext=0x0 %t1.o -o %t.out # RUN: llvm-objdump -s -t %t.out | FileCheck %s # CHECK: Contents of section .text: -# CHECK-NEXT: 0000 020100 +# CHECK-NEXT: 0000 020100 ## 0x3 + addend(-1) = 0x02 ## 0x3 + addend(-2) = 0x0100 # CHECK: SYMBOL TABLE: diff --git a/test/ELF/i386-tls-ie-shared.s b/test/ELF/i386-tls-ie-shared.s index f419eb45dfb9..2b842a86eb0f 100644 --- a/test/ELF/i386-tls-ie-shared.s +++ b/test/ELF/i386-tls-ie-shared.s @@ -1,7 +1,7 @@ // 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: ld.lld --hash-style=sysv -shared %t.o %tso -o %t1 // RUN: llvm-readobj -s -r -d %t1 | FileCheck --check-prefix=GOTRELSHARED %s // RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s diff --git a/test/ELF/icf-absolute.s b/test/ELF/icf-absolute.s index 601322477dae..09f6790907a1 100644 --- a/test/ELF/icf-absolute.s +++ b/test/ELF/icf-absolute.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-absolute.s -o %t2 -# RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose | FileCheck %s +# RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s # CHECK: selected .text.f1 # CHECK: removed .text.f2 diff --git a/test/ELF/icf-comdat.s b/test/ELF/icf-comdat.s index 28c0a586bf03..aab6a00f484d 100644 --- a/test/ELF/icf-comdat.s +++ b/test/ELF/icf-comdat.s @@ -1,7 +1,7 @@ # 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: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s # CHECK: selected .text.f1 # CHECK: removed .text.f2 diff --git a/test/ELF/icf-i386.s b/test/ELF/icf-i386.s index 292883e16fe5..b01e0503d405 100644 --- a/test/ELF/icf-i386.s +++ b/test/ELF/icf-i386.s @@ -2,7 +2,7 @@ # This test is to make sure that we can handle implicit addends properly. # RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t -# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s +# RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s # CHECK: selected .text.f1 # CHECK: removed .text.f2 diff --git a/test/ELF/icf-merge-sec.s b/test/ELF/icf-merge-sec.s index 39f6a884fa93..1e866a0caa49 100644 --- a/test/ELF/icf-merge-sec.s +++ b/test/ELF/icf-merge-sec.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge-sec.s -o %t2 -# RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose | FileCheck %s +# RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s # CHECK: selected .text.f1 # CHECK: removed .text.f2 diff --git a/test/ELF/icf-merge.s b/test/ELF/icf-merge.s index 938b749da6b8..06e852fe9dd5 100644 --- a/test/ELF/icf-merge.s +++ b/test/ELF/icf-merge.s @@ -2,13 +2,13 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge.s -o %t1 -# RUN: ld.lld %t %t1 -o %t1.out --icf=all --verbose | FileCheck %s +# RUN: ld.lld %t %t1 -o %t1.out --icf=all --verbose 2>&1 | FileCheck %s # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge2.s -o %t2 -# RUN: ld.lld %t %t2 -o %t3.out --icf=all --verbose | FileCheck --check-prefix=NOMERGE %s +# RUN: ld.lld %t %t2 -o %t3.out --icf=all --verbose 2>&1 | FileCheck --check-prefix=NOMERGE %s # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge3.s -o %t3 -# RUN: ld.lld %t %t3 -o %t3.out --icf=all --verbose | FileCheck --check-prefix=NOMERGE %s +# RUN: ld.lld %t %t3 -o %t3.out --icf=all --verbose 2>&1 | FileCheck --check-prefix=NOMERGE %s # CHECK: selected .text.f1 # CHECK: removed .text.f2 diff --git a/test/ELF/icf-non-mergeable.s b/test/ELF/icf-non-mergeable.s index 378c7b33696d..48ba2008cacc 100644 --- a/test/ELF/icf-non-mergeable.s +++ b/test/ELF/icf-non-mergeable.s @@ -1,14 +1,14 @@ // REQUIRES: x86 // This file contains two functions. They are themselves identical, -// but because they have reloactions against different data section, +// but because they have relocations against different data sections, // they are not mergeable. // 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/icf-non-mergeable.s -o %t2 -// RUN: ld.lld %t1 %t2 -o %t3 --icf=all --verbose | FileCheck %s +// RUN: ld.lld %t1 %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s // CHECK-NOT: selected .text.f1 // CHECK-NOT: removed .text.f2 diff --git a/test/ELF/icf-none.s b/test/ELF/icf-none.s index 671f2085f669..9ec1406de8a4 100644 --- a/test/ELF/icf-none.s +++ b/test/ELF/icf-none.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: ld.lld %t -o %t2 --icf=all --icf=none --verbose | FileCheck %s +# RUN: ld.lld %t -o %t2 --icf=all --icf=none --verbose 2>&1 | FileCheck %s # CHECK-NOT: selected .text.f1 diff --git a/test/ELF/icf-symbol-type.s b/test/ELF/icf-symbol-type.s new file mode 100644 index 000000000000..9cc1c509689a --- /dev/null +++ b/test/ELF/icf-symbol-type.s @@ -0,0 +1,26 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld --hash-style=sysv %t.o -o %t --icf=all -shared +# RUN: llvm-readelf --dyn-symbols --sections %t | FileCheck %s + +# We used to mark bar as absolute. + +# CHECK: .text PROGBITS 0000000000001000 +# CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 foo +# CHECK: 0000000000001001 0 NOTYPE GLOBAL DEFAULT 4 bar + +# The nop makes the test more interesting by making the offset of +# text.f non zero. + +nop + + .section .text.f,"ax",@progbits + .globl foo +foo: + retq + + .section .text.g,"ax",@progbits + .globl bar +bar: + retq diff --git a/test/ELF/icf1.s b/test/ELF/icf1.s index bb060078476e..e2562b5a83e7 100644 --- a/test/ELF/icf1.s +++ b/test/ELF/icf1.s @@ -1,7 +1,7 @@ # 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: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s # CHECK: selected .text.f1 # CHECK: removed .text.f2 diff --git a/test/ELF/icf2.s b/test/ELF/icf2.s index be595112b7e7..fd0a311cbd1d 100644 --- a/test/ELF/icf2.s +++ b/test/ELF/icf2.s @@ -2,7 +2,7 @@ # 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 +# RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose 2>&1 | FileCheck %s # CHECK: selected .text.f1 # CHECK: removed .text.f2 diff --git a/test/ELF/icf3.s b/test/ELF/icf3.s index 9f39ff6c7477..40067cefb200 100644 --- a/test/ELF/icf3.s +++ b/test/ELF/icf3.s @@ -2,7 +2,7 @@ # 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 +# RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose 2>&1 | FileCheck %s # CHECK-NOT: Selected .text.f1 # CHECK-NOT: Selected .text.f2 diff --git a/test/ELF/icf4.s b/test/ELF/icf4.s index 08830c8e503c..b7f40e805733 100644 --- a/test/ELF/icf4.s +++ b/test/ELF/icf4.s @@ -1,7 +1,7 @@ # 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: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s # CHECK-NOT: Selected .text.f1 # CHECK-NOT: Selected .text.f2 diff --git a/test/ELF/icf5.s b/test/ELF/icf5.s index 952fe3601a4d..749cc5e923a0 100644 --- a/test/ELF/icf5.s +++ b/test/ELF/icf5.s @@ -1,7 +1,7 @@ # 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: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s # CHECK-NOT: Selected .text.f1 # CHECK-NOT: Selected .text.f2 diff --git a/test/ELF/icf6.s b/test/ELF/icf6.s index ecb62fee2a0c..6420868523bf 100644 --- a/test/ELF/icf6.s +++ b/test/ELF/icf6.s @@ -1,7 +1,7 @@ # 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: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s # CHECK-NOT: Selected .text.f1 # CHECK-NOT: Selected .text.f2 diff --git a/test/ELF/icf7.s b/test/ELF/icf7.s index 8504ca2ac610..00fca793aeea 100644 --- a/test/ELF/icf7.s +++ b/test/ELF/icf7.s @@ -1,7 +1,7 @@ # 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: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s # RUN: llvm-objdump -t %t2 | FileCheck -check-prefix=ALIGN %s # CHECK: selected .text.f1 diff --git a/test/ELF/icf9.s b/test/ELF/icf9.s index c5a532915cc7..de6db60f9684 100644 --- a/test/ELF/icf9.s +++ b/test/ELF/icf9.s @@ -2,19 +2,31 @@ ### Make sure that we do not merge data. # 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: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s +# RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=SEC %s -# CHECK-NOT: selected .data.d1 -# CHECK-NOT: selected .data.d2 +# SEC: .rodata PROGBITS 0000000000200120 000120 000002 00 A 0 0 1 + +# CHECK-NOT: selected .rodata.d1 +# CHECK-NOT: selected .rodata.d2 + +# We do merge rodata if passed --icf-data +# RUN: ld.lld %t -o %t2 --icf=all --verbose --icf-data 2>&1 | FileCheck --check-prefix=DATA %s +# RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=DATA-SEC %s + +# DATA: selected .rodata.d1 +# DATA: removed .rodata.d2 + +# DATA-SEC: .rodata PROGBITS 0000000000200120 000120 000001 00 A 0 0 1 .globl _start, d1, d2 _start: ret -.section .data.f1, "a" +.section .rodata.d1, "a" d1: .byte 1 -.section .data.f2, "a" +.section .rodata.d2, "a" d2: .byte 1 diff --git a/test/ELF/image-base.s b/test/ELF/image-base.s index a6d160744b70..eb79acdced81 100644 --- a/test/ELF/image-base.s +++ b/test/ELF/image-base.s @@ -6,6 +6,9 @@ # RUN: ld.lld -image-base=0x1000 -z max-page-size=0x2000 %t -o %t1 2>&1 | FileCheck --check-prefix=WARN %s # WARN: warning: -image-base: address isn't multiple of page size: 0x1000 +# Check alias. +# RUN: ld.lld -image-base 0x1000000 %t -o %t1 +# RUN: llvm-readobj -program-headers %t1 | FileCheck %s .global _start _start: @@ -41,8 +44,8 @@ _start: # CHECK-NEXT: Offset: 0x1000 # CHECK-NEXT: VirtualAddress: 0x1001000 # CHECK-NEXT: PhysicalAddress: 0x1001000 -# CHECK-NEXT: FileSize: 1 -# CHECK-NEXT: MemSize: 1 +# CHECK-NEXT: FileSize: 4096 +# CHECK-NEXT: MemSize: 4096 # CHECK-NEXT: Flags [ (0x5) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_X (0x1) diff --git a/test/ELF/init_fini_priority.s b/test/ELF/init_fini_priority.s index 84e5dc35e9d2..b10b925063e5 100644 --- a/test/ELF/init_fini_priority.s +++ b/test/ELF/init_fini_priority.s @@ -1,34 +1,46 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: llvm-objdump -section-headers %t | FileCheck %s --check-prefix=OBJ // RUN: ld.lld %t -o %t.exe // RUN: llvm-objdump -s %t.exe | FileCheck %s // REQUIRES: x86 +// OBJ: 3 .init_array +// OBJ-NEXT: 4 .init_array.100 +// OBJ-NEXT: 5 .init_array.5 +// OBJ-NEXT: 6 .init_array +// OBJ-NEXT: 7 .init_array +// OBJ-NEXT: 8 .fini_array +// OBJ-NEXT: 9 .fini_array.100 +// OBJ-NEXT: 10 .fini_array.5 +// OBJ-NEXT: 11 .fini_array +// OBJ-NEXT: 12 .fini_array + .globl _start _start: nop -.section .init_array, "aw", @init_array +.section .init_array, "aw", @init_array, unique, 0 .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 +.section .init_array, "aw", @init_array, unique, 1 .byte 4 -.section .init_array, "aw", @init_array +.section .init_array, "aw", @init_array, unique, 2 .byte 5 -.section .fini_array, "aw", @fini_array +.section .fini_array, "aw", @fini_array, unique, 0 .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 +.section .fini_array, "aw", @fini_array, unique, 1 .byte 0x14 -.section .fini_array, "aw", @fini_array +.section .fini_array, "aw", @fini_array, unique, 2 .byte 0x15 // CHECK: Contents of section .init_array: diff --git a/test/ELF/invalid-linkerscript.test b/test/ELF/invalid-linkerscript.test index 280686eff41b..f9fb8478251f 100644 --- a/test/ELF/invalid-linkerscript.test +++ b/test/ELF/invalid-linkerscript.test @@ -45,7 +45,7 @@ # 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 find linker script /no/such/file # ERR7: cannot open no-such-file: # RUN: echo "OUTPUT_FORMAT(x y z)" > %t8 diff --git a/test/ELF/invalid-local-symbol-in-dso.s b/test/ELF/invalid-local-symbol-in-dso.s new file mode 100644 index 000000000000..dc6bff7bd792 --- /dev/null +++ b/test/ELF/invalid-local-symbol-in-dso.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 + +# We used to crash on this +# RUN: ld.lld %p/Inputs/local-symbol-in-dso.so -o %t 2>&1 | \ +# RUN: FileCheck -check-prefix=WARN %s +# WARN: found local symbol 'foo' in global part of symbol table in file {{.*}}local-symbol-in-dso.so + +# RUN: llvm-mc %s -o %t.o -filetype=obj -triple x86_64-pc-linux +# RUN: not ld.lld %t.o %p/Inputs/local-symbol-in-dso.so -o %t + +.globl main +main: + movq foo@GOTTPOFF(%rip), %rax diff --git a/test/ELF/invalid-undef-section-symbol.test b/test/ELF/invalid-undef-section-symbol.test new file mode 100644 index 000000000000..f634d6ad8c63 --- /dev/null +++ b/test/ELF/invalid-undef-section-symbol.test @@ -0,0 +1,27 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: not ld.lld -r %t.o -o %2.o 2>&1 | FileCheck %s + +# We used to crash at this. +# CHECK: STT_SECTION symbol should be defined + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + - Name: .rela.text + Type: SHT_RELA + AddressAlign: 0x0000000000000008 + Info: .text + Relocations: + - Offset: 0x0000000000000000 + Symbol: .text + Type: R_X86_64_NONE +Symbols: + Local: + - Name: .text + Type: STT_SECTION diff --git a/test/ELF/invalid/Inputs/section-index2.elf b/test/ELF/invalid/Inputs/section-index2.elf Binary files differdeleted file mode 100644 index 5d842880b375..000000000000 --- a/test/ELF/invalid/Inputs/section-index2.elf +++ /dev/null diff --git a/test/ELF/invalid/invalid-debug-relocations.test b/test/ELF/invalid/invalid-debug-relocations.test index 75e41d18514f..9c86b6743093 100644 --- a/test/ELF/invalid/invalid-debug-relocations.test +++ b/test/ELF/invalid/invalid-debug-relocations.test @@ -2,8 +2,7 @@ # RUN: yaml2obj %s -o %t.o # RUN: not ld.lld -gdb-index %t.o -o %t.exe 2>&1 | FileCheck %s -# CHECK: error: {{.*}}.o: error parsing DWARF data: -# CHECK-NEXT: >>> failed to compute relocation: Unknown, Invalid data was encountered while parsing the file +# CHECK: error: {{.*}}invalid-debug-relocations.test.tmp.o:(.debug_info+0x0): has non-ABS relocation Unknown (255) against symbol '_start' !ELF FileHeader: diff --git a/test/ELF/invalid/invalid-elf.test b/test/ELF/invalid/invalid-elf.test index e03450ed289c..8be0437c0680 100644 --- a/test/ELF/invalid/invalid-elf.test +++ b/test/ELF/invalid/invalid-elf.test @@ -20,10 +20,6 @@ # RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s # INVALID-SECTION-INDEX-LLD: invalid section index -## section-index2.elf has local symbol with incorrect section index. -# RUN: not ld.lld %p/Inputs/section-index2.elf -o %t2 2>&1 | \ -# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s - # RUN: not ld.lld %p/Inputs/multiple-eh-relocs.elf -o %t2 2>&1 | \ # RUN: FileCheck --check-prefix=INVALID-EH-RELOCS %s # INVALID-EH-RELOCS: multiple relocation sections to one section are not supported diff --git a/test/ELF/invalid/invalid-relocation-x64.test b/test/ELF/invalid/invalid-relocation-x64.test index 9b8ebb59e474..a9b316415697 100644 --- a/test/ELF/invalid/invalid-relocation-x64.test +++ b/test/ELF/invalid/invalid-relocation-x64.test @@ -1,7 +1,10 @@ -# RUN: yaml2obj %s -o %t.o -# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s -# CHECK: {{.*}}.o: unknown relocation type: Unknown (152) -# CHECK: {{.*}}.o: unknown relocation type: Unknown (153) +# REQUIRES: x86 +# RUN: yaml2obj %s -o %t1.o +# RUN: echo ".global foo; foo:" > %t2.s +# RUN: llvm-mc %t2.s -o %t2.o -filetype=obj -triple x86_64-pc-linux +# RUN: not ld.lld %t1.o %t2.o -o /dev/null 2>&1 | FileCheck %s +# CHECK: error: unrecognized reloc 152 +# CHECK: error: unrecognized reloc 153 !ELF FileHeader: @@ -20,8 +23,11 @@ Sections: Info: .text Relocations: - Offset: 0x0000000000000000 - Symbol: '' + Symbol: foo Type: 0x98 - Offset: 0x0000000000000000 - Symbol: '' + Symbol: foo Type: 0x99 +Symbols: + Global: + - Name: foo diff --git a/test/ELF/libsearch.s b/test/ELF/libsearch.s index 32be866a66a9..d21baf9dd95f 100644 --- a/test/ELF/libsearch.s +++ b/test/ELF/libsearch.s @@ -60,6 +60,7 @@ // Check long forms as well // RUN: ld.lld -o %t3 %t.o --library-path=%t.dir --library=ls +// RUN: ld.lld -o %t3 %t.o --library-path %t.dir --library ls // Should not search for dynamic libraries if -Bstatic is specified // RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -lls diff --git a/test/ELF/linkerscript/Inputs/common-filespec1.s b/test/ELF/linkerscript/Inputs/common-filespec1.s new file mode 100644 index 000000000000..9e25d1291354 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/common-filespec1.s @@ -0,0 +1,2 @@ +.comm common_uniq_1,8,8 +.comm common_multiple,16,8 diff --git a/test/ELF/linkerscript/Inputs/common-filespec2.s b/test/ELF/linkerscript/Inputs/common-filespec2.s new file mode 100644 index 000000000000..ceac01793599 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/common-filespec2.s @@ -0,0 +1,2 @@ +.comm common_uniq_2,16,16 +.comm common_multiple,32,8 diff --git a/test/ELF/linkerscript/Inputs/copy-rel-symbol-value.s b/test/ELF/linkerscript/Inputs/copy-rel-symbol-value.s new file mode 100644 index 000000000000..b10a698eac18 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/copy-rel-symbol-value.s @@ -0,0 +1,5 @@ + .global bar + .type bar, @object + .size bar, 8 +bar: + .quad 0 diff --git a/test/ELF/linkerscript/Inputs/provide-shared.s b/test/ELF/linkerscript/Inputs/provide-shared.s new file mode 100644 index 000000000000..5ea4e952a766 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/provide-shared.s @@ -0,0 +1,5 @@ + .global foo + .size foo, 8 + .type foo, @object +foo: + .quad 42 diff --git a/test/ELF/linkerscript/Inputs/symbol-reserved.script b/test/ELF/linkerscript/Inputs/symbol-reserved.script new file mode 100644 index 000000000000..269bb120de95 --- /dev/null +++ b/test/ELF/linkerscript/Inputs/symbol-reserved.script @@ -0,0 +1,5 @@ +SECTIONS +{ + .text : { *(.text) } + PROVIDE_HIDDEN(_end = .); +} diff --git a/test/ELF/linkerscript/absolute2.s b/test/ELF/linkerscript/absolute2.s new file mode 100644 index 000000000000..513468d25814 --- /dev/null +++ b/test/ELF/linkerscript/absolute2.s @@ -0,0 +1,17 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: echo "SECTIONS { .text : { *(.text) } foo = ABSOLUTE(_start) + _start; };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -t %t | FileCheck %s + +# RUN: echo "SECTIONS { .text : { *(.text) } foo = _start + ABSOLUTE(_start); };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -t %t | FileCheck %s + +# CHECK: 0000000000000001 .text 00000000 _start +# CHECK: 0000000000000002 .text 00000000 foo + + .global _start + nop +_start: diff --git a/test/ELF/linkerscript/align-section-offset.s b/test/ELF/linkerscript/align-section-offset.s new file mode 100644 index 000000000000..9c1603a19853 --- /dev/null +++ b/test/ELF/linkerscript/align-section-offset.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { .foo : ALIGN(2M) { *(.foo) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o -shared +# RUN: llvm-readelf -S -l %t | FileCheck %s + +# CHECK: .foo PROGBITS 0000000000200000 200000 000008 00 WA 0 0 2097152 +# CHECK: LOAD 0x200000 0x0000000000200000 0x0000000000200000 {{.*}} RW 0x200000 + + .section .foo, "aw" + .quad 42 diff --git a/test/ELF/linkerscript/align-section.s b/test/ELF/linkerscript/align-section.s new file mode 100644 index 000000000000..d26f15c87329 --- /dev/null +++ b/test/ELF/linkerscript/align-section.s @@ -0,0 +1,6 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { .foo : ALIGN(2M) { } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o -shared + +# We would crash if an empty section had an ALIGN. diff --git a/test/ELF/linkerscript/align.s b/test/ELF/linkerscript/align.s index 357f54ce1ca5..99e7382daa59 100644 --- a/test/ELF/linkerscript/align.s +++ b/test/ELF/linkerscript/align.s @@ -66,6 +66,51 @@ # SYMBOLS-NEXT: 0000000000011000 .bbb 00000000 __start_bbb # SYMBOLS-NEXT: 0000000000012000 .bbb 00000000 __end_bbb +## Check that ALIGN zero do nothing and does not crash #1. +# RUN: echo "SECTIONS { . = ALIGN(0x123, 0); .aaa : { *(.aaa) } }" > %t.script +# RUN: ld.lld -o %t4 --script %t.script %t +# RUN: llvm-objdump -section-headers %t4 | FileCheck %s -check-prefix=ZERO + +# ZERO: Sections: +# ZERO-NEXT: Idx Name Size Address Type +# ZERO-NEXT: 0 00000000 0000000000000000 +# ZERO-NEXT: 1 .aaa 00000008 0000000000000123 DATA + +## Check that ALIGN zero do nothing and does not crash #2. +# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0); .aaa : { *(.aaa) } }" > %t.script +# RUN: ld.lld -o %t5 --script %t.script %t +# RUN: llvm-objdump -section-headers %t5 | FileCheck %s -check-prefix=ZERO + +## Test we fail gracefuly when alignment value is not a power of 2 (#1). +# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(0x123, 3); .aaa : { *(.aaa) } }" > %t.script +# RUN: not ld.lld -o %t6 --script %t.script %t 2>&1 | FileCheck -check-prefix=ERR %s +# ERR: {{.*}}.script:1: alignment must be power of 2 + +## Test we fail gracefuly when alignment value is not a power of 2 (#2). +# RUN: echo "SECTIONS { . = 0x123; . = ALIGN(3); .aaa : { *(.aaa) } }" > %t.script +# RUN: not ld.lld -o %t7 --script %t.script %t 2>&1 | FileCheck -check-prefix=ERR %s + +# RUN: echo "SECTIONS { \ +# RUN: . = 0xff8; \ +# RUN: .aaa : { \ +# RUN: *(.aaa) \ +# RUN: foo = ALIGN(., 0x100); \ +# RUN: bar = .; \ +# RUN: zed1 = ALIGN(., 0x100) + 1; \ +# RUN: zed2 = ALIGN(., 0x100) - 1; \ +# RUN: } \ +# RUN: .bbb : { *(.bbb); } \ +# RUN: .ccc : { *(.ccc); } \ +# RUN: .text : { *(.text); } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=OFFSET %s + +# OFFSET: 0000000000001000 .aaa 00000000 foo +# OFFSET: 0000000000001000 .aaa 00000000 bar +# OFFSET: 0000000000001001 .aaa 00000000 zed1 +# OFFSET: 0000000000000fff .aaa 00000000 zed2 + .global _start _start: nop diff --git a/test/ELF/linkerscript/arm-exidx-order.s b/test/ELF/linkerscript/arm-exidx-order.s new file mode 100644 index 000000000000..1ff1711e60be --- /dev/null +++ b/test/ELF/linkerscript/arm-exidx-order.s @@ -0,0 +1,19 @@ +# REQUIRES: arm +# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \ +# RUN: .ARM.exidx : { *(.ARM.exidx*) } \ +# RUN: .foo : { _foo = 0; } }" > %t.script +# RUN: ld.lld -T %t.script %t.o -shared -o %t.so +# RUN: llvm-readobj -s %t.so | FileCheck %s + +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .foo +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] + +.fnstart +.cantunwind +.fnend diff --git a/test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s b/test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s new file mode 100644 index 000000000000..8cee22f7fed2 --- /dev/null +++ b/test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s @@ -0,0 +1,24 @@ +# REQUIRES: arm +# RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: .ARM.exidx 0x1000 : { *(.ARM.exidx*) foo = .; } \ +# RUN: .text 0x2000 : { *(.text*) } \ +# RUN: }" > %t.script +## We used to crash if the last output section command for .ARM.exidx +## was anything but an input section description. +# RUN: ld.lld --no-merge-exidx-entries -T %t.script %t.o -shared -o %t.so +# RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s + + .syntax unified + .text + .global _start +_start: + .fnstart + .cantunwind + bx lr + .fnend + +// CHECK: Contents of section .ARM.exidx: +// 1000 + 1000 = 0x2000 = _start +// 1008 + 0ffc = 0x2004 = _start + sizeof(_start) +// CHECK-NEXT: 1000 00100000 01000000 fc0f0000 01000000 diff --git a/test/ELF/linkerscript/at-addr.s b/test/ELF/linkerscript/at-addr.s index 0eddf3d9e3fb..f0ab989c52c7 100644 --- a/test/ELF/linkerscript/at-addr.s +++ b/test/ELF/linkerscript/at-addr.s @@ -9,10 +9,6 @@ # RUN: llvm-readobj -program-headers %t2 | FileCheck %s # CHECK: Type: PT_LOAD -# CHECK-NEXT: Offset: 0x0 -# CHECK-NEXT: VirtualAddress: 0x0 -# CHECK-NEXT: PhysicalAddress: 0x0 -# CHECK: Type: PT_LOAD # CHECK-NEXT: Offset: 0x1000 # CHECK-NEXT: VirtualAddress: 0x1000 # CHECK-NEXT: PhysicalAddress: 0xB00 diff --git a/test/ELF/linkerscript/at.s b/test/ELF/linkerscript/at.s index 26441f1ffd9e..430e68a53d98 100644 --- a/test/ELF/linkerscript/at.s +++ b/test/ELF/linkerscript/at.s @@ -13,31 +13,6 @@ # 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: -# CHECK-NEXT: MemSize: -# 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: -# CHECK-NEXT: MemSize: -# CHECK-NEXT: Flags [ -# CHECK-NEXT: PF_R -# CHECK-NEXT: PF_X -# CHECK-NEXT: ] -# CHECK-NEXT: Alignment: -# CHECK-NEXT: } -# CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD # CHECK-NEXT: Offset: 0x1000 # CHECK-NEXT: VirtualAddress: 0x1000 diff --git a/test/ELF/linkerscript/common-exclude.s b/test/ELF/linkerscript/common-exclude.s new file mode 100644 index 000000000000..ef2d51b1b229 --- /dev/null +++ b/test/ELF/linkerscript/common-exclude.s @@ -0,0 +1,86 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfile0.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec1.s -o %tfile1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec2.s -o %tfile2.o +# RUN: echo "SECTIONS { .common.incl : { *(EXCLUDE_FILE (*file2.o) COMMON) } .common.excl : { *(COMMON) } }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %tfile0.o %tfile1.o %tfile2.o +# RUN: llvm-readobj -s -t %t1 | FileCheck %s + +# Commons from file0 and file1 are not excluded, so they must be in .common.incl +# Commons from file2 are excluded from the first rule and should be caught by +# the second in .common.excl +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common.incl +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x8 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 16 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common.excl +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x20 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 48 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 16 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_multiple +# CHECK-NEXT: Value: 0x20 +# CHECK-NEXT: Size: 32 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common.excl +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_0 +# CHECK-NEXT: Value: 0x8 +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common.incl +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_1 +# CHECK-NEXT: Value: 0x10 +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common.incl +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_2 +# CHECK-NEXT: Value: 0x40 +# CHECK-NEXT: Size: 16 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common.excl +# CHECK-NEXT: } + +.globl _start +_start: + jmp _start + +.comm common_uniq_0,4,4 +.comm common_multiple,8,8 diff --git a/test/ELF/linkerscript/common-filespec.s b/test/ELF/linkerscript/common-filespec.s new file mode 100644 index 000000000000..25bb486ed445 --- /dev/null +++ b/test/ELF/linkerscript/common-filespec.s @@ -0,0 +1,105 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfile0.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec1.s -o %tfile1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/common-filespec2.s -o %tfile2.o +# RUN: echo "SECTIONS { .common_0 : { *file0.o(COMMON) } .common_1 : { *file1.o(COMMON) } .common_2 : { *file2.o(COMMON) } }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %tfile0.o %tfile1.o %tfile2.o +# RUN: llvm-readobj -s -t %t1 | FileCheck %s + +# Make sure all 3 sections are allocated and they have sizes and alignments +# corresponding to the commons assigned to them +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common_0 +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x4 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common_1 +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x8 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .common_2 +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10 +# CHECK-NEXT: Offset: 0x +# CHECK-NEXT: Size: 48 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 16 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } + +# Commons with unique name in each file must be assigned to that file's section. +# For a common with multiple definitions, the largest one wins and it must be +# assigned to the section from the file which provided the winning def +# CHECK: Symbol { +# CHECK: Name: common_multiple +# CHECK-NEXT: Value: 0x10 +# CHECK-NEXT: Size: 32 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common_2 +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_0 +# CHECK-NEXT: Value: 0x4 +# CHECK-NEXT: Size: 4 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common_0 +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_1 +# CHECK-NEXT: Value: 0x8 +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common_1 +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: common_uniq_2 +# CHECK-NEXT: Value: 0x30 +# CHECK-NEXT: Size: 16 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .common_2 +# CHECK-NEXT: } + +.globl _start +_start: + jmp _start + +.comm common_uniq_0,4,4 +.comm common_multiple,8,8 diff --git a/test/ELF/linkerscript/common.s b/test/ELF/linkerscript/common.s index 2e5972d52379..52f0371526c4 100644 --- a/test/ELF/linkerscript/common.s +++ b/test/ELF/linkerscript/common.s @@ -4,8 +4,6 @@ # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-readobj -s -t %t1 | FileCheck %s -# q2 alignment is greater than q1, so it should have smaller offset -# because of sorting # CHECK: Section { # CHECK: Index: # CHECK: Name: .common @@ -16,7 +14,7 @@ # CHECK-NEXT: ] # CHECK-NEXT: Address: 0x200 # CHECK-NEXT: Offset: 0x -# CHECK-NEXT: Size: 256 +# CHECK-NEXT: Size: 384 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 256 @@ -24,7 +22,7 @@ # CHECK-NEXT: } # CHECK: Symbol { # CHECK: Name: q1 -# CHECK-NEXT: Value: 0x280 +# CHECK-NEXT: Value: 0x200 # CHECK-NEXT: Size: 128 # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: Object @@ -33,7 +31,7 @@ # CHECK-NEXT: } # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: q2 -# CHECK-NEXT: Value: 0x200 +# CHECK-NEXT: Value: 0x300 # CHECK-NEXT: Size: 128 # CHECK-NEXT: Binding: Global # CHECK-NEXT: Type: Object diff --git a/test/ELF/linkerscript/compress-debug-sections.s b/test/ELF/linkerscript/compress-debug-sections.s index 6798a217b5ac..5e8cd004068d 100644 --- a/test/ELF/linkerscript/compress-debug-sections.s +++ b/test/ELF/linkerscript/compress-debug-sections.s @@ -10,12 +10,12 @@ # RUN: echo "SECTIONS { }" > %t.script # RUN: ld.lld -O0 %t1.o %t2.o %t.script -o %t1 --compress-debug-sections=zlib -# RUN: llvm-dwarfdump %t1 | FileCheck %s +# RUN: llvm-dwarfdump -a %t1 | FileCheck %s # RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS # RUN: echo "SECTIONS { .debug_str 0 : { *(.debug_str) } }" > %t2.script # RUN: ld.lld -O0 %t1.o %t2.o %t2.script -o %t2 --compress-debug-sections=zlib -# RUN: llvm-dwarfdump %t2 | FileCheck %s +# RUN: llvm-dwarfdump -a %t2 | FileCheck %s # RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS # CHECK: .debug_str contents: diff --git a/test/ELF/linkerscript/copy-rel-symbol-value-err.s b/test/ELF/linkerscript/copy-rel-symbol-value-err.s new file mode 100644 index 000000000000..f134edbb1d0c --- /dev/null +++ b/test/ELF/linkerscript/copy-rel-symbol-value-err.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/copy-rel-symbol-value.s -o %t2.o +# RUN: ld.lld %t2.o -o %t2.so -shared +# RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; foo = bar; }" > %t.script +# RUN: not ld.lld %t.o %t2.so --script %t.script -o %t 2>&1 | FileCheck %s + +# CHECK: symbol not found: bar + +.global _start +_start: +.quad bar@got diff --git a/test/ELF/linkerscript/copy-rel-symbol-value.s b/test/ELF/linkerscript/copy-rel-symbol-value.s new file mode 100644 index 000000000000..64627b42f885 --- /dev/null +++ b/test/ELF/linkerscript/copy-rel-symbol-value.s @@ -0,0 +1,27 @@ +# 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/copy-rel-symbol-value.s -o %t2.o +# RUN: ld.lld %t2.o -o %t2.so -shared +# RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; foo = bar; }" > %t.script +# RUN: ld.lld %t.o %t2.so --script %t.script -o %t +# RUN: llvm-readobj -t %t | FileCheck %s + +# CHECK: Name: bar +# CHECK-NEXT: Value: 0x[[VAL:.*]] +# CHECK-NEXT: Size: 8 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .bss.rel.ro + +# CHECK: Name: foo +# CHECK-NEXT: Value: 0x[[VAL]] +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .bss.rel.ro + +.global _start +_start: +.quad bar diff --git a/test/ELF/linkerscript/data-segment-relro.s b/test/ELF/linkerscript/data-segment-relro.s index 7f69319dde7a..e835f42e22c6 100644 --- a/test/ELF/linkerscript/data-segment-relro.s +++ b/test/ELF/linkerscript/data-segment-relro.s @@ -19,9 +19,9 @@ ## With relro or without DATA_SEGMENT_RELRO_END just aligns to ## page boundary. -# RUN: ld.lld -z norelro %t1.o %t2.so --script %t.script -o %t +# RUN: ld.lld --hash-style=sysv -z norelro %t1.o %t2.so --script %t.script -o %t # RUN: llvm-readobj -s %t | FileCheck %s -# RUN: ld.lld -z relro %t1.o %t2.so --script %t.script -o %t2 +# RUN: ld.lld --hash-style=sysv -z relro %t1.o %t2.so --script %t.script -o %t2 # RUN: llvm-readobj -s %t2 | FileCheck %s # CHECK: Section { diff --git a/test/ELF/linkerscript/diagnostic.s b/test/ELF/linkerscript/diagnostic.s index bd1ebd01b5d2..af185729c430 100644 --- a/test/ELF/linkerscript/diagnostic.s +++ b/test/ELF/linkerscript/diagnostic.s @@ -50,9 +50,9 @@ # RUN: echo ".temp : { *(.temp) } }" >> %t.script # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ # RUN: FileCheck -check-prefix=ERR6 -strict-whitespace %s -# ERR6: error: {{.*}}.script:1: -# ERR6-NEXT: error: {{.*}}.script:1: UNKNOWN_TAG { -# ERR6-NEXT: error: {{.*}}.script:1: ^ +# ERR6: error: {{.*}}.script:1: unknown directive: UNKNOWN_TAG +# ERR6-NEXT: >>> UNKNOWN_TAG { +# ERR6-NEXT: >>> ^ ## One more check that text of lines and pointer to 'bad' token are working ok. # RUN: echo "SECTIONS {" > %t.script @@ -62,8 +62,8 @@ # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ # RUN: FileCheck -check-prefix=ERR7 -strict-whitespace %s # ERR7: error: {{.*}}.script:4: malformed number: .temp -# ERR7-NEXT: error: {{.*}}.script:4: boom .temp : { *(.temp) } } -# ERR7-NEXT: error: {{.*}}.script:4: ^ +# ERR7-NEXT: >>> boom .temp : { *(.temp) } } +# ERR7-NEXT: >>> ^ ## Check tokenize() error # RUN: echo "SECTIONS {}" > %t.script @@ -89,8 +89,8 @@ # RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \ # RUN: FileCheck -check-prefix=ERR10 -strict-whitespace %s # ERR10: error: {{.*}}.script.inc:4: malformed number: .temp -# ERR10-NEXT: error: {{.*}}.script.inc:4: boom .temp : { *(.temp) } } -# ERR10-NEXT: error: {{.*}}.script.inc:4: ^ +# ERR10-NEXT: >>> boom .temp : { *(.temp) } } +# ERR10-NEXT: >>> ^ ## Check error reporting in script with INCLUDE directive. # RUN: echo "SECTIONS {" > %t.script.inc diff --git a/test/ELF/linkerscript/discard-section-err.s b/test/ELF/linkerscript/discard-section-err.s index 5d9955545d92..8ad5b486cb39 100644 --- a/test/ELF/linkerscript/discard-section-err.s +++ b/test/ELF/linkerscript/discard-section-err.s @@ -21,3 +21,5 @@ # RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \ # RUN: FileCheck -check-prefix=DYNSTR %s # DYNSTR: discarding .dynstr section is not allowed + +.comm foo,4,4 diff --git a/test/ELF/linkerscript/early-assign-symbol.s b/test/ELF/linkerscript/early-assign-symbol.s index 0626e66e6fb6..5f6117863666 100644 --- a/test/ELF/linkerscript/early-assign-symbol.s +++ b/test/ELF/linkerscript/early-assign-symbol.s @@ -1,14 +1,28 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: echo "SECTIONS { aaa = 1 + ABSOLUTE(foo - 1); .text : { *(.text*) } }" > %t1.script -# RUN: not ld.lld -o %t --script %t1.script %t.o 2>&1 | FileCheck %s - -# RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text : { *(.text*) } }" > %t2.script -# RUN: not ld.lld -o %t --script %t2.script %t.o 2>&1 | FileCheck %s +# RUN: echo "SECTIONS { aaa = foo | 1; .text : { *(.text*) } }" > %t3.script +# RUN: not ld.lld -o %t --script %t3.script %t.o 2>&1 | FileCheck %s # CHECK: error: {{.*}}.script:1: unable to evaluate expression: input section .text has no output section assigned +# Simple cases that we can handle. + +# RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text : { *(.text*) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s + +# RUN: echo "SECTIONS { aaa = 1 + ABSOLUTE(foo - 1); .text : { *(.text*) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s + +# RUN: echo "SECTIONS { aaa = ABSOLUTE(foo); .text : { *(.text*) } }" > %t4.script +# RUN: ld.lld -o %t --script %t4.script %t.o +# RUN: llvm-objdump -t %t | FileCheck --check-prefix=VAL %s + +# VAL: 0000000000000000 .text 00000000 foo +# VAL: 0000000000000000 *ABS* 00000000 aaa + .section .text .globl foo foo: diff --git a/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s index 54c0cc74d394..817e458fa5ef 100644 --- a/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s +++ b/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s @@ -12,7 +12,7 @@ # RUN: }" > %t.script # RUN: not ld.lld %t.o -T %t.script -o %t 2>&1 | FileCheck %s -# CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range +# CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range: 64424443872 is not in [-2147483648, 2147483647] .text .globl _start diff --git a/test/ELF/linkerscript/emit-reloc-section-names.s b/test/ELF/linkerscript/emit-reloc-section-names.s new file mode 100644 index 000000000000..8661ff060a79 --- /dev/null +++ b/test/ELF/linkerscript/emit-reloc-section-names.s @@ -0,0 +1,22 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { .text.zed : { *(.text.foo) } \ +# RUN: .text.qux : { *(.text.bar) } }" > %t.script +# RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t +# RUN: llvm-objdump -section-headers %t | FileCheck %s + +## Check we name relocation sections in according to +## their target sections names. + +# CHECK: .text.zed +# CHECK: .text.qux +# CHECK: .rela.text.zed +# CHECK: .rela.text.qux + +.section .text.foo,"ax" +foo: + mov $bar, %rax + +.section .text.bar,"ax" +bar: + mov $foo, %rax diff --git a/test/ELF/linkerscript/emit-reloc.s b/test/ELF/linkerscript/emit-reloc.s index 725f314a9772..2fe127af8590 100644 --- a/test/ELF/linkerscript/emit-reloc.s +++ b/test/ELF/linkerscript/emit-reloc.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "SECTIONS { .rela.dyn : { *(.rela.data) } }" > %t.script -# RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t.so -shared +# RUN: ld.lld --hash-style=sysv -T %t.script --emit-relocs %t.o -o %t.so -shared # RUN: llvm-readobj -r %t.so | FileCheck %s .data diff --git a/test/ELF/linkerscript/emit-relocs-multiple.s b/test/ELF/linkerscript/emit-relocs-multiple.s index b04ca1be7a15..dcf40b3d9312 100644 --- a/test/ELF/linkerscript/emit-relocs-multiple.s +++ b/test/ELF/linkerscript/emit-relocs-multiple.s @@ -5,7 +5,7 @@ # RUN: llvm-readobj -r %t1 | FileCheck %s # CHECK: Relocations [ -# CHECK-NEXT: Section {{.*}} .rela.foo { +# CHECK-NEXT: Section {{.*}} .rela.zed { # CHECK-NEXT: 0x1 R_X86_64_32 .zed 0x0 # CHECK-NEXT: 0x6 R_X86_64_32 .zed 0x5 # CHECK-NEXT: } diff --git a/test/ELF/linkerscript/extend-pt-load.s b/test/ELF/linkerscript/extend-pt-load.s index f9a77c8c12bf..72740f1092ee 100644 --- a/test/ELF/linkerscript/extend-pt-load.s +++ b/test/ELF/linkerscript/extend-pt-load.s @@ -15,7 +15,7 @@ # RUN: . = ALIGN(0x1000); \ # RUN: .data.rel.ro : { *(.data.rel.ro) } \ # RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t.o -shared # RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck --check-prefix=CHECK1 %s # CHECK1: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX @@ -33,18 +33,17 @@ # RUN: .hash : { } \ # RUN: .dynstr : { } \ # RUN: .text : { *(.text) } \ -# RUN: . = ALIGN(0x1000); \ -# RUN: bar : { HIDDEN(bar_sym = .); } \ +# RUN: bar : { . = ALIGN(0x1000); } \ # RUN: .data.rel.ro : { *(.data.rel.ro) } \ # RUN: }" > %t.script -# RUN: ld.lld -o %t2 --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t2 --script %t.script %t.o -shared # RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck --check-prefix=CHECK2 %s # CHECK2: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX -# CHECK2-NEXT: bar PROGBITS 0000000000001000 001000 000000 00 AX +# CHECK2-NEXT: bar NOBITS 00000000000001bd 0001bd 000e43 00 AX # CHECK2-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA -# CHECK2: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001000 0x001000 R E +# CHECK2: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x001000 R E # CHECK2-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW # If the current behavior becomes a problem we should consider just moving the commands out @@ -60,7 +59,7 @@ # RUN: HIDDEN(bar_sym = .); \ # RUN: .data.rel.ro : { *(.data.rel.ro) } \ # RUN: }" > %t.script -# RUN: ld.lld -o %t3 --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t3 --script %t.script %t.o -shared # RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck --check-prefix=CHECK1 %s nop diff --git a/test/ELF/linkerscript/filename-spec.s b/test/ELF/linkerscript/filename-spec.s index d4bc495efb81..5f075a8e5005 100644 --- a/test/ELF/linkerscript/filename-spec.s +++ b/test/ELF/linkerscript/filename-spec.s @@ -33,24 +33,63 @@ # RUN: ld.lld -o %t4 --script %t4.script %tfirst.o %tsecond.o # RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=SECONDFIRST %s -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %T/filename-spec1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o filename-spec1.o # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ -# RUN: %p/Inputs/filename-spec.s -o %T/filename-spec2.o +# RUN: %p/Inputs/filename-spec.s -o filename-spec2.o # RUN: echo "SECTIONS { .foo : { \ # RUN: filename-spec2.o(.foo) \ # RUN: filename-spec1.o(.foo) } }" > %t5.script # RUN: ld.lld -o %t5 --script %t5.script \ -# RUN: %T/filename-spec1.o %T/filename-spec2.o +# RUN: filename-spec1.o filename-spec2.o # RUN: llvm-objdump -s %t5 | FileCheck --check-prefix=SECONDFIRST %s # RUN: echo "SECTIONS { .foo : { \ # RUN: filename-spec1.o(.foo) \ # RUN: filename-spec2.o(.foo) } }" > %t6.script # RUN: ld.lld -o %t6 --script %t6.script \ -# RUN: %T/filename-spec1.o %T/filename-spec2.o +# RUN: filename-spec1.o filename-spec2.o # RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTSECOND %s +# RUN: mkdir -p %t.testdir1 %t.testdir2 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.testdir1/filename-spec1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ +# RUN: %p/Inputs/filename-spec.s -o %t.testdir2/filename-spec2.o +# RUN: llvm-ar rsc %t.testdir1/lib1.a %t.testdir1/filename-spec1.o +# RUN: llvm-ar rsc %t.testdir2/lib2.a %t.testdir2/filename-spec2.o + +# Verify matching of archive library names. +# RUN: echo "SECTIONS { .foo : { \ +# RUN: *lib2*(.foo) \ +# RUN: *lib1*(.foo) } }" > %t7.script +# RUN: ld.lld -o %t7 --script %t7.script --whole-archive \ +# RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a +# RUN: llvm-objdump -s %t7 | FileCheck --check-prefix=SECONDFIRST %s + +# Verify matching directories. +# RUN: echo "SECTIONS { .foo : { \ +# RUN: *testdir2*(.foo) \ +# RUN: *testdir1*(.foo) } }" > %t8.script +# RUN: ld.lld -o %t8 --script %t8.script --whole-archive \ +# RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a +# RUN: llvm-objdump -s %t8 | FileCheck --check-prefix=SECONDFIRST %s + +# Verify matching of archive library names in KEEP. +# RUN: echo "SECTIONS { .foo : { \ +# RUN: KEEP(*lib2*(.foo)) \ +# RUN: KEEP(*lib1*(.foo)) } }" > %t9.script +# RUN: ld.lld -o %t9 --script %t9.script --whole-archive \ +# RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a +# RUN: llvm-objdump -s %t9 | FileCheck --check-prefix=SECONDFIRST %s + +# Verify matching directories in KEEP. +# RUN: echo "SECTIONS { .foo : { \ +# RUN: KEEP(*testdir2*(.foo)) \ +# RUN: KEEP(*testdir1*(.foo)) } }" > %t10.script +# RUN: ld.lld -o %t10 --script %t10.script --whole-archive \ +# RUN: %t.testdir1/lib1.a %t.testdir2/lib2.a +# RUN: llvm-objdump -s %t10 | FileCheck --check-prefix=SECONDFIRST %s + .global _start _start: nop diff --git a/test/ELF/linkerscript/header-addr.s b/test/ELF/linkerscript/header-addr.s index f37d319aaabe..70e6f674bafb 100644 --- a/test/ELF/linkerscript/header-addr.s +++ b/test/ELF/linkerscript/header-addr.s @@ -2,20 +2,20 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "PHDRS {all PT_LOAD PHDRS;} \ # RUN: SECTIONS { \ -# RUN: . = 0x2000; \ +# RUN: . = 0x2000 + SIZEOF_HEADERS; \ # RUN: .text : {*(.text)} :all \ # RUN: }" > %t.script -# RUN: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared # RUN: llvm-readobj -program-headers %t.so | FileCheck %s # CHECK: ProgramHeaders [ # CHECK-NEXT: ProgramHeader { # CHECK-NEXT: Type: PT_LOAD # CHECK-NEXT: Offset: 0x40 -# CHECK-NEXT: VirtualAddress: 0x1040 -# CHECK-NEXT: PhysicalAddress: 0x1040 -# CHECK-NEXT: FileSize: 4176 -# CHECK-NEXT: MemSize: 4176 +# CHECK-NEXT: VirtualAddress: 0x2040 +# CHECK-NEXT: PhysicalAddress: 0x2040 +# CHECK-NEXT: FileSize: 200 +# CHECK-NEXT: MemSize: 200 # CHECK-NEXT: Flags [ # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: PF_W (0x2) @@ -25,7 +25,7 @@ # CHECK-NEXT: } # CHECK-NEXT: ] -# RUN: ld.lld -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000 +# RUN: ld.lld --hash-style=sysv -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000 # RUN: llvm-readobj -program-headers %t2.so \ # RUN: | FileCheck --check-prefix=MAXPAGE %s @@ -33,10 +33,10 @@ # MAXPAGE-NEXT: ProgramHeader { # MAXPAGE-NEXT: Type: PT_LOAD # MAXPAGE-NEXT: Offset: 0x40 -# MAXPAGE-NEXT: VirtualAddress: 0x40 -# MAXPAGE-NEXT: PhysicalAddress: 0x40 -# MAXPAGE-NEXT: FileSize: 8272 -# MAXPAGE-NEXT: MemSize: 8272 +# MAXPAGE-NEXT: VirtualAddress: 0x2040 +# MAXPAGE-NEXT: PhysicalAddress: 0x2040 +# MAXPAGE-NEXT: FileSize: 200 +# MAXPAGE-NEXT: MemSize: 200 # MAXPAGE-NEXT: Flags [ # MAXPAGE-NEXT: PF_R # MAXPAGE-NEXT: PF_W diff --git a/test/ELF/linkerscript/header-phdr.s b/test/ELF/linkerscript/header-phdr.s new file mode 100644 index 000000000000..8c9097d8dfa5 --- /dev/null +++ b/test/ELF/linkerscript/header-phdr.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "PHDRS { foobar PT_LOAD FILEHDR PHDRS; } \ +# RUN: SECTIONS { . = 0x1000; .abc : { *(.zed) } : foobar }" > %t.script +# RUN: ld.lld --script %t.script %t.o -o %t +# RUN: llvm-readelf -l -S -W %t | FileCheck %s + +.section .zed, "a" +.zero 4 + + +# CHECK: [ 1] .abc PROGBITS 0000000000001000 001000 000004 00 A 0 0 1 +# CHECK: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001004 0x001004 R E 0x1000 diff --git a/test/ELF/linkerscript/image-base.s b/test/ELF/linkerscript/image-base.s new file mode 100644 index 000000000000..0ae463fce8a9 --- /dev/null +++ b/test/ELF/linkerscript/image-base.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { mysym = .; }" > %t.script + +# RUN: ld.lld %t.o -o %t-default.elf -T %t.script +# RUN: llvm-readobj --symbols %t-default.elf | FileCheck %s --check-prefix=DEFAULT +# DEFAULT: Name: mysym +# DEFAULT-NEXT: Value: 0x0 + +# RUN: ld.lld %t.o -o %t-switch.elf -T %t.script --image-base=0x100000 +# RUN: llvm-readobj --symbols %t-switch.elf | FileCheck %s --check-prefix=SWITCH +# SWITCH: Name: mysym +# SWITCH-NEXT: Value: 0x100000 + +.global _start +_start: + nop diff --git a/test/ELF/linkerscript/implicit-program-header.s b/test/ELF/linkerscript/implicit-program-header.s index 9598a6abebb0..95cdf142fe42 100644 --- a/test/ELF/linkerscript/implicit-program-header.s +++ b/test/ELF/linkerscript/implicit-program-header.s @@ -1,6 +1,6 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: ld.lld -o %t1 --script %S/Inputs/implicit-program-header.script \ +# RUN: ld.lld --hash-style=sysv -o %t1 --script %S/Inputs/implicit-program-header.script \ # RUN: %t.o -shared # RUN: llvm-readobj -elf-output-style=GNU -l %t1 | FileCheck %s diff --git a/test/ELF/linkerscript/include-cycle.s b/test/ELF/linkerscript/include-cycle.s new file mode 100644 index 000000000000..e93ed904f05a --- /dev/null +++ b/test/ELF/linkerscript/include-cycle.s @@ -0,0 +1,15 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +# RUN: echo "INCLUDE \"%t1.script\"" > %t1.script +# RUN: not ld.lld %t.o %t1.script 2>&1 | FileCheck %s + +# RUN: echo "INCLUDE \"%t2.script\"" > %t1.script +# RUN: echo "INCLUDE \"%t1.script\"" > %t2.script +# RUN: not ld.lld %t.o %t1.script 2>&1 | FileCheck %s + +# CHECK: there is a cycle in linker script INCLUDEs + +.globl _start +_start: + ret diff --git a/test/ELF/linkerscript/linker-script-in-search-path.s b/test/ELF/linkerscript/linker-script-in-search-path.s new file mode 100644 index 000000000000..be83b55b8995 --- /dev/null +++ b/test/ELF/linkerscript/linker-script-in-search-path.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# Check that we fall back to search paths if a linker script was not found +# This behaviour matches ld.bfd and various projects appear to rely on this + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: mkdir -p %T/searchpath +# RUN: echo "OUTPUT(\"%t.out\")" > %T/searchpath/foo.script +# RUN: ld.lld -T%T/searchpath/foo.script %t.o +# RUN: llvm-readobj %t.out | FileCheck %s +# CHECK: Format: ELF64-x86-64 + +# If the linker script specified with -T is missing we should emit an error +# RUN: not ld.lld -Tfoo.script %t.o 2>&1 | FileCheck %s -check-prefix ERROR +# ERROR: error: cannot find linker script foo.script + +# But if it exists in the search path we should fall back to that instead: +# RUN: rm %t.out +# RUN: ld.lld -L %T/searchpath -Tfoo.script %t.o +# RUN: llvm-readobj %t.out | FileCheck %s diff --git a/test/ELF/linkerscript/linkerscript.s b/test/ELF/linkerscript/linkerscript.s index cac902af4270..6a239ea57c8d 100644 --- a/test/ELF/linkerscript/linkerscript.s +++ b/test/ELF/linkerscript/linkerscript.s @@ -37,8 +37,8 @@ # RUN: echo "OUTPUT(\"%t.out\")" > %T/foo.script # RUN: not ld.lld %t.script > %t.log 2>&1 # RUN: FileCheck -check-prefix=INCLUDE_ERR %s < %t.log -# INCLUDE_ERR: error: {{.+}}.script:1: cannot open foo.script -# INCLUDE_ERR-NEXT: error: {{.+}}.script:1: INCLUDE "foo.script" +# INCLUDE_ERR: error: {{.+}}.script:1: cannot find linker script foo.script +# INCLUDE_ERR-NEXT: INCLUDE "foo.script" # RUN: ld.lld -L %T %t.script %t # RUN: echo "FOO(BAR)" > %t.script diff --git a/test/ELF/linkerscript/memory-at.s b/test/ELF/linkerscript/memory-at.s new file mode 100644 index 000000000000..9e56dbdbd657 --- /dev/null +++ b/test/ELF/linkerscript/memory-at.s @@ -0,0 +1,46 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { \ +# RUN: FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0x100 \ +# RUN: RAM (rwx) : ORIGIN = 0x2000, LENGTH = 0x100 } \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text*) } > FLASH \ +# RUN: __etext = .; \ +# RUN: .data : AT (__etext) { *(.data*) } > RAM \ +# RUN: }" > %t.script +# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-readobj -program-headers %t2 | FileCheck %s + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1000 +# CHECK-NEXT: PhysicalAddress: 0x1000 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_X +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD +# CHECK-NEXT: Offset: 0x2000 +# CHECK-NEXT: VirtualAddress: 0x2000 +# CHECK-NEXT: PhysicalAddress: 0x1008 +# CHECK-NEXT: FileSize: 8 +# CHECK-NEXT: MemSize: 8 +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: PF_W +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: +# CHECK-NEXT: } + +.section .text, "ax" +.quad 0 + +.section .data, "aw" +.quad 0 diff --git a/test/ELF/linkerscript/memory-err.s b/test/ELF/linkerscript/memory-err.s new file mode 100644 index 000000000000..19517687b78d --- /dev/null +++ b/test/ELF/linkerscript/memory-err.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { name : ORIGIN = DATA_SEGMENT_RELRO_END; }" > %t.script +# RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 | FileCheck %s +# CHECK: error: {{.*}}.script:1: unable to calculate page size + +# RUN: echo "MEMORY { name : ORIGIN = CONSTANT(COMMONPAGESIZE); }" > %t.script +# RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 |\ +# RUN: FileCheck %s --check-prefix=ERR2 +# ERR2: error: {{.*}}.script:1: unable to calculate page size + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { name : ORIGIN = .; }" > %t.script +# RUN: not ld.lld -shared -o %t2 --script %t.script %t 2>&1 |\ +# RUN: FileCheck %s --check-prefix=ERR3 +# ERR3: error: {{.*}}.script:1: unable to get location counter value diff --git a/test/ELF/linkerscript/memory.s b/test/ELF/linkerscript/memory.s index 774a6f92ab17..172768394d30 100644 --- a/test/ELF/linkerscript/memory.s +++ b/test/ELF/linkerscript/memory.s @@ -21,8 +21,8 @@ # RUN: rom (rx) : org = (0x80 * 0x1000 * 0x1000), len = 64M \ # RUN: } \ # RUN: SECTIONS { \ -# RUN: .text : { *(.text) } > rom \ -# RUN: .data : { *(.data) } > ram \ +# RUN: .text : { *(.text) } >rom \ +# RUN: .data : { *(.data) } >ram \ # RUN: }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAMROM %s diff --git a/test/ELF/linkerscript/memory2.s b/test/ELF/linkerscript/memory2.s new file mode 100644 index 000000000000..2e7381fb8914 --- /dev/null +++ b/test/ELF/linkerscript/memory2.s @@ -0,0 +1,14 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0, LENGTH = 2K } \ +# RUN: SECTIONS { .text : { *(.text*) } > ram }" > %t.script +# RUN: ld.lld -o %t2 --script %t.script %t + +.text +.global _start +_start: + .zero 1024 + +.section .text.foo,"ax",%progbits +foo: + nop diff --git a/test/ELF/linkerscript/memory3.s b/test/ELF/linkerscript/memory3.s new file mode 100644 index 000000000000..6a24313f0621 --- /dev/null +++ b/test/ELF/linkerscript/memory3.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { ram2 (ax) : ORIGIN = 0x1000, LENGTH = 1K \ +# RUN: ram1 (ax) : ORIGIN = 0x4000, LENGTH = 1K } \ +# RUN: SECTIONS {}" > %t1.script +# RUN: ld.lld -o %t1 --script %t1.script %t +# RUN: llvm-objdump -section-headers %t1 | FileCheck %s + +# RUN: echo "MEMORY { ram1 (ax) : ORIGIN = 0x1000, LENGTH = 1K \ +# RUN: ram2 (ax) : ORIGIN = 0x4000, LENGTH = 1K } \ +# RUN: SECTIONS {}" > %t2.script +# RUN: ld.lld -o %t2 --script %t2.script %t +# RUN: llvm-objdump -section-headers %t2 | FileCheck %s + +## Check we place .text into first defined memory region with appropriate flags. +# CHECK: Sections: +# CHECK: Idx Name Size Address +# CHECK: 0 00000000 0000000000000000 +# CHECK: 1 .text 00000001 0000000000001000 + +.section .text.foo,"ax",%progbits +foo: + nop diff --git a/test/ELF/linkerscript/merge-sections.s b/test/ELF/linkerscript/merge-sections.s index 950d822ec403..2709bdaee444 100644 --- a/test/ELF/linkerscript/merge-sections.s +++ b/test/ELF/linkerscript/merge-sections.s @@ -36,7 +36,7 @@ # RUN: llvm-readobj -s -t %t2 | FileCheck %s --check-prefix=GC # GC: Name: .foo -# GC-NEXT: Type: SHT_PROGBITS +# GC-NEXT: Type: SHT_NOBITS # GC-NEXT: Flags [ # GC-NEXT: SHF_ALLOC # GC-NEXT: ] diff --git a/test/ELF/linkerscript/no-space.s b/test/ELF/linkerscript/no-space.s index fc9e5b13325f..21a38e42b2a3 100644 --- a/test/ELF/linkerscript/no-space.s +++ b/test/ELF/linkerscript/no-space.s @@ -2,11 +2,11 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: echo "SECTIONS {foo 0 : {*(foo*)} }" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s # RUN: echo "SECTIONS {foo : {*(foo*)} }" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared # RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s # There is not enough address space available for the header, so just start the PT_LOAD diff --git a/test/ELF/linkerscript/noload.s b/test/ELF/linkerscript/noload.s index 9d0e085a0504..28be55df1f12 100644 --- a/test/ELF/linkerscript/noload.s +++ b/test/ELF/linkerscript/noload.s @@ -4,10 +4,10 @@ # RUN: .data_noload_a (NOLOAD) : { *(.data_noload_a) } \ # RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } };" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o -# RUN: llvm-readobj --symbols -sections %t +# RUN: llvm-readobj --symbols -sections %t | FileCheck %s # CHECK: Section { -# CHECK-NEXT: Index: 2 +# CHECK: Index: 2 # CHECK-NEXT: Name: .data_noload_a # CHECK-NEXT: Type: SHT_NOBITS # CHECK-NEXT: Flags [ diff --git a/test/ELF/linkerscript/non-alloc.s b/test/ELF/linkerscript/non-alloc.s index 861c74996b85..3257cb965565 100644 --- a/test/ELF/linkerscript/non-alloc.s +++ b/test/ELF/linkerscript/non-alloc.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t # RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -shared +# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared # RUN: llvm-readobj -elf-output-style=GNU -s -l %t1 | FileCheck %s # Test that we create all necessary PT_LOAD. We use to stop at the first diff --git a/test/ELF/linkerscript/operators.s b/test/ELF/linkerscript/operators.s index 470558d29df1..868805b34c2e 100644 --- a/test/ELF/linkerscript/operators.s +++ b/test/ELF/linkerscript/operators.s @@ -25,6 +25,7 @@ # RUN: commonpagesize = CONSTANT (COMMONPAGESIZE); \ # RUN: . = 0xfff0; \ # RUN: datasegmentalign = DATA_SEGMENT_ALIGN (0xffff, 0); \ +# RUN: datasegmentalign2 = DATA_SEGMENT_ALIGN (0, 0); \ # RUN: }" > %t.script # RUN: ld.lld %t --script %t.script -o %t2 # RUN: llvm-objdump -t %t2 | FileCheck %s @@ -51,6 +52,7 @@ # CHECK: 00000000001000 *ABS* 00000000 maxpagesize # CHECK: 00000000001000 *ABS* 00000000 commonpagesize # CHECK: 0000000000ffff *ABS* 00000000 datasegmentalign +# CHECK: 0000000000fff0 *ABS* 00000000 datasegmentalign2 ## Mailformed number error. # RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script diff --git a/test/ELF/linkerscript/orphan-discard.s b/test/ELF/linkerscript/orphan-discard.s new file mode 100644 index 000000000000..6fd6fafcd7f4 --- /dev/null +++ b/test/ELF/linkerscript/orphan-discard.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 +# RUN: llvm-mc -position-independent -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { \ +# RUN: . = 0xffffffff80000000; \ +# RUN: .text : ALIGN(4096) { *(.text) } \ +# RUN: .data : ALIGN(4096) { *(.data) } \ +# RUN: .bss : ALIGN(4096) { *(.bss); } \ +# RUN: . = ALIGN(4096); \ +# RUN: _end = .; \ +# RUN: /DISCARD/ : { *(.comment) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readelf -s -symbols %t | FileCheck %s + +# CHECK: .bss NOBITS ffffffff80002000 002008 000002 00 WA 0 0 4096 +# CHECK: ffffffff80003000 0 NOTYPE GLOBAL DEFAULT 3 _end + +.section .text, "ax" + ret + +.section .data, "aw" + .quad 0 + +.section .bss, "", @nobits + .short 0 diff --git a/test/ELF/linkerscript/orphan-end.s b/test/ELF/linkerscript/orphan-end.s new file mode 100644 index 000000000000..5f56d8f487a2 --- /dev/null +++ b/test/ELF/linkerscript/orphan-end.s @@ -0,0 +1,57 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o + +# Test that .orphan_rx is placed after __stack_end. This matches bfd's +# behavior when the orphan section is the last one. + +# RUN: echo "SECTIONS { \ +# RUN: __start_text = .; \ +# RUN: .text : { *(.text*) } \ +# RUN: __end_text = .; \ +# RUN: __stack_start = .; \ +# RUN: . = . + 0x1000; \ +# RUN: __stack_end = .; \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readelf -S --symbols %t | FileCheck %s + +# CHECK-DAG: .text PROGBITS 0000000000000000 +# CHECK-DAG: .orphan_rx PROGBITS 0000000000001004 + +# CHECK-DAG: 0000000000000000 {{.*}} __start_text +# CHECK-DAG: 0000000000000004 {{.*}} __end_text +# CHECK-DAG: 0000000000000004 {{.*}} __stack_start +# CHECK-DAG: 0000000000001004 {{.*}} __stack_end + +# Test that .orphan_rx is now placed before __stack_end. This matches bfd's +# behavior when the orphan section is not the last one. + +# RUN: echo "SECTIONS { \ +# RUN: __start_text = .; \ +# RUN: .text : { *(.text*) } \ +# RUN: __end_text = .; \ +# RUN: __stack_start = .; \ +# RUN: . = . + 0x1000; \ +# RUN: __stack_end = .; \ +# RUN: .orphan_rw : { *(.orphan_rw*) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readelf -S --symbols %t | FileCheck --check-prefix=MIDDLE %s + +# MIDDLE-DAG: .text PROGBITS 0000000000000000 +# MIDDLE-DAG: .orphan_rx PROGBITS 0000000000000004 + +# MIDDLE-DAG: 0000000000000000 {{.*}} __start_text +# MIDDLE-DAG: 0000000000000004 {{.*}} __end_text +# MIDDLE-DAG: 0000000000000004 {{.*}} __stack_start +# MIDDLE-DAG: 0000000000001008 {{.*}} __stack_end + + .global _start +_start: + .zero 4 + + .section .orphan_rx,"ax" + .zero 4 + + .section .orphan_rw,"aw" + .zero 4 diff --git a/test/ELF/linkerscript/orphan-phdrs.s b/test/ELF/linkerscript/orphan-phdrs.s new file mode 100644 index 000000000000..648911162e97 --- /dev/null +++ b/test/ELF/linkerscript/orphan-phdrs.s @@ -0,0 +1,34 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "PHDRS { \ +# RUN: exec PT_LOAD FLAGS(0x4 | 0x1); \ +# RUN: rw PT_LOAD FLAGS(0x4 | 0x2); \ +# RUN: } \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text) } :exec \ +# RUN: .empty : { *(.empty) } :rw \ +# RUN: .rw : { *(.rw) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s + +## Check that the orphan section is placed correctly and belongs to +## the correct segment. + +# CHECK: Section Headers +# CHECK: .text +# CHECK-NEXT: .orphan +# CHECK-NEXT: .rw + +# CHECK: Segment Sections +# CHECK-NEXT: .text .orphan +# CHECK-NEXT: .rw + +.section .text, "ax" + ret + +.section .rw, "aw" + .quad 0 + +.section .orphan, "ax" + ret diff --git a/test/ELF/linkerscript/orphan-report.s b/test/ELF/linkerscript/orphan-report.s new file mode 100644 index 000000000000..241857b239c4 --- /dev/null +++ b/test/ELF/linkerscript/orphan-report.s @@ -0,0 +1,54 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { .text : { *(.text.1) } }" > %t.script + +## Check we do not report orphans by default even with -verbose. +# RUN: ld.lld -shared -o %t.out --script %t.script %t.o 2>&1 -verbose \ +# RUN: | FileCheck %s --check-prefix=DEFAULT +# DEFAULT-NOT: placed + +## Check --orphan-handling=place has the same behavior as default. +# RUN: ld.lld -shared --orphan-handling=place -o %t.out --script %t.script \ +# RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=DEFAULT + +## Check --orphan-handling=error reports errors about orphans. +# RUN: not ld.lld -shared --orphan-handling=error -o %t.out --script %t.script \ +# RUN: %t.o 2>&1 -verbose -error-limit=0 | FileCheck %s --check-prefix=REPORT +# REPORT: {{.*}}.o:(.text) is being placed in '.text' +# REPORT-NEXT: {{.*}}.o:(.text.2) is being placed in '.text' +# REPORT-NEXT: <internal>:(.comment) is being placed in '.comment' +# REPORT-NEXT: <internal>:(.bss) is being placed in '.bss' +# REPORT-NEXT: <internal>:(.bss.rel.ro) is being placed in '.bss.rel.ro' +# REPORT-NEXT: <internal>:(.dynsym) is being placed in '.dynsym' +# REPORT-NEXT: <internal>:(.gnu.version) is being placed in '.gnu.version' +# REPORT-NEXT: <internal>:(.gnu.version_r) is being placed in '.gnu.version_r' +# REPORT-NEXT: <internal>:(.gnu.hash) is being placed in '.gnu.hash' +# REPORT-NEXT: <internal>:(.hash) is being placed in '.hash' +# REPORT-NEXT: <internal>:(.dynamic) is being placed in '.dynamic' +# REPORT-NEXT: <internal>:(.dynstr) is being placed in '.dynstr' +# REPORT-NEXT: <internal>:(.rela.dyn) is being placed in '.rela.dyn' +# REPORT-NEXT: <internal>:(.got) is being placed in '.got' +# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt' +# REPORT-NEXT: <internal>:(.got.plt) is being placed in '.got.plt' +# REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt' +# REPORT-NEXT: <internal>:(.rela.plt) is being placed in '.rela.plt' +# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt' +# REPORT-NEXT: <internal>:(.plt) is being placed in '.plt' +# REPORT-NEXT: <internal>:(.eh_frame) is being placed in '.eh_frame' +# REPORT-NEXT: <internal>:(.symtab) is being placed in '.symtab' +# REPORT-NEXT: <internal>:(.shstrtab) is being placed in '.shstrtab' +# REPORT-NEXT: <internal>:(.strtab) is being placed in '.strtab' + +## Check --orphan-handling=warn reports warnings about orphans. +# RUN: ld.lld -shared --orphan-handling=warn -o %t.out --script %t.script \ +# RUN: %t.o 2>&1 -verbose | FileCheck %s --check-prefix=REPORT + +# RUN: not ld.lld --orphan-handling=foo -o %t.out --script %t.script %t.o 2>&1 \ +# RUN: | FileCheck %s --check-prefix=UNKNOWN +# UNKNOWN: unknown --orphan-handling mode: foo + +.section .text.1,"a" + nop + +.section .text.2,"a" + nop diff --git a/test/ELF/linkerscript/out-of-order.s b/test/ELF/linkerscript/out-of-order.s index 6cfd533c4e14..c43df43e5002 100644 --- a/test/ELF/linkerscript/out-of-order.s +++ b/test/ELF/linkerscript/out-of-order.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-linux %s -o %t.o # RUN: echo "SECTIONS { .data 0x4000 : { *(.data) } .text 0x2000 : { *(.text) } }" > %t.script -# RUN: ld.lld -o %t.so --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t.so --script %t.script %t.o -shared # RUN: llvm-objdump -section-headers %t.so | FileCheck %s # CHECK: Sections: diff --git a/test/ELF/linkerscript/phdr-check.s b/test/ELF/linkerscript/phdr-check.s index c7229ed3312c..b35256be6b71 100644 --- a/test/ELF/linkerscript/phdr-check.s +++ b/test/ELF/linkerscript/phdr-check.s @@ -1,14 +1,14 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: echo "SECTIONS { . = 0x10000000; .text : {*(.text.*)} }" > %t.script +# RUN: echo "SECTIONS { . = 0x10000000 + SIZEOF_HEADERS; .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 +# CHECK-NEXT: VirtualAddress: 0x10000040 .global _start _start: diff --git a/test/ELF/linkerscript/phdrs.s b/test/ELF/linkerscript/phdrs.s index 025ced95b30a..b65015994533 100644 --- a/test/ELF/linkerscript/phdrs.s +++ b/test/ELF/linkerscript/phdrs.s @@ -39,9 +39,9 @@ # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s -## Check that error is reported when trying to use phdr which is not listed +## Check that error is reported when trying to use phdr which is not listed ## inside PHDRS {} block -## TODO: If script doesn't contain PHDRS {} block then default phdr is always +## TODO: If script doesn't contain PHDRS {} block then default phdr is always ## created and error is not reported. # RUN: echo "PHDRS { all PT_LOAD; } \ # RUN: SECTIONS { .baz : {*(.foo.*)} :bar }" > %t.script diff --git a/test/ELF/linkerscript/provide-shared.s b/test/ELF/linkerscript/provide-shared.s new file mode 100644 index 000000000000..e3f1bdb2ea3d --- /dev/null +++ b/test/ELF/linkerscript/provide-shared.s @@ -0,0 +1,13 @@ +# 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/provide-shared.s -o %t2.o +# RUN: ld.lld %t2.o -o %t2.so -shared +# RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; PROVIDE(foo = 42);}" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o %t2.so +# RUN: llvm-objdump -t %t | FileCheck %s + +# CHECK: 000000000000002a *ABS* 00000000 foo + +.global _start +_start: +.quad foo diff --git a/test/ELF/linkerscript/region-alias.s b/test/ELF/linkerscript/region-alias.s new file mode 100644 index 000000000000..8a88f6f5ad9f --- /dev/null +++ b/test/ELF/linkerscript/region-alias.s @@ -0,0 +1,54 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "MEMORY { \ +# RUN: ROM (rwx): ORIGIN = 0x1000, LENGTH = 0x100 \ +# RUN: RAM (rwx): ORIGIN = 0x2000, LENGTH = 0x100 \ +# RUN: } \ +# RUN: INCLUDE \"%t.script.inc\" \ +# RUN: SECTIONS { \ +# RUN: .text : { *(.text*) } > ALIAS_TEXT \ +# RUN: .data : { *(.data*) } > ALIAS_DATA \ +# RUN: }" > %t.script + +## .text to ROM, .data to RAM. +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc +# RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", RAM);" >> %t.script.inc +# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-objdump -section-headers %t2 | FileCheck %s +# CHECK: .text 00000001 0000000000001000 TEXT DATA +# CHECK: .data 00000008 0000000000002000 DATA + +## All to ROM. +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc +# RUN: echo "REGION_ALIAS (\"ALIAS_DATA\", ROM);" >> %t.script.inc +# RUN: ld.lld %t --script %t.script -o %t2 +# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=RAM +# RAM: .text 00000001 0000000000001000 TEXT DATA +# RAM: .data 00000008 0000000000001001 DATA + +## Redefinition of region. +# RUN: echo "REGION_ALIAS (\"ROM\", ROM);" > %t.script.inc +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR1 +# ERR1: {{.*}}script.inc:1: redefinition of memory region 'ROM' + +## Redefinition of alias. +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" > %t.script.inc +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", ROM);" >> %t.script.inc +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR2 +# ERR2: {{.*}}script.inc:2: redefinition of memory region 'ALIAS_TEXT' + +## Attemp to create an alias for undefined region. +# RUN: echo "REGION_ALIAS (\"ALIAS_TEXT\", FOO);" > %t.script.inc +# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \ +# RUN: FileCheck %s --check-prefix=ERR3 +# ERR3: {{.*}}script.inc:1: memory region 'FOO' is not defined + +.text +.global _start +_start: + nop + +.section .data,"aw" +.quad 0 diff --git a/test/ELF/linkerscript/repsection-symbol.s b/test/ELF/linkerscript/repsection-symbol.s index d2d8c9dd56ef..195380be9ff8 100644 --- a/test/ELF/linkerscript/repsection-symbol.s +++ b/test/ELF/linkerscript/repsection-symbol.s @@ -6,7 +6,7 @@ # RUN: .text : { *(.text) } \ # RUN: .foo : {foo1 = .; *(.foo.*) foo2 = .; *(.bar) foo3 = .;} \ # RUN: }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -shared +# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared # RUN: llvm-readobj -t %t1 | FileCheck %s # CHECK: Name: foo1 diff --git a/test/ELF/linkerscript/sections-sort.s b/test/ELF/linkerscript/sections-sort.s index 0e99851910f4..99bbbead925c 100644 --- a/test/ELF/linkerscript/sections-sort.s +++ b/test/ELF/linkerscript/sections-sort.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { .text : {*(.text)} foo : {*(foo)}}" > %t.script -# RUN: ld.lld -o %t --script %t.script %t.o -shared +# RUN: ld.lld --hash-style=sysv -o %t --script %t.script %t.o -shared # RUN: llvm-objdump --section-headers %t | FileCheck %s # Test the section order. This is a case where at least with libstdc++'s diff --git a/test/ELF/linkerscript/segment-headers.s b/test/ELF/linkerscript/segment-headers.s new file mode 100644 index 000000000000..b3bdad9ea08b --- /dev/null +++ b/test/ELF/linkerscript/segment-headers.s @@ -0,0 +1,26 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { . = 0x2000; .text : AT(0x100000) { *(.text) } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -l %t | FileCheck %s + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x2000 +# CHECK-NEXT: PhysicalAddress: 0x100000 +# 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: } + +.section .text +.global _start + +_start: + ret diff --git a/test/ELF/linkerscript/segment-start.s b/test/ELF/linkerscript/segment-start.s index e46c398f63f9..69897d604b3b 100644 --- a/test/ELF/linkerscript/segment-start.s +++ b/test/ELF/linkerscript/segment-start.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: ld.lld %t.o %S/Inputs/segment-start.script -shared -o %t.so +// RUN: ld.lld --hash-style=sysv %t.o %S/Inputs/segment-start.script -shared -o %t.so // RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s // CHECK: Name: foobar1 diff --git a/test/ELF/linkerscript/sort-non-script.s b/test/ELF/linkerscript/sort-non-script.s index b0517608d51b..4611b18d55ef 100644 --- a/test/ELF/linkerscript/sort-non-script.s +++ b/test/ELF/linkerscript/sort-non-script.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t # RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script -# RUN: ld.lld -o %t1 --script %t.script %t -shared +# RUN: ld.lld --hash-style=sysv -o %t1 --script %t.script %t -shared # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s # CHECK: .text {{.*}} AX diff --git a/test/ELF/linkerscript/subalign.s b/test/ELF/linkerscript/subalign.s index 8b441d440b0e..1396798c82f6 100644 --- a/test/ELF/linkerscript/subalign.s +++ b/test/ELF/linkerscript/subalign.s @@ -22,6 +22,23 @@ # SUBALIGN: 01000000 00000000 02000000 00000000 # SUBALIGN: 03000000 00000000 04000000 00000000 +## Test we do not assert or crash when dot(.) is used inside SUBALIGN. +## ld.bfd does not allow to use dot in such expressions, our behavior is +## different for simplicity of implementation. Value of dot is undefined. +# RUN: echo "SECTIONS { . = 0x32; .aaa : SUBALIGN(.) { *(.aaa*) } }" > %t3.script +# RUN: ld.lld %t1.o --script %t3.script -o %t3 +# RUN: llvm-objdump -s %t3 > /dev/null + +## Test we are able to link with zero alignment, this is consistent with bfd 2.26.1. +# RUN: echo "SECTIONS { .aaa : SUBALIGN(0) { *(.aaa*) } }" > %t4.script +# RUN: ld.lld %t1.o --script %t4.script -o %t4 +# RUN: llvm-objdump -s %t4 | FileCheck -check-prefix=SUBALIGN %s + +## Test we fail gracefuly when alignment value is not a power of 2. +# RUN: echo "SECTIONS { .aaa : SUBALIGN(3) { *(.aaa*) } }" > %t5.script +# RUN: not ld.lld %t1.o --script %t5.script -o %t5 2>&1 | FileCheck -check-prefix=ERR %s +# ERR: {{.*}}.script:1: alignment must be power of 2 + .global _start _start: nop diff --git a/test/ELF/linkerscript/symbol-assignexpr.s b/test/ELF/linkerscript/symbol-assignexpr.s index 14a1f0890ca6..9ab03a173f1c 100644 --- a/test/ELF/linkerscript/symbol-assignexpr.s +++ b/test/ELF/linkerscript/symbol-assignexpr.s @@ -6,7 +6,7 @@ # RUN: symbol2 = symbol + 0x1234; \ # RUN: symbol3 = symbol2; \ # RUN: symbol4 = symbol + -4; \ -# RUN: symbol5 = symbol - ~ 0xfffb; \ +# RUN: symbol5 = symbol - ~0xfffb; \ # RUN: symbol6 = symbol - ~(0xfff0 + 0xb); \ # RUN: symbol7 = symbol - ~ 0xfffb + 4; \ # RUN: symbol8 = ~ 0xffff + 4; \ @@ -15,6 +15,9 @@ # RUN: symbol11 = ((0x28000 + 0x1fff) & ~(0x1000 + -1)); \ # RUN: symbol12 = 0x1234; \ # RUN: symbol12 += 1; \ +# RUN: symbol13 = !1; \ +# RUN: symbol14 = !0; \ +# RUN: symbol15 = 0!=1; \ # RUN: bar = 0x5678; \ # RUN: baz = 0x9abc; \ # RUN: }" > %t.script @@ -39,6 +42,9 @@ # CHECK-NEXT: fedcba9876543210 *ABS* 00000000 symbol10 # CHECK-NEXT: 0000000000029000 *ABS* 00000000 symbol11 # CHECK-NEXT: 0000000000001235 *ABS* 00000000 symbol12 +# CHECK-NEXT: 0000000000000000 *ABS* 00000000 symbol13 +# CHECK-NEXT: 0000000000000001 *ABS* 00000000 symbol14 +# CHECK-NEXT: 0000000000000001 *ABS* 00000000 symbol15 # RUN: echo "SECTIONS { symbol2 = symbol; }" > %t2.script # RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \ diff --git a/test/ELF/linkerscript/symbol-only-flags.s b/test/ELF/linkerscript/symbol-only-flags.s new file mode 100644 index 000000000000..300d8d88da97 --- /dev/null +++ b/test/ELF/linkerscript/symbol-only-flags.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \ +# RUN: .tbss : { *(.tbss) } \ +# RUN: .foo : { bar = .; } }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -s %t | FileCheck %s + +## Check .foo does not get SHF_TLS flag. +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .foo +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] + +.section .tbss,"awT",@nobits +.quad 0 diff --git a/test/ELF/linkerscript/symbol-only.s b/test/ELF/linkerscript/symbol-only.s index 2fb57260b333..76d54f01cdc7 100644 --- a/test/ELF/linkerscript/symbol-only.s +++ b/test/ELF/linkerscript/symbol-only.s @@ -12,7 +12,7 @@ # CHECK: Sections: # CHECK-NEXT: Idx Name Size Address # CHECK-NEXT: 0 00000000 0000000000000000 -# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] DATA +# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] BSS # CHECK-NEXT: bar 00000000 0000000000001000 DATA # CHECK: SYMBOL TABLE: diff --git a/test/ELF/linkerscript/symbol-ordering-file.s b/test/ELF/linkerscript/symbol-ordering-file.s new file mode 100644 index 000000000000..be686c420887 --- /dev/null +++ b/test/ELF/linkerscript/symbol-ordering-file.s @@ -0,0 +1,23 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "SECTIONS { .foo : { *(.foo) } }" > %t.script + +# RUN: ld.lld %t.o --script %t.script -o %t.out +# RUN: llvm-objdump -s %t.out| FileCheck %s --check-prefix=BEFORE +# BEFORE: Contents of section .foo: +# BEFORE-NEXT: 1122 + +# RUN: echo "_foo2" > %t.ord +# RUN: echo "_foo1" >> %t.ord +# RUN: ld.lld --symbol-ordering-file %t.ord %t.o --script %t.script -o %t2.out +# RUN: llvm-objdump -s %t2.out| FileCheck %s --check-prefix=AFTER +# AFTER: Contents of section .foo: +# AFTER-NEXT: 2211 + +.section .foo,"ax",@progbits,unique,1 +_foo1: + .byte 0x11 + +.section .foo,"ax",@progbits,unique,2 +_foo2: + .byte 0x22 diff --git a/test/ELF/linkerscript/symbol-reserved.s b/test/ELF/linkerscript/symbol-reserved.s index e0b259597381..8ae9d0cd661a 100644 --- a/test/ELF/linkerscript/symbol-reserved.s +++ b/test/ELF/linkerscript/symbol-reserved.s @@ -17,6 +17,34 @@ # ALIGNED: 0000000000200005 .text 00000000 .hidden newsym +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(3, 8) + 10);" > %t.script +# RUN: ld.lld -o %t1 %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGN-ADD %s +# ALIGN-ADD: 0000000000000012 *ABS* 00000000 .hidden newsym + +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(11, 8) - 10);" > %t.script +# RUN: ld.lld -o %t1 %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGN-SUB %s +# ALIGN-SUB: 0000000000000006 *ABS* 00000000 .hidden newsym + +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script +# RUN: ld.lld -o %t1 %t %t.script +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE %s +# RELATIVE: 0000000000202005 .text 00000000 .hidden newsym +# RELATIVE: 0000000000201007 .text 00000000 _end + +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script +# RUN: ld.lld -o %t1 --script %p/Inputs/symbol-reserved.script %t %t.script +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE-ADD %s +# RELATIVE-ADD: 0000000000001005 .text 00000000 .hidden newsym +# RELATIVE-ADD: 0000000000000007 .text 00000000 .hidden _end + +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) - 5);" > %t.script +# RUN: ld.lld -o %t1 --script %p/Inputs/symbol-reserved.script %t %t.script +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE-SUB %s +# RELATIVE-SUB: 0000000000000ffb .text 00000000 .hidden newsym +# RELATIVE-SUB: 0000000000000007 .text 00000000 .hidden _end + .global _start _start: lea newsym(%rip),%rax diff --git a/test/ELF/linkerscript/symbols.s b/test/ELF/linkerscript/symbols.s index 4656635171c8..a6d797584417 100644 --- a/test/ELF/linkerscript/symbols.s +++ b/test/ELF/linkerscript/symbols.s @@ -12,14 +12,13 @@ # The symbol is not referenced. Don't provide it. # RUN: echo "SECTIONS { PROVIDE(newsym = 1);}" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE1 %s -# PROVIDE1-NOT: 0000000000000001 *ABS* 00000000 newsym +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s +# DONTPROVIDE-NOT: newsym # The symbol is not referenced. Don't provide it. # RUN: echo "SECTIONS { PROVIDE_HIDDEN(newsym = 1);}" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN1 %s -# HIDDEN1-NOT: 0000000000000001 *ABS* 00000000 .hidden newsym +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s # Provide existing symbol. The value should be 0, even though we # have value of 1 in PROVIDE() @@ -44,14 +43,12 @@ # The symbol is not referenced. Don't provide it. # RUN: echo "PROVIDE(newsym = 1);" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE4 %s -# PROVIDE4-NOT: 0000000000000001 *ABS* 00000000 newsym +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s # The symbol is not referenced. Don't provide it. # RUN: echo "PROVIDE_HIDDEN(newsym = 1);" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t -# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN4 %s -# HIDDEN4-NOT: 0000000000000001 *ABS* 00000000 .hidden newsym +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=DONTPROVIDE %s # Provide existing symbol. The value should be 0, even though we # have value of 1 in PROVIDE() diff --git a/test/ELF/linkerscript/thunk-gen-mips.s b/test/ELF/linkerscript/thunk-gen-mips.s new file mode 100644 index 000000000000..97d06d0ee654 --- /dev/null +++ b/test/ELF/linkerscript/thunk-gen-mips.s @@ -0,0 +1,40 @@ +# REQUIRES: mips +# RUN: llvm-mc -filetype=obj -defsym=MAIN=1 -triple=mips-unknown-freebsd %s -o %t +# RUN: llvm-mc -filetype=obj -defsym=TARGET=1 -triple=mips-unknown-freebsd %s -o %t1 + +# SECTIONS command with the first pattern that does not match. +# Linking a PIC and non-PIC object files triggers the LA25 thunk generation. +# RUN: echo "SECTIONS { \ +# RUN: .text : { \ +# RUN: *(.nomatch) \ +# RUN: %t(.text) \ +# RUN: . = . + 0x100000 ; \ +# RUN: %t1(.text) \ +# RUN: } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t.exe --script %t.script %t %t1 +# RUN: llvm-objdump -t %t.exe | FileCheck %s +# CHECK: SYMBOL TABLE: +# CHECK-ANY: 00000000 .text 00000000 _start +# CHECK-ANY: 0010000c l F .text 00000010 __LA25Thunk_too_far +# CHECK-ANY: 00100020 g F .text 00000024 too_far + +.ifdef MAIN +.global _start +_start: + j too_far + nop +.endif + +.ifdef TARGET + .text + .abicalls + .set noreorder + .globl too_far + .ent too_far +too_far: + nop + jr $ra + nop + .end too_far +.endif diff --git a/test/ELF/linkerscript/unused-synthetic.s b/test/ELF/linkerscript/unused-synthetic.s index c9295fff7b59..b7cedbc8e09c 100644 --- a/test/ELF/linkerscript/unused-synthetic.s +++ b/test/ELF/linkerscript/unused-synthetic.s @@ -13,6 +13,16 @@ # CHECK: .text # CHECK-NEXT: .dynsym +# Test that the size of a removed unused synthetic input section is not added +# to the output section size. Adding a symbol assignment prevents removal of +# the output section, but does not cause the section size to be recomputed. +# RUN: echo "SECTIONS { \ +# RUN: .got.plt : { a_sym = .; *(.got.plt) } \ +# RUN: }" > %t2.script +# RUN: ld.lld -shared -o %t2.so --script %t2.script %t.o +# RUN: llvm-objdump -section-headers %t2.so | FileCheck %s --check-prefix=CHECK2 +# CHECK2: .got.plt 00000000 + .global _start _start: nop diff --git a/test/ELF/linkerscript/version-linker-symbol.s b/test/ELF/linkerscript/version-linker-symbol.s new file mode 100644 index 000000000000..de30cf5c2ed5 --- /dev/null +++ b/test/ELF/linkerscript/version-linker-symbol.s @@ -0,0 +1,28 @@ +# REQUIRES: x86 + +# RUN: echo "VER1 { global: _end; foo ; local: * ; } ;" > %t.script +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so +# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s + +# CHECK: Name: _end@@VER1 +# CHECK-NEXT: Value: 0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .dynamic + +# CHECK: Name: foo@@VER1 +# CHECK-NEXT: Value: 0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text + +.global foo +foo: + .data + .quad _end + .quad foo diff --git a/test/ELF/lit.local.cfg b/test/ELF/lit.local.cfg index b93a36d2b50b..284077d687fa 100644 --- a/test/ELF/lit.local.cfg +++ b/test/ELF/lit.local.cfg @@ -1,2 +1 @@ config.suffixes = ['.test', '.s', '.ll'] - diff --git a/test/ELF/local-got-pie.s b/test/ELF/local-got-pie.s index 417f9d002034..b1b213af6659 100644 --- a/test/ELF/local-got-pie.s +++ b/test/ELF/local-got-pie.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -// RUN: ld.lld %t.o -o %t -pie +// RUN: ld.lld --hash-style=sysv %t.o -o %t -pie // RUN: llvm-readobj -s -r -d %t | FileCheck %s // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s diff --git a/test/ELF/local-got-shared.s b/test/ELF/local-got-shared.s index e4fd46997517..c858424cfd96 100644 --- a/test/ELF/local-got-shared.s +++ b/test/ELF/local-got-shared.s @@ -1,5 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -// RUN: ld.lld %t.o -o %t -shared +// RUN: ld.lld --hash-style=sysv %t.o -o %t -shared // RUN: llvm-readobj -s -r -d %t | FileCheck %s // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s diff --git a/test/ELF/local-got.s b/test/ELF/local-got.s index 7e6ef9e0be7e..17517f6a70ea 100644 --- a/test/ELF/local-got.s +++ b/test/ELF/local-got.s @@ -1,7 +1,7 @@ // 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: ld.lld -shared %t2.o -o %t2.so -// RUN: ld.lld %t.o %t2.so -o %t +// RUN: ld.lld --hash-style=sysv %t.o %t2.so -o %t // RUN: llvm-readobj -s -r -section-data %t | FileCheck %s // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s diff --git a/test/ELF/lto-plugin-ignore.s b/test/ELF/lto-plugin-ignore.s new file mode 100644 index 000000000000..2f45a43b2428 --- /dev/null +++ b/test/ELF/lto-plugin-ignore.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -plugin-opt=/foo/bar -plugin-opt=-fresolution=zed \ +# RUN: -plugin-opt=-pass-through=-lgcc -plugin-opt=-function-sections \ +# RUN: -plugin-opt=-data-sections -o /dev/null + +# RUN: not ld.lld %t -plugin-opt=-data-sectionssss \ +# RUN: -plugin-opt=-function-sectionsss 2>&1 | FileCheck %s +# CHECK: unknown option: -data-sectionsss +# CHECK: unknown option: -function-sectionsss diff --git a/test/ELF/lto/Inputs/data-ordering-lto.ll b/test/ELF/lto/Inputs/data-ordering-lto.ll new file mode 100644 index 000000000000..a95fa6d5a58a --- /dev/null +++ b/test/ELF/lto/Inputs/data-ordering-lto.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-scei-ps4" + +@pat = global i32 33, align 4 +@tin = global i32 33, align 4 +@dipsy = global i32 33, align 4 diff --git a/test/ELF/lto/Inputs/linker-script-symbols-ipo.ll b/test/ELF/lto/Inputs/linker-script-symbols-ipo.ll new file mode 100644 index 000000000000..c872f9e1dd52 --- /dev/null +++ b/test/ELF/lto/Inputs/linker-script-symbols-ipo.ll @@ -0,0 +1,9 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare i32 @bar() + +define i32 @_start() { + %1 = tail call i32 @bar() + ret i32 %1 +} diff --git a/test/ELF/lto/Inputs/symbol-ordering-lto.ll b/test/ELF/lto/Inputs/symbol-ordering-lto.ll new file mode 100644 index 000000000000..164659ce27ba --- /dev/null +++ b/test/ELF/lto/Inputs/symbol-ordering-lto.ll @@ -0,0 +1,10 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-scei-ps4" + +define i32 @tin() { + ret i32 22 +} + +define i32 @pat() { + ret i32 42 +} diff --git a/test/ELF/lto/cache.ll b/test/ELF/lto/cache.ll index 6731f522606f..5ab74f5c5457 100644 --- a/test/ELF/lto/cache.ll +++ b/test/ELF/lto/cache.ll @@ -7,7 +7,7 @@ ; Create two files that would be removed by cache pruning due to age. ; We should only remove files matching the pattern "llvmcache-*". ; RUN: touch -t 197001011200 %t.cache/llvmcache-foo %t.cache/foo -; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=1h -o %t3 %t2.o %t.o +; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=1h:prune_interval=0s -o %t3 %t2.o %t.o ; Two cached objects, plus a timestamp file and "foo", minus the file we removed. ; RUN: ls %t.cache | count 4 @@ -16,13 +16,21 @@ ; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo ; This should leave the file in place. -; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k -o %t3 %t2.o %t.o +; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k:prune_interval=0s -o %t3 %t2.o %t.o ; RUN: ls %t.cache | count 5 ; This should remove it. -; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k -o %t3 %t2.o %t.o +; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k:prune_interval=0s -o %t3 %t2.o %t.o ; RUN: ls %t.cache | count 4 +; Setting max number of files to 0 should disable the limit, not delete everything. +; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=0:prune_interval=0s -o %t3 %t2.o %t.o +; RUN: ls %t.cache | count 4 + +; Delete everything except for the timestamp, "foo" and one cache file. +; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=0s:cache_size=0%:cache_size_files=1:prune_interval=0s -o %t3 %t2.o %t.o +; RUN: ls %t.cache | count 3 + target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/ELF/lto/data-ordering-lto.s b/test/ELF/lto/data-ordering-lto.s new file mode 100644 index 000000000000..0364e587b908 --- /dev/null +++ b/test/ELF/lto/data-ordering-lto.s @@ -0,0 +1,27 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-scei-ps4 %s -o %t.o +# RUN: llvm-as %p/Inputs/data-ordering-lto.ll -o %t.bc + +# Set up the symbol file +# RUN: echo "tin " > %t_order_lto.txt +# RUN: echo "dipsy " >> %t_order_lto.txt +# RUN: echo "pat " >> %t_order_lto.txt + +# RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out +# RUN: llvm-readobj -elf-output-style=GNU -t %t2.out| FileCheck %s + +# Check that the order is tin -> dipsy -> pat. + +# CHECK: Symbol table '.symtab' contains 5 entries: +# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name +# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +# CHECK-NEXT: 1: 0000000000201000 0 NOTYPE GLOBAL DEFAULT 1 _start +# CHECK-NEXT: 2: 0000000000202004 4 OBJECT GLOBAL DEFAULT 2 dipsy +# CHECK-NEXT: 3: 0000000000202008 4 OBJECT GLOBAL DEFAULT 2 pat +# CHECK-NEXT: 4: 0000000000202000 4 OBJECT GLOBAL DEFAULT 2 tin + +.globl _start +_start: + movl $pat, %ecx + movl $dipsy, %ebx + movl $tin, %eax diff --git a/test/ELF/lto/keep-undefined.ll b/test/ELF/lto/keep-undefined.ll new file mode 100644 index 000000000000..cb0f4ce491f9 --- /dev/null +++ b/test/ELF/lto/keep-undefined.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86 +; This test checks that symbols which are specified in "-u" switches +; are kept over LTO if we link an executable. +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %tout -u foo +; RUN: llvm-nm %tout | FileCheck %s + +; CHECK: T foo + +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 @_start() { + call void @foo() + ret void +} diff --git a/test/ELF/lto/linker-script-symbols-assign.ll b/test/ELF/lto/linker-script-symbols-assign.ll new file mode 100644 index 000000000000..2ffdc823a484 --- /dev/null +++ b/test/ELF/lto/linker-script-symbols-assign.ll @@ -0,0 +1,48 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o + +; RUN: echo "foo = 1;" > %t.script +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps +; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s + +; CHECK-NOT: bar +; CHECK: Symbol { +; CHECK: Name: foo +; CHECK-NEXT: Value: 0x0 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: Binding: Weak +; CHECK-NEXT: Type: Object +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .bss.foo +; CHECK-NEXT: } +; CHECK-NEXT:] + +; RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=VAL +; VAL: Symbol { +; VAL: Name: foo +; VAL-NEXT: Value: 0x1 +; VAL-NEXT: Size: +; VAL-NEXT: Binding: Global +; VAL-NEXT: Type: None +; VAL-NEXT: Other: +; VAL-NEXT: Section: Absolute +; VAL-NEXT: } + +; RUN: echo "zed = 1;" > %t2.script +; RUN: ld.lld -m elf_x86_64 %t.o -o %t3 --script %t2.script +; RUN: llvm-readobj -symbols %t3 | FileCheck %s --check-prefix=ABS +; ABS: Symbol { +; ABS: Name: zed +; ABS-NEXT: Value: 0x1 +; ABS-NEXT: Size: 0 +; ABS-NEXT: Binding: Global +; ABS-NEXT: Type: None +; ABS-NEXT: Other: 0 +; ABS-NEXT: Section: Absolute +; ABS-NEXT: } + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +@foo = global i32 0 +@bar = global i32 0 diff --git a/test/ELF/lto/linker-script-symbols-ipo.ll b/test/ELF/lto/linker-script-symbols-ipo.ll new file mode 100644 index 000000000000..6ac1a83e1ec0 --- /dev/null +++ b/test/ELF/lto/linker-script-symbols-ipo.ll @@ -0,0 +1,32 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: llvm-as %S/Inputs/linker-script-symbols-ipo.ll -o %t2.o +; RUN: echo "bar = foo;" > %t.script + +;; Check that without linkerscript bar is inlined. +; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps +; RUN: llvm-objdump -d %t3 | FileCheck %s --check-prefix=IPO +; IPO: Disassembly of section .text: +; IPO: _start: +; IPO-NEXT: 201000: {{.*}} movl $1, %eax +; IPO-NEXT: 201005: {{.*}} retq + +;; Check that LTO does not do IPO for symbols assigned by script. +; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t4 --script %t.script -save-temps +; RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=NOIPO +; NOIPO: Disassembly of section .text: +; NOIPO: foo: +; NOIPO-NEXT: 201010: {{.*}} movl $2, %eax +; NOIPO: _start: +; NOIPO-NEXT: 201020: {{.*}} jmp -21 <foo> + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @bar() { + ret i32 1 +} + +define i32 @foo() { + ret i32 2 +} diff --git a/test/ELF/lto/linker-script-symbols.ll b/test/ELF/lto/linker-script-symbols.ll new file mode 100644 index 000000000000..c2a58b6e841d --- /dev/null +++ b/test/ELF/lto/linker-script-symbols.ll @@ -0,0 +1,29 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: echo "foo = bar;" > %t.script + +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 --script %t.script -save-temps +; RUN: llvm-readobj -symbols %t2.lto.o | FileCheck %s + +; CHECK-NOT: zed +; CHECK: Symbol { +; CHECK: Name: bar +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: +; CHECK-NEXT: Section: +; CHECK-NEXT: } +; CHECK-NOT: zed + +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 +} + +define void @zed() { + ret void +} diff --git a/test/ELF/lto/opt-level.ll b/test/ELF/lto/opt-level.ll index 1065ca775751..57fa3041ac65 100644 --- a/test/ELF/lto/opt-level.ll +++ b/test/ELF/lto/opt-level.ll @@ -2,18 +2,31 @@ ; 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 %t0 -m elf_x86_64 -e main --plugin-opt=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 +; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --plugin-opt=O2 %t.o +; RUN: llvm-nm %t2 | 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: FileCheck --check-prefix=INVALID1 %s +; INVALID1: invalid optimization level for LTO: 6 +; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=O6 %t.o 2>&1 | \ +; RUN: FileCheck --check-prefix=INVALID1 %s +; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=Ofoo %t.o 2>&1 | \ +; RUN: FileCheck --check-prefix=INVALID2 %s +; INVALID2: --plugin-opt: number expected, but got 'foo' + ; 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 +; RUN: FileCheck --check-prefix=INVALIDNEGATIVE1 %s +; INVALIDNEGATIVE1: invalid optimization level for LTO: 4294967295 +; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --plugin-opt=O-1 %t.o 2>&1 | \ +; RUN: FileCheck --check-prefix=INVALIDNEGATIVE2 %s +; INVALIDNEGATIVE2: invalid optimization level for LTO: 4294967295 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/ELF/lto/opt-remarks.ll b/test/ELF/lto/opt-remarks.ll index e29cc72bb3cc..19b141feb258 100644 --- a/test/ELF/lto/opt-remarks.ll +++ b/test/ELF/lto/opt-remarks.ll @@ -15,13 +15,13 @@ ; CHECK-NEXT: ret i32 %a.i ; CHECK-NEXT: } -; YAML: --- !Analysis +; YAML: --- !Passed ; YAML-NEXT: Pass: inline -; YAML-NEXT: Name: CanBeInlined +; YAML-NEXT: Name: Inlined ; YAML-NEXT: Function: main ; YAML-NEXT: Args: ; YAML-NEXT: - Callee: tinkywinky -; YAML-NEXT: - String: ' can be inlined into ' +; YAML-NEXT: - String: ' inlined into ' ; YAML-NEXT: - Caller: main ; YAML-NEXT: - String: ' with cost=' ; YAML-NEXT: - Cost: '0' @@ -29,19 +29,9 @@ ; YAML-NEXT: - Threshold: '337' ; YAML-NEXT: - String: ')' ; YAML-NEXT: ... -; YAML-NEXT: --- !Passed -; YAML-NEXT: Pass: inline -; YAML-NEXT: Name: Inlined -; YAML-NEXT: Function: main -; YAML-NEXT: Args: -; YAML-NEXT: - Callee: tinkywinky -; YAML-NEXT: - String: ' inlined into ' -; YAML-NEXT: - Caller: main -; YAML-NEXT: ... -; YAML-HOT: ... -; YAML-HOT: --- !Passed -; YAML-HOT: Pass: inline +; YAML-HOT: --- !Passed +; YAML-HOT-NEXT: Pass: inline ; YAML-HOT-NEXT: Name: Inlined ; YAML-HOT-NEXT: Function: main ; YAML-HOT-NEXT: Hotness: 300 @@ -49,6 +39,11 @@ ; YAML-HOT-NEXT: - Callee: tinkywinky ; YAML-HOT-NEXT: - String: ' inlined into ' ; YAML-HOT-NEXT: - Caller: main +; YAML-HOT-NEXT: - String: ' with cost=' +; YAML-HOT-NEXT: - Cost: '0' +; YAML-HOT-NEXT: - String: ' (threshold=' +; YAML-HOT-NEXT: - Threshold: '337' +; YAML-HOT-NEXT: - String: ')' ; YAML-HOT-NEXT: ... target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/test/ELF/lto/relocatable.ll b/test/ELF/lto/relocatable.ll new file mode 100644 index 000000000000..ef21f84a621a --- /dev/null +++ b/test/ELF/lto/relocatable.ll @@ -0,0 +1,55 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t1.o +; RUN: ld.lld %t1.o -r -o %t +; RUN: llvm-readobj -symbols %t | FileCheck %s + +; 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: +; CHECK-NEXT: Value: 0x0 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: Binding: Local +; CHECK-NEXT: Type: Section +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text +; CHECK-NEXT: } +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: +; CHECK-NEXT: Value: 0x0 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: Binding: Local +; CHECK-NEXT: Type: Section +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text.foo +; CHECK-NEXT: } +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: foo +; CHECK-NEXT: Value: 0x0 +; CHECK-NEXT: Size: 1 +; CHECK-NEXT: Binding: Global +; CHECK-NEXT: Type: Function +; CHECK-NEXT: Other: 0 +; CHECK-NEXT: Section: .text.foo +; 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" + +define void @foo() { + call void @bar() + ret void +} + +define internal void @bar() { + ret void +} diff --git a/test/ELF/lto/save-temps.ll b/test/ELF/lto/save-temps.ll index f7af99ed40af..c8e52ff4b4ec 100644 --- a/test/ELF/lto/save-temps.ll +++ b/test/ELF/lto/save-temps.ll @@ -9,6 +9,13 @@ ; RUN: llvm-nm a.out.lto.o | FileCheck %s ; RUN: llvm-dis a.out.0.0.preopt.bc +; RUN: rm -f a.out a.out.lto.bc a.out.lto.o +; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o --plugin-opt=save-temps +; RUN: llvm-nm a.out | FileCheck %s +; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s +; RUN: llvm-nm a.out.lto.o | FileCheck %s +; RUN: llvm-dis a.out.0.0.preopt.bc + target triple = "x86_64-unknown-linux-gnu" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" diff --git a/test/ELF/lto/section-name.ll b/test/ELF/lto/section-name.ll new file mode 100644 index 000000000000..483184716a07 --- /dev/null +++ b/test/ELF/lto/section-name.ll @@ -0,0 +1,35 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld %t.o -o %t.so -shared +; RUN: llvm-readelf -s %t.so | FileCheck %s +; RUN: ld.lld %t.o -o %t.so -shared --gc-sections +; RUN: llvm-readelf -s %t.so | FileCheck --check-prefix=GC %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@foo = hidden global i32 42, section "foo_section" +@bar = hidden global i32 42, section "bar_section" +@zed = hidden global i32 42, section "zed_section" + +@__start_foo_section = external global i32 +@__stop_bar_section = external global i32 + +define hidden i32* @use1() { + ret i32* @__start_foo_section +} + +define i32* @use2() { + ret i32* @__stop_bar_section +} + +; CHECK-NOT: zed_section +; CHECK: foo_section PROGBITS +; CHECK-NEXT: bar_section PROGBITS +; CHECK-NOT: zed_section + +; GC-NOT: zed_section +; GC-NOT: foo_section +; GC: bar_section PROGBITS +; GC-NOT: zed_section +; GC-NOT: foo_section diff --git a/test/ELF/lto/shlib-undefined.ll b/test/ELF/lto/shlib-undefined.ll index 0250ed761927..6d37bfa6b304 100644 --- a/test/ELF/lto/shlib-undefined.ll +++ b/test/ELF/lto/shlib-undefined.ll @@ -1,6 +1,6 @@ ; REQUIRES: x86 ; RUN: llvm-as %s -o %t.o -; RUN: echo .global __progname > %t2.s +; RUN: echo ".global __progname; .data; .dc.a __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 diff --git a/test/ELF/lto/symbol-ordering-lto.s b/test/ELF/lto/symbol-ordering-lto.s new file mode 100644 index 000000000000..4c29e54c476e --- /dev/null +++ b/test/ELF/lto/symbol-ordering-lto.s @@ -0,0 +1,25 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-scei-ps4 %s -o %t.o +# RUN: llvm-as %p/Inputs/symbol-ordering-lto.ll -o %t.bc + +# Set up the symbol file +# RUN: echo "tin " > %t_order_lto.txt +# RUN: echo "_start " >> %t_order_lto.txt +# RUN: echo "pat " >> %t_order_lto.txt + +# RUN: ld.lld --symbol-ordering-file %t_order_lto.txt %t.o %t.bc -o %t2.out +# RUN: llvm-readobj -elf-output-style=GNU -t %t2.out| FileCheck %s + +# Check that the order is tin -> _start -> pat. + +# CHECK: Symbol table '.symtab' contains 4 entries: +# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name +# CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +# CHECK-NEXT: 1: 0000000000201008 0 NOTYPE GLOBAL DEFAULT 1 _start +# CHECK-NEXT: 2: 0000000000201020 6 FUNC GLOBAL DEFAULT 1 pat +# CHECK-NEXT: 3: 0000000000201000 6 FUNC GLOBAL DEFAULT 1 tin + +.globl _start +_start: + call pat + call tin diff --git a/test/ELF/lto/thinlto.ll b/test/ELF/lto/thinlto.ll index 99dd19130d28..37d2b88131f6 100644 --- a/test/ELF/lto/thinlto.ll +++ b/test/ELF/lto/thinlto.ll @@ -6,14 +6,14 @@ ; First force single-threaded mode ; RUN: rm -f %t.lto.o %t1.lto.o ; RUN: ld.lld -save-temps --thinlto-jobs=1 -shared %t.o %t2.o -o %t -; RUN: llvm-nm %t.lto.o | FileCheck %s --check-prefix=NM1 -; RUN: llvm-nm %t1.lto.o | FileCheck %s --check-prefix=NM2 +; RUN: llvm-nm %t1.lto.o | FileCheck %s --check-prefix=NM1 +; RUN: llvm-nm %t2.lto.o | FileCheck %s --check-prefix=NM2 ; Next force multi-threaded mode ; RUN: rm -f %t2.lto.o %t21.lto.o ; RUN: ld.lld -save-temps --thinlto-jobs=2 -shared %t.o %t2.o -o %t2 -; RUN: llvm-nm %t2.lto.o | FileCheck %s --check-prefix=NM1 -; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM2 +; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM1 +; RUN: llvm-nm %t22.lto.o | FileCheck %s --check-prefix=NM2 ; NM1: T f ; NM1-NOT: U g diff --git a/test/ELF/lto/verify-invalid.ll b/test/ELF/lto/verify-invalid.ll index 16d6a3e54f12..e6138a3cca62 100644 --- a/test/ELF/lto/verify-invalid.ll +++ b/test/ELF/lto/verify-invalid.ll @@ -4,6 +4,8 @@ ; 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 +; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \ +; RUN: --plugin-opt=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" diff --git a/test/ELF/lto/wrap-1.ll b/test/ELF/lto/wrap-1.ll index 1dd9139808b6..83e09493fb5d 100644 --- a/test/ELF/lto/wrap-1.ll +++ b/test/ELF/lto/wrap-1.ll @@ -19,7 +19,7 @@ ; Make sure that the 'r' (linker redefined) bit is set for bar and __wrap_bar ; in the resolutions file. -; RESOLS: ,bar,r +; RESOLS: ,bar,xr ; RESOLS: ,__wrap_bar,px ; RESOLS: ,__real_bar,pxr diff --git a/test/ELF/lto/wrap-2.ll b/test/ELF/lto/wrap-2.ll index 06ef4064e4d1..4e82d4a0e8b0 100644 --- a/test/ELF/lto/wrap-2.ll +++ b/test/ELF/lto/wrap-2.ll @@ -28,11 +28,11 @@ ; THIN-NEXT: jmp{{.*}}<bar> ; Check that bar and __wrap_bar retain their original binding. -; BIND: Name: bar +; BIND: Name: __wrap_bar ; BIND-NEXT: Value: ; BIND-NEXT: Size: ; BIND-NEXT: Binding: Local -; BIND: Name: __wrap_bar +; BIND: Name: bar ; BIND-NEXT: Value: ; BIND-NEXT: Size: ; BIND-NEXT: Binding: Local diff --git a/test/ELF/many-alloc-sections.s b/test/ELF/many-alloc-sections.s index 648ab8250286..a022b9275d9f 100644 --- a/test/ELF/many-alloc-sections.s +++ b/test/ELF/many-alloc-sections.s @@ -1,8 +1,7 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o // RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script -// FIXME: threads are disable because the test is too slow with them (PR32942). -// RUN: ld.lld -T %t.script %t.o -o %t --no-threads +// RUN: ld.lld -T %t.script %t.o -o %t // RUN: llvm-readobj -t %t | FileCheck %s // Test that _start is in the correct section. diff --git a/test/ELF/many-sections.s b/test/ELF/many-sections.s index 7ef0f7ceaac4..e3b845f305a8 100644 --- a/test/ELF/many-sections.s +++ b/test/ELF/many-sections.s @@ -11,15 +11,12 @@ // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: dm (0xFF00) - -// FIXME: threads are disable because the test is too slow with them (PR32942). -// RUN: ld.lld %t -o %t2 --no-threads +// RUN: ld.lld %t -o %t2 // RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s // Test also with a linker script. // RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script -// FIXME: threads are disable because the test is too slow with them (PR32942). -// RUN: ld.lld -T %t.script %t -o %t2 --no-threads +// RUN: ld.lld -T %t.script %t -o %t2 // RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s // Test that _start is in the correct section. diff --git a/test/ELF/map-file.s b/test/ELF/map-file.s index 9dbbda0ff0e9..d1acabe28126 100644 --- a/test/ELF/map-file.s +++ b/test/ELF/map-file.s @@ -4,15 +4,21 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file2.s -o %t2.o // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file3.s -o %t3.o // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file4.s -o %t4.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file5.s -o %t5.o +// RUN: ld.lld -shared %t5.o -o %t5.so -soname dso // RUN: rm -f %t4.a // RUN: llvm-ar rc %t4.a %t4.o -// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -M | FileCheck -strict-whitespace %s -// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -print-map | FileCheck -strict-whitespace %s -// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=%t.map +// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a %t5.so -o %t -M | FileCheck -strict-whitespace %s +// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a %t5.so -o %t -print-map | FileCheck -strict-whitespace %s +// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a %t5.so -o %t -Map=%t.map // RUN: FileCheck -strict-whitespace %s < %t.map .global _start _start: + .quad sharedFoo + .quad sharedBar + callq sharedFunc1 + callq sharedFunc2 call baz .global _Z1fi _Z1fi: @@ -25,34 +31,62 @@ bar: .long zed - . local: .comm common,4,16 +.global abs +abs = 0xAB5 +labs = 0x1AB5 // CHECK: Address Size Align Out In Symbol -// CHECK-NEXT: 0000000000200158 0000000000000030 8 .eh_frame -// CHECK-NEXT: 0000000000200158 0000000000000030 8 <internal>:(.eh_frame) -// CHECK-NEXT: 0000000000201000 0000000000000015 4 .text -// CHECK-NEXT: 0000000000201000 000000000000000e 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text) +// CHECK-NEXT: 00000000002001c8 0000000000000078 8 .dynsym +// CHECK-NEXT: 00000000002001c8 0000000000000078 8 <internal>:(.dynsym) +// CHECK-NEXT: 0000000000200240 000000000000002c 8 .gnu.hash +// CHECK-NEXT: 0000000000200240 000000000000002c 8 <internal>:(.gnu.hash) +// CHECK-NEXT: 000000000020026c 0000000000000030 4 .hash +// CHECK-NEXT: 000000000020026c 0000000000000030 4 <internal>:(.hash) +// CHECK-NEXT: 000000000020029c 0000000000000031 1 .dynstr +// CHECK-NEXT: 000000000020029c 0000000000000031 1 <internal>:(.dynstr) +// CHECK-NEXT: 00000000002002d0 0000000000000030 8 .rela.dyn +// CHECK-NEXT: 00000000002002d0 0000000000000030 8 <internal>:(.rela.dyn) +// CHECK-NEXT: 0000000000200300 0000000000000030 8 .rela.plt +// CHECK-NEXT: 0000000000200300 0000000000000030 8 <internal>:(.rela.plt) +// CHECK-NEXT: 0000000000200330 0000000000000030 8 .eh_frame +// CHECK-NEXT: 0000000000200330 0000000000000030 8 <internal>:(.eh_frame) +// CHECK-NEXT: 0000000000201000 000000000000002d 4 .text +// CHECK-NEXT: 0000000000201000 0000000000000028 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text) // CHECK-NEXT: 0000000000201000 0000000000000000 0 _start -// CHECK-NEXT: 0000000000201005 0000000000000000 0 f(int) -// CHECK-NEXT: 000000000020100e 0000000000000000 0 local -// CHECK-NEXT: 0000000000201010 0000000000000002 4 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text) -// CHECK-NEXT: 0000000000201010 0000000000000000 0 foo -// CHECK-NEXT: 0000000000201011 0000000000000000 0 bar -// CHECK-NEXT: 0000000000201012 0000000000000000 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed) -// CHECK-NEXT: 0000000000201012 0000000000000000 0 zed -// CHECK-NEXT: 0000000000201014 0000000000000000 4 {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text) -// CHECK-NEXT: 0000000000201014 0000000000000000 0 bah -// CHECK-NEXT: 0000000000201014 0000000000000001 4 {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text) -// CHECK-NEXT: 0000000000201014 0000000000000000 0 baz -// CHECK-NEXT: 0000000000202000 0000000000000004 16 .bss -// CHECK-NEXT: 0000000000202000 0000000000000004 16 <internal>:(COMMON) +// CHECK-NEXT: 000000000020101f 0000000000000000 0 f(int) +// CHECK-NEXT: 0000000000201028 0000000000000000 0 local +// CHECK-NEXT: 0000000000201028 0000000000000002 4 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text) +// CHECK-NEXT: 0000000000201028 0000000000000000 0 foo +// CHECK-NEXT: 0000000000201029 0000000000000000 0 bar +// CHECK-NEXT: 000000000020102a 0000000000000000 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed) +// CHECK-NEXT: 000000000020102a 0000000000000000 0 zed +// CHECK-NEXT: 000000000020102c 0000000000000000 4 {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text) +// CHECK-NEXT: 000000000020102c 0000000000000000 0 bah +// CHECK-NEXT: 000000000020102c 0000000000000001 4 {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text) +// CHECK-NEXT: 000000000020102c 0000000000000000 0 baz +// CHECK-NEXT: 0000000000201030 0000000000000030 16 .plt +// CHECK-NEXT: 0000000000201030 0000000000000030 16 <internal>:(.plt) +// CHECK-NEXT: 0000000000201040 0000000000000000 0 sharedFunc1 +// CHECK-NEXT: 0000000000201050 0000000000000000 0 sharedFunc2 +// CHECK-NEXT: 0000000000202000 0000000000000028 8 .got.plt +// CHECK-NEXT: 0000000000202000 0000000000000028 8 <internal>:(.got.plt) +// CHECK-NEXT: 0000000000203000 0000000000000100 8 .dynamic +// CHECK-NEXT: 0000000000203000 0000000000000100 8 <internal>:(.dynamic) +// CHECK-NEXT: 0000000000204000 0000000000000010 16 .bss +// CHECK-NEXT: 0000000000204000 0000000000000004 16 {{.*}}{{/|\\}}map-file.s.tmp1.o:(COMMON) +// CHECK-NEXT: 0000000000204000 0000000000000004 0 common +// CHECK-NEXT: 0000000000204004 0000000000000004 1 <internal>:(.bss) +// CHECK-NEXT: 0000000000204004 0000000000000004 0 sharedFoo +// CHECK-NEXT: 0000000000204008 0000000000000008 1 <internal>:(.bss) +// CHECK-NEXT: 0000000000204008 0000000000000008 0 sharedBar // CHECK-NEXT: 0000000000000000 0000000000000008 1 .comment // CHECK-NEXT: 0000000000000000 0000000000000008 1 <internal>:(.comment) -// CHECK-NEXT: 0000000000000000 00000000000000f0 8 .symtab -// CHECK-NEXT: 0000000000000000 00000000000000f0 8 <internal>:(.symtab) -// CHECK-NEXT: 0000000000000000 0000000000000039 1 .shstrtab -// CHECK-NEXT: 0000000000000000 0000000000000039 1 <internal>:(.shstrtab) -// CHECK-NEXT: 0000000000000000 000000000000002f 1 .strtab -// CHECK-NEXT: 0000000000000000 000000000000002f 1 <internal>:(.strtab) +// CHECK-NEXT: 0000000000000000 0000000000000198 8 .symtab +// CHECK-NEXT: 0000000000000000 0000000000000198 8 <internal>:(.symtab) +// CHECK-NEXT: 0000000000000000 0000000000000084 1 .shstrtab +// CHECK-NEXT: 0000000000000000 0000000000000084 1 <internal>:(.shstrtab) +// CHECK-NEXT: 0000000000000000 000000000000006d 1 .strtab +// CHECK-NEXT: 0000000000000000 000000000000006d 1 <internal>:(.strtab) // RUN: not ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=/ 2>&1 \ // RUN: | FileCheck -check-prefix=FAIL %s diff --git a/test/ELF/merge-align.s b/test/ELF/merge-align.s new file mode 100644 index 000000000000..dea2fc2086e4 --- /dev/null +++ b/test/ELF/merge-align.s @@ -0,0 +1,34 @@ +// 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 -section-data %t.so | FileCheck %s + + .section .rodata.foo,"aM",@progbits,1 + .align 16 + .byte 0x42 + + .section .rodata.bar,"aM",@progbits,1 + .align 16 + .byte 0x42 + + .section .rodata.zed,"aM",@progbits,1 + .align 16 + .byte 0x41 + +// CHECK: Name: .rodata ( +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: 17 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 16 +// CHECK-NEXT: EntrySize: 1 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 42000000 00000000 00000000 00000000 | +// CHECK-NEXT: 0010: 41 | +// CHECK-NEXT: ) diff --git a/test/ELF/merge-entsize.s b/test/ELF/merge-entsize.s new file mode 100644 index 000000000000..c2e41ccf185a --- /dev/null +++ b/test/ELF/merge-entsize.s @@ -0,0 +1,27 @@ +// 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 -s %t | FileCheck %s + + .section .rodata.1,"aM",@progbits,1 + .byte 0x42 + + .section .rodata.2,"aM",@progbits,2 + .short 0x42 + +// Since the output section has both .rodata.1 and .rodata.2, it +// contains elements of different sizes and we use an entsize of 0. + +// CHECK: Name: .rodata ( +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_MERGE +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: +// CHECK-NEXT: Info: +// CHECK-NEXT: AddressAlignment: +// CHECK-NEXT: EntrySize: 0 diff --git a/test/ELF/merge-reloc.s b/test/ELF/merge-reloc.s index 934ac3b9384e..3dde6aa35297 100644 --- a/test/ELF/merge-reloc.s +++ b/test/ELF/merge-reloc.s @@ -3,14 +3,13 @@ # RUN: ld.lld %t.o -r -o %t-rel # RUN: llvm-readobj -s -section-data %t-rel | FileCheck %s -# When linker generates a relocatable object it should keep "merge" -# sections as-is: do not merge content, do not join regular and -# "merge" sections, do not joint "merge" sections with different -# entry size. +# When linker generates a relocatable object it does string merging in the same +# way as for regular link. It should keep SHF_MERGE flag and set proper sh_entsize +# value so that final link can perform the final merging optimization. # CHECK: Section { # CHECK: Index: -# CHECK: Name: .rodata +# CHECK: Name: .rodata.1 ( # CHECK-NEXT: Type: SHT_PROGBITS # CHECK-NEXT: Flags [ # CHECK-NEXT: SHF_ALLOC @@ -18,18 +17,18 @@ # CHECK-NEXT: ] # CHECK-NEXT: Address: # CHECK-NEXT: Offset: -# CHECK-NEXT: Size: 12 +# CHECK-NEXT: Size: 4 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 4 # CHECK-NEXT: EntrySize: 4 # CHECK-NEXT: SectionData ( -# CHECK-NEXT: 0000: 42000000 42000000 42000000 +# CHECK-NEXT: 0000: 42000000 # CHECK-NEXT: ) # CHECK-NEXT: } # CHECK: Section { # CHECK: Index: -# CHECK: Name: .rodata +# CHECK: Name: .rodata.2 ( # CHECK-NEXT: Type: SHT_PROGBITS # CHECK-NEXT: Flags [ # CHECK-NEXT: SHF_ALLOC @@ -37,13 +36,13 @@ # CHECK-NEXT: ] # CHECK-NEXT: Address: # CHECK-NEXT: Offset: -# CHECK-NEXT: Size: 16 +# CHECK-NEXT: Size: 8 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 # CHECK-NEXT: AddressAlignment: 8 # CHECK-NEXT: EntrySize: 8 # CHECK-NEXT: SectionData ( -# CHECK-NEXT: 0000: 42000000 42000000 42000000 42000000 +# CHECK-NEXT: 0000: 42000000 42000000 # CHECK-NEXT: ) # CHECK-NEXT: } # CHECK: Section { diff --git a/test/ELF/merge-string.s b/test/ELF/merge-string.s index 13c89f029711..d284d0ab523c 100644 --- a/test/ELF/merge-string.s +++ b/test/ELF/merge-string.s @@ -1,10 +1,10 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: ld.lld -O2 %t.o -o %t.so -shared +// RUN: ld.lld -O 2 %t.o -o %t.so -shared // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s -// RUN: ld.lld -O1 %t.o -o %t.so -shared +// RUN: ld.lld -O 1 %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: ld.lld -O 0 %t.o -o %t.so -shared // RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOMERGE %s .section .rodata1,"aMS",@progbits,1 @@ -34,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: ) @@ -52,9 +52,9 @@ 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: 0000: 62630061 626300 |bc.abc.| // NOTAIL-NEXT: ) // NOMERGE: Name: .rodata1 @@ -88,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 fba41346c536..b84d33a3411e 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: ) diff --git a/test/ELF/mips-26-n32-n64.s b/test/ELF/mips-26-n32-n64.s new file mode 100644 index 000000000000..2e24873332a7 --- /dev/null +++ b/test/ELF/mips-26-n32-n64.s @@ -0,0 +1,35 @@ +# Check R_MIPS_26 relocation handling in case of N64 ABIs. + +# RUN: llvm-mc -filetype=obj -triple=mips64-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=mips64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-objdump -d %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: __start: +# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120 +# CHECK-NEXT: 20004: 00 00 00 00 nop +# CHECK-NEXT: Disassembly of section .plt: +# CHECK-NEXT: .plt: +# CHECK-NEXT: 20010: 3c 0e 00 03 lui $14, 3 +# CHECK-NEXT: 20014: dd d9 00 08 ld $25, 8($14) +# CHECK-NEXT: 20018: 25 ce 00 08 addiu $14, $14, 8 +# CHECK-NEXT: 2001c: 03 0e c0 23 subu $24, $24, $14 +# CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra +# CHECK-NEXT: 20024: 00 18 c0 c2 srl $24, $24, 3 +# CHECK-NEXT: 20028: 03 20 f8 09 jalr $25 +# CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2 +# CHECK-NEXT: 20030: 3c 0f 00 03 lui $15, 3 +# CHECK-NEXT: 20034: 8d f9 00 18 lw $25, 24($15) +# CHECK-NEXT: 20038: 03 20 00 08 jr $25 +# CHECK-NEXT: 2003c: 25 f8 00 18 addiu $24, $15, 24 + + .text + .option pic0 + .global __start +__start: + jal foo0 diff --git a/test/ELF/mips-64-gprel-so.s b/test/ELF/mips-64-gprel-so.s index a390ec082b1b..437238ef5f26 100644 --- a/test/ELF/mips-64-gprel-so.s +++ b/test/ELF/mips-64-gprel-so.s @@ -12,7 +12,7 @@ # CHECK-NEXT: 10004: 03 99 e0 2d daddu $gp, $gp, $25 # CHECK-NEXT: 10008: 67 9c 7f f0 daddiu $gp, $gp, 32752 -# CHECK: 0000000000027ff0 *ABS* 00000000 .hidden _gp +# CHECK: 0000000000027ff0 .got 00000000 .hidden _gp # CHECK: 0000000000010000 .text 00000000 foo .text diff --git a/test/ELF/mips-64-rels.s b/test/ELF/mips-64-rels.s index 93d893aacbde..78671554b1cb 100644 --- a/test/ELF/mips-64-rels.s +++ b/test/ELF/mips-64-rels.s @@ -20,11 +20,11 @@ # ^-- %lo(0x17ff0) # CHECK: Contents of section .rodata: -# CHECK-NEXT: 10158 ffffffff fffe8014 -# ^-- 0x20004 - 0x37ff0 = 0xfffffffffffe8014 +# CHECK-NEXT: {{[0-9a-f]+}} ffffffff fffe8014 +# ^-- 0x20004 - 0x37ff0 = 0xfffffffffffe8014 # CHECK: 0000000000020004 .text 00000000 loc -# CHECK: 0000000000037ff0 *ABS* 00000000 .hidden _gp +# CHECK: 0000000000037ff0 .got 00000000 .hidden _gp # CHECK: 0000000000020000 .text 00000000 __start # REL: Relocations [ diff --git a/test/ELF/mips-align-err.s b/test/ELF/mips-align-err.s index 0c71ffba8cb9..a3bf134e4386 100644 --- a/test/ELF/mips-align-err.s +++ b/test/ELF/mips-align-err.s @@ -4,7 +4,7 @@ # 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: {{.*}}:(.text+0x1): improper alignment for relocation R_MIPS_PC16 +# CHECK: {{.*}}:(.text+0x1): improper alignment for relocation R_MIPS_PC16: 0xB is not aligned to 4 bytes .globl __start __start: diff --git a/test/ELF/mips-elf-flags-err.s b/test/ELF/mips-elf-flags-err.s index 28d93eb6bea7..e1ac8c5e015e 100644 --- a/test/ELF/mips-elf-flags-err.s +++ b/test/ELF/mips-elf-flags-err.s @@ -71,8 +71,14 @@ __start: # R1R2-NEXT: EF_MIPS_CPIC # R1R2-NEXT: ] -# R3R32: target ISA 'mips3' is incompatible with 'mips32': {{.*}}mips-elf-flags-err.s.tmp2.o -# R6OCTEON: target ISA 'mips64r6' is incompatible with 'octeon': {{.*}}mips-elf-flags-err.s.tmp2.o +# R3R32: error: incompatible target ISA: +# R3R32-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp1.o: mips3 +# R3R32-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp2.o: mips32 + +# R6OCTEON: error: incompatible target ISA: +# R6OCTEON-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp1.o: mips64r6 +# R6OCTEON-NEXT: >>> {{.+}}mips-elf-flags-err.s.tmp2.o: mips64r2 (octeon) + # FPABI: target floating point ABI '-mdouble-float' is incompatible with '-mgp32 -mfp64': {{.*}}mips-elf-flags-err.s.tmp2.o # OCTEON: Flags [ diff --git a/test/ELF/mips-elf-flags.s b/test/ELF/mips-elf-flags.s index f8f916c9353d..d2b3d929e2f5 100644 --- a/test/ELF/mips-elf-flags.s +++ b/test/ELF/mips-elf-flags.s @@ -35,6 +35,12 @@ # RUN: llvm-readobj -h -mips-abi-flags %t.exe \ # RUN: | FileCheck -check-prefix=OCTEON %s +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %S/Inputs/mips-fpic.s -o %t-mm.o +# RUN: ld.lld %t.o %t-mm.o -o %t.exe +# RUN: llvm-readobj -h -mips-abi-flags %t.exe | FileCheck -check-prefix=MICRO %s + # REQUIRES: mips .text @@ -170,3 +176,26 @@ __start: # OCTEON-NEXT: ] # OCTEON-NEXT: Flags 2: 0x0 # OCTEON-NEXT: } + +# MICRO: Flags [ +# MICRO-NEXT: EF_MIPS_ABI_O32 +# MICRO-NEXT: EF_MIPS_ARCH_32 +# MICRO-NEXT: EF_MIPS_CPIC +# MICRO-NEXT: EF_MIPS_MICROMIPS +# MICRO-NEXT: ] +# MICRO: MIPS ABI Flags { +# MICRO-NEXT: Version: 0 +# MICRO-NEXT: ISA: MIPS32 +# MICRO-NEXT: ISA Extension: None +# MICRO-NEXT: ASEs [ +# MICRO-NEXT: microMIPS +# MICRO-NEXT: ] +# MICRO-NEXT: FP ABI: Hard float (double precision) +# MICRO-NEXT: GPR size: 32 +# MICRO-NEXT: CPR1 size: 32 +# MICRO-NEXT: CPR2 size: 0 +# MICRO-NEXT: Flags 1 [ +# MICRO-NEXT: ODDSPREG +# MICRO-NEXT: ] +# MICRO-NEXT: Flags 2: 0x0 +# MICRO-NEXT: } diff --git a/test/ELF/mips-got-page-script.s b/test/ELF/mips-got-page-script.s new file mode 100644 index 000000000000..056e4fda77c2 --- /dev/null +++ b/test/ELF/mips-got-page-script.s @@ -0,0 +1,65 @@ +# Check calculation of MIPS GOT page address entries number +# when a linker script is provided. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -o %t.o %s +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.text) } \ +# RUN: .data 0x10000 : { *(.data) } }" > %t.script +# RUN: ld.lld -shared --script %t.script -o %t.so %t.o +# RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s + +# REQUIRES: mips + +# CHECK: Name: foo1 +# CHECK-NEXT: Value: 0x10000 +# CHECK: Name: foo2 +# CHECK-NEXT: Value: 0x20000 +# CHECK: Name: foo3 +# CHECK-NEXT: Value: 0x30000 +# CHECK: Name: foo4 +# CHECK-NEXT: Value: 0x40000 + +# CHECK: Local entries [ +# CHECK-BEXT: Entry { +# CHECK-BEXT: Address: +# CHECK-BEXT: Access: +# CHECK-BEXT: Initial: 0x10000 +# CHECK-BEXT: } +# CHECK-BEXT: Entry { +# CHECK-BEXT: Address: +# CHECK-BEXT: Access: +# CHECK-BEXT: Initial: 0x20000 +# CHECK-BEXT: } +# CHECK-BEXT: Entry { +# CHECK-BEXT: Address: +# CHECK-BEXT: Access: +# CHECK-BEXT: Initial: 0x30000 +# CHECK-BEXT: } +# CHECK-BEXT: Entry { +# CHECK-BEXT: Address: +# CHECK-BEXT: Access: +# CHECK-BEXT: Initial: 0x40000 +# CHECK-BEXT: } +# CHECK-BEXT: Entry { +# CHECK-BEXT: Address: +# CHECK-BEXT: Access: +# CHECK-BEXT: Initial: 0x50000 +# CHECK-BEXT: } +# CHECK-BEXT: ] + + .option pic2 + .text + ld $v0,%got_page(foo1)($gp) + ld $v0,%got_page(foo2)($gp) + ld $v0,%got_page(foo3)($gp) + ld $v0,%got_page(foo4)($gp) + + .data +foo1: + .space 0x10000 +foo2: + .space 0x10000 +foo3: + .space 0x10000 +foo4: + .word 0 diff --git a/test/ELF/mips-got-relocs.s b/test/ELF/mips-got-relocs.s index 4471bc210e2d..5b443e51938a 100644 --- a/test/ELF/mips-got-relocs.s +++ b/test/ELF/mips-got-relocs.s @@ -47,7 +47,7 @@ v1: # EXE_SYM: Sections: # EXE_SYM: .got 0000000c 0000000000030010 DATA # EXE_SYM: SYMBOL TABLE: -# EXE_SYM: 00038000 *ABS* 00000000 .hidden _gp +# EXE_SYM: 00038000 .got 00000000 .hidden _gp # ^-- .got + GP offset (0x7ff0) # EXE_SYM: 00030000 g .data 00000004 v1 @@ -71,7 +71,7 @@ v1: # DSO_SYM: Sections: # DSO_SYM: .got 0000000c 0000000000020010 DATA # DSO_SYM: SYMBOL TABLE: -# DSO_SYM: 00028000 *ABS* 00000000 .hidden _gp +# DSO_SYM: 00028000 .got 00000000 .hidden _gp # ^-- .got + GP offset (0x7ff0) # DSO_SYM: 00020000 g .data 00000004 v1 diff --git a/test/ELF/mips-got-script.s b/test/ELF/mips-got-script.s new file mode 100644 index 000000000000..da1858469863 --- /dev/null +++ b/test/ELF/mips-got-script.s @@ -0,0 +1,47 @@ +# Check number of got entries is adjusted for linker script-added space. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: echo "SECTIONS { .data : { *(.data.1); . += 0x10000; *(.data.2) } }" > %t.script +# RUN: ld.lld %t.o -shared -o %t.so -T %t.script +# RUN: llvm-readobj -mips-plt-got -dynamic-table %t.so | FileCheck %s + +# REQUIRES: mips + +# CHECK: 0x7000000A MIPS_LOCAL_GOTNO 5 +# ^-- 2 * header + 3 local entries +# CHECK: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: -32744 +# CHECK-NEXT: Initial: 0x0 +# ^-- loc1 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: -32740 +# CHECK-NEXT: Initial: 0x10000 +# ^-- loc2 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: -32736 +# CHECK-NEXT: Initial: 0x20000 +# ^-- redundant +# 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) + + .section .data.1,"aw",%progbits +loc1: + .word 0 + + .section .data.2,"aw",%progbits +loc2: + .word 0 diff --git a/test/ELF/mips-gp-disp.s b/test/ELF/mips-gp-disp.s index 62a2b1084530..7a0fd6409d18 100644 --- a/test/ELF/mips-gp-disp.s +++ b/test/ELF/mips-gp-disp.s @@ -24,7 +24,7 @@ # 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 .hidden _gp +# DIS: 00027ff0 .got 00000000 .hidden _gp # REL: Relocations [ # REL-NEXT: ] diff --git a/test/ELF/mips-gp-ext.s b/test/ELF/mips-gp-ext.s index 98b9cbc06d28..2fd21b7a9818 100644 --- a/test/ELF/mips-gp-ext.s +++ b/test/ELF/mips-gp-ext.s @@ -12,6 +12,13 @@ # RUN: echo "SECTIONS { \ # RUN: .text : { *(.text) } \ +# RUN: _gp = 0x100 + ABSOLUTE(.); \ +# RUN: .got : { *(.got) } }" > %t.rel.script +# RUN: ld.lld -shared -o %t.rel.so --script %t.rel.script %t.o +# RUN: llvm-objdump -s -t %t.rel.so | FileCheck --check-prefix=REL %s + +# RUN: echo "SECTIONS { \ +# RUN: .text : { *(.text) } \ # RUN: _gp = 0x200; \ # RUN: .got : { *(.got) } }" > %t.abs.script # RUN: ld.lld -shared -o %t.abs.so --script %t.abs.script %t.o diff --git a/test/ELF/mips-gp-local.s b/test/ELF/mips-gp-local.s index b77dbb8367ae..8bb3c236edf0 100644 --- a/test/ELF/mips-gp-local.s +++ b/test/ELF/mips-gp-local.s @@ -11,7 +11,7 @@ # CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 # CHECK-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752 -# CHECK: 00037ff0 *ABS* 00000000 .hidden _gp +# CHECK: 00037ff0 .got 00000000 .hidden _gp .text .globl __start diff --git a/test/ELF/mips-gprel32-relocs-gp0.s b/test/ELF/mips-gprel32-relocs-gp0.s index 4f1962bd683b..507224e05d15 100644 --- a/test/ELF/mips-gprel32-relocs-gp0.s +++ b/test/ELF/mips-gprel32-relocs-gp0.s @@ -22,14 +22,14 @@ # DSO: GP: 0x27FF0 # DUMP: Contents of section .rodata: -# DUMP: 00f4 ffff0004 ffff0008 -# ^ 0x10004 + 0x7ff0 - 0x27ff0 -# ^ 0x10008 + 0x7ff0 - 0x27ff0 +# DUMP: {{[0-9a-f]+}} ffff0004 ffff0008 +# ^ 0x10004 + 0x7ff0 - 0x27ff0 +# ^ 0x10008 + 0x7ff0 - 0x27ff0 # DUMP: SYMBOL TABLE: # DUMP: 00010008 .text 00000000 bar # DUMP: 00010004 .text 00000000 foo -# DUMP: 00027ff0 *ABS* 00000000 .hidden _gp +# DUMP: 00027ff0 .got 00000000 .hidden _gp # ERR: error: {{.*}}mips-gp0-non-zero.o: unsupported non-zero ri_gp_value diff --git a/test/ELF/mips-gprel32-relocs.s b/test/ELF/mips-gprel32-relocs.s index 1c877b12b297..047165f19ae4 100644 --- a/test/ELF/mips-gprel32-relocs.s +++ b/test/ELF/mips-gprel32-relocs.s @@ -21,11 +21,11 @@ v1: .gpword bar # CHECK: Contents of section .rodata: -# CHECK: 00f4 fffe8014 fffe8018 -# ^ 0x10004 - 0x27ff0 -# ^ 0x10008 - 0x27ff0 +# CHECK: {{[0-9a-f]+}} fffe8014 fffe8018 +# ^ 0x10004 - 0x27ff0 +# ^ 0x10008 - 0x27ff0 # CHECK: SYMBOL TABLE: # CHECK: 00010008 .text 00000000 bar # CHECK: 00010004 .text 00000000 foo -# CHECK: 00027ff0 *ABS* 00000000 .hidden _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 62e03c7b6760..c7229ee0da25 100644 --- a/test/ELF/mips-hilo-gp-disp.s +++ b/test/ELF/mips-hilo-gp-disp.s @@ -34,7 +34,7 @@ bar: # EXE: SYMBOL TABLE: # EXE: 0002000c .text 00000000 bar -# EXE: 00038000 *ABS* 00000000 .hidden _gp +# EXE: 00038000 .got 00000000 .hidden _gp # EXE: 00020000 .text 00000000 __start # SO: Disassembly of section .text: @@ -51,5 +51,5 @@ bar: # SO: SYMBOL TABLE: # SO: 0001000c .text 00000000 bar -# SO: 00028000 *ABS* 00000000 .hidden _gp +# SO: 00028000 .got 00000000 .hidden _gp # SO: 00010000 .text 00000000 __start diff --git a/test/ELF/mips-hilo-hi-only.s b/test/ELF/mips-hilo-hi-only.s index 97808b515da5..0858e3f6cd17 100644 --- a/test/ELF/mips-hilo-hi-only.s +++ b/test/ELF/mips-hilo-hi-only.s @@ -18,7 +18,7 @@ _label: # CHECK: Disassembly of section .text: # CHECK-NEXT: __start: -# CHECK-NEXT: 20000: 3c 08 00 02 lui $8, 2 +# CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3 # ^-- %hi(__start) w/o addend # CHECK-NEXT 20004: 21 08 00 08 addi $8, $8, 8 # ^-- %lo(_label) diff --git a/test/ELF/mips-micro-got.s b/test/ELF/mips-micro-got.s new file mode 100644 index 000000000000..8d077f2800f1 --- /dev/null +++ b/test/ELF/mips-micro-got.s @@ -0,0 +1,46 @@ +# Check microMIPS GOT relocations for O32 ABI. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mattr=micromips \ +# RUN: %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -mattr=micromips \ +# 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-readobj -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: -32744 +# CHECK-NEXT: Initial: 0x30000 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: -32740 +# CHECK-NEXT: Initial: 0x40000 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# 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: ] + + .text + .global __start +__start: + lw $4, %got(data)($28) + addiu $4, $4, %lo(data) + lw $25, %call16(foo0)($28) + + .data +data: + .word 0 diff --git a/test/ELF/mips-micro-got64.s b/test/ELF/mips-micro-got64.s new file mode 100644 index 000000000000..653bfbfbe8ce --- /dev/null +++ b/test/ELF/mips-micro-got64.s @@ -0,0 +1,48 @@ +# Check microMIPS GOT relocations for N64 ABI. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -mattr=micromips \ +# RUN: %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -mattr=micromips \ +# 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-readobj -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: -32736 +# CHECK-NEXT: Initial: 0x30000 +# CHECK-NEXT: } +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: -32728 +# CHECK-NEXT: Initial: 0x40000 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: -32720 +# CHECK-NEXT: Initial: 0x0 +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: foo0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .text + .global __start +__start: + lui $28, %hi(%neg(%gp_rel(foo0))) + addiu $28, $28, %lo(%neg(%gp_rel(foo0))) + lw $4, %got_page(data)($28) + addiu $4, $4, %got_ofst(data) + lw $25, %call16(foo0)($28) + + .data +data: + .word 0 diff --git a/test/ELF/mips-micro-jal.s b/test/ELF/mips-micro-jal.s new file mode 100644 index 000000000000..83826126f766 --- /dev/null +++ b/test/ELF/mips-micro-jal.s @@ -0,0 +1,155 @@ +# Check PLT creation for microMIPS to microMIPS calls. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1eb.o +# RUN: ld.lld -shared -o %teb.so %t1eb.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %s -o %t2eb.o +# RUN: ld.lld -o %teb.exe %t2eb.o %teb.so +# RUN: llvm-objdump -d -mattr=micromips %teb.exe | FileCheck --check-prefix=EB %s +# RUN: llvm-readobj -mips-plt-got %teb.exe | FileCheck --check-prefix=PLT %s + +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1el.o +# RUN: ld.lld -shared -o %tel.so %t1el.o +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -mattr=micromips %s -o %t2el.o +# RUN: ld.lld -o %tel.exe %t2el.o %tel.so +# RUN: llvm-objdump -d -mattr=micromips %tel.exe | FileCheck --check-prefix=EL %s +# RUN: llvm-readobj -mips-plt-got %tel.exe | FileCheck --check-prefix=PLT %s + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips -mcpu=mips32r6 %S/Inputs/mips-micro.s -o %t1eb.o +# RUN: ld.lld -shared -o %teb.so %t1eb.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips -mcpu=mips32r6 %s -o %t2eb.o +# RUN: ld.lld -o %teb.exe %t2eb.o %teb.so +# RUN: llvm-objdump -d -mattr=micromips %teb.exe | FileCheck --check-prefix=EBR6 %s + +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -mattr=micromips -mcpu=mips32r6 %S/Inputs/mips-micro.s -o %t1el.o +# RUN: ld.lld -shared -o %tel.so %t1el.o +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -mattr=micromips -mcpu=mips32r6 %s -o %t2el.o +# RUN: ld.lld -o %tel.exe %t2el.o %tel.so +# RUN: llvm-objdump -d -mattr=micromips %tel.exe | FileCheck --check-prefix=ELR6 %s + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1eb.o +# RUN: ld.lld -shared -o %teb.so %t1eb.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-fpic.s -o %t-reg.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %s -o %t2eb.o +# RUN: ld.lld --no-threads -o %teb.exe %t-reg.o %t2eb.o %teb.so +# RUN: llvm-objdump -d -mattr=micromips %teb.exe \ +# RUN: | FileCheck --check-prefix=MIXED %s + +# REQUIRES: mips + +# EB: Disassembly of section .plt: +# EB-NEXT: .plt: +# EB-NEXT: 20010: 79 80 3f fd addiupc $3, 65524 +# EB-NEXT: 20014: ff 23 00 00 lw $25, 0($3) +# EB-NEXT: 20018: 05 35 subu16 $2, $2, $3 +# EB-NEXT: 2001a: 25 25 srl16 $2, $2, 2 +# EB-NEXT: 2001c: 33 02 ff fe addiu $24, $2, -2 +# EB-NEXT: 20020: 0d ff move $15, $ra +# EB-NEXT: 20022: 45 f9 jalrs16 $25 +# EB-NEXT: 20024: 0f 83 move $gp, $3 +# EB-NEXT: 20026: 0c 00 nop +# EB-NEXT: 20028: 00 00 00 00 nop +# EB-NEXT: 2002c: 00 00 00 00 nop + +# EB-NEXT: 20030: 79 00 3f f7 addiupc $2, 65500 +# EB-NEXT: 20034: ff 22 00 00 lw $25, 0($2) +# EB-NEXT: 20038: 45 99 jr16 $25 +# EB-NEXT: 2003a: 0f 02 move $24, $2 + +# EL: Disassembly of section .plt: +# EL-NEXT: .plt: +# EL-NEXT: 20010: 80 79 fd 3f addiupc $3, 65524 +# EL-NEXT: 20014: 23 ff 00 00 lw $25, 0($3) +# EL-NEXT: 20018: 35 05 subu16 $2, $2, $3 +# EL-NEXT: 2001a: 25 25 srl16 $2, $2, 2 +# EL-NEXT: 2001c: 02 33 fe ff addiu $24, $2, -2 +# EL-NEXT: 20020: ff 0d move $15, $ra +# EL-NEXT: 20022: f9 45 jalrs16 $25 +# EL-NEXT: 20024: 83 0f move $gp, $3 +# EL-NEXT: 20026: 00 0c nop +# EL-NEXT: 20028: 00 00 00 00 nop +# EL-NEXT: 2002c: 00 00 00 00 nop + +# EL-NEXT: 20030: 00 79 f7 3f addiupc $2, 65500 +# EL-NEXT: 20034: 22 ff 00 00 lw $25, 0($2) +# EL-NEXT: 20038: 99 45 jr16 $25 +# EL-NEXT: 2003a: 02 0f move $24, $2 + +# EBR6: Disassembly of section .plt: +# EBR6-NEXT: .plt: +# EBR6-NEXT: 20010: 78 60 3f fd lapc $3, 65524 +# EBR6-NEXT: 20014: ff 23 00 00 lw $25, 0($3) +# EBR6-NEXT: 20018: 05 35 subu16 $2, $2, $3 +# EBR6-NEXT: 2001a: 25 25 srl16 $2, $2, 2 +# EBR6-NEXT: 2001c: 33 02 ff fe addiu $24, $2, -2 +# EBR6-NEXT: 20020: 0d ff move16 $15, $ra +# EBR6-NEXT: 20022: 0f 83 move16 $gp, $3 +# EBR6-NEXT: 20024: 47 2b jalr $25 + +# EBR6: 20030: 78 40 3f f7 lapc $2, 65500 +# EBR6-NEXT: 20034: ff 22 00 00 lw $25, 0($2) +# EBR6-NEXT: 20038: 0f 02 move16 $24, $2 +# EBR6-NEXT: 2003a: 47 23 jrc16 $25 + +# ELR6: Disassembly of section .plt: +# ELR6-NEXT: .plt: +# ELR6-NEXT: 20010: 60 78 fd 3f lapc $3, 65524 +# ELR6-NEXT: 20014: 23 ff 00 00 lw $25, 0($3) +# ELR6-NEXT: 20018: 35 05 subu16 $2, $2, $3 +# ELR6-NEXT: 2001a: 25 25 srl16 $2, $2, 2 +# ELR6-NEXT: 2001c: 02 33 fe ff addiu $24, $2, -2 +# ELR6-NEXT: 20020: ff 0d move16 $15, $ra +# ELR6-NEXT: 20022: 83 0f move16 $gp, $3 +# ELR6-NEXT: 20024: 2b 47 jalr $25 + +# ELR6: 20030: 40 78 f7 3f lapc $2, 65500 +# ELR6-NEXT: 20034: 22 ff 00 00 lw $25, 0($2) +# ELR6-NEXT: 20038: 02 0f move16 $24, $2 +# ELR6-NEXT: 2003a: 23 47 jrc16 $25 + +# MIXED: Disassembly of section .plt: +# MIXED-NEXT: .plt: +# MIXED-NEXT: 20020: 79 80 3f f9 addiupc $3, 65508 +# MIXED-NEXT: 20024: ff 23 00 00 lw $25, 0($3) +# MIXED-NEXT: 20028: 05 35 subu16 $2, $2, $3 +# MIXED-NEXT: 2002a: 25 25 srl16 $2, $2, 2 +# MIXED-NEXT: 2002c: 33 02 ff fe addiu $24, $2, -2 +# MIXED-NEXT: 20030: 0d ff move $15, $ra +# MIXED-NEXT: 20032: 45 f9 jalrs16 $25 +# MIXED-NEXT: 20034: 0f 83 move $gp, $3 +# MIXED-NEXT: 20036: 0c 00 nop +# MIXED-NEXT: 20038: 00 00 00 00 nop +# MIXED-NEXT: 2003c: 00 00 00 00 nop + +# MIXED-NEXT: 20040: 79 00 3f f3 addiupc $2, 65484 +# MIXED-NEXT: 20044: ff 22 00 00 lw $25, 0($2) +# MIXED-NEXT: 20048: 45 99 jr16 $25 +# MIXED-NEXT: 2004a: 0f 02 move $24, $2 + +# PLT: Entries [ +# PLT-NEXT: Entry { +# PLT-NEXT: Address: 0x3000C +# ^ 0x20030 + 65500 +# PLT-NEXT: Initial: +# PLT-NEXT: Value: 0x0 +# PLT-NEXT: Type: Function +# PLT-NEXT: Section: Undefined +# PLT-NEXT: Name: foo +# PLT-NEXT: } +# PLT-NEXT: ] + + .text + .set micromips + .global __start +__start: + jal foo diff --git a/test/ELF/mips-micro-plt.s b/test/ELF/mips-micro-plt.s new file mode 100644 index 000000000000..5671dc420c55 --- /dev/null +++ b/test/ELF/mips-micro-plt.s @@ -0,0 +1,91 @@ +# Check less-significant bit setup for microMIPS PLT. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %S/Inputs/mips-dynamic.s -o %t-dso.o +# RUN: ld.lld %t-dso.o -shared -o %t.so +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %s -o %t-exe.o +# RUN: ld.lld %t-exe.o %t.so -o %t.exe +# RUN: llvm-readobj -t -dt -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Symbols [ +# CHECK: Symbol { +# CHECK: Name: foo +# CHECK-NEXT: Value: 0x20008 +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Local +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other [ +# CHECK-NEXT: STO_MIPS_MICROMIPS +# CHECK-NEXT: STV_HIDDEN +# CHECK-NEXT: ] +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: __start +# CHECK-NEXT: Value: 0x20000 +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other [ +# CHECK-NEXT: STO_MIPS_MICROMIPS +# CHECK-NEXT: ] +# CHECK-NEXT: Section: .text +# CHECK-NEXT: } +# CHECK: Symbol { +# CHECK: Name: foo0 +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK: DynamicSymbols [ +# CHECK: Symbol { +# CHECK: Name: foo0 +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: +# CHECK-NEXT: Binding: Global +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } +# CHECK-NEXT: ] + +# CHECK: Primary GOT { +# CHECK: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: +# CHECK-NEXT: Initial: 0x20009 +# CHECK-NEXT: } +# CHECK: ] +# CHECK: } + +# CHECK: PLT GOT { +# CHECK: Entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Initial: 0x20011 +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Type: Function +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: foo0@ +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } + + .text + .set micromips + .global foo + .hidden foo + .global __start +__start: + lw $t0,%got(foo)($gp) + addi $t0,$t0,%lo(foo) +foo: + jal foo0 diff --git a/test/ELF/mips-micro-relocs.s b/test/ELF/mips-micro-relocs.s new file mode 100644 index 000000000000..3986711cc7f7 --- /dev/null +++ b/test/ELF/mips-micro-relocs.s @@ -0,0 +1,59 @@ +# Check handling of microMIPS relocations. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1eb.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %s -o %t2eb.o +# RUN: ld.lld -o %teb.exe %t1eb.o %t2eb.o +# RUN: llvm-objdump -d -t -mattr=micromips %teb.exe \ +# RUN: | FileCheck --check-prefixes=EB,SYM %s + +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1el.o +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -mattr=micromips %s -o %t2el.o +# RUN: ld.lld -o %tel.exe %t1el.o %t2el.o +# RUN: llvm-objdump -d -t -mattr=micromips %tel.exe \ +# RUN: | FileCheck --check-prefixes=EL,SYM %s + +# REQUIRES: mips + +# EB: __start: +# EB-NEXT: 20010: 41 a3 00 01 lui $3, 1 +# EB-NEXT: 20014: 30 63 7f df addiu $3, $3, 32735 +# EB-NEXT: 20018: fc 7c 80 18 lw $3, -32744($gp) +# EB-NEXT: 2001c: fc 63 80 18 lw $3, -32744($3) +# EB-NEXT: 20020: 8f 70 beqz16 $6, -32 +# EB-NEXT: 20022: 00 7e 00 00 sll $3, $fp, 0 +# EB-NEXT: 20026: cf ec b16 -40 +# EB-NEXT: 20028: 00 00 00 00 nop +# EB-NEXT: 2002c: 94 00 ff e8 b -44 + +# EL: __start: +# EL-NEXT: 20010: a3 41 01 00 lui $3, 1 +# EL-NEXT: 20014: 63 30 df 7f addiu $3, $3, 32735 +# EL-NEXT: 20018: 7c fc 18 80 lw $3, -32744($gp) +# EL-NEXT: 2001c: 63 fc 18 80 lw $3, -32744($3) +# EL-NEXT: 20020: 70 8f beqz16 $6, -32 +# EL-NEXT: 20022: 7e 00 00 00 sll $3, $fp, 0 +# EL-NEXT: 20026: ec cf b16 -40 +# EL-NEXT: 20028: 00 00 00 00 nop +# EL-NEXT: 2002c: 00 94 e8 ff b -44 + +# SYM: 00037ff0 .got 00000000 .hidden _gp +# SYM: 00020000 g F .text 00000000 foo +# SYM: 00020010 .text 00000000 __start + + .text + .set micromips + .global __start +__start: + lui $3, %hi(_gp_disp) # R_MICROMIPS_HI16 + addiu $3, $3, %lo(_gp_disp) # R_MICROMIPS_LO16 + + lw $3, %call16(foo)($gp) # R_MICROMIPS_CALL16 + lw $3, %got(foo)($3) # R_MICROMIPS_GOT16 + + beqz16 $6, foo # R_MICROMIPS_PC7_S1 + b16 foo # R_MICROMIPS_PC10_S1 + b foo # R_MICROMIPS_PC16_S1 diff --git a/test/ELF/mips-micro-thunks.s b/test/ELF/mips-micro-thunks.s new file mode 100644 index 000000000000..18a8fc33f53c --- /dev/null +++ b/test/ELF/mips-micro-thunks.s @@ -0,0 +1,47 @@ +# Check microMIPS thunk generation. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -mattr=micromips %s -o %t-eb.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: -position-independent -mattr=micromips \ +# RUN: %S/Inputs/mips-micro.s -o %t-eb-pic.o +# RUN: ld.lld -o %t-eb.exe %t-eb.o %t-eb-pic.o +# RUN: llvm-objdump -d -mattr=+micromips %t-eb.exe \ +# RUN: | FileCheck --check-prefix=EB %s + +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -mattr=micromips %s -o %t-el.o +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ +# RUN: -position-independent -mattr=micromips \ +# RUN: %S/Inputs/mips-micro.s -o %t-el-pic.o +# RUN: ld.lld -o %t-el.exe %t-el.o %t-el-pic.o +# RUN: llvm-objdump -d -mattr=+micromips %t-el.exe \ +# RUN: | FileCheck --check-prefix=EL %s + +# REQUIRES: mips + +# EB: __start: +# EB-NEXT: 20000: f4 01 00 04 jal 131080 <__microLA25Thunk_foo> +# EB-NEXT: 20004: 00 00 00 00 nop + +# EB: __microLA25Thunk_foo: +# EB-NEXT: 20008: 41 b9 00 02 lui $25, 2 +# EB-NEXT: 2000c: d4 01 00 10 j 131104 +# EB-NEXT: 20010: 33 39 00 21 addiu $25, $25, 33 +# EB-NEXT: 20014: 0c 00 nop + +# EL: __start: +# EL-NEXT: 20000: 01 f4 04 00 jal 131080 <__microLA25Thunk_foo> +# EL-NEXT: 20004: 00 00 00 00 nop + +# EL: __microLA25Thunk_foo: +# EL-NEXT: 20008: b9 41 02 00 lui $25, 2 +# EL-NEXT: 2000c: 01 d4 10 00 j 131104 +# EL-NEXT: 20010: 39 33 21 00 addiu $25, $25, 33 +# EL-NEXT: 20014: 00 0c nop + + .text + .set micromips + .global __start +__start: + jal foo diff --git a/test/ELF/mips-n32-rels.s b/test/ELF/mips-n32-rels.s index 7706e2591a33..954d4c30a157 100644 --- a/test/ELF/mips-n32-rels.s +++ b/test/ELF/mips-n32-rels.s @@ -38,11 +38,11 @@ # ^-- %lo(0x17ff0) # CHECK: Contents of section .rodata: -# CHECK-NEXT: 100d4 00020004 -# ^-- loc +# CHECK-NEXT: {{[0-9a-f]+}} 00020004 +# ^-- loc # CHECK: 00020004 .text 00000000 loc -# CHECK: 00037ff0 *ABS* 00000000 .hidden _gp +# CHECK: 00037ff0 .got 00000000 .hidden _gp # CHECK: 00020000 g F .text 00000000 __start # ELF: Format: ELF32-mips diff --git a/test/ELF/mips-out-of-bounds-call16-reloc.s b/test/ELF/mips-out-of-bounds-call16-reloc.s new file mode 100644 index 000000000000..64e9ab3aa7e2 --- /dev/null +++ b/test/ELF/mips-out-of-bounds-call16-reloc.s @@ -0,0 +1,29 @@ +# Check that we create an error on an out-of-bounds R_MIPS_CALL_16 + +# REQUIRES: mips +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o +# RUN: not ld.lld %t1.o -o %t.exe 2>&1 | FileCheck %s + +# CHECK: relocation R_MIPS_CALL16 out of range: 32768 is not in [-32768, 32767] + +.macro generate_values + .irp i, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + .irp j, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + .irp k, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + .irp l, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + .text + .globl sym_\i\j\k\l + sym_\i\j\k\l: + nop + lw $25,%call16(sym_\i\j\k\l)($28) + .endr + .endr + .endr + .endr +.endm + +generate_values + +.globl __start +__start: + nop diff --git a/test/ELF/no-inhibit-exec.s b/test/ELF/no-inhibit-exec.s index d0970d93f21e..afb7aed94c12 100644 --- a/test/ELF/no-inhibit-exec.s +++ b/test/ELF/no-inhibit-exec.s @@ -2,12 +2,16 @@ # RUN: not ld.lld %t -o %t2 # RUN: ld.lld %t --noinhibit-exec -o %t2 # RUN: llvm-objdump -d %t2 | FileCheck %s +# RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=RELOC # REQUIRES: x86 # CHECK: Disassembly of section .text: # CHECK-NEXT: _start # CHECK-NEXT: 201000: {{.*}} callq -2101253 +# RELOC: Relocations [ +# RELOC-NEXT: ] + # next code will not link without noinhibit-exec flag # because of undefined symbol _bar .globl _start diff --git a/test/ELF/non-abs-reloc.s b/test/ELF/non-abs-reloc.s index ef9ba4466133..454104cca076 100644 --- a/test/ELF/non-abs-reloc.s +++ b/test/ELF/non-abs-reloc.s @@ -1,7 +1,7 @@ // 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 -// CHECK: {{.*}}:(.dummy+0x0): has non-ABS reloc +// CHECK: {{.*}}:(.dummy+0x0): has non-ABS relocation R_X86_64_GOTPCREL against symbol 'foo' .globl _start _start: diff --git a/test/ELF/noplt-pie.s b/test/ELF/noplt-pie.s index 81e4410ac2c2..7f6ccf23d5cc 100644 --- a/test/ELF/noplt-pie.s +++ b/test/ELF/noplt-pie.s @@ -2,7 +2,7 @@ # 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: ld.lld --hash-style=sysv %t1.o %t2.so -o %t.out # RUN: llvm-readobj -s -r %t.out | FileCheck %s # CHECK: Section { diff --git a/test/ELF/pack-dyn-relocs.s b/test/ELF/pack-dyn-relocs.s new file mode 100644 index 000000000000..cb8674318ec6 --- /dev/null +++ b/test/ELF/pack-dyn-relocs.s @@ -0,0 +1,210 @@ +// REQUIRES: arm, aarch64 + +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-shared.s -o %t.a32.so.o +// RUN: ld.lld -shared %t.a32.so.o -o %t.a32.so +// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.a32 +// RUN: ld.lld -pie --pack-dyn-relocs=none %t.a32 %t.a32.so -o %t2.a32 +// RUN: llvm-readobj -relocations %t2.a32 | FileCheck --check-prefix=UNPACKED32 %s +// RUN: ld.lld -pie --pack-dyn-relocs=android %t.a32 %t.a32.so -o %t3.a32 +// RUN: llvm-readobj -s -dynamic-table %t3.a32 | FileCheck --check-prefix=PACKED32-HEADERS %s +// RUN: llvm-readobj -relocations %t3.a32 | FileCheck --check-prefix=PACKED32 %s + +// Unpacked should have the relative relocations in their natural order. +// UNPACKED32: 0x1000 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x100C R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x101C R_ARM_RELATIVE - 0x0 + +// UNPACKED32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x102C R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x103C R_ARM_RELATIVE - 0x0 + +// UNPACKED32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x104C R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x105C R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0 +// UNPACKED32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0 + +// UNPACKED32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0 +// UNPACKED32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0 + +// PACKED32-HEADERS: Index: 1 +// PACKED32-HEADERS-NEXT: Name: .dynsym + +// PACKED32-HEADERS: Name: .rel.dyn +// PACKED32-HEADERS-NEXT: Type: SHT_ANDROID_REL +// PACKED32-HEADERS-NEXT: Flags [ (0x2) +// PACKED32-HEADERS-NEXT: SHF_ALLOC (0x2) +// PACKED32-HEADERS-NEXT: ] +// PACKED32-HEADERS-NEXT: Address: [[ADDR:.*]] +// PACKED32-HEADERS-NEXT: Offset: [[ADDR]] +// PACKED32-HEADERS-NEXT: Size: [[SIZE:.*]] +// PACKED32-HEADERS-NEXT: Link: 1 +// PACKED32-HEADERS-NEXT: Info: 0 +// PACKED32-HEADERS-NEXT: AddressAlignment: 4 +// PACKED32-HEADERS-NEXT: EntrySize: 1 + +// PACKED32-HEADERS: 0x6000000F ANDROID_REL [[ADDR]] +// PACKED32-HEADERS: 0x60000010 ANDROID_RELSZ [[SIZE]] + +// Packed should have the larger groups of relative relocations first, +// i.e. the 8 and 9 followed by the 7. +// PACKED32: 0x1000 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1004 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1008 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x100C R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1010 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1014 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1018 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x101C R_ARM_RELATIVE - 0x0 + +// PACKED32-NEXT: 0x1044 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1048 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x104C R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1050 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1054 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1058 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x105C R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1060 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1064 R_ARM_RELATIVE - 0x0 + +// PACKED32-NEXT: 0x1024 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1028 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x102C R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1030 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1034 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x1038 R_ARM_RELATIVE - 0x0 +// PACKED32-NEXT: 0x103C R_ARM_RELATIVE - 0x0 + +// PACKED32-NEXT: 0x1020 R_ARM_ABS32 bar2 0x0 +// PACKED32-NEXT: 0x1040 R_ARM_ABS32 zed2 0x0 + +// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/shared2.s -o %t.a64.so.o +// RUN: ld.lld -shared %t.a64.so.o -o %t.a64.so +// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.a64 +// RUN: ld.lld -pie --pack-dyn-relocs=none %t.a64 %t.a64.so -o %t2.a64 +// RUN: llvm-readobj -relocations %t2.a64 | FileCheck --check-prefix=UNPACKED64 %s +// RUN: ld.lld -pie --pack-dyn-relocs=android %t.a64 %t.a64.so -o %t3.a64 +// RUN: llvm-readobj -s -dynamic-table %t3.a64 | FileCheck --check-prefix=PACKED64-HEADERS %s +// RUN: llvm-readobj -relocations %t3.a64 | FileCheck --check-prefix=PACKED64 %s + +// UNPACKED64: 0x10000 R_AARCH64_RELATIVE - 0x1 +// UNPACKED64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2 +// UNPACKED64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3 +// UNPACKED64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4 +// UNPACKED64-NEXT: 0x10020 R_AARCH64_RELATIVE - 0x5 +// UNPACKED64-NEXT: 0x10028 R_AARCH64_RELATIVE - 0x6 +// UNPACKED64-NEXT: 0x10030 R_AARCH64_RELATIVE - 0x7 +// UNPACKED64-NEXT: 0x10038 R_AARCH64_RELATIVE - 0x8 + +// UNPACKED64-NEXT: 0x10048 R_AARCH64_RELATIVE - 0x1 +// UNPACKED64-NEXT: 0x10050 R_AARCH64_RELATIVE - 0x2 +// UNPACKED64-NEXT: 0x10058 R_AARCH64_RELATIVE - 0x3 +// UNPACKED64-NEXT: 0x10060 R_AARCH64_RELATIVE - 0x4 +// UNPACKED64-NEXT: 0x10068 R_AARCH64_RELATIVE - 0x5 +// UNPACKED64-NEXT: 0x10070 R_AARCH64_RELATIVE - 0x6 +// UNPACKED64-NEXT: 0x10078 R_AARCH64_RELATIVE - 0x7 + +// UNPACKED64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x1 +// UNPACKED64-NEXT: 0x10090 R_AARCH64_RELATIVE - 0x2 +// UNPACKED64-NEXT: 0x10098 R_AARCH64_RELATIVE - 0x3 +// UNPACKED64-NEXT: 0x100A0 R_AARCH64_RELATIVE - 0x4 +// UNPACKED64-NEXT: 0x100A8 R_AARCH64_RELATIVE - 0x5 +// UNPACKED64-NEXT: 0x100B0 R_AARCH64_RELATIVE - 0x6 +// UNPACKED64-NEXT: 0x100B8 R_AARCH64_RELATIVE - 0x7 +// UNPACKED64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x8 +// UNPACKED64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x9 + +// UNPACKED64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1 +// UNPACKED64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0 + +// PACKED64: 0x10000 R_AARCH64_RELATIVE - 0x1 +// PACKED64-NEXT: 0x10008 R_AARCH64_RELATIVE - 0x2 +// PACKED64-NEXT: 0x10010 R_AARCH64_RELATIVE - 0x3 +// PACKED64-NEXT: 0x10018 R_AARCH64_RELATIVE - 0x4 +// PACKED64-NEXT: 0x10020 R_AARCH64_RELATIVE - 0x5 +// PACKED64-NEXT: 0x10028 R_AARCH64_RELATIVE - 0x6 +// PACKED64-NEXT: 0x10030 R_AARCH64_RELATIVE - 0x7 +// PACKED64-NEXT: 0x10038 R_AARCH64_RELATIVE - 0x8 + +// PACKED64-NEXT: 0x10088 R_AARCH64_RELATIVE - 0x1 +// PACKED64-NEXT: 0x10090 R_AARCH64_RELATIVE - 0x2 +// PACKED64-NEXT: 0x10098 R_AARCH64_RELATIVE - 0x3 +// PACKED64-NEXT: 0x100A0 R_AARCH64_RELATIVE - 0x4 +// PACKED64-NEXT: 0x100A8 R_AARCH64_RELATIVE - 0x5 +// PACKED64-NEXT: 0x100B0 R_AARCH64_RELATIVE - 0x6 +// PACKED64-NEXT: 0x100B8 R_AARCH64_RELATIVE - 0x7 +// PACKED64-NEXT: 0x100C0 R_AARCH64_RELATIVE - 0x8 +// PACKED64-NEXT: 0x100C8 R_AARCH64_RELATIVE - 0x9 + +// PACKED64-NEXT: 0x10048 R_AARCH64_RELATIVE - 0x1 +// PACKED64-NEXT: 0x10050 R_AARCH64_RELATIVE - 0x2 +// PACKED64-NEXT: 0x10058 R_AARCH64_RELATIVE - 0x3 +// PACKED64-NEXT: 0x10060 R_AARCH64_RELATIVE - 0x4 +// PACKED64-NEXT: 0x10068 R_AARCH64_RELATIVE - 0x5 +// PACKED64-NEXT: 0x10070 R_AARCH64_RELATIVE - 0x6 +// PACKED64-NEXT: 0x10078 R_AARCH64_RELATIVE - 0x7 + +// PACKED64-NEXT: 0x10040 R_AARCH64_ABS64 bar2 0x1 +// PACKED64-NEXT: 0x10080 R_AARCH64_ABS64 zed2 0x0 + +// PACKED64-HEADERS: Index: 1 +// PACKED64-HEADERS-NEXT: Name: .dynsym + +// PACKED64-HEADERS: Name: .rela.dyn +// PACKED64-HEADERS-NEXT: Type: SHT_ANDROID_RELA +// PACKED64-HEADERS-NEXT: Flags [ (0x2) +// PACKED64-HEADERS-NEXT: SHF_ALLOC (0x2) +// PACKED64-HEADERS-NEXT: ] +// PACKED64-HEADERS-NEXT: Address: [[ADDR:.*]] +// PACKED64-HEADERS-NEXT: Offset: [[ADDR]] +// PACKED64-HEADERS-NEXT: Size: [[SIZE:.*]] +// PACKED64-HEADERS-NEXT: Link: 1 +// PACKED64-HEADERS-NEXT: Info: 0 +// PACKED64-HEADERS-NEXT: AddressAlignment: 8 +// PACKED64-HEADERS-NEXT: EntrySize: 1 + +// PACKED64-HEADERS: 0x0000000060000011 ANDROID_RELA [[ADDR]] +// PACKED64-HEADERS: 0x0000000060000012 ANDROID_RELASZ [[SIZE]] + +.data +.dc.a __ehdr_start + 1 +.dc.a __ehdr_start + 2 +.dc.a __ehdr_start + 3 +.dc.a __ehdr_start + 4 +.dc.a __ehdr_start + 5 +.dc.a __ehdr_start + 6 +.dc.a __ehdr_start + 7 +.dc.a __ehdr_start + 8 +.dc.a bar2 + 1 + +.dc.a __ehdr_start + 1 +.dc.a __ehdr_start + 2 +.dc.a __ehdr_start + 3 +.dc.a __ehdr_start + 4 +.dc.a __ehdr_start + 5 +.dc.a __ehdr_start + 6 +.dc.a __ehdr_start + 7 +.dc.a zed2 + +.dc.a __ehdr_start + 1 +.dc.a __ehdr_start + 2 +.dc.a __ehdr_start + 3 +.dc.a __ehdr_start + 4 +.dc.a __ehdr_start + 5 +.dc.a __ehdr_start + 6 +.dc.a __ehdr_start + 7 +.dc.a __ehdr_start + 8 +.dc.a __ehdr_start + 9 diff --git a/test/ELF/pie-weak.s b/test/ELF/pie-weak.s index 99dbd47488fc..c4d64e3ff287 100644 --- a/test/ELF/pie-weak.s +++ b/test/ELF/pie-weak.s @@ -1,10 +1,13 @@ # REQUIRES: x86 # 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: ld.lld --hash-style=sysv -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: Section ({{.*}}) .rela.dyn { +# RELOCS-NEXT: R_X86_64_GLOB_DAT foo 0x0 +# RELOCS-NEXT: } # RELOCS-NEXT: ] .weak foo @@ -12,6 +15,6 @@ .globl _start _start: # DISASM: _start: -# DISASM-NEXT: 1000: 48 8b 05 69 10 00 00 movq 4201(%rip), %rax +# DISASM-NEXT: 1000: 48 8b 05 99 10 00 00 movq 4249(%rip), %rax # ^ .got - (.text + 7) mov foo@gotpcrel(%rip), %rax diff --git a/test/ELF/ppc-relocs.s b/test/ELF/ppc-relocs.s index 78542dd64a4c..5aa3474e6339 100644 --- a/test/ELF/ppc-relocs.s +++ b/test/ELF/ppc-relocs.s @@ -17,6 +17,20 @@ msg: # CHECK: msg: # CHECK: 11004: 66 6f 6f 00 oris 15, 19, 28416 +.section .R_PPC_ADDR16_HI,"ax",@progbits +.globl _starti +_starti: + lis 4,msgi@h +msgi: + .string "foo" + leni = . - msgi + +# CHECK: Disassembly of section .R_PPC_ADDR16_HI: +# CHECK: _starti: +# CHECK: 11008: 3c 80 00 01 lis 4, 1 +# CHECK: msgi: +# CHECK: 1100c: 66 6f 6f 00 oris 15, 19, 28416 + .section .R_PPC_ADDR16_LO,"ax",@progbits addi 4, 4, msg@l mystr: @@ -25,9 +39,9 @@ mystr: # CHECK: Disassembly of section .R_PPC_ADDR16_LO: # CHECK: .R_PPC_ADDR16_LO: -# CHECK: 11008: 38 84 10 04 addi 4, 4, 4100 +# CHECK: 11010: 38 84 10 04 addi 4, 4, 4100 # CHECK: mystr: -# CHECK: 1100c: 62 6c 61 68 ori 12, 19, 24936 +# CHECK: 11014: 62 6c 61 68 ori 12, 19, 24936 .align 2 .section .R_PPC_REL24,"ax",@progbits @@ -39,7 +53,7 @@ mystr: # CHECK: Disassembly of section .R_PPC_REL24: # CHECK: .FR_PPC_REL24: -# CHECK: 11014: 48 00 00 04 b .+4 +# CHECK: 1101c: 48 00 00 04 b .+4 .section .R_PPC_REL32,"ax",@progbits .globl .FR_PPC_REL32 @@ -50,7 +64,7 @@ mystr: # CHECK: Disassembly of section .R_PPC_REL32: # CHECK: .FR_PPC_REL32: -# CHECK: 11018: 00 00 00 04 +# CHECK: 11020: 00 00 00 04 .section .R_PPC_ADDR32,"ax",@progbits .globl .FR_PPC_ADDR32 @@ -61,4 +75,16 @@ mystr: # CHECK: Disassembly of section .R_PPC_ADDR32: # CHECK: .FR_PPC_ADDR32: -# CHECK: 1101c: 00 01 10 20 +# CHECK: 11024: 00 01 10 28 + +.align 2 +.section .R_PPC_PLTREL24,"ax",@progbits +.globl .R_PPC_PLTREL24 +.FR_PPC_PLTREL24: + b .Lfoox4@PLT +.section .R_PPC_PLTREL24_2,"ax",@progbits +.Lfoox4: + +# CHECK: Disassembly of section .R_PPC_PLTREL24: +# CHECK: .R_PPC_PLTREL24: +# CHECK: 11028: 48 00 00 04 b .+4 diff --git a/test/ELF/ppc64-addr16-error.s b/test/ELF/ppc64-addr16-error.s index 2bc8ef2ae4d7..f16ca69957a3 100644 --- a/test/ELF/ppc64-addr16-error.s +++ b/test/ELF/ppc64-addr16-error.s @@ -5,4 +5,4 @@ .short sym+65539 -// CHECK: relocation R_PPC64_ADDR16 out of range +// CHECK: relocation R_PPC64_ADDR16 out of range: 65539 is not in [-32768, 32767] diff --git a/test/ELF/pr34660.s b/test/ELF/pr34660.s new file mode 100644 index 000000000000..7c78bbc11c7b --- /dev/null +++ b/test/ELF/pr34660.s @@ -0,0 +1,25 @@ +# REQUIRES: aarch64 + +# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o +# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t +# RUN: llvm-objdump %t -d | FileCheck %s --check-prefix=DISASM +# RUN: llvm-readobj -elf-output-style=GNU %t -t | FileCheck %s --check-prefix=SYM + +# It would be much easier to understand/read this test if llvm-objdump would print +# the immediates in hex. +# IMM = hex(65540) = 0x10004 +# PC = 0x10000 +# As the relocation is PC-relative, IMM + PC = 0x20004 which is the VA of the +# correct symbol. + +# DISASM: Disassembly of section .text: +# DISASM-NEXT: $x.0: +# DISASM-NEXT: 10000: 28 00 08 58 ldr x8, #65540 + +# SYM: Symbol table '.symtab' +# SYM: 0000000000020004 0 NOTYPE LOCAL DEFAULT 5 patatino + + ldr x8, patatino + .data + .zero 4 +patatino: diff --git a/test/ELF/pr34872.s b/test/ELF/pr34872.s new file mode 100644 index 000000000000..c656be2a9279 --- /dev/null +++ b/test/ELF/pr34872.s @@ -0,0 +1,14 @@ +# RUN: llvm-mc %s -filetype=obj -triple=x86_64-pc-linux -o %t.o +# RUN: llvm-mc %p/Inputs/undefined-error.s -filetype=obj \ +# RUN: -triple=x86_64-pc-linux -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t2.so +# RUN: not ld.lld %t2.so %t.o 2>&1 | FileCheck %s + +# CHECK: undefined symbol: fmod +# Check we're not emitting other diagnostics for this symbol. +# CHECK-NOT: fmod + +.global main + +main: + callq fmod diff --git a/test/ELF/progname.s b/test/ELF/progname.s index be8ab9e31c4f..ecd0fd872347 100644 --- a/test/ELF/progname.s +++ b/test/ELF/progname.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -// RUN: echo .global __progname > %t2.s +// RUN: echo ".global __progname; .data; .dc.a __progname" > %t2.s // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so // RUN: ld.lld -o %t %t.o %t2.so diff --git a/test/ELF/relocatable-comdat2.s b/test/ELF/relocatable-comdat2.s new file mode 100644 index 000000000000..2643e645fda9 --- /dev/null +++ b/test/ELF/relocatable-comdat2.s @@ -0,0 +1,35 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -r %t.o -o %t +# RUN: llvm-readobj -elf-section-groups -s %t | FileCheck %s + +## Check .foo was not merged. +# CHECK: Sections [ +# CHECK: Name: .foo +# CHECK: Name: .foo +# CHECK: Name: .foo + +# CHECK: Groups { +# CHECK-NEXT: Group { +# CHECK-NEXT: Name: .group +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Type: COMDAT +# CHECK-NEXT: Signature: bar +# CHECK-NEXT: Section(s) in group [ +# CHECK-NEXT: .foo (3) +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: Group { +# CHECK-NEXT: Name: .group +# CHECK-NEXT: Index: 4 +# CHECK-NEXT: Type: COMDAT +# CHECK-NEXT: Signature: zed +# CHECK-NEXT: Section(s) in group [ +# CHECK-NEXT: .foo (5) +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } + +.section .foo,"axG",@progbits,bar,comdat +.section .foo,"axG",@progbits,zed,comdat +.section .foo,"ax",@progbits diff --git a/test/ELF/relocatable-common.s b/test/ELF/relocatable-common.s index 3ead775492fc..698380b650fc 100644 --- a/test/ELF/relocatable-common.s +++ b/test/ELF/relocatable-common.s @@ -30,7 +30,10 @@ # DEFCOMM-NEXT: Binding: Global # DEFCOMM-NEXT: Type: Object # DEFCOMM-NEXT: Other: 0 -# DEFCOMM-NEXT: Section: COMMON (0x2) +# DEFCOMM-NEXT: Section: COMMON # DEFCOMM-NEXT: } +# RUN: not ld.lld -shared --no-define-common %t1.o -o %t 2>&1 | FileCheck --check-prefix=ERROR %s +# ERROR: error: -no-define-common not supported in non relocatable output + .comm common,4,4 diff --git a/test/ELF/relocatable-compressed-input.s b/test/ELF/relocatable-compressed-input.s index 3c0199c33f7d..47d8c111452d 100644 --- a/test/ELF/relocatable-compressed-input.s +++ b/test/ELF/relocatable-compressed-input.s @@ -24,11 +24,11 @@ # CHECK-NEXT: AddressAlignment: 1 # CHECK-NEXT: EntrySize: 1 # CHECK-NEXT: SectionData ( -# CHECK-NEXT: 0000: {{.*}} |short unsigned i| -# CHECK-NEXT: 0010: {{.*}} |nt.unsigned int.| -# CHECK-NEXT: 0020: {{.*}} |long unsigned in| -# CHECK-NEXT: 0030: {{.*}} |t.char.unsigned | -# CHECK-NEXT: 0040: {{.*}} |char.| +# CHECK-NEXT: 0000: {{.*}} |long unsigned in| +# CHECK-NEXT: 0010: {{.*}} |t.unsigned char.| +# CHECK-NEXT: 0020: {{.*}} |unsigned int.cha| +# CHECK-NEXT: 0030: {{.*}} |r.short unsigned| +# CHECK-NEXT: 0040: {{.*}} | int.| # CHECK-NEXT: ) # CHECK-NEXT: } diff --git a/test/ELF/relocatable.s b/test/ELF/relocatable.s index 00572d07cbb9..7cb2a084c935 100644 --- a/test/ELF/relocatable.s +++ b/test/ELF/relocatable.s @@ -81,7 +81,7 @@ # CHECKEXE-NEXT: Version: 1 # CHECKEXE-NEXT: Entry: 0x201000 # CHECKEXE-NEXT: ProgramHeaderOffset: 0x40 -# CHECKEXE-NEXT: SectionHeaderOffset: 0x11F8 +# CHECKEXE-NEXT: SectionHeaderOffset: 0x21A0 # CHECKEXE-NEXT: Flags [ # CHECKEXE-NEXT: ] # CHECKEXE-NEXT: HeaderSize: 64 diff --git a/test/ELF/relocation-b-aarch64.test b/test/ELF/relocation-b-aarch64.test new file mode 100644 index 000000000000..24bf4b74ef92 --- /dev/null +++ b/test/ELF/relocation-b-aarch64.test @@ -0,0 +1,48 @@ +# REQUIRES: aarch64 + +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o -o %t.out +# RUN: llvm-objdump -d -triple=aarch64-none-linux %t.out | FileCheck %s + +# Check that the R_AARCH64_JUMP26 writes the branch opcode as well as the +# immediate. We use this property to overwrite instructions with a branch. + +# CHECK: Disassembly of section .text: +# CHECK-NEXT: foo: +# CHECK-NEXT: 20000: 01 00 00 14 b #4 +# CHECK: bar: +# CHECK-NEXT: 20004: ff ff ff 17 b #-4 + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 +Sections: + - Type: SHT_PROGBITS + Name: .text + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Content: "0000000000000000" + - Type: SHT_RELA + Name: .rela.text + Link: .symtab + Info: .text + Relocations: + - Offset: 0 + Symbol: bar + Type: R_AARCH64_JUMP26 + - Offset: 4 + Symbol: foo + Type: R_AARCH64_JUMP26 + +Symbols: + Local: + - Type: STT_FUNC + Section: .text + Name: foo + Value: 0 + - Type: STT_FUNC + Section: .text + Name: bar + Value: 4 diff --git a/test/ELF/relocation-copy-alias.s b/test/ELF/relocation-copy-alias.s index 15712e39bc93..f2251bbeefc2 100644 --- a/test/ELF/relocation-copy-alias.s +++ b/test/ELF/relocation-copy-alias.s @@ -1,8 +1,10 @@ // 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: ld.lld --hash-style=sysv -shared %t2.o -o %t.so +// RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t3 +// RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t3 | FileCheck %s +// RUN: ld.lld --hash-style=sysv --gc-sections %t.o %t.so -o %t3 // RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t3 | FileCheck %s .global _start @@ -61,7 +63,7 @@ movl $5, b2 // CHECK: Name: b3 // CHECK-NEXT: Value: [[B]] // CHECK-NEXT: Size: 1 -// CHECK-NEXT: Binding: Weak +// CHECK-NEXT: Binding: Global // CHECK-NEXT: Type: Object (0x1) // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .bss diff --git a/test/ELF/relocation-copy-align-common.s b/test/ELF/relocation-copy-align-common.s index a94c208a8b22..56eab76cbf81 100644 --- a/test/ELF/relocation-copy-align-common.s +++ b/test/ELF/relocation-copy-align-common.s @@ -3,7 +3,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \ # RUN: %p/Inputs/relocation-copy-align-common.s -o %t2.o # RUN: ld.lld -shared %t2.o -o %t.so -# RUN: ld.lld %t.o %t.so -o %t3 +# RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t3 # RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s # CHECK: Section { diff --git a/test/ELF/relocation-copy-flags.s b/test/ELF/relocation-copy-flags.s index 4d97e3d95d24..3f74bade3347 100644 --- a/test/ELF/relocation-copy-flags.s +++ b/test/ELF/relocation-copy-flags.s @@ -3,7 +3,7 @@ // 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: ld.lld --hash-style=sysv %t.o %t2.so -o %t.exe // RUN: llvm-readobj -s -section-data -r %t.exe | FileCheck %s .global _start diff --git a/test/ELF/relocation-copy-relro.s b/test/ELF/relocation-copy-relro.s index 1684c409e349..947c6c73f674 100644 --- a/test/ELF/relocation-copy-relro.s +++ b/test/ELF/relocation-copy-relro.s @@ -2,7 +2,7 @@ // 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-relro.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t.so -// RUN: ld.lld %t.o %t.so -o %t3 +// RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t3 // RUN: llvm-readobj -program-headers -s -r %t3 | FileCheck %s // CHECK: Name: .bss.rel.ro (48) diff --git a/test/ELF/relocation-i686.s b/test/ELF/relocation-i686.s index 4bb55d9684b0..3986357d66f2 100644 --- a/test/ELF/relocation-i686.s +++ b/test/ELF/relocation-i686.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t // 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 %t2.so -o %t2 +// RUN: ld.lld --hash-style=sysv %t %t2.so -o %t2 // RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=ADDR %s // RUN: llvm-objdump -d %t2 | FileCheck %s // REQUIRES: x86 diff --git a/test/ELF/relocation-relative-weak.s b/test/ELF/relocation-relative-weak.s index c525012acf67..7f28fced7116 100644 --- a/test/ELF/relocation-relative-weak.s +++ b/test/ELF/relocation-relative-weak.s @@ -4,6 +4,7 @@ # RUN: llvm-readobj -dyn-relocations %t | FileCheck %s # CHECK: Dynamic Relocations { +# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT w 0x0 # CHECK-NEXT: } .globl _start diff --git a/test/ELF/relocation.s b/test/ELF/relocation.s index 77c766960f46..3359a8badda6 100644 --- a/test/ELF/relocation.s +++ b/test/ELF/relocation.s @@ -1,7 +1,7 @@ // 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/shared.s -o %t2 // RUN: ld.lld %t2 -o %t2.so -shared -// RUN: ld.lld %t %t2.so -o %t3 +// RUN: ld.lld --hash-style=sysv %t %t2.so -o %t3 // RUN: llvm-readobj -s %t3 | FileCheck --check-prefix=SEC %s // RUN: llvm-objdump -s -d %t3 | FileCheck %s // REQUIRES: x86 diff --git a/test/ELF/relro-copyrel-bss-script.s b/test/ELF/relro-copyrel-bss-script.s new file mode 100644 index 000000000000..5f3b981cae98 --- /dev/null +++ b/test/ELF/relro-copyrel-bss-script.s @@ -0,0 +1,40 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o +// RUN: ld.lld -shared %t.o %t2.o -o %t.so + +// A linker script that will map .bss.rel.ro into .bss. +// RUN: echo "SECTIONS { \ +// RUN: .bss : { *(.bss) *(.bss.*) } \ +// RUN: } " > %t.script + +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o +// RUN: ld.lld %t3.o %t.so -z relro -o %t --script=%t.script 2>&1 +// RUN: llvm-readobj --program-headers %t | FileCheck %s + .section .text, "ax", @progbits + .global bar + .global foo + .global _start +_start: + callq bar + // Will produce .bss.rel.ro that will match in .bss, this will lose + // the relro property of the copy relocation. + .quad foo + + // Non relro bss + .bss + // make large enough to affect PT_GNU_RELRO MemSize if this was marked + // as relro. + .space 0x2000 + +// CHECK: Type: PT_GNU_RELRO (0x6474E552) +// CHECK-NEXT: Offset: +// CHECK-NEXT: VirtualAddress: +// CHECK-NEXT: PhysicalAddress: +// CHECK-NEXT: FileSize: +// CHECK-NEXT: MemSize: 4096 +// CHECK-NEXT: Flags [ (0x4) +// CHECK-NEXT: PF_R (0x4) +// CHECK-NEXT: ] +// CHECK-NEXT: Alignment: 1 +// CHECK-NEXT: } diff --git a/test/ELF/relro-non-contiguous-script-data.s b/test/ELF/relro-non-contiguous-script-data.s new file mode 100644 index 000000000000..c2332d14a982 --- /dev/null +++ b/test/ELF/relro-non-contiguous-script-data.s @@ -0,0 +1,25 @@ +// REQUIRES: x86 + +// RUN: echo "SECTIONS { \ +// RUN: .dynamic : { *(.dynamic) } \ +// RUN: .non_ro : { . += 1; } \ +// RUN: .jcr : { *(.jcr) } \ +// RUN: } " > %t.script +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: not ld.lld --export-dynamic %t.o -o %t --script=%t.script 2>&1 | FileCheck %s + +// RUN: echo "SECTIONS { \ +// RUN: .dynamic : { *(.dynamic) } \ +// RUN: .non_ro : { BYTE(1); } \ +// RUN: .jcr : { *(.jcr) } \ +// RUN: } " > %t2.script +// RUN: not ld.lld --export-dynamic %t.o -o %t --script=%t2.script 2>&1 | FileCheck %s + +// CHECK: error: section: .jcr is not contiguous with other relro sections + +.global _start +_start: + + // non-empty relro section + .section .jcr, "aw", @progbits + .quad 0 diff --git a/test/ELF/relro-non-contiguous.s b/test/ELF/relro-non-contiguous.s new file mode 100644 index 000000000000..ce6680860edf --- /dev/null +++ b/test/ELF/relro-non-contiguous.s @@ -0,0 +1,28 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o +// RUN: ld.lld -shared %t.o %t2.o -o %t.so + +// Place the .got.plt (non relro) immediately after .dynamic. This is the +// reverse order of the non-linker script case. The linker created .bss.rel.ro +// section will be placed after .got.plt causing the relro to be non-contiguous. +// RUN: echo "SECTIONS { \ +// RUN: .dynamic : { *(.dynamic) } \ +// RUN: .got.plt : { *(.got.plt) } \ +// RUN: } " > %t.script +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o + +// Expect error for non-contiguous relro +// RUN: not ld.lld %t3.o %t.so -z relro -o %t --script=%t.script 2>&1 | FileCheck %s +// No error when we do not request relro. +// RUN: ld.lld %t3.o %t.so -z norelro -o %t --script=%t.script +// REQUIRES: x86 + +// CHECK: error: section: .bss.rel.ro is not contiguous with other relro sections + .section .text, "ax", @progbits + .global _start + .global bar + .global foo +_start: + .quad bar + .quad foo + diff --git a/test/ELF/relro-omagic.s b/test/ELF/relro-omagic.s index 6e9d59a35279..97c3a812406d 100644 --- a/test/ELF/relro-omagic.s +++ b/test/ELF/relro-omagic.s @@ -1,7 +1,7 @@ # 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: ld.lld -shared %t2.o -o %t2.so -soname relro-omagic.s.tmp2.so -# RUN: ld.lld -N %t.o %t2.so -o %t +# RUN: ld.lld --hash-style=sysv -N %t.o %t2.so -o %t # RUN: llvm-objdump -section-headers %t | FileCheck --check-prefix=NORELRO %s # RUN: llvm-readobj --program-headers %t | FileCheck --check-prefix=NOPHDRS %s diff --git a/test/ELF/relro-script.s b/test/ELF/relro-script.s new file mode 100644 index 000000000000..f0dca67a3422 --- /dev/null +++ b/test/ELF/relro-script.s @@ -0,0 +1,29 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o +// RUN: ld.lld -shared %t.o %t2.o -o %t.so + +// ld.bfd and gold use .data.rel.ro rather than .bss.rel.ro. When a linker +// script, such as ld.bfd's internal linker script has a .data.rel.ro +// OutputSection we rename .bss.rel.ro to .data.rel.ro.bss in order to match in +// .data.rel.ro. This keeps the relro sections contiguous. + +// Use the same sections and ordering as the ld.bfd internal linker script. +// RUN: echo "SECTIONS { \ +// RUN: .data.rel.ro : { *(.data.rel.ro .data.rel.ro.*) } \ +// RUN: .dynamic : { *(.dynamic) } \ +// RUN: .got : { *(.got) } \ +// RUN: .got.plt : { *(.got.plt) } \ +// RUN: } " > %t.script +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o +// RUN: ld.lld %t3.o %t.so -o %t --script=%t.script --print-map | FileCheck %s + +// CHECK: .data.rel.ro +// CHECK-NEXT: <internal>:(.bss.rel.ro) + .section .text, "ax", @progbits + .global _start + .global bar + .global foo +_start: + .quad bar + .quad foo diff --git a/test/ELF/reproduce-thin-archive.s b/test/ELF/reproduce-thin-archive.s index 2de88d77f51b..c3e6e88757eb 100644 --- a/test/ELF/reproduce-thin-archive.s +++ b/test/ELF/reproduce-thin-archive.s @@ -5,11 +5,17 @@ # 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.tar # RUN: tar xf repro.tar # RUN: diff foo.a repro/%:t.dir/foo.a # RUN: diff foo.o repro/%:t.dir/foo.o +# RUN: ld.lld -m elf_x86_64 --whole-archive foo.a -o bar --reproduce repro2.tar +# RUN: tar xf repro2.tar +# RUN: diff foo.a repro2/%:t.dir/foo.a +# RUN: diff foo.o repro2/%:t.dir/foo.o + .globl _start _start: nop diff --git a/test/ELF/reproduce.s b/test/ELF/reproduce.s index 0a93be08d040..69671a088473 100644 --- a/test/ELF/reproduce.s +++ b/test/ELF/reproduce.s @@ -33,27 +33,36 @@ # RUN: echo "{};" > dyn # RUN: echo > file # RUN: echo > file2 +# RUN: echo "_start" > order +# RUN: mkdir "sysroot with spaces" # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o 'foo bar' # RUN: ld.lld --reproduce repro2.tar '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: --dynamic-list dyn -rpath file --script=file --symbol-ordering-file order \ +# RUN: --sysroot "sysroot with spaces" --sysroot="sysroot with spaces" \ +# RUN: --version-script ver --dynamic-linker "some unusual/path" -soname 'foo bar' \ +# RUN: -soname='foo bar' # RUN: tar xf repro2.tar # RUN: FileCheck %s --check-prefix=RSP2 < repro2/response.txt +# RSP2: --chroot . # 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: --library-path "[[BASEDIR:.+]]/foo bar" +# RSP2-NEXT: --library-path [[BASEDIR]]/file +# RSP2-NEXT: --script [[BASEDIR]]/file2 +# RSP2-NEXT: --dynamic-list [[BASEDIR]]/dyn +# RSP2-NEXT: -rpath [[BASEDIR]]/file +# RSP2-NEXT: --script [[BASEDIR]]/file +# RSP2-NEXT: --symbol-ordering-file [[BASEDIR]]/order +# RSP2-NEXT: --sysroot "[[BASEDIR]]/sysroot with spaces" +# RSP2-NEXT: --sysroot "[[BASEDIR]]/sysroot with spaces" +# RSP2-NEXT: --version-script [[BASEDIR]]/ver # RSP2-NEXT: --dynamic-linker "some unusual/path" -# RSP2-NEXT: -soname="foo bar" -# RSP2-NEXT: -soname="foo bar" +# RSP2-NEXT: -soname "foo bar" +# RSP2-NEXT: -soname "foo bar" # RUN: tar tf repro2.tar | FileCheck %s # CHECK: repro2/response.txt # CHECK-NEXT: repro2/version.txt +# CHECK-NEXT: repro2/{{.*}}/order # CHECK-NEXT: repro2/{{.*}}/dyn # CHECK-NEXT: repro2/{{.*}}/ver # CHECK-NEXT: repro2/{{.*}}/foo bar diff --git a/test/ELF/resolution-end.s b/test/ELF/resolution-end.s index aa1c999fb79a..26858372ce09 100644 --- a/test/ELF/resolution-end.s +++ b/test/ELF/resolution-end.s @@ -1,7 +1,7 @@ # 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/resolution-end.s -o %t2.o # RUN: ld.lld -shared -o %t2.so %t2.o -# RUN: ld.lld %t1.o %t2.so -o %t +# RUN: ld.lld --hash-style=sysv %t1.o %t2.so -o %t # RUN: llvm-readobj -t -s -section-data %t | FileCheck %s # REQUIRES: x86 diff --git a/test/ELF/retain-symbols-file.s b/test/ELF/retain-symbols-file.s index aa7d35d914eb..79d569d69cdb 100644 --- a/test/ELF/retain-symbols-file.s +++ b/test/ELF/retain-symbols-file.s @@ -2,11 +2,11 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t # RUN: echo "bar" > %t_retain.txt # RUN: echo "foo" >> %t_retain.txt -# RUN: ld.lld -shared --retain-symbols-file=%t_retain.txt %t -o %t2 +# RUN: ld.lld --hash-style=sysv -shared --retain-symbols-file=%t_retain.txt %t -o %t2 # RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s ## Check separate form. -# RUN: ld.lld -shared --retain-symbols-file %t_retain.txt %t -o %t2 +# RUN: ld.lld --hash-style=sysv -shared --retain-symbols-file %t_retain.txt %t -o %t2 # RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s # CHECK: DynamicSymbols [ diff --git a/test/ELF/section-metadata-err.s b/test/ELF/section-metadata-err.s index f3b5842945cb..1bcbedfbab71 100644 --- a/test/ELF/section-metadata-err.s +++ b/test/ELF/section-metadata-err.s @@ -3,7 +3,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s -# CHECK: error: Merge and .eh_frame sections are not supported with SHF_LINK_ORDER {{.*}}section-metadata-err.s.tmp.o:(.foo) +# CHECK: error: a section with SHF_LINK_ORDER should not refer a non-regular section: {{.*}}section-metadata-err.s.tmp.o:(.foo) .global _start _start: diff --git a/test/ELF/segments.s b/test/ELF/segments.s index 9307ba39fe46..4648ba97a854 100644 --- a/test/ELF/segments.s +++ b/test/ELF/segments.s @@ -1,7 +1,10 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t + # RUN: ld.lld %t -o %t1 # RUN: llvm-readobj --program-headers %t1 | FileCheck --check-prefix=ROSEGMENT %s +# RUN: ld.lld --omagic --no-omagic %t -o %t1 +# RUN: llvm-readobj --program-headers %t1 | FileCheck --check-prefix=ROSEGMENT %s # ROSEGMENT: ProgramHeader { # ROSEGMENT: Type: PT_LOAD @@ -76,6 +79,8 @@ # RUN: ld.lld -N %t -o %t3 # RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=OMAGIC %s +# RUN: ld.lld --omagic %t -o %t3 +# RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=OMAGIC %s # OMAGIC: ProgramHeader { # OMAGIC: Type: PT_LOAD diff --git a/test/ELF/shared-lazy.s b/test/ELF/shared-lazy.s new file mode 100644 index 000000000000..bc1e61c3c949 --- /dev/null +++ b/test/ELF/shared-lazy.s @@ -0,0 +1,16 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o +// RUN: rm -f %t1.a +// RUN: llvm-ar rc %t1.a %t1.o +// RUN: ld.lld %t1.o -o %t1.so -shared +// RUN: echo ".global foo" > %t2.s +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o +// RUN: ld.lld %t1.a %t1.so %t2.o -o %t.so -shared +// RUN: llvm-readelf --dyn-symbols %t.so | FileCheck %s + +// Test that 'foo' from %t1.so is used and we don't fetch a member +// from the archive. + +// CHECK: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo + +.global foo +foo: diff --git a/test/ELF/shared.s b/test/ELF/shared.s index d4c79d914ffb..65ad2c61359b 100644 --- a/test/ELF/shared.s +++ b/test/ELF/shared.s @@ -1,10 +1,10 @@ // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o // 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 --hash-style=sysv -shared %t2.o -o %t2.so // RUN: llvm-readobj -s %t2.so | FileCheck --check-prefix=SO %s -// RUN: ld.lld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t +// RUN: ld.lld --hash-style=sysv -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t // RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data -hash-table %t | FileCheck %s -// RUN: ld.lld %t.o %t2.so %t2.so -o %t2 +// RUN: ld.lld --hash-style=sysv %t.o %t2.so %t2.so -o %t2 // RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s // REQUIRES: x86 diff --git a/test/ELF/silent-ignore.test b/test/ELF/silent-ignore.test new file mode 100644 index 000000000000..6655754ace58 --- /dev/null +++ b/test/ELF/silent-ignore.test @@ -0,0 +1,20 @@ +RUN: ld.lld --version \ +RUN: -allow-shlib-undefined \ +RUN: -cref \ +RUN: -g \ +RUN: -no-add-needed \ +RUN: -no-allow-shlib-undefined \ +RUN: -no-copy-dt-needed-entries \ +RUN: -no-ctors-in-init-array \ +RUN: -no-keep-memory \ +RUN: -no-warn-common \ +RUN: -no-warn-mismatch \ +RUN: -sort-common \ +RUN: -stats \ +RUN: -warn-execstack \ +RUN: -warn-once \ +RUN: -warn-shared-textrel \ +RUN: -EB \ +RUN: -EL \ +RUN: -Qy +RUN: not ld.lld --version --not-an-ignored-argument diff --git a/test/ELF/sort-norosegment.s b/test/ELF/sort-norosegment.s index c5a759a08a77..bd74f2eb330a 100644 --- a/test/ELF/sort-norosegment.s +++ b/test/ELF/sort-norosegment.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t -# RUN: ld.lld -no-rosegment -o %t1 %t -shared +# RUN: ld.lld --hash-style=sysv -no-rosegment -o %t1 %t -shared # RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s # CHECK: .text {{.*}} AX diff --git a/test/ELF/startstop-gccollect.s b/test/ELF/startstop-gccollect.s index daff08187cdf..cb0009c54bec 100644 --- a/test/ELF/startstop-gccollect.s +++ b/test/ELF/startstop-gccollect.s @@ -11,21 +11,27 @@ # RUN: ld.lld %t --gc-sections -o %tout # RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s +# RUN: echo ".global __start_foo; __start_foo:" > %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 %t --gc-sections -o %tout %t2.so +# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s + # DISASM: _start: # DISASM-NEXT: 201000: e8 05 00 00 00 callq 5 <__start_foo> -# DISASM-NEXT: 201005: e8 01 00 00 00 callq 1 <__start_bar> +# DISASM-NEXT: 201005: e8 02 00 00 00 callq 2 <__stop_bar> # DISASM-NEXT: Disassembly of section foo: # DISASM-NEXT: __start_foo: # DISASM-NEXT: 20100a: 90 nop # DISASM-NEXT: Disassembly of section bar: -# DISASM-NEXT: __start_bar: +# DISASM-NEXT: bar: # DISASM-NEXT: 20100b: 90 nop .global _start .text _start: callq __start_foo - callq __start_bar + callq __stop_bar .section foo,"ax" nop diff --git a/test/ELF/startstop.s b/test/ELF/startstop.s index 250fb2cb3f5c..1e75042a0c8c 100644 --- a/test/ELF/startstop.s +++ b/test/ELF/startstop.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -// RUN: ld.lld %t -o %tout -shared +// RUN: ld.lld --hash-style=sysv %t -o %tout -shared // RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s // RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s diff --git a/test/ELF/string-gc.s b/test/ELF/string-gc.s index 3157a79a65cd..96c75e9236f4 100644 --- a/test/ELF/string-gc.s +++ b/test/ELF/string-gc.s @@ -14,7 +14,7 @@ // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: s3 -// CHECK-NEXT: Value: 0x200125 +// CHECK-NEXT: Value: 0x200120 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local (0x0) // CHECK-NEXT: Type: Object (0x1) @@ -23,7 +23,7 @@ // CHECK-NEXT: } // CHECK-NEXT: Symbol { // CHECK-NEXT: Name: s1 -// CHECK-NEXT: Value: 0x200120 +// CHECK-NEXT: Value: 0x200125 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local (0x0) // CHECK-NEXT: Type: Object (0x1) diff --git a/test/ELF/strip-debug.s b/test/ELF/strip-debug.s index 81f7572aa7c5..8005cfacee6c 100644 --- a/test/ELF/strip-debug.s +++ b/test/ELF/strip-debug.s @@ -1,25 +1,14 @@ # 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: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: ld.lld %t -o %t2 --strip-debug -# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s +# RUN: llvm-readobj -sections %t2 | FileCheck %s # RUN: ld.lld %t -o %t2 -S -# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s +# RUN: llvm-readobj -sections %t2 | FileCheck %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 +# RUN: llvm-readobj -sections %t2 | FileCheck %s -# STRIP-NOT: Name: .debug_info -# STRIP-NOT: Name: .debug_abbrev -# STRIP-NOT: Name: .debug_aranges -# STRIP-NOT: Name: .debug_line +# CHECK-NOT: Foo +# CHECK-NOT: Bar -.globl _start -_start: - ret +.section .debug_Foo,"",@progbits +.section .zdebug_Bar,"",@progbits diff --git a/test/ELF/symbol-ordering-file2.s b/test/ELF/symbol-ordering-file2.s new file mode 100644 index 000000000000..723eef1dfb72 --- /dev/null +++ b/test/ELF/symbol-ordering-file2.s @@ -0,0 +1,21 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "bar" > %t.order +# RUN: ld.lld --symbol-ordering-file %t.order -shared %t.o -o %t.so +# RUN: llvm-nm %t.so | FileCheck %s + +# CHECK: 0000000000002000 d _DYNAMIC +# CHECK-NEXT: 0000000000001000 T bar +# CHECK-NEXT: 0000000000001004 T foo + + .section .text.foo,"ax",@progbits + .align 4 + .global foo +foo: + retq + + .section .text.bar,"ax",@progbits + .align 4 + .global bar +bar: + retq diff --git a/test/ELF/synthetic-got.s b/test/ELF/synthetic-got.s index 8d82f3177f80..375a4387f1c8 100644 --- a/test/ELF/synthetic-got.s +++ b/test/ELF/synthetic-got.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { }" > %t0.script -# RUN: ld.lld -shared %t.o -o %t0.out --script %t0.script +# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t0.out --script %t0.script # RUN: llvm-objdump -section-headers %t0.out | FileCheck %s --check-prefix=GOT # RUN: llvm-objdump -s -section=.got -section=.got.plt %t0.out \ # RUN: | FileCheck %s --check-prefix=GOTDATA @@ -16,7 +16,7 @@ # GOTDATA-NEXT: 01d0 00000000 00000000 # RUN: echo "SECTIONS { .mygot : { *(.got) *(.got.plt) } }" > %t1.script -# RUN: ld.lld -shared %t.o -o %t1.out --script %t1.script +# RUN: ld.lld --hash-style=sysv -shared %t.o -o %t1.out --script %t1.script # RUN: llvm-objdump -section-headers %t1.out | FileCheck %s --check-prefix=MYGOT # RUN: llvm-objdump -s -section=.mygot %t1.out | FileCheck %s --check-prefix=MYGOTDATA diff --git a/test/ELF/sysroot.s b/test/ELF/sysroot.s index 358b4d9dfa5b..6b40c7d3952a 100644 --- a/test/ELF/sysroot.s +++ b/test/ELF/sysroot.s @@ -28,6 +28,8 @@ // Should substitute SysRoot if specified // RUN: ld.lld -o %t/r %t/m.o --sysroot=%t -L=lib -l:libls.a // RUN: ld.lld -o %t/r %t/m.o --sysroot=%t -L=/lib -l:libls.a +// Check alias. +// RUN: ld.lld -o %t/r %t/m.o --sysroot %t -L=lib -l:libls.a // Should not substitute SysRoot if the directory name does not start with '=' // RUN: not ld.lld -o %t/r %r/m.o --sysroot=%t -Llib -l:libls.a diff --git a/test/ELF/tls-dynamic-i686.s b/test/ELF/tls-dynamic-i686.s index ac88e6eaed31..1b13f26cc134 100644 --- a/test/ELF/tls-dynamic-i686.s +++ b/test/ELF/tls-dynamic-i686.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t -// RUN: ld.lld -shared %t -o %tout +// RUN: ld.lld --hash-style=sysv -shared %t -o %tout // RUN: llvm-readobj -sections -relocations %tout | FileCheck %s // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS diff --git a/test/ELF/tls-dynamic.s b/test/ELF/tls-dynamic.s index 05473d4b5b18..167f7687451e 100644 --- a/test/ELF/tls-dynamic.s +++ b/test/ELF/tls-dynamic.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -// RUN: ld.lld -shared %t -o %tout +// RUN: ld.lld --hash-style=sysv -shared %t -o %tout // RUN: llvm-readobj -sections -relocations %tout | FileCheck %s // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS diff --git a/test/ELF/tls-got.s b/test/ELF/tls-got.s index 450dd634d7a9..b1686cd6d5f4 100644 --- a/test/ELF/tls-got.s +++ b/test/ELF/tls-got.s @@ -1,7 +1,7 @@ // 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/tls-got.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so -// RUN: ld.lld -e main %t1.o %t2.so -o %t3 +// RUN: ld.lld --hash-style=sysv -e main %t1.o %t2.so -o %t3 // RUN: llvm-readobj -s -r %t3 | FileCheck %s // RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM %s diff --git a/test/ELF/tls-i686.s b/test/ELF/tls-i686.s index 7f2dd605cacd..c411fc74cd68 100644 --- a/test/ELF/tls-i686.s +++ b/test/ELF/tls-i686.s @@ -1,7 +1,7 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t // RUN: ld.lld %t -o %tout -// RUN: ld.lld %t -shared -o %tsharedout +// RUN: ld.lld --hash-style=sysv %t -shared -o %tsharedout // RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS // RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC // RUN: llvm-objdump -d %tsharedout | FileCheck %s --check-prefix=DISSHARED diff --git a/test/ELF/tls-initial-exec-local.s b/test/ELF/tls-initial-exec-local.s index 0aef3c8237b6..e65fb294bc17 100644 --- a/test/ELF/tls-initial-exec-local.s +++ b/test/ELF/tls-initial-exec-local.s @@ -1,6 +1,6 @@ // 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: ld.lld --hash-style=sysv -shared %t.o -o %t // RUN: llvm-readobj -r -s %t | FileCheck %s // RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s diff --git a/test/ELF/tls-opt-gdie.s b/test/ELF/tls-opt-gdie.s index c423a3e0f246..6e8531257714 100644 --- a/test/ELF/tls-opt-gdie.s +++ b/test/ELF/tls-opt-gdie.s @@ -1,7 +1,7 @@ // 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-opt-gdie.s -o %tso.o // RUN: ld.lld -shared %tso.o -o %t.so -// RUN: ld.lld %t.o %t.so -o %t1 +// RUN: ld.lld --hash-style=sysv %t.o %t.so -o %t1 // RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=RELOC %s // RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s diff --git a/test/ELF/tls-opt-gdiele-i686.s b/test/ELF/tls-opt-gdiele-i686.s index 1432a9607da9..2dc3731eba57 100644 --- a/test/ELF/tls-opt-gdiele-i686.s +++ b/test/ELF/tls-opt-gdiele-i686.s @@ -1,7 +1,7 @@ // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-gdiele-i686.s -o %tso.o // RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o // RUN: ld.lld -shared %tso.o -o %tso -// RUN: ld.lld %t.o %tso -o %tout +// RUN: ld.lld --hash-style=sysv %t.o %tso -o %tout // RUN: llvm-readobj -r %tout | FileCheck --check-prefix=NORELOC %s // RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s diff --git a/test/ELF/tls-opt-iele-i686-nopic.s b/test/ELF/tls-opt-iele-i686-nopic.s index b6608c16551c..02148b5dbff9 100644 --- a/test/ELF/tls-opt-iele-i686-nopic.s +++ b/test/ELF/tls-opt-iele-i686-nopic.s @@ -1,7 +1,7 @@ // 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 %t.o %tso -o %t1 +// RUN: ld.lld --hash-style=sysv %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 diff --git a/test/ELF/tls-static.s b/test/ELF/tls-static.s index 81ecc82758d7..338d95c817ee 100644 --- a/test/ELF/tls-static.s +++ b/test/ELF/tls-static.s @@ -3,12 +3,20 @@ // RUN: ld.lld -static %t -o %tout // RUN: ld.lld %t -o %tout // RUN: ld.lld -shared %tso -o %tshared -// RUN: not ld.lld -static %t %tshared -o %tout 2>&1 | FileCheck %s +// RUN: ld.lld -static %t %tshared -o %tout // REQUIRES: x86 .global _start _start: - call __tls_get_addr + data16 + leaq foobar@TLSGD(%rip), %rdi + data16 + data16 + rex64 + callq __tls_get_addr@PLT -// CHECK: error: undefined symbol: __tls_get_addr -// CHECK: >>> referenced by {{.*}}:(.text+0x1) + +.section .tdata,"awT",@progbits +.global foobar +foobar: + .long 42 diff --git a/test/ELF/tls-two-relocs.s b/test/ELF/tls-two-relocs.s index 7c5d6abf77f4..d5687e9bf862 100644 --- a/test/ELF/tls-two-relocs.s +++ b/test/ELF/tls-two-relocs.s @@ -1,6 +1,6 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -// RUN: ld.lld %t -o %tout -shared +// RUN: ld.lld --hash-style=sysv %t -o %tout -shared // RUN: llvm-readobj -r %tout | FileCheck %s data16 diff --git a/test/ELF/trace-symbols.s b/test/ELF/trace-symbols.s index eb8e17c709a5..c8ba9b21bcdb 100644 --- a/test/ELF/trace-symbols.s +++ b/test/ELF/trace-symbols.s @@ -31,19 +31,23 @@ # 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 %t2 %t1.a -o %t3 2>&1 | \ +# RUN: FileCheck -check-prefix=FOO_AND_COMMON %s +# FOO_AND_COMMON: trace-symbols.s.tmp: reference to foo +# FOO_AND_COMMON: trace-symbols.s.tmp2: definition of foo +# FOO_AND_COMMON: trace-symbols.s.tmp1.a: lazy definition of common + # 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 +# SHLIBDCOMMON: trace-symbols.s.tmp1.so: shared 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 +# SHLIBD2FOO: trace-symbols.s.tmp2.so: shared 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 | \ @@ -61,7 +65,7 @@ # 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 +# SHLIBDBAR: trace-symbols.s.tmp2.so: shared definition of bar # RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \ # RUN: FileCheck -check-prefix=SHLIBRBAR %s diff --git a/test/ELF/typed-undef.s b/test/ELF/typed-undef.s new file mode 100644 index 000000000000..d00e07f82518 --- /dev/null +++ b/test/ELF/typed-undef.s @@ -0,0 +1,11 @@ +# REQUIRES: x86 + +# We used to crash on this, check that we don't + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t -pie --unresolved-symbols=ignore-all + + .global _start +_start: + .quad foo - . + .type foo, @object diff --git a/test/ELF/undef-broken-debug.test b/test/ELF/undef-broken-debug.test new file mode 100644 index 000000000000..1238ebe70aca --- /dev/null +++ b/test/ELF/undef-broken-debug.test @@ -0,0 +1,47 @@ +# REQUIRES: x86 +# RUN: yaml2obj %s -o %t.o +# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck %s + +# The debug info has a broken relocation. Check that we don't crash +# and still report the undefined symbol. + +# CHECK: error: unsupported relocation target while parsing debug info +# CHECK: error: undefined symbol: bar + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Content: '0000000000000000' + - Name: .rela.text + Type: SHT_RELA + AddressAlign: 8 + Link: .symtab + Info: .text + Relocations: + - Offset: 0x0000000000000000 + Symbol: bar + Type: R_X86_64_64 + - Name: .debug_line + Type: SHT_PROGBITS + Content: 3300000002001C0000000101FB0E0D000101010100000001000001006162632E7300000000000009020000000000000000140208000101 + - Name: .rela.debug_line + AddressAlign: 8 + Type: SHT_RELA + Link: .symtab + Info: .debug_line + Relocations: + - Offset: 0x0000000000000029 + Symbol: bar + Type: R_X86_64_64 +Symbols: + Global: + - Name: _start + Section: .text + - Name: bar diff --git a/test/ELF/undef-version-script.s b/test/ELF/undef-version-script.s index 529728328747..024ac1dc0727 100644 --- a/test/ELF/undef-version-script.s +++ b/test/ELF/undef-version-script.s @@ -3,9 +3,6 @@ # 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: @ @@ -38,3 +35,6 @@ .global foo .weak bar +.data + .dc.a foo + .dc.a bar diff --git a/test/ELF/unresolved-symbols.s b/test/ELF/unresolved-symbols.s index 18656dcceca3..97ecd5014b12 100644 --- a/test/ELF/unresolved-symbols.s +++ b/test/ELF/unresolved-symbols.s @@ -13,6 +13,9 @@ # 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 +## Check alias. +# RUN: not ld.lld %t1.o %t2.o -o %t --unresolved-symbols xxx 2>&1 | \ +# RUN: FileCheck -check-prefix=ERR1 %s ## Ignore all should not produce error for symbols from object except ## case when --no-undefined specified. diff --git a/test/ELF/verdef-defaultver.s b/test/ELF/verdef-defaultver.s index c37c90a66d92..496a29e3db5a 100644 --- a/test/ELF/verdef-defaultver.s +++ b/test/ELF/verdef-defaultver.s @@ -3,7 +3,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/verdef-defaultver.s -o %t1 # RUN: echo "V1 { global: a; local: *; };" > %t.script # RUN: echo "V2 { global: b; c; } V1;" >> %t.script -# RUN: ld.lld -shared -soname shared %t1 --version-script %t.script -o %t.so +# RUN: ld.lld --hash-style=sysv -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 [ @@ -107,7 +107,7 @@ ## 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: ld.lld --hash-style=sysv %t2 %t.so -o %t3 # RUN: llvm-readobj -V -dyn-symbols %t3 | FileCheck --check-prefix=EXE %s # EXE: DynamicSymbols [ diff --git a/test/ELF/verdef.s b/test/ELF/verdef.s index 7fd60a95d1df..b5d12ee3884f 100644 --- a/test/ELF/verdef.s +++ b/test/ELF/verdef.s @@ -3,7 +3,7 @@ # RUN: echo "LIBSAMPLE_1.0 { global: a; local: *; };" > %t.script # RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; };" >> %t.script # RUN: echo "LIBSAMPLE_3.0 { global: c; local: *; };" >> %t.script -# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so +# RUN: ld.lld --hash-style=sysv --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 { @@ -65,7 +65,7 @@ ## 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: ld.lld --hash-style=sysv %tmain.o %t.so -o %tout # RUN: llvm-readobj -V %tout | FileCheck --check-prefix=MAIN %s # MAIN: Version symbols { @@ -100,7 +100,7 @@ # RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; };" >> %t.script # RUN: echo "LIBSAMPLE_3.0 { global: c; local: *; };" >> %t.script # RUN: echo "}" >> %t.script -# RUN: ld.lld --script %t.script -shared -soname shared %t.o -o %t2.so +# RUN: ld.lld --hash-style=sysv --script %t.script -shared -soname shared %t.o -o %t2.so # RUN: llvm-readobj -V -dyn-symbols %t2.so | FileCheck --check-prefix=DSO %s .globl a diff --git a/test/ELF/verneed-as-needed-weak.s b/test/ELF/verneed-as-needed-weak.s index a8efdc42d6d4..df15bc78ca6c 100644 --- a/test/ELF/verneed-as-needed-weak.s +++ b/test/ELF/verneed-as-needed-weak.s @@ -1,6 +1,10 @@ # REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed1.s -o %t1.o +# RUN: echo "v1 {}; v2 {}; v3 { local: *; };" > %t.script +# RUN: ld.lld -shared %t1.o --version-script %t.script -o %t.so + # 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: ld.lld %t.o --as-needed %t.so -o %t # RUN: llvm-readobj -V %t | FileCheck %s # CHECK: SHT_GNU_verneed { diff --git a/test/ELF/verneed-local.s b/test/ELF/verneed-local.s index 9ab6cd791484..208d8ecf8f62 100644 --- a/test/ELF/verneed-local.s +++ b/test/ELF/verneed-local.s @@ -1,6 +1,10 @@ # REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed1.s -o %t1.o +# RUN: echo "v1 {}; v2 {}; v3 { local: *; };" > %t.script +# RUN: ld.lld -shared %t1.o --version-script %t.script -o %t.so + # 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 +# RUN: not ld.lld %t.o %t.so -o %t 2>&1 | FileCheck %s # CHECK: error: undefined symbol: f3 # CHECK: >>> referenced by {{.*}}:(.text+0x1) diff --git a/test/ELF/verneed.s b/test/ELF/verneed.s index d0d0067250aa..27ab047e8222 100644 --- a/test/ELF/verneed.s +++ b/test/ELF/verneed.s @@ -1,6 +1,12 @@ # REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed1.s -o %t1.o +# RUN: echo "v1 {}; v2 {}; v3 { local: *; };" > %t.script +# RUN: ld.lld -shared %t1.o --version-script %t.script -o %t1.so -soname verneed1.so.0 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/verneed2.s -o %t2.o +# RUN: ld.lld -shared %t2.o --version-script %t.script -o %t2.so -soname verneed2.so.0 + # 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: ld.lld --hash-style=sysv %t.o %t1.so %t2.so -o %t # RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s # CHECK: Section { diff --git a/test/ELF/version-script-err.s b/test/ELF/version-script-err.s index ea3f664ea6ce..bd786d913369 100644 --- a/test/ELF/version-script-err.s +++ b/test/ELF/version-script-err.s @@ -8,4 +8,3 @@ // RUN: not ld.lld --version-script %terr1.script -shared %t.o -o %t.so 2>&1 | \ // RUN: FileCheck -check-prefix=ERR1 %s // ERR1: {{.*}}:1: unclosed quote -// ERR1-NEXT: {{.*}}: unexpected EOF diff --git a/test/ELF/version-script-extern.s b/test/ELF/version-script-extern.s index 2b89839c369a..c63ff817fb40 100644 --- a/test/ELF/version-script-extern.s +++ b/test/ELF/version-script-extern.s @@ -7,7 +7,7 @@ # RUN: echo "LIBSAMPLE_2.0 { global:" >> %t.script # RUN: echo ' extern "C" { _Z3bari; };' >> %t.script # RUN: echo "};" >> %t.script -# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so +# RUN: ld.lld --hash-style=sysv --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 [ diff --git a/test/ELF/version-script-twice.s b/test/ELF/version-script-twice.s index 3aeedd5b5ddc..1227dcd50f1d 100644 --- a/test/ELF/version-script-twice.s +++ b/test/ELF/version-script-twice.s @@ -7,7 +7,11 @@ .weak openat openat: + + .global openat@FBSD_1.1 openat@FBSD_1.1 = openat + + .global openat@@FBSD_1.2 openat@@FBSD_1.2 = openat # CHECK-DAG: openat@FBSD_1.1 diff --git a/test/ELF/version-script.s b/test/ELF/version-script.s index 72f9eeb944d1..abc716250eba 100644 --- a/test/ELF/version-script.s +++ b/test/ELF/version-script.s @@ -42,6 +42,12 @@ # RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2 # RUN: llvm-readobj %t2 > /dev/null +## Check that we can handle multiple "--version-script" options. +# RUN: echo "VERSION_1.0 { global : foo1; local : *; };" > %t7a.script +# RUN: echo "VERSION_2.0 { global: foo3; local: *; };" > %t7b.script +# RUN: ld.lld --version-script %t7a.script --version-script %t7b.script -shared %t.o %t2.so -o %t7.so +# RUN: llvm-readobj -dyn-symbols %t7.so | FileCheck --check-prefix=VERDSO %s + # DSO: DynamicSymbols [ # DSO-NEXT: Symbol { # DSO-NEXT: Name: @ @@ -142,12 +148,12 @@ # 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: ld.lld --hash-style=sysv -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: ld.lld --hash-style=sysv --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 [ diff --git a/test/ELF/weak-entry.s b/test/ELF/weak-entry.s new file mode 100644 index 000000000000..427230ab82c6 --- /dev/null +++ b/test/ELF/weak-entry.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t +# RUN: ld.lld %t -o %tout +# RUN: llvm-nm %tout | FileCheck %s + +# CHECK: w _start +# CHECK-NEXT: T foo + +.global foo +.weak _start +.text +foo: + .dc.a _start diff --git a/test/ELF/weak-undef-export.s b/test/ELF/weak-undef-export.s new file mode 100644 index 000000000000..164bc1730832 --- /dev/null +++ b/test/ELF/weak-undef-export.s @@ -0,0 +1,31 @@ +# REQUIRES: x86 + +# Test that we don't fail with foo being undefined. + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld --export-dynamic %t.o -o %t +# 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: Symbol { +# CHECK-NEXT: Name: foo@ (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: ] + + .weak foo + .quad foo diff --git a/test/ELF/weak-undef-lazy.s b/test/ELF/weak-undef-lazy.s new file mode 100644 index 000000000000..113013ea2e0f --- /dev/null +++ b/test/ELF/weak-undef-lazy.s @@ -0,0 +1,11 @@ +# 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 %S/Inputs/weak-undef-lazy.s -o %t2.o +# RUN: rm -f %t2.a +# RUN: llvm-ar rc %t2.a %t2.o +# RUN: ld.lld %t.o %t2.a -o %t --export-dynamic + + .global _start +_start: + .weak foobar + .quad foobar diff --git a/test/ELF/weak-undef-val.s b/test/ELF/weak-undef-val.s new file mode 100644 index 000000000000..acd42f4845de --- /dev/null +++ b/test/ELF/weak-undef-val.s @@ -0,0 +1,26 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t --export-dynamic +# RUN: llvm-readobj -s -section-data %t | 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: 0x201000 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Size: +# CHECK-NEXT: Link: +# CHECK-NEXT: Info: +# CHECK-NEXT: AddressAlignment: +# CHECK-NEXT: EntrySize: +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: 0000: 00F0DFFF | +# CHECK-NEXT: ) + + .global _start +_start: + .weak foobar + .long foobar - . diff --git a/test/ELF/weak-undef.s b/test/ELF/weak-undef.s index b6340339ebac..09c2a4c4440f 100644 --- a/test/ELF/weak-undef.s +++ b/test/ELF/weak-undef.s @@ -13,9 +13,21 @@ # 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: Weak +# CHECK-NEXT: Type: None +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: } # CHECK-NEXT: ] .weak foo .globl _start _start: + +.data + .dc.a foo diff --git a/test/ELF/wrap-no-real.s b/test/ELF/wrap-no-real.s new file mode 100644 index 000000000000..100efa6bbc28 --- /dev/null +++ b/test/ELF/wrap-no-real.s @@ -0,0 +1,77 @@ +// 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/wrap-no-real.s -o %t2.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-no-real2.s -o %t3.o +// RUN: ld.lld -o %t3.so -shared %t3.o + +// RUN: ld.lld -o %t %t1.o %t2.o -wrap foo +// RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s + +// RUN: ld.lld -o %t %t1.o %t2.o %t3.so -wrap foo +// RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s + +// CHECK: _start: +// CHECK-NEXT: movl $0x11010, %edx +// CHECK-NEXT: movl $0x11010, %edx +// CHECK-NEXT: movl $0x11000, %edx + +// RUN: llvm-readobj -t %t | FileCheck -check-prefix=SYM %s + +// Test the full symbol table. It is verbose, but lld at times +// produced duplicated symbols which are hard to test otherwise. + +// SYM: Symbols [ +// SYM-NEXT: Symbol { +// SYM-NEXT: Name: (0) +// SYM-NEXT: Value: +// SYM-NEXT: Size: +// SYM-NEXT: Binding: +// SYM-NEXT: Type +// SYM-NEXT: Other: +// SYM-NEXT: Section: +// SYM-NEXT: } +// SYM-NEXT: Symbol { +// SYM-NEXT: Name: _DYNAMIC +// SYM-NEXT: Value: +// SYM-NEXT: Size: +// SYM-NEXT: Binding: +// SYM-NEXT: Type: +// SYM-NEXT: Other [ +// SYM-NEXT: STV_HIDDEN +// SYM-NEXT: ] +// SYM-NEXT: Section: .dynamic +// SYM-NEXT: } +// SYM-NEXT: Symbol { +// SYM-NEXT: Name: foo +// SYM-NEXT: Value: 0x11000 +// SYM-NEXT: Size: +// SYM-NEXT: Binding: +// SYM-NEXT: Type: +// SYM-NEXT: Other: +// SYM-NEXT: Section: +// SYM-NEXT: } +// SYM-NEXT: Symbol { +// SYM-NEXT: Name: _start +// SYM-NEXT: Value: +// SYM-NEXT: Size: +// SYM-NEXT: Binding: +// SYM-NEXT: Type +// SYM-NEXT: Other: +// SYM-NEXT: Section: +// SYM-NEXT: } +// SYM-NEXT: Symbol { +// SYM-NEXT: Name: __wrap_foo +// SYM-NEXT: Value: 0x11010 +// SYM-NEXT: Size: +// SYM-NEXT: Binding: +// SYM-NEXT: Type: +// SYM-NEXT: Other: +// SYM-NEXT: Section: +// SYM-NEXT: } +// SYM-NEXT: ] + +.global _start +_start: + movl $foo, %edx + movl $__wrap_foo, %edx + movl $__real_foo, %edx diff --git a/test/ELF/wrap.s b/test/ELF/wrap.s index 3e75fdbad811..b96917b7be49 100644 --- a/test/ELF/wrap.s +++ b/test/ELF/wrap.s @@ -12,17 +12,31 @@ // CHECK-NEXT: movl $0x11010, %edx // CHECK-NEXT: movl $0x11000, %edx -// This shows an oddity of our implementation. The symbol foo gets -// mapped to __wrap_foo, but stays in the symbol table. This results -// in it showing up twice in the output. +// RUN: llvm-readobj -t %t3 > %t4.dump +// RUN: FileCheck --check-prefix=SYM1 %s < %t4.dump +// RUN: FileCheck --check-prefix=SYM2 %s < %t4.dump +// RUN: FileCheck --check-prefix=SYM3 %s < %t4.dump -// RUN: llvm-readobj -t -s %t3 | FileCheck -check-prefix=SYM %s -// SYM: Name: foo -// SYM-NEXT: Value: 0x11000 -// SYM: Name: __wrap_foo -// SYM-NEXT: Value: 0x11010 -// SYM: Name: __wrap_foo -// SYM-NEXT: Value: 0x11010 +// SYM1: Name: foo +// SYM1-NEXT: Value: 0x11000 +// SYM1-NEXT: Size: +// SYM1-NEXT: Binding: Global +// SYM1-NEXT: Type: None +// SYM1-NEXT: Other: 0 +// SYM2: Name: __wrap_foo +// SYM2-NEXT: Value: 0x11010 +// SYM2-NEXT: Size: +// SYM2-NEXT: Binding: Weak +// SYM2-NEXT: Type: None +// SYM2-NEXT: Other [ +// SYM2-NEXT: STV_PROTECTED +// SYM2-NEXT: ] +// SYM3: Name: __real_foo +// SYM3-NEXT: Value: 0x11020 +// SYM3-NEXT: Size: +// SYM3-NEXT: Binding: Global +// SYM3-NEXT: Type: None +// SYM3-NEXT: Other: 0 .global _start _start: diff --git a/test/ELF/x86-64-dyn-rel-error.s b/test/ELF/x86-64-dyn-rel-error.s index ee39e2cb83fd..f479eca2e778 100644 --- a/test/ELF/x86-64-dyn-rel-error.s +++ b/test/ELF/x86-64-dyn-rel-error.s @@ -10,3 +10,5 @@ _start: .long bar // CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC + +// RUN: ld.lld --noinhibit-exec %t.o %t2.so -o %t 2>&1 | FileCheck %s diff --git a/test/ELF/x86-64-relax-got-abs.s b/test/ELF/x86-64-relax-got-abs.s index c4291202f035..0caf6dcec1fa 100644 --- a/test/ELF/x86-64-relax-got-abs.s +++ b/test/ELF/x86-64-relax-got-abs.s @@ -1,7 +1,7 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %s \ // RUN: -o %t.o -// RUN: ld.lld %t.o -o %t.so -shared +// RUN: ld.lld --hash-style=sysv %t.o -o %t.so -shared // RUN: llvm-objdump -d %t.so | FileCheck %s // We used to fail trying to relax this into a pc relocation to an absolute diff --git a/test/ELF/x86-64-reloc-16.s b/test/ELF/x86-64-reloc-16.s index 2954d9900cfa..4822ec71757b 100644 --- a/test/ELF/x86-64-reloc-16.s +++ b/test/ELF/x86-64-reloc-16.s @@ -9,6 +9,6 @@ // CHECK-NEXT: 200000 42 // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s -// ERROR: relocation R_X86_64_16 out of range +// ERROR: relocation R_X86_64_16 out of range: 65536 is not in [0, 65535] .short foo diff --git a/test/ELF/x86-64-reloc-8.s b/test/ELF/x86-64-reloc-8.s index 1c3831fafa20..8f6ba5aa14bb 100644 --- a/test/ELF/x86-64-reloc-8.s +++ b/test/ELF/x86-64-reloc-8.s @@ -9,6 +9,6 @@ // CHECK-NEXT: 200000 42 // RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s -// ERROR: relocation R_X86_64_8 out of range +// ERROR: relocation R_X86_64_8 out of range: 256 is not in [0, 255] .byte foo diff --git a/test/ELF/x86-64-reloc-error.s b/test/ELF/x86-64-reloc-error.s index ece1bd45aa4f..cb600d9bf1e3 100644 --- a/test/ELF/x86-64-reloc-error.s +++ b/test/ELF/x86-64-reloc-error.s @@ -6,5 +6,5 @@ movl $big, %edx movq $foo - 0x1000000000000, %rdx -# CHECK: {{.*}}:(.text+0x1): relocation R_X86_64_32 out of range -# CHECK: {{.*}}:(.text+0x8): relocation R_X86_64_32S out of range +# CHECK: {{.*}}:(.text+0x1): relocation R_X86_64_32 out of range: 68719476736 is not in [0, 4294967295] +# CHECK: {{.*}}:(.text+0x8): relocation R_X86_64_32S out of range: -281474976710656 is not in [-2147483648, 2147483647] diff --git a/test/ELF/x86-64-reloc-range.s b/test/ELF/x86-64-reloc-range.s index 08f604ee6a30..2913458ab5cb 100644 --- a/test/ELF/x86-64-reloc-range.s +++ b/test/ELF/x86-64-reloc-range.s @@ -1,7 +1,7 @@ // 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: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range +// CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range: 2147483648 is not in [-2147483648, 2147483647] // CHECK-NOT: relocation lea foo(%rip), %rax diff --git a/test/ELF/x86-64-tls-gd-local.s b/test/ELF/x86-64-tls-gd-local.s index ec6115dc2f75..8879737ad3fb 100644 --- a/test/ELF/x86-64-tls-gd-local.s +++ b/test/ELF/x86-64-tls-gd-local.s @@ -1,6 +1,6 @@ // 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: ld.lld --hash-style=sysv %t.o -o %t.so -shared // RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s .byte 0x66 |