t_bsd.pas 29 KB

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