assemble.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. {
  2. $Id$
  3. Copyright (c) 1998 by the FPC development team
  4. This unit handles the assemblerfile write and assembler calls of FPC
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************}
  17. unit assemble;
  18. interface
  19. uses
  20. dos,cobjects,globals,aasm;
  21. const
  22. {$ifdef tp}
  23. AsmOutSize=1024;
  24. {$else}
  25. AsmOutSize=10000;
  26. {$endif}
  27. {$ifdef i386}
  28. { tof = (of_none,of_o,of_obj,of_masm,of_att,of_nasm,of_win32) }
  29. AsBin : array[tof] of string[8]=('','as','nasm','masm','as','nasm','asw');
  30. {$endif}
  31. {$ifdef m68k}
  32. { tof = (of_none,of_o,of_gas,of_mot,of_mit) }
  33. AsBin : array[tof] of string[8]=('','','','','');
  34. {$endif}
  35. type
  36. PAsmList=^TAsmList;
  37. TAsmList=object
  38. outcnt : longint;
  39. outbuf : array[0..AsmOutSize-1] of char;
  40. outfile : file;
  41. constructor Init;
  42. destructor Done;
  43. Procedure AsmFlush;
  44. Procedure AsmWrite(const s:string);
  45. Procedure AsmWritePChar(p:pchar);
  46. Procedure AsmWriteLn(const s:string);
  47. Procedure AsmLn;
  48. procedure OpenAsmList(const fn,fn2:string);
  49. procedure CloseAsmList;
  50. procedure WriteTree(p:paasmoutput);virtual;
  51. procedure WriteAsmList;virtual;
  52. end;
  53. PAsmFile=^TAsmFile;
  54. TAsmFile=object
  55. asmlist : pasmlist;
  56. path:dirstr;
  57. asmfile,
  58. objfile,
  59. srcfile,
  60. as_bin : string;
  61. Constructor Init(const fn:string);
  62. Destructor Done;
  63. Function FindAssembler(curr_of:tof):string;
  64. Procedure WriteAsmSource;
  65. Function CallAssembler(const command,para:string):Boolean;
  66. Procedure RemoveAsm;
  67. Function DoAssemble:boolean;
  68. end;
  69. Implementation
  70. uses
  71. script,files,systems,verbose
  72. {$ifdef linux}
  73. ,linux
  74. {$endif}
  75. ,strings
  76. {$ifdef i386}
  77. ,ag386att,ag386int
  78. {$endif}
  79. {$ifdef m68k}
  80. ,ag68kmot,ag68kgas,ag68kmit
  81. {$endif}
  82. ;
  83. Function DoPipe:boolean;
  84. begin
  85. DoPipe:=use_pipe and (not writeasmfile) and (current_module^.output_format=of_o);
  86. end;
  87. {*****************************************************************************
  88. TASMLIST
  89. *****************************************************************************}
  90. Procedure TAsmList.AsmFlush;
  91. begin
  92. if outcnt>0 then
  93. begin
  94. BlockWrite(outfile,outbuf,outcnt);
  95. outcnt:=0;
  96. end;
  97. end;
  98. Procedure TAsmList.AsmWrite(const s:string);
  99. begin
  100. if OutCnt+length(s)>=AsmOutSize then
  101. AsmFlush;
  102. Move(s[1],OutBuf[OutCnt],length(s));
  103. inc(OutCnt,length(s));
  104. end;
  105. Procedure TAsmList.AsmWriteLn(const s:string);
  106. begin
  107. AsmWrite(s);
  108. AsmLn;
  109. end;
  110. Procedure TAsmList.AsmWritePChar(p:pchar);
  111. var
  112. i,j : longint;
  113. begin
  114. i:=StrLen(p);
  115. j:=i;
  116. while j>0 do
  117. begin
  118. i:=min(j,AsmOutSize);
  119. if OutCnt+i>=AsmOutSize then
  120. AsmFlush;
  121. Move(p[0],OutBuf[OutCnt],i);
  122. inc(OutCnt,i);
  123. dec(j,i);
  124. p:=pchar(@p[i]);
  125. end;
  126. end;
  127. Procedure TAsmList.AsmLn;
  128. begin
  129. if OutCnt>=AsmOutSize-2 then
  130. AsmFlush;
  131. OutBuf[OutCnt]:=target_info.newline[1];
  132. inc(OutCnt);
  133. if length(target_info.newline)>1 then
  134. begin
  135. OutBuf[OutCnt]:=target_info.newline[2];
  136. inc(OutCnt);
  137. end;
  138. end;
  139. procedure TAsmList.OpenAsmList(const fn,fn2:string);
  140. begin
  141. {$ifdef linux}
  142. if DoPipe then
  143. begin
  144. Message1(exec_i_assembling_pipe,fn);
  145. POpen(outfile,'as -o '+fn2,'W');
  146. end
  147. else
  148. {$endif}
  149. begin
  150. Assign(outfile,fn);
  151. {$I-}
  152. Rewrite(outfile,1);
  153. {$I+}
  154. if ioresult<>0 then
  155. Message1(exec_d_cant_create_asmfile,fn);
  156. end;
  157. outcnt:=0;
  158. end;
  159. procedure TAsmList.CloseAsmList;
  160. var
  161. f : file;
  162. l : longint;
  163. begin
  164. AsmFlush;
  165. {$ifdef linux}
  166. if DoPipe then
  167. Close(outfile)
  168. else
  169. {$endif}
  170. begin
  171. {Touch Assembler time to ppu time is there is a ppufilename}
  172. if Assigned(current_module^.ppufilename) then
  173. begin
  174. Assign(f,current_module^.ppufilename^);
  175. reset(f,1);
  176. if ioresult=0 then
  177. begin
  178. getftime(f,l);
  179. close(f);
  180. reset(outfile,1);
  181. setftime(outfile,l);
  182. end;
  183. end;
  184. close(outfile);
  185. end;
  186. end;
  187. procedure TAsmList.WriteTree(p:paasmoutput);
  188. begin
  189. end;
  190. procedure TAsmList.WriteAsmList;
  191. begin
  192. end;
  193. constructor TAsmList.Init;
  194. begin
  195. OutCnt:=0;
  196. end;
  197. destructor TAsmList.Done;
  198. begin
  199. end;
  200. {*****************************************************************************
  201. TASMFILE
  202. *****************************************************************************}
  203. Constructor TAsmFile.Init(const fn:string);
  204. var
  205. name:namestr;
  206. ext:extstr;
  207. begin
  208. {Create filenames for easier access}
  209. fsplit(fn,path,name,ext);
  210. srcfile:=fn;
  211. asmfile:=path+name+target_info.asmext;
  212. objfile:=path+name+target_info.objext;
  213. {Init output format}
  214. case current_module^.output_format of
  215. {$ifdef i386}
  216. of_o,
  217. of_win32,
  218. of_att:
  219. asmlist:=new(pi386attasmlist,Init);
  220. of_obj,
  221. of_masm,
  222. of_nasm:
  223. asmlist:=new(pi386intasmlist,Init);
  224. {$endif}
  225. {$ifdef m68k}
  226. of_o,
  227. of_gas : asmlist:=new(pm68kgasasmlist,Init);
  228. of_mot : asmlist:=new(pm68kmotasmlist,Init);
  229. of_mit : asmlist:=new(pm68kmitasmlist,Init);
  230. {$endif}
  231. else
  232. internalerror(30000);
  233. end;
  234. end;
  235. Destructor TAsmFile.Done;
  236. begin
  237. end;
  238. Procedure TAsmFile.WriteAsmSource;
  239. begin
  240. asmlist^.OpenAsmList(asmfile,objfile);
  241. asmlist^.WriteAsmList;
  242. asmlist^.CloseAsmList;
  243. end;
  244. const
  245. last_of : tof=of_none;
  246. var
  247. LastASBin : string;
  248. Function TAsmFile.FindAssembler(curr_of:tof):string;
  249. var
  250. asfound : boolean;
  251. begin
  252. if last_of<>curr_of then
  253. begin
  254. last_of:=curr_of;
  255. LastASBin:=FindExe(asbin[curr_of],asfound);
  256. if (not asfound) and (not externasm) then
  257. begin
  258. Message1(exec_w_assembler_not_found,LastASBin);
  259. externasm:=true;
  260. end;
  261. if asfound then
  262. Message1(exec_u_using_assembler,LastASBin);
  263. end;
  264. FindAssembler:=LastASBin;
  265. end;
  266. Function TAsmFile.CallAssembler(const command,para:string):Boolean;
  267. begin
  268. if not externasm then
  269. begin
  270. swapvectors;
  271. exec(command,para);
  272. swapvectors;
  273. if (dosexitcode<>0) then
  274. begin
  275. Message(exec_w_error_while_assembling);
  276. callassembler:=false;
  277. exit;
  278. end
  279. else
  280. if (doserror<>0) then
  281. begin
  282. Message(exec_w_cant_call_assembler);
  283. externasm:=true;
  284. end;
  285. end;
  286. if externasm then
  287. AsmRes.AddAsmCommand(command,para,asmfile);
  288. callassembler:=true;
  289. end;
  290. procedure TAsmFile.RemoveAsm;
  291. var
  292. g : file;
  293. i : word;
  294. begin
  295. if writeasmfile then
  296. exit;
  297. if ExternAsm then
  298. AsmRes.AddDeleteCommand (AsmFile)
  299. else
  300. begin
  301. assign(g,asmfile);
  302. {$I-}
  303. erase(g);
  304. {$I+}
  305. i:=ioresult;
  306. end;
  307. end;
  308. Function TAsmFile.DoAssemble:boolean;
  309. begin
  310. if DoPipe then
  311. exit;
  312. if not externasm then
  313. Message1(exec_i_assembling,asmfile);
  314. case current_module^.output_format of
  315. {$ifdef i386}
  316. of_att : begin
  317. externasm:=true; {Force Extern Asm}
  318. if CallAssembler(FindAssembler(of_att),' -D -o '+objfile+' '+asmfile) then
  319. RemoveAsm;
  320. end;
  321. of_o : begin
  322. if CallAssembler(FindAssembler(of_o),'-D -o '+objfile+' '+asmfile) then
  323. RemoveAsm;
  324. end;
  325. of_win32 : begin
  326. if CallAssembler(FindAssembler(of_win32),'-D -o '+objfile+' '+asmfile) then
  327. RemoveAsm;
  328. end;
  329. of_nasm : begin
  330. {$ifdef linux}
  331. if CallAssembler(FindAssembler(of_nasm),' -f elf -o '+objfile+' '+asmfile) then
  332. RemoveAsm;
  333. {$else}
  334. if CallAssembler(FindAssembler(of_nasm),' -f coff -o '+objfile+' '+asmfile) then
  335. RemoveAsm;
  336. {$endif}
  337. end;
  338. of_obj : begin
  339. if CallAssembler(FindAssembler(of_nasm),' -f obj -o '+objfile+' '+asmfile) then
  340. RemoveAsm;
  341. end;
  342. of_masm : begin
  343. { !! Nothing yet !! }
  344. end;
  345. {$endif}
  346. {$ifdef m68k}
  347. of_o,
  348. of_mot,
  349. of_mit,
  350. of_gas : begin
  351. { !! Nothing yet !! }
  352. end;
  353. {$endif}
  354. else
  355. internalerror(30000);
  356. end;
  357. DoAssemble:=true;
  358. end;
  359. end.
  360. {
  361. $Log$
  362. Revision 1.3 1998-04-10 14:41:43 peter
  363. * removed some Hints
  364. * small speed optimization for AsmLn
  365. Revision 1.2 1998/04/08 11:34:18 peter
  366. * nasm works (linux only tested)
  367. Revision 1.1.1.1 1998/03/25 11:18:16 root
  368. * Restored version
  369. Revision 1.17 1998/03/10 13:23:00 florian
  370. * small win32 problems fixed
  371. Revision 1.16 1998/03/10 01:17:14 peter
  372. * all files have the same header
  373. * messages are fully implemented, EXTDEBUG uses Comment()
  374. + AG... files for the Assembler generation
  375. Revision 1.15 1998/03/09 10:37:41 peter
  376. * fixed very long pchar writing (> outbufsize)
  377. Revision 1.14 1998/03/05 22:43:45 florian
  378. * some win32 support stuff added
  379. Revision 1.13 1998/03/04 14:18:58 michael
  380. * modified messaging system
  381. Revision 1.12 1998/03/04 01:34:51 peter
  382. * messages for unit-handling and assembler/linker
  383. * the compiler compiles without -dGDB, but doesn't work yet
  384. + -vh for Hint
  385. Revision 1.11 1998/03/02 01:48:05 peter
  386. * renamed target_DOS to target_GO32V1
  387. + new verbose system, merged old errors and verbose units into one new
  388. verbose.pas, so errors.pas is obsolete
  389. Revision 1.10 1998/02/26 11:57:00 daniel
  390. * New assembler optimizations commented out, because of bugs.
  391. * Use of dir-/name- and extstr.
  392. Revision 1.9 1998/02/24 10:29:12 peter
  393. * -a works again
  394. Revision 1.8 1998/02/21 03:31:40 carl
  395. + mit68k asm support.
  396. Revision 1.7 1998/02/18 14:18:16 michael
  397. + added log at end of file (retroactively)
  398. revision 1.6
  399. date: 1998/02/18 13:43:11; author: michael; state: Exp; lines: +3 -19
  400. + Implemented an OS independent AsmRes object.
  401. ----------------------------
  402. revision 1.5
  403. date: 1998/02/17 21:20:28; author: peter; state: Exp; lines: +60 -54
  404. + Script unit
  405. + __EXIT is called again to exit a program
  406. - target_info.link/assembler calls
  407. * linking works again for dos
  408. * optimized a few filehandling functions
  409. * fixed stabs generation for procedures
  410. ----------------------------
  411. revision 1.4
  412. date: 1998/02/16 12:51:27; author: michael; state: Exp; lines: +2 -2
  413. + Implemented linker object
  414. ----------------------------
  415. revision 1.3
  416. date: 1998/02/15 21:15:58; author: peter; state: Exp; lines: +8 -9
  417. * all assembler outputs supported by assemblerobject
  418. * cleanup with assembleroutputs, better .ascii generation
  419. * help_constructor/destructor are now added to the externals
  420. - generation of asmresponse is not outputformat depended
  421. ----------------------------
  422. revision 1.2
  423. date: 1998/02/14 01:45:04; author: peter; state: Exp; lines: +3 -14
  424. * more fixes
  425. - pmode target is removed
  426. - search_as_ld is removed, this is done in the link.pas/assemble.pas
  427. + findexe() to search for an executable (linker,assembler,binder)
  428. ----------------------------
  429. revision 1.1
  430. date: 1998/02/13 22:28:16; author: peter; state: Exp;
  431. + Initial implementation
  432. }