1/* $NetBSD: crtbegin.S,v 1.1 2011/02/08 02:02:25 matt Exp $ */ 2/*- 3 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Matt Thomas of 3am Software Foundry. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <powerpc/asm.h> 32 33RCSID("$NetBSD: crtbegin.S,v 1.1 2011/02/08 02:02:25 matt 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 ".got2","aw", @progbits 54.LCTOC = . + 32768 55 56 .section .data.rel, "aw", @progbits 57 .p2align 2 58 .type __dso_handle, @object 59 .size __dso_handle, 4 60 .globl __dso_handle 61 .hidden __dso_handle 62__dso_handle: 63#ifdef SHARED 64 .long __dso_handle 65#else 66 .long 0 67#endif 68 69 .lcomm __dwarf_eh_object,8*SZREG,SZREG 70 .lcomm __initialized,1,1 71 .lcomm __finished,1,1 72 73 .text 74 .weak __cxa_finalize 75 .weak __deregister_frame_info 76 .weak __register_frame_info 77 .weak _Jv_RegisterClasses 78 79/* 80 * All variables are local to this DSO so we can skip using GOT references 81 * and instead use PCREL references to access them. We do this regardless 82 * of being PIC since it isn't any additional overhead to do so. 83 * 84 * We don't setup a TOC since all of ours calls are indirect so it isn't 85 * needed. 86 */ 87 88__do_global_dtors_aux: 89 mflr %r7 /* save return address */ 90 bcl 20,31,1f /* find out what address */ 911: mflr %r3 /* we are at */ 92 mtlr %r7 /* restore return address */ 93 94 addis %r4,%r3,__finished-1b@ha /* PCREL ref (upper) */ 95 lbzu %r0,__finished-1b@l(%r4) /* PCREL ref (lower) & load */ 96 cmpwi %r0,0 /* done this already? */ 97 bnelr /* yep, return */ 98 99 li %r0, 1 100 stb %r0, 0(%r4) /* remember we've done this */ 101 102 stw %r7,(1*SZREG)(%r1) /* save LR */ 103 stwu %r1,-(8*SZREG)(%r1) /* alloc our stack frame */ 104 stw %r31,(7*SZREG)(%r1) /* save some registers */ 105 stw %r30,(6*SZREG)(%r1) 106 stw %r29,(5*SZREG)(%r1) 107 stw %r28,(4*SZREG)(%r1) 108 109 mr %r29,%r3 /* move this to a safe place */ 110 111 /* 112 * Get a reference to our TOC. 113 */ 114 addis %r30,%r29,.LCTOC-1b@ha 115 addi %r30,%r30,.LCTOC-1b@l 116 117 /* 118 * Get a reference to the GOT. 119 */ 120 addis %r31,%r29,_GLOBAL_OFFSET_TABLE_-1b@ha /* pcrel (hi) */ 121 addi %r31,%r31,_GLOBAL_OFFSET_TABLE_-1b@l /* pcrel (lo) */ 122 123#ifdef SHARED 124 /* 125 * if (__cxa_finalize) 126 * __cxa_finalize(&__dso_handle); 127 */ 128 lwz %r0, __cxa_finalize@got(%r31) 129 cmpwi %r0, 0 130 beq 2f 131 132 addis %r3,%r29,__dso_handle-1b@ha /* get &__dso_handle (pcrel) */ 133 addi %r3,%r3,__dso_handle-1b@l 134 mtctr %r0 /* setup for indirect branch */ 135 bctrl /* and call the routine */ 1362: 137#endif 138 139 addis %r28,%r29,__DTOR_LIST__-1b@ha /* get &__DTOR_LIST__ */ 140 addi %r28,%r28,__DTOR_LIST__-1b@l 141 /* 142 * We know the first entry is -1 so skip it. We use load with update 143 * to advance the pointer along. 144 */ 1453: 146 lwzu %r0, 4(%r28) /* get entry */ 147 cmpwi %r0, 0 /* end of list? */ 148 beq 4f /* yep. */ 149 mtctr %r0 /* setup for indirect branch */ 150 bctrl /* and call the routine */ 151 b 3b /* do it again */ 152 1534: 154 /* 155 * if (__deregister_frame_info) 156 * __deregister_frame_info(&__EH_FRAME_LIST__[0]); 157 */ 158 lwz %r0,__deregister_frame_info@got(%r31) 159 cmpwi %r0, 0 /* routine actually exist? */ 160 beq 5f /* nope, skip call */ 161 162 addis %r3,%r29,__EH_FRAME_LIST__-1b@ha 163 addi %r3,%r3,__EH_FRAME_LIST__-1b@l 164 mtctr %r0 /* setup for indirect branch */ 165 bctrl /* and call the routine */ 1665: 167 lwz %r28,(4*SZREG)(%r1) /* restore registers */ 168 lwz %r29,(5*SZREG)(%r1) 169 lwz %r30,(6*SZREG)(%r1) 170 lwz %r31,(7*SZREG)(%r1) 171 addi %r1,%r1,8*SZREG /* adjust stack */ 172 lwz %r0,(1*SZREG)(%r1) /* get return addr */ 173 mtlr %r0 174 blr /* and return */ 175 176__do_global_ctors_aux: 177 mflr %r7 /* save return address */ 178 bcl 20,31,1f /* find out what address */ 1791: mflr %r3 /* we are at */ 180 mtlr %r7 /* restore return address */ 181 182 addis %r4,%r3,__initialized-1b@ha /* pcrel (hi) */ 183 lbzu %r0,__initialized-1b@l(%r4) /* pcrel (lo) load+update */ 184 cmpwi %r0,0 /* have we already done this? */ 185 bnelr /* yep, return */ 186 187 li %r0,1 188 stb %r0,0(%r4) /* remember we've been here */ 189 190 stw %r7,(1*SZREG)(%r1) /* save LR */ 191 stwu %r1,-(8*SZREG)(%r1) /* alloc our stack frame */ 192 stw %r31,(7*SZREG)(%r1) /* save some registers */ 193 stw %r30,(6*SZREG)(%r1) 194 stw %r29,(5*SZREG)(%r1) 195 stw %r28,(4*SZREG)(%r1) 196 197 mr %r29,%r3 /* move this to a safe place */ 198 199 /* 200 * Get a reference to our TOC. 201 */ 202 addis %r30,%r29,.LCTOC-1b@ha 203 addi %r30,%r30,.LCTOC-1b@l 204 205 /* 206 * Get a reference to the GOT. 207 */ 208 addis %r31,%r29,_GLOBAL_OFFSET_TABLE_-1b@ha /* pcrel (hi) */ 209 addi %r31,%r31,_GLOBAL_OFFSET_TABLE_-1b@l /* pcrel (lo) */ 210 211 /* 212 * if (__register_frame_info) 213 * __register_frame_info(&__EH_FRAME_LIST__[0], &__dwarf_eh_object) 214 */ 215 lwz %r0, __register_frame_info@got(%r31) 216 cmpwi %r0, 0 217 beq 2f 218 219 addis %r3,%r29,__EH_FRAME_LIST__-1b@ha /* pcrel (hi) */ 220 addi %r3,%r3,__EH_FRAME_LIST__-1b@l /* pcrel (lo) */ 221 addis %r4,%r29,__dwarf_eh_object-1b@ha /* pcrel (hi) */ 222 addi %r4,%r4,__dwarf_eh_object-1b@l /* pcrel (lo) */ 223 mtctr %r0 /* setup for indirect branch */ 224 bctrl /* and call the routine */ 225 2262: 227 /* 228 * if (_Jv_RegisterClasses && __JCR_LIST__[0]) 229 * _Jv_RegisterClasses(&__JCR_LIST__[0]); 230 */ 231 lwz %r0, _Jv_RegisterClasses@got(%r31) 232 cmpwi %r0, 0 233 beq 3f 234 235 mtctr %r0 /* setup for indirect branch */ 236 addis %r3, %r29, __JCR_LIST__-1b@ha /* pcrel (hi) */ 237 addi %r3, %r3, __JCR_LIST__-1b@l /* pcrel (lo) */ 238 lwz %r4, 0(%r3) /* load first entry */ 239 cmpwi %r4, 0 /* is the list empty? */ 240 bnectrl /* call the routine if not */ 2413: 242 243 /* 244 * Get end of list of CTOR list. 245 */ 246 addis %r28,%r29,__CTOR_LIST_END__-1b@ha 247 addi %r28,%r28,__CTOR_LIST_END__-1b@l 2484: 249 lwzu %r0, -4(%r28) /* get entry */ 250 cmpwi %r0, -1 /* first entry? */ 251 beq 5f /* yes, we're done */ 252 mtctr %r0 /* setup for indirect branch */ 253 bctrl /* call the routine */ 254 b 4b /* do it again */ 2555: 256 lwz %r28,(4*SZREG)(%r1) /* restore registers */ 257 lwz %r29,(5*SZREG)(%r1) 258 lwz %r30,(6*SZREG)(%r1) 259 lwz %r31,(7*SZREG)(%r1) 260 addi %r1,%r1,8*SZREG /* adjust stack */ 261 lwz %r0,(1*SZREG)(%r1) /* get return addr */ 262 mtlr %r0 263 blr /* and return */ 264 265 .section .init, "ax", @progbits 266 bl __do_global_ctors_aux 267 .section .fini, "ax", @progbits 268 bl __do_global_dtors_aux 269