t_gba.pas 21 KB

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