ppc32-call-stub-pic.s
5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# REQUIRES: ppc
# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o
# RUN: echo '.globl f, g, h; f: g: h:' | llvm-mc -filetype=obj -triple=powerpc - -o %t1.o
# RUN: ld.lld -shared %t1.o -soname t1.so -o %t1.so
# RUN: echo 'bl f+0x8000@plt' | llvm-mc -filetype=obj -triple=powerpc - -o %t2.o
## Check we can create PLT entries for -fPIE or -fpie executable.
# RUN: ld.lld -pie %t.o %t1.so %t2.o -o %t
# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
# RUN: llvm-readobj -d %t | FileCheck --check-prefix=DYN %s
# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC %s
# RUN: llvm-readelf -x .plt %t | FileCheck --check-prefix=HEX %s
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,PIE %s
## Check we can create PLT entries for -fPIC or -fpic DSO.
# RUN: ld.lld -shared %t.o %t1.so %t2.o -o %t
# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=CHECK,SHARED %s
# RELOC: .rela.dyn {
# RELOC-NEXT: R_PPC_ADDR32 f 0x0
# RELOC-NEXT: R_PPC_ADDR32 g 0x0
# RELOC-NEXT: R_PPC_ADDR32 h 0x0
# RELOC-NEXT: }
# RELOC-NEXT: .rela.plt {
# RELOC-NEXT: R_PPC_JMP_SLOT f 0x0
# RELOC-NEXT: R_PPC_JMP_SLOT g 0x0
# RELOC-NEXT: R_PPC_JMP_SLOT h 0x0
# RELOC-NEXT: }
# SEC: .got PROGBITS 00020370
# DYN: PPC_GOT 0x20370
## .got2+0x8000-0x10004 = 0x30000+0x8000-0x10004 = 65536*2+32764
# CHECK-LABEL: <_start>:
# PIE-NEXT: bcl 20, 31, 0x10210
# PIE-NEXT: 10210: mflr 30
# PIE-NEXT: addis 30, 30, 3
# PIE-NEXT: addi 30, 30, -32404
## Two bl 00008000.got2.plt_pic32.f
# PIE-NEXT: bl 0x10244
# PIE-NEXT: bl 0x10244
## Two bl 00008000.got2.plt_pic32.g
# PIE-NEXT: bl 0x10254
# PIE-NEXT: bl 0x10254
## Two bl 00008000.got2.plt_pic32.h
# PIE-NEXT: bl 0x10264
# PIE-NEXT: bl 0x10264
# PIE-NEXT: addis 30, 30, {{.*}}
# PIE-NEXT: addi 30, 30, {{.*}}
## bl 00008000.plt_pic32.f
# PIE-NEXT: bl 0x10274
## bl 00008000.plt_pic32.f
# PIE-NEXT: bl 0x10284
# SHARED-NEXT: bcl 20, 31, 0x10230
# SHARED-NEXT: 10230: mflr 30
# SHARED-NEXT: addis 30, 30, 3
# SHARED-NEXT: addi 30, 30, -32420
# SHARED-NEXT: bl 0x10264
# SHARED-NEXT: bl 0x10264
# SHARED-NEXT: bl 0x10274
# SHARED-NEXT: bl 0x10274
# SHARED-NEXT: bl 0x10284
# SHARED-NEXT: bl 0x10284
# SHARED-NEXT: addis 30, 30, {{.*}}
# SHARED-NEXT: addi 30, 30, {{.*}}
# SHARED-NEXT: bl 0x10294
# SHARED-NEXT: bl 0x102a4
# CHECK-EMPTY:
## -fPIC call stubs of f and g.
# CHECK-NEXT: <00008000.got2.plt_pic32.f>:
# CHECK-NEXT: lwz 11, 32760(30)
# CHECK-NEXT: mtctr 11
# CHECK-NEXT: bctr
# CHECK-NEXT: nop
# CHECK-EMPTY:
# CHECK-NEXT: <00008000.got2.plt_pic32.g>:
# CHECK-NEXT: lwz 11, 32764(30)
# CHECK-NEXT: mtctr 11
# CHECK-NEXT: bctr
# CHECK-NEXT: nop
# CHECK-EMPTY:
## The -fPIC call stub of h needs two instructions addis+lwz to represent the offset 65536*1-32768.
# CHECK-NEXT: <00008000.got2.plt_pic32.h>:
# CHECK-NEXT: addis 11, 30, 1
# CHECK-NEXT: lwz 11, -32768(11)
# CHECK-NEXT: mtctr 11
# CHECK-NEXT: bctr
# CHECK-EMPTY:
## -fpic call stub of f.
# CHECK-NEXT: <00000000.plt_pic32.f>:
# CHECK-NEXT: addis 11, 30, 2
# CHECK-NEXT: lwz 11, 4(11)
# CHECK-NEXT: mtctr 11
# CHECK-NEXT: bctr
# CHECK-EMPTY:
## Another -fPIC call stub of f from another object file %t2.o
## .got2 may have different addresses in different object files,
## so the call stub cannot be shared.
# CHECK-NEXT: <00008000.got2.plt_pic32.f>:
## In Secure PLT ABI, .plt stores function pointers to first instructions of .glink
# HEX: 0x00040374 00010294 00010298 0001029c
## These instructions are referenced by .plt entries.
# CHECK: [[#%x,GLINK:]] <.glink>:
# CHECK-NEXT: b 0x[[#%x,GLINK+12]]
# CHECK-NEXT: b 0x[[#%x,GLINK+12]]
# CHECK-NEXT: b 0x[[#%x,GLINK+12]]
## PLTresolve
## Operand of addi: 0x102cc-.glink = 24
# CHECK-NEXT: addis 11, 11, 0
# CHECK-NEXT: mflr 0
# CHECK-NEXT: bcl 20, 31, 0x[[#%x,NEXT:]]
# CHECK-NEXT: [[#%x,NEXT]]: addi 11, 11, 24
# CHECK-NEXT: mflr 12
# CHECK-NEXT: mtlr 0
# CHECK-NEXT: sub 11, 11, 12
## Operand of lwz in -pie mode: &.got[1] - 0x102bc = 0x20380+4 - 0x102bc = 65536*1+200
# CHECK-NEXT: addis 12, 12, 1
# PIE-NEXT: lwz 0, 200(12)
# SHARED-NEXT: lwz 0, 184(12)
# PIE-NEXT: lwz 12, 204(12)
# SHARED-NEXT: lwz 12, 188(12)
# CHECK-NEXT: mtctr 0
# CHECK-NEXT: add 0, 11, 11
# CHECK-NEXT: add 11, 0, 11
# CHECK-NEXT: bctr
.section .got2,"aw"
.space 65516
.long f
.long g
.long h
.text
.globl _start
_start:
bcl 20,31,.L
.L:
mflr 30
addis 30, 30, .got2+0x8000-.L@ha
addi 30, 30, .got2+0x8000-.L@l
bl f+0x8000@plt
bl f+0x8000@plt
bl g+0x8000@plt
bl g+0x8000@plt
bl h+0x8000@plt
bl h+0x8000@plt
## An addend of 0 indicates r30 is stored in _GLOBAL_OFFSET_TABLE_.
## The existing thunk is incompatible, thus it cannot be reused.
addis 30, 30, _GLOBAL_OFFSET_TABLE_-.L@ha
addi 30, 30, _GLOBAL_OFFSET_TABLE_-.L@l
bl f@plt