t_sunos.pas 17 KB

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