t_bsd.pas 29 KB

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