1# REQUIRES: riscv 2# RUN: echo '.globl bar, weak; .type bar,@function; .type weak,@function; bar: weak:' > %t1.s 3 4# RUN: llvm-mc -filetype=obj -triple=riscv32 %t1.s -o %t1.32.o 5# RUN: ld.lld -shared %t1.32.o -soname=t1.32.so -o %t1.32.so 6# RUN: llvm-mc -filetype=obj -triple=riscv32 %s -o %t.32.o 7# RUN: ld.lld %t.32.o %t1.32.so -z separate-code -o %t.32 8# RUN: llvm-readelf -S -s %t.32 | FileCheck --check-prefixes=SEC,NM %s 9# RUN: llvm-readobj -r %t.32 | FileCheck --check-prefix=RELOC32 %s 10# RUN: llvm-readelf -x .got.plt %t.32 | FileCheck --check-prefix=GOTPLT32 %s 11# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=DIS,DIS32 %s 12 13# RUN: llvm-mc -filetype=obj -triple=riscv64 %t1.s -o %t1.64.o 14# RUN: ld.lld -shared %t1.64.o -soname=t1.64.so -o %t1.64.so 15# RUN: llvm-mc -filetype=obj -triple=riscv64 %s -o %t.64.o 16# RUN: ld.lld %t.64.o %t1.64.so -z separate-code -o %t.64 17# RUN: llvm-readelf -S -s %t.64 | FileCheck --check-prefixes=SEC,NM %s 18# RUN: llvm-readobj -r %t.64 | FileCheck --check-prefix=RELOC64 %s 19# RUN: llvm-readelf -x .got.plt %t.64 | FileCheck --check-prefix=GOTPLT64 %s 20# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=DIS,DIS64 %s 21 22# SEC: .plt PROGBITS {{0*}}00011030 23 24## A canonical PLT has a non-zero st_value. bar and weak are called but their 25## addresses are not taken, so a canonical PLT is not necessary. 26# NM: {{0*}}00000000 0 FUNC GLOBAL DEFAULT UND bar 27# NM: {{0*}}00000000 0 FUNC WEAK DEFAULT UND weak 28 29## The .got.plt slots relocated by .rela.plt point to .plt 30## This is required by glibc. 31# RELOC32: .rela.plt { 32# RELOC32-NEXT: 0x13070 R_RISCV_JUMP_SLOT bar 0x0 33# RELOC32-NEXT: 0x13074 R_RISCV_JUMP_SLOT weak 0x0 34# RELOC32-NEXT: } 35# GOTPLT32: section '.got.plt' 36# GOTPLT32-NEXT: 0x00013068 00000000 00000000 30100100 30100100 37 38# RELOC64: .rela.plt { 39# RELOC64-NEXT: 0x130E0 R_RISCV_JUMP_SLOT bar 0x0 40# RELOC64-NEXT: 0x130E8 R_RISCV_JUMP_SLOT weak 0x0 41# RELOC64-NEXT: } 42# GOTPLT64: section '.got.plt' 43# GOTPLT64-NEXT: 0x000130d0 00000000 00000000 00000000 00000000 44# GOTPLT64-NEXT: 0x000130e0 30100100 00000000 30100100 00000000 45 46# DIS: <_start>: 47## Direct call 48## foo - . = 0x11020-0x11000 = 32 49# DIS-NEXT: 11000: auipc ra, 0 50# DIS-NEXT: jalr 32(ra) 51## bar@plt - . = 0x11050-0x11008 = 72 52# DIS-NEXT: 11008: auipc ra, 0 53# DIS-NEXT: jalr 72(ra) 54## bar@plt - . = 0x11050-0x11010 = 64 55# DIS-NEXT: 11010: auipc ra, 0 56# DIS-NEXT: jalr 64(ra) 57## weak@plt - . = 0x11060-0x11018 = 72 58# DIS-NEXT: 11018: auipc ra, 0 59# DIS-NEXT: jalr 72(ra) 60# DIS: <foo>: 61# DIS-NEXT: 11020: 62 63# DIS: Disassembly of section .plt: 64# DIS: <.plt>: 65# DIS-NEXT: auipc t2, 2 66# DIS-NEXT: sub t1, t1, t3 67## .got.plt - .plt = 0x13068 - 0x11030 = 4096*2+56 68# DIS32-NEXT: lw t3, 56(t2) 69# DIS64-NEXT: ld t3, 160(t2) 70# DIS-NEXT: addi t1, t1, -44 71# DIS32-NEXT: addi t0, t2, 56 72# DIS64-NEXT: addi t0, t2, 160 73# DIS32-NEXT: srli t1, t1, 2 74# DIS64-NEXT: srli t1, t1, 1 75# DIS32-NEXT: lw t0, 4(t0) 76# DIS64-NEXT: ld t0, 8(t0) 77# DIS-NEXT: jr t3 78 79## 32-bit: &.got.plt[bar]-. = 0x13070-0x11050 = 4096*2+32 80# DIS: 11050: auipc t3, 2 81# DIS32-NEXT: lw t3, 32(t3) 82# DIS64-NEXT: ld t3, 144(t3) 83# DIS-NEXT: jalr t1, t3 84# DIS-NEXT: nop 85 86## 32-bit: &.got.plt[weak]-. = 0x13074-0x11060 = 4096*2+20 87# DIS: 11060: auipc t3, 2 88# DIS32-NEXT: lw t3, 20(t3) 89# DIS64-NEXT: ld t3, 136(t3) 90# DIS-NEXT: jalr t1, t3 91# DIS-NEXT: nop 92 93.global _start, foo, bar 94.weak weak 95 96_start: 97 call foo 98 call bar 99 call bar@plt 100 call weak 101 102## foo is local and non-preemptale, no PLT is generated. 103foo: 104 ret 105