rev |
line source |
nuclear@0
|
1 /* Linker Script v1.3 by Jeff Frohwein */
|
nuclear@0
|
2 /* v1.0 - Original release */
|
nuclear@0
|
3 /* v1.1 - Added proper .data section support */
|
nuclear@0
|
4 /* v1.2 - Added support for c++ & iwram overlays */
|
nuclear@0
|
5 /* - Major contributions by Jason Wilkins. */
|
nuclear@0
|
6 /* v1.3 - .ewram section now can be used when */
|
nuclear@0
|
7 /* compiling for MULTIBOOT mode. This fixes */
|
nuclear@0
|
8 /* malloc() in DevKitAdvance which depends */
|
nuclear@0
|
9 /* on __eheap_start instead of end to define*/
|
nuclear@0
|
10 /* the starting location of heap space. */
|
nuclear@0
|
11 /* External global variable __gba_iwram_heap*/
|
nuclear@0
|
12 /* support added to allow labels end, _end, */
|
nuclear@0
|
13 /* & __end__ to point to end of iwram or */
|
nuclear@0
|
14 /* the end of ewram. */
|
nuclear@0
|
15
|
nuclear@0
|
16 /* This file is released into the public domain */
|
nuclear@0
|
17 /* for commercial or non-commercial use with no */
|
nuclear@0
|
18 /* restrictions placed upon it. */
|
nuclear@0
|
19
|
nuclear@0
|
20 /* NOTE!!!: This linker script defines the RAM & */
|
nuclear@0
|
21 /* ROM start addresses. In order for it to work */
|
nuclear@0
|
22 /* properly, remove -Ttext and -Tbss linker */
|
nuclear@0
|
23 /* options from your makefile if they are */
|
nuclear@0
|
24 /* present. */
|
nuclear@0
|
25
|
nuclear@0
|
26 /* You can use the following to view section */
|
nuclear@0
|
27 /* addresses in your .elf file: */
|
nuclear@0
|
28 /* objdump -h file.elf */
|
nuclear@0
|
29 /* Please note that empty sections may incorrectly*/
|
nuclear@0
|
30 /* list the lma address as the vma address for */
|
nuclear@0
|
31 /* some versions of objdump. */
|
nuclear@0
|
32
|
nuclear@0
|
33 OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
nuclear@0
|
34 OUTPUT_ARCH(arm)
|
nuclear@0
|
35 ENTRY(_start)
|
nuclear@0
|
36 /* SEARCH_DIR(/bin/arm); */
|
nuclear@0
|
37
|
nuclear@0
|
38 /* By default this linker script will generate code */
|
nuclear@0
|
39 /* for flash carts located at 0x8000000. In order to */
|
nuclear@0
|
40 /* generate code that is compiled at 0x2000000 that */
|
nuclear@0
|
41 /* will run on flash carts or in multiboot mode then */
|
nuclear@0
|
42 /* you need to add the following variable to your main */
|
nuclear@0
|
43 /* project file. It's value is NOT important but */
|
nuclear@0
|
44 /* IT MUST BE A GLOBAL VARIABLE OR IT WILL NOT WORK: */
|
nuclear@0
|
45
|
nuclear@0
|
46 /* #define MULTIBOOT int __gba_multiboot; */
|
nuclear@0
|
47 /* Then use it like this: MULTIBOOT */
|
nuclear@0
|
48
|
nuclear@0
|
49 /* By default this linker script will set the labels */
|
nuclear@0
|
50 /* end, _end, & __end__ at the end of ewram. To force */
|
nuclear@0
|
51 /* them to be set to the end of iwram then you need to */
|
nuclear@0
|
52 /* add the following variable to your main */
|
nuclear@0
|
53 /* project file. It's value is NOT important but */
|
nuclear@0
|
54 /* IT MUST BE A GLOBAL VARIABLE OR IT WILL NOT WORK: */
|
nuclear@0
|
55
|
nuclear@0
|
56 /* #define IWRAMHEAP int __gba_iwram_heap; */
|
nuclear@0
|
57 /* Then use it like this: IWRAMHEAP */
|
nuclear@0
|
58
|
nuclear@0
|
59 /* The linker script function "var1 += var2;" sometimes */
|
nuclear@0
|
60 /* reports incorrect values in the *.map file but the */
|
nuclear@0
|
61 /* actual value it calculates is usually, if not always, */
|
nuclear@0
|
62 /* correct. If you leave out the ". = ALIGN(4);" at the */
|
nuclear@0
|
63 /* end of each section then the return value of SIZEOF() */
|
nuclear@0
|
64 /* is sometimes incorrect and "var1 += var2;" appears to */
|
nuclear@0
|
65 /* not work as well. "var1 += var2" style functions are */
|
nuclear@0
|
66 /* avoided below as a result. */
|
nuclear@0
|
67
|
nuclear@0
|
68 /* The linker script MEMORY directive is not used here due */
|
nuclear@0
|
69 /* to the fact that __text_start is not always a fixed value. */
|
nuclear@0
|
70
|
nuclear@0
|
71 __text_start = DEFINED (__gba_multiboot) ? 0x2000000 : 0x8000000;
|
nuclear@0
|
72 /* __ewram_start = 0x2000000; */ /* Removed in v1.3 */
|
nuclear@0
|
73 __eheap_end = 0x2040000;
|
nuclear@0
|
74 __iwram_start = 0x3000000;
|
nuclear@0
|
75 __iheap_end = 0x3008000 - 0x400;
|
nuclear@0
|
76 __sp_usr = 0x3008000 - 0x100;
|
nuclear@0
|
77 __sp_irq = 0x3008000 - 0x60;
|
nuclear@0
|
78 __intr_vector_buf = 0x3008000 - 4;
|
nuclear@0
|
79 __sp_usr_offset = __sp_usr - __iwram_start;
|
nuclear@0
|
80 __intr_vect_offset = __intr_vector_buf - __sp_usr;
|
nuclear@0
|
81
|
nuclear@0
|
82 SECTIONS
|
nuclear@0
|
83 {
|
nuclear@0
|
84 .text __text_start : /* ALIGN (4): */
|
nuclear@0
|
85 {
|
nuclear@0
|
86 *(EXCLUDE_FILE (*text.iwram*) .text)
|
nuclear@0
|
87 *(.text.*)
|
nuclear@0
|
88 *(.stub)
|
nuclear@0
|
89 /* .gnu.warning sections are handled specially by elf32.em. */
|
nuclear@0
|
90 *(.gnu.warning)
|
nuclear@0
|
91 *(.gnu.linkonce.t*)
|
nuclear@0
|
92 *(.glue_7)
|
nuclear@0
|
93 *(.glue_7t)
|
nuclear@0
|
94 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
95 } = 0xff
|
nuclear@0
|
96 /* laddr = ADDR(.text) + SIZEOF(.text); */
|
nuclear@0
|
97 __text_end = .;
|
nuclear@0
|
98
|
nuclear@0
|
99 .rodata :
|
nuclear@0
|
100 {
|
nuclear@0
|
101 *(.rodata)
|
nuclear@0
|
102 *all.rodata*(*)
|
nuclear@0
|
103 *(.roda)
|
nuclear@0
|
104 *(.rodata.*)
|
nuclear@0
|
105 *(.gnu.linkonce.r*)
|
nuclear@0
|
106 SORT(CONSTRUCTORS)
|
nuclear@0
|
107 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
108 } = 0xff
|
nuclear@0
|
109 /* laddr += SIZEOF(.rodata); */
|
nuclear@0
|
110
|
nuclear@0
|
111 .ctors :
|
nuclear@0
|
112 {
|
nuclear@0
|
113 /* gcc uses crtbegin.o to find the start of the constructors, so
|
nuclear@0
|
114 we make sure it is first. Because this is a wildcard, it
|
nuclear@0
|
115 doesn't matter if the user does not actually link against
|
nuclear@0
|
116 crtbegin.o; the linker won't look for a file to match a
|
nuclear@0
|
117 wildcard. The wildcard also means that it doesn't matter which
|
nuclear@0
|
118 directory crtbegin.o is in. */
|
nuclear@0
|
119 KEEP (*crtbegin.o(.ctors))
|
nuclear@0
|
120 KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
nuclear@0
|
121 KEEP (*(SORT(.ctors.*)))
|
nuclear@0
|
122 KEEP (*(.ctors))
|
nuclear@0
|
123 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
124 } = 0
|
nuclear@0
|
125 /* laddr += SIZEOF(.ctors); */
|
nuclear@0
|
126 laddr = ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ctors);
|
nuclear@0
|
127
|
nuclear@0
|
128 .dtors :
|
nuclear@0
|
129 {
|
nuclear@0
|
130 KEEP (*crtbegin.o(.dtors))
|
nuclear@0
|
131 KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
nuclear@0
|
132 KEEP (*(SORT(.dtors.*)))
|
nuclear@0
|
133 KEEP (*(.dtors))
|
nuclear@0
|
134 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
135 } = 0
|
nuclear@0
|
136 /* laddr += SIZEOF(.dtors); */
|
nuclear@0
|
137 laddr = ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors);
|
nuclear@0
|
138
|
nuclear@0
|
139 .eh_frame :
|
nuclear@0
|
140 {
|
nuclear@0
|
141 KEEP (*(.eh_frame))
|
nuclear@0
|
142 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
143 } = 0
|
nuclear@0
|
144 /* laddr += SIZEOF(.eh_frame); */
|
nuclear@0
|
145
|
nuclear@0
|
146 .gcc_except_table :
|
nuclear@0
|
147 {
|
nuclear@0
|
148 *(.gcc_except_table)
|
nuclear@0
|
149 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
150 } = 0
|
nuclear@0
|
151 /* laddr += (SIZEOF(.gcc_except_table) + 3) & ~ 3; */
|
nuclear@0
|
152 /* __iwram_lma = laddr; */
|
nuclear@0
|
153 __iwram_lma = (ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors) + SIZEOF(.eh_frame) + SIZEOF(.gcc_except_table) + 3) & ~ 3;
|
nuclear@0
|
154
|
nuclear@0
|
155 .iwram __iwram_start : AT (__iwram_lma)
|
nuclear@0
|
156 {
|
nuclear@0
|
157 __iwram_start = ABSOLUTE(.) ;
|
nuclear@0
|
158 *(.iwram)
|
nuclear@0
|
159 *iwram.*(.text)
|
nuclear@0
|
160 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
161 } = 0xff
|
nuclear@0
|
162 /* laddr += SIZEOF(.iwram); */
|
nuclear@0
|
163 /* __data_lma = laddr; */
|
nuclear@0
|
164 __data_lma = ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors) + SIZEOF(.eh_frame) + SIZEOF(.gcc_except_table) + SIZEOF(.iwram);
|
nuclear@0
|
165
|
nuclear@0
|
166 __iwram_end = . ;
|
nuclear@0
|
167
|
nuclear@0
|
168 .bss ALIGN(4) :
|
nuclear@0
|
169 {
|
nuclear@0
|
170 __bss_start = ABSOLUTE(.);
|
nuclear@0
|
171 __bss_start__ = ABSOLUTE(.);
|
nuclear@0
|
172 *(.dynbss)
|
nuclear@0
|
173 *(.gnu.linkonce.b*)
|
nuclear@0
|
174 *(COMMON)
|
nuclear@0
|
175 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
176 }
|
nuclear@0
|
177
|
nuclear@0
|
178 __bss_end = . ;
|
nuclear@0
|
179 __bss_end__ = . ;
|
nuclear@0
|
180
|
nuclear@0
|
181 .data ALIGN(4) : AT (__data_lma)
|
nuclear@0
|
182 {
|
nuclear@0
|
183 __data_start = ABSOLUTE(.);
|
nuclear@0
|
184 *(.data)
|
nuclear@0
|
185 *(.data.*)
|
nuclear@0
|
186 *(.gnu.linkonce.d*)
|
nuclear@0
|
187 CONSTRUCTORS
|
nuclear@0
|
188 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
189 } = 0xff
|
nuclear@0
|
190 /* laddr += SIZEOF(.data); */
|
nuclear@0
|
191 /* __iwram_overlay_lma = laddr; */
|
nuclear@0
|
192 __iwram_overlay_lma = ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors) + SIZEOF(.eh_frame) + SIZEOF(.gcc_except_table) + SIZEOF(.iwram) + SIZEOF(.data);
|
nuclear@0
|
193
|
nuclear@0
|
194 __data_end = .;
|
nuclear@0
|
195 PROVIDE (edata = .);
|
nuclear@0
|
196 /* __data_lma = LOADADDR(.data); */
|
nuclear@0
|
197 __iwram_overlay_start = . ;
|
nuclear@0
|
198
|
nuclear@0
|
199 OVERLAY : NOCROSSREFS AT (__iwram_overlay_lma)
|
nuclear@0
|
200 {
|
nuclear@0
|
201 .iwram0 { *(.iwram0) . = ALIGN(4);}
|
nuclear@0
|
202 .iwram1 { *(.iwram1) . = ALIGN(4);}
|
nuclear@0
|
203 .iwram2 { *(.iwram2) . = ALIGN(4);}
|
nuclear@0
|
204 .iwram3 { *(.iwram3) . = ALIGN(4);}
|
nuclear@0
|
205 .iwram4 { *(.iwram4) . = ALIGN(4);}
|
nuclear@0
|
206 .iwram5 { *(.iwram5) . = ALIGN(4);}
|
nuclear@0
|
207 .iwram6 { *(.iwram6) . = ALIGN(4);}
|
nuclear@0
|
208 .iwram7 { *(.iwram7) . = ALIGN(4);}
|
nuclear@0
|
209 .iwram8 { *(.iwram8) . = ALIGN(4);}
|
nuclear@0
|
210 .iwram9 { *(.iwram9) . = ALIGN(4);}
|
nuclear@0
|
211 } = 0xff
|
nuclear@0
|
212 /* laddr += (SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9)); */
|
nuclear@0
|
213 /* __ewram_lma = laddr; */
|
nuclear@0
|
214 __ewram_lma = ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors) + SIZEOF(.eh_frame) + SIZEOF(.gcc_except_table) + SIZEOF(.iwram) + SIZEOF(.data) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9);
|
nuclear@0
|
215
|
nuclear@0
|
216 /* __iwram_overlay_lma = LOADADDR (.iwram0); */
|
nuclear@0
|
217 __iwram_overlay_end = . ;
|
nuclear@0
|
218 /* _end = . ; */
|
nuclear@0
|
219 /* __end__ = . ; */
|
nuclear@0
|
220 /* PROVIDE (end = .); */
|
nuclear@0
|
221 __iheap_start = . ;
|
nuclear@0
|
222
|
nuclear@0
|
223 /* v1.3 */
|
nuclear@0
|
224 __ewram_start = DEFINED (__gba_multiboot) ? __ewram_lma : 0x2000000;
|
nuclear@0
|
225
|
nuclear@0
|
226 .ewram __ewram_start : AT (__ewram_lma)
|
nuclear@0
|
227 {
|
nuclear@0
|
228 /* __ewram_start = ABSOLUTE(.); */
|
nuclear@0
|
229 *(.ewram)
|
nuclear@0
|
230 . = ALIGN(4); /* REQUIRED. LD is flaky without it. */
|
nuclear@0
|
231 } = 0xff
|
nuclear@0
|
232 /* laddr += SIZEOF(.ewram); */
|
nuclear@0
|
233 /* __ewram_overlay_lma = laddr; */
|
nuclear@0
|
234 __ewram_overlay_lma = ADDR(.text) + SIZEOF(.text) + SIZEOF(.rodata) + SIZEOF(.ctors) + SIZEOF(.dtors) + SIZEOF(.eh_frame) + SIZEOF(.gcc_except_table) + SIZEOF(.iwram) + SIZEOF(.data) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9) + SIZEOF(.ewram);
|
nuclear@0
|
235
|
nuclear@0
|
236 /* __ewram_lma = LOADADDR(.ewram); */
|
nuclear@0
|
237 __ewram_end = . ;
|
nuclear@0
|
238 __ewram_overlay_start = . ;
|
nuclear@0
|
239
|
nuclear@0
|
240 OVERLAY ALIGN(4): NOCROSSREFS AT (__ewram_overlay_lma)
|
nuclear@0
|
241 {
|
nuclear@0
|
242 .ewram0 { *(.ewram0) . = ALIGN(4);}
|
nuclear@0
|
243 .ewram1 { *(.ewram1) . = ALIGN(4);}
|
nuclear@0
|
244 .ewram2 { *(.ewram2) . = ALIGN(4);}
|
nuclear@0
|
245 .ewram3 { *(.ewram3) . = ALIGN(4);}
|
nuclear@0
|
246 .ewram4 { *(.ewram4) . = ALIGN(4);}
|
nuclear@0
|
247 .ewram5 { *(.ewram5) . = ALIGN(4);}
|
nuclear@0
|
248 .ewram6 { *(.ewram6) . = ALIGN(4);}
|
nuclear@0
|
249 .ewram7 { *(.ewram7) . = ALIGN(4);}
|
nuclear@0
|
250 .ewram8 { *(.ewram8) . = ALIGN(4);}
|
nuclear@0
|
251 .ewram9 { *(.ewram9) . = ALIGN(4);}
|
nuclear@0
|
252 } = 0xff
|
nuclear@0
|
253
|
nuclear@0
|
254 __ewram_overlay_end = . ;
|
nuclear@0
|
255
|
nuclear@0
|
256 __eheap_start = . ;
|
nuclear@0
|
257
|
nuclear@0
|
258 _end = DEFINED (__gba_iwram_heap) ? __iheap_start : .; /* v1.3 */
|
nuclear@0
|
259 __end__ = _end ; /* v1.3 */
|
nuclear@0
|
260 PROVIDE (end = _end); /* v1.3 */
|
nuclear@0
|
261
|
nuclear@0
|
262 /* Stabs debugging sections. */
|
nuclear@0
|
263 .stab 0 : { *(.stab) }
|
nuclear@0
|
264 .stabstr 0 : { *(.stabstr) }
|
nuclear@0
|
265 .stab.excl 0 : { *(.stab.excl) }
|
nuclear@0
|
266 .stab.exclstr 0 : { *(.stab.exclstr) }
|
nuclear@0
|
267 .stab.index 0 : { *(.stab.index) }
|
nuclear@0
|
268 .stab.indexstr 0 : { *(.stab.indexstr) }
|
nuclear@0
|
269 .comment 0 : { *(.comment) }
|
nuclear@0
|
270 /* DWARF debug sections.
|
nuclear@0
|
271 Symbols in the DWARF debugging sections are relative to the beginning
|
nuclear@0
|
272 of the section so we begin them at 0. */
|
nuclear@0
|
273 /* DWARF 1 */
|
nuclear@0
|
274 .debug 0 : { *(.debug) }
|
nuclear@0
|
275 .line 0 : { *(.line) }
|
nuclear@0
|
276 /* GNU DWARF 1 extensions */
|
nuclear@0
|
277 .debug_srcinfo 0 : { *(.debug_srcinfo) }
|
nuclear@0
|
278 .debug_sfnames 0 : { *(.debug_sfnames) }
|
nuclear@0
|
279 /* DWARF 1.1 and DWARF 2 */
|
nuclear@0
|
280 .debug_aranges 0 : { *(.debug_aranges) }
|
nuclear@0
|
281 .debug_pubnames 0 : { *(.debug_pubnames) }
|
nuclear@0
|
282 /* DWARF 2 */
|
nuclear@0
|
283 .debug_info 0 : { *(.debug_info) }
|
nuclear@0
|
284 .debug_abbrev 0 : { *(.debug_abbrev) }
|
nuclear@0
|
285 .debug_line 0 : { *(.debug_line) }
|
nuclear@0
|
286 .debug_frame 0 : { *(.debug_frame) }
|
nuclear@0
|
287 .debug_str 0 : { *(.debug_str) }
|
nuclear@0
|
288 .debug_loc 0 : { *(.debug_loc) }
|
nuclear@0
|
289 .debug_macinfo 0 : { *(.debug_macinfo) }
|
nuclear@0
|
290 /* SGI/MIPS DWARF 2 extensions */
|
nuclear@0
|
291 .debug_weaknames 0 : { *(.debug_weaknames) }
|
nuclear@0
|
292 .debug_funcnames 0 : { *(.debug_funcnames) }
|
nuclear@0
|
293 .debug_typenames 0 : { *(.debug_typenames) }
|
nuclear@0
|
294 .debug_varnames 0 : { *(.debug_varnames) }
|
nuclear@0
|
295 .stack 0x80000 : { _stack = .; *(.stack) }
|
nuclear@0
|
296 /* These must appear regardless of . */
|
nuclear@0
|
297 }
|