t_embed.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  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_embed;
  19. {$i fpcdefs.inc}
  20. interface
  21. implementation
  22. uses
  23. SysUtils,
  24. cutils,cfileutl,cclasses,
  25. globtype,globals,systems,verbose,script,fmodule,i_embed,link,
  26. cpuinfo;
  27. type
  28. TlinkerEmbedded=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. TlinkerEmbedded
  38. *****************************************************************************}
  39. Constructor TlinkerEmbedded.Create;
  40. begin
  41. Inherited Create;
  42. SharedLibFiles.doubles:=true;
  43. StaticLibFiles.doubles:=true;
  44. end;
  45. procedure TlinkerEmbedded.SetDefaultInfo;
  46. begin
  47. with Info do
  48. begin
  49. ExeCmd[1]:='ld -g $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE -T $RES';
  50. end;
  51. end;
  52. Function TlinkerEmbedded.WriteResponseFile: Boolean;
  53. Var
  54. linkres : TLinkRes;
  55. i : longint;
  56. HPath : TCmdStrListItem;
  57. s,s1,s2 : TCmdStr;
  58. prtobj,
  59. cprtobj : string[80];
  60. linklibc : boolean;
  61. found1,
  62. found2 : boolean;
  63. {$ifdef AVR32}
  64. flashsize,ramsize: longword;
  65. {$endif AVR32}
  66. begin
  67. WriteResponseFile:=False;
  68. linklibc:=(SharedLibFiles.Find('c')<>nil);
  69. {$if defined(ARM) or defined(i386) or defined(AVR) or defined(AVR32)}
  70. prtobj:='';
  71. {$else}
  72. prtobj:='prt0';
  73. {$endif}
  74. cprtobj:='cprt0';
  75. if linklibc then
  76. prtobj:=cprtobj;
  77. { Open link.res file }
  78. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  79. { Write path to search libraries }
  80. HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
  81. while assigned(HPath) do
  82. begin
  83. s:=HPath.Str;
  84. if (cs_link_on_target in current_settings.globalswitches) then
  85. s:=ScriptFixFileName(s);
  86. LinkRes.Add('-L'+s);
  87. HPath:=TCmdStrListItem(HPath.Next);
  88. end;
  89. HPath:=TCmdStrListItem(LibrarySearchPath.First);
  90. while assigned(HPath) do
  91. begin
  92. s:=HPath.Str;
  93. if s<>'' then
  94. LinkRes.Add('SEARCH_DIR('+(maybequoted(s))+')');
  95. HPath:=TCmdStrListItem(HPath.Next);
  96. end;
  97. LinkRes.Add('INPUT (');
  98. { add objectfiles, start with prt0 always }
  99. //s:=FindObjectFile('prt0','',false);
  100. if prtobj<>'' then
  101. begin
  102. s:=FindObjectFile(prtobj,'',false);
  103. LinkRes.AddFileName(s);
  104. end;
  105. { try to add crti and crtbegin if linking to C }
  106. if linklibc then
  107. begin
  108. if librarysearchpath.FindFile('crtbegin.o',false,s) then
  109. LinkRes.AddFileName(s);
  110. if librarysearchpath.FindFile('crti.o',false,s) then
  111. LinkRes.AddFileName(s);
  112. end;
  113. while not ObjectFiles.Empty do
  114. begin
  115. s:=ObjectFiles.GetFirst;
  116. if s<>'' then
  117. begin
  118. { vlink doesn't use SEARCH_DIR for object files }
  119. if not(cs_link_on_target in current_settings.globalswitches) then
  120. s:=FindObjectFile(s,'',false);
  121. LinkRes.AddFileName((maybequoted(s)));
  122. end;
  123. end;
  124. { Write staticlibraries }
  125. if not StaticLibFiles.Empty then
  126. begin
  127. { vlink doesn't need, and doesn't support GROUP }
  128. if (cs_link_on_target in current_settings.globalswitches) then
  129. begin
  130. LinkRes.Add(')');
  131. LinkRes.Add('GROUP(');
  132. end;
  133. while not StaticLibFiles.Empty do
  134. begin
  135. S:=StaticLibFiles.GetFirst;
  136. LinkRes.AddFileName((maybequoted(s)));
  137. end;
  138. end;
  139. if (cs_link_on_target in current_settings.globalswitches) then
  140. begin
  141. LinkRes.Add(')');
  142. { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
  143. here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
  144. linklibc:=false;
  145. while not SharedLibFiles.Empty do
  146. begin
  147. S:=SharedLibFiles.GetFirst;
  148. if s<>'c' then
  149. begin
  150. i:=Pos(target_info.sharedlibext,S);
  151. if i>0 then
  152. Delete(S,i,255);
  153. LinkRes.Add('-l'+s);
  154. end
  155. else
  156. begin
  157. LinkRes.Add('-l'+s);
  158. linklibc:=true;
  159. end;
  160. end;
  161. { be sure that libc&libgcc is the last lib }
  162. if linklibc then
  163. begin
  164. LinkRes.Add('-lc');
  165. LinkRes.Add('-lgcc');
  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 linklibc then
  179. begin
  180. found1:=librarysearchpath.FindFile('crtend.o',false,s1);
  181. found2:=librarysearchpath.FindFile('crtn.o',false,s2);
  182. if found1 or found2 then
  183. begin
  184. LinkRes.Add('INPUT(');
  185. if found1 then
  186. LinkRes.AddFileName(s1);
  187. if found2 then
  188. LinkRes.AddFileName(s2);
  189. LinkRes.Add(')');
  190. end;
  191. end;
  192. {$ifdef ARM}
  193. case current_settings.controllertype of
  194. ct_none:
  195. ;
  196. ct_lpc2114,
  197. ct_lpc2124,
  198. ct_lpc2194:
  199. with linkres do
  200. begin
  201. Add('ENTRY(_START)');
  202. Add('MEMORY');
  203. Add('{');
  204. Add(' flash : ORIGIN = 0, LENGTH = 256K');
  205. Add(' ram : ORIGIN = 0x40000000, LENGTH = 16K');
  206. Add('}');
  207. Add('_stack_top = 0x40003FFC;');
  208. end;
  209. ct_at91sam7s256,
  210. ct_at91sam7se256,
  211. ct_at91sam7x256,
  212. ct_at91sam7xc256:
  213. with linkres do
  214. begin
  215. Add('ENTRY(_START)');
  216. Add('MEMORY');
  217. Add('{');
  218. Add(' flash : ORIGIN = 0, LENGTH = 256K');
  219. Add(' ram : ORIGIN = 0x200000, LENGTH = 64K');
  220. Add('}');
  221. Add('_stack_top = 0x20FFFC;');
  222. end;
  223. ct_stm32f103re:
  224. with linkres do
  225. begin
  226. Add('ENTRY(_START)');
  227. Add('MEMORY');
  228. Add('{');
  229. Add(' flash : ORIGIN = 0x08000000, LENGTH = 512K');
  230. Add(' ram : ORIGIN = 0x20000000, LENGTH = 64K');
  231. Add('}');
  232. Add('_stack_top = 0x2000FFFC;');
  233. end;
  234. else
  235. internalerror(200902011);
  236. end;
  237. with linkres do
  238. begin
  239. Add('SECTIONS');
  240. Add('{');
  241. Add(' .text :');
  242. Add(' {');
  243. Add(' KEEP(*(.init, .init.*))');
  244. Add(' *(.text, .text.*)');
  245. Add(' *(.strings)');
  246. Add(' *(.rodata, .rodata.*)');
  247. Add(' *(.comment)');
  248. Add(' _etext = .;');
  249. Add(' } >flash');
  250. Add(' .data :');
  251. Add(' {');
  252. Add(' _data = .;');
  253. Add(' *(.data, .data.*)');
  254. Add(' KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
  255. Add(' _edata = .;');
  256. Add(' } >ram AT >flash');
  257. Add(' .bss :');
  258. Add(' {');
  259. Add(' _bss_start = .;');
  260. Add(' *(.bss, .bss.*)');
  261. Add(' *(COMMON)');
  262. Add(' } >ram');
  263. Add('. = ALIGN(4);');
  264. Add('_bss_end = . ;');
  265. Add('}');
  266. Add('_end = .;');
  267. end;
  268. {$endif ARM}
  269. {$ifdef i386}
  270. with linkres do
  271. begin
  272. Add('ENTRY(_START)');
  273. Add('SECTIONS');
  274. Add('{');
  275. Add(' . = 0x100000;');
  276. Add(' .text ALIGN (0x1000) :');
  277. Add(' {');
  278. Add(' KEEP(*(.init, .init.*))');
  279. Add(' *(.text, .text.*)');
  280. Add(' *(.strings)');
  281. Add(' *(.rodata, .rodata.*)');
  282. Add(' *(.comment)');
  283. Add(' _etext = .;');
  284. Add(' }');
  285. Add(' .data ALIGN (0x1000) :');
  286. Add(' {');
  287. Add(' _data = .;');
  288. Add(' *(.data, .data.*)');
  289. Add(' KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
  290. Add(' _edata = .;');
  291. Add(' }');
  292. Add(' . = ALIGN(4);');
  293. Add(' .bss :');
  294. Add(' {');
  295. Add(' _bss_start = .;');
  296. Add(' *(.bss, .bss.*)');
  297. Add(' *(COMMON)');
  298. Add(' }');
  299. Add('_bss_end = . ;');
  300. Add('}');
  301. Add('_end = .;');
  302. end;
  303. {$endif i386}
  304. {$ifdef AVR}
  305. with linkres do
  306. begin
  307. { linker script from ld 2.19 }
  308. Add('ENTRY(_START)');
  309. Add('OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")');
  310. Add('OUTPUT_ARCH(avr:2)');
  311. Add('MEMORY');
  312. Add('{');
  313. Add(' text (rx) : ORIGIN = 0, LENGTH = 8K');
  314. Add(' data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0');
  315. Add(' eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K');
  316. Add(' fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K');
  317. Add(' lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K');
  318. Add(' signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K');
  319. Add('}');
  320. Add('SECTIONS');
  321. Add('{');
  322. Add(' /* Read-only sections, merged into text segment: */');
  323. Add(' .hash : { *(.hash) }');
  324. Add(' .dynsym : { *(.dynsym) }');
  325. Add(' .dynstr : { *(.dynstr) }');
  326. Add(' .gnu.version : { *(.gnu.version) }');
  327. Add(' .gnu.version_d : { *(.gnu.version_d) }');
  328. Add(' .gnu.version_r : { *(.gnu.version_r) }');
  329. Add(' .rel.init : { *(.rel.init) }');
  330. Add(' .rela.init : { *(.rela.init) }');
  331. Add(' .rel.text :');
  332. Add(' {');
  333. Add(' *(.rel.text)');
  334. Add(' *(.rel.text.*)');
  335. Add(' *(.rel.gnu.linkonce.t*)');
  336. Add(' }');
  337. Add(' .rela.text :');
  338. Add(' {');
  339. Add(' *(.rela.text)');
  340. Add(' *(.rela.text.*)');
  341. Add(' *(.rela.gnu.linkonce.t*)');
  342. Add(' }');
  343. Add(' .rel.fini : { *(.rel.fini) }');
  344. Add(' .rela.fini : { *(.rela.fini) }');
  345. Add(' .rel.rodata :');
  346. Add(' {');
  347. Add(' *(.rel.rodata)');
  348. Add(' *(.rel.rodata.*)');
  349. Add(' *(.rel.gnu.linkonce.r*)');
  350. Add(' }');
  351. Add(' .rela.rodata :');
  352. Add(' {');
  353. Add(' *(.rela.rodata)');
  354. Add(' *(.rela.rodata.*)');
  355. Add(' *(.rela.gnu.linkonce.r*)');
  356. Add(' }');
  357. Add(' .rel.data :');
  358. Add(' {');
  359. Add(' *(.rel.data)');
  360. Add(' *(.rel.data.*)');
  361. Add(' *(.rel.gnu.linkonce.d*)');
  362. Add(' }');
  363. Add(' .rela.data :');
  364. Add(' {');
  365. Add(' *(.rela.data)');
  366. Add(' *(.rela.data.*)');
  367. Add(' *(.rela.gnu.linkonce.d*)');
  368. Add(' }');
  369. Add(' .rel.ctors : { *(.rel.ctors) }');
  370. Add(' .rela.ctors : { *(.rela.ctors) }');
  371. Add(' .rel.dtors : { *(.rel.dtors) }');
  372. Add(' .rela.dtors : { *(.rela.dtors) }');
  373. Add(' .rel.got : { *(.rel.got) }');
  374. Add(' .rela.got : { *(.rela.got) }');
  375. Add(' .rel.bss : { *(.rel.bss) }');
  376. Add(' .rela.bss : { *(.rela.bss) }');
  377. Add(' .rel.plt : { *(.rel.plt) }');
  378. Add(' .rela.plt : { *(.rela.plt) }');
  379. Add(' /* Internal text space or external memory. */');
  380. Add(' .text :');
  381. Add(' {');
  382. Add(' *(.vectors)');
  383. Add(' KEEP(*(.vectors))');
  384. Add(' /* For data that needs to reside in the lower 64k of progmem. */');
  385. Add(' *(.progmem.gcc*)');
  386. Add(' *(.progmem*)');
  387. Add(' . = ALIGN(2);');
  388. Add(' __trampolines_start = . ;');
  389. Add(' /* The jump trampolines for the 16-bit limited relocs will reside here. */');
  390. Add(' *(.trampolines)');
  391. Add(' *(.trampolines*)');
  392. Add(' __trampolines_end = . ;');
  393. Add(' /* For future tablejump instruction arrays for 3 byte pc devices.');
  394. Add(' We don''t relax jump/call instructions within these sections. */');
  395. Add(' *(.jumptables)');
  396. Add(' *(.jumptables*)');
  397. Add(' /* For code that needs to reside in the lower 128k progmem. */');
  398. Add(' *(.lowtext)');
  399. Add(' *(.lowtext*)');
  400. Add(' __ctors_start = . ;');
  401. Add(' *(.ctors)');
  402. Add(' __ctors_end = . ;');
  403. Add(' __dtors_start = . ;');
  404. Add(' *(.dtors)');
  405. Add(' __dtors_end = . ;');
  406. Add(' KEEP(SORT(*)(.ctors))');
  407. Add(' KEEP(SORT(*)(.dtors))');
  408. Add(' /* From this point on, we don''t bother about wether the insns are');
  409. Add(' below or above the 16 bits boundary. */');
  410. Add(' *(.init0) /* Start here after reset. */');
  411. Add(' KEEP (*(.init0))');
  412. Add(' *(.init1)');
  413. Add(' KEEP (*(.init1))');
  414. Add(' *(.init2) /* Clear __zero_reg__, set up stack pointer. */');
  415. Add(' KEEP (*(.init2))');
  416. Add(' *(.init3)');
  417. Add(' KEEP (*(.init3))');
  418. Add(' *(.init4) /* Initialize data and BSS. */');
  419. Add(' KEEP (*(.init4))');
  420. Add(' *(.init5)');
  421. Add(' KEEP (*(.init5))');
  422. Add(' *(.init6) /* C++ constructors. */');
  423. Add(' KEEP (*(.init6))');
  424. Add(' *(.init7)');
  425. Add(' KEEP (*(.init7))');
  426. Add(' *(.init8)');
  427. Add(' KEEP (*(.init8))');
  428. Add(' *(.init9) /* Call main(). */');
  429. Add(' KEEP (*(.init9))');
  430. Add(' *(.text)');
  431. Add(' . = ALIGN(2);');
  432. Add(' *(.text.*)');
  433. Add(' . = ALIGN(2);');
  434. Add(' *(.fini9) /* _exit() starts here. */');
  435. Add(' KEEP (*(.fini9))');
  436. Add(' *(.fini8)');
  437. Add(' KEEP (*(.fini8))');
  438. Add(' *(.fini7)');
  439. Add(' KEEP (*(.fini7))');
  440. Add(' *(.fini6) /* C++ destructors. */');
  441. Add(' KEEP (*(.fini6))');
  442. Add(' *(.fini5)');
  443. Add(' KEEP (*(.fini5))');
  444. Add(' *(.fini4)');
  445. Add(' KEEP (*(.fini4))');
  446. Add(' *(.fini3)');
  447. Add(' KEEP (*(.fini3))');
  448. Add(' *(.fini2)');
  449. Add(' KEEP (*(.fini2))');
  450. Add(' *(.fini1)');
  451. Add(' KEEP (*(.fini1))');
  452. Add(' *(.fini0) /* Infinite loop after program termination. */');
  453. Add(' KEEP (*(.fini0))');
  454. Add(' _etext = . ;');
  455. Add(' } > text');
  456. Add(' .data : AT (ADDR (.text) + SIZEOF (.text))');
  457. Add(' {');
  458. Add(' PROVIDE (__data_start = .) ;');
  459. Add(' *(.data)');
  460. Add(' *(.data*)');
  461. Add(' *(.rodata) /* We need to include .rodata here if gcc is used */');
  462. Add(' *(.rodata*) /* with -fdata-sections. */');
  463. Add(' *(.gnu.linkonce.d*)');
  464. Add(' . = ALIGN(2);');
  465. Add(' _edata = . ;');
  466. Add(' PROVIDE (__data_end = .) ;');
  467. Add(' } > data');
  468. Add(' .bss : AT (ADDR (.bss))');
  469. Add(' {');
  470. Add(' PROVIDE (__bss_start = .) ;');
  471. Add(' *(.bss)');
  472. Add(' *(.bss*)');
  473. Add(' *(COMMON)');
  474. Add(' PROVIDE (__bss_end = .) ;');
  475. Add(' } > data');
  476. Add(' __data_load_start = LOADADDR(.data);');
  477. Add(' __data_load_end = __data_load_start + SIZEOF(.data);');
  478. Add(' /* Global data not cleared after reset. */');
  479. Add(' .noinit :');
  480. Add(' {');
  481. Add(' PROVIDE (__noinit_start = .) ;');
  482. Add(' *(.noinit*)');
  483. Add(' PROVIDE (__noinit_end = .) ;');
  484. Add(' _end = . ;');
  485. Add(' PROVIDE (__heap_start = .) ;');
  486. Add(' } > data');
  487. Add(' .eeprom :');
  488. Add(' {');
  489. Add(' *(.eeprom*)');
  490. Add(' __eeprom_end = . ;');
  491. Add(' } > eeprom');
  492. Add(' .fuse :');
  493. Add(' {');
  494. Add(' KEEP(*(.fuse))');
  495. Add(' KEEP(*(.lfuse))');
  496. Add(' KEEP(*(.hfuse))');
  497. Add(' KEEP(*(.efuse))');
  498. Add(' } > fuse');
  499. Add(' .lock :');
  500. Add(' {');
  501. Add(' KEEP(*(.lock*))');
  502. Add(' } > lock');
  503. Add(' .signature :');
  504. Add(' {');
  505. Add(' KEEP(*(.signature*))');
  506. Add(' } > signature');
  507. Add(' /* Stabs debugging sections. */');
  508. Add(' .stab 0 : { *(.stab) }');
  509. Add(' .stabstr 0 : { *(.stabstr) }');
  510. Add(' .stab.excl 0 : { *(.stab.excl) }');
  511. Add(' .stab.exclstr 0 : { *(.stab.exclstr) }');
  512. Add(' .stab.index 0 : { *(.stab.index) }');
  513. Add(' .stab.indexstr 0 : { *(.stab.indexstr) }');
  514. Add(' .comment 0 : { *(.comment) }');
  515. Add(' /* DWARF debug sections.');
  516. Add(' Symbols in the DWARF debugging sections are relative to the beginning');
  517. Add(' of the section so we begin them at 0. */');
  518. Add(' /* DWARF 1 */');
  519. Add(' .debug 0 : { *(.debug) }');
  520. Add(' .line 0 : { *(.line) }');
  521. Add(' /* GNU DWARF 1 extensions */');
  522. Add(' .debug_srcinfo 0 : { *(.debug_srcinfo) }');
  523. Add(' .debug_sfnames 0 : { *(.debug_sfnames) }');
  524. Add(' /* DWARF 1.1 and DWARF 2 */');
  525. Add(' .debug_aranges 0 : { *(.debug_aranges) }');
  526. Add(' .debug_pubnames 0 : { *(.debug_pubnames) }');
  527. Add(' /* DWARF 2 */');
  528. Add(' .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }');
  529. Add(' .debug_abbrev 0 : { *(.debug_abbrev) }');
  530. Add(' .debug_line 0 : { *(.debug_line) }');
  531. Add(' .debug_frame 0 : { *(.debug_frame) }');
  532. Add(' .debug_str 0 : { *(.debug_str) }');
  533. Add(' .debug_loc 0 : { *(.debug_loc) }');
  534. Add(' .debug_macinfo 0 : { *(.debug_macinfo) }');
  535. Add('}');
  536. end;
  537. {$endif AVR}
  538. {$ifdef AVR32}
  539. case current_settings.controllertype of
  540. ct_none:
  541. ;
  542. ct_at32uc3l016:
  543. begin
  544. flashsize:=16;
  545. ramsize:=8;
  546. end;
  547. ct_at32uc3l032:
  548. begin
  549. flashsize:=32;
  550. ramsize:=16;
  551. end;
  552. ct_at32uc3l064:
  553. begin
  554. flashsize:=64;
  555. ramsize:=16;
  556. end;
  557. ct_at32uc3b1256:
  558. begin
  559. flashsize:=256;
  560. ramsize:=32;
  561. end;
  562. else
  563. internalerror(200902011);
  564. end;
  565. if current_settings.controllertype<>ct_none then
  566. begin
  567. with linkres do
  568. begin
  569. Add('ENTRY(_START)');
  570. Add('MEMORY');
  571. Add('{');
  572. Add(Format(' flash : ORIGIN = 0x80000000, LENGTH = %DK',[flashsize]));
  573. Add(Format(' ram : ORIGIN = 0, LENGTH = %DK',[ramsize]));
  574. Add('}');
  575. Add(format('_stack_top = 0x%X;',[ramsize*1024-4]));
  576. end;
  577. end;
  578. with linkres do
  579. begin
  580. Add('SECTIONS');
  581. Add('{');
  582. Add(' .rel.init : { *(.rel.init) }');
  583. Add(' .rela.init : { *(.rela.init) }');
  584. Add(' .rel.text :');
  585. Add(' {');
  586. Add(' *(.rel.text)');
  587. Add(' *(.rel.text.*)');
  588. Add(' *(.rel.gnu.linkonce.t*)');
  589. Add(' }');
  590. Add(' .rela.text :');
  591. Add(' {');
  592. Add(' *(.rela.text)');
  593. Add(' *(.rela.text.*)');
  594. Add(' *(.rela.gnu.linkonce.t*)');
  595. Add(' }');
  596. Add(' .rel.fini : { *(.rel.fini) }');
  597. Add(' .rela.fini : { *(.rela.fini) }');
  598. Add(' .rel.rodata :');
  599. Add(' {');
  600. Add(' *(.rel.rodata)');
  601. Add(' *(.rel.rodata.*)');
  602. Add(' *(.rel.gnu.linkonce.r*)');
  603. Add(' }');
  604. Add(' .rela.rodata :');
  605. Add(' {');
  606. Add(' *(.rela.rodata)');
  607. Add(' *(.rela.rodata.*)');
  608. Add(' *(.rela.gnu.linkonce.r*)');
  609. Add(' }');
  610. Add(' .rel.data :');
  611. Add(' {');
  612. Add(' *(.rel.data)');
  613. Add(' *(.rel.data.*)');
  614. Add(' *(.rel.gnu.linkonce.d*)');
  615. Add(' }');
  616. Add(' .rela.data :');
  617. Add(' {');
  618. Add(' *(.rela.data)');
  619. Add(' *(.rela.data.*)');
  620. Add(' *(.rela.gnu.linkonce.d*)');
  621. Add(' }');
  622. Add(' .rel.ctors : { *(.rel.ctors) }');
  623. Add(' .rela.ctors : { *(.rela.ctors) }');
  624. Add(' .rel.dtors : { *(.rel.dtors) }');
  625. Add(' .rela.dtors : { *(.rela.dtors) }');
  626. Add(' .rel.got : { *(.rel.got) }');
  627. Add(' .rela.got : { *(.rela.got) } >flash');
  628. Add(' .rel.bss : { *(.rel.bss) }');
  629. Add(' .rela.bss : { *(.rela.bss) }');
  630. Add(' .rel.plt : { *(.rel.plt) }');
  631. Add(' .rela.plt : { *(.rela.plt) }');
  632. Add(' .text :');
  633. Add(' {');
  634. Add(' KEEP(*(.init))');
  635. Add(' KEEP(*(.init.*))');
  636. Add(' *(.text)');
  637. Add(' *(.text.*)');
  638. Add(' *(.strings)');
  639. Add(' *(.rodata)');
  640. Add(' *(.rodata.*)');
  641. Add(' *(.comment)');
  642. Add(' . = ALIGN(4);');
  643. Add(' _etext = .;');
  644. Add(' } >flash =0xd703d703');
  645. Add(' .data : ALIGN(4) ');
  646. Add(' {');
  647. Add(' _data = .;');
  648. Add(' *(.data)');
  649. Add(' *(.data.*)');
  650. Add(' KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
  651. Add(' . = ALIGN(4);');
  652. Add(' _edata = .;');
  653. Add(' } >ram AT >flash');
  654. Add(' .bss : ');
  655. Add(' {');
  656. Add(' _bss_start = .;');
  657. Add(' *(.bss)');
  658. Add(' *(.bss.*)');
  659. Add(' *(COMMON)');
  660. Add(' } >ram');
  661. Add('. = ALIGN(4);');
  662. Add('_bss_end = . ;');
  663. Add('}');
  664. Add('_end = .;');
  665. end;
  666. {$endif AVR32}
  667. { Write and Close response }
  668. linkres.writetodisk;
  669. linkres.free;
  670. WriteResponseFile:=True;
  671. end;
  672. function TlinkerEmbedded.MakeExecutable:boolean;
  673. var
  674. binstr,
  675. cmdstr : TCmdStr;
  676. success : boolean;
  677. StaticStr,
  678. GCSectionsStr,
  679. DynLinkStr,
  680. StripStr: string;
  681. begin
  682. { for future use }
  683. StaticStr:='';
  684. StripStr:='';
  685. DynLinkStr:='';
  686. GCSectionsStr:='--gc-sections';
  687. //if not(cs_link_extern in current_settings.globalswitches) then
  688. if not(cs_link_nolink in current_settings.globalswitches) then
  689. Message1(exec_i_linking,current_module.exefilename^);
  690. { Write used files and libraries }
  691. WriteResponseFile();
  692. { Call linker }
  693. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  694. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  695. if not(cs_link_on_target in current_settings.globalswitches) then
  696. begin
  697. Replace(cmdstr,'$EXE',(maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename^,'.elf')))));
  698. Replace(cmdstr,'$RES',(maybequoted(ScriptFixFileName(outputexedir+Info.ResName))));
  699. Replace(cmdstr,'$STATIC',StaticStr);
  700. Replace(cmdstr,'$STRIP',StripStr);
  701. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  702. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  703. end
  704. else
  705. begin
  706. Replace(cmdstr,'$EXE',maybequoted(ScriptFixFileName(ChangeFileExt(current_module.exefilename^,'.elf'))));
  707. Replace(cmdstr,'$RES',maybequoted(ScriptFixFileName(outputexedir+Info.ResName)));
  708. Replace(cmdstr,'$STATIC',StaticStr);
  709. Replace(cmdstr,'$STRIP',StripStr);
  710. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  711. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  712. end;
  713. success:=DoExec(FindUtil(utilsprefix+BinStr),cmdstr,true,false);
  714. { Remove ReponseFile }
  715. if success and not(cs_link_nolink in current_settings.globalswitches) then
  716. DeleteFile(outputexedir+Info.ResName);
  717. { Post process }
  718. if success and (target_info.system=system_arm_embedded) then
  719. begin
  720. success:=DoExec(FindUtil(utilsprefix+'objcopy'),'-O ihex '+
  721. ChangeFileExt(current_module.exefilename^,'.elf')+' '+
  722. ChangeFileExt(current_module.exefilename^,'.hex'),true,false);
  723. end;
  724. MakeExecutable:=success; { otherwise a recursive call to link method }
  725. end;
  726. {*****************************************************************************
  727. Initialize
  728. *****************************************************************************}
  729. initialization
  730. {$ifdef arm}
  731. RegisterExternalLinker(system_arm_embedded_info,TlinkerEmbedded);
  732. RegisterTarget(system_arm_embedded_info);
  733. {$endif arm}
  734. {$ifdef avr}
  735. RegisterExternalLinker(system_avr_embedded_info,TlinkerEmbedded);
  736. RegisterTarget(system_avr_embedded_info);
  737. {$endif avr}
  738. {$ifdef i386}
  739. RegisterExternalLinker(system_i386_embedded_info,TlinkerEmbedded);
  740. RegisterTarget(system_i386_embedded_info);
  741. {$endif i386}
  742. {$ifdef avr32}
  743. RegisterExternalLinker(system_avr32_embedded_info,TlinkerEmbedded);
  744. RegisterTarget(system_avr32_embedded_info);
  745. {$endif avr32}
  746. end.