t_sunos.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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,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. const
  423. target_i386_sunos_info : ttargetinfo =
  424. (
  425. target : target_i386_sunos;
  426. name : 'SunOS/ELF for i386';
  427. shortname : 'SunOS';
  428. flags : [tf_under_development];
  429. cpu : i386;
  430. unit_env : 'SUNOSUNITS';
  431. extradefines : 'UNIX;SOLARIS;LIBC';
  432. sourceext : '.pp';
  433. pasext : '.pas';
  434. exeext : '';
  435. defext : '.def';
  436. scriptext : '.sh';
  437. smartext : '.sl';
  438. unitext : '.ppu';
  439. unitlibext : '.ppl';
  440. asmext : '.s';
  441. objext : '.o';
  442. resext : '.res';
  443. resobjext : '.or';
  444. sharedlibext : '.so';
  445. staticlibext : '.a';
  446. staticlibprefix : 'libp';
  447. sharedlibprefix : 'lib';
  448. sharedClibext : '.so';
  449. staticClibext : '.a';
  450. staticClibprefix : 'lib';
  451. sharedClibprefix : 'lib';
  452. Cprefix : '';
  453. newline : #10;
  454. dirsep : '/';
  455. files_case_relevent : true;
  456. assem : as_i386_as;
  457. assemextern : as_i386_as;
  458. link : ld_i386_sunos;
  459. linkextern : ld_i386_sunos;
  460. ar : ar_gnu_ar;
  461. res : res_none;
  462. script : script_unix;
  463. endian : endian_little;
  464. alignment :
  465. (
  466. procalign : 4;
  467. loopalign : 4;
  468. jumpalign : 0;
  469. constalignmin : 0;
  470. constalignmax : 1;
  471. varalignmin : 0;
  472. varalignmax : 1;
  473. localalignmin : 0;
  474. localalignmax : 1;
  475. paraalign : 4;
  476. recordalignmin : 0;
  477. recordalignmax : 2;
  478. maxCrecordalign : 4
  479. );
  480. size_of_pointer : 4;
  481. size_of_longint : 4;
  482. heapsize : 256*1024;
  483. maxheapsize : 32768*1024;
  484. stacksize : 262144;
  485. DllScanSupported:false;
  486. use_bound_instruction : false;
  487. use_function_relative_addresses : true
  488. );
  489. initialization
  490. RegisterLinker(ld_i386_sunos,TLinkerSunos);
  491. RegisterImport(target_i386_sunos,TImportLibSunos);
  492. RegisterExport(target_i386_sunos,TExportLibSunos);
  493. RegisterTarget(target_i386_sunos_info);
  494. end.
  495. {
  496. $Log$
  497. Revision 1.16 2002-03-04 19:10:14 peter
  498. * removed compiler warnings
  499. Revision 1.15 2001/12/15 05:29:36 carl
  500. + crtbegin.o and crtend.o now not linked anymore since they can cause conflicts with
  501. GCC and the native C library...
  502. Revision 1.14 2001/12/09 03:37:38 carl
  503. * Updated SunOS stack size
  504. Revision 1.13 2001/11/02 22:58:12 peter
  505. * procsym definition rewrite
  506. Revision 1.12 2001/09/18 11:32:00 michael
  507. * Fixes win32 linking problems with import libraries
  508. * LINKLIB Libraries are now looked for using C file extensions
  509. * get_exepath fix
  510. Revision 1.11 2001/09/17 21:29:16 peter
  511. * merged netbsd, fpu-overflow from fixes branch
  512. Revision 1.10 2001/08/12 17:57:07 peter
  513. * under development flag for targets
  514. Revision 1.9 2001/08/07 18:47:15 peter
  515. * merged netbsd start
  516. * profile for win32
  517. Revision 1.8 2001/07/01 20:16:21 peter
  518. * alignmentinfo record added
  519. * -Oa argument supports more alignment settings that can be specified
  520. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  521. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  522. required alignment and the maximum usefull alignment. The final
  523. alignment will be choosen per variable size dependent on these
  524. settings
  525. Revision 1.7 2001/06/28 19:46:25 peter
  526. * added override and virtual for constructors
  527. Revision 1.6 2001/06/03 15:15:32 peter
  528. * dllprt0 stub for linux shared libs
  529. * pass -init and -fini for linux shared libs
  530. * libprefix splitted into staticlibprefix and sharedlibprefix
  531. Revision 1.5 2001/06/02 19:22:44 peter
  532. * extradefines field added
  533. Revision 1.4 2001/04/21 15:34:01 peter
  534. * fixed writing of end objects to not output an empty INPUT()
  535. Revision 1.3 2001/04/18 22:02:04 peter
  536. * registration of targets and assemblers
  537. Revision 1.2 2001/04/13 01:22:22 peter
  538. * symtable change to classes
  539. * range check generation and errors fixed, make cycle DEBUG=1 works
  540. * memory leaks fixed
  541. Revision 1.1 2001/02/26 19:43:11 peter
  542. * moved target units to subdir
  543. }