1 {
2 This unit implements support import,export,link routines
3 for the (arm) Nintendo DS target
4
5 Copyright (c) 2001-2002 by Peter Vreman
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 ****************************************************************************
22 }
23 unit t_nds;
24
25 {$i fpcdefs.inc}
26
27 interface
28
29
30 implementation
31
32 uses
33 aasmbase,
34 SysUtils,
35 cutils,cfileutl,cclasses,
36 globtype,globals,systems,verbose,cscript,fmodule,i_nds,link;
37
38 type
39 TlinkerNDS=class(texternallinker)
40 private
WriteResponseFilenull41 Function WriteResponseFile: Boolean;
42 public
43 constructor Create; override;
44 procedure SetDefaultInfo; override;
MakeExecutablenull45 function MakeExecutable:boolean; override;
46 end;
47
48
49
50 {*****************************************************************************
51 TLINKERNDS
52 *****************************************************************************}
53
54 Constructor TLinkerNDS.Create;
55 begin
56 Inherited Create;
57 SharedLibFiles.doubles:=true;
58 StaticLibFiles.doubles:=true;
59 // set arm9 as default apptype
60 if (apptype <> app_arm9) or (apptype <> app_arm7) then
61 apptype:=app_arm9;
62 end;
63
64
65 procedure TLinkerNDS.SetDefaultInfo;
66 begin
67 with Info do
68 begin
69 ExeCmd[1]:='ld -g $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE -T $RES';
70 end;
71 end;
72
73
TLinkerNDS.WriteResponseFilenull74 Function TLinkerNDS.WriteResponseFile: Boolean;
75 Var
76 linkres : TLinkRes;
77 i : longint;
78 HPath : TCmdStrListItem;
79 s,s1,s2 : TCmdStr;
80 prtobj,
81 cprtobj : string[80];
82 linklibc,
83 linklibgcc : boolean;
84 found1,
85 found2 : boolean;
86 begin
87 WriteResponseFile:=False;
88 linklibc:=(SharedLibFiles.Find('c')<>nil);
89 linklibgcc:=(SharedLibFiles.Find('gcc')<>nil);
90
91 prtobj:='';
92 cprtobj:='';
93 case apptype of
94 app_arm9:
95 begin
96 prtobj:='prt09';
97 cprtobj:='cprt09';
98 end;
99 app_arm7:
100 begin
101 prtobj:='prt07';
102 cprtobj:='cprt07';
103 end;
104 end;
105
106 if (linklibc or linklibgcc) then
107 prtobj:=cprtobj;
108
109 { Open link.res file }
110 LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true);
111
112 { Write path to search libraries }
113 HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
114 while assigned(HPath) do
115 begin
116 s:=HPath.Str;
117 if (cs_link_on_target in current_settings.globalswitches) then
118 s:=ScriptFixFileName(s);
119 LinkRes.Add('-L'+s);
120 HPath:=TCmdStrListItem(HPath.Next);
121 end;
122 HPath:=TCmdStrListItem(LibrarySearchPath.First);
123 while assigned(HPath) do
124 begin
125 s:=HPath.Str;
126 if s<>'' then
127 LinkRes.Add('SEARCH_DIR("'+s+'")');
128 HPath:=TCmdStrListItem(HPath.Next);
129 end;
130
131 LinkRes.Add('INPUT (');
132 { add objectfiles, start with prt0 always }
133 if prtobj<>'' then
134 s:=FindObjectFile(prtobj,'',false);
135 LinkRes.AddFileName(s);
136 { try to add crti and crtbegin if linking to C }
137 if linklibc then
138 begin
139 if librarysearchpath.FindFile('crti.o',false,s) then
140 LinkRes.AddFileName(s);
141 end;
142 if linklibgcc then
143 begin
144 if librarysearchpath.FindFile('crtbegin.o',false,s) then
145 LinkRes.AddFileName(s);
146 end;
147 while not ObjectFiles.Empty do
148 begin
149 s:=ObjectFiles.GetFirst;
150 if s<>'' then
151 begin
152 { vlink doesn't use SEARCH_DIR for object files }
153 if not(cs_link_on_target in current_settings.globalswitches) then
154 s:=FindObjectFile(s,'',false);
155 LinkRes.AddFileName((maybequoted(s)));
156 end;
157 end;
158
159 { Write staticlibraries }
160 if not StaticLibFiles.Empty then
161 begin
162 { vlink doesn't need, and doesn't support GROUP }
163 if (cs_link_on_target in current_settings.globalswitches) then
164 begin
165 LinkRes.Add(')');
166 LinkRes.Add('GROUP(');
167 end;
168 while not StaticLibFiles.Empty do
169 begin
170 S:=StaticLibFiles.GetFirst;
171 LinkRes.AddFileName((maybequoted(s)));
172 end;
173 end;
174
175 if (cs_link_on_target in current_settings.globalswitches) then
176 begin
177 LinkRes.Add(')');
178
179 { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
180 here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
181 linklibc:=false;
182 linklibgcc:=false;
183 while not SharedLibFiles.Empty do
184 begin
185 S:=SharedLibFiles.GetFirst;
186 if s<>'c' then
187 begin
188 i:=Pos(target_info.sharedlibext,S);
189 if i>0 then
190 Delete(S,i,255);
191 LinkRes.Add('-l'+s);
192 end
193 else
194 begin
195 LinkRes.Add('-l'+s);
196 linklibc:=true;
197 linklibgcc:=true;
198 end;
199 end;
200 { be sure that libc&libgcc is the last lib }
201 if linklibgcc then
202 begin
203 LinkRes.Add('-lgcc');
204 end;
205 if linklibc then
206 begin
207 LinkRes.Add('-lc');
208 end;
209 end
210 else
211 begin
212 while not SharedLibFiles.Empty do
213 begin
214 S:=SharedLibFiles.GetFirst;
215 LinkRes.Add('lib'+s+target_info.staticlibext);
216 end;
217 LinkRes.Add(')');
218 end;
219
220 { objects which must be at the end }
221 if linklibgcc then
222 begin
223 found1:=librarysearchpath.FindFile('crtend.o',false,s1);
224 if found1 then
225 begin
226 LinkRes.Add('INPUT(');
227 if found1 then
228 LinkRes.AddFileName(s1);
229 LinkRes.Add(')');
230 end;
231 end;
232 if linklibc then
233 begin
234 found2:=librarysearchpath.FindFile('crtn.o',false,s2);
235 if found2 then
236 begin
237 LinkRes.Add('INPUT(');
238 if found2 then
239 LinkRes.AddFileName(s2);
240 LinkRes.Add(')');
241 end;
242 end;
243
244 with linkres do
245 begin
246 if apptype=app_arm9 then //ARM9
247 begin
248 add('MEMORY {');
249 add(' rom : ORIGIN = 0x08000000, LENGTH = 32M');
250 add(' ewram : ORIGIN = 0x02000000, LENGTH = 4M - 4k');
251 add(' dtcm : ORIGIN = 0x0b000000, LENGTH = 16K');
252 add(' vectors : ORIGIN = 0x01000000, LENGTH = 256');
253 add(' itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256');
254 add('}');
255 add('');
256 add('OUTPUT_ARCH(arm)');
257 add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
258 add('ENTRY(_start)');
259 add('');
260 add('__vectors_start = ORIGIN(vectors);');
261 add('__itcm_start = ORIGIN(itcm);');
262 add('__ewram_end = ORIGIN(ewram) + LENGTH(ewram);');
263 add('__eheap_end = ORIGIN(ewram) + LENGTH(ewram);');
264 add('__dtcm_start = ORIGIN(dtcm);');
265 add('__dtcm_top = ORIGIN(dtcm) + LENGTH(dtcm);');
266 add('__irq_flags = __dtcm_top - 0x08;');
267 add('__irq_vector = __dtcm_top - 0x04;');
268 add('');
269 add('__sp_svc = __dtcm_top - 0x100;');
270 add('__sp_irq = __sp_svc - 0x100;');
271 add('__sp_usr = __sp_irq - 0x100;');
272 add('');
273 add('SECTIONS');
274 add('{');
275 add(' .init :');
276 add(' {');
277 add(' __text_start = . ;');
278 add(' KEEP (*(.init))');
279 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
280 add(' } >ewram = 0xff');
281 add('');
282 add(' .plt : { *(.plt) } >ewram = 0xff');
283 add('');
284 add(' .text : /* ALIGN (4): */');
285 add(' {');
286 add(' *(EXCLUDE_FILE (*.itcm*) .text)');
287 add('');
288 add(' *(.text.*)');
289 add(' *(.stub)');
290 add(' /* .gnu.warning sections are handled specially by elf32.em. */');
291 add(' *(.gnu.warning)');
292 add(' *(.gnu.linkonce.t*)');
293 add(' *(.glue_7)');
294 add(' *(.glue_7t)');
295 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
296 add(' } >ewram = 0xff');
297 add('');
298 add(' .fini :');
299 add(' {');
300 add(' KEEP (*(.fini))');
301 add(' } >ewram =0xff');
302 add('');
303 add(' __text_end = . ;');
304 add('');
305 add(' .rodata :');
306 add(' {');
307 add(' *(.rodata)');
308 add(' *all.rodata*(*)');
309 add(' *(.roda)');
310 add(' *(.rodata.*)');
311 add(' *(.gnu.linkonce.r*)');
312 add(' SORT(CONSTRUCTORS)');
313 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
314 add(' } >ewram = 0xff');
315 add('');
316 add(' .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram');
317 add(' __exidx_start = .;');
318 add(' ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram');
319 add(' __exidx_end = .;');
320 add('');
321 add(' /* Ensure the __preinit_array_start label is properly aligned. We');
322 add(' could instead move the label definition inside the section, but');
323 add(' the linker would then create the section even if it turns out to');
324 add(' be empty, which isn''t pretty. */');
325 add('');
326 add(' . = ALIGN(32 / 8);');
327 add('');
328 add(' PROVIDE (__preinit_array_start = .);');
329 add(' .preinit_array : { KEEP (*(.preinit_array)) } >ewram = 0xff');
330 add(' PROVIDE (__preinit_array_end = .);');
331 add(' PROVIDE (__init_array_start = .);');
332 add(' .init_array :');
333 add(' {');
334 add(' KEEP (*(SORT(.init_array.*)))');
335 add(' KEEP (*(.init_array))');
336 add(' } >ewram = 0xff');
337 add(' PROVIDE (__init_array_end = .);');
338 add(' PROVIDE (__fini_array_start = .);');
339 add(' .fini_array :');
340 add(' {');
341 add(' KEEP (*(.fini_array))');
342 add(' KEEP (*(SORT(.fini_array.*)))');
343 add(' } >ewram = 0xff');
344 add('');
345 add(' PROVIDE (__fini_array_end = .);');
346 add('');
347 add(' .ctors :');
348 add(' {');
349 add(' /* gcc uses crtbegin.o to find the start of the constructors, so');
350 add(' we make sure it is first. Because this is a wildcard, it');
351 add(' doesn''t matter if the user does not actually link against');
352 add(' crtbegin.o; the linker won''t look for a file to match a');
353 add(' wildcard. The wildcard also means that it doesn''t matter which');
354 add(' directory crtbegin.o is in. */');
355 add(' KEEP (*crtbegin.o(.ctors))');
356 add(' KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))');
357 add(' KEEP (*(SORT(.ctors.*)))');
358 add(' KEEP (*(.ctors))');
359 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
360 add(' } >ewram = 0xff');
361 add('');
362 add(' .dtors :');
363 add(' {');
364 add(' KEEP (*crtbegin.o(.dtors))');
365 add(' KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))');
366 add(' KEEP (*(SORT(.dtors.*)))');
367 add(' KEEP (*(.dtors))');
368 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
369 add(' } >ewram = 0xff');
370 add('');
371 add(' .eh_frame :');
372 add(' {');
373 add(' KEEP (*(.eh_frame))');
374 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
375 add(' } >ewram = 0xff');
376 add('');
377 add(' .gcc_except_table :');
378 add(' {');
379 add(' *(.gcc_except_table)');
380 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
381 add(' } >ewram = 0xff');
382 add(' .jcr : { KEEP (*(.jcr)) } >ewram = 0');
383 add(' .got : { *(.got.plt) *(.got) *(.rel.got) } >ewram = 0');
384 add('');
385 add(' .ewram ALIGN(4) : ');
386 add(' {');
387 add(' __ewram_start = ABSOLUTE(.) ;');
388 add(' *(.ewram)');
389 add(' *ewram.*(.text)');
390 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
391 add(' } >ewram = 0xff');
392 add('');
393 add('');
394 add(' .data ALIGN(4) :');
395 add(' {');
396 add(' __data_start = ABSOLUTE(.);');
397 add(' *(.data)');
398 add(' *(.data.*)');
399 add(' *(.gnu.linkonce.d*)');
400 add(' CONSTRUCTORS');
401 add(' . = ALIGN(4);');
402 add(' __data_end = ABSOLUTE(.) ;');
403 add(' } >ewram = 0xff');
404 add('');
405 add('');
406 add(' __dtcm_lma = . ;');
407 add(' __bss_vma = . ;');
408 add('');
409 add(' .dtcm __dtcm_start : AT (__dtcm_lma)');
410 add(' {');
411 add(' *(.dtcm)');
412 add(' *(.dtcm.*)');
413 add(' . = ALIGN(4);');
414 add(' __dtcm_end = ABSOLUTE(.);');
415 add(' } >dtcm = 0xff');
416 add('');
417 add('');
418 add(' __itcm_lma = __dtcm_lma + SIZEOF(.dtcm);');
419 add('');
420 add(' .itcm __itcm_start : AT (__itcm_lma)');
421 add(' {');
422 add(' *(.itcm)');
423 add(' *itcm.*(.text)');
424 add(' . = ALIGN(4);');
425 add(' __itcm_end = ABSOLUTE(.);');
426 add(' } >itcm = 0xff');
427 add(' ');
428 add(' __vectors_lma = __itcm_lma + SIZEOF(.itcm);');
429 add('');
430 add(' .vectors __vectors_start : AT (__vectors_lma)');
431 add(' {');
432 add(' *(.vectors)');
433 add(' *vectors.*(.text)');
434 add(' . = ALIGN(4);');
435 add(' __vectors_end = ABSOLUTE(.);');
436 add(' } >vectors = 0xff');
437 add(' ');
438 add(' .sbss __dtcm_end (NOLOAD): ');
439 add(' {');
440 add(' __sbss_start = ABSOLUTE(.);');
441 add(' __sbss_start__ = ABSOLUTE(.);');
442 add(' *(.sbss)');
443 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
444 add(' __sbss_end = ABSOLUTE(.);');
445 add(' } >dtcm ');
446 add('');
447 add(' .bss __bss_vma (NOLOAD): ');
448 add(' {');
449 add(' __bss_start = ABSOLUTE(.);');
450 add(' __bss_start__ = ABSOLUTE(.);');
451 add(' *(.dynbss)');
452 add(' *(.gnu.linkonce.b*)');
453 add(' *(.bss*)');
454 add(' *(COMMON)');
455 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
456 add(' __bss_end__ = ABSOLUTE(.) ;');
457 add(' __end__ = ABSOLUTE(.) ;');
458 add(' } AT>ewram ');
459 add('');
460 add('');
461 add('');
462 add(' /* Stabs debugging sections. */');
463 add(' .stab 0 : { *(.stab) }');
464 add(' .stabstr 0 : { *(.stabstr) }');
465 add(' .stab.excl 0 : { *(.stab.excl) }');
466 add(' .stab.exclstr 0 : { *(.stab.exclstr) }');
467 add(' .stab.index 0 : { *(.stab.index) }');
468 add(' .stab.indexstr 0 : { *(.stab.indexstr) }');
469 add(' .comment 0 : { *(.comment) }');
470 add(' /* DWARF debug sections.');
471 add(' Symbols in the DWARF debugging sections are relative to the beginning');
472 add(' of the section so we begin them at 0. */');
473 add(' /* DWARF 1 */');
474 add(' .debug 0 : { *(.debug) }');
475 add(' .line 0 : { *(.line) }');
476 add(' /* GNU DWARF 1 extensions */');
477 add(' .debug_srcinfo 0 : { *(.debug_srcinfo) }');
478 add(' .debug_sfnames 0 : { *(.debug_sfnames) }');
479 add(' /* DWARF 1.1 and DWARF 2 */');
480 add(' .debug_aranges 0 : { *(.debug_aranges) }');
481 add(' .debug_pubnames 0 : { *(.debug_pubnames) }');
482 add(' /* DWARF 2 */');
483 add(' .debug_info 0 : { *(.debug_info) }');
484 add(' .debug_abbrev 0 : { *(.debug_abbrev) }');
485 add(' .debug_line 0 : { *(.debug_line) }');
486 add(' .debug_frame 0 : { *(.debug_frame) }');
487 add(' .debug_str 0 : { *(.debug_str) }');
488 add(' .debug_loc 0 : { *(.debug_loc) }');
489 add(' .debug_macinfo 0 : { *(.debug_macinfo) }');
490 add(' /* SGI/MIPS DWARF 2 extensions */');
491 add(' .debug_weaknames 0 : { *(.debug_weaknames) }');
492 add(' .debug_funcnames 0 : { *(.debug_funcnames) }');
493 add(' .debug_typenames 0 : { *(.debug_typenames) }');
494 add(' .debug_varnames 0 : { *(.debug_varnames) }');
495 add(' .stack 0x80000 : { _stack = .; *(.stack) }');
496 add(' /* These must appear regardless of . */');
497 add('}');
498 add('');
499 end;
500 if apptype=app_arm7 then
501 begin
502 add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
503 add('OUTPUT_ARCH(arm)');
504 add('ENTRY(_start)');
505 add('');
506 add('MEMORY {');
507 add('');
508 add(' rom : ORIGIN = 0x08000000, LENGTH = 32M');
509 add(' iwram : ORIGIN = 0x037f8000, LENGTH = 96K ');
510 add('}');
511 add('');
512 add('__iwram_start = ORIGIN(iwram);');
513 add('__iwram_top = ORIGIN(iwram)+ LENGTH(iwram);');
514 add('');
515 add('__sp_irq = __iwram_top - 0x100;');
516 add('__sp_svc = __sp_irq - 0x100;');
517 add('__sp_usr = __sp_svc - 0x100;');
518 add('');
519 add('__irq_flags = 0x04000000 - 8;');
520 add('__irq_flagsaux = 0x04000000 - 0x40;');
521 add('__irq_vector = 0x04000000 - 4;');
522 add('');
523 add('SECTIONS');
524 add('{');
525 add(' .init :');
526 add(' {');
527 add(' __text_start = . ;');
528 add(' KEEP (*(.init))');
529 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
530 add(' } >iwram = 0xff');
531 add(' .plt : { *(.plt) } >iwram = 0xff');
532 add('');
533 add(' .text : /* ALIGN (4): */');
534 add(' {');
535 add(' *(.text .stub .text.* .gnu.linkonce.t.*)');
536 add(' KEEP (*(.text.*personality*))');
537 add(' /* .gnu.warning sections are handled specially by elf32.em. */');
538 add(' *(.gnu.warning)');
539 add(' *(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
540 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
541 add(' } >iwram = 0xff');
542 add('');
543 add(' .fini :');
544 add(' {');
545 add(' KEEP (*(.fini))');
546 add(' } >iwram =0xff');
547 add('');
548 add(' __text_end = . ;');
549 add('');
550 add(' .rodata :');
551 add(' {');
552 add(' *(.rodata)');
553 add(' *all.rodata*(*)');
554 add(' *(.roda)');
555 add(' *(.rodata.*)');
556 add(' *(.gnu.linkonce.r*)');
557 add(' SORT(CONSTRUCTORS)');
558 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
559 add(' } >iwram = 0xff');
560 add('');
561 add(' .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >iwram');
562 add(' __exidx_start = .;');
563 add(' .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >iwram');
564 add(' __exidx_end = .;');
565 add('');
566 add('/* Ensure the __preinit_array_start label is properly aligned. We');
567 add(' could instead move the label definition inside the section, but');
568 add(' the linker would then create the section even if it turns out to');
569 add(' be empty, which isn''t pretty. */');
570 add(' . = ALIGN(32 / 8);');
571 add(' PROVIDE (__preinit_array_start = .);');
572 add(' .preinit_array : { KEEP (*(.preinit_array)) } >iwram = 0xff');
573 add(' PROVIDE (__preinit_array_end = .);');
574 add(' PROVIDE (__init_array_start = .);');
575 add(' .init_array : { KEEP (*(.init_array)) } >iwram = 0xff');
576 add(' PROVIDE (__init_array_end = .);');
577 add(' PROVIDE (__fini_array_start = .);');
578 add(' .fini_array : { KEEP (*(.fini_array)) } >iwram = 0xff');
579 add(' PROVIDE (__fini_array_end = .);');
580 add('');
581 add(' .ctors :');
582 add(' {');
583 add(' /* gcc uses crtbegin.o to find the start of the constructors, so');
584 add(' we make sure it is first. Because this is a wildcard, it');
585 add(' doesn''t matter if the user does not actually link against');
586 add(' crtbegin.o; the linker won''t look for a file to match a');
587 add(' wildcard. The wildcard also means that it doesn''t matter which');
588 add(' directory crtbegin.o is in. */');
589 add(' KEEP (*crtbegin.o(.ctors))');
590 add(' KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))');
591 add(' KEEP (*(SORT(.ctors.*)))');
592 add(' KEEP (*(.ctors))');
593 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
594 add(' } >iwram = 0xff');
595 add('');
596 add(' .dtors :');
597 add(' {');
598 add(' KEEP (*crtbegin.o(.dtors))');
599 add(' KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))');
600 add(' KEEP (*(SORT(.dtors.*)))');
601 add(' KEEP (*(.dtors))');
602 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
603 add(' } >iwram = 0xff');
604 add('');
605 add(' .eh_frame :');
606 add(' {');
607 add(' KEEP (*(.eh_frame))');
608 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
609 add(' } >iwram = 0xff');
610 add('');
611 add(' .gcc_except_table :');
612 add(' {');
613 add(' *(.gcc_except_table)');
614 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
615 add(' } >iwram = 0xff');
616 add(' .jcr : { KEEP (*(.jcr)) } >iwram = 0');
617 add(' .got : { *(.got.plt) *(.got) } >iwram = 0');
618 add('');
619 add(' .data ALIGN(4) : {');
620 add(' __data_start = ABSOLUTE(.);');
621 add(' *(.data)');
622 add(' *(.data.*)');
623 add(' *(.gnu.linkonce.d*)');
624 add(' CONSTRUCTORS');
625 add(' . = ALIGN(4);');
626 add(' __data_end = ABSOLUTE(.) ;');
627 add(' } >iwram = 0xff');
628 add('');
629 add(' .bss ALIGN(4) :');
630 add(' {');
631 add(' __bss_start = ABSOLUTE(.);');
632 add(' __bss_start__ = ABSOLUTE(.);');
633 add(' *(.dynbss)');
634 add(' *(.gnu.linkonce.b*)');
635 add(' *(.bss*)');
636 add(' *(COMMON)');
637 add(' . = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
638 add(' __bss_end__ = ABSOLUTE(.);');
639 add(' __end__ = ABSOLUTE(.);');
640 add(' } >iwram');
641 add('');
642 add(' /* Stabs debugging sections. */');
643 add(' .stab 0 : { *(.stab) }');
644 add(' .stabstr 0 : { *(.stabstr) }');
645 add(' .stab.excl 0 : { *(.stab.excl) }');
646 add(' .stab.exclstr 0 : { *(.stab.exclstr) }');
647 add(' .stab.index 0 : { *(.stab.index) }');
648 add(' .stab.indexstr 0 : { *(.stab.indexstr) }');
649 add(' .comment 0 : { *(.comment) }');
650 add(' /* DWARF debug sections.');
651 add(' Symbols in the DWARF debugging sections are relative to the beginning');
652 add(' of the section so we begin them at 0. */');
653 add(' /* DWARF 1 */');
654 add(' .debug 0 : { *(.debug) }');
655 add(' .line 0 : { *(.line) }');
656 add(' /* GNU DWARF 1 extensions */');
657 add(' .debug_srcinfo 0 : { *(.debug_srcinfo) }');
658 add(' .debug_sfnames 0 : { *(.debug_sfnames) }');
659 add(' /* DWARF 1.1 and DWARF 2 */');
660 add(' .debug_aranges 0 : { *(.debug_aranges) }');
661 add(' .debug_pubnames 0 : { *(.debug_pubnames) }');
662 add(' /* DWARF 2 */');
663 add(' .debug_info 0 : { *(.debug_info) }');
664 add(' .debug_abbrev 0 : { *(.debug_abbrev) }');
665 add(' .debug_line 0 : { *(.debug_line) }');
666 add(' .debug_frame 0 : { *(.debug_frame) }');
667 add(' .debug_str 0 : { *(.debug_str) }');
668 add(' .debug_loc 0 : { *(.debug_loc) }');
669 add(' .debug_macinfo 0 : { *(.debug_macinfo) }');
670 add(' /* SGI/MIPS DWARF 2 extensions */');
671 add(' .debug_weaknames 0 : { *(.debug_weaknames) }');
672 add(' .debug_funcnames 0 : { *(.debug_funcnames) }');
673 add(' .debug_typenames 0 : { *(.debug_typenames) }');
674 add(' .debug_varnames 0 : { *(.debug_varnames) }');
675 add(' .stack 0x80000 : { _stack = .; *(.stack) }');
676 add(' /* These must appear regardless of . */');
677 add('}');
678 end;
679 end;
680
681 { Write and Close response }
682 linkres.writetodisk;
683 linkres.free;
684
685 WriteResponseFile:=True;
686
687 end;
688
689
MakeExecutablenull690 function TLinkerNDS.MakeExecutable:boolean;
691 var
692 binstr,
693 cmdstr : TCmdStr;
694 success : boolean;
695 StaticStr,
696 GCSectionsStr,
697 DynLinkStr,
698 MapStr,
699 StripStr: string;
700 preName: string;
701 begin
702 { for future use }
703 StaticStr:='';
704 StripStr:='';
705 MapStr:='';
706 DynLinkStr:='';
707 GCSectionsStr:='';
708 preName:='';
709 case apptype of
710 app_arm9: preName:='.nef';
711 app_arm7: preName:='.nlf';
712 end;
713
714 if (cs_link_strip in current_settings.globalswitches) and
715 not(cs_link_separate_dbg_file in current_settings.globalswitches) then
716 StripStr:='-s';
717 if (cs_link_map in current_settings.globalswitches) then
718 StripStr:='-Map '+maybequoted(ChangeFileExt(current_module.exefilename,'.map'));
719 if create_smartlink_sections then
720 GCSectionsStr:='--gc-sections';
721 if not(cs_link_nolink in current_settings.globalswitches) then
722 Message1(exec_i_linking,current_module.exefilename);
723
724 { Write used files and libraries }
725 WriteResponseFile();
726
727 { Call linker }
728 SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
729 Replace(cmdstr,'$OPT',Info.ExtraOptions);
730
731 Replace(cmdstr,'$EXE',(maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename,preName)))));
732 Replace(cmdstr,'$RES',(maybequoted(ScriptFixFileName(outputexedir+Info.ResName))));
733 Replace(cmdstr,'$STATIC',StaticStr);
734 Replace(cmdstr,'$STRIP',StripStr);
735 Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
736 Replace(cmdstr,'$MAP',MapStr);
737 Replace(cmdstr,'$DYNLINK',DynLinkStr);
738
739 success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false);
740
741 { Remove ReponseFile }
742 if (success) and not(cs_link_nolink in current_settings.globalswitches) then
743 DeleteFile(outputexedir+Info.ResName);
744
745 { Post process }
746 if success then
747 begin
748 success:=DoExec(FindUtil(utilsprefix + 'objcopy'), '-O binary '+
749 ChangeFileExt(current_module.exefilename, preName) + ' ' +
750 ChangeFileExt(current_module.exefilename, preName+target_info.exeext),
751 true,false);
752 end;
753
754 if success and (apptype=app_arm9) then
755 begin
756 success:=DoExec(FindUtil('ndstool'), '-c ' +
757 ChangeFileExt(current_module.exefilename, '.nds') + ' -9 ' +
758 ChangeFileExt(current_module.exefilename, preName+target_info.exeext),
759 true,false);
760 end;
761 MakeExecutable:=success; { otherwise a recursive call to link method }
762 end;
763
764
765 {*****************************************************************************
766 Initialize
767 *****************************************************************************}
768
769 initialization
770 RegisterLinker(ld_nds,TLinkerNDS);
771 RegisterTarget(system_arm_nds_info);
772 end.
773