2 * Special support for eabi and SVR4
4 * Copyright (C) 1995-2024 Free Software Foundation, Inc.
5 * Written By Michael Meissner
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
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.
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.
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/>.
27 /* Do any initializations needed for the eabi environment */
36 .LCTOC1 = . /* +32768 */
38 /* Table of addresses */
40 .long .LCTOC1 /* address we are really at */
43 .long _SDA_BASE_ /* address of the first small data area */
46 .long __SDATA_START__ /* start of .sdata/.sbss section */
49 .long __SBSS_END__ /* end of .sdata/.sbss section */
52 .long _SDA2_BASE_ /* address of the second small data area */
55 .long __SDATA2_START__ /* start of .sdata2/.sbss2 section */
58 .long __SBSS2_END__ /* end of .sdata2/.sbss2 section */
62 .long __GOT_START__ /* Global offset table start */
65 .long _GLOBAL_OFFSET_TABLE_-4 /* end of GOT ptrs before BLCL + 3 reserved words */
68 .long _GLOBAL_OFFSET_TABLE_+12 /* start of GOT ptrs after BLCL + 3 reserved words */
71 .long __GOT_END__ /* Global offset table end */
74 .long __GOT2_START__ /* -mrelocatable GOT pointers start */
77 .long __GOT2_END__ /* -mrelocatable GOT pointers end */
80 .long __FIXUP_START__ /* start of .fixup section */
83 .long __FIXUP_END__ /* end of .fixup section */
86 .long __CTOR_LIST__ /* start of .ctor section */
89 .long __CTOR_END__ /* end of .ctor section */
92 .long __DTOR_LIST__ /* start of .dtor section */
95 .long __DTOR_END__ /* end of .dtor section */
98 .long __EXCEPT_START__ /* start of .gcc_except_table section */
100 .Lexcepte = .-.LCTOC1
101 .long __EXCEPT_END__ /* end of .gcc_except_table section */
104 .long .Linit_p /* address of variable to say we've been called */
109 .long .LCTOC1-.Laddr /* PC relative pointer to .got2 */
121 /* Eliminate -mrelocatable code if not -mrelocatable, so that this file can
122 be assembled with other assemblers than GAS. */
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 */
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 */
133 #else /* -mrelocatable */
135 bl .Laddr /* get current address */
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 */
150 /* We need to relocate the .got2 pointers. */
152 lwz 3,.Lgot2s(11) /* GOT2 pointers start */
153 lwz 4,.Lgot2e(11) /* GOT2 pointers end */
154 add 3,12,3 /* adjust pointers */
156 bl FUNC_NAME(__eabi_convert) /* convert pointers in .got2 section */
158 /* Fixup the .ctor section for static constructors */
160 lwz 3,.Lctors(11) /* constructors pointers start */
161 lwz 4,.Lctore(11) /* constructors pointers end */
162 bl FUNC_NAME(__eabi_convert) /* convert constructors */
164 /* Fixup the .dtor section for static destructors */
166 lwz 3,.Ldtors(11) /* destructors pointers start */
167 lwz 4,.Ldtore(11) /* destructors pointers end */
168 bl FUNC_NAME(__eabi_convert) /* convert destructors */
170 /* Fixup the .gcc_except_table section for G++ exceptions */
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 */
176 /* Fixup the addresses in the GOT below _GLOBAL_OFFSET_TABLE_-4 */
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 */
182 /* Fixup the addresses in the GOT above _GLOBAL_OFFSET_TABLE_+12 */
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 */
188 /* Fixup any user initialized pointers now (the compiler drops pointers to */
189 /* each of the relocs that it does in the .fixup section). */
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 */
197 mtlr 0 /* restore link register */
198 #endif /* _RELOCATABLE */
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 */
206 lwz 13,.Lsda(11) /* load r13 with _SDA_BASE_ address */
208 /* Only load up register 2 if there is a .sdata2 and/or .sbss2 section */
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 */
216 lwz 2,.Lsda2(11) /* load r2 with _SDA2_BASE_ address */
218 /* Done adjusting pointers, return by way of doing the C++ global constructors. */
221 b FUNC_NAME(__init) /* do any C++ global constructors (which returns to caller) */
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 */
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 */
239 addi 3,3,-4 /* start-4 for use with lwzu */
243 lwzu 6,4(3) /* pointer to convert */
245 beq- .Lcvt2 /* if pointer is null, don't convert */
247 add 6,6,12 /* convert pointer */
253 FUNC_END(__eabi_convert)
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
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 */
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 */
273 addi 3,3,-4 /* start-4 for use with lwzu */
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 */
286 FUNC_END(__eabi_uconvert)