t_bsd.pas 29 KB

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