t_bsd.pas 30 KB

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