t_bsd.pas 29 KB

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