t_nds.pas 27 KB

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