t_bsd.pas 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Peter Vreman (original Linux)
  4. (c) 2000 by Marco van de Voort (FreeBSD mods)
  5. This unit implements support import,export,link routines
  6. for the (i386)FreeBSD target
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ****************************************************************************
  19. }
  20. unit t_bsd;
  21. {$i fpcdefs.inc}
  22. interface
  23. implementation
  24. uses
  25. {$ifdef gdb}
  26. gdb,
  27. {$endif gdb}
  28. cutils,cclasses,
  29. verbose,systems,globtype,globals,
  30. symconst,script,
  31. fmodule,aasmbase,aasmtai,aasmcpu,cpubase,symsym,symdef,
  32. import,export,link,i_bsd,
  33. cgutils,cgbase,cgobj;
  34. type
  35. tdarwinimported_item = class(timported_item)
  36. procdef : tprocdef;
  37. end;
  38. timportlibdarwin=class(timportlib)
  39. procedure preparelib(const s:string);override;
  40. procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
  41. procedure importvariable(vs:tvarsym;const name,module:string);override;
  42. procedure generatelib;override;
  43. procedure generatesmartlib;override;
  44. private
  45. procedure darwinimportproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
  46. procedure importvariable_str(const s:string;const name,module:string);
  47. end;
  48. timportlibbsd=class(timportlib)
  49. procedure preparelib(const s:string);override;
  50. procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
  51. procedure importvariable(vs:tvarsym;const name,module:string);override;
  52. procedure generatelib;override;
  53. end;
  54. texportlibbsd=class(texportlib)
  55. procedure preparelib(const s : string);override;
  56. procedure exportprocedure(hp : texported_item);override;
  57. procedure exportvar(hp : texported_item);override;
  58. procedure generatelib;override;
  59. end;
  60. tlinkerbsd=class(texternallinker)
  61. private
  62. LdSupportsNoResponseFile : boolean;
  63. LibrarySuffix : Char;
  64. Function WriteResponseFile(isdll:boolean) : Boolean;
  65. public
  66. constructor Create;override;
  67. procedure SetDefaultInfo;override;
  68. function MakeExecutable:boolean;override;
  69. function MakeSharedLibrary:boolean;override;
  70. end;
  71. {*****************************************************************************
  72. TIMPORTLIBDARWIN
  73. *****************************************************************************}
  74. procedure timportlibdarwin.preparelib(const s : string);
  75. begin
  76. if not(assigned(importssection)) then
  77. importssection:=TAAsmoutput.create;
  78. end;
  79. procedure timportlibdarwin.darwinimportproc(aprocdef:tprocdef;const func,module : string;index : longint;const name : string);
  80. var
  81. hp1 : timportlist;
  82. hp2 : tdarwinimported_item;
  83. begin
  84. { force the current mangledname }
  85. if assigned(aprocdef) then
  86. aprocdef.has_mangledname:=true;
  87. { search for the module }
  88. hp1:=timportlist(current_module.imports.first);
  89. { generate a new item ? }
  90. if not(assigned(hp1)) then
  91. begin
  92. { we don't need an import section per library }
  93. hp1:=timportlist.create('imports');
  94. current_module.imports.concat(hp1);
  95. end;
  96. { search for reuse of old import item }
  97. hp2:=tdarwinimported_item(hp1.imported_items.first);
  98. while assigned(hp2) do
  99. begin
  100. if hp2.func^=func then
  101. break;
  102. { there's already another declaration refering to this imported symbol }
  103. { -> make this declaration refer to that entry as well }
  104. if (hp2.name^ = name) then
  105. begin
  106. if not assigned(aprocdef) then
  107. internalerror(2004010306);
  108. if assigned(aprocdef) then
  109. aprocdef.setmangledname(hp2.func^);
  110. break;
  111. end;
  112. hp2:=tdarwinimported_item(hp2.next);
  113. end;
  114. if not assigned(hp2) then
  115. begin
  116. hp2:=tdarwinimported_item.create(func,name,index);
  117. hp2.procdef:=aprocdef;
  118. hp1.imported_items.concat(hp2);
  119. end;
  120. end;
  121. procedure timportlibdarwin.importprocedure(aprocdef:tprocdef;const module : string;index : longint;const name : string);
  122. begin
  123. darwinimportproc(aprocdef,aprocdef.mangledname,module,index,name);
  124. end;
  125. procedure timportlibdarwin.importvariable(vs:tvarsym;const name,module:string);
  126. begin
  127. importvariable_str(vs.mangledname,name,module);
  128. end;
  129. procedure timportlibdarwin.importvariable_str(const s:string;const name,module:string);
  130. var
  131. hp1 : timportlist;
  132. hp2 : tdarwinimported_item;
  133. begin
  134. { search for the module }
  135. hp1:=timportlist(current_module.imports.first);
  136. { generate a new item ? }
  137. if not(assigned(hp1)) then
  138. begin
  139. hp1:=timportlist.create('imports');
  140. current_module.imports.concat(hp1);
  141. end;
  142. hp2:=tdarwinimported_item.create_var(s,name);
  143. hp2.procdef:=nil;
  144. hp1.imported_items.concat(hp2);
  145. end;
  146. procedure timportlibdarwin.generatesmartlib;
  147. begin
  148. generatelib;
  149. end;
  150. procedure timportlibdarwin.generatelib;
  151. var
  152. hp1 : timportlist;
  153. hp2 : tdarwinimported_item;
  154. l1 : tasmsymbol;
  155. symname: string;
  156. mangledstring : string;
  157. {$ifdef GDB}
  158. importname : string;
  159. suffix : integer;
  160. {$endif GDB}
  161. href : treference;
  162. begin
  163. hp1:=timportlist(current_module.imports.first);
  164. while assigned(hp1) do
  165. begin
  166. hp2:=tdarwinimported_item(hp1.imported_items.first);
  167. while assigned(hp2) do
  168. begin
  169. if not assigned(hp2.name) then
  170. internalerror(2004010302);
  171. symname := hp2.name^;
  172. if assigned(tdarwinimported_item(hp2).procdef) and
  173. (tdarwinimported_item(hp2).procdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
  174. symname := target_info.Cprefix+symname;
  175. if not hp2.is_var then
  176. begin
  177. {$IfDef GDB}
  178. if (cs_debuginfo in aktmoduleswitches) then
  179. importssection.concat(tai_stab_function_name.create(nil));
  180. {$EndIf GDB}
  181. if not assigned(hp2.procdef) then
  182. internalerror(2004010306);
  183. mangledstring := hp2.func^;
  184. {$ifdef powerpc}
  185. if (po_public in hp2.procdef.procoptions) then
  186. begin
  187. importsSection.concat(Tai_section.Create(sec_code));
  188. importsSection.concat(Tai_symbol.createname_global(mangledstring,0));
  189. mangledstring := '_$'+mangledstring;
  190. importsSection.concat(taicpu.op_sym(A_B,objectlibrary.newasmsymbol(mangledstring)));
  191. end;
  192. {$else powerpc}
  193. internalerror(2004010501);
  194. {$endif powerpc}
  195. importsSection.concat(Tai_section.Create(sec_data));
  196. importsSection.concat(Tai_direct.create(strpnew('.section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16')));
  197. importsSection.concat(Tai_align.Create(4));
  198. importsSection.concat(Tai_symbol.Createname(mangledstring,0));
  199. importsSection.concat(Tai_direct.create(strpnew((#9+'.indirect_symbol ')+symname)));
  200. l1 := objectlibrary.newasmsymbol(mangledstring+'$lazy_ptr');
  201. reference_reset_symbol(href,l1,0);
  202. {$IfDef GDB}
  203. if (cs_debuginfo in aktmoduleswitches) and assigned(hp2.procdef) then
  204. begin
  205. mangledstring:=hp2.procdef.mangledname;
  206. hp2.procdef.setmangledname(mangledstring);
  207. hp2.procdef.concatstabto(importssection);
  208. hp2.procdef.setmangledname(mangledstring);
  209. end;
  210. {$EndIf GDB}
  211. {$ifdef powerpc}
  212. href.refaddr := addr_hi;
  213. importsSection.concat(taicpu.op_reg_ref(A_LIS,NR_R11,href));
  214. href.refaddr := addr_lo;
  215. href.base := NR_R11;
  216. importsSection.concat(taicpu.op_reg_ref(A_LWZU,NR_R12,href));
  217. importsSection.concat(taicpu.op_reg(A_MTCTR,NR_R12));
  218. importsSection.concat(taicpu.op_none(A_BCTR));
  219. {$else powerpc}
  220. internalerror(2004010502);
  221. {$endif powerpc}
  222. importsSection.concat(Tai_section.Create(sec_data));
  223. importsSection.concat(Tai_direct.create(strpnew('.lazy_symbol_pointer')));
  224. importsSection.concat(Tai_symbol.Create(l1,0));
  225. importsSection.concat(Tai_direct.create(strpnew((#9+'.indirect_symbol ')+symname)));
  226. importsSection.concat(tai_const_symbol.createname(strpnew('dyld_stub_binding_helper')));
  227. end
  228. else
  229. begin
  230. importsSection.concat(Tai_section.Create(sec_data));
  231. importsSection.concat(Tai_direct.create(strpnew('.non_lazy_symbol_pointer')));
  232. importsSection.concat(Tai_symbol.Createname(hp2.func^,0));
  233. importsSection.concat(Tai_direct.create(strpnew((#9+'.indirect_symbol ')+hp2.name^)));
  234. importsSection.concat(Tai_const.create_32bit(0));
  235. end;
  236. hp2:=tdarwinimported_item(hp2.next);
  237. end;
  238. hp1:=timportlist(hp1.next);
  239. end;
  240. end;
  241. {*****************************************************************************
  242. TIMPORTLIBBSD
  243. *****************************************************************************}
  244. procedure timportlibbsd.preparelib(const s : string);
  245. begin
  246. end;
  247. procedure timportlibbsd.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
  248. begin
  249. { insert sharedlibrary }
  250. current_module.linkothersharedlibs.add(SplitName(module),link_allways);
  251. { do nothing with the procedure, only set the mangledname }
  252. if name<>'' then
  253. begin
  254. aprocdef.setmangledname(name);
  255. end
  256. else
  257. message(parser_e_empty_import_name);
  258. end;
  259. procedure timportlibbsd.importvariable(vs:tvarsym;const name,module:string);
  260. begin
  261. { insert sharedlibrary }
  262. current_module.linkothersharedlibs.add(SplitName(module),link_allways);
  263. { reset the mangledname and turn off the dll_var option }
  264. vs.set_mangledname(name);
  265. exclude(vs.varoptions,vo_is_dll_var);
  266. end;
  267. procedure timportlibbsd.generatelib;
  268. begin
  269. end;
  270. {*****************************************************************************
  271. TEXPORTLIBBSD
  272. *****************************************************************************}
  273. procedure texportlibbsd.preparelib(const s:string);
  274. begin
  275. end;
  276. procedure texportlibbsd.exportprocedure(hp : texported_item);
  277. var
  278. hp2 : texported_item;
  279. begin
  280. { first test the index value }
  281. if (hp.options and eo_index)<>0 then
  282. begin
  283. Message1(parser_e_no_export_with_index_for_target,'freebsd');
  284. exit;
  285. end;
  286. { now place in correct order }
  287. hp2:=texported_item(current_module._exports.first);
  288. while assigned(hp2) and
  289. (hp.name^>hp2.name^) do
  290. hp2:=texported_item(hp2.next);
  291. { insert hp there !! }
  292. if assigned(hp2) and (hp2.name^=hp.name^) then
  293. begin
  294. { this is not allowed !! }
  295. Message1(parser_e_export_name_double,hp.name^);
  296. exit;
  297. end;
  298. if hp2=texported_item(current_module._exports.first) then
  299. current_module._exports.concat(hp)
  300. else if assigned(hp2) then
  301. begin
  302. hp.next:=hp2;
  303. hp.previous:=hp2.previous;
  304. if assigned(hp2.previous) then
  305. hp2.previous.next:=hp;
  306. hp2.previous:=hp;
  307. end
  308. else
  309. current_module._exports.concat(hp);
  310. end;
  311. procedure texportlibbsd.exportvar(hp : texported_item);
  312. begin
  313. hp.is_var:=true;
  314. exportprocedure(hp);
  315. end;
  316. procedure texportlibbsd.generatelib;
  317. var
  318. hp2 : texported_item;
  319. begin
  320. hp2:=texported_item(current_module._exports.first);
  321. while assigned(hp2) do
  322. begin
  323. if (not hp2.is_var) and
  324. (hp2.sym.typ=procsym) then
  325. begin
  326. { the manglednames can already be the same when the procedure
  327. is declared with cdecl }
  328. if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
  329. begin
  330. {$ifdef i386}
  331. { place jump in codesegment }
  332. codesegment.concat(Tai_align.Create_op(4,$90));
  333. codeSegment.concat(Tai_symbol.Createname_global(hp2.name^,0));
  334. codeSegment.concat(Taicpu.Op_sym(A_JMP,S_NO,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname)));
  335. codeSegment.concat(Tai_symbol_end.Createname(hp2.name^));
  336. {$endif i386}
  337. end;
  338. end
  339. else
  340. Message1(parser_e_no_export_of_variables_for_target,'freebsd');
  341. hp2:=texported_item(hp2.next);
  342. end;
  343. end;
  344. {*****************************************************************************
  345. TLINKERLINUX
  346. *****************************************************************************}
  347. Constructor TLinkerBSD.Create;
  348. begin
  349. Inherited Create;
  350. if not Dontlinkstdlibpath Then
  351. if (target_info.system <> system_powerpc_darwin) then
  352. LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib',true)
  353. else
  354. { Mac OS X doesn't have a /lib }
  355. LibrarySearchPath.AddPath('/usr/lib',true)
  356. end;
  357. procedure TLinkerBSD.SetDefaultInfo;
  358. {
  359. This will also detect which libc version will be used
  360. }
  361. begin
  362. LibrarySuffix:=' ';
  363. LdSupportsNoResponseFile := (target_info.system in [system_m68k_netbsd,system_powerpc_darwin]);
  364. with Info do
  365. begin
  366. if LdSupportsNoResponseFile then
  367. begin
  368. ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE `cat $RES`';
  369. end
  370. else
  371. ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE $RES';
  372. DllCmd[1]:='ld $OPT -shared -L. -o $EXE $RES';
  373. DllCmd[2]:='strip --strip-unneeded $EXE';
  374. { first try glibc2 }
  375. {$ifdef GLIBC2} {Keep linux code in place. FBSD might go to a different
  376. glibc too once}
  377. DynamicLinker:='/lib/ld-linux.so.2';
  378. if FileExists(DynamicLinker) then
  379. begin
  380. Glibc2:=true;
  381. { Check for 2.0 files, else use the glibc 2.1 stub }
  382. if FileExists('/lib/ld-2.0.*') then
  383. Glibc21:=false
  384. else
  385. Glibc21:=true;
  386. end
  387. else
  388. DynamicLinker:='/lib/ld-linux.so.1';
  389. {$else}
  390. DynamicLinker:='';
  391. {$endif}
  392. end;
  393. end;
  394. Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;
  395. Var
  396. linkres : TLinkRes;
  397. i : longint;
  398. cprtobj,
  399. gprtobj,
  400. prtobj : string[80];
  401. HPath : TStringListItem;
  402. s,s1,s2 : string;
  403. linkpthread,
  404. linkdynamic,
  405. linklibc : boolean;
  406. Fl1,Fl2 : Boolean;
  407. begin
  408. WriteResponseFile:=False;
  409. { set special options for some targets }
  410. if target_info.system <> system_powerpc_darwin then
  411. begin
  412. linkdynamic:=not(SharedLibFiles.empty);
  413. linklibc:=(SharedLibFiles.Find('c')<>nil);
  414. linkpthread:=(SharedLibFiles.Find('pthread')<>nil);
  415. if (target_info.system =system_i386_freebsd) and linkpthread Then
  416. Begin
  417. if not (cs_link_pthread in aktglobalswitches) Then
  418. begin
  419. {delete pthreads from list, in this case it is in libc_r}
  420. SharedLibFiles.Remove(SharedLibFiles.Find('pthread').str);
  421. LibrarySuffix:='r';
  422. end;
  423. End;
  424. prtobj:='prt0';
  425. cprtobj:='cprt0';
  426. gprtobj:='gprt0';
  427. if cs_profile in aktmoduleswitches then
  428. begin
  429. prtobj:=gprtobj;
  430. AddSharedLibrary('c');
  431. LibrarySuffix:='p';
  432. linklibc:=true;
  433. end
  434. else
  435. begin
  436. if linklibc then
  437. prtobj:=cprtobj;
  438. end;
  439. end
  440. else
  441. begin
  442. { for darwin: always link dynamically against libc }
  443. linklibc := true;
  444. if not(cs_profile in aktmoduleswitches) then
  445. prtobj:='/usr/lib/crt1.o'
  446. else
  447. prtobj:='/usr/lib/gcrt1.o';
  448. end;
  449. { Open link.res file }
  450. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  451. { Write path to search libraries }
  452. HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
  453. while assigned(HPath) do
  454. begin
  455. if LdSupportsNoResponseFile then
  456. LinkRes.Add('-L'+HPath.Str)
  457. else
  458. LinkRes.Add('SEARCH_DIR('+HPath.Str+')');
  459. HPath:=TStringListItem(HPath.Next);
  460. end;
  461. HPath:=TStringListItem(LibrarySearchPath.First);
  462. while assigned(HPath) do
  463. begin
  464. if LdSupportsNoResponseFile then
  465. LinkRes.Add('-L'+HPath.Str)
  466. else
  467. LinkRes.Add('SEARCH_DIR('+HPath.Str+')');
  468. HPath:=TStringListItem(HPath.Next);
  469. end;
  470. if not LdSupportsNoResponseFile then
  471. LinkRes.Add('INPUT(');
  472. { add objectfiles, start with prt0 always }
  473. if prtobj<>'' then
  474. LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
  475. { try to add crti and crtbegin if linking to C }
  476. if linklibc and
  477. (target_info.system <> system_powerpc_darwin) then
  478. begin
  479. if librarysearchpath.FindFile('crtbegin.o',s) then
  480. LinkRes.AddFileName(s);
  481. if librarysearchpath.FindFile('crti.o',s) then
  482. LinkRes.AddFileName(s);
  483. end;
  484. { main objectfiles }
  485. while not ObjectFiles.Empty do
  486. begin
  487. s:=ObjectFiles.GetFirst;
  488. if s<>'' then
  489. LinkRes.AddFileName(s);
  490. end;
  491. if not LdSupportsNoResponseFile then
  492. LinkRes.Add(')');
  493. { Write staticlibraries }
  494. if not StaticLibFiles.Empty then
  495. begin
  496. if not LdSupportsNoResponseFile then
  497. LinkRes.Add('GROUP(');
  498. While not StaticLibFiles.Empty do
  499. begin
  500. S:=StaticLibFiles.GetFirst;
  501. LinkRes.AddFileName(s)
  502. end;
  503. if not LdSupportsNoResponseFile then
  504. LinkRes.Add(')');
  505. end;
  506. { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
  507. here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
  508. if not SharedLibFiles.Empty then
  509. begin
  510. if not LdSupportsNoResponseFile then
  511. LinkRes.Add('INPUT(');
  512. While not SharedLibFiles.Empty do
  513. begin
  514. S:=SharedLibFiles.GetFirst;
  515. if s<>'c' then
  516. begin
  517. i:=Pos(target_info.sharedlibext,S);
  518. if i>0 then
  519. Delete(S,i,255);
  520. LinkRes.Add('-l'+s);
  521. end
  522. else
  523. begin
  524. linklibc:=true;
  525. linkdynamic:=false; { libc will include the ld-linux for us }
  526. end;
  527. end;
  528. { be sure that libc is the last lib }
  529. if linklibc then
  530. Begin
  531. If LibrarySuffix=' ' Then
  532. LinkRes.Add('-lc')
  533. else
  534. LinkRes.Add('-lc_'+LibrarySuffix)
  535. end;
  536. { when we have -static for the linker the we also need libgcc }
  537. if (cs_link_staticflag in aktglobalswitches) then
  538. LinkRes.Add('-lgcc');
  539. if linkdynamic and (Info.DynamicLinker<>'') then
  540. LinkRes.AddFileName(Info.DynamicLinker);
  541. if not LdSupportsNoResponseFile then
  542. LinkRes.Add(')');
  543. end;
  544. { objects which must be at the end }
  545. if linklibc and
  546. (target_info.system <> system_powerpc_darwin) then
  547. begin
  548. Fl1:=librarysearchpath.FindFile('crtend.o',s1);
  549. Fl2:=librarysearchpath.FindFile('crtn.o',s2);
  550. if Fl1 or Fl2 then
  551. begin
  552. LinkRes.Add('INPUT(');
  553. If Fl1 Then
  554. LinkRes.AddFileName(s1);
  555. If Fl2 Then
  556. LinkRes.AddFileName(s2);
  557. LinkRes.Add(')');
  558. end;
  559. end;
  560. { Write and Close response }
  561. linkres.writetodisk;
  562. linkres.Free;
  563. WriteResponseFile:=True;
  564. end;
  565. function TLinkerBSD.MakeExecutable:boolean;
  566. var
  567. binstr,
  568. cmdstr : string;
  569. success : boolean;
  570. DynLinkStr : string[60];
  571. StaticStr,
  572. StripStr : string[40];
  573. begin
  574. if not(cs_link_extern in aktglobalswitches) then
  575. Message1(exec_i_linking,current_module.exefilename^);
  576. { Create some replacements }
  577. StaticStr:='';
  578. StripStr:='';
  579. DynLinkStr:='';
  580. if (cs_link_staticflag in aktglobalswitches) then
  581. begin
  582. if (target_info.system=system_m68k_netbsd) and
  583. ((cs_link_on_target in aktglobalswitches) or
  584. (target_info.system=source_info.system)) then
  585. StaticStr:='-Bstatic'
  586. else
  587. StaticStr:='-static';
  588. end;
  589. if (cs_link_strip in aktglobalswitches) then
  590. StripStr:='-s';
  591. If (cs_profile in aktmoduleswitches) or
  592. ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
  593. DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
  594. if CShared Then
  595. DynLinKStr:=DynLinkStr+' --shared';
  596. { Write used files and libraries }
  597. WriteResponseFile(false);
  598. { Call linker }
  599. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  600. Replace(cmdstr,'$EXE',current_module.exefilename^);
  601. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  602. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  603. Replace(cmdstr,'$STATIC',StaticStr);
  604. Replace(cmdstr,'$STRIP',StripStr);
  605. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  606. success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,LdSupportsNoResponseFile);
  607. { Remove ReponseFile }
  608. if (success) and not(cs_link_extern in aktglobalswitches) then
  609. RemoveFile(outputexedir+Info.ResName);
  610. MakeExecutable:=success; { otherwise a recursive call to link method }
  611. end;
  612. Function TLinkerBSD.MakeSharedLibrary:boolean;
  613. var
  614. binstr,
  615. cmdstr : string;
  616. success : boolean;
  617. begin
  618. MakeSharedLibrary:=false;
  619. if not(cs_link_extern in aktglobalswitches) then
  620. Message1(exec_i_linking,current_module.sharedlibfilename^);
  621. { Write used files and libraries }
  622. WriteResponseFile(true);
  623. { Call linker }
  624. SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
  625. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  626. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  627. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  628. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
  629. { Strip the library ? }
  630. if success and (cs_link_strip in aktglobalswitches) then
  631. begin
  632. SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
  633. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  634. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
  635. end;
  636. { Remove ReponseFile }
  637. if (success) and not(cs_link_extern in aktglobalswitches) then
  638. RemoveFile(outputexedir+Info.ResName);
  639. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  640. end;
  641. {*****************************************************************************
  642. Initialize
  643. *****************************************************************************}
  644. initialization
  645. {$ifdef i386}
  646. RegisterExternalLinker(system_i386_FreeBSD_info,TLinkerBSD);
  647. RegisterExternalLinker(system_i386_NetBSD_info,TLinkerBSD);
  648. RegisterExternalLinker(system_i386_OpenBSD_info,TLinkerBSD);
  649. RegisterImport(system_i386_freebsd,timportlibbsd);
  650. RegisterExport(system_i386_freebsd,texportlibbsd);
  651. RegisterTarget(system_i386_freebsd_info);
  652. RegisterImport(system_i386_netbsd,timportlibbsd);
  653. RegisterExport(system_i386_netbsd,texportlibbsd);
  654. RegisterTarget(system_i386_netbsd_info);
  655. RegisterImport(system_i386_openbsd,timportlibbsd);
  656. RegisterExport(system_i386_openbsd,texportlibbsd);
  657. RegisterTarget(system_i386_openbsd_info);
  658. {$endif i386}
  659. {$ifdef m68k}
  660. // RegisterExternalLinker(system_m68k_FreeBSD_info,TLinkerBSD);
  661. RegisterExternalLinker(system_m68k_NetBSD_info,TLinkerBSD);
  662. RegisterImport(system_m68k_netbsd,timportlibbsd);
  663. RegisterExport(system_m68k_netbsd,texportlibbsd);
  664. RegisterTarget(system_m68k_netbsd_info);
  665. {$endif m68k}
  666. {$ifdef powerpc}
  667. // RegisterExternalLinker(system_m68k_FreeBSD_info,TLinkerBSD);
  668. RegisterExternalLinker(system_powerpc_darwin_info,TLinkerBSD);
  669. RegisterImport(system_powerpc_darwin,timportlibdarwin);
  670. RegisterExport(system_powerpc_darwin,texportlibbsd);
  671. RegisterTarget(system_powerpc_darwin_info);
  672. RegisterExternalLinker(system_powerpc_netbsd_info,TLinkerBSD);
  673. RegisterImport(system_powerpc_netbsd,timportlibbsd);
  674. RegisterExport(system_powerpc_netbsd,texportlibbsd);
  675. RegisterTarget(system_powerpc_netbsd_info);
  676. {$endif powerpc}
  677. end.
  678. {
  679. $Log$
  680. Revision 1.10 2004-02-27 10:21:05 florian
  681. * top_symbol killed
  682. + refaddr to treference added
  683. + refsymbol to treference added
  684. * top_local stuff moved to an extra record to save memory
  685. + aint introduced
  686. * tppufile.get/putint64/aint implemented
  687. Revision 1.9 2004/02/15 16:34:18 marco
  688. * pthread on -CURRENT related fixes.
  689. Revision 1.8 2004/01/21 20:53:51 marco
  690. * Copy and pasted some structures from Net- to OpenBSD (3.4+ ELF!)
  691. Revision 1.7 2004/01/05 08:13:30 jonas
  692. * fixed compilation problems under x86
  693. Revision 1.6 2004/01/04 21:26:31 jonas
  694. + Darwin support for routines imported from external libraries (not yet
  695. ideal, we should generate stubs in all files where the routines are
  696. used -> these are automatically merged by the linker; now we generate
  697. one global symbol with a jump to a stub in unit where the routine is
  698. declared)
  699. + (not yet working) Darwin support for imported variables
  700. + Darwin support for linking
  701. Revision 1.5 2003/10/30 18:35:30 marco
  702. * librarysuffix + profiling
  703. Revision 1.4 2003/10/11 19:32:04 marco
  704. * -Xd
  705. Revision 1.3 2003/10/03 14:16:48 marco
  706. * -XP<prefix> support
  707. Revision 1.2 2003/05/25 23:15:04 marco
  708. * NetBSD target support. OpenBSD reserved in the enum, for future use.
  709. Revision 1.1 2003/05/20 23:54:00 florian
  710. + basic darwin support added
  711. Revision 1.5 2003/04/27 07:29:52 peter
  712. * aktprocdef cleanup, aktprocdef is now always nil when parsing
  713. a new procdef declaration
  714. * aktprocsym removed
  715. * lexlevel removed, use symtable.symtablelevel instead
  716. * implicit init/final code uses the normal genentry/genexit
  717. * funcret state checking updated for new funcret handling
  718. Revision 1.4 2003/04/26 09:16:08 peter
  719. * .o files belonging to the unit are first searched in the same dir
  720. as the .ppu
  721. Revision 1.3 2003/01/18 16:16:13 marco
  722. * Small fix for netbsd
  723. Revision 1.2 2002/09/09 17:34:17 peter
  724. * tdicationary.replace added to replace and item in a dictionary. This
  725. is only allowed for the same name
  726. * varsyms are inserted in symtable before the types are parsed. This
  727. fixes the long standing "var longint : longint" bug
  728. - consume_idlist and idstringlist removed. The loops are inserted
  729. at the callers place and uses the symtable for duplicate id checking
  730. Revision 1.1 2002/09/06 15:03:51 carl
  731. * moved files to systems directory
  732. Revision 1.29 2002/09/03 16:26:28 daniel
  733. * Make Tprocdef.defs protected
  734. Revision 1.28 2002/08/12 15:08:44 carl
  735. + stab register indexes for powerpc (moved from gdb to cpubase)
  736. + tprocessor enumeration moved to cpuinfo
  737. + linker in target_info is now a class
  738. * many many updates for m68k (will soon start to compile)
  739. - removed some ifdef or correct them for correct cpu
  740. Revision 1.27 2002/08/11 14:32:32 peter
  741. * renamed current_library to objectlibrary
  742. Revision 1.26 2002/08/11 13:24:19 peter
  743. * saving of asmsymbols in ppu supported
  744. * asmsymbollist global is removed and moved into a new class
  745. tasmlibrarydata that will hold the info of a .a file which
  746. corresponds with a single module. Added librarydata to tmodule
  747. to keep the library info stored for the module. In the future the
  748. objectfiles will also be stored to the tasmlibrarydata class
  749. * all getlabel/newasmsymbol and friends are moved to the new class
  750. Revision 1.25 2002/07/26 21:15:45 florian
  751. * rewrote the system handling
  752. Revision 1.24 2002/07/24 13:51:34 marco
  753. * Fixed small error
  754. Revision 1.23 2002/07/24 13:10:22 marco
  755. * urgent fix.
  756. Revision 1.22 2002/07/01 18:46:34 peter
  757. * internal linker
  758. * reorganized aasm layer
  759. Revision 1.21 2002/05/18 13:34:26 peter
  760. * readded missing revisions
  761. Revision 1.20 2002/05/16 19:46:53 carl
  762. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  763. + try to fix temp allocation (still in ifdef)
  764. + generic constructor calls
  765. + start of tassembler / tmodulebase class cleanup
  766. Revision 1.18 2002/04/22 18:19:22 carl
  767. - remove use_bound_instruction field
  768. Revision 1.17 2002/04/20 21:43:18 carl
  769. * fix stack size for some targets
  770. + add offset to parameters from frame pointer info.
  771. - remove some unused stuff
  772. Revision 1.16 2002/04/19 15:46:04 peter
  773. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  774. in most cases and not written to the ppu
  775. * add mangeledname_prefix() routine to generate the prefix of
  776. manglednames depending on the current procedure, object and module
  777. * removed static procprefix since the mangledname is now build only
  778. on demand from tprocdef.mangledname
  779. Revision 1.15 2002/04/15 19:16:57 carl
  780. - remove size_of_pointer field
  781. Revision 1.14 2002/01/29 21:27:34 peter
  782. * default alignment changed to 4 bytes for locals and static const,var
  783. }