1/* PLT trampolines.  SH version.
2   Copyright (C) 2005-2021 Free Software Foundation, Inc.
3   This file is part of the GNU C Library.
4
5   The GNU C Library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9
10   The GNU C Library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with the GNU C Library; if not, see
17   <https://www.gnu.org/licenses/>.  */
18
19#include <sysdep.h>
20
21	.text
22	.globl _dl_runtime_resolve
23	.type _dl_runtime_resolve, @function
24	cfi_startproc
25	.align 5
26_dl_runtime_resolve:
27	mov.l r2,@-r15
28	cfi_adjust_cfa_offset (4)
29	mov.l r3,@-r15
30	cfi_adjust_cfa_offset (4)
31	mov.l r4,@-r15
32	cfi_adjust_cfa_offset (4)
33	mov.l r5,@-r15
34	cfi_adjust_cfa_offset (4)
35	mov.l r6,@-r15
36	cfi_adjust_cfa_offset (4)
37	mov.l r7,@-r15
38	cfi_adjust_cfa_offset (4)
39	mov.l r12,@-r15
40	cfi_adjust_cfa_offset (4)
41	sts.l macl,@-r15
42	cfi_adjust_cfa_offset (4)
43	sts.l mach,@-r15
44	cfi_adjust_cfa_offset (4)
45	movt r3			! Save T flag.
46	mov.l r3,@-r15
47	cfi_adjust_cfa_offset (4)
48#ifdef HAVE_FPU
49	sts.l	fpscr,@-r15
50	cfi_adjust_cfa_offset (4)
51	mov	#8,r3
52	swap.w	r3,r3
53	lds	r3,fpscr
54	fmov.s	fr11,@-r15
55	cfi_adjust_cfa_offset (4)
56	fmov.s	fr10,@-r15
57	cfi_adjust_cfa_offset (4)
58	fmov.s	fr9,@-r15
59	cfi_adjust_cfa_offset (4)
60	fmov.s	fr8,@-r15
61	cfi_adjust_cfa_offset (4)
62	fmov.s	fr7,@-r15
63	cfi_adjust_cfa_offset (4)
64	fmov.s	fr6,@-r15
65	cfi_adjust_cfa_offset (4)
66	fmov.s	fr5,@-r15
67	cfi_adjust_cfa_offset (4)
68	fmov.s	fr4,@-r15
69	cfi_adjust_cfa_offset (4)
70#endif
71	sts.l pr,@-r15
72	cfi_adjust_cfa_offset (4)
73	tst r0,r0
74	bt 1f
75	mov r0,r2
761:
77	mov r0,r4		! PLT type
78	mov r2,r5		! link map address
79#ifdef SHARED
80	mov.l 2f,r2
81	mova 2f,r0
82	add r0,r2		! Get GOT address in r2
83	mov.l 3f,r0
84	add r2,r0
85#else
86	mov.l 3f,r0
87#endif
88	jsr @r0			! Call resolver.
89	 mov r1,r6		! reloc offset
90	lds.l @r15+,pr		! Get register content back.
91	cfi_adjust_cfa_offset (-4)
92#ifdef HAVE_FPU
93	fmov.s	@r15+,fr4
94	cfi_adjust_cfa_offset (-4)
95	fmov.s	@r15+,fr5
96	cfi_adjust_cfa_offset (-4)
97	fmov.s	@r15+,fr6
98	cfi_adjust_cfa_offset (-4)
99	fmov.s	@r15+,fr7
100	cfi_adjust_cfa_offset (-4)
101	fmov.s	@r15+,fr8
102	cfi_adjust_cfa_offset (-4)
103	fmov.s	@r15+,fr9
104	cfi_adjust_cfa_offset (-4)
105	fmov.s	@r15+,fr10
106	cfi_adjust_cfa_offset (-4)
107	fmov.s	@r15+,fr11
108	cfi_adjust_cfa_offset (-4)
109	lds.l	@r15+,fpscr
110	cfi_adjust_cfa_offset (-4)
111#endif
112	mov.l @r15+,r3
113	cfi_adjust_cfa_offset (-4)
114	shal r3			! Lode T flag.
115	lds.l @r15+,mach
116	cfi_adjust_cfa_offset (-4)
117	lds.l @r15+,macl
118	cfi_adjust_cfa_offset (-4)
119	mov.l @r15+,r12
120	cfi_adjust_cfa_offset (-4)
121	mov.l @r15+,r7
122	cfi_adjust_cfa_offset (-4)
123	mov.l @r15+,r6
124	cfi_adjust_cfa_offset (-4)
125	mov.l @r15+,r5
126	cfi_adjust_cfa_offset (-4)
127	mov.l @r15+,r4
128	cfi_adjust_cfa_offset (-4)
129	mov.l @r15+,r3
130	cfi_adjust_cfa_offset (-4)
131	jmp @r0			! Jump to function address.
132	 mov.l @r15+,r2
133	cfi_adjust_cfa_offset (-4)
134	.align 2
135#ifdef SHARED
1362:	.long _GLOBAL_OFFSET_TABLE_
1373:	.long _dl_fixup@GOTOFF
138#else
1393:	.long _dl_fixup
140#endif
141	cfi_endproc
142	.size _dl_runtime_resolve, .-_dl_runtime_resolve
143
144
145	.globl _dl_runtime_profile
146	.type _dl_runtime_profile,@function
147	cfi_startproc
148	.align 5
149_dl_runtime_profile:
150	mov.l r12,@-r15
151	cfi_adjust_cfa_offset (4)
152#ifdef HAVE_FPU
153	sts.l	fpscr,@-r15
154	cfi_adjust_cfa_offset (4)
155	mov	#8,r12
156	swap.w	r12,r12
157	lds	r12,fpscr
158	fmov.s	fr11,@-r15
159	cfi_adjust_cfa_offset (4)
160	fmov.s	fr10,@-r15
161	cfi_adjust_cfa_offset (4)
162	fmov.s	fr9,@-r15
163	cfi_adjust_cfa_offset (4)
164	fmov.s	fr8,@-r15
165	cfi_adjust_cfa_offset (4)
166	fmov.s	fr7,@-r15
167	cfi_adjust_cfa_offset (4)
168	fmov.s	fr6,@-r15
169	cfi_adjust_cfa_offset (4)
170	fmov.s	fr5,@-r15
171	cfi_adjust_cfa_offset (4)
172	fmov.s	fr4,@-r15
173	cfi_adjust_cfa_offset (4)
174#else
175	add #-36,r15
176	cfi_adjust_cfa_offset (36)
177#endif
178	mov.l r7,@-r15
179	cfi_adjust_cfa_offset (4)
180	mov.l r6,@-r15
181	cfi_adjust_cfa_offset (4)
182	mov.l r5,@-r15
183	cfi_adjust_cfa_offset (4)
184	mov.l r4,@-r15
185	cfi_adjust_cfa_offset (4)
186	mov.l r3,@-r15
187	cfi_adjust_cfa_offset (4)
188	mov.l r2,@-r15
189	cfi_adjust_cfa_offset (4)
190	sts.l macl,@-r15
191	cfi_adjust_cfa_offset (4)
192	sts.l mach,@-r15
193	cfi_adjust_cfa_offset (4)
194	movt r3			! Save T flag.
195	mov.l r3,@-r15
196	cfi_adjust_cfa_offset (4)
197	sts.l pr,@-r15
198	cfi_adjust_cfa_offset (4)
199	tst r0,r0
200	bt 1f
201	mov r0,r2
2021:
203	mov r0,r4		! PLT type
204	mov r2,r5		! link map address
205	sts pr,r7		! return address
206	add #-24,r15
207	cfi_adjust_cfa_offset (24)
208	mov #40,r0
209	add r15,r0
210	mov.l r0,@r15		! Address of the register structure
211	mov #-1,r0
212	mov.l r0,@(8,r15)
213	mov #8,r0
214	add r15,r0
215	mov.l r0,@(4,r15)
216	mov.l r5,@(12,r15)
217	mov.l r1,@(16,r15)
218#ifdef SHARED
219	mov.l 2f,r12
220	mova 2f,r0
221	add r0,r12		! Get GOT address in r12
222	mov.l 3f,r0
223	add r12,r0
224#else
225	mov.l 3f,r0
226#endif
227	jsr @r0			! Call resolver.
228	 mov r1,r6		! reloc offset
229	mov.l @(8,r15),r1
230	cmp/pz r1
231	bt 4f
232	add #24,r15
233	cfi_adjust_cfa_offset (-24)
234	lds.l @r15+,pr		! Get register content back.
235	cfi_adjust_cfa_offset (-4)
236	mov.l @r15+,r3
237	cfi_adjust_cfa_offset (-4)
238	shal r3			! Lode T flag.
239	lds.l @r15+,mach
240	cfi_adjust_cfa_offset (-4)
241	lds.l @r15+,macl
242	cfi_adjust_cfa_offset (-4)
243	mov.l @r15+,r2
244	cfi_adjust_cfa_offset (-4)
245	mov.l @r15+,r3
246	cfi_adjust_cfa_offset (-4)
247	mov.l @r15+,r4
248	cfi_adjust_cfa_offset (-4)
249	mov.l @r15+,r5
250	cfi_adjust_cfa_offset (-4)
251	mov.l @r15+,r6
252	cfi_adjust_cfa_offset (-4)
253	mov.l @r15+,r7
254	cfi_adjust_cfa_offset (-4)
255#ifdef HAVE_FPU
256	fmov.s	@r15+,fr4
257	cfi_adjust_cfa_offset (-4)
258	fmov.s	@r15+,fr5
259	cfi_adjust_cfa_offset (-4)
260	fmov.s	@r15+,fr6
261	cfi_adjust_cfa_offset (-4)
262	fmov.s	@r15+,fr7
263	cfi_adjust_cfa_offset (-4)
264	fmov.s	@r15+,fr8
265	cfi_adjust_cfa_offset (-4)
266	fmov.s	@r15+,fr9
267	cfi_adjust_cfa_offset (-4)
268	fmov.s	@r15+,fr10
269	cfi_adjust_cfa_offset (-4)
270	fmov.s	@r15+,fr11
271	cfi_adjust_cfa_offset (-4)
272	lds.l	@r15+,fpscr
273	cfi_adjust_cfa_offset (-4)
274#else
275	add #36,r15
276	cfi_adjust_cfa_offset (-36)
277#endif
278	jmp @r0			! Jump to function address.
279	 mov.l @r15+,r12
280	cfi_adjust_cfa_offset (-4)
281	.align 2
282#ifdef SHARED
2832:	.long _GLOBAL_OFFSET_TABLE_
2843:	.long _dl_profile_fixup@GOTOFF
285#else
2863:	.long _dl_profile_fixup
287#endif
288
289	cfi_adjust_cfa_offset (104)
2904:
291	mov #104,r3
292	add r15,r3		! Original stack
293	mov.l r8,@(20,r15)
294	cfi_rel_offset (r8, 20)
295	mov r15,r8
296	sub r1,r15
297	shlr2 r15
298	shll2 r15
299	mov r15,r4
300	shlr2 r1
301	tst r1,r1
3025:
303	bt/s 6f
304	 dt r1
305	mov.l @r3+,r2
306	mov.l r2,@r4
307	bra 5b
308	 add #4,r4
3096:
310	mov.l @r8,r12
311	mov.l @r12+,r2
312	mov.l @r12+,r3
313	mov.l @r12+,r4
314	mov.l @r12+,r5
315	mov.l @r12+,r6
316	mov.l @r12+,r7
317#ifdef HAVE_FPU
318	fmov.s	@r12+,fr4
319	fmov.s	@r12+,fr5
320	fmov.s	@r12+,fr6
321	fmov.s	@r12+,fr7
322	fmov.s	@r12+,fr8
323	fmov.s	@r12+,fr9
324	fmov.s	@r12+,fr10
325	fmov.s	@r12+,fr11
326	lds.l	@r12+,fpscr
327#else
328	add #36,r2
329#endif
330	jsr @r0			! Call function.
331	 nop
332	mov r8,r15
333	mov.l @(12,r15),r4	! link map address
334	mov.l @(16,r15),r5	! reloc offset
335	mov.l @r15,r6		! input registers
336#ifdef HAVE_FPU
337	mov #16,r8
338	add r15,r8
339	fmov.s fr1,@-r8
340	fmov.s fr0,@-r8
341#else
342	mov #8,r8
343	add r15,r8
344#endif
345	mov.l r1,@-r8
346	mov.l r0,@-r8
347	mov.l @(20,r15),r8
348	cfi_restore (r8)
349#ifdef SHARED
350	mov.l 7f,r12
351	mova 7f,r0
352	add r0,r12		! Get GOT address in r12
353	mov.l 8f,r0
354	add r12,r0
355#else
356	mov.l 8f,r0
357#endif
358	jsr @r0
359	 mov r15,r7		! output registers
360	mov.l @r15+,r0
361	cfi_adjust_cfa_offset (-4)
362	mov.l @r15+,r1
363	cfi_adjust_cfa_offset (-4)
364#ifdef HAVE_FPU
365	fmov.s @r15+,fr0
366	cfi_adjust_cfa_offset (-4)
367	fmov.s @r15+,fr1
368	cfi_adjust_cfa_offset (-4)
369	add #8,r15
370	cfi_adjust_cfa_offset (-8)
371#else
372	add #16,r15
373	cfi_adjust_cfa_offset (-16)
374#endif
375	lds.l @r15+,pr		! Get register content back.
376	cfi_adjust_cfa_offset (-4)
377	mov.l @r15+,r3
378	cfi_adjust_cfa_offset (-4)
379	shal r3			! Lode T flag.
380	lds.l @r15+,mach
381	cfi_adjust_cfa_offset (-4)
382	lds.l @r15+,macl
383	cfi_adjust_cfa_offset (-4)
384	mov.l @r15+,r2
385	cfi_adjust_cfa_offset (-4)
386	mov.l @r15+,r3
387	cfi_adjust_cfa_offset (-4)
388	mov.l @r15+,r4
389	cfi_adjust_cfa_offset (-4)
390	mov.l @r15+,r5
391	cfi_adjust_cfa_offset (-4)
392	mov.l @r15+,r6
393	cfi_adjust_cfa_offset (-4)
394	mov.l @r15+,r7
395	cfi_adjust_cfa_offset (-4)
396#ifdef HAVE_FPU
397	fmov.s	@r15+,fr4
398	cfi_adjust_cfa_offset (-4)
399	fmov.s	@r15+,fr5
400	cfi_adjust_cfa_offset (-4)
401	fmov.s	@r15+,fr6
402	cfi_adjust_cfa_offset (-4)
403	fmov.s	@r15+,fr7
404	cfi_adjust_cfa_offset (-4)
405	fmov.s	@r15+,fr8
406	cfi_adjust_cfa_offset (-4)
407	fmov.s	@r15+,fr9
408	cfi_adjust_cfa_offset (-4)
409	fmov.s	@r15+,fr10
410	cfi_adjust_cfa_offset (-4)
411	fmov.s	@r15+,fr11
412	cfi_adjust_cfa_offset (-4)
413	lds.l	@r15+,fpscr
414	cfi_adjust_cfa_offset (-4)
415#else
416	add #36,r15
417	cfi_adjust_cfa_offset (-36)
418#endif
419	rts			! Jump to function address.
420	 mov.l @r15+,r12
421	cfi_adjust_cfa_offset (-4)
422	cfi_endproc
423	.align 2
424#ifdef SHARED
4257:	.long _GLOBAL_OFFSET_TABLE_
4268:	.long _dl_audit_pltexit@GOTOFF
427#else
4288:	.long _dl_audit_pltexit
429#endif
430	.size _dl_runtime_profile, .-_dl_runtime_profile
431