rtld_start.S revision 1.3 1 1.3 jakllsch /* $NetBSD: rtld_start.S,v 1.3 2018/09/20 18:41:05 jakllsch Exp $ */
2 1.1 matt
3 1.1 matt /*-
4 1.1 matt * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 1.1 matt * All rights reserved.
6 1.1 matt *
7 1.1 matt * This code is derived from software contributed to The NetBSD Foundation
8 1.1 matt * by Matt Thomas of 3am Software Foundry.
9 1.1 matt *
10 1.1 matt * Redistribution and use in source and binary forms, with or without
11 1.1 matt * modification, are permitted provided that the following conditions
12 1.1 matt * are met:
13 1.1 matt * 1. Redistributions of source code must retain the above copyright
14 1.1 matt * notice, this list of conditions and the following disclaimer.
15 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 matt * notice, this list of conditions and the following disclaimer in the
17 1.1 matt * documentation and/or other materials provided with the distribution.
18 1.1 matt *
19 1.1 matt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 matt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 matt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 matt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 matt * POSSIBILITY OF SUCH DAMAGE.
30 1.1 matt */
31 1.1 matt
32 1.3 jakllsch /*-
33 1.3 jakllsch * Copyright (c) 2014 The FreeBSD Foundation
34 1.3 jakllsch * All rights reserved.
35 1.3 jakllsch *
36 1.3 jakllsch * This software was developed by Andrew Turner under
37 1.3 jakllsch * sponsorship from the FreeBSD Foundation.
38 1.3 jakllsch *
39 1.3 jakllsch * Redistribution and use in source and binary forms, with or without
40 1.3 jakllsch * modification, are permitted provided that the following conditions
41 1.3 jakllsch * are met:
42 1.3 jakllsch * 1. Redistributions of source code must retain the above copyright
43 1.3 jakllsch * notice, this list of conditions and the following disclaimer.
44 1.3 jakllsch * 2. Redistributions in binary form must reproduce the above copyright
45 1.3 jakllsch * notice, this list of conditions and the following disclaimer in the
46 1.3 jakllsch * documentation and/or other materials provided with the distribution.
47 1.3 jakllsch *
48 1.3 jakllsch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
49 1.3 jakllsch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 1.3 jakllsch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 1.3 jakllsch * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
52 1.3 jakllsch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 1.3 jakllsch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 1.3 jakllsch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 1.3 jakllsch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 1.3 jakllsch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 1.3 jakllsch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 1.3 jakllsch * SUCH DAMAGE.
59 1.3 jakllsch */
60 1.3 jakllsch
61 1.1 matt #include <machine/asm.h>
62 1.1 matt
63 1.3 jakllsch RCSID("$NetBSD: rtld_start.S,v 1.3 2018/09/20 18:41:05 jakllsch Exp $")
64 1.1 matt
65 1.1 matt /*
66 1.1 matt * void _rtld_start(void (*cleanup)(void), const Obj_Entry *obj,
67 1.1 matt * struct ps_strings *ps_strings);
68 1.1 matt *
69 1.1 matt * X0 = NULL
70 1.1 matt * X1 = NULL
71 1.1 matt * X2 = ps_strings
72 1.1 matt * X30 (LR) = 0
73 1.1 matt * X29 (FP) = 0
74 1.1 matt */
75 1.1 matt ENTRY_NP(_rtld_start)
76 1.1 matt mov x24, x2 /* save ps_strings */
77 1.1 matt
78 1.1 matt adrp x1, :got:_DYNAMIC /* load _DYNAMIC offset from GOT */
79 1.1 matt ldr x1, [x1, #:got_lo12:_DYNAMIC]
80 1.1 matt
81 1.1 matt adrp x0, _DYNAMIC /* get &_DYNAMIC */
82 1.1 matt add x0, x0, #:lo12:_DYNAMIC
83 1.2 skrll
84 1.1 matt sub x25, x0, x1 /* relocbase = &_DYNAMIC - GOT:_DYNAMIC */
85 1.1 matt mov x1, x25 /* pass as 2nd argument */
86 1.2 skrll bl _C_LABEL(_rtld_relocate_nonplt_self)
87 1.1 matt
88 1.1 matt sub sp, sp, #16 /* reserve space for returns */
89 1.1 matt mov x0, sp /* pointer to reserved space */
90 1.1 matt mov x1, x25 /* pass relocbase */
91 1.2 skrll bl _C_LABEL(_rtld)
92 1.1 matt mov x17, x0 /* save entry point */
93 1.1 matt
94 1.1 matt ldp x0, x1, [sp], #16 /* pop cleanup & obj_main */
95 1.1 matt mov x2, x24 /* restore ps_strings */
96 1.1 matt
97 1.1 matt br x17 /* call saved entry point */
98 1.1 matt END(_rtld_start)
99 1.1 matt
100 1.1 matt /*
101 1.1 matt * Upon entry from plt0 entry:
102 1.2 skrll *
103 1.2 skrll * SP+0 = &PLTGOT[n + 3]
104 1.2 skrll * SP+8 = return addr
105 1.2 skrll * X16 = &PLTGOT[2]
106 1.1 matt */
107 1.1 matt ENTRY_NP(_rtld_bind_start)
108 1.2 skrll ldr x9, [sp] /* x9 = &PLTGOT[n+3] */
109 1.2 skrll
110 1.2 skrll /* save x0-x8 for arguments */
111 1.2 skrll stp x0, x1, [sp, #-16]!
112 1.2 skrll stp x2, x3, [sp, #-16]!
113 1.2 skrll stp x4, x5, [sp, #-16]!
114 1.2 skrll stp x6, x7, [sp, #-16]!
115 1.2 skrll stp x8, xzr, [sp, #-16]!
116 1.2 skrll
117 1.2 skrll /* save q0-q7 for arguments */
118 1.2 skrll stp q0, q1, [sp, #-32]!
119 1.2 skrll stp q2, q3, [sp, #-32]!
120 1.2 skrll stp q4, q5, [sp, #-32]!
121 1.2 skrll stp q6, q7, [sp, #-32]!
122 1.2 skrll
123 1.2 skrll ldr x0, [x16, #-8] /* x0 = PLTGOT[1] */
124 1.2 skrll sub x1, x9, x16 /* x1 = &PLTGOT[n+3] - &PLTGOT[1] = offset+8 */
125 1.2 skrll sub x1, x1, #8 /* x1 = offset */
126 1.2 skrll lsr x1, x1, #3 /* x1 /= sizeof(void *) */
127 1.2 skrll
128 1.2 skrll bl _C_LABEL(_rtld_bind)
129 1.2 skrll mov x17, x0 /* save result */
130 1.2 skrll
131 1.2 skrll /* restore q0-q7 for arguments */
132 1.2 skrll ldp q6, q7, [sp], #32
133 1.2 skrll ldp q4, q5, [sp], #32
134 1.2 skrll ldp q2, q3, [sp], #32
135 1.2 skrll ldp q0, q1, [sp], #32
136 1.2 skrll
137 1.2 skrll /* restore x0-x8 for arguments */
138 1.2 skrll ldp x8, xzr, [sp], #16
139 1.2 skrll ldp x6, x7, [sp], #16
140 1.2 skrll ldp x4, x5, [sp], #16
141 1.2 skrll ldp x2, x3, [sp], #16
142 1.2 skrll ldp x0, x1, [sp], #16
143 1.2 skrll
144 1.2 skrll ldp xzr, lr, [sp], #16 /* restore original lr pushed by plt0 */
145 1.1 matt br x17 /* call bound function */
146 1.1 matt END(_rtld_bind_start)
147 1.2 skrll
148 1.2 skrll
149 1.2 skrll ENTRY(_rtld_tlsdesc)
150 1.2 skrll ldr x0, [x0, #8]
151 1.2 skrll ret
152 1.2 skrll END(_rtld_tlsdesc)
153 1.3 jakllsch
154 1.3 jakllsch /*
155 1.3 jakllsch * uint64_t _rtld_tlsdesc_dynamic(struct tlsdesc *);
156 1.3 jakllsch *
157 1.3 jakllsch * TODO: We could lookup the saved index here to skip saving the entire stack.
158 1.3 jakllsch */
159 1.3 jakllsch ENTRY(_rtld_tlsdesc_dynamic)
160 1.3 jakllsch /* Store any registers we may use in rtld_tlsdesc_handle */
161 1.3 jakllsch stp x29, x30, [sp, #-(10 * 16)]!
162 1.3 jakllsch mov x29, sp
163 1.3 jakllsch stp x1, x2, [sp, #(1 * 16)]
164 1.3 jakllsch stp x3, x4, [sp, #(2 * 16)]
165 1.3 jakllsch stp x5, x6, [sp, #(3 * 16)]
166 1.3 jakllsch stp x7, x8, [sp, #(4 * 16)]
167 1.3 jakllsch stp x9, x10, [sp, #(5 * 16)]
168 1.3 jakllsch stp x11, x12, [sp, #(6 * 16)]
169 1.3 jakllsch stp x13, x14, [sp, #(7 * 16)]
170 1.3 jakllsch stp x15, x16, [sp, #(8 * 16)]
171 1.3 jakllsch stp x17, x18, [sp, #(9 * 16)]
172 1.3 jakllsch
173 1.3 jakllsch /* Find the tls offset */
174 1.3 jakllsch ldr x0, [x0, #8]
175 1.3 jakllsch mov x1, #1
176 1.3 jakllsch bl _rtld_tlsdesc_handle
177 1.3 jakllsch
178 1.3 jakllsch /* Restore the registers */
179 1.3 jakllsch ldp x17, x18, [sp, #(9 * 16)]
180 1.3 jakllsch ldp x15, x16, [sp, #(8 * 16)]
181 1.3 jakllsch ldp x13, x14, [sp, #(7 * 16)]
182 1.3 jakllsch ldp x11, x12, [sp, #(6 * 16)]
183 1.3 jakllsch ldp x9, x10, [sp, #(5 * 16)]
184 1.3 jakllsch ldp x7, x8, [sp, #(4 * 16)]
185 1.3 jakllsch ldp x5, x6, [sp, #(3 * 16)]
186 1.3 jakllsch ldp x3, x4, [sp, #(2 * 16)]
187 1.3 jakllsch ldp x1, x2, [sp, #(1 * 16)]
188 1.3 jakllsch ldp x29, x30, [sp], #(10 * 16)
189 1.3 jakllsch
190 1.3 jakllsch ret
191 1.3 jakllsch END(_rtld_tlsdesc_dynamic)
192