t_nds.pas 31 KB

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