2 # RUN: echo '.globl bar, weak; .type bar,@function; .type weak,@function; bar: weak:' > %t1.s
4 # RUN: llvm-mc --filetype=obj --triple=loongarch32 %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=loongarch32 %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
13 # RUN: llvm-mc --filetype=obj --triple=loongarch64 %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=loongarch64 %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
22 # SEC: .plt PROGBITS {{0*}}00020020
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
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: 0x40070 R_LARCH_JUMP_SLOT bar 0x0
33 # RELOC32-NEXT: 0x40074 R_LARCH_JUMP_SLOT weak 0x0
35 # GOTPLT32: section '.got.plt'
36 # GOTPLT32-NEXT: 0x00040068 00000000 00000000 20000200 20000200
38 # RELOC64: .rela.plt {
39 # RELOC64-NEXT: 0x400E0 R_LARCH_JUMP_SLOT bar 0x0
40 # RELOC64-NEXT: 0x400E8 R_LARCH_JUMP_SLOT weak 0x0
42 # GOTPLT64: section '.got.plt'
43 # GOTPLT64-NEXT: 0x000400d0 00000000 00000000 00000000 00000000
44 # GOTPLT64-NEXT: 0x000400e0 20000200 00000000 20000200 00000000
48 ## foo - . = 0x20010-0x20000 = 16
49 # DIS-NEXT: 20000: bl 16
50 ## bar@plt - . = 0x20040-0x20004 = 60
51 # DIS-NEXT: 20004: bl 60
52 ## bar@plt - . = 0x20040-0x20008 = 56
53 # DIS-NEXT: 20008: bl 56
54 ## weak@plt - . = 0x20050-0x2000c = 68
55 # DIS-NEXT: 2000c: bl 68
59 # DIS: Disassembly of section .plt:
61 ## 32-bit: .got.plt - .plt = 0x40068 - 0x20020 = 4096*32+72
62 # DIS32-NEXT: pcaddu12i $t2, 32
63 # DIS32-NEXT: sub.w $t1, $t1, $t3
64 # DIS32-NEXT: ld.w $t3, $t2, 72
65 # DIS32-NEXT: addi.w $t1, $t1, -44
66 # DIS32-NEXT: addi.w $t0, $t2, 72
67 # DIS32-NEXT: srli.w $t1, $t1, 2
68 # DIS32-NEXT: ld.w $t0, $t0, 4
71 ## 64-bit: .got.plt - .plt = 0x400d0 - 0x20020 = 4096*32+176
72 # DIS64-NEXT: pcaddu12i $t2, 32
73 # DIS64-NEXT: sub.d $t1, $t1, $t3
74 # DIS64-NEXT: ld.d $t3, $t2, 176
75 # DIS64-NEXT: addi.d $t1, $t1, -44
76 # DIS64-NEXT: addi.d $t0, $t2, 176
77 # DIS64-NEXT: srli.d $t1, $t1, 1
78 # DIS64-NEXT: ld.d $t0, $t0, 8
81 ## 32-bit: &.got.plt[bar]-. = 0x40070-0x20040 = 4096*32+48
82 ## 64-bit: &.got.plt[bar]-. = 0x400e0-0x20040 = 4096*32+160
83 # DIS: 20040: pcaddu12i $t3, 32
84 # DIS32-NEXT: ld.w $t3, $t3, 48
85 # DIS64-NEXT: ld.d $t3, $t3, 160
86 # DIS-NEXT: jirl $t1, $t3, 0
89 ## 32-bit: &.got.plt[weak]-. = 0x40074-0x20050 = 4096*32+36
90 ## 64-bit: &.got.plt[weak]-. = 0x400e8-0x20050 = 4096*32+152
91 # DIS: 20050: pcaddu12i $t3, 32
92 # DIS32-NEXT: ld.w $t3, $t3, 36
93 # DIS64-NEXT: ld.d $t3, $t3, 152
94 # DIS-NEXT: jirl $t1, $t3, 0
97 .global _start, foo, bar
106 ## foo is local and non-preemptible, no PLT is generated.