t_sunos.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 defines.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,aasm,cpuasm,cpubase,symsym,
  32. import,export,link;
  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(const varname,module:string;const name: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(tlinker)
  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(const varname,module:string;const name: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. aktvarsym.setmangledname(name);
  85. exclude(aktvarsym.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).defs^.def.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,newasmsymbol(tprocsym(hp2.sym).defs^.def.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,s1,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 glibc21 then
  238. begin
  239. cprtobj:='cprt21';
  240. gprtobj:='gprt21';
  241. end;
  242. *)
  243. if cs_profile in aktmoduleswitches then
  244. begin
  245. prtobj:=gprtobj;
  246. if not glibc2 then
  247. AddSharedLibrary('gmon');
  248. AddSharedLibrary('c');
  249. linklibc:=true;
  250. end
  251. else
  252. begin
  253. if linklibc then
  254. prtobj:=cprtobj
  255. else
  256. AddSharedLibrary('c'); { quick hack: this sunos implementation needs alwys libc }
  257. end;
  258. { Open link.res file }
  259. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  260. { Write path to search libraries }
  261. HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
  262. while assigned(HPath) do
  263. begin
  264. LinkRes.Add('SEARCH_DIR('+HPath.Str+')');
  265. HPath:=TStringListItem(HPath.Next);
  266. end;
  267. HPath:=TStringListItem(LibrarySearchPath.First);
  268. while assigned(HPath) do
  269. begin
  270. LinkRes.Add('SEARCH_DIR('+HPath.Str+')');
  271. HPath:=TStringListItem(HPath.Next);
  272. end;
  273. LinkRes.Add('INPUT(');
  274. { add objectfiles, start with prt0 always }
  275. if prtobj<>'' then
  276. LinkRes.AddFileName(FindObjectFile(prtobj,''));
  277. { try to add crti and crtbegin if linking to C }
  278. if linklibc then { Needed in sunos? }
  279. begin
  280. if librarysearchpath.FindFile('crtbegin.o',s) then
  281. LinkRes.AddFileName(s);
  282. if librarysearchpath.FindFile('crti.o',s) then
  283. LinkRes.AddFileName(s);
  284. end;
  285. { main objectfiles }
  286. while not ObjectFiles.Empty do
  287. begin
  288. s:=ObjectFiles.GetFirst;
  289. if s<>'' then
  290. LinkRes.AddFileName(s);
  291. end;
  292. LinkRes.Add(')');
  293. { Write staticlibraries }
  294. if not StaticLibFiles.Empty then
  295. begin
  296. LinkRes.Add('GROUP(');
  297. While not StaticLibFiles.Empty do
  298. begin
  299. S:=StaticLibFiles.GetFirst;
  300. LinkRes.AddFileName(s)
  301. end;
  302. LinkRes.Add(')');
  303. end;
  304. { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
  305. here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
  306. if not SharedLibFiles.Empty then
  307. begin
  308. LinkRes.Add('INPUT(');
  309. While not SharedLibFiles.Empty do
  310. begin
  311. S:=SharedLibFiles.GetFirst;
  312. if s<>'c' then
  313. begin
  314. i:=Pos(target_info.sharedlibext,S);
  315. if i>0 then
  316. Delete(S,i,255);
  317. LinkRes.Add('-l'+s);
  318. end
  319. else
  320. begin
  321. linklibc:=true;
  322. linkdynamic:=false; { libc will include the ld-sunos (war ld-linux) for us }
  323. end;
  324. end;
  325. { be sure that libc is the last lib }
  326. if linklibc then
  327. LinkRes.Add('-lc');
  328. { when we have -static for the linker the we also need libgcc }
  329. if (cs_link_staticflag in aktglobalswitches) then begin
  330. LinkRes.Add('-lgcc');
  331. end;
  332. if linkdynamic and (Info.DynamicLinker<>'') then { gld has a default, DynamicLinker is not set in sunos }
  333. LinkRes.AddFileName(Info.DynamicLinker);
  334. LinkRes.Add(')');
  335. end;
  336. { objects which must be at the end }
  337. if linklibc then {needed in sunos ? }
  338. begin
  339. if librarysearchpath.FindFile('crtend.o',s1) or
  340. librarysearchpath.FindFile('crtn.o',s2) then
  341. begin
  342. LinkRes.Add('INPUT(');
  343. LinkRes.AddFileName(s1);
  344. LinkRes.AddFileName(s2);
  345. LinkRes.Add(')');
  346. end;
  347. end;
  348. { Write and Close response }
  349. linkres.writetodisk;
  350. LinkRes.Free;
  351. WriteResponseFile:=True;
  352. end;
  353. function TLinkersunos.MakeExecutable:boolean;
  354. var
  355. binstr,
  356. cmdstr : string;
  357. success : boolean;
  358. DynLinkStr : string[60];
  359. StaticStr,
  360. StripStr : string[40];
  361. begin
  362. if not(cs_link_extern in aktglobalswitches) then
  363. Message1(exec_i_linking,current_module.exefilename^);
  364. { Create some replacements }
  365. StaticStr:='';
  366. StripStr:='';
  367. DynLinkStr:='';
  368. if (cs_link_staticflag in aktglobalswitches) then
  369. StaticStr:='-Bstatic';
  370. if (cs_link_strip in aktglobalswitches) then
  371. StripStr:='-s';
  372. If (cs_profile in aktmoduleswitches) or
  373. ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
  374. DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;
  375. { sunos sets DynamicLinker, but gld will (hopefully) defaults to -Bdynamic and add the default-linker }
  376. { Write used files and libraries }
  377. WriteResponseFile(false);
  378. { Call linker }
  379. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  380. Replace(cmdstr,'$EXE',current_module.exefilename^);
  381. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  382. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  383. Replace(cmdstr,'$STATIC',StaticStr);
  384. Replace(cmdstr,'$STRIP',StripStr);
  385. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  386. success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
  387. { Remove ReponseFile }
  388. {$IFNDEF LinkTest}
  389. if (success) and not(cs_link_extern in aktglobalswitches) then
  390. RemoveFile(outputexedir+Info.ResName);
  391. {$ENDIF}
  392. MakeExecutable:=success; { otherwise a recursive call to link method }
  393. end;
  394. Function TLinkersunos.MakeSharedLibrary:boolean;
  395. var
  396. binstr,
  397. cmdstr : string;
  398. success : boolean;
  399. begin
  400. MakeSharedLibrary:=false;
  401. if not(cs_link_extern in aktglobalswitches) then
  402. Message1(exec_i_linking,current_module.sharedlibfilename^);
  403. { Write used files and libraries }
  404. WriteResponseFile(true);
  405. { Call linker }
  406. SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
  407. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  408. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  409. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  410. success:=DoExec(FindUtil(binstr),cmdstr,true,false);
  411. { Strip the library ? }
  412. if success and (cs_link_strip in aktglobalswitches) then
  413. begin
  414. SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
  415. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  416. success:=DoExec(FindUtil(binstr),cmdstr,true,false);
  417. end;
  418. { Remove ReponseFile }
  419. {$IFNDEF LinkTest}
  420. if (success) and not(cs_link_extern in aktglobalswitches) then
  421. RemoveFile(outputexedir+Info.ResName);
  422. {$ENDIF}
  423. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  424. end;
  425. {*****************************************************************************
  426. Initialize
  427. *****************************************************************************}
  428. const
  429. target_i386_sunos_info : ttargetinfo =
  430. (
  431. target : target_i386_sunos;
  432. name : 'SunOS/ELF for i386';
  433. shortname : 'SunOS';
  434. flags : [tf_under_development];
  435. cpu : i386;
  436. unit_env : 'SUNOSUNITS';
  437. extradefines : 'UNIX;SOLARIS;LIBC';
  438. sourceext : '.pp';
  439. pasext : '.pas';
  440. exeext : '';
  441. defext : '.def';
  442. scriptext : '.sh';
  443. smartext : '.sl';
  444. unitext : '.ppu';
  445. unitlibext : '.ppl';
  446. asmext : '.s';
  447. objext : '.o';
  448. resext : '.res';
  449. resobjext : '.or';
  450. sharedlibext : '.so';
  451. staticlibext : '.a';
  452. staticlibprefix : 'libp';
  453. sharedlibprefix : 'lib';
  454. sharedClibext : '.so';
  455. staticClibext : '.a';
  456. staticClibprefix : 'lib';
  457. sharedClibprefix : 'lib';
  458. Cprefix : '';
  459. newline : #10;
  460. dirsep : '/';
  461. files_case_relevent : true;
  462. assem : as_i386_as;
  463. assemextern : as_i386_as;
  464. link : ld_i386_sunos;
  465. linkextern : ld_i386_sunos;
  466. ar : ar_gnu_ar;
  467. res : res_none;
  468. script : script_unix;
  469. endian : endian_little;
  470. alignment :
  471. (
  472. procalign : 4;
  473. loopalign : 4;
  474. jumpalign : 0;
  475. constalignmin : 0;
  476. constalignmax : 1;
  477. varalignmin : 0;
  478. varalignmax : 1;
  479. localalignmin : 0;
  480. localalignmax : 1;
  481. paraalign : 4;
  482. recordalignmin : 0;
  483. recordalignmax : 2;
  484. maxCrecordalign : 4
  485. );
  486. size_of_pointer : 4;
  487. size_of_longint : 4;
  488. heapsize : 256*1024;
  489. maxheapsize : 32768*1024;
  490. stacksize : 262144;
  491. DllScanSupported:false;
  492. use_bound_instruction : false;
  493. use_function_relative_addresses : true
  494. );
  495. initialization
  496. RegisterLinker(ld_i386_sunos,TLinkerSunos);
  497. RegisterImport(target_i386_sunos,TImportLibSunos);
  498. RegisterExport(target_i386_sunos,TExportLibSunos);
  499. RegisterTarget(target_i386_sunos_info);
  500. end.
  501. {
  502. $Log$
  503. Revision 1.14 2001-12-09 03:37:38 carl
  504. * Updated SunOS stack size
  505. Revision 1.13 2001/11/02 22:58:12 peter
  506. * procsym definition rewrite
  507. Revision 1.12 2001/09/18 11:32:00 michael
  508. * Fixes win32 linking problems with import libraries
  509. * LINKLIB Libraries are now looked for using C file extensions
  510. * get_exepath fix
  511. Revision 1.11 2001/09/17 21:29:16 peter
  512. * merged netbsd, fpu-overflow from fixes branch
  513. Revision 1.10 2001/08/12 17:57:07 peter
  514. * under development flag for targets
  515. Revision 1.9 2001/08/07 18:47:15 peter
  516. * merged netbsd start
  517. * profile for win32
  518. Revision 1.8 2001/07/01 20:16:21 peter
  519. * alignmentinfo record added
  520. * -Oa argument supports more alignment settings that can be specified
  521. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  522. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  523. required alignment and the maximum usefull alignment. The final
  524. alignment will be choosen per variable size dependent on these
  525. settings
  526. Revision 1.7 2001/06/28 19:46:25 peter
  527. * added override and virtual for constructors
  528. Revision 1.6 2001/06/03 15:15:32 peter
  529. * dllprt0 stub for linux shared libs
  530. * pass -init and -fini for linux shared libs
  531. * libprefix splitted into staticlibprefix and sharedlibprefix
  532. Revision 1.5 2001/06/02 19:22:44 peter
  533. * extradefines field added
  534. Revision 1.4 2001/04/21 15:34:01 peter
  535. * fixed writing of end objects to not output an empty INPUT()
  536. Revision 1.3 2001/04/18 22:02:04 peter
  537. * registration of targets and assemblers
  538. Revision 1.2 2001/04/13 01:22:22 peter
  539. * symtable change to classes
  540. * range check generation and errors fixed, make cycle DEBUG=1 works
  541. * memory leaks fixed
  542. Revision 1.1 2001/02/26 19:43:11 peter
  543. * moved target units to subdir
  544. }