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