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