t_beos.pas 17 KB

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