crtbegin.S revision 1.1 1 1.1 uwe /* $NetBSD: crtbegin.S,v 1.1 2012/01/31 20:30:15 uwe Exp $ */
2 1.1 uwe /*-
3 1.1 uwe * Copyright (c) 2010 Joerg Sonnenberger <joerg (at) NetBSD.org>
4 1.1 uwe * All rights reserved.
5 1.1 uwe *
6 1.1 uwe * Redistribution and use in source and binary forms, with or without
7 1.1 uwe * modification, are permitted provided that the following conditions
8 1.1 uwe * are met:
9 1.1 uwe *
10 1.1 uwe * 1. Redistributions of source code must retain the above copyright
11 1.1 uwe * notice, this list of conditions and the following disclaimer.
12 1.1 uwe * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 uwe * notice, this list of conditions and the following disclaimer in
14 1.1 uwe * the documentation and/or other materials provided with the
15 1.1 uwe * distribution.
16 1.1 uwe *
17 1.1 uwe * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 1.1 uwe * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 1.1 uwe * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 1.1 uwe * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 1.1 uwe * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 uwe * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 1.1 uwe * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 1.1 uwe * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 1.1 uwe * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 1.1 uwe * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 1.1 uwe * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 1.1 uwe * SUCH DAMAGE.
29 1.1 uwe */
30 1.1 uwe
31 1.1 uwe #include <machine/asm.h>
32 1.1 uwe
33 1.1 uwe RCSID("$NetBSD: crtbegin.S,v 1.1 2012/01/31 20:30:15 uwe Exp $")
34 1.1 uwe
35 1.1 uwe .section .ctors, "aw", @progbits
36 1.1 uwe .p2align 2
37 1.1 uwe __CTOR_LIST__:
38 1.1 uwe .long -1
39 1.1 uwe
40 1.1 uwe .section .dtors, "aw", @progbits
41 1.1 uwe .p2align 2
42 1.1 uwe __DTOR_LIST__:
43 1.1 uwe .long -1
44 1.1 uwe
45 1.1 uwe .section .eh_frame, "a", @progbits
46 1.1 uwe .p2align 2
47 1.1 uwe __EH_FRAME_LIST__:
48 1.1 uwe
49 1.1 uwe .section .jcr, "aw", @progbits
50 1.1 uwe .p2align 2
51 1.1 uwe __JCR_LIST__:
52 1.1 uwe
53 1.1 uwe .section .data.rel, "aw", @progbits
54 1.1 uwe .p2align 2
55 1.1 uwe .globl __dso_handle
56 1.1 uwe .hidden __dso_handle
57 1.1 uwe .type __dso_handle, @object
58 1.1 uwe .size __dso_handle, 4
59 1.1 uwe __dso_handle:
60 1.1 uwe #ifdef SHARED
61 1.1 uwe .long __dso_handle
62 1.1 uwe #else
63 1.1 uwe .long 0
64 1.1 uwe #endif
65 1.1 uwe
66 1.1 uwe __dwarf_eh_object:
67 1.1 uwe .zero 32
68 1.1 uwe
69 1.1 uwe __initialized:
70 1.1 uwe .zero 1
71 1.1 uwe __finished:
72 1.1 uwe .zero 1
73 1.1 uwe
74 1.1 uwe .text
75 1.1 uwe .weak __cxa_finalize
76 1.1 uwe .weak __deregister_frame_info
77 1.1 uwe .weak __register_frame_info
78 1.1 uwe .weak _Jv_RegisterClasses
79 1.1 uwe
80 1.1 uwe /*
81 1.1 uwe * A bit of CPP syntactic sugar for accessing variables.
82 1.1 uwe *
83 1.1 uwe * For PIC we are obliged to use @(r0, r12) since r12 has the GOT
84 1.1 uwe * address and only r0 can be used in @(r0, Rm) addressing mode, so we
85 1.1 uwe * always load variable address to r0.
86 1.1 uwe */
87 1.1 uwe #ifdef PIC
88 1.1 uwe #define VAR_DATUM(var) var@GOTOFF
89 1.1 uwe #define FUNC_DATUM(f) f@GOT
90 1.1 uwe #define R0VAR (r0, r12)
91 1.1 uwe #else
92 1.1 uwe #define VAR_DATUM(var) var
93 1.1 uwe #define FUNC_DATUM(f) f
94 1.1 uwe #define R0VAR r0
95 1.1 uwe #endif
96 1.1 uwe
97 1.1 uwe
98 1.1 uwe __do_global_ctors_aux:
99 1.1 uwe mov.l r8, @-sp
100 1.1 uwe mov.l r9, @-sp
101 1.1 uwe #ifdef PIC
102 1.1 uwe mov.l r12, @-sp
103 1.1 uwe mov.l .Lc_got, r12
104 1.1 uwe mova .Lc_got, r0
105 1.1 uwe add r0, r12
106 1.1 uwe #endif
107 1.1 uwe mov.l r14, @-sp
108 1.1 uwe sts.l pr, @-sp
109 1.1 uwe mov sp, r14
110 1.1 uwe
111 1.1 uwe !! if (__initialized) return;
112 1.1 uwe mov.l .Lc___initialized, r0
113 1.1 uwe mov.b @R0VAR, r1
114 1.1 uwe tst r1, r1
115 1.1 uwe bf .Lc_return
116 1.1 uwe
117 1.1 uwe !! __initialized = 1;
118 1.1 uwe mov #1, r1
119 1.1 uwe mov.b r1, @R0VAR
120 1.1 uwe
121 1.1 uwe
122 1.1 uwe !! if (__register_frame_info)
123 1.1 uwe !! __register_frame_info(&__EH_FRAME_LIST__[0], &__dwarf_eh_object)
124 1.1 uwe #ifdef PIC
125 1.1 uwe mov.l .Lc___register_frame_info_GOT, r0
126 1.1 uwe mov.l @R0VAR, r1
127 1.1 uwe tst r1, r1
128 1.1 uwe bt .Lc___register_frame_info_done
129 1.1 uwe mov.l .Lc___register_frame_info, r0
130 1.1 uwe mov.l .Lc___EH_FRAME_LIST__, r4
131 1.1 uwe mov.l .Lc___dwarf_eh_object, r5
132 1.1 uwe add r12, r4
133 1.1 uwe .Lc___register_frame_info_call:
134 1.1 uwe CALL r0
135 1.1 uwe add r12, r5
136 1.1 uwe #else /* !PIC */
137 1.1 uwe mov.l .Lc___register_frame_info, r0
138 1.1 uwe tst r0, r0
139 1.1 uwe bt .Lc___register_frame_info_done
140 1.1 uwe mov.l .Lc___EH_FRAME_LIST__, r4
141 1.1 uwe mov.l .Lc___dwarf_eh_object, r5
142 1.1 uwe CALL r0
143 1.1 uwe nop
144 1.1 uwe #endif
145 1.1 uwe .Lc___register_frame_info_done:
146 1.1 uwe
147 1.1 uwe !! if (_Jv_RegisterClasses && __JCR_LIST__[0])
148 1.1 uwe !! _Jv_RegisterClasses(&__JCR_LIST__[0]);
149 1.1 uwe #ifdef PIC
150 1.1 uwe mov.l .Lc__Jv_RegisterClasses_GOT, r0
151 1.1 uwe mov.l @R0VAR, r1
152 1.1 uwe tst r1, r1
153 1.1 uwe bt .Lc__Jv_RegisterClasses_done
154 1.1 uwe
155 1.1 uwe mov.l .Lc___JCR_LIST__, r0
156 1.1 uwe mov.l @R0VAR, r1
157 1.1 uwe tst r1, r1
158 1.1 uwe bt .Lc__Jv_RegisterClasses_done
159 1.1 uwe
160 1.1 uwe mov.l .Lc__Jv_RegisterClasses, r2
161 1.1 uwe mov r0, r4
162 1.1 uwe .Lc__Jv_RegisterClasses_call:
163 1.1 uwe CALL r2
164 1.1 uwe add r12, r4
165 1.1 uwe
166 1.1 uwe #else /* !PIC */
167 1.1 uwe mov.l .Lc__Jv_RegisterClasses, r2
168 1.1 uwe tst r2, r2
169 1.1 uwe bt .Lc__Jv_RegisterClasses_done
170 1.1 uwe
171 1.1 uwe mov.l .Lc___JCR_LIST__, r0
172 1.1 uwe mov.l @R0VAR, r1
173 1.1 uwe tst r1, r1
174 1.1 uwe bt .Lc__Jv_RegisterClasses_done
175 1.1 uwe
176 1.1 uwe mov r0, r4
177 1.1 uwe .Lc__Jv_RegisterClasses_call:
178 1.1 uwe CALL r2
179 1.1 uwe add r12, r4
180 1.1 uwe #endif
181 1.1 uwe .Lc__Jv_RegisterClasses_done:
182 1.1 uwe
183 1.1 uwe
184 1.1 uwe !! call all constructors on __CTOR_LIST__ in reverse order
185 1.1 uwe mov.l .Lc___CTOR_LIST_END__, r8
186 1.1 uwe #ifdef PIC
187 1.1 uwe add r12, r8
188 1.1 uwe #endif
189 1.1 uwe add #-4, r8
190 1.1 uwe mov.l @r8, r9
191 1.1 uwe not r9, r0 ! sentinel at __CTOR_LIST__[0] is -1
192 1.1 uwe .Lc_ctor_list_loop:
193 1.1 uwe tst r0, r0
194 1.1 uwe bt.s .Lc_ctor_list_done
195 1.1 uwe add #-4, r8
196 1.1 uwe jsr @r9
197 1.1 uwe mov.l @r8, r9
198 1.1 uwe bra .Lc_ctor_list_loop
199 1.1 uwe not r9, r0
200 1.1 uwe .Lc_ctor_list_done:
201 1.1 uwe
202 1.1 uwe .Lc_return:
203 1.1 uwe mov r14, sp
204 1.1 uwe lds.l @sp+, pr
205 1.1 uwe mov.l @sp+, r14
206 1.1 uwe #ifdef PIC
207 1.1 uwe mov.l @sp+, r12
208 1.1 uwe #endif
209 1.1 uwe mov.l @sp+, r9
210 1.1 uwe rts
211 1.1 uwe mov.l @sp+, r8
212 1.1 uwe
213 1.1 uwe .p2align 2
214 1.1 uwe .Lc_got:
215 1.1 uwe PIC_GOT_DATUM
216 1.1 uwe .Lc___initialized:
217 1.1 uwe .long VAR_DATUM(__initialized)
218 1.1 uwe #ifdef PIC
219 1.1 uwe .Lc___register_frame_info_GOT:
220 1.1 uwe .long __register_frame_info@GOT
221 1.1 uwe #endif
222 1.1 uwe .Lc___register_frame_info:
223 1.1 uwe CALL_DATUM(__register_frame_info, .Lc___register_frame_info_call)
224 1.1 uwe .Lc___EH_FRAME_LIST__:
225 1.1 uwe .long VAR_DATUM(__EH_FRAME_LIST__)
226 1.1 uwe .Lc___dwarf_eh_object:
227 1.1 uwe .long VAR_DATUM(__dwarf_eh_object)
228 1.1 uwe #ifdef PIC
229 1.1 uwe .Lc__Jv_RegisterClasses_GOT:
230 1.1 uwe .long _Jv_RegisterClasses@GOT
231 1.1 uwe #endif
232 1.1 uwe .Lc__Jv_RegisterClasses:
233 1.1 uwe CALL_DATUM(_Jv_RegisterClasses, .Lc__Jv_RegisterClasses_call)
234 1.1 uwe .Lc___JCR_LIST__:
235 1.1 uwe .long VAR_DATUM(__JCR_LIST__)
236 1.1 uwe .Lc___CTOR_LIST_END__:
237 1.1 uwe .long VAR_DATUM(__CTOR_LIST_END__)
238 1.1 uwe
239 1.1 uwe
240 1.1 uwe __do_global_dtors_aux:
241 1.1 uwe mov.l r8, @-sp
242 1.1 uwe mov.l r9, @-sp
243 1.1 uwe #ifdef PIC
244 1.1 uwe mov.l r12, @-sp
245 1.1 uwe mov.l .Ld_got, r12
246 1.1 uwe mova .Ld_got, r0
247 1.1 uwe add r0, r12
248 1.1 uwe #endif
249 1.1 uwe mov.l r14, @-sp
250 1.1 uwe sts.l pr, @-sp
251 1.1 uwe mov sp, r14
252 1.1 uwe
253 1.1 uwe !! if (__finished) return;
254 1.1 uwe mov.l .Ld___finished, r0
255 1.1 uwe mov.b @R0VAR, r1
256 1.1 uwe tst r1, r1
257 1.1 uwe bf .Ld_return
258 1.1 uwe
259 1.1 uwe !! __finished = 1;
260 1.1 uwe mov #1, r1
261 1.1 uwe mov.b r1, @R0VAR
262 1.1 uwe
263 1.1 uwe #ifdef SHARED /* implies PIC */
264 1.1 uwe !! if (__cxa_finalize)
265 1.1 uwe !! __cxa_finalize(&__dso_handle);
266 1.1 uwe mov.l .Ld___cxa_finalize_GOT, r0
267 1.1 uwe mov.l @R0VAR, r1
268 1.1 uwe tst r1, r1
269 1.1 uwe bt .Ld___cxa_finalize_done
270 1.1 uwe mov.l .Ld___cxa_finalize, r0
271 1.1 uwe mov.l .Ld___dso_handle, r4
272 1.1 uwe .Ld___cxa_finalize_call:
273 1.1 uwe CALL r0
274 1.1 uwe add r12, r4
275 1.1 uwe .Ld___cxa_finalize_done:
276 1.1 uwe #endif /* SHARED */
277 1.1 uwe
278 1.1 uwe !! call all destructors on __DTOR_LIST__
279 1.1 uwe mov.l .Ld___DTOR_LIST__, r8
280 1.1 uwe #ifdef PIC
281 1.1 uwe add r12, r8
282 1.1 uwe #endif
283 1.1 uwe add #4, r8 ! skip first entry that we know to be -1
284 1.1 uwe mov.l @r8+, r9
285 1.1 uwe tst r9, r9
286 1.1 uwe .Ld_dtor_list_loop:
287 1.1 uwe bt .Ld_dtor_list_done
288 1.1 uwe jsr @r9
289 1.1 uwe mov.l @r8+, r9
290 1.1 uwe bra .Ld_dtor_list_loop
291 1.1 uwe tst r9, r9
292 1.1 uwe .Ld_dtor_list_done:
293 1.1 uwe
294 1.1 uwe !! if (__deregister_frame_info)
295 1.1 uwe !! __deregister_frame_info(&__EH_FRAME_LIST__[0]);
296 1.1 uwe #ifdef PIC
297 1.1 uwe mov.l .Ld___deregister_frame_info_GOT, r0
298 1.1 uwe mov.l @R0VAR, r1
299 1.1 uwe tst r1, r1
300 1.1 uwe bt .Ld___deregister_frame_info_done
301 1.1 uwe mov.l .Ld___deregister_frame_info, r0
302 1.1 uwe mov.l .Ld___EH_FRAME_LIST__, r4
303 1.1 uwe .Ld___deregister_frame_info_call:
304 1.1 uwe CALL r0
305 1.1 uwe add r12, r4
306 1.1 uwe #else /* !PIC */
307 1.1 uwe mov.l .Ld___deregister_frame_info, r0
308 1.1 uwe tst r0, r0
309 1.1 uwe bt .Ld___deregister_frame_info_done
310 1.1 uwe mov.l .Ld___EH_FRAME_LIST__, r4
311 1.1 uwe CALL r0
312 1.1 uwe nop
313 1.1 uwe #endif
314 1.1 uwe .Ld___deregister_frame_info_done:
315 1.1 uwe
316 1.1 uwe .Ld_return:
317 1.1 uwe mov r14, sp
318 1.1 uwe lds.l @sp+, pr
319 1.1 uwe mov.l @sp+, r14
320 1.1 uwe #ifdef PIC
321 1.1 uwe mov.l @sp+, r12
322 1.1 uwe #endif
323 1.1 uwe mov.l @sp+, r9
324 1.1 uwe rts
325 1.1 uwe mov.l @sp+, r8
326 1.1 uwe
327 1.1 uwe .p2align 2
328 1.1 uwe .Ld_got:
329 1.1 uwe PIC_GOT_DATUM
330 1.1 uwe .Ld___finished:
331 1.1 uwe .long VAR_DATUM(__finished)
332 1.1 uwe #ifdef SHARED /* implies PIC */
333 1.1 uwe .Ld___cxa_finalize_GOT:
334 1.1 uwe .long __cxa_finalize@GOT
335 1.1 uwe .Ld___cxa_finalize:
336 1.1 uwe CALL_DATUM(__cxa_finalize, .Ld___cxa_finalize_call)
337 1.1 uwe .Ld___dso_handle:
338 1.1 uwe .long VAR_DATUM(__dso_handle)
339 1.1 uwe #endif
340 1.1 uwe .Ld___DTOR_LIST__:
341 1.1 uwe .long VAR_DATUM(__DTOR_LIST__)
342 1.1 uwe #ifdef PIC
343 1.1 uwe .Ld___deregister_frame_info_GOT:
344 1.1 uwe .long __deregister_frame_info@GOT
345 1.1 uwe #endif
346 1.1 uwe .Ld___deregister_frame_info:
347 1.1 uwe CALL_DATUM(__deregister_frame_info, .Ld___deregister_frame_info_call)
348 1.1 uwe .Ld___EH_FRAME_LIST__:
349 1.1 uwe .long VAR_DATUM(__EH_FRAME_LIST__)
350 1.1 uwe
351 1.1 uwe
352 1.1 uwe
353 1.1 uwe #define _CALL_INIT_FINI_FUNCTION(func) \
354 1.1 uwe mov.l 1f, r1; \
355 1.1 uwe mova 2f, r0; \
356 1.1 uwe 0: braf r1; /* NB: branch, not call ... */ \
357 1.1 uwe lds r0, pr; /* skip the following .long when returning */ \
358 1.1 uwe .p2align 2; \
359 1.1 uwe 1: .long func - (0b+4); \
360 1.1 uwe 2: ;
361 1.1 uwe
362 1.1 uwe .section .init, "ax", @progbits
363 1.1 uwe _CALL_INIT_FINI_FUNCTION(__do_global_ctors_aux)
364 1.1 uwe
365 1.1 uwe .section .fini, "ax", @progbits
366 1.1 uwe _CALL_INIT_FINI_FUNCTION(__do_global_dtors_aux)
367