t_sunos.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Peter Vreman
  4. This unit implements support import,export,link routines
  5. for the (i386) sunos target
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit t_sunos;
  20. {$i fpcdefs.inc}
  21. interface
  22. { copy from t_linux
  23. // Up to now we use gld since the solaris ld seems not support .res-files}
  24. {-$DEFINE LinkTest} { DON't del link.res and write Info }
  25. {$DEFINE GnuLd} {The other is not implemented }
  26. implementation
  27. uses
  28. cutils,cclasses,
  29. verbose,systems,globtype,globals,
  30. symconst,script,
  31. fmodule,aasmbase,aasmtai,aasmcpu,cpubase,symsym,symdef,
  32. import,export,link,i_sunos;
  33. type
  34. timportlibsunos=class(timportlib)
  35. procedure preparelib(const s:string);override;
  36. procedure importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);override;
  37. procedure importvariable(vs:tvarsym;const name,module:string);override;
  38. procedure generatelib;override;
  39. end;
  40. texportlibsunos=class(texportlib)
  41. procedure preparelib(const s : string);override;
  42. procedure exportprocedure(hp : texported_item);override;
  43. procedure exportvar(hp : texported_item);override;
  44. procedure generatelib;override;
  45. end;
  46. tlinkersunos=class(texternallinker)
  47. private
  48. Glibc2,
  49. Glibc21 : boolean;
  50. Function WriteResponseFile(isdll:boolean) : Boolean;
  51. public
  52. constructor Create;override;
  53. procedure SetDefaultInfo;override;
  54. function MakeExecutable:boolean;override;
  55. function MakeSharedLibrary:boolean;override;
  56. end;
  57. {*****************************************************************************
  58. TIMPORTLIBsunos
  59. *****************************************************************************}
  60. procedure timportlibsunos.preparelib(const s : string);
  61. begin
  62. {$ifDef LinkTest}
  63. WriteLN('Prepare import: ',s);
  64. {$EndIf}
  65. end;
  66. procedure timportlibsunos.importprocedure(aprocdef:tprocdef;const module:string;index:longint;const name:string);
  67. begin
  68. { insert sharedlibrary }
  69. {$ifDef LinkTest}
  70. WriteLN('Import: f:',func,' m:',module,' n:',name);
  71. {$EndIf}
  72. current_module.linkothersharedlibs.add(SplitName(module),link_allways);
  73. { do nothing with the procedure, only set the mangledname }
  74. if name<>'' then
  75. begin
  76. aprocdef.setmangledname(name);
  77. end
  78. else
  79. message(parser_e_empty_import_name);
  80. end;
  81. procedure timportlibsunos.importvariable(vs:tvarsym;const name,module:string);
  82. begin
  83. { insert sharedlibrary }
  84. current_module.linkothersharedlibs.add(SplitName(module),link_allways);
  85. { reset the mangledname and turn off the dll_var option }
  86. vs.set_mangledname(name);
  87. exclude(vs.varoptions,vo_is_dll_var);
  88. end;
  89. procedure timportlibsunos.generatelib;
  90. begin
  91. end;
  92. {*****************************************************************************
  93. TEXPORTLIBsunos
  94. *****************************************************************************}
  95. procedure texportlibsunos.preparelib(const s:string);
  96. begin
  97. end;
  98. procedure texportlibsunos.exportprocedure(hp : texported_item);
  99. var
  100. hp2 : texported_item;
  101. begin
  102. { first test the index value }
  103. if (hp.options and eo_index)<>0 then
  104. begin
  105. Message1(parser_e_no_export_with_index_for_target,'SunOS');
  106. exit;
  107. end;
  108. { use pascal name is none specified }
  109. if (hp.options and eo_name)=0 then
  110. begin
  111. hp.name:=stringdup(hp.sym.name);
  112. hp.options:=hp.options or eo_name;
  113. end;
  114. { now place in correct order }
  115. hp2:=texported_item(current_module._exports.first);
  116. while assigned(hp2) and
  117. (hp.name^>hp2.name^) do
  118. hp2:=texported_item(hp2.next);
  119. { insert hp there !! }
  120. if assigned(hp2) and (hp2.name^=hp.name^) then
  121. begin
  122. { this is not allowed !! }
  123. Message1(parser_e_export_name_double,hp.name^);
  124. exit;
  125. end;
  126. if hp2=texported_item(current_module._exports.first) then
  127. current_module._exports.insert(hp)
  128. else if assigned(hp2) then
  129. begin
  130. hp.next:=hp2;
  131. hp.previous:=hp2.previous;
  132. if assigned(hp2.previous) then
  133. hp2.previous.next:=hp;
  134. hp2.previous:=hp;
  135. end
  136. else
  137. current_module._exports.concat(hp);
  138. end;
  139. procedure texportlibsunos.exportvar(hp : texported_item);
  140. begin
  141. hp.is_var:=true;
  142. exportprocedure(hp);
  143. end;
  144. procedure texportlibsunos.generatelib;
  145. var
  146. hp2 : texported_item;
  147. begin
  148. hp2:=texported_item(current_module._exports.first);
  149. while assigned(hp2) do
  150. begin
  151. if (not hp2.is_var) and
  152. (hp2.sym.typ=procsym) then
  153. begin
  154. { the manglednames can already be the same when the procedure
  155. is declared with cdecl }
  156. if tprocsym(hp2.sym).first_procdef.mangledname<>hp2.name^ then
  157. begin
  158. {$ifdef i386}
  159. { place jump in codesegment }
  160. codesegment.concat(Tai_align.Create_op(4,$90));
  161. codeSegment.concat(Tai_symbol.Createname_global(hp2.name^,0));
  162. codeSegment.concat(Taicpu.Op_sym(A_JMP,S_NO,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname)));
  163. codeSegment.concat(Tai_symbol_end.Createname(hp2.name^));
  164. {$endif i386}
  165. end;
  166. end
  167. else
  168. Message1(parser_e_no_export_of_variables_for_target,'SunOS');
  169. hp2:=texported_item(hp2.next);
  170. end;
  171. end;
  172. {*****************************************************************************
  173. TLINKERSUNOS
  174. *****************************************************************************}
  175. Constructor TLinkersunos.Create;
  176. begin
  177. Inherited Create;
  178. if NOT Dontlinkstdlibpath Then
  179. LibrarySearchPath.AddPath('/lib;/usr/lib;/usr/X11R6/lib;/opt/sfw/lib',true);
  180. {$ifdef LinkTest}
  181. if (cs_link_staticflag in aktglobalswitches) then WriteLN('ForceLinkStaticFlag');
  182. if (cs_link_static in aktglobalswitches) then WriteLN('LinkStatic-Flag');
  183. if (cs_link_shared in aktglobalswitches) then WriteLN('LinkSynamicFlag');
  184. {$EndIf}
  185. end;
  186. procedure TLinkersunos.SetDefaultInfo;
  187. {
  188. This will also detect which libc version will be used
  189. }
  190. begin
  191. Glibc2:=false;
  192. Glibc21:=false;
  193. with Info do
  194. begin
  195. {$IFDEF GnuLd}
  196. ExeCmd[1]:='gld $OPT $DYNLINK $STATIC $STRIP -L. -o $EXE $RES';
  197. DllCmd[1]:='gld $OPT -shared -L. -o $EXE $RES';
  198. DllCmd[2]:='strip --strip-unneeded $EXE';
  199. DynamicLinker:=''; { Gnu uses the default }
  200. Glibc21:=false;
  201. {$ELSE}
  202. Not Implememted
  203. {$ENDIF}
  204. (* Linux Stuff not needed?
  205. { first try glibc2 } // muss noch gendert werden
  206. if FileExists(DynamicLinker) then
  207. begin
  208. Glibc2:=true;
  209. { Check for 2.0 files, else use the glibc 2.1 stub }
  210. if FileExists('/lib/ld-2.0.*') then
  211. Glibc21:=false
  212. else
  213. Glibc21:=true;
  214. end
  215. else
  216. DynamicLinker:='/lib/ld-linux.so.1';
  217. *)
  218. end;
  219. end;
  220. Function TLinkersunos.WriteResponseFile(isdll:boolean) : Boolean;
  221. Var
  222. linkres : TLinkRes;
  223. i : longint;
  224. cprtobj,
  225. gprtobj,
  226. prtobj : string[80];
  227. HPath : TStringListItem;
  228. s,s2 : string;
  229. linkdynamic,
  230. linklibc : boolean;
  231. begin
  232. WriteResponseFile:=False;
  233. { set special options for some targets }
  234. linkdynamic:=not(SharedLibFiles.empty);
  235. { linkdynamic:=false; // da nicht getestet }
  236. linklibc:=(SharedLibFiles.Find('c')<>nil);
  237. prtobj:='prt0';
  238. cprtobj:='cprt0';
  239. gprtobj:='gprt0';
  240. if cs_profile in aktmoduleswitches then
  241. begin
  242. prtobj:=gprtobj;
  243. if not glibc2 then
  244. AddSharedLibrary('gmon');
  245. AddSharedLibrary('c');
  246. linklibc:=true;
  247. end
  248. else
  249. begin
  250. if linklibc then
  251. prtobj:=cprtobj
  252. else
  253. AddSharedLibrary('c'); { quick hack: this sunos implementation needs alwys libc }
  254. end;
  255. { Open link.res file }
  256. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  257. { Write path to search libraries }
  258. HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
  259. while assigned(HPath) do
  260. begin
  261. LinkRes.Add('SEARCH_DIR('+HPath.Str+')');
  262. HPath:=TStringListItem(HPath.Next);
  263. end;
  264. HPath:=TStringListItem(LibrarySearchPath.First);
  265. while assigned(HPath) do
  266. begin
  267. LinkRes.Add('SEARCH_DIR('+HPath.Str+')');
  268. HPath:=TStringListItem(HPath.Next);
  269. end;
  270. LinkRes.Add('INPUT(');
  271. { add objectfiles, start with prt0 always }
  272. if prtobj<>'' then
  273. LinkRes.AddFileName(FindObjectFile(prtobj,'',false));
  274. { try to add crti and crtbegin if linking to C }
  275. if linklibc then { Needed in sunos? }
  276. begin
  277. { if librarysearchpath.FindFile('crtbegin.o',s) then
  278. LinkRes.AddFileName(s);}
  279. if librarysearchpath.FindFile('crti.o',s) then
  280. LinkRes.AddFileName(s);
  281. end;
  282. { main objectfiles }
  283. while not ObjectFiles.Empty do
  284. begin
  285. s:=ObjectFiles.GetFirst;
  286. if s<>'' then
  287. LinkRes.AddFileName(s);
  288. end;
  289. LinkRes.Add(')');
  290. { Write staticlibraries }
  291. if not StaticLibFiles.Empty then
  292. begin
  293. LinkRes.Add('GROUP(');
  294. While not StaticLibFiles.Empty do
  295. begin
  296. S:=StaticLibFiles.GetFirst;
  297. LinkRes.AddFileName(s)
  298. end;
  299. LinkRes.Add(')');
  300. end;
  301. { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
  302. here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
  303. if not SharedLibFiles.Empty then
  304. begin
  305. LinkRes.Add('INPUT(');
  306. While not SharedLibFiles.Empty do
  307. begin
  308. S:=SharedLibFiles.GetFirst;
  309. if s<>'c' then
  310. begin
  311. i:=Pos(target_info.sharedlibext,S);
  312. if i>0 then
  313. Delete(S,i,255);
  314. LinkRes.Add('-l'+s);
  315. end
  316. else
  317. begin
  318. linklibc:=true;
  319. linkdynamic:=false; { libc will include the ld-sunos (war ld-linux) for us }
  320. end;
  321. end;
  322. { be sure that libc is the last lib }
  323. if linklibc then
  324. LinkRes.Add('-lc');
  325. { when we have -static for the linker the we also need libgcc }
  326. if (cs_link_staticflag in aktglobalswitches) then begin
  327. LinkRes.Add('-lgcc');
  328. end;
  329. if linkdynamic and (Info.DynamicLinker<>'') then { gld has a default, DynamicLinker is not set in sunos }
  330. LinkRes.AddFileName(Info.DynamicLinker);
  331. LinkRes.Add(')');
  332. end;
  333. { objects which must be at the end }
  334. if linklibc then {needed in sunos ? }
  335. begin
  336. if {librarysearchpath.FindFile('crtend.o',s1) or}
  337. librarysearchpath.FindFile('crtn.o',s2) then
  338. begin
  339. LinkRes.Add('INPUT(');
  340. { LinkRes.AddFileName(s1);}
  341. LinkRes.AddFileName(s2);
  342. LinkRes.Add(')');
  343. end;
  344. end;
  345. { Write and Close response }
  346. linkres.writetodisk;
  347. LinkRes.Free;
  348. WriteResponseFile:=True;
  349. end;
  350. function TLinkersunos.MakeExecutable:boolean;
  351. var
  352. binstr,
  353. cmdstr : string;
  354. success : boolean;
  355. DynLinkStr : string[60];
  356. StaticStr,
  357. StripStr : string[40];
  358. begin
  359. if not(cs_link_extern in aktglobalswitches) then
  360. Message1(exec_i_linking,current_module.exefilename^);
  361. { Create some replacements }
  362. StaticStr:='';
  363. StripStr:='';
  364. DynLinkStr:='';
  365. if (cs_link_staticflag in aktglobalswitches) then
  366. StaticStr:='-Bstatic';
  367. if (cs_link_strip in aktglobalswitches) then
  368. StripStr:='-s';
  369. If (cs_profile in aktmoduleswitches) or
  370. ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
  371. DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
  372. { sunos sets DynamicLinker, but gld will (hopefully) defaults to -Bdynamic and add the default-linker }
  373. { Write used files and libraries }
  374. WriteResponseFile(false);
  375. { Call linker }
  376. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  377. Replace(cmdstr,'$EXE',current_module.exefilename^);
  378. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  379. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  380. Replace(cmdstr,'$STATIC',StaticStr);
  381. Replace(cmdstr,'$STRIP',StripStr);
  382. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  383. success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
  384. { Remove ReponseFile }
  385. {$IFNDEF LinkTest}
  386. if (success) and not(cs_link_extern in aktglobalswitches) then
  387. RemoveFile(outputexedir+Info.ResName);
  388. {$ENDIF}
  389. MakeExecutable:=success; { otherwise a recursive call to link method }
  390. end;
  391. Function TLinkersunos.MakeSharedLibrary:boolean;
  392. var
  393. binstr,
  394. cmdstr : string;
  395. success : boolean;
  396. begin
  397. MakeSharedLibrary:=false;
  398. if not(cs_link_extern in aktglobalswitches) then
  399. Message1(exec_i_linking,current_module.sharedlibfilename^);
  400. { Write used files and libraries }
  401. WriteResponseFile(true);
  402. { Call linker }
  403. SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
  404. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  405. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  406. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  407. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
  408. { Strip the library ? }
  409. if success and (cs_link_strip in aktglobalswitches) then
  410. begin
  411. SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
  412. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  413. success:=DoExec(utilsprefix+FindUtil(binstr),cmdstr,true,false);
  414. end;
  415. { Remove ReponseFile }
  416. {$IFNDEF LinkTest}
  417. if (success) and not(cs_link_extern in aktglobalswitches) then
  418. RemoveFile(outputexedir+Info.ResName);
  419. {$ENDIF}
  420. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  421. end;
  422. {*****************************************************************************
  423. Initialize
  424. *****************************************************************************}
  425. initialization
  426. RegisterExternalLinker(system_i386_sunos_info,TLinkerSunos);
  427. RegisterImport(system_i386_sunos,TImportLibSunos);
  428. RegisterExport(system_i386_sunos,TExportLibSunos);
  429. RegisterTarget(system_i386_sunos_info);
  430. end.
  431. {
  432. $Log$
  433. Revision 1.6 2003-10-11 19:32:04 marco
  434. * -Xd
  435. Revision 1.5 2003/10/03 14:16:48 marco
  436. * -XP<prefix> support
  437. Revision 1.4 2003/04/27 07:29:52 peter
  438. * aktprocdef cleanup, aktprocdef is now always nil when parsing
  439. a new procdef declaration
  440. * aktprocsym removed
  441. * lexlevel removed, use symtable.symtablelevel instead
  442. * implicit init/final code uses the normal genentry/genexit
  443. * funcret state checking updated for new funcret handling
  444. Revision 1.3 2003/04/26 09:16:08 peter
  445. * .o files belonging to the unit are first searched in the same dir
  446. as the .ppu
  447. Revision 1.2 2002/09/09 17:34:17 peter
  448. * tdicationary.replace added to replace and item in a dictionary. This
  449. is only allowed for the same name
  450. * varsyms are inserted in symtable before the types are parsed. This
  451. fixes the long standing "var longint : longint" bug
  452. - consume_idlist and idstringlist removed. The loops are inserted
  453. at the callers place and uses the symtable for duplicate id checking
  454. Revision 1.1 2002/09/06 15:03:50 carl
  455. * moved files to systems directory
  456. Revision 1.29 2002/09/03 16:26:29 daniel
  457. * Make Tprocdef.defs protected
  458. Revision 1.28 2002/08/12 15:08:44 carl
  459. + stab register indexes for powerpc (moved from gdb to cpubase)
  460. + tprocessor enumeration moved to cpuinfo
  461. + linker in target_info is now a class
  462. * many many updates for m68k (will soon start to compile)
  463. - removed some ifdef or correct them for correct cpu
  464. Revision 1.27 2002/08/11 14:32:32 peter
  465. * renamed current_library to objectlibrary
  466. Revision 1.26 2002/08/11 13:24:20 peter
  467. * saving of asmsymbols in ppu supported
  468. * asmsymbollist global is removed and moved into a new class
  469. tasmlibrarydata that will hold the info of a .a file which
  470. corresponds with a single module. Added librarydata to tmodule
  471. to keep the library info stored for the module. In the future the
  472. objectfiles will also be stored to the tasmlibrarydata class
  473. * all getlabel/newasmsymbol and friends are moved to the new class
  474. Revision 1.25 2002/07/26 21:15:46 florian
  475. * rewrote the system handling
  476. Revision 1.24 2002/07/01 18:46:35 peter
  477. * internal linker
  478. * reorganized aasm layer
  479. Revision 1.23 2002/05/18 13:34:27 peter
  480. * readded missing revisions
  481. Revision 1.22 2002/05/16 19:46:53 carl
  482. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  483. + try to fix temp allocation (still in ifdef)
  484. + generic constructor calls
  485. + start of tassembler / tmodulebase class cleanup
  486. Revision 1.20 2002/04/22 18:19:22 carl
  487. - remove use_bound_instruction field
  488. Revision 1.19 2002/04/20 21:43:18 carl
  489. * fix stack size for some targets
  490. + add offset to parameters from frame pointer info.
  491. - remove some unused stuff
  492. Revision 1.18 2002/04/19 15:46:05 peter
  493. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  494. in most cases and not written to the ppu
  495. * add mangeledname_prefix() routine to generate the prefix of
  496. manglednames depending on the current procedure, object and module
  497. * removed static procprefix since the mangledname is now build only
  498. on demand from tprocdef.mangledname
  499. Revision 1.17 2002/04/15 19:16:57 carl
  500. - remove size_of_pointer field
  501. Revision 1.16 2002/03/04 19:10:14 peter
  502. * removed compiler warnings
  503. }