eabi.asm revision 117395
1180740Sdes/* 2180740Sdes * Special support for eabi and SVR4 3226046Sdes * 4226046Sdes * Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc. 5226046Sdes * Written By Michael Meissner 6180740Sdes * 7180740Sdes * This file is free software; you can redistribute it and/or modify it 8180740Sdes * under the terms of the GNU General Public License as published by the 9180740Sdes * Free Software Foundation; either version 2, or (at your option) any 10180740Sdes * later version. 11180740Sdes * 12180740Sdes * In addition to the permissions in the GNU General Public License, the 13180746Sdes * Free Software Foundation gives you unlimited permission to link the 14180746Sdes * compiled version of this file with other programs, and to distribute 15180746Sdes * those programs without any restriction coming from the use of this 16180740Sdes * file. (The General Public License restrictions do apply in other 17180740Sdes * respects; for example, they cover modification of the file, and 18180740Sdes * distribution when not linked into another program.) 19240075Sdes * 20240075Sdes * This file is distributed in the hope that it will be useful, but 21240075Sdes * WITHOUT ANY WARRANTY; without even the implied warranty of 22180740Sdes * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23180740Sdes * General Public License for more details. 24180740Sdes * 25180740Sdes * You should have received a copy of the GNU General Public License 26180740Sdes * along with this program; see the file COPYING. If not, write to 27180740Sdes * the Free Software Foundation, 59 Temple Place - Suite 330, 28180740Sdes * Boston, MA 02111-1307, USA. 29180740Sdes * 30180740Sdes * As a special exception, if you link this library with files 31180746Sdes * compiled with GCC to produce an executable, this does not cause 32180746Sdes * the resulting executable to be covered by the GNU General Public License. 33180746Sdes * This exception does not however invalidate any other reasons why 34180740Sdes * the executable file might be covered by the GNU General Public License. 35180740Sdes */ 36180740Sdes 37180740Sdes/* Do any initializations needed for the eabi environment */ 38180740Sdes 39180740Sdes .file "eabi.asm" 40180740Sdes .section ".text" 41180740Sdes #include "ppc-asm.h" 42180740Sdes 43180740Sdes#ifndef __powerpc64__ 44180740Sdes 45180740Sdes .section ".got2","aw" 46180740Sdes .align 2 47180750Sdes.LCTOC1 = . /* +32768 */ 48180750Sdes 49180750Sdes/* Table of addresses */ 50262566Sdes.Ltable = .-.LCTOC1 51262566Sdes .long .LCTOC1 /* address we are really at */ 52262566Sdes 53262566Sdes.Lsda = .-.LCTOC1 54180740Sdes .long _SDA_BASE_ /* address of the first small data area */ 55180740Sdes 56180740Sdes.Lsdas = .-.LCTOC1 57180740Sdes .long __SDATA_START__ /* start of .sdata/.sbss section */ 58180740Sdes 59180740Sdes.Lsdae = .-.LCTOC1 60180740Sdes .long __SBSS_END__ /* end of .sdata/.sbss section */ 61180740Sdes 62180740Sdes.Lsda2 = .-.LCTOC1 63180740Sdes .long _SDA2_BASE_ /* address of the second small data area */ 64180740Sdes 65180740Sdes.Lsda2s = .-.LCTOC1 66180740Sdes .long __SDATA2_START__ /* start of .sdata2/.sbss2 section */ 67180740Sdes 68180740Sdes.Lsda2e = .-.LCTOC1 69180740Sdes .long __SBSS2_END__ /* end of .sdata2/.sbss2 section */ 70180740Sdes 71180740Sdes#ifdef _RELOCATABLE 72180740Sdes.Lgots = .-.LCTOC1 73180740Sdes .long __GOT_START__ /* Global offset table start */ 74180740Sdes 75180746Sdes.Lgotm1 = .-.LCTOC1 76180746Sdes .long _GLOBAL_OFFSET_TABLE_-4 /* end of GOT ptrs before BLCL + 3 reserved words */ 77180746Sdes 78180740Sdes.Lgotm2 = .-.LCTOC1 79180740Sdes .long _GLOBAL_OFFSET_TABLE_+12 /* start of GOT ptrs after BLCL + 3 reserved words */ 80180740Sdes 81262566Sdes.Lgote = .-.LCTOC1 82248619Sdes .long __GOT_END__ /* Global offset table end */ 83248619Sdes 84197679Sdes.Lgot2s = .-.LCTOC1 85197679Sdes .long __GOT2_START__ /* -mrelocatable GOT pointers start */ 86197679Sdes 87180740Sdes.Lgot2e = .-.LCTOC1 88180740Sdes .long __GOT2_END__ /* -mrelocatable GOT pointers end */ 89180740Sdes 90180740Sdes.Lfixups = .-.LCTOC1 91180740Sdes .long __FIXUP_START__ /* start of .fixup section */ 92180740Sdes 93180740Sdes.Lfixupe = .-.LCTOC1 94180740Sdes .long __FIXUP_END__ /* end of .fixup section */ 95180740Sdes 96180740Sdes.Lctors = .-.LCTOC1 97180740Sdes .long __CTOR_LIST__ /* start of .ctor section */ 98180740Sdes 99180740Sdes.Lctore = .-.LCTOC1 100180740Sdes .long __CTOR_END__ /* end of .ctor section */ 101180740Sdes 102180740Sdes.Ldtors = .-.LCTOC1 103180740Sdes .long __DTOR_LIST__ /* start of .dtor section */ 104180740Sdes 105180740Sdes.Ldtore = .-.LCTOC1 106180740Sdes .long __DTOR_END__ /* end of .dtor section */ 107180740Sdes 108180740Sdes.Lexcepts = .-.LCTOC1 109180740Sdes .long __EXCEPT_START__ /* start of .gcc_except_table section */ 110180740Sdes 111180740Sdes.Lexcepte = .-.LCTOC1 112180740Sdes .long __EXCEPT_END__ /* end of .gcc_except_table section */ 113180740Sdes 114180740Sdes.Linit = .-.LCTOC1 115180740Sdes .long .Linit_p /* address of variable to say we've been called */ 116180740Sdes 117180740Sdes .text 118180740Sdes .align 2 119180740Sdes.Lptr: 120180740Sdes .long .LCTOC1-.Laddr /* PC relative pointer to .got2 */ 121180740Sdes#endif 122180740Sdes 123180740Sdes .data 124180740Sdes .align 2 125180740Sdes.Linit_p: 126180740Sdes .long 0 127180740Sdes 128180740Sdes .text 129180740Sdes 130180740SdesFUNC_START(__eabi) 131180740Sdes 132180740Sdes/* Eliminate -mrelocatable code if not -mrelocatable, so that this file can 133180740Sdes be assembled with other assemblers than GAS. */ 134180740Sdes 135204917Sdes#ifndef _RELOCATABLE 136204917Sdes addis 10,0,.Linit_p@ha /* init flag */ 137204917Sdes addis 11,0,.LCTOC1@ha /* load address of .LCTOC1 */ 138221420Sdes lwz 9,.Linit_p@l(10) /* init flag */ 139221420Sdes addi 11,11,.LCTOC1@l 140221420Sdes cmplwi 2,9,0 /* init flag != 0? */ 141197679Sdes bnelr 2 /* return now, if we've been called already */ 142180750Sdes stw 1,.Linit_p@l(10) /* store a nonzero value in the done flag */ 143180750Sdes 144197679Sdes#else /* -mrelocatable */ 145197679Sdes mflr 0 146197679Sdes bl .Laddr /* get current address */ 147180740Sdes.Laddr: 148180740Sdes mflr 12 /* real address of .Laddr */ 149180740Sdes lwz 11,(.Lptr-.Laddr)(12) /* linker generated address of .LCTOC1 */ 150180740Sdes add 11,11,12 /* correct to real pointer */ 151180740Sdes lwz 12,.Ltable(11) /* get linker's idea of where .Laddr is */ 152180740Sdes lwz 10,.Linit(11) /* address of init flag */ 153180740Sdes subf. 12,12,11 /* calculate difference */ 154180740Sdes lwzx 9,10,12 /* done flag */ 155180740Sdes cmplwi 2,9,0 /* init flag != 0? */ 156180740Sdes mtlr 0 /* restore in case branch was taken */ 157180740Sdes bnelr 2 /* return now, if we've been called already */ 158180740Sdes stwx 1,10,12 /* store a nonzero value in the done flag */ 159221420Sdes beq+ 0,.Lsdata /* skip if we don't need to relocate */ 160221420Sdes 161221420Sdes/* We need to relocate the .got2 pointers. */ 162180740Sdes 163180740Sdes lwz 3,.Lgot2s(11) /* GOT2 pointers start */ 164180740Sdes lwz 4,.Lgot2e(11) /* GOT2 pointers end */ 165180740Sdes add 3,12,3 /* adjust pointers */ 166180740Sdes add 4,12,4 167180740Sdes bl FUNC_NAME(__eabi_convert) /* convert pointers in .got2 section */ 168180740Sdes 169180740Sdes/* Fixup the .ctor section for static constructors */ 170180740Sdes 171180740Sdes lwz 3,.Lctors(11) /* constructors pointers start */ 172180740Sdes lwz 4,.Lctore(11) /* constructors pointers end */ 173180740Sdes bl FUNC_NAME(__eabi_convert) /* convert constructors */ 174180740Sdes 175180740Sdes/* Fixup the .dtor section for static destructors */ 176180740Sdes 177180740Sdes lwz 3,.Ldtors(11) /* destructors pointers start */ 178180740Sdes lwz 4,.Ldtore(11) /* destructors pointers end */ 179180740Sdes bl FUNC_NAME(__eabi_convert) /* convert destructors */ 180180740Sdes 181180740Sdes/* Fixup the .gcc_except_table section for G++ exceptions */ 182180740Sdes 183180740Sdes lwz 3,.Lexcepts(11) /* exception table pointers start */ 184180740Sdes lwz 4,.Lexcepte(11) /* exception table pointers end */ 185180740Sdes bl FUNC_NAME(__eabi_convert) /* convert exceptions */ 186180750Sdes 187180750Sdes/* Fixup the addresses in the GOT below _GLOBAL_OFFSET_TABLE_-4 */ 188180750Sdes 189262566Sdes lwz 3,.Lgots(11) /* GOT table pointers start */ 190262566Sdes lwz 4,.Lgotm1(11) /* GOT table pointers below _GLOBAL_OFFSET_TABLE-4 */ 191262566Sdes bl FUNC_NAME(__eabi_convert) /* convert lower GOT */ 192180750Sdes 193180750Sdes/* Fixup the addresses in the GOT above _GLOBAL_OFFSET_TABLE_+12 */ 194180750Sdes 195180740Sdes lwz 3,.Lgotm2(11) /* GOT table pointers above _GLOBAL_OFFSET_TABLE+12 */ 196180740Sdes lwz 4,.Lgote(11) /* GOT table pointers end */ 197180740Sdes bl FUNC_NAME(__eabi_convert) /* convert lower GOT */ 198180740Sdes 199180740Sdes/* Fixup any user initialized pointers now (the compiler drops pointers to */ 200180740Sdes/* each of the relocs that it does in the .fixup section). */ 201180744Sdes 202180744Sdes.Lfix: 203180744Sdes lwz 3,.Lfixups(11) /* fixup pointers start */ 204180740Sdes lwz 4,.Lfixupe(11) /* fixup pointers end */ 205180740Sdes bl FUNC_NAME(__eabi_uconvert) /* convert user initialized pointers */ 206180740Sdes 207180746Sdes.Lsdata: 208180746Sdes mtlr 0 /* restore link register */ 209180746Sdes#endif /* _RELOCATABLE */ 210180740Sdes 211180740Sdes/* Only load up register 13 if there is a .sdata and/or .sbss section */ 212180740Sdes lwz 3,.Lsdas(11) /* start of .sdata/.sbss section */ 213180740Sdes lwz 4,.Lsdae(11) /* end of .sdata/.sbss section */ 214180740Sdes cmpw 1,3,4 /* .sdata/.sbss section non-empty? */ 215180740Sdes beq- 1,.Lsda2l /* skip loading r13 */ 216180740Sdes 217180740Sdes lwz 13,.Lsda(11) /* load r13 with _SDA_BASE_ address */ 218180740Sdes 219180740Sdes/* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */ 220180740Sdes 221180740Sdes.Lsda2l: 222262566Sdes lwz 3,.Lsda2s(11) /* start of .sdata/.sbss section */ 223262566Sdes lwz 4,.Lsda2e(11) /* end of .sdata/.sbss section */ 224262566Sdes cmpw 1,3,4 /* .sdata/.sbss section non-empty? */ 225180740Sdes beq+ 1,.Ldone /* skip loading r2 */ 226180740Sdes 227180740Sdes lwz 2,.Lsda2(11) /* load r2 with _SDA2_BASE_ address */ 228262566Sdes 229262566Sdes/* Done adjusting pointers, return by way of doing the C++ global constructors. */ 230262566Sdes 231262566Sdes.Ldone: 232262566Sdes b FUNC_NAME(__init) /* do any C++ global constructors (which returns to caller) */ 233262566SdesFUNC_END(__eabi) 234262566Sdes 235262566Sdes/* Special subroutine to convert a bunch of pointers directly. 236262566Sdes r0 has original link register 237262566Sdes r3 has low pointer to convert 238262566Sdes r4 has high pointer to convert 239262566Sdes r5 .. r10 are scratch registers 240262566Sdes r11 has the address of .LCTOC1 in it. 241262566Sdes r12 has the value to add to each pointer 242262566Sdes r13 .. r31 are unchanged */ 243262566Sdes 244262566SdesFUNC_START(__eabi_convert) 245262566Sdes cmplw 1,3,4 /* any pointers to convert? */ 246221420Sdes subf 5,3,4 /* calculate number of words to convert */ 247221420Sdes bclr 4,4 /* return if no pointers */ 248221420Sdes 249248619Sdes srawi 5,5,2 250248619Sdes addi 3,3,-4 /* start-4 for use with lwzu */ 251248619Sdes mtctr 5 252180740Sdes 253180740Sdes.Lcvt: 254180740Sdes lwzu 6,4(3) /* pointer to convert */ 255180740Sdes cmpi 0,6,0 256180740Sdes beq- .Lcvt2 /* if pointer is null, don't convert */ 257180740Sdes 258262566Sdes add 6,6,12 /* convert pointer */ 259262566Sdes stw 6,0(3) 260262566Sdes.Lcvt2: 261180740Sdes bdnz+ .Lcvt 262180740Sdes blr 263180740Sdes 264255767SdesFUNC_END(__eabi_convert) 265255767Sdes 266255767Sdes/* Special subroutine to convert the pointers the user has initialized. The 267180740Sdes compiler has placed the address of the initialized pointer into the .fixup 268180740Sdes section. 269180740Sdes 270180740Sdes r0 has original link register 271180740Sdes r3 has low pointer to convert 272180740Sdes r4 has high pointer to convert 273180740Sdes r5 .. r10 are scratch registers 274180740Sdes r11 has the address of .LCTOC1 in it. 275180740Sdes r12 has the value to add to each pointer 276180740Sdes r13 .. r31 are unchanged */ 277180740Sdes 278180740SdesFUNC_START(__eabi_uconvert) 279255767Sdes cmplw 1,3,4 /* any pointers to convert? */ 280255767Sdes subf 5,3,4 /* calculate number of words to convert */ 281255767Sdes bclr 4,4 /* return if no pointers */ 282180740Sdes 283180740Sdes srawi 5,5,2 284180740Sdes addi 3,3,-4 /* start-4 for use with lwzu */ 285180740Sdes mtctr 5 286180740Sdes 287180740Sdes.Lucvt: 288180740Sdes lwzu 6,4(3) /* next pointer to pointer to convert */ 289180740Sdes add 6,6,12 /* adjust pointer */ 290180740Sdes lwz 7,0(6) /* get the pointer it points to */ 291180740Sdes stw 6,0(3) /* store adjusted pointer */ 292180740Sdes add 7,7,12 /* adjust */ 293180740Sdes stw 7,0(6) 294180740Sdes bdnz+ .Lucvt 295180740Sdes blr 296180740Sdes 297180740SdesFUNC_END(__eabi_uconvert) 298180740Sdes 299180740Sdes#endif 300180740Sdes