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