t_beos.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  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. var
  153. s : string;
  154. i : integer;
  155. begin
  156. Inherited Create;
  157. s:=GetEnv('BELIBRARIES');
  158. { convert to correct format in case under unix system }
  159. for i:=1 to length(s) do
  160. if s[i] = ':' then
  161. s[i] := ';';
  162. { just in case we have a single path : add the ending ; }
  163. { since that is what the compiler expects. }
  164. if pos(';',s) = 0 then
  165. s:=s+';';
  166. LibrarySearchPath.AddPath(s,true); {format:'path1;path2;...'}
  167. end;
  168. procedure TLinkerBeOS.SetDefaultInfo;
  169. begin
  170. with Info do
  171. begin
  172. ExeCmd[1]:='sh $RES $EXE $OPT $STATIC $STRIP -L.';
  173. { ExeCmd[1]:='sh $RES $EXE $OPT $DYNLINK $STATIC $STRIP -L.';}
  174. DllCmd[1]:='sh $RES $EXE $OPT -L.';
  175. { DllCmd[1]:='sh $RES $EXE $OPT -L. -g -nostart -soname=$EXE';
  176. } DllCmd[2]:='strip --strip-unneeded $EXE';
  177. { DynamicLinker:='/lib/ld-beos.so.2';}
  178. end;
  179. end;
  180. function TLinkerBeOS.WriteResponseFile(isdll:boolean;makelib:boolean) : Boolean;
  181. Var
  182. linkres : TLinkRes;
  183. i : integer;
  184. cprtobj,
  185. prtobj : string[80];
  186. HPath : TStringListItem;
  187. s : string;
  188. linklibc : boolean;
  189. begin
  190. WriteResponseFile:=False;
  191. { set special options for some targets }
  192. linklibc:=(SharedLibFiles.Find('root')<>nil);
  193. prtobj:='prt0';
  194. cprtobj:='cprt0';
  195. if (cs_profile in aktmoduleswitches) or
  196. (not SharedLibFiles.Empty) then
  197. begin
  198. AddSharedLibrary('root');
  199. linklibc:=true;
  200. end;
  201. if (not linklibc) and makelib then
  202. begin
  203. linklibc:=true;
  204. cprtobj:='dllprt.o';
  205. end;
  206. if linklibc then
  207. prtobj:=cprtobj;
  208. { Open link.res file }
  209. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
  210. if not isdll then
  211. LinkRes.Add('ld -o $1 $2 $3 $4 $5 $6 $7 $8 $9 \')
  212. else
  213. LinkRes.Add('ld -o $1 -e 0 $2 $3 $4 $5 $6 $7 $8 $9\');
  214. LinkRes.Add('-m elf_i386_be -shared -Bsymbolic \');
  215. { Write path to search libraries }
  216. HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
  217. while assigned(HPath) do
  218. begin
  219. LinkRes.Add('-L'+HPath.Str+' \');
  220. HPath:=TStringListItem(HPath.Next);
  221. end;
  222. HPath:=TStringListItem(LibrarySearchPath.First);
  223. while assigned(HPath) do
  224. begin
  225. LinkRes.Add('-L'+HPath.Str+' \');
  226. HPath:=TStringListItem(HPath.Next);
  227. end;
  228. { try to add crti and crtbegin if linking to C }
  229. if linklibc then
  230. begin
  231. if librarysearchpath.FindFile('crti.o',s) then
  232. LinkRes.AddFileName(s+' \');
  233. if librarysearchpath.FindFile('crtbegin.o',s) then
  234. LinkRes.AddFileName(s+' \');
  235. { s:=librarysearchpath.FindFile('start_dyn.o',found)+'start_dyn.o';
  236. if found then LinkRes.AddFileName(s+' \');}
  237. if prtobj<>'' then
  238. LinkRes.AddFileName(FindObjectFile(prtobj,'')+' \');
  239. if isdll then
  240. LinkRes.AddFileName(FindObjectFile('func.o','')+' \');
  241. if librarysearchpath.FindFile('init_term_dyn.o',s) then
  242. LinkRes.AddFileName(s+' \');
  243. end
  244. else
  245. begin
  246. if prtobj<>'' then
  247. LinkRes.AddFileName(FindObjectFile(prtobj,'')+' \');
  248. end;
  249. { main objectfiles }
  250. while not ObjectFiles.Empty do
  251. begin
  252. s:=ObjectFiles.GetFirst;
  253. if s<>'' then
  254. LinkRes.AddFileName(s+' \');
  255. end;
  256. { LinkRes.Add('-lroot \');
  257. LinkRes.Add('/boot/develop/tools/gnupro/lib/gcc-lib/i586-beos/2.9-beos-991026/crtend.o \');
  258. LinkRes.Add('/boot/develop/lib/x86/crtn.o \');}
  259. { Write staticlibraries }
  260. if not StaticLibFiles.Empty then
  261. begin
  262. While not StaticLibFiles.Empty do
  263. begin
  264. S:=StaticLibFiles.GetFirst;
  265. LinkRes.AddFileName(s+' \')
  266. end;
  267. end;
  268. { Write sharedlibraries like -l<lib> }
  269. if not SharedLibFiles.Empty then
  270. begin
  271. While not SharedLibFiles.Empty do
  272. begin
  273. S:=SharedLibFiles.GetFirst;
  274. if s<>'c' then
  275. begin
  276. i:=Pos(target_info.sharedlibext,S);
  277. if i>0 then
  278. Delete(S,i,255);
  279. LinkRes.Add('-l'+s+' \');
  280. end
  281. else
  282. begin
  283. linklibc:=true;
  284. end;
  285. end;
  286. { be sure that libc is the last lib }
  287. { if linklibc then
  288. LinkRes.Add('-lroot');}
  289. { if linkdynamic and (Info.DynamicLinker<>'') then
  290. LinkRes.AddFileName(Info.DynamicLinker);}
  291. end;
  292. if isdll then
  293. LinkRes.Add('-lroot \');
  294. { objects which must be at the end }
  295. if linklibc then
  296. begin
  297. if librarysearchpath.FindFile('crtend.o',s) then
  298. LinkRes.AddFileName(s+' \');
  299. if librarysearchpath.FindFile('crtn.o',s) then
  300. LinkRes.AddFileName(s+' \');
  301. end;
  302. { Write and Close response }
  303. linkres.Add(' ');
  304. linkres.writetodisk;
  305. linkres.free;
  306. WriteResponseFile:=True;
  307. end;
  308. function TLinkerBeOS.MakeExecutable:boolean;
  309. var
  310. binstr,
  311. cmdstr : string;
  312. success : boolean;
  313. { DynLinkStr : string[60];}
  314. StaticStr,
  315. StripStr : string[40];
  316. begin
  317. if not(cs_link_extern in aktglobalswitches) then
  318. Message1(exec_i_linking,current_module.exefilename^);
  319. { Create some replacements }
  320. StaticStr:='';
  321. StripStr:='';
  322. { DynLinkStr:='';}
  323. if (cs_link_staticflag in aktglobalswitches) then
  324. StaticStr:='-static';
  325. if (cs_link_strip in aktglobalswitches) then
  326. StripStr:='-s';
  327. { If (cs_profile in aktmoduleswitches) or
  328. ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
  329. DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;}
  330. { Write used files and libraries }
  331. WriteResponseFile(false,false);
  332. { Call linker }
  333. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  334. Replace(cmdstr,'$EXE',current_module.exefilename^);
  335. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  336. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  337. Replace(cmdstr,'$STATIC',StaticStr);
  338. Replace(cmdstr,'$STRIP',StripStr);
  339. { Replace(cmdstr,'$DYNLINK',DynLinkStr);}
  340. success:=DoExec(FindUtil(BinStr),CmdStr,true,false);
  341. { Remove ReponseFile }
  342. if (success) and not(cs_link_extern in aktglobalswitches) then
  343. RemoveFile(outputexedir+Info.ResName);
  344. MakeExecutable:=success; { otherwise a recursive call to link method }
  345. end;
  346. Function TLinkerBeOS.MakeSharedLibrary:boolean;
  347. var
  348. binstr,
  349. cmdstr : string;
  350. success : boolean;
  351. begin
  352. MakeSharedLibrary:=false;
  353. if not(cs_link_extern in aktglobalswitches) then
  354. Message1(exec_i_linking,current_module.sharedlibfilename^);
  355. { Write used files and libraries }
  356. WriteResponseFile(true,true);
  357. { Call linker }
  358. SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
  359. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  360. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  361. Replace(cmdstr,'$RES',outputexedir+Info.ResName);
  362. success:=DoExec(FindUtil(binstr),cmdstr,true,false);
  363. { Strip the library ? }
  364. if success and (cs_link_strip in aktglobalswitches) then
  365. begin
  366. SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
  367. Replace(cmdstr,'$EXE',current_module.sharedlibfilename^);
  368. success:=DoExec(FindUtil(binstr),cmdstr,true,false);
  369. end;
  370. { Remove ReponseFile }
  371. if (success) and not(cs_link_extern in aktglobalswitches) then
  372. RemoveFile(outputexedir+Info.ResName);
  373. MakeSharedLibrary:=success; { otherwise a recursive call to link method }
  374. end;
  375. {*****************************************************************************
  376. Initialize
  377. *****************************************************************************}
  378. {$ifdef i386}
  379. const
  380. target_i386_beos_info : ttargetinfo =
  381. (
  382. target : target_i386_BeOS;
  383. name : 'Beos for i386';
  384. shortname : 'Beos';
  385. flags : [tf_under_development];
  386. cpu : i386;
  387. unit_env : 'BEOSUNITS';
  388. extradefines : '';
  389. sourceext : '.pp';
  390. pasext : '.pas';
  391. exeext : '';
  392. defext : '.def';
  393. scriptext : '.sh';
  394. smartext : '.sl';
  395. unitext : '.ppu';
  396. unitlibext : '.ppl';
  397. asmext : '.s';
  398. objext : '.o';
  399. resext : '.res';
  400. resobjext : '.or';
  401. sharedlibext : '.so';
  402. staticlibext : '.a';
  403. staticlibprefix : 'libp';
  404. sharedlibprefix : 'lib';
  405. sharedClibext : '.so';
  406. staticClibext : '.a';
  407. staticClibprefix : 'lib';
  408. sharedClibprefix : 'lib';
  409. Cprefix : '';
  410. newline : #10;
  411. dirsep : '/';
  412. files_case_relevent : true;
  413. assem : as_i386_as;
  414. assemextern : as_i386_as;
  415. link : ld_i386_beos;
  416. linkextern : ld_i386_beos;
  417. ar : ar_gnu_ar;
  418. res : res_none;
  419. script : script_unix;
  420. endian : endian_little;
  421. alignment :
  422. (
  423. procalign : 4;
  424. loopalign : 4;
  425. jumpalign : 0;
  426. constalignmin : 0;
  427. constalignmax : 1;
  428. varalignmin : 0;
  429. varalignmax : 1;
  430. localalignmin : 0;
  431. localalignmax : 1;
  432. paraalign : 4;
  433. recordalignmin : 0;
  434. recordalignmax : 2;
  435. maxCrecordalign : 4
  436. );
  437. size_of_pointer : 4;
  438. size_of_longint : 4;
  439. heapsize : 256*1024;
  440. maxheapsize : 32768*1024;
  441. stacksize : 8192;
  442. DllScanSupported:false;
  443. use_bound_instruction : false;
  444. use_function_relative_addresses : true
  445. );
  446. {$endif i386}
  447. initialization
  448. {$ifdef i386}
  449. RegisterLinker(ld_i386_beos,TLinkerbeos);
  450. RegisterImport(target_i386_beos,timportlibbeos);
  451. RegisterExport(target_i386_beos,texportlibbeos);
  452. RegisterTarget(target_i386_beos_info);
  453. {$endif i386}
  454. end.
  455. {
  456. $Log$
  457. Revision 1.9 2001-10-12 16:05:34 peter
  458. * system lib search fixed (merged)
  459. Revision 1.8 2001/09/18 11:32:00 michael
  460. * Fixes win32 linking problems with import libraries
  461. * LINKLIB Libraries are now looked for using C file extensions
  462. * get_exepath fix
  463. Revision 1.7 2001/09/17 21:29:15 peter
  464. * merged netbsd, fpu-overflow from fixes branch
  465. Revision 1.6 2001/08/12 17:57:07 peter
  466. * under development flag for targets
  467. Revision 1.5 2001/08/07 18:47:15 peter
  468. * merged netbsd start
  469. * profile for win32
  470. Revision 1.4 2001/07/01 20:16:20 peter
  471. * alignmentinfo record added
  472. * -Oa argument supports more alignment settings that can be specified
  473. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  474. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  475. required alignment and the maximum usefull alignment. The final
  476. alignment will be choosen per variable size dependent on these
  477. settings
  478. Revision 1.3 2001/06/28 19:46:25 peter
  479. * added override and virtual for constructors
  480. Revision 1.2 2001/06/03 15:15:31 peter
  481. * dllprt0 stub for linux shared libs
  482. * pass -init and -fini for linux shared libs
  483. * libprefix splitted into staticlibprefix and sharedlibprefix
  484. Revision 1.1 2001/06/02 19:29:37 peter
  485. * beos target
  486. }