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