diff --git a/tests/riscv64/riscv-branch.rv64.o b/tests/riscv64/riscv-branch.rv64.o new file mode 100644 index 00000000..37ffc125 Binary files /dev/null and b/tests/riscv64/riscv-branch.rv64.o differ diff --git a/tests/riscv64/riscv-call.rv64.o b/tests/riscv64/riscv-call.rv64.o new file mode 100644 index 00000000..c0c1b7a3 Binary files /dev/null and b/tests/riscv64/riscv-call.rv64.o differ diff --git a/tests/riscv64/riscv-hi20-lo12.rv64.o b/tests/riscv64/riscv-hi20-lo12.rv64.o new file mode 100644 index 00000000..0e568088 Binary files /dev/null and b/tests/riscv64/riscv-hi20-lo12.rv64.o differ diff --git a/tests/riscv64/riscv-jal.rv64.o b/tests/riscv64/riscv-jal.rv64.o new file mode 100644 index 00000000..67bde1f5 Binary files /dev/null and b/tests/riscv64/riscv-jal.rv64.o differ diff --git a/tests/riscv64/riscv-pcrel-hilo.rv64.o b/tests/riscv64/riscv-pcrel-hilo.rv64.o new file mode 100644 index 00000000..75a62e70 Binary files /dev/null and b/tests/riscv64/riscv-pcrel-hilo.rv64.o differ diff --git a/tests/riscv64/riscv-plt.64.o b/tests/riscv64/riscv-plt.64.o new file mode 100644 index 00000000..e1514cda Binary files /dev/null and b/tests/riscv64/riscv-plt.64.o differ diff --git a/tests/riscv64/riscv-reloc-64-pic.o b/tests/riscv64/riscv-reloc-64-pic.o new file mode 100644 index 00000000..c39b5bdc Binary files /dev/null and b/tests/riscv64/riscv-reloc-64-pic.o differ diff --git a/tests/riscv64/riscv-reloc-copy.o b/tests/riscv64/riscv-reloc-copy.o new file mode 100644 index 00000000..046649ff Binary files /dev/null and b/tests/riscv64/riscv-reloc-copy.o differ diff --git a/tests/riscv64/riscv-reloc-copy_1.o b/tests/riscv64/riscv-reloc-copy_1.o new file mode 100644 index 00000000..046649ff Binary files /dev/null and b/tests/riscv64/riscv-reloc-copy_1.o differ diff --git a/tests/riscv64/riscv-reloc-got.o b/tests/riscv64/riscv-reloc-got.o new file mode 100644 index 00000000..506281e9 Binary files /dev/null and b/tests/riscv64/riscv-reloc-got.o differ diff --git a/tests/riscv64/riscv64-reloc-64-pic.o b/tests/riscv64/riscv64-reloc-64-pic.o new file mode 100644 index 00000000..371cae66 Binary files /dev/null and b/tests/riscv64/riscv64-reloc-64-pic.o differ diff --git a/tests/riscv64/riscv64-reloc-64-pic.so b/tests/riscv64/riscv64-reloc-64-pic.so new file mode 100755 index 00000000..112d4dbb Binary files /dev/null and b/tests/riscv64/riscv64-reloc-64-pic.so differ diff --git a/tests_src/relocs/riscv64/riscv-branch.s b/tests_src/relocs/riscv64/riscv-branch.s new file mode 100644 index 00000000..e5a685c1 --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-branch.s @@ -0,0 +1,34 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-branch.s + +# REQUIRES: riscv + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv32 +# RUN: ld.lld %t.rv64.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv64 +# RUN: llvm-objdump -d %t.rv32 | FileCheck %s +# RUN: llvm-objdump -d %t.rv64 | FileCheck %s +# CHECK: 63 02 00 00 beqz zero, 4 +# CHECK: e3 1e 00 fe bnez zero, -4 +# +# RUN: ld.lld %t.rv32.o --defsym foo=_start+0xffe --defsym bar=_start+4-0x1000 -o %t.rv32.limits +# RUN: ld.lld %t.rv64.o --defsym foo=_start+0xffe --defsym bar=_start+4-0x1000 -o %t.rv64.limits +# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s +# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s +# LIMITS: e3 0f 00 7e beqz zero, 4094 +# LIMITS-NEXT: 63 10 00 80 bnez zero, -4096 + +# RUN: not ld.lld %t.rv32.o --defsym foo=_start+0x1000 --defsym bar=_start+4-0x1002 -o %t 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s +# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x1000 --defsym bar=_start+4-0x1002 -o %t 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s +# ERROR-RANGE: relocation R_RISCV_BRANCH out of range: 2048 is not in [-2048, 2047] +# ERROR-RANGE-NEXT: relocation R_RISCV_BRANCH out of range: -2049 is not in [-2048, 2047] + +# RUN: not ld.lld %t.rv32.o --defsym foo=_start+1 --defsym bar=_start-1 -o %t 2>&1 | FileCheck --check-prefix=ERROR-ALIGN %s +# RUN: not ld.lld %t.rv64.o --defsym foo=_start+1 --defsym bar=_start-1 -o %t 2>&1 | FileCheck --check-prefix=ERROR-ALIGN %s +# ERROR-ALIGN: improper alignment for relocation R_RISCV_BRANCH: 0x1 is not aligned to 2 bytes + +.global _start +_start: + beq x0, x0, foo + bne x0, x0, bar \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv-call.s b/tests_src/relocs/riscv64/riscv-call.s new file mode 100644 index 00000000..fd072b8f --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-call.s @@ -0,0 +1,34 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-call.s + +# REQUIRES: riscv + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+8 --defsym bar=_start -o %t.rv32 +# RUN: ld.lld %t.rv64.o --defsym foo=_start+8 --defsym bar=_start -o %t.rv64 +# RUN: llvm-objdump -d %t.rv32 | FileCheck %s +# RUN: llvm-objdump -d %t.rv64 | FileCheck %s +# CHECK: 97 00 00 00 auipc ra, 0 +# CHECK-NEXT: e7 80 80 00 jalr 8(ra) +# CHECK: 97 00 00 00 auipc ra, 0 +# CHECK-NEXT: e7 80 80 ff jalr -8(ra) + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+8-0x80000800 -o %t.rv32.limits +# RUN: ld.lld %t.rv64.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+8-0x80000800 -o %t.rv64.limits +# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s +# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s +# LIMITS: 97 f0 ff 7f auipc ra, 524287 +# LIMITS-NEXT: e7 80 f0 7f jalr 2047(ra) +# LIMITS-NEXT: 97 00 00 80 auipc ra, 524288 +# LIMITS-NEXT: e7 80 00 80 jalr -2048(ra) + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+8-0x80000801 -o %t +# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+8-0x80000801 -o %t 2>&1 | FileCheck --check-prefix=ERROR %s +# ERROR: relocation R_RISCV_CALL out of range: 524288 is not in [-524288, 524287] +# ERROR-NEXT: relocation R_RISCV_CALL out of range: -524289 is not in [-524288, 524287] + +.global _start +_start: + call foo + call bar \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv-hi20-lo12.s b/tests_src/relocs/riscv64/riscv-hi20-lo12.s new file mode 100644 index 00000000..80fb5c6a --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-hi20-lo12.s @@ -0,0 +1,42 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-hi20-lo12.s + +# REQUIRES: riscv + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o + +# RUN: ld.lld %t.rv32.o --defsym foo=0 --defsym bar=42 -o %t.rv32 +# RUN: ld.lld %t.rv64.o --defsym foo=0 --defsym bar=42 -o %t.rv64 +# RUN: llvm-objdump -d %t.rv32 | FileCheck %s +# RUN: llvm-objdump -d %t.rv64 | FileCheck %s +# CHECK: 37 05 00 00 lui a0, 0 +# CHECK-NEXT: 13 05 05 00 mv a0, a0 +# CHECK-NEXT: 23 20 a5 00 sw a0, 0(a0) +# CHECK-NEXT: b7 05 00 00 lui a1, 0 +# CHECK-NEXT: 93 85 a5 02 addi a1, a1, 42 +# CHECK-NEXT: 23 a5 b5 02 sw a1, 42(a1) + +# RUN: ld.lld %t.rv32.o --defsym foo=0x7ffff7ff --defsym bar=0x7ffff800 -o %t.rv32.limits +# RUN: ld.lld %t.rv64.o --defsym foo=0x7ffff7ff --defsym bar=0xffffffff7ffff800 -o %t.rv64.limits +# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s +# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s +# LIMITS: 37 f5 ff 7f lui a0, 524287 +# LIMITS-NEXT: 13 05 f5 7f addi a0, a0, 2047 +# LIMITS-NEXT: a3 2f a5 7e sw a0, 2047(a0) +# LIMITS-NEXT: b7 05 00 80 lui a1, 524288 +# LIMITS-NEXT: 93 85 05 80 addi a1, a1, -2048 +# LIMITS-NEXT: 23 a0 b5 80 sw a1, -2048(a1) + +# RUN: not ld.lld %t.rv64.o --defsym foo=0x7ffff800 --defsym bar=0xffffffff7ffff7ff -o %t 2>&1 | FileCheck --check-prefix ERROR %s +# ERROR: relocation R_RISCV_HI20 out of range: 524288 is not in [-524288, 524287] +# ERROR-NEXT: relocation R_RISCV_HI20 out of range: -524289 is not in [-524288, 524287] + +.global _start + +_start: + lui a0, %hi(foo) + addi a0, a0, %lo(foo) + sw a0, %lo(foo)(a0) + lui a1, %hi(bar) + addi a1, a1, %lo(bar) + sw a1, %lo(bar)(a1) \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv-jal.s b/tests_src/relocs/riscv64/riscv-jal.s new file mode 100644 index 00000000..241ad264 --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-jal.s @@ -0,0 +1,36 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-jal.s + +# REQUIRES: riscv + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv32 +# RUN: ld.lld %t.rv64.o --defsym foo=_start+4 --defsym bar=_start -o %t.rv64 +# RUN: llvm-objdump -d %t.rv32 | FileCheck %s +# RUN: llvm-objdump -d %t.rv64 | FileCheck %s +# CHECK: 6f 00 40 00 j 4 +# CHECK: ef f0 df ff jal -4 + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+0xffffe --defsym bar=_start+4-0x100000 -o %t.rv32.limits +# RUN: ld.lld %t.rv64.o --defsym foo=_start+0xffffe --defsym bar=_start+4-0x100000 -o %t.rv64.limits +# RUN: llvm-objdump -d %t.rv32.limits | FileCheck --check-prefix=LIMITS %s +# RUN: llvm-objdump -d %t.rv64.limits | FileCheck --check-prefix=LIMITS %s +# LIMITS: 6f f0 ff 7f j 1048574 +# LIMITS-NEXT: ef 00 00 80 jal -1048576 + +# RUN: not ld.lld %t.rv32.o --defsym foo=_start+0x100000 --defsym bar=_start+4-0x100002 -o %t 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s +# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x100000 --defsym bar=_start+4-0x100002 -o %t 2>&1 | FileCheck --check-prefix=ERROR-RANGE %s +# ERROR-RANGE: relocation R_RISCV_JAL out of range: 524288 is not in [-524288, 524287] +# ERROR-RANGE-NEXT: relocation R_RISCV_JAL out of range: -524289 is not in [-524288, 524287] + +# RUN: not ld.lld %t.rv32.o --defsym foo=_start+1 --defsym bar=_start+4+3 -o %t 2>&1 | FileCheck --check-prefix=ERROR-ALIGN %s +# RUN: not ld.lld %t.rv64.o --defsym foo=_start+1 --defsym bar=_start+4+3 -o %t 2>&1 | FileCheck --check-prefix=ERROR-ALIGN %s +# ERROR-ALIGN: improper alignment for relocation R_RISCV_JAL: 0x1 is not aligned to 2 bytes +# ERROR-ALIGN-NEXT: improper alignment for relocation R_RISCV_JAL: 0x3 is not aligned to 2 bytes + +.global _start + +_start: + jal x0, foo + jal x1, bar \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv-pcrel-hilo.s b/tests_src/relocs/riscv64/riscv-pcrel-hilo.s new file mode 100644 index 00000000..b6c47fd0 --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-pcrel-hilo.s @@ -0,0 +1,47 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-pcrel-hilo.s + +# REQUIRES: riscv + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=-relax %s -o %t.rv32.o +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=-relax %s -o %t.rv64.o + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+12 --defsym bar=_start -o %t.rv32 +# RUN: ld.lld %t.rv64.o --defsym foo=_start+12 --defsym bar=_start -o %t.rv64 +# RUN: llvm-objdump -d --no-show-raw-insn %t.rv32 | FileCheck %s +# RUN: llvm-objdump -d --no-show-raw-insn %t.rv64 | FileCheck %s +# RUN: ld.lld -pie %t.rv32.o --defsym foo=_start+12 --defsym bar=_start -o %t.rv32 +# RUN: ld.lld -pie %t.rv64.o --defsym foo=_start+12 --defsym bar=_start -o %t.rv64 +# RUN: llvm-objdump -d --no-show-raw-insn %t.rv32 | FileCheck %s +# RUN: llvm-objdump -d --no-show-raw-insn %t.rv64 | FileCheck %s +# CHECK: auipc a0, 0 +# CHECK-NEXT: addi a0, a0, 12 +# CHECK-NEXT: sw zero, 12(a0) +# CHECK: auipc a0, 0 +# CHECK-NEXT: addi a0, a0, -12 +# CHECK-NEXT: sw zero, -12(a0) + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+12-0x80000800 -o %t.rv32.limits +# RUN: ld.lld %t.rv64.o --defsym foo=_start+0x7ffff7ff --defsym bar=_start+12-0x80000800 -o %t.rv64.limits +# RUN: llvm-objdump -d --no-show-raw-insn %t.rv32.limits | FileCheck --check-prefix=LIMITS %s +# RUN: llvm-objdump -d --no-show-raw-insn %t.rv64.limits | FileCheck --check-prefix=LIMITS %s +# LIMITS: auipc a0, 524287 +# LIMITS-NEXT: addi a0, a0, 2047 +# LIMITS-NEXT: sw zero, 2047(a0) +# LIMITS: auipc a0, 524288 +# LIMITS-NEXT: addi a0, a0, -2048 +# LIMITS-NEXT: sw zero, -2048(a0) + +# RUN: ld.lld %t.rv32.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+12-0x80000801 -o %t +# RUN: not ld.lld %t.rv64.o --defsym foo=_start+0x7ffff800 --defsym bar=_start+12-0x80000801 -o %t 2>&1 | FileCheck --check-prefix=ERROR %s +# ERROR: relocation R_RISCV_PCREL_HI20 out of range: 524288 is not in [-524288, 524287] +# ERROR-NEXT: relocation R_RISCV_PCREL_HI20 out of range: -524289 is not in [-524288, 524287] + +.global _start +_start: + auipc a0, %pcrel_hi(foo) + addi a0, a0, %pcrel_lo(_start) + sw x0, %pcrel_lo(_start)(a0) +.L1: + auipc a0, %pcrel_hi(bar) + addi a0, a0, %pcrel_lo(.L1) + sw x0, %pcrel_lo(.L1)(a0) \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv-plt.s b/tests_src/relocs/riscv64/riscv-plt.s new file mode 100644 index 00000000..95652976 --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-plt.s @@ -0,0 +1,106 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-plt.s + +# REQUIRES: riscv +# RUN: echo '.globl bar, weak; .type bar,@function; .type weak,@function; bar: weak:' > %t1.s + +# RUN: llvm-mc -filetype=obj -triple=riscv32 %t1.s -o %t1.32.o +# RUN: ld.lld -shared %t1.32.o -soname=t1.32.so -o %t1.32.so +# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o +# RUN: ld.lld %t.32.o %t1.32.so -z separate-code -o %t.32 +# RUN: llvm-readelf -S -s %t.32 | FileCheck --check-prefixes=SEC,NM %s +# RUN: llvm-readobj -r %t.32 | FileCheck --check-prefix=RELOC32 %s +# RUN: llvm-readelf -x .got.plt %t.32 | FileCheck --check-prefix=GOTPLT32 %s +# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=DIS,DIS32 %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64 %t1.s -o %t1.64.o +# RUN: ld.lld -shared %t1.64.o -soname=t1.64.so -o %t1.64.so +# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o +# RUN: ld.lld %t.64.o %t1.64.so -z separate-code -o %t.64 +# RUN: llvm-readelf -S -s %t.64 | FileCheck --check-prefixes=SEC,NM %s +# RUN: llvm-readobj -r %t.64 | FileCheck --check-prefix=RELOC64 %s +# RUN: llvm-readelf -x .got.plt %t.64 | FileCheck --check-prefix=GOTPLT64 %s +# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=DIS,DIS64 %s + +# SEC: .plt PROGBITS {{0*}}00011030 + +## A canonical PLT has a non-zero st_value. bar and weak are called but their +## addresses are not taken, so a canonical PLT is not necessary. +# NM: {{0*}}00000000 0 FUNC GLOBAL DEFAULT UND bar +# NM: {{0*}}00000000 0 FUNC WEAK DEFAULT UND weak + +## The .got.plt slots relocated by .rela.plt point to .plt +## This is required by glibc. +# RELOC32: .rela.plt { +# RELOC32-NEXT: 0x13070 R_RISCV_JUMP_SLOT bar 0x0 +# RELOC32-NEXT: 0x13074 R_RISCV_JUMP_SLOT weak 0x0 +# RELOC32-NEXT: } +# GOTPLT32: section '.got.plt' +# GOTPLT32-NEXT: 0x00013068 00000000 00000000 30100100 30100100 + +# RELOC64: .rela.plt { +# RELOC64-NEXT: 0x130E0 R_RISCV_JUMP_SLOT bar 0x0 +# RELOC64-NEXT: 0x130E8 R_RISCV_JUMP_SLOT weak 0x0 +# RELOC64-NEXT: } +# GOTPLT64: section '.got.plt' +# GOTPLT64-NEXT: 0x000130d0 00000000 00000000 00000000 00000000 +# GOTPLT64-NEXT: 0x000130e0 30100100 00000000 30100100 00000000 + +# DIS: _start: +## Direct call +## foo - . = 0x11020-0x11000 = 32 +# DIS-NEXT: 11000: auipc ra, 0 +# DIS-NEXT: jalr 32(ra) +## bar@plt - . = 0x11050-0x11008 = 72 +# DIS-NEXT: 11008: auipc ra, 0 +# DIS-NEXT: jalr 72(ra) +## bar@plt - . = 0x11050-0x11010 = 64 +# DIS-NEXT: 11010: auipc ra, 0 +# DIS-NEXT: jalr 64(ra) +## weak@plt - . = 0x11060-0x11018 = 72 +# DIS-NEXT: 11018: auipc ra, 0 +# DIS-NEXT: jalr 72(ra) +# DIS: foo: +# DIS-NEXT: 11020: + +# DIS: Disassembly of section .plt: +# DIS: .plt: +# DIS-NEXT: auipc t2, 2 +# DIS-NEXT: sub t1, t1, t3 +## .got.plt - .plt = 0x13068 - 0x11030 = 4096*2+56 +# DIS32-NEXT: lw t3, 56(t2) +# DIS64-NEXT: ld t3, 160(t2) +# DIS-NEXT: addi t1, t1, -44 +# DIS32-NEXT: addi t0, t2, 56 +# DIS64-NEXT: addi t0, t2, 160 +# DIS32-NEXT: srli t1, t1, 2 +# DIS64-NEXT: srli t1, t1, 1 +# DIS32-NEXT: lw t0, 4(t0) +# DIS64-NEXT: ld t0, 8(t0) +# DIS-NEXT: jr t3 + +## 32-bit: &.got.plt[bar]-. = 0x13070-0x11050 = 4096*2+32 +# DIS: 11050: auipc t3, 2 +# DIS32-NEXT: lw t3, 32(t3) +# DIS64-NEXT: ld t3, 144(t3) +# DIS-NEXT: jalr t1, t3 +# DIS-NEXT: nop + +## 32-bit: &.got.plt[weak]-. = 0x13074-0x11060 = 4096*2+20 +# DIS: 11060: auipc t3, 2 +# DIS32-NEXT: lw t3, 20(t3) +# DIS64-NEXT: ld t3, 136(t3) +# DIS-NEXT: jalr t1, t3 +# DIS-NEXT: nop + +.global _start, foo, bar +.weak weak + +_start: + call foo + call bar + call bar@plt + call weak + +## foo is local and non-preemptale, no PLT is generated. +foo: + ret \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv-reloc-64-pic.s b/tests_src/relocs/riscv64/riscv-reloc-64-pic.s new file mode 100644 index 00000000..c97e7b47 --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-reloc-64-pic.s @@ -0,0 +1,12 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-reloc-64-pic.s + +# REQUIRES: riscv +# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o +# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s + +# CHECK: error: relocation R_RISCV_32 cannot be used against symbol a + +.globl a + +.data +.long a \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv-reloc-copy.s b/tests_src/relocs/riscv64/riscv-reloc-copy.s new file mode 100644 index 00000000..1fbb35eb --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-reloc-copy.s @@ -0,0 +1,26 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-reloc-copy.s + +# REQUIRES: riscv +# RUN: llvm-mc -filetype=obj -triple=riscv32 %p/Inputs/relocation-copy.s -o %t1.o +# RUN: ld.lld -shared %t1.o -soname=t1.so -o %t1.so +# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.o +# RUN: ld.lld %t.o %t1.so -o %t +# RUN: llvm-readobj -r %t | FileCheck --check-prefixes=REL,REL32 %s +# RUN: llvm-nm -S %t | FileCheck --check-prefix=NM32 %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64 %p/Inputs/relocation-copy.s -o %t1.o +# RUN: ld.lld -shared %t1.o -soname=t1.so -o %t1.so +# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o +# RUN: ld.lld %t.o %t1.so -o %t +# RUN: llvm-readobj -r %t | FileCheck --check-prefixes=REL,REL64 %s +# RUN: llvm-nm -S %t | FileCheck --check-prefix=NM64 %s + +# REL: .rela.dyn { +# REL32-NEXT: 0x13210 R_RISCV_COPY x 0x0 +# REL64-NEXT: 0x13360 R_RISCV_COPY x 0x0 +# REL-NEXT: } + +# NM32: 00013210 00000004 B x +# NM64: 0000000000013360 0000000000000004 B x + +la a0, x \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv-reloc-got.s b/tests_src/relocs/riscv64/riscv-reloc-got.s new file mode 100644 index 00000000..565697d8 --- /dev/null +++ b/tests_src/relocs/riscv64/riscv-reloc-got.s @@ -0,0 +1,71 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv-reloc-got.s + +# REQUIRES: riscv +# RUN: echo '.globl b; b:' | llvm-mc -filetype=obj -triple=riscv32 - -o %t1.o +# RUN: ld.lld -shared %t1.o -soname=t1.so -o %t1.so + +# RUN: llvm-mc -filetype=obj -triple=riscv32 -position-independent %s -o %t.o +# RUN: ld.lld %t.o %t1.so -o %t +# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC32 %s +# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC32 %s +# RUN: llvm-nm %t | FileCheck --check-prefix=NM32 %s +# RUN: llvm-readobj -x .got %t | FileCheck --check-prefix=HEX32 %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=DIS32 %s + +# RUN: echo '.globl b; b:' | llvm-mc -filetype=obj -triple=riscv64 - -o %t1.o +# RUN: ld.lld -shared %t1.o -soname=t1.so -o %t1.so + +# RUN: llvm-mc -filetype=obj -triple=riscv64 -position-independent %s -o %t.o +# RUN: ld.lld %t.o %t1.so -o %t +# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC64 %s +# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC64 %s +# RUN: llvm-nm %t | FileCheck --check-prefix=NM64 %s +# RUN: llvm-readobj -x .got %t | FileCheck --check-prefix=HEX64 %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=DIS64 %s + +# SEC32: .got PROGBITS 0001220c 00020c 00000c +# SEC64: .got PROGBITS 0000000000012358 000358 000018 + +# RELOC32: .rela.dyn { +# RELOC32-NEXT: 0x12214 R_RISCV_32 b 0x0 +# RELOC32-NEXT: } + +# RELOC64: .rela.dyn { +# RELOC64-NEXT: 0x12368 R_RISCV_64 b 0x0 +# RELOC64-NEXT: } + +# NM32: 00013218 d a +# NM64: 0000000000013370 d a + +## .got[0] = _DYNAMIC +## .got[1] = a (filled at link time) +## .got[2] = 0 (relocated by R_RISCV_64 at runtime) +# HEX32: section '.got': +# HEX32: 0x0001220c ac210100 18320100 00000000 + +# HEX64: section '.got': +# HEX64: 0x00012358 98220100 00000000 70330100 00000000 +# HEX64: 0x00012368 00000000 00000000 + +## &.got[1]-. = 0x12210-0x1119c = 4096*1+116 +# DIS32: 1119c: auipc a0, 1 +# DIS32-NEXT: lw a0, 116(a0) +## &.got[2]-. = 0x12214-0x111a4 = 4096*1+112 +# DIS32: 111a4: auipc a0, 1 +# DIS32-NEXT: lw a0, 112(a0) + +## &.got[1]-. = 0x12360-0x11288 = 4096*1+216 +# DIS64: 11288: auipc a0, 1 +# DIS64-NEXT: ld a0, 216(a0) +## &.got[2]-. = 0x12368-0x11290 = 4096*1+216 +# DIS64: 11290: auipc a0, 1 +# DIS64-NEXT: ld a0, 216(a0) + +la a0,a +la a0,b + +.data +a: +## An undefined reference of _GLOBAL_OFFSET_TABLE_ causes .got[0] to be +## allocated to store _DYNAMIC. +.long _GLOBAL_OFFSET_TABLE_ - . \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv64-reloc-64-pic.s b/tests_src/relocs/riscv64/riscv64-reloc-64-pic.s new file mode 100644 index 00000000..2f273f56 --- /dev/null +++ b/tests_src/relocs/riscv64/riscv64-reloc-64-pic.s @@ -0,0 +1,25 @@ +# https://github.com/llvm/llvm-project/blob/523f999acf6faa94d497ca1e81cb676d0a6063d5/lld/test/ELF/riscv64-reloc-64-pic.s + +# REQUIRES: riscv +# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-nm %t.so | FileCheck --check-prefix=NM %s +# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOC %s + +## R_RISCV_64 is an absolute relocation type. +## In PIC mode, it creates a relative relocation if the symbol is non-preemptable. + +# NM: 0000000000003350 d b + +# RELOC: .rela.dyn { +# RELOC-NEXT: 0x3350 R_RISCV_RELATIVE - 0x3350 +# RELOC-NEXT: 0x3348 R_RISCV_64 a 0 +# RELOC-NEXT: } + +.globl a, b +.hidden b + +.data +.quad a +b: +.quad b \ No newline at end of file diff --git a/tests_src/relocs/riscv64/riscv64-reloc-generate.sh b/tests_src/relocs/riscv64/riscv64-reloc-generate.sh new file mode 100755 index 00000000..a3f3c287 --- /dev/null +++ b/tests_src/relocs/riscv64/riscv64-reloc-generate.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +TARGET_DIR="../../../../binaries/tests/riscv64" +MC="llvm-mc" +LLD="ld.lld" +TRIPLE="riscv64-unknown-elf" +MC_FLAGS="-filetype=obj -triple=$TRIPLE -mattr=-relax" + +clean_up() { + echo "Cleaning up old build files..." + rm -f "${TARGET_DIR:?Target directory not set} "/*.{o,so} +} + +build_all() { + echo "Starting compilation of RISC-V 64 relocation test cases..." + + $MC $MC_FLAGS riscv-call.s -o riscv-call.rv64.o + $MC $MC_FLAGS riscv-hi20-lo12.s -o riscv-hi20-lo12.rv64.o + $MC $MC_FLAGS riscv-jal.s -o riscv-jal.rv64.o + $MC $MC_FLAGS riscv-branch.s -o riscv-branch.rv64.o + $MC $MC_FLAGS riscv-pcrel-hilo.s -o riscv-pcrel-hilo.rv64.o + $MC $MC_FLAGS riscv-plt.s -o riscv-plt.64.o + + $MC -filetype=obj -triple=riscv64 -position-independent riscv-reloc-got.s -o riscv-reloc-got.o + $MC -filetype=obj -triple=riscv64 riscv64-reloc-64-pic.s -o riscv64-reloc-64-pic.o + $LLD -shared riscv64-reloc-64-pic.o -o riscv64-reloc-64-pic.so + + $MC -filetype=obj -triple=riscv64 riscv-reloc-copy.s -o riscv-reloc-copy.o +} + +move_to_binaries() { + if [ ! -d "$TARGET_DIR" ]; then + echo "Creating target directory: $TARGET_DIR" + mkdir -p "$TARGET_DIR" + fi + + echo "Moving files to $TARGET_DIR ..." + # Move .o and .so files, suppressing errors if files are missing + mv -v *.o *.so "$TARGET_DIR/" 2>/dev/null +} + +clean_up + +build_all + +move_to_binaries + +echo "All tasks completed successfully!"