t_sunos.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  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.set_mangledname(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_longint : 4;
  481. heapsize : 256*1024;
  482. maxheapsize : 32768*1024;
  483. stacksize : 262144;
  484. DllScanSupported:false;
  485. use_bound_instruction : false;
  486. use_function_relative_addresses : true
  487. );
  488. initialization
  489. RegisterLinker(ld_i386_sunos,TLinkerSunos);
  490. RegisterImport(target_i386_sunos,TImportLibSunos);
  491. RegisterExport(target_i386_sunos,TExportLibSunos);
  492. RegisterTarget(target_i386_sunos_info);
  493. end.
  494. {
  495. $Log$
  496. Revision 1.18 2002-04-19 15:46:05 peter
  497. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  498. in most cases and not written to the ppu
  499. * add mangeledname_prefix() routine to generate the prefix of
  500. manglednames depending on the current procedure, object and module
  501. * removed static procprefix since the mangledname is now build only
  502. on demand from tprocdef.mangledname
  503. Revision 1.17 2002/04/15 19:16:57 carl
  504. - remove size_of_pointer field
  505. Revision 1.16 2002/03/04 19:10:14 peter
  506. * removed compiler warnings
  507. Revision 1.15 2001/12/15 05:29:36 carl
  508. + crtbegin.o and crtend.o now not linked anymore since they can cause conflicts with
  509. GCC and the native C library...
  510. Revision 1.14 2001/12/09 03:37:38 carl
  511. * Updated SunOS stack size
  512. Revision 1.13 2001/11/02 22:58:12 peter
  513. * procsym definition rewrite
  514. Revision 1.12 2001/09/18 11:32:00 michael
  515. * Fixes win32 linking problems with import libraries
  516. * LINKLIB Libraries are now looked for using C file extensions
  517. * get_exepath fix
  518. Revision 1.11 2001/09/17 21:29:16 peter
  519. * merged netbsd, fpu-overflow from fixes branch
  520. Revision 1.10 2001/08/12 17:57:07 peter
  521. * under development flag for targets
  522. Revision 1.9 2001/08/07 18:47:15 peter
  523. * merged netbsd start
  524. * profile for win32
  525. Revision 1.8 2001/07/01 20:16:21 peter
  526. * alignmentinfo record added
  527. * -Oa argument supports more alignment settings that can be specified
  528. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  529. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  530. required alignment and the maximum usefull alignment. The final
  531. alignment will be choosen per variable size dependent on these
  532. settings
  533. Revision 1.7 2001/06/28 19:46:25 peter
  534. * added override and virtual for constructors
  535. Revision 1.6 2001/06/03 15:15:32 peter
  536. * dllprt0 stub for linux shared libs
  537. * pass -init and -fini for linux shared libs
  538. * libprefix splitted into staticlibprefix and sharedlibprefix
  539. Revision 1.5 2001/06/02 19:22:44 peter
  540. * extradefines field added
  541. Revision 1.4 2001/04/21 15:34:01 peter
  542. * fixed writing of end objects to not output an empty INPUT()
  543. Revision 1.3 2001/04/18 22:02:04 peter
  544. * registration of targets and assemblers
  545. Revision 1.2 2001/04/13 01:22:22 peter
  546. * symtable change to classes
  547. * range check generation and errors fixed, make cycle DEBUG=1 works
  548. * memory leaks fixed
  549. Revision 1.1 2001/02/26 19:43:11 peter
  550. * moved target units to subdir
  551. }