t_beos.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Peter Vreman
  4. This unit implements support import,export,link routines
  5. for the (i386) BeOS 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_beos;
  20. {$i defines.inc}
  21. interface
  22. uses
  23. import,export,link;
  24. type
  25. timportlibbeos=class(timportlib)
  26. procedure preparelib(const s:string);override;
  27. procedure importprocedure(const func,module:string;index:longint;const name:string);override;
  28. procedure importvariable(const varname,module:string;const name:string);override;
  29. procedure generatelib;override;
  30. end;
  31. texportlibbeos=class(texportlib)
  32. procedure preparelib(const s : string);override;
  33. procedure exportprocedure(hp : texported_item);override;
  34. procedure exportvar(hp : texported_item);override;
  35. procedure generatelib;override;
  36. end;
  37. tlinkerbeos=class(tlinker)
  38. private
  39. Function WriteResponseFile(isdll:boolean;makelib:boolean) : Boolean;
  40. public
  41. constructor Create;override;
  42. procedure SetDefaultInfo;override;
  43. function MakeExecutable:boolean;override;
  44. function MakeSharedLibrary:boolean;override;
  45. end;
  46. implementation
  47. uses
  48. dos,
  49. cutils,cclasses,
  50. verbose,systems,globtype,globals,
  51. symconst,script,
  52. fmodule,aasm,cpuasm,cpubase,symsym;
  53. {*****************************************************************************
  54. TIMPORTLIBBEOS
  55. *****************************************************************************}
  56. procedure timportlibbeos.preparelib(const s : string);
  57. begin
  58. end;
  59. procedure timportlibbeos.importprocedure(const func,module : string;index : longint;const name : string);
  60. begin
  61. { insert sharedlibrary }
  62. current_module.linkothersharedlibs.add(SplitName(module),link_allways);
  63. { do nothing with the procedure, only set the mangledname }
  64. if name<>'' then
  65. aktprocsym.definition.setmangledname(name)
  66. else
  67. message(parser_e_empty_import_name);
  68. end;
  69. procedure timportlibbeos.importvariable(const varname,module:string;const name:string);
  70. begin
  71. { insert sharedlibrary }
  72. current_module.linkothersharedlibs.add(SplitName(module),link_allways);
  73. { reset the mangledname and turn off the dll_var option }
  74. aktvarsym.setmangledname(name);
  75. exclude(aktvarsym.varoptions,vo_is_dll_var);
  76. end;
  77. procedure timportlibbeos.generatelib;
  78. begin
  79. end;
  80. {*****************************************************************************
  81. TEXPORTLIBBEOS
  82. *****************************************************************************}
  83. procedure texportlibbeos.preparelib(const s:string);
  84. begin
  85. end;
  86. procedure texportlibbeos.exportprocedure(hp : texported_item);
  87. var
  88. hp2 : texported_item;
  89. begin
  90. { first test the index value }
  91. if (hp.options and eo_index)<>0 then
  92. begin
  93. Message1(parser_e_no_export_with_index_for_target,'beos');
  94. exit;
  95. end;
  96. { now place in correct order }
  97. hp2:=texported_item(current_module._exports.first);
  98. while assigned(hp2) and
  99. (hp.name^>hp2.name^) do
  100. hp2:=texported_item(hp2.next);
  101. { insert hp there !! }
  102. if assigned(hp2) and (hp2.name^=hp.name^) then
  103. begin
  104. { this is not allowed !! }
  105. Message1(parser_e_export_name_double,hp.name^);
  106. exit;
  107. end;
  108. if hp2=texported_item(current_module._exports.first) then
  109. current_module._exports.concat(hp)
  110. else if assigned(hp2) then
  111. begin
  112. hp.next:=hp2;
  113. hp.previous:=hp2.previous;
  114. if assigned(hp2.previous) then
  115. hp2.previous.next:=hp;
  116. hp2.previous:=hp;
  117. end
  118. else
  119. current_module._exports.concat(hp);
  120. end;
  121. procedure texportlibbeos.exportvar(hp : texported_item);
  122. begin
  123. hp.is_var:=true;
  124. exportprocedure(hp);
  125. end;
  126. procedure texportlibbeos.generatelib;
  127. var
  128. hp2 : texported_item;
  129. begin
  130. hp2:=texported_item(current_module._exports.first);
  131. while assigned(hp2) do
  132. begin
  133. if not hp2.is_var then
  134. begin
  135. {$ifdef i386}
  136. { place jump in codesegment }
  137. codesegment.concat(Tai_align.Create_op(4,$90));
  138. codeSegment.concat(Tai_symbol.Createname_global(hp2.name^,0));
  139. codeSegment.concat(Taicpu.Op_sym(A_JMP,S_NO,newasmsymbol(hp2.sym.mangledname)));
  140. codeSegment.concat(Tai_symbol_end.Createname(hp2.name^));
  141. {$endif i386}
  142. end
  143. else
  144. Message1(parser_e_no_export_of_variables_for_target,'beos');
  145. hp2:=texported_item(hp2.next);
  146. end;
  147. end;
  148. {*****************************************************************************
  149. TLINKERBEOS
  150. *****************************************************************************}
  151. Constructor TLinkerBeos.Create;
  152. begin
  153. Inherited Create;
  154. LibrarySearchPath.AddPath(GetEnv('BELIBRARIES'),true); {format:'path1;path2;...'}
  155. end;
  156. procedure TLinkerBeOS.SetDefaultInfo;
  157. begin
  158. with Info do
  159. begin
  160. ExeCmd[1]:='sh $RES $EXE $OPT $STATIC $STRIP -L.';
  161. { ExeCmd[1]:='sh $RES $EXE $OPT $DYNLINK $STATIC $STRIP -L.';}
  162. DllCmd[1]:='sh $RES $EXE $OPT -L.';
  163. { DllCmd[1]:='sh $RES $EXE $OPT -L. -g -nostart -soname=$EXE';
  164. } DllCmd[2]:='strip --strip-unneeded $EXE';
  165. { DynamicLinker:='/lib/ld-beos.so.2';}
  166. end;
  167. end;
  168. function TLinkerBeOS.WriteResponseFile(isdll:boolean;makelib:boolean) : Boolean;
  169. Var
  170. linkres : TLinkRes;
  171. i : integer;
  172. cprtobj,
  173. prtobj : string[80];
  174. HPath : TStringListItem;
  175. s : string;
  176. linklibc : boolean;
  177. begin
  178. WriteResponseFile:=False;
  179. { set special options for some targets }
  180. linklibc:=(SharedLibFiles.Find('root')<>nil);
  181. prtobj:='prt0';
  182. cprtobj:='cprt0';
  183. if (cs_profile in aktmoduleswitches) or
  184. (not SharedLibFiles.Empty) then
  185. begin
  186. AddSharedLibrary('root');
  187. linklibc:=true;
  188. end;
  189. if (not linklibc) and makelib then
  190. begin
  191. linklibc:=true;
  192. cprtobj:='dllprt.o';
  193. end;
  194. if linklibc then
  195. prtobj:=cprtobj;
  196. { Open link.res file }
  197. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  198. if not isdll then
  199. LinkRes.Add('ld -o $1 $2 $3 $4 $5 $6 $7 $8 $9 \')
  200. else
  201. LinkRes.Add('ld -o $1 -e 0 $2 $3 $4 $5 $6 $7 $8 $9\');
  202. LinkRes.Add('-m elf_i386_be -shared -Bsymbolic \');
  203. { Write path to search libraries }
  204. HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
  205. while assigned(HPath) do
  206. begin
  207. LinkRes.Add('-L'+HPath.Str+' \');
  208. HPath:=TStringListItem(HPath.Next);
  209. end;
  210. HPath:=TStringListItem(LibrarySearchPath.First);
  211. while assigned(HPath) do
  212. begin
  213. LinkRes.Add('-L'+HPath.Str+' \');
  214. HPath:=TStringListItem(HPath.Next);
  215. end;
  216. { try to add crti and crtbegin if linking to C }
  217. if linklibc then
  218. begin
  219. if librarysearchpath.FindFile('crti.o',s) then
  220. LinkRes.AddFileName(s+' \');
  221. if librarysearchpath.FindFile('crtbegin.o',s) then
  222. LinkRes.AddFileName(s+' \');
  223. { s:=librarysearchpath.FindFile('start_dyn.o',found)+'start_dyn.o';
  224. if found then LinkRes.AddFileName(s+' \');}
  225. if prtobj<>'' then
  226. LinkRes.AddFileName(FindObjectFile(prtobj,'')+' \');
  227. if isdll then
  228. LinkRes.AddFileName(FindObjectFile('func.o','')+' \');
  229. if librarysearchpath.FindFile('init_term_dyn.o',s) then
  230. LinkRes.AddFileName(s+' \');
  231. end
  232. else
  233. begin
  234. if prtobj<>'' then
  235. LinkRes.AddFileName(FindObjectFile(prtobj,'')+' \');
  236. end;
  237. { main objectfiles }
  238. while not ObjectFiles.Empty do
  239. begin
  240. s:=ObjectFiles.GetFirst;
  241. if s<>'' then
  242. LinkRes.AddFileName(s+' \');
  243. end;
  244. { LinkRes.Add('-lroot \');
  245. LinkRes.Add('/boot/develop/tools/gnupro/lib/gcc-lib/i586-beos/2.9-beos-991026/crtend.o \');
  246. LinkRes.Add('/boot/develop/lib/x86/crtn.o \');}
  247. { Write staticlibraries }
  248. if not StaticLibFiles.Empty then
  249. begin
  250. While not StaticLibFiles.Empty do
  251. begin
  252. S:=StaticLibFiles.GetFirst;
  253. LinkRes.AddFileName(s+' \')
  254. end;
  255. end;
  256. { Write sharedlibraries like -l<lib> }
  257. if not SharedLibFiles.Empty then
  258. begin
  259. While not SharedLibFiles.Empty do
  260. begin
  261. S:=SharedLibFiles.GetFirst;
  262. if s<>'c' then
  263. begin
  264. i:=Pos(target_info.sharedlibext,S);
  265. if i>0 then
  266. Delete(S,i,255);
  267. LinkRes.Add('-l'+s+' \');
  268. end
  269. else
  270. begin
  271. linklibc:=true;
  272. end;
  273. end;
  274. { be sure that libc is the last lib }
  275. { if linklibc then
  276. LinkRes.Add('-lroot');}
  277. { if linkdynamic and (Info.DynamicLinker<>'') then
  278. LinkRes.AddFileName(Info.DynamicLinker);}
  279. end;
  280. if isdll then
  281. LinkRes.Add('-lroot \');
  282. { objects which must be at the end }
  283. if linklibc then
  284. begin
  285. if librarysearchpath.FindFile('crtend.o',s) then
  286. LinkRes.AddFileName(s+' \');
  287. if librarysearchpath.FindFile('crtn.o',s) then
  288. LinkRes.AddFileName(s+' \');
  289. end;
  290. { Write and Close response }
  291. linkres.Add(' ');
  292. linkres.writetodisk;
  293. linkres.free;
  294. WriteResponseFile:=True;
  295. end;
  296. function TLinkerBeOS.MakeExecutable:boolean;
  297. var
  298. binstr,
  299. cmdstr : string;
  300. success : boolean;
  301. { DynLinkStr : string[60];}
  302. StaticStr,
  303. StripStr : string[40];
  304. begin
  305. if not(cs_link_extern in aktglobalswitches) then
  306. Message1(exec_i_linking,current_module.exefilename^);
  307. { Create some replacements }
  308. StaticStr:='';
  309. StripStr:='';
  310. { DynLinkStr:='';}
  311. if (cs_link_staticflag in aktglobalswitches) then
  312. StaticStr:='-static';
  313. if (cs_link_strip in aktglobalswitches) then
  314. StripStr:='-s';
  315. { If (cs_profile in aktmoduleswitches) or
  316. ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
  317. DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;}
  318. { Write used files and libraries }
  319. WriteResponseFile(false,false);
  320. { Call linker }
  321. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  322. Replace(cmdstr,'$EXE',current_module.exefilename^);
  323. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  324. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  325. Replace(cmdstr,'$STATIC',StaticStr);
  326. Replace(cmdstr,'$STRIP',StripStr);
  327. { Replace(cmdstr,'$DYNLINK',DynLinkStr);}
  328. success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
  329. { Remove ReponseFile }
  330. if (success) and not(cs_link_extern in aktglobalswitches) then
  331. RemoveFile(outputexedir+Info.ResName);
  332. MakeExecutable:=success; { otherwise a recursive call to link method }
  333. end;
  334. Function TLinkerBeOS.MakeSharedLibrary:boolean;
  335. var
  336. binstr,
  337. cmdstr : string;
  338. success : boolean;
  339. begin
  340. MakeSharedLibrary:=false;
  341. if not(cs_link_extern in aktglobalswitches) then
  342. Message1(exec_i_linking,current_module.sharedlibfilename^);
  343. { Write used files and libraries }
  344. WriteResponseFile(true,true);
  345. { Call linker }
  346. SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
  347. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  348. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  349. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  350. success:=DoExec(FindUtil(binstr),cmdstr,true,false);
  351. { Strip the library ? }
  352. if success and (cs_link_strip in aktglobalswitches) then
  353. begin
  354. SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
  355. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  356. success:=DoExec(FindUtil(binstr),cmdstr,true,false);
  357. end;
  358. { Remove ReponseFile }
  359. if (success) and not(cs_link_extern in aktglobalswitches) then
  360. RemoveFile(outputexedir+Info.ResName);
  361. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  362. end;
  363. {*****************************************************************************
  364. Initialize
  365. *****************************************************************************}
  366. {$ifdef i386}
  367. const
  368. target_i386_beos_info : ttargetinfo =
  369. (
  370. target : target_i386_BeOS;
  371. name : 'Beos for i386';
  372. shortname : 'Beos';
  373. flags : [];
  374. cpu : i386;
  375. unit_env : 'BEOSUNITS';
  376. extradefines : '';
  377. sharedlibext : '.so';
  378. staticlibext : '.a';
  379. sourceext : '.pp';
  380. pasext : '.pas';
  381. exeext : '';
  382. defext : '.def';
  383. scriptext : '.sh';
  384. smartext : '.sl';
  385. unitext : '.ppu';
  386. unitlibext : '.ppl';
  387. asmext : '.s';
  388. objext : '.o';
  389. resext : '.res';
  390. resobjext : '.or';
  391. staticlibprefix : 'libp';
  392. sharedlibprefix : 'lib';
  393. Cprefix : '';
  394. newline : #10;
  395. assem : as_i386_as;
  396. assemextern : as_i386_as;
  397. link : ld_i386_beos;
  398. linkextern : ld_i386_beos;
  399. ar : ar_gnu_ar;
  400. res : res_none;
  401. endian : endian_little;
  402. alignment :
  403. (
  404. procalign : 4;
  405. loopalign : 4;
  406. jumpalign : 0;
  407. constalignmin : 0;
  408. constalignmax : 1;
  409. varalignmin : 0;
  410. varalignmax : 1;
  411. localalignmin : 0;
  412. localalignmax : 1;
  413. paraalign : 4;
  414. recordalignmin : 0;
  415. recordalignmax : 2;
  416. maxCrecordalign : 4
  417. );
  418. size_of_pointer : 4;
  419. size_of_longint : 4;
  420. heapsize : 256*1024;
  421. maxheapsize : 32768*1024;
  422. stacksize : 8192;
  423. DllScanSupported:false;
  424. use_bound_instruction : false;
  425. use_function_relative_addresses : true
  426. );
  427. {$endif i386}
  428. initialization
  429. {$ifdef i386}
  430. RegisterLinker(ld_i386_beos,TLinkerbeos);
  431. RegisterImport(target_i386_beos,timportlibbeos);
  432. RegisterExport(target_i386_beos,texportlibbeos);
  433. RegisterTarget(target_i386_beos_info);
  434. {$endif i386}
  435. end.
  436. {
  437. $Log$
  438. Revision 1.4 2001-07-01 20:16:20 peter
  439. * alignmentinfo record added
  440. * -Oa argument supports more alignment settings that can be specified
  441. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  442. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  443. required alignment and the maximum usefull alignment. The final
  444. alignment will be choosen per variable size dependent on these
  445. settings
  446. Revision 1.3 2001/06/28 19:46:25 peter
  447. * added override and virtual for constructors
  448. Revision 1.2 2001/06/03 15:15:31 peter
  449. * dllprt0 stub for linux shared libs
  450. * pass -init and -fini for linux shared libs
  451. * libprefix splitted into staticlibprefix and sharedlibprefix
  452. Revision 1.1 2001/06/02 19:29:37 peter
  453. * beos target
  454. }