1/* 2 * Special support for eabi and SVR4 3 * 4 * Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc. 5 * Written By Michael Meissner 6 * 7 * This file is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2, or (at your option) any 10 * later version. 11 * 12 * In addition to the permissions in the GNU General Public License, the 13 * Free Software Foundation gives you unlimited permission to link the 14 * compiled version of this file with other programs, and to distribute 15 * those programs without any restriction coming from the use of this 16 * file. (The General Public License restrictions do apply in other 17 * respects; for example, they cover modification of the file, and 18 * distribution when not linked into another program.) 19 * 20 * This file is distributed in the hope that it will be useful, but 21 * WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 * General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; see the file COPYING. If not, write to 27 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 28 * Boston, MA 02110-1301, USA. 29 * 30 * As a special exception, if you link this library with files 31 * compiled with GCC to produce an executable, this does not cause 32 * the resulting executable to be covered by the GNU General Public License. 33 * This exception does not however invalidate any other reasons why 34 * the executable file might be covered by the GNU General Public License. 35 */ 36 37/* Do any initializations needed for the eabi environment */ 38 39 .file "eabi.asm" 40 .section ".text" 41 #include "ppc-asm.h" 42 43#ifndef __powerpc64__ 44 45 .section ".got2","aw" 46 .align 2 47.LCTOC1 = . /* +32768 */ 48 49/* Table of addresses */ 50.Ltable = .-.LCTOC1 51 .long .LCTOC1 /* address we are really at */ 52 53.Lsda = .-.LCTOC1 54 .long _SDA_BASE_ /* address of the first small data area */ 55 56.Lsdas = .-.LCTOC1 57 .long __SDATA_START__ /* start of .sdata/.sbss section */ 58 59.Lsdae = .-.LCTOC1 60 .long __SBSS_END__ /* end of .sdata/.sbss section */ 61 62.Lsda2 = .-.LCTOC1 63 .long _SDA2_BASE_ /* address of the second small data area */ 64 65.Lsda2s = .-.LCTOC1 66 .long __SDATA2_START__ /* start of .sdata2/.sbss2 section */ 67 68.Lsda2e = .-.LCTOC1 69 .long __SBSS2_END__ /* end of .sdata2/.sbss2 section */ 70 71#ifdef _RELOCATABLE 72.Lgots = .-.LCTOC1 73 .long __GOT_START__ /* Global offset table start */ 74 75.Lgotm1 = .-.LCTOC1 76 .long _GLOBAL_OFFSET_TABLE_-4 /* end of GOT ptrs before BLCL + 3 reserved words */ 77 78.Lgotm2 = .-.LCTOC1 79 .long _GLOBAL_OFFSET_TABLE_+12 /* start of GOT ptrs after BLCL + 3 reserved words */ 80 81.Lgote = .-.LCTOC1 82 .long __GOT_END__ /* Global offset table end */ 83 84.Lgot2s = .-.LCTOC1 85 .long __GOT2_START__ /* -mrelocatable GOT pointers start */ 86 87.Lgot2e = .-.LCTOC1 88 .long __GOT2_END__ /* -mrelocatable GOT pointers end */ 89 90.Lfixups = .-.LCTOC1 91 .long __FIXUP_START__ /* start of .fixup section */ 92 93.Lfixupe = .-.LCTOC1 94 .long __FIXUP_END__ /* end of .fixup section */ 95 96.Lctors = .-.LCTOC1 97 .long __CTOR_LIST__ /* start of .ctor section */ 98 99.Lctore = .-.LCTOC1 100 .long __CTOR_END__ /* end of .ctor section */ 101 102.Ldtors = .-.LCTOC1 103 .long __DTOR_LIST__ /* start of .dtor section */ 104 105.Ldtore = .-.LCTOC1 106 .long __DTOR_END__ /* end of .dtor section */ 107 108.Lexcepts = .-.LCTOC1 109 .long __EXCEPT_START__ /* start of .gcc_except_table section */ 110 111.Lexcepte = .-.LCTOC1 112 .long __EXCEPT_END__ /* end of .gcc_except_table section */ 113 114.Linit = .-.LCTOC1 115 .long .Linit_p /* address of variable to say we've been called */ 116 117 .text 118 .align 2 119.Lptr: 120 .long .LCTOC1-.Laddr /* PC relative pointer to .got2 */ 121#endif 122 123 .data 124 .align 2 125.Linit_p: 126 .long 0 127 128 .text 129 130FUNC_START(__eabi) 131 132/* Eliminate -mrelocatable code if not -mrelocatable, so that this file can 133 be assembled with other assemblers than GAS. */ 134 135#ifndef _RELOCATABLE 136 addis 10,0,.Linit_p@ha /* init flag */ 137 addis 11,0,.LCTOC1@ha /* load address of .LCTOC1 */ 138 lwz 9,.Linit_p@l(10) /* init flag */ 139 addi 11,11,.LCTOC1@l 140 cmplwi 2,9,0 /* init flag != 0? */ 141 bnelr 2 /* return now, if we've been called already */ 142 stw 1,.Linit_p@l(10) /* store a nonzero value in the done flag */ 143 144#else /* -mrelocatable */ 145 mflr 0 146 bl .Laddr /* get current address */ 147.Laddr: 148 mflr 12 /* real address of .Laddr */ 149 lwz 11,(.Lptr-.Laddr)(12) /* linker generated address of .LCTOC1 */ 150 add 11,11,12 /* correct to real pointer */ 151 lwz 12,.Ltable(11) /* get linker's idea of where .Laddr is */ 152 lwz 10,.Linit(11) /* address of init flag */ 153 subf. 12,12,11 /* calculate difference */ 154 lwzx 9,10,12 /* done flag */ 155 cmplwi 2,9,0 /* init flag != 0? */ 156 mtlr 0 /* restore in case branch was taken */ 157 bnelr 2 /* return now, if we've been called already */ 158 stwx 1,10,12 /* store a nonzero value in the done flag */ 159 beq+ 0,.Lsdata /* skip if we don't need to relocate */ 160 161/* We need to relocate the .got2 pointers. */ 162 163 lwz 3,.Lgot2s(11) /* GOT2 pointers start */ 164 lwz 4,.Lgot2e(11) /* GOT2 pointers end */ 165 add 3,12,3 /* adjust pointers */ 166 add 4,12,4 167 bl FUNC_NAME(__eabi_convert) /* convert pointers in .got2 section */ 168 169/* Fixup the .ctor section for static constructors */ 170 171 lwz 3,.Lctors(11) /* constructors pointers start */ 172 lwz 4,.Lctore(11) /* constructors pointers end */ 173 bl FUNC_NAME(__eabi_convert) /* convert constructors */ 174 175/* Fixup the .dtor section for static destructors */ 176 177 lwz 3,.Ldtors(11) /* destructors pointers start */ 178 lwz 4,.Ldtore(11) /* destructors pointers end */ 179 bl FUNC_NAME(__eabi_convert) /* convert destructors */ 180 181/* Fixup the .gcc_except_table section for G++ exceptions */ 182 183 lwz 3,.Lexcepts(11) /* exception table pointers start */ 184 lwz 4,.Lexcepte(11) /* exception table pointers end */ 185 bl FUNC_NAME(__eabi_convert) /* convert exceptions */ 186 187/* Fixup the addresses in the GOT below _GLOBAL_OFFSET_TABLE_-4 */ 188 189 lwz 3,.Lgots(11) /* GOT table pointers start */ 190 lwz 4,.Lgotm1(11) /* GOT table pointers below _GLOBAL_OFFSET_TABLE-4 */ 191 bl FUNC_NAME(__eabi_convert) /* convert lower GOT */ 192 193/* Fixup the addresses in the GOT above _GLOBAL_OFFSET_TABLE_+12 */ 194 195 lwz 3,.Lgotm2(11) /* GOT table pointers above _GLOBAL_OFFSET_TABLE+12 */ 196 lwz 4,.Lgote(11) /* GOT table pointers end */ 197 bl FUNC_NAME(__eabi_convert) /* convert lower GOT */ 198 199/* Fixup any user initialized pointers now (the compiler drops pointers to */ 200/* each of the relocs that it does in the .fixup section). */ 201 202.Lfix: 203 lwz 3,.Lfixups(11) /* fixup pointers start */ 204 lwz 4,.Lfixupe(11) /* fixup pointers end */ 205 bl FUNC_NAME(__eabi_uconvert) /* convert user initialized pointers */ 206 207.Lsdata: 208 mtlr 0 /* restore link register */ 209#endif /* _RELOCATABLE */ 210 211/* Only load up register 13 if there is a .sdata and/or .sbss section */ 212 lwz 3,.Lsdas(11) /* start of .sdata/.sbss section */ 213 lwz 4,.Lsdae(11) /* end of .sdata/.sbss section */ 214 cmpw 1,3,4 /* .sdata/.sbss section non-empty? */ 215 beq- 1,.Lsda2l /* skip loading r13 */ 216 217 lwz 13,.Lsda(11) /* load r13 with _SDA_BASE_ address */ 218 219/* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */ 220 221.Lsda2l: 222 lwz 3,.Lsda2s(11) /* start of .sdata/.sbss section */ 223 lwz 4,.Lsda2e(11) /* end of .sdata/.sbss section */ 224 cmpw 1,3,4 /* .sdata/.sbss section non-empty? */ 225 beq+ 1,.Ldone /* skip loading r2 */ 226 227 lwz 2,.Lsda2(11) /* load r2 with _SDA2_BASE_ address */ 228 229/* Done adjusting pointers, return by way of doing the C++ global constructors. */ 230 231.Ldone: 232 b FUNC_NAME(__init) /* do any C++ global constructors (which returns to caller) */ 233FUNC_END(__eabi) 234 235/* Special subroutine to convert a bunch of pointers directly. 236 r0 has original link register 237 r3 has low pointer to convert 238 r4 has high pointer to convert 239 r5 .. r10 are scratch registers 240 r11 has the address of .LCTOC1 in it. 241 r12 has the value to add to each pointer 242 r13 .. r31 are unchanged */ 243 244FUNC_START(__eabi_convert) 245 cmplw 1,3,4 /* any pointers to convert? */ 246 subf 5,3,4 /* calculate number of words to convert */ 247 bclr 4,4 /* return if no pointers */ 248 249 srawi 5,5,2 250 addi 3,3,-4 /* start-4 for use with lwzu */ 251 mtctr 5 252 253.Lcvt: 254 lwzu 6,4(3) /* pointer to convert */ 255 cmpwi 0,6,0 256 beq- .Lcvt2 /* if pointer is null, don't convert */ 257 258 add 6,6,12 /* convert pointer */ 259 stw 6,0(3) 260.Lcvt2: 261 bdnz+ .Lcvt 262 blr 263 264FUNC_END(__eabi_convert) 265 266/* Special subroutine to convert the pointers the user has initialized. The 267 compiler has placed the address of the initialized pointer into the .fixup 268 section. 269 270 r0 has original link register 271 r3 has low pointer to convert 272 r4 has high pointer to convert 273 r5 .. r10 are scratch registers 274 r11 has the address of .LCTOC1 in it. 275 r12 has the value to add to each pointer 276 r13 .. r31 are unchanged */ 277 278FUNC_START(__eabi_uconvert) 279 cmplw 1,3,4 /* any pointers to convert? */ 280 subf 5,3,4 /* calculate number of words to convert */ 281 bclr 4,4 /* return if no pointers */ 282 283 srawi 5,5,2 284 addi 3,3,-4 /* start-4 for use with lwzu */ 285 mtctr 5 286 287.Lucvt: 288 lwzu 6,4(3) /* next pointer to pointer to convert */ 289 add 6,6,12 /* adjust pointer */ 290 lwz 7,0(6) /* get the pointer it points to */ 291 stw 6,0(3) /* store adjusted pointer */ 292 add 7,7,12 /* adjust */ 293 stw 7,0(6) 294 bdnz+ .Lucvt 295 blr 296 297FUNC_END(__eabi_uconvert) 298 299#endif 300