xref: /openbsd-src/libexec/ld.so/m88k/ldasm.S (revision d7a24b570c4e19ddff7ac1653e97326d8f619c8d)
1/*	$OpenBSD: ldasm.S,v 1.29 2019/02/03 02:20:36 guenther Exp $	*/
2
3/*
4 * Copyright (c) 2013 Miodrag Vallat.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18/*
19 * Copyright (c) 2006 Dale Rahn
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 * 1. Redistributions of source code must retain the above copyright
25 *    notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 *    notice, this list of conditions and the following disclaimer in the
28 *    documentation and/or other materials provided with the distribution.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
31 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
34 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
41 *
42 */
43
44#include <machine/asm.h>
45#include <sys/syscall.h>
46
47#define	AUX_base	7
48#define	AUX_entry	9
49
50/*
51 * ld.so entry point.
52 * On entry: r31 points to the kernel argument struct (argv, argv, environ).
53 * The environment pointers list is followed by an array of AuxInfo
54 * structs filled by the kernel.
55 */
56ENTRY(_dl_start)
57	/*
58	 * Two nop because execution may skip up to two instructions.
59	 * See setregs() in the kernel for details.
60	 *
61	 * Note that I have been hacking m88k for years and still fall
62	 * into this trap, every time. -- miod
63	 */
64	or	%r0,  %r0,  %r0
65	or	%r0,  %r0,  %r0
66
67	/*
68	 * Get some room for the contiguous AUX pointers array.
69	  */
70	or	%r30, %r31, 0
71	subu	%r31, %r31, (4 * (AUX_entry + 1))
72
73	/*
74	 * Align the stack to a 16 byte boundary.
75	 */
76	clr	%r31, %r31, 4<0>
77
78	/*
79	 * Invoke _dl_boot_bind
80	 */
81	or	%r2,  %r30, 0		| kernel args
82	or	%r3,  %r31, 0		| array base
83	bsr	1f			| the following instruction is skipped
84	bsr	_DYNAMIC		| but gives us the pc-relative offset
851:	ld	%r6, %r1, 0		| fetch branch instruction
86	mak	%r5, %r6, 26<2>		| pick branch offset and shift left by 2
87	addu	%r4, %r5, %r1
88	bsr	_dl_boot_bind
89
90	ld	%r2,  %r30, 0		| argc
91	addu	%r6,  %r30, 4 + 4
92	lda	%r3,  %r6[%r2]		| envp
93	ld	%r4,  %r31, 4 * AUX_base| ldoff
94	or	%r5,  %r31, 0		| array base
95	bsr.n	_dl_boot
96	 addu	%r2,  %r30, 4		| argv
97
98	or	%r31, %r30, 0
99	bsr	1f			| the following instruction is skipped
100	bcnd	eq0, %r0, _dl_dtors	| but gives us the pc-relative offset
1011:	ld.h	%r5, %r1, 2		| fetch branch offset (low 16 bits)
102	jmp.n	%r2
103	 lda	%r5, %r1[%r5]		| cleanup
104END(_dl_start)
105
106/*
107 * PLT resolver entry point.
108 * Invoked with the following stack frame:
109 *	r31(0x00)	zero
110 *	r31(0x04)	ELF object
111 *	r31(0x08)	saved r11
112 *	r31(0x0c)	saved r1
113 * All registers but r1 and r11 must be preserved. The resolver must return
114 * to the resolved address with r1 restored.
115 */
116#define	OBJECT_OFFSET	(4 * 1)
117#define	R11_OFFSET	(4 * 2)
118#define	R1_OFFSET	(4 * 3)
119#define	PLT_FRAME_SIZE	(4 * 4)
120#define REG_SIZE	(4 * 12)
121ENTRY(_dl_bind_start)
122	/*
123	 * Preserve caller-saved registers.
124	 */
125	subu	%r31, %r31, REG_SIZE
126	st.d	%r2,  %r31, 4 * 0
127	st.d	%r4,  %r31, 4 * 2
128	st.d	%r6,  %r31, 4 * 4
129	st.d	%r8,  %r31, 4 * 6
130	st	%r10, %r31, 4 * 8
131	st.d	%r12, %r31, 4 * 10
132
133	/*
134	 * Invoke resolver entry point.
135	 */
136	ld	%r2,  %r31, REG_SIZE + OBJECT_OFFSET
137	bsr.n	_dl_bind
138	 ld	%r3,  %r31, REG_SIZE + R11_OFFSET	| reloff
139
140	/*
141	 * Preserve return address.
142	 */
143	or	%r11, %r2,  %r0
144
145	/*
146	 * Restore caller-saved registers.
147	 */
148	ld.d	%r12, %r31, 4 * 10
149	ld	%r10, %r31, 4 * 8
150	ld.d	%r8,  %r31, 4 * 6
151	ld.d	%r6,  %r31, 4 * 4
152	ld.d	%r4,  %r31, 4 * 2
153	ld.d	%r2,  %r31, 4 * 0
154	ld	%r1,  %r31, REG_SIZE + R1_OFFSET
155
156	jmp.n	%r11
157	 addu	%r31, %r31, REG_SIZE + PLT_FRAME_SIZE
158END(_dl_bind_start)
159
160ENTRY(_dl_cacheflush)
161	tb0	0, %r0, 451
162	or	%r0, %r0, %r0				| never hit
163	jmp	%r1
164END(_dl_cacheflush)
165