t_gba.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  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_gba;
  19. {$i fpcdefs.inc}
  20. interface
  21. implementation
  22. uses
  23. SysUtils,
  24. cutils,cfileutils,cclasses,
  25. globtype,globals,systems,verbose,script,fmodule,i_gba,link;
  26. type
  27. TlinkerGBA=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. TLINKERGBA
  37. *****************************************************************************}
  38. Constructor TLinkerGba.Create;
  39. begin
  40. Inherited Create;
  41. SharedLibFiles.doubles:=true;
  42. StaticLibFiles.doubles:=true;
  43. end;
  44. procedure TLinkerGba.SetDefaultInfo;
  45. begin
  46. with Info do
  47. begin
  48. ExeCmd[1]:='ld -g $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE -T $RES';
  49. end;
  50. end;
  51. Function TLinkerGba.WriteResponseFile: Boolean;
  52. Var
  53. linkres : TLinkRes;
  54. i : longint;
  55. HPath : TCmdStrListItem;
  56. s,s1,s2 : TCmdStr;
  57. prtobj,
  58. cprtobj : string[80];
  59. linklibc : boolean;
  60. found1,
  61. found2 : boolean;
  62. begin
  63. WriteResponseFile:=False;
  64. linklibc:=(SharedLibFiles.Find('c')<>nil);
  65. prtobj:='prt0';
  66. cprtobj:='cprt0';
  67. if linklibc then
  68. prtobj:=cprtobj;
  69. { Open link.res file }
  70. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  71. { Write path to search libraries }
  72. HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
  73. while assigned(HPath) do
  74. begin
  75. s:=HPath.Str;
  76. if (cs_link_on_target in current_settings.globalswitches) then
  77. s:=ScriptFixFileName(s);
  78. LinkRes.Add('-L'+s);
  79. HPath:=TCmdStrListItem(HPath.Next);
  80. end;
  81. HPath:=TCmdStrListItem(LibrarySearchPath.First);
  82. while assigned(HPath) do
  83. begin
  84. s:=HPath.Str;
  85. if s<>'' then
  86. LinkRes.Add('SEARCH_DIR('+(maybequoted(s))+')');
  87. HPath:=TCmdStrListItem(HPath.Next);
  88. end;
  89. LinkRes.Add('INPUT (');
  90. { add objectfiles, start with prt0 always }
  91. //s:=FindObjectFile('prt0','',false);
  92. if prtobj<>'' then
  93. s:=FindObjectFile(prtobj,'',false);
  94. LinkRes.AddFileName(s);
  95. { try to add crti and crtbegin if linking to C }
  96. if linklibc then
  97. begin
  98. if librarysearchpath.FindFile('crtbegin.o',false,s) then
  99. LinkRes.AddFileName(s);
  100. if librarysearchpath.FindFile('crti.o',false,s) then
  101. LinkRes.AddFileName(s);
  102. end;
  103. while not ObjectFiles.Empty do
  104. begin
  105. s:=ObjectFiles.GetFirst;
  106. if s<>'' then
  107. begin
  108. { vlink doesn't use SEARCH_DIR for object files }
  109. if not(cs_link_on_target in current_settings.globalswitches) then
  110. s:=FindObjectFile(s,'',false);
  111. LinkRes.AddFileName((maybequoted(s)));
  112. end;
  113. end;
  114. { Write staticlibraries }
  115. if not StaticLibFiles.Empty then
  116. begin
  117. { vlink doesn't need, and doesn't support GROUP }
  118. if (cs_link_on_target in current_settings.globalswitches) then
  119. begin
  120. LinkRes.Add(')');
  121. LinkRes.Add('GROUP(');
  122. end;
  123. while not StaticLibFiles.Empty do
  124. begin
  125. S:=StaticLibFiles.GetFirst;
  126. LinkRes.AddFileName((maybequoted(s)));
  127. end;
  128. end;
  129. if (cs_link_on_target in current_settings.globalswitches) then
  130. begin
  131. LinkRes.Add(')');
  132. { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
  133. here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
  134. linklibc:=false;
  135. while not SharedLibFiles.Empty do
  136. begin
  137. S:=SharedLibFiles.GetFirst;
  138. if s<>'c' then
  139. begin
  140. i:=Pos(target_info.sharedlibext,S);
  141. if i>0 then
  142. Delete(S,i,255);
  143. LinkRes.Add('-l'+s);
  144. end
  145. else
  146. begin
  147. LinkRes.Add('-l'+s);
  148. linklibc:=true;
  149. end;
  150. end;
  151. { be sure that libc&libgcc is the last lib }
  152. if linklibc then
  153. begin
  154. LinkRes.Add('-lc');
  155. LinkRes.Add('-lgcc');
  156. end;
  157. end
  158. else
  159. begin
  160. while not SharedLibFiles.Empty do
  161. begin
  162. S:=SharedLibFiles.GetFirst;
  163. LinkRes.Add('lib'+s+target_info.staticlibext);
  164. end;
  165. LinkRes.Add(')');
  166. end;
  167. { objects which must be at the end }
  168. if linklibc then
  169. begin
  170. found1:=librarysearchpath.FindFile('crtend.o',false,s1);
  171. found2:=librarysearchpath.FindFile('crtn.o',false,s2);
  172. if found1 or found2 then
  173. begin
  174. LinkRes.Add('INPUT(');
  175. if found1 then
  176. LinkRes.AddFileName(s1);
  177. if found2 then
  178. LinkRes.AddFileName(s2);
  179. LinkRes.Add(')');
  180. end;
  181. end;
  182. with linkres do
  183. begin
  184. add('/* Linker Script Original v1.3 by Jeff Frohwein */');
  185. add('/* v1.0 - Original release */');
  186. add('/* v1.1 - Added proper .data section support */');
  187. add('/* v1.2 - Added support for c++ & iwram overlays */');
  188. add('/* - Major contributions by Jason Wilkins. */');
  189. add('/* v1.3 - .ewram section now can be used when */');
  190. add('/* compiling for MULTIBOOT mode. This fixes */');
  191. add('/* malloc() in DevKitAdvance which depends */');
  192. add('/* on __eheap_start instead of end to define*/');
  193. add('/* the starting location of heap space. */');
  194. add('/* External global variable __gba_iwram_heap*/');
  195. add('/* support added to allow labels end, _end, */');
  196. add('/* & __end__ to point to end of iwram or */');
  197. add('/* the end of ewram. */');
  198. add('/* Additions by WinterMute */');
  199. add('/* v1.4 - .sbss section added for unitialised */');
  200. add('/* data in ewram */');
  201. add('/* v1.5 - padding section added to stop EZF */');
  202. add('/* stripping important data */');
  203. add('');
  204. add('/* This file is released into the public domain */');
  205. add('/* for commercial or non-commercial use with no */');
  206. add('/* restrictions placed upon it. */');
  207. add('');
  208. add('/* NOTE!!!: This linker script defines the RAM & */');
  209. add('/* ROM start addresses. In order for it to work */');
  210. add('/* properly, remove -Ttext and -Tbss linker */');
  211. add('/* options from your makefile if they are */');
  212. add('/* present. */');
  213. add('');
  214. add('/* You can use the following to view section */');
  215. add('/* addresses in your .elf file: */');
  216. add('/* objdump -h file.elf */');
  217. add('/* Please note that empty sections may incorrectly*/');
  218. add('/* list the lma address as the vma address for */');
  219. add('/* some versions of objdump. */');
  220. add('');
  221. add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")');
  222. add('OUTPUT_ARCH(arm)');
  223. add('ENTRY(_start)');
  224. add('/* SEARCH_DIR(/bin/arm); */');
  225. add('');
  226. add('/* The linker script function "var1 += var2;" sometimes */');
  227. add('/* reports incorrect values in the *.map file but the */');
  228. add('/* actual value it calculates is usually, if not always, */');
  229. add('/* correct. If you leave out the ". = ALIGN(4);" at the */');
  230. add('/* end of each section then the return value of SIZEOF() */');
  231. add('/* is sometimes incorrect and "var1 += var2;" appears to */');
  232. add('/* not work as well. "var1 += var2" style functions are */');
  233. add('/* avoided below as a result. */');
  234. add('');
  235. add('MEMORY {');
  236. add('');
  237. add('rom : ORIGIN = 0x08000000, LENGTH = 32M');
  238. add('iwram : ORIGIN = 0x03000000, LENGTH = 32K');
  239. add('ewram : ORIGIN = 0x02000000, LENGTH = 256K');
  240. add('}');
  241. add('');
  242. add('/*');
  243. add('__text_start = 0x8000000;');
  244. add('__eheap_end = 0x2040000;');
  245. add('__iwram_start = 0x3000000;');
  246. add('__iwram_end = 0x3008000;');
  247. add('');
  248. add('__sp_irq = __iwram_end - 0x100;');
  249. add('__sp_usr = __sp_irq - 0x100;');
  250. add('*/');
  251. add('__text_start = ORIGIN(rom);');
  252. add('/* __eheap_end = ORIGIN(ewram) + 0x40000; */');
  253. add('__eheap_end = ORIGIN(ewram) + LENGTH(ewram);');
  254. add('__iwram_start = ORIGIN(iwram);');
  255. add('/* __iwram_end = ORIGIN(iwram) + 0x8000; */');
  256. add('__iwram_end = ORIGIN(iwram) + LENGTH(iwram); ');
  257. add('__sp_irq = __iwram_end - 0x100;');
  258. add('__sp_usr = __sp_irq - 0x100;');
  259. add('');
  260. add('');
  261. add('SECTIONS');
  262. add('{');
  263. add('. = __text_start;');
  264. add('.init :');
  265. add('{');
  266. add('KEEP (*(.init))');
  267. add('. = ALIGN(4);');
  268. add('} >rom =0xff');
  269. add('');
  270. add('.plt :');
  271. add('{');
  272. add('*(.plt)');
  273. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  274. add('} >rom');
  275. add('');
  276. add('.text : /* ALIGN (4): */');
  277. add('{');
  278. add('*(EXCLUDE_FILE (*.iwram*) .text)');
  279. add('*(.text.*)');
  280. add('*(.stub)');
  281. add('/* .gnu.warning sections are handled specially by elf32.em. */');
  282. add('*(.gnu.warning)');
  283. add('*(.gnu.linkonce.t*)');
  284. add('*(.glue_7)');
  285. add('*(.glue_7t)');
  286. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  287. add('} >rom = 0xff');
  288. add('');
  289. add('__text_end = .;');
  290. add('.fini :');
  291. add('{');
  292. add('KEEP (*(.fini))');
  293. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  294. add('} >rom =0');
  295. add('');
  296. add('.rodata :');
  297. add('{');
  298. add('*(.rodata)');
  299. add('*all.rodata*(*)');
  300. add('*(.roda)');
  301. add('*(.rodata.*)');
  302. add('*(.gnu.linkonce.r*)');
  303. add('SORT(CONSTRUCTORS)');
  304. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  305. add('} >rom = 0xff');
  306. add('');
  307. add('.ctors :');
  308. add('{');
  309. add('/* gcc uses crtbegin.o to find the start of the constructors, so');
  310. add('we make sure it is first. Because this is a wildcard, it');
  311. add('doesn''t matter if the user does not actually link against');
  312. add('crtbegin.o; the linker won''t look for a file to match a');
  313. add('wildcard. The wildcard also means that it doesn''t matter which');
  314. add('directory crtbegin.o is in. */');
  315. add('KEEP (*crtbegin.o(.ctors))');
  316. add('KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))');
  317. add('KEEP (*(SORT(.ctors.*)))');
  318. add('KEEP (*(.ctors))');
  319. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  320. add('} >rom = 0');
  321. add('');
  322. add('.dtors :');
  323. add('{');
  324. add('KEEP (*crtbegin.o(.dtors))');
  325. add('KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))');
  326. add('KEEP (*(SORT(.dtors.*)))');
  327. add('KEEP (*(.dtors))');
  328. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  329. add('} >rom = 0');
  330. add('');
  331. add('.jcr : { KEEP (*(.jcr)) } >rom ');
  332. add('');
  333. add('.eh_frame :');
  334. add('{');
  335. add('KEEP (*(.eh_frame))');
  336. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  337. add('} >rom = 0');
  338. add('');
  339. add('.gcc_except_table :');
  340. add('{');
  341. add('*(.gcc_except_table)');
  342. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  343. add('} >rom = 0');
  344. add('');
  345. add('__iwram_lma = .;');
  346. add('');
  347. add('.iwram __iwram_start : AT (__iwram_lma)');
  348. add('{');
  349. add('__iwram_start = ABSOLUTE(.) ;');
  350. add('*(.iwram)');
  351. add('*iwram.*(.text)');
  352. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  353. add('} >iwram = 0xff');
  354. add('');
  355. add('__data_lma = __iwram_lma + SIZEOF(.iwram) ;');
  356. add('__iwram_end = . ;');
  357. add('');
  358. add('.bss ALIGN(4) :');
  359. add('{');
  360. add('__bss_start = ABSOLUTE(.);');
  361. add('__bss_start__ = ABSOLUTE(.);');
  362. add('*(.dynbss)');
  363. add('*(.gnu.linkonce.b*)');
  364. add('*(.bss*)');
  365. add('*(COMMON)');
  366. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  367. add('} >iwram');
  368. add('');
  369. add('__bss_end = . ;');
  370. add('__bss_end__ = . ;');
  371. add('');
  372. add('.data ALIGN(4) : AT (__data_lma)');
  373. add('{');
  374. add('__data_start = ABSOLUTE(.);');
  375. add('*(.data)');
  376. add('*(.data.*)');
  377. add('*(.gnu.linkonce.d*)');
  378. add('*(.fpc*)');
  379. add('CONSTRUCTORS');
  380. add('. = ALIGN(4);');
  381. add('} >iwram = 0xff');
  382. add('');
  383. add('__iwram_overlay_lma = __data_lma + SIZEOF(.data);');
  384. add('');
  385. add('__data_end = .;');
  386. add('__iwram_overlay_start = . ;');
  387. add('');
  388. add('OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma)');
  389. add('{');
  390. add('.iwram0 { *(.iwram0) . = ALIGN(4);}');
  391. add('.iwram1 { *(.iwram1) . = ALIGN(4);}');
  392. add('.iwram2 { *(.iwram2) . = ALIGN(4);}');
  393. add('.iwram3 { *(.iwram3) . = ALIGN(4);}');
  394. add('.iwram4 { *(.iwram4) . = ALIGN(4);}');
  395. add('.iwram5 { *(.iwram5) . = ALIGN(4);}');
  396. add('.iwram6 { *(.iwram6) . = ALIGN(4);}');
  397. add('.iwram7 { *(.iwram7) . = ALIGN(4);}');
  398. add('.iwram8 { *(.iwram8) . = ALIGN(4);}');
  399. add('.iwram9 { *(.iwram9) . = ALIGN(4);}');
  400. add('}>iwram = 0xff');
  401. add('');
  402. add('__ewram_lma = LOADADDR(.iwram0) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9);');
  403. add('');
  404. add('__iwram_overlay_end = . ;');
  405. add('__iheap_start = . ;');
  406. add('');
  407. add('__ewram_start = 0x2000000;');
  408. add('.ewram __ewram_start : AT (__ewram_lma)');
  409. add('{');
  410. add('*(.ewram)');
  411. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  412. add('}>ewram = 0xff');
  413. add('');
  414. add('__ewram_overlay_lma = __ewram_lma + SIZEOF(.ewram);');
  415. add('');
  416. add('.sbss ALIGN(4):');
  417. add('{');
  418. add('__sbss_start = ABSOLUTE(.);');
  419. add('*(.sbss)');
  420. add('. = ALIGN(4);');
  421. add('} >ewram');
  422. add(' ');
  423. add('__sbss_end = .;');
  424. add('');
  425. add('__ewram_end = . ;');
  426. add('__ewram_overlay_start = . ;');
  427. add('');
  428. add('OVERLAY ALIGN(4): NOCROSSREFS AT (__ewram_overlay_lma)');
  429. add('{');
  430. add('.ewram0 { *(.ewram0) . = ALIGN(4);}');
  431. add('.ewram1 { *(.ewram1) . = ALIGN(4);}');
  432. add('.ewram2 { *(.ewram2) . = ALIGN(4);}');
  433. add('.ewram3 { *(.ewram3) . = ALIGN(4);}');
  434. add('.ewram4 { *(.ewram4) . = ALIGN(4);}');
  435. add('.ewram5 { *(.ewram5) . = ALIGN(4);}');
  436. add('.ewram6 { *(.ewram6) . = ALIGN(4);}');
  437. add('.ewram7 { *(.ewram7) . = ALIGN(4);}');
  438. add('.ewram8 { *(.ewram8) . = ALIGN(4);}');
  439. add('.ewram9 { *(.ewram9) . = ALIGN(4);}');
  440. add('}>ewram = 0xff');
  441. add('');
  442. add('__pad_lma = LOADADDR(.ewram0) + SIZEOF(.ewram0)+SIZEOF(.ewram1)+SIZEOF(.ewram2)+SIZEOF(.ewram3)+SIZEOF(.ewram4)+SIZEOF(.ewram5)+SIZEOF(.ewram6)+SIZEOF(.ewram7)+SIZEOF(.ewram8)+SIZEOF(.ewram9);');
  443. add('');
  444. add('/* EZF Advance strips trailing 0xff bytes, add a pad section so nothing important is removed */');
  445. add('.pad ALIGN(4) : AT (__pad_lma)');
  446. add('{');
  447. add('LONG(0x52416b64)');
  448. add('LONG(0x4d)');
  449. add('. = ALIGN(4); /* REQUIRED. LD is flaky without it. */');
  450. add('} = 0xff');
  451. add('');
  452. add('__ewram_overlay_end = . ;');
  453. add('__eheap_start = . ;');
  454. add('');
  455. add('_end = .;');
  456. add('__end__ = _end ; /* v1.3 */');
  457. add('PROVIDE (end = _end); /* v1.3 */');
  458. add('');
  459. add('/* Stabs debugging sections. */');
  460. add('.stab 0 : { *(.stab) }');
  461. add('.stabstr 0 : { *(.stabstr) }');
  462. add('.stab.excl 0 : { *(.stab.excl) }');
  463. add('.stab.exclstr 0 : { *(.stab.exclstr) }');
  464. add('.stab.index 0 : { *(.stab.index) }');
  465. add('.stab.indexstr 0 : { *(.stab.indexstr) }');
  466. add('.comment 0 : { *(.comment) }');
  467. add('/* DWARF debug sections.');
  468. add('Symbols in the DWARF debugging sections are relative to the beginning');
  469. add('of the section so we begin them at 0. */');
  470. add('/* DWARF 1 */');
  471. add('.debug 0 : { *(.debug) }');
  472. add('.line 0 : { *(.line) }');
  473. add('/* GNU DWARF 1 extensions */');
  474. add('.debug_srcinfo 0 : { *(.debug_srcinfo) }');
  475. add('.debug_sfnames 0 : { *(.debug_sfnames) }');
  476. add('/* DWARF 1.1 and DWARF 2 */');
  477. add('.debug_aranges 0 : { *(.debug_aranges) }');
  478. add('.debug_pubnames 0 : { *(.debug_pubnames) }');
  479. add('/* DWARF 2 */');
  480. add('.debug_info 0 : { *(.debug_info) }');
  481. add('.debug_abbrev 0 : { *(.debug_abbrev) }');
  482. add('.debug_line 0 : { *(.debug_line) }');
  483. add('.debug_frame 0 : { *(.debug_frame) }');
  484. add('.debug_str 0 : { *(.debug_str) }');
  485. add('.debug_loc 0 : { *(.debug_loc) }');
  486. add('.debug_macinfo 0 : { *(.debug_macinfo) }');
  487. add('/* SGI/MIPS DWARF 2 extensions */');
  488. add('.debug_weaknames 0 : { *(.debug_weaknames) }');
  489. add('.debug_funcnames 0 : { *(.debug_funcnames) }');
  490. add('.debug_typenames 0 : { *(.debug_typenames) }');
  491. add('.debug_varnames 0 : { *(.debug_varnames) }');
  492. add('.stack 0x80000 : { _stack = .; *(.stack) }');
  493. add('/* These must appear regardless of . */');
  494. add('}');
  495. end;
  496. { Write and Close response }
  497. linkres.writetodisk;
  498. linkres.free;
  499. WriteResponseFile:=True;
  500. end;
  501. function TLinkerGba.MakeExecutable:boolean;
  502. var
  503. binstr : string;
  504. cmdstr : TCmdStr;
  505. success : boolean;
  506. StaticStr,
  507. GCSectionsStr,
  508. DynLinkStr,
  509. StripStr: string;
  510. begin
  511. { for future use }
  512. StaticStr:='';
  513. StripStr:='';
  514. DynLinkStr:='';
  515. GCSectionsStr:='--gc-sections';
  516. //if not(cs_link_extern in current_settings.globalswitches) then
  517. if not(cs_link_nolink in current_settings.globalswitches) then
  518. Message1(exec_i_linking,current_module.exefilename^);
  519. { Write used files and libraries }
  520. WriteResponseFile();
  521. { Call linker }
  522. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  523. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  524. if not(cs_link_on_target in current_settings.globalswitches) then
  525. begin
  526. Replace(cmdstr,'$EXE',(maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename^,'.elf')))));
  527. Replace(cmdstr,'$RES',(maybequoted(ScriptFixFileName(outputexedir+Info.ResName))));
  528. Replace(cmdstr,'$STATIC',StaticStr);
  529. Replace(cmdstr,'$STRIP',StripStr);
  530. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  531. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  532. end
  533. else
  534. begin
  535. Replace(cmdstr,'$EXE',maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename^,'.elf'))));
  536. Replace(cmdstr,'$RES',maybequoted(ScriptFixFileName(outputexedir+Info.ResName)));
  537. Replace(cmdstr,'$STATIC',StaticStr);
  538. Replace(cmdstr,'$STRIP',StripStr);
  539. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  540. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  541. end;
  542. success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false);
  543. { Remove ReponseFile }
  544. if (success) and not(cs_link_nolink in current_settings.globalswitches) then
  545. DeleteFile(outputexedir+Info.ResName);
  546. { Post process }
  547. if success then
  548. begin
  549. success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O binary '+
  550. ChangeFileExt(current_module.exefilename^,'.elf')+' '+
  551. current_module.exefilename^,true,false);
  552. end;
  553. MakeExecutable:=success; { otherwise a recursive call to link method }
  554. end;
  555. {*****************************************************************************
  556. Initialize
  557. *****************************************************************************}
  558. initialization
  559. RegisterExternalLinker(system_arm_gba_info,TLinkerGba);
  560. RegisterTarget(system_arm_gba_info);
  561. end.