t_bsd.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  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. 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.symaddr := refs_ha;
  213. importsSection.concat(taicpu.op_reg_ref(A_LIS,NR_R11,href));
  214. href.symaddr := refs_l;
  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.9 2004-02-15 16:34:18 marco
  681. * pthread on -CURRENT related fixes.
  682. Revision 1.8 2004/01/21 20:53:51 marco
  683. * Copy and pasted some structures from Net- to OpenBSD (3.4+ ELF!)
  684. Revision 1.7 2004/01/05 08:13:30 jonas
  685. * fixed compilation problems under x86
  686. Revision 1.6 2004/01/04 21:26:31 jonas
  687. + Darwin support for routines imported from external libraries (not yet
  688. ideal, we should generate stubs in all files where the routines are
  689. used -> these are automatically merged by the linker; now we generate
  690. one global symbol with a jump to a stub in unit where the routine is
  691. declared)
  692. + (not yet working) Darwin support for imported variables
  693. + Darwin support for linking
  694. Revision 1.5 2003/10/30 18:35:30 marco
  695. * librarysuffix + profiling
  696. Revision 1.4 2003/10/11 19:32:04 marco
  697. * -Xd
  698. Revision 1.3 2003/10/03 14:16:48 marco
  699. * -XP<prefix> support
  700. Revision 1.2 2003/05/25 23:15:04 marco
  701. * NetBSD target support. OpenBSD reserved in the enum, for future use.
  702. Revision 1.1 2003/05/20 23:54:00 florian
  703. + basic darwin support added
  704. Revision 1.5 2003/04/27 07:29:52 peter
  705. * aktprocdef cleanup, aktprocdef is now always nil when parsing
  706. a new procdef declaration
  707. * aktprocsym removed
  708. * lexlevel removed, use symtable.symtablelevel instead
  709. * implicit init/final code uses the normal genentry/genexit
  710. * funcret state checking updated for new funcret handling
  711. Revision 1.4 2003/04/26 09:16:08 peter
  712. * .o files belonging to the unit are first searched in the same dir
  713. as the .ppu
  714. Revision 1.3 2003/01/18 16:16:13 marco
  715. * Small fix for netbsd
  716. Revision 1.2 2002/09/09 17:34:17 peter
  717. * tdicationary.replace added to replace and item in a dictionary. This
  718. is only allowed for the same name
  719. * varsyms are inserted in symtable before the types are parsed. This
  720. fixes the long standing "var longint : longint" bug
  721. - consume_idlist and idstringlist removed. The loops are inserted
  722. at the callers place and uses the symtable for duplicate id checking
  723. Revision 1.1 2002/09/06 15:03:51 carl
  724. * moved files to systems directory
  725. Revision 1.29 2002/09/03 16:26:28 daniel
  726. * Make Tprocdef.defs protected
  727. Revision 1.28 2002/08/12 15:08:44 carl
  728. + stab register indexes for powerpc (moved from gdb to cpubase)
  729. + tprocessor enumeration moved to cpuinfo
  730. + linker in target_info is now a class
  731. * many many updates for m68k (will soon start to compile)
  732. - removed some ifdef or correct them for correct cpu
  733. Revision 1.27 2002/08/11 14:32:32 peter
  734. * renamed current_library to objectlibrary
  735. Revision 1.26 2002/08/11 13:24:19 peter
  736. * saving of asmsymbols in ppu supported
  737. * asmsymbollist global is removed and moved into a new class
  738. tasmlibrarydata that will hold the info of a .a file which
  739. corresponds with a single module. Added librarydata to tmodule
  740. to keep the library info stored for the module. In the future the
  741. objectfiles will also be stored to the tasmlibrarydata class
  742. * all getlabel/newasmsymbol and friends are moved to the new class
  743. Revision 1.25 2002/07/26 21:15:45 florian
  744. * rewrote the system handling
  745. Revision 1.24 2002/07/24 13:51:34 marco
  746. * Fixed small error
  747. Revision 1.23 2002/07/24 13:10:22 marco
  748. * urgent fix.
  749. Revision 1.22 2002/07/01 18:46:34 peter
  750. * internal linker
  751. * reorganized aasm layer
  752. Revision 1.21 2002/05/18 13:34:26 peter
  753. * readded missing revisions
  754. Revision 1.20 2002/05/16 19:46:53 carl
  755. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  756. + try to fix temp allocation (still in ifdef)
  757. + generic constructor calls
  758. + start of tassembler / tmodulebase class cleanup
  759. Revision 1.18 2002/04/22 18:19:22 carl
  760. - remove use_bound_instruction field
  761. Revision 1.17 2002/04/20 21:43:18 carl
  762. * fix stack size for some targets
  763. + add offset to parameters from frame pointer info.
  764. - remove some unused stuff
  765. Revision 1.16 2002/04/19 15:46:04 peter
  766. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  767. in most cases and not written to the ppu
  768. * add mangeledname_prefix() routine to generate the prefix of
  769. manglednames depending on the current procedure, object and module
  770. * removed static procprefix since the mangledname is now build only
  771. on demand from tprocdef.mangledname
  772. Revision 1.15 2002/04/15 19:16:57 carl
  773. - remove size_of_pointer field
  774. Revision 1.14 2002/01/29 21:27:34 peter
  775. * default alignment changed to 4 bytes for locals and static const,var
  776. }