rtld_start.S revision 1.4 1 1.4 skrll /* $NetBSD: rtld_start.S,v 1.4 2006/10/16 13:52:47 skrll Exp $ */
2 1.1 fredette
3 1.1 fredette /*-
4 1.1 fredette * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 1.1 fredette * All rights reserved.
6 1.1 fredette *
7 1.1 fredette * This code is derived from software contributed to The NetBSD Foundation
8 1.1 fredette * by Matt Fredette.
9 1.1 fredette *
10 1.1 fredette * Redistribution and use in source and binary forms, with or without
11 1.1 fredette * modification, are permitted provided that the following conditions
12 1.1 fredette * are met:
13 1.1 fredette * 1. Redistributions of source code must retain the above copyright
14 1.1 fredette * notice, this list of conditions and the following disclaimer.
15 1.1 fredette * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 fredette * notice, this list of conditions and the following disclaimer in the
17 1.1 fredette * documentation and/or other materials provided with the distribution.
18 1.1 fredette * 3. All advertising materials mentioning features or use of this software
19 1.1 fredette * must display the following acknowledgement:
20 1.1 fredette * This product includes software developed by the NetBSD
21 1.1 fredette * Foundation, Inc. and its contributors.
22 1.1 fredette * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1 fredette * contributors may be used to endorse or promote products derived
24 1.1 fredette * from this software without specific prior written permission.
25 1.1 fredette *
26 1.1 fredette * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1 fredette * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1 fredette * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1 fredette * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1 fredette * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1 fredette * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1 fredette * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1 fredette * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1 fredette * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1 fredette * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1 fredette * POSSIBILITY OF SUCH DAMAGE.
37 1.1 fredette */
38 1.1 fredette
39 1.1 fredette #include <machine/asm.h>
40 1.1 fredette #define _LOCORE /* XXX fredette we MUST get rid of this */
41 1.1 fredette #include <machine/frame.h>
42 1.1 fredette #undef _LOCORE
43 1.1 fredette
44 1.1 fredette .import _GLOBAL_OFFSET_TABLE_
45 1.1 fredette
46 1.4 skrll ENTRY($rtld_start,HPPA_FRAME_SIZE)
47 1.1 fredette
48 1.1 fredette /* Start stack calling convention. */
49 1.1 fredette copy %r3, %r1
50 1.1 fredette copy %sp, %r3
51 1.1 fredette stw,ma %r1, HPPA_FRAME_SIZE(%sp)
52 1.1 fredette
53 1.1 fredette /*
54 1.1 fredette * Save our single argument, the ps_strings pointer.
55 1.1 fredette * We'll need this twice later: once to call _rtld,
56 1.1 fredette * and again to transfer to the program's entry point.
57 1.1 fredette */
58 1.1 fredette stw %arg0, HPPA_FRAME_ARG(0)(%r3)
59 1.1 fredette
60 1.1 fredette /*
61 1.1 fredette * We can't move to C until we relocate at least the
62 1.1 fredette * Global Offset Table. Even finding the GOT is tricky
63 1.1 fredette * without inadvertently causing the linker to make
64 1.1 fredette * relocations for this part of the text segment.
65 1.1 fredette */
66 1.1 fredette
67 1.3 skrll bl L$lpc1, %r19
68 1.3 skrll depi 0, 31, 2, %r19
69 1.3 skrll L$lpc1: addil L'_DYNAMIC - ($PIC_pcrel$0 - 8), %r19
70 1.3 skrll ldo R'_DYNAMIC - ($PIC_pcrel$0 - 12)(%r1),%arg0
71 1.1 fredette
72 1.1 fredette /*
73 1.1 fredette * Load the absolute address of the beginning of the
74 1.1 fredette * GOT into %r19, the shared library linkage table
75 1.1 fredette * register, leaving it ready-to-use by the dynamic
76 1.1 fredette * linker C code.
77 1.1 fredette */
78 1.3 skrll addil L'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 16), %r19
79 1.3 skrll ldo R'_GLOBAL_OFFSET_TABLE_ - ($PIC_pcrel$0 - 20)(%r1),%r19
80 1.1 fredette
81 1.1 fredette /*
82 1.1 fredette * The linker sets the first entry in the GOT to the
83 1.1 fredette * unrelocated address of _DYNAMIC. Subtract this
84 1.1 fredette * from the absolute address of _DYNAMIC to get our
85 1.1 fredette * relocbase.
86 1.1 fredette */
87 1.1 fredette ldw 0(%r19), %arg1
88 1.1 fredette sub %arg0, %arg1, %arg1 ; %arg1 = relocbase
89 1.3 skrll bl _rtld_relocate_nonplt_self, %rp
90 1.3 skrll copy %arg1, %r4 ; save for later
91 1.1 fredette
92 1.1 fredette /*
93 1.1 fredette * Recover the ps_strings pointer, and take out the
94 1.1 fredette * ps_argvstr member.
95 1.1 fredette */
96 1.1 fredette ldw HPPA_FRAME_ARG(0)(%r3), %arg0 ; ps_strings
97 1.1 fredette ldw 0(%arg0), %arg0 ; ps_argvstr member first in struct
98 1.1 fredette
99 1.1 fredette /*
100 1.1 fredette * ps_argvstr - 4 would get us a pointer to argc,
101 1.1 fredette * comparable to the initial stack pointer on
102 1.1 fredette * architectures where the stack grows down.
103 1.1 fredette * Subtracting an additional eight creates the
104 1.1 fredette * storage for obj and cleanup that _rtld needs.
105 1.1 fredette */
106 1.1 fredette ldo -12(%arg0), %arg0
107 1.3 skrll stw %arg0, HPPA_FRAME_ARG(1)(%r3)
108 1.1 fredette
109 1.3 skrll /* Call _rtld, copying relocbase into arg1. */
110 1.1 fredette bl _rtld, %rp
111 1.3 skrll copy %r4, %arg1 ; %arg1 = relocbase
112 1.1 fredette
113 1.1 fredette /* Prepare the arguments for the entry point. */
114 1.1 fredette ldw HPPA_FRAME_ARG(1)(%r3), %r1
115 1.1 fredette ldw HPPA_FRAME_ARG(0)(%r3), %arg0 ; ps_strings
116 1.1 fredette ldw 0(%r1), %arg1 ; cleanup
117 1.1 fredette ldw 4(%r1), %arg2 ; obj
118 1.1 fredette
119 1.1 fredette /* End stack calling convention. */
120 1.1 fredette ldo HPPA_FRAME_SIZE(%r3), %sp
121 1.1 fredette ldw,mb -HPPA_FRAME_SIZE(%sp), %r3
122 1.1 fredette
123 1.1 fredette /* Go for it. */
124 1.1 fredette bv %r0(%ret0)
125 1.1 fredette copy %r0, %rp
126 1.1 fredette EXIT($rtld_start)
127 1.1 fredette
128 1.1 fredette /*
129 1.1 fredette * This does our setup for an object's GOT. %arg0 is the
130 1.1 fredette * Obj_Entry * for the object, and %arg1 is its GOT pointer.
131 1.1 fredette */
132 1.1 fredette LEAF_ENTRY(__rtld_setup_hppa_pltgot)
133 1.1 fredette
134 1.1 fredette /*
135 1.1 fredette * The second entry of the GOT is reserved for
136 1.1 fredette * the dynamic linker. We put the Obj_Entry *
137 1.1 fredette * for the object in there.
138 1.1 fredette */
139 1.1 fredette stw %arg0, 4(%arg1)
140 1.1 fredette
141 1.1 fredette /*
142 1.1 fredette * Fill the fixup_func and fixup_ltp members of
143 1.1 fredette * the PLT stub. This stub is inserted by the
144 1.1 fredette * linker immediately before the GOT. We use
145 1.1 fredette * this stub to enter our binder.
146 1.1 fredette */
147 1.3 skrll
148 1.3 skrll bl L$lpc2, %arg0
149 1.3 skrll depi 0, 31, 2, %arg0
150 1.3 skrll L$lpc2: addil L'_rtld_bind_start - ($PIC_pcrel$0 - 8), %arg0
151 1.3 skrll ldo R'_rtld_bind_start - ($PIC_pcrel$0 - 12)(%r1),%arg0
152 1.3 skrll
153 1.1 fredette stw %arg0, -8(%arg1)
154 1.1 fredette bv %r0(%rp)
155 1.1 fredette stw %r19, -4(%arg1)
156 1.1 fredette EXIT(__rtld_hppa_setup_pltgot)
157 1.1 fredette
158 1.1 fredette /*
159 1.1 fredette * In order to support lazy binding, this implementation of
160 1.1 fredette * _rtld_bind_start is very closely tied to the shared-library
161 1.1 fredette * call stub and the PLT stub, both inserted by the linker.
162 1.1 fredette */
163 1.4 skrll ENTRY(_rtld_bind_start,HPPA_FRAME_SIZE)
164 1.1 fredette
165 1.1 fredette /* Start stack calling convention. */
166 1.1 fredette copy %r3, %r1
167 1.1 fredette copy %sp, %r3
168 1.3 skrll
169 1.3 skrll stw,ma %r1, HPPA_FRAME_SIZE(%sp)
170 1.1 fredette
171 1.1 fredette /*
172 1.1 fredette * We have to save all calling convention registers
173 1.1 fredette * that are set by the caller, because we have to
174 1.1 fredette * restore them before transferring to the bound
175 1.1 fredette * function. Note that this includes %ret0 and %ret1,
176 1.1 fredette * because they can have meaning on entry to a function.
177 1.1 fredette */
178 1.1 fredette stw %rp, HPPA_FRAME_CRP(%r3)
179 1.1 fredette stw %arg0, HPPA_FRAME_ARG(0)(%r3)
180 1.1 fredette stw %arg1, HPPA_FRAME_ARG(1)(%r3)
181 1.1 fredette stw %arg2, HPPA_FRAME_ARG(2)(%r3)
182 1.1 fredette stw %arg3, HPPA_FRAME_ARG(3)(%r3)
183 1.1 fredette /* 0(%r3) is filled with the saved %r3 above */
184 1.1 fredette stw %ret0, 4(%r3)
185 1.1 fredette stw %ret1, 8(%r3)
186 1.1 fredette
187 1.1 fredette /*
188 1.1 fredette * The linker PLT stub loads %r20 with (GOT - 8) for
189 1.1 fredette * the object that needs binding done. The second entry
190 1.1 fredette * of the GOT is reserved for the dynamic linker's use,
191 1.1 fredette * and we previously stashed the object's Obj_Entry *
192 1.1 fredette * there.
193 1.1 fredette */
194 1.1 fredette ldw 12(%r20), %arg0
195 1.1 fredette
196 1.1 fredette /*
197 1.1 fredette * The linker shared-library call stub loads %r19 from
198 1.1 fredette * the shared linkage member of the PLT entry. We
199 1.1 fredette * previously stashed the reloff of the relocation there.
200 1.1 fredette */
201 1.1 fredette copy %r19, %arg1
202 1.1 fredette
203 1.1 fredette /*
204 1.1 fredette * The linker PLT stub loads %r21 with the fixup_ltp
205 1.1 fredette * word in itself. We previously stashed our %r19
206 1.1 fredette * value there.
207 1.1 fredette */
208 1.1 fredette bl _rtld_bind, %rp
209 1.1 fredette copy %r21, %r19
210 1.1 fredette
211 1.1 fredette /*
212 1.3 skrll * Our hppa version of _rtld_bind
213 1.1 fredette * returns to us the address of the PLT entry that
214 1.1 fredette * it fixed up. Load the function address and
215 1.1 fredette * shared linkage for the newly bound function.
216 1.1 fredette */
217 1.1 fredette ldw 0(%ret0), %r21
218 1.1 fredette ldw 4(%ret0), %r19
219 1.1 fredette
220 1.1 fredette /* Restore registers saved above. */
221 1.1 fredette ldw HPPA_FRAME_CRP(%r3), %rp
222 1.1 fredette ldw HPPA_FRAME_ARG(0)(%r3), %arg0
223 1.1 fredette ldw HPPA_FRAME_ARG(1)(%r3), %arg1
224 1.1 fredette ldw HPPA_FRAME_ARG(2)(%r3), %arg2
225 1.1 fredette ldw HPPA_FRAME_ARG(3)(%r3), %arg3
226 1.1 fredette ldw 4(%r3), %ret0
227 1.1 fredette ldw 8(%r3), %ret1
228 1.1 fredette
229 1.1 fredette /* End stack calling convention. */
230 1.1 fredette ldo HPPA_FRAME_SIZE(%r3), %sp
231 1.1 fredette ldw,mb -HPPA_FRAME_SIZE(%sp), %r3
232 1.1 fredette
233 1.1 fredette /* Transfer to the function. */
234 1.1 fredette bv %r0(%r21)
235 1.1 fredette nop
236 1.1 fredette EXIT(_rtld_bind_start)
237