1 1.3 joerg /* $NetBSD: crtbegin.S,v 1.3 2013/09/12 15:36:14 joerg Exp $ */ 2 1.1 uwe /*- 3 1.2 uwe * Copyright (c) 2012 Valeriy E. Ushakov 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.3 joerg RCSID("$NetBSD: crtbegin.S,v 1.3 2013/09/12 15:36:14 joerg 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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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.3 joerg #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