assemble.pas 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Peter Vreman
  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. }
  18. unit assemble;
  19. {$i defines.inc}
  20. interface
  21. { Use multiple passes in the internal assembler to optimize jumps }
  22. {$define MULTIPASS}
  23. uses
  24. {$ifdef Delphi}
  25. sysutils,
  26. dmisc,
  27. {$else Delphi}
  28. strings,
  29. dos,
  30. {$endif Delphi}
  31. systems,globtype,globals,aasm,ogbase;
  32. const
  33. AsmOutSize=32768;
  34. type
  35. TAssembler=class
  36. public
  37. {filenames}
  38. path : pathstr;
  39. name : namestr;
  40. asmfile, { current .s and .o file }
  41. objfile : string;
  42. SmartAsm : boolean;
  43. SmartFilesCount,
  44. SmartHeaderCount : longint;
  45. Constructor Create(smart:boolean);virtual;
  46. Destructor Destroy;override;
  47. procedure NextSmartName(place:tcutplace);
  48. procedure MakeObject;virtual;abstract;
  49. end;
  50. TExternalAssembler=class(TAssembler)
  51. private
  52. procedure CreateSmartLinkPath(const s:string);
  53. protected
  54. {outfile}
  55. AsmSize,
  56. AsmStartSize,
  57. outcnt : longint;
  58. outbuf : array[0..AsmOutSize-1] of char;
  59. outfile : file;
  60. public
  61. Function FindAssembler:string;
  62. Function CallAssembler(const command,para:string):Boolean;
  63. Function DoAssemble:boolean;virtual;
  64. Procedure RemoveAsm;
  65. Procedure AsmFlush;
  66. Procedure AsmClear;
  67. Procedure AsmWrite(const s:string);
  68. Procedure AsmWritePChar(p:pchar);
  69. Procedure AsmWriteLn(const s:string);
  70. Procedure AsmLn;
  71. procedure AsmCreate(Aplace:tcutplace);
  72. procedure AsmClose;
  73. procedure WriteTree(p:TAAsmoutput);virtual;
  74. procedure WriteAsmList;virtual;
  75. public
  76. Constructor Create(smart:boolean);override;
  77. procedure MakeObject;override;
  78. end;
  79. TInternalAssembler=class(TAssembler)
  80. public
  81. constructor create(smart:boolean);override;
  82. destructor destroy;override;
  83. procedure MakeObject;override;
  84. protected
  85. { object alloc and output }
  86. objectalloc : tobjectalloc;
  87. objectoutput : tobjectoutput;
  88. private
  89. { the aasmoutput lists that need to be processed }
  90. lists : byte;
  91. list : array[1..maxoutputlists] of TAAsmoutput;
  92. { current processing }
  93. currlistidx : byte;
  94. currlist : TAAsmoutput;
  95. currpass : byte;
  96. {$ifdef GDB}
  97. n_line : byte; { different types of source lines }
  98. linecount,
  99. includecount : longint;
  100. funcname : tasmsymbol;
  101. stabslastfileinfo : tfileposinfo;
  102. procedure convertstabs(p:pchar);
  103. procedure emitlineinfostabs(nidx,line : longint);
  104. procedure emitstabs(s:string);
  105. procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
  106. procedure StartFileLineInfo;
  107. procedure EndFileLineInfo;
  108. {$endif}
  109. function MaybeNextList(var hp:Tai):boolean;
  110. function TreePass0(hp:Tai):Tai;
  111. function TreePass1(hp:Tai):Tai;
  112. function TreePass2(hp:Tai):Tai;
  113. procedure writetree;
  114. procedure writetreesmart;
  115. end;
  116. TAssemblerClass = class of TAssembler;
  117. Procedure GenerateAsm(smart:boolean);
  118. Procedure OnlyAsm;
  119. procedure RegisterAssembler(const r:tasminfo;c:TAssemblerClass);
  120. procedure InitAssembler;
  121. procedure DoneAssembler;
  122. Implementation
  123. uses
  124. {$ifdef unix}
  125. {$ifdef ver1_0}
  126. linux,
  127. {$else}
  128. unix,
  129. {$endif}
  130. {$endif}
  131. cutils,script,finput,fmodule,verbose,
  132. {$ifdef GDB}
  133. gdb,
  134. {$endif GDB}
  135. cpubase,cpuasm
  136. ;
  137. var
  138. CAssembler : array[tasm] of TAssemblerClass;
  139. {*****************************************************************************
  140. TAssembler
  141. *****************************************************************************}
  142. Constructor TAssembler.Create(smart:boolean);
  143. begin
  144. { load start values }
  145. asmfile:=current_module.asmfilename^;
  146. objfile:=current_module.objfilename^;
  147. name:=Lower(current_module.modulename^);
  148. path:=current_module.outputpath^;
  149. SmartAsm:=smart;
  150. SmartFilesCount:=0;
  151. SmartHeaderCount:=0;
  152. SmartLinkOFiles.Clear;
  153. end;
  154. Destructor TAssembler.Destroy;
  155. begin
  156. end;
  157. procedure TAssembler.NextSmartName(place:tcutplace);
  158. var
  159. s : string;
  160. begin
  161. inc(SmartFilesCount);
  162. if SmartFilesCount>999999 then
  163. Message(asmw_f_too_many_asm_files);
  164. case place of
  165. cut_begin :
  166. begin
  167. inc(SmartHeaderCount);
  168. s:=current_module.asmprefix^+tostr(SmartHeaderCount)+'h';
  169. end;
  170. cut_normal :
  171. s:=current_module.asmprefix^+tostr(SmartHeaderCount)+'s';
  172. cut_end :
  173. s:=current_module.asmprefix^+tostr(SmartHeaderCount)+'t';
  174. end;
  175. AsmFile:=Path+FixFileName(s+tostr(SmartFilesCount)+target_info.asmext);
  176. ObjFile:=Path+FixFileName(s+tostr(SmartFilesCount)+target_info.objext);
  177. { insert in container so it can be cleared after the linking }
  178. SmartLinkOFiles.Insert(Objfile);
  179. end;
  180. {*****************************************************************************
  181. TExternalAssembler
  182. *****************************************************************************}
  183. Function DoPipe:boolean;
  184. begin
  185. DoPipe:=(cs_asm_pipe in aktglobalswitches) and
  186. not(cs_asm_leave in aktglobalswitches)
  187. {$ifdef i386}
  188. and ((aktoutputformat=as_i386_as) or
  189. (aktoutputformat=as_i386_asbsd));
  190. {$endif i386}
  191. {$ifdef m68k}
  192. and ((aktoutputformat=as_m68k_as) or
  193. (aktoutputformat=as_m68k_asbsd));
  194. {$endif m68k}
  195. end;
  196. Constructor TExternalAssembler.Create(smart:boolean);
  197. begin
  198. inherited Create(smart);
  199. if SmartAsm then
  200. begin
  201. path:=FixPath(current_module.outputpath^+FixFileName(current_module.modulename^)+target_info.smartext,false);
  202. CreateSmartLinkPath(path);
  203. end;
  204. Outcnt:=0;
  205. end;
  206. procedure TExternalAssembler.CreateSmartLinkPath(const s:string);
  207. var
  208. dir : searchrec;
  209. hs : string;
  210. begin
  211. if PathExists(s) then
  212. begin
  213. { the path exists, now we clean only all the .o and .s files }
  214. { .o files }
  215. findfirst(s+dirsep+'*'+target_info.objext,anyfile,dir);
  216. while (doserror=0) do
  217. begin
  218. RemoveFile(s+dirsep+dir.name);
  219. findnext(dir);
  220. end;
  221. findclose(dir);
  222. { .s files }
  223. findfirst(s+dirsep+'*'+target_info.asmext,anyfile,dir);
  224. while (doserror=0) do
  225. begin
  226. RemoveFile(s+dirsep+dir.name);
  227. findnext(dir);
  228. end;
  229. findclose(dir);
  230. end
  231. else
  232. begin
  233. hs:=s;
  234. if hs[length(hs)] in ['/','\'] then
  235. delete(hs,length(hs),1);
  236. {$I-}
  237. mkdir(hs);
  238. {$I+}
  239. if ioresult<>0 then;
  240. end;
  241. end;
  242. const
  243. lastas : byte=255;
  244. var
  245. LastASBin : pathstr;
  246. Function TExternalAssembler.FindAssembler:string;
  247. var
  248. asfound : boolean;
  249. UtilExe : string;
  250. begin
  251. asfound:=false;
  252. UtilExe:=AddExtension(target_asm.asmbin,source_info.exeext);
  253. if lastas<>ord(target_asm.id) then
  254. begin
  255. lastas:=ord(target_asm.id);
  256. { is an assembler passed ? }
  257. if utilsdirectory<>'' then
  258. asfound:=FindFile(UtilExe,utilsdirectory,LastASBin);
  259. if not AsFound then
  260. asfound:=FindExe(UtilExe,LastASBin);
  261. if (not asfound) and not(cs_asm_extern in aktglobalswitches) then
  262. begin
  263. Message1(exec_e_assembler_not_found,LastASBin);
  264. aktglobalswitches:=aktglobalswitches+[cs_asm_extern];
  265. end;
  266. if asfound then
  267. Message1(exec_t_using_assembler,LastASBin);
  268. end;
  269. FindAssembler:=LastASBin;
  270. end;
  271. Function TExternalAssembler.CallAssembler(const command,para:string):Boolean;
  272. begin
  273. callassembler:=true;
  274. if not(cs_asm_extern in aktglobalswitches) then
  275. begin
  276. swapvectors;
  277. exec(command,para);
  278. swapvectors;
  279. if (doserror<>0) then
  280. begin
  281. Message1(exec_e_cant_call_assembler,tostr(doserror));
  282. aktglobalswitches:=aktglobalswitches+[cs_asm_extern];
  283. callassembler:=false;
  284. end
  285. else
  286. if (dosexitcode<>0) then
  287. begin
  288. Message1(exec_e_error_while_assembling,tostr(dosexitcode));
  289. callassembler:=false;
  290. end;
  291. end
  292. else
  293. AsmRes.AddAsmCommand(command,para,name);
  294. end;
  295. procedure TExternalAssembler.RemoveAsm;
  296. var
  297. g : file;
  298. begin
  299. if cs_asm_leave in aktglobalswitches then
  300. exit;
  301. if cs_asm_extern in aktglobalswitches then
  302. AsmRes.AddDeleteCommand(AsmFile)
  303. else
  304. begin
  305. assign(g,AsmFile);
  306. {$I-}
  307. erase(g);
  308. {$I+}
  309. if ioresult<>0 then;
  310. end;
  311. end;
  312. Function TExternalAssembler.DoAssemble:boolean;
  313. var
  314. s : string;
  315. begin
  316. DoAssemble:=true;
  317. if DoPipe then
  318. exit;
  319. if not(cs_asm_extern in aktglobalswitches) then
  320. begin
  321. if SmartAsm then
  322. begin
  323. if (SmartFilesCount<=1) then
  324. Message1(exec_i_assembling_smart,name);
  325. end
  326. else
  327. Message1(exec_i_assembling,name);
  328. end;
  329. s:=target_asm.asmcmd;
  330. Replace(s,'$ASM',AsmFile);
  331. Replace(s,'$OBJ',ObjFile);
  332. if CallAssembler(FindAssembler,s) then
  333. RemoveAsm
  334. else
  335. begin
  336. DoAssemble:=false;
  337. GenerateError;
  338. end;
  339. end;
  340. Procedure TExternalAssembler.AsmFlush;
  341. begin
  342. if outcnt>0 then
  343. begin
  344. BlockWrite(outfile,outbuf,outcnt);
  345. outcnt:=0;
  346. end;
  347. end;
  348. Procedure TExternalAssembler.AsmClear;
  349. begin
  350. outcnt:=0;
  351. end;
  352. Procedure TExternalAssembler.AsmWrite(const s:string);
  353. begin
  354. if OutCnt+length(s)>=AsmOutSize then
  355. AsmFlush;
  356. Move(s[1],OutBuf[OutCnt],length(s));
  357. inc(OutCnt,length(s));
  358. inc(AsmSize,length(s));
  359. end;
  360. Procedure TExternalAssembler.AsmWriteLn(const s:string);
  361. begin
  362. AsmWrite(s);
  363. AsmLn;
  364. end;
  365. Procedure TExternalAssembler.AsmWritePChar(p:pchar);
  366. var
  367. i,j : longint;
  368. begin
  369. i:=StrLen(p);
  370. j:=i;
  371. while j>0 do
  372. begin
  373. i:=min(j,AsmOutSize);
  374. if OutCnt+i>=AsmOutSize then
  375. AsmFlush;
  376. Move(p[0],OutBuf[OutCnt],i);
  377. inc(OutCnt,i);
  378. inc(AsmSize,i);
  379. dec(j,i);
  380. p:=pchar(@p[i]);
  381. end;
  382. end;
  383. Procedure TExternalAssembler.AsmLn;
  384. begin
  385. if OutCnt>=AsmOutSize-2 then
  386. AsmFlush;
  387. OutBuf[OutCnt]:=target_info.newline[1];
  388. inc(OutCnt);
  389. inc(AsmSize);
  390. if length(target_info.newline)>1 then
  391. begin
  392. OutBuf[OutCnt]:=target_info.newline[2];
  393. inc(OutCnt);
  394. inc(AsmSize);
  395. end;
  396. end;
  397. procedure TExternalAssembler.AsmCreate(Aplace:tcutplace);
  398. begin
  399. if SmartAsm then
  400. NextSmartName(Aplace);
  401. {$ifdef unix}
  402. if DoPipe then
  403. begin
  404. Message1(exec_i_assembling_pipe,asmfile);
  405. POpen(outfile,'as -o '+objfile,'W');
  406. end
  407. else
  408. {$endif}
  409. begin
  410. Assign(outfile,asmfile);
  411. {$I-}
  412. Rewrite(outfile,1);
  413. {$I+}
  414. if ioresult<>0 then
  415. Message1(exec_d_cant_create_asmfile,asmfile);
  416. end;
  417. outcnt:=0;
  418. AsmSize:=0;
  419. AsmStartSize:=0;
  420. end;
  421. procedure TExternalAssembler.AsmClose;
  422. var
  423. f : file;
  424. l : longint;
  425. begin
  426. AsmFlush;
  427. {$ifdef unix}
  428. if DoPipe then
  429. PClose(outfile)
  430. else
  431. {$endif}
  432. begin
  433. {Touch Assembler time to ppu time is there is a ppufilename}
  434. if Assigned(current_module.ppufilename) then
  435. begin
  436. Assign(f,current_module.ppufilename^);
  437. {$I-}
  438. reset(f,1);
  439. {$I+}
  440. if ioresult=0 then
  441. begin
  442. getftime(f,l);
  443. close(f);
  444. reset(outfile,1);
  445. setftime(outfile,l);
  446. end;
  447. end;
  448. close(outfile);
  449. end;
  450. end;
  451. procedure TExternalAssembler.WriteTree(p:TAAsmoutput);
  452. begin
  453. end;
  454. procedure TExternalAssembler.WriteAsmList;
  455. begin
  456. end;
  457. procedure TExternalAssembler.MakeObject;
  458. begin
  459. AsmCreate(cut_normal);
  460. WriteAsmList;
  461. AsmClose;
  462. DoAssemble;
  463. end;
  464. {*****************************************************************************
  465. TInternalAssembler
  466. *****************************************************************************}
  467. constructor TInternalAssembler.create(smart:boolean);
  468. begin
  469. inherited create(smart);
  470. objectoutput:=nil;
  471. objectalloc:=tobjectalloc.create;
  472. SmartAsm:=smart;
  473. currpass:=0;
  474. end;
  475. destructor TInternalAssembler.destroy;
  476. {$ifdef MEMDEBUG}
  477. var
  478. d : tmemdebug;
  479. {$endif}
  480. begin
  481. {$ifdef MEMDEBUG}
  482. d.init('agbin');
  483. {$endif}
  484. objectoutput.free;
  485. objectalloc.free;
  486. {$ifdef MEMDEBUG}
  487. d.free;
  488. {$endif}
  489. end;
  490. {$ifdef GDB}
  491. procedure TInternalAssembler.convertstabs(p:pchar);
  492. var
  493. ofs,
  494. nidx,nother,ii,i,line,j : longint;
  495. code : integer;
  496. hp : pchar;
  497. reloc : boolean;
  498. sec : tsection;
  499. ps : tasmsymbol;
  500. s : string;
  501. begin
  502. ofs:=0;
  503. reloc:=true;
  504. ps:=nil;
  505. sec:=sec_none;
  506. if p[0]='"' then
  507. begin
  508. i:=1;
  509. { we can have \" inside the string !! PM }
  510. while not ((p[i]='"') and (p[i-1]<>'\')) do
  511. inc(i);
  512. p[i]:=#0;
  513. ii:=i;
  514. hp:=@p[1];
  515. s:=StrPas(@P[i+2]);
  516. end
  517. else
  518. begin
  519. hp:=nil;
  520. s:=StrPas(P);
  521. i:=-2; {needed below (PM) }
  522. end;
  523. { When in pass 1 then only alloc and leave }
  524. if currpass=1 then
  525. begin
  526. objectalloc.staballoc(hp);
  527. if assigned(hp) then
  528. p[i]:='"';
  529. exit;
  530. end;
  531. { Parse the rest of the stabs }
  532. if s='' then
  533. internalerror(33000);
  534. j:=pos(',',s);
  535. if j=0 then
  536. internalerror(33001);
  537. Val(Copy(s,1,j-1),nidx,code);
  538. if code<>0 then
  539. internalerror(33002);
  540. i:=i+2+j;
  541. Delete(s,1,j);
  542. j:=pos(',',s);
  543. if (j=0) then
  544. internalerror(33003);
  545. Val(Copy(s,1,j-1),nother,code);
  546. if code<>0 then
  547. internalerror(33004);
  548. i:=i+j;
  549. Delete(s,1,j);
  550. j:=pos(',',s);
  551. if j=0 then
  552. begin
  553. j:=256;
  554. ofs:=-1;
  555. end;
  556. Val(Copy(s,1,j-1),line,code);
  557. if code<>0 then
  558. internalerror(33005);
  559. if ofs=0 then
  560. begin
  561. Delete(s,1,j);
  562. i:=i+j;
  563. Val(s,ofs,code);
  564. if code=0 then
  565. reloc:=false
  566. else
  567. begin
  568. ofs:=0;
  569. s:=strpas(@p[i]);
  570. { handle asmsymbol or
  571. asmsymbol - asmsymbol }
  572. j:=pos(' ',s);
  573. if j=0 then
  574. j:=pos('-',s);
  575. { single asmsymbol }
  576. if j=0 then
  577. j:=256;
  578. { the symbol can be external
  579. so we must use newasmsymbol and
  580. not getasmsymbol !! PM }
  581. ps:=newasmsymbol(copy(s,1,j-1));
  582. if not assigned(ps) then
  583. internalerror(33006)
  584. else
  585. begin
  586. sec:=ps.section;
  587. ofs:=ps.address;
  588. reloc:=true;
  589. UsedAsmSymbolListInsert(ps);
  590. end;
  591. if j<256 then
  592. begin
  593. i:=i+j;
  594. s:=strpas(@p[i]);
  595. if (s<>'') and (s[1]=' ') then
  596. begin
  597. j:=0;
  598. while (s[j+1]=' ') do
  599. inc(j);
  600. i:=i+j;
  601. s:=strpas(@p[i]);
  602. end;
  603. ps:=getasmsymbol(s);
  604. if not assigned(ps) then
  605. internalerror(33007)
  606. else
  607. begin
  608. if ps.section<>sec then
  609. internalerror(33008);
  610. ofs:=ofs-ps.address;
  611. reloc:=false;
  612. UsedAsmSymbolListInsert(ps);
  613. end;
  614. end;
  615. end;
  616. end;
  617. { external bss need speical handling (PM) }
  618. if assigned(ps) and (ps.section=sec_none) then
  619. begin
  620. if currpass=2 then
  621. begin
  622. objectdata.writesymbol(ps);
  623. objectoutput.exportsymbol(ps);
  624. end;
  625. objectdata.WriteSymStabs(sec,ofs,hp,ps,nidx,nother,line,reloc)
  626. end
  627. else
  628. objectdata.WriteStabs(sec,ofs,hp,nidx,nother,line,reloc);
  629. if assigned(hp) then
  630. p[ii]:='"';
  631. end;
  632. procedure TInternalAssembler.emitlineinfostabs(nidx,line : longint);
  633. var
  634. sec : tsection;
  635. begin
  636. if currpass=1 then
  637. begin
  638. objectalloc.staballoc(nil);
  639. exit;
  640. end;
  641. if (nidx=n_textline) and assigned(funcname) and
  642. (target_info.use_function_relative_addresses) then
  643. objectdata.WriteStabs(sec_code,objectdata.sectionsize(sec_code)-funcname.address,
  644. nil,nidx,0,line,false)
  645. else
  646. begin
  647. if nidx=n_textline then
  648. sec:=sec_code
  649. else if nidx=n_dataline then
  650. sec:=sec_data
  651. else
  652. sec:=sec_bss;
  653. objectdata.WriteStabs(sec,objectdata.sectionsize(sec),
  654. nil,nidx,0,line,true);
  655. end;
  656. end;
  657. procedure TInternalAssembler.emitstabs(s:string);
  658. begin
  659. s:=s+#0;
  660. ConvertStabs(@s[1]);
  661. end;
  662. procedure TInternalAssembler.WriteFileLineInfo(var fileinfo : tfileposinfo);
  663. var
  664. curr_n : byte;
  665. hp : tasmsymbol;
  666. infile : tinputfile;
  667. begin
  668. if not ((cs_debuginfo in aktmoduleswitches) or
  669. (cs_gdb_lineinfo in aktglobalswitches)) then
  670. exit;
  671. { file changed ? (must be before line info) }
  672. if (fileinfo.fileindex<>0) and
  673. (stabslastfileinfo.fileindex<>fileinfo.fileindex) then
  674. begin
  675. infile:=current_module.sourcefiles.get_file(fileinfo.fileindex);
  676. if includecount=0 then
  677. curr_n:=n_sourcefile
  678. else
  679. curr_n:=n_includefile;
  680. { get symbol for this includefile }
  681. hp:=newasmsymboltype('Ltext'+ToStr(IncludeCount),AB_LOCAL,AT_FUNCTION);
  682. if currpass=1 then
  683. begin
  684. hp.setaddress(currpass,objectalloc.currsec,objectalloc.sectionsize,0);
  685. UsedAsmSymbolListInsert(hp);
  686. end
  687. else
  688. objectdata.writesymbol(hp);
  689. { emit stabs }
  690. if (infile.path^<>'') then
  691. EmitStabs('"'+lower(BsToSlash(FixPath(infile.path^,false)))+'",'+tostr(curr_n)+
  692. ',0,0,Ltext'+ToStr(IncludeCount));
  693. EmitStabs('"'+lower(FixFileName(infile.name^))+'",'+tostr(curr_n)+
  694. ',0,0,Ltext'+ToStr(IncludeCount));
  695. inc(includecount);
  696. end;
  697. { line changed ? }
  698. if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
  699. emitlineinfostabs(n_line,fileinfo.line);
  700. stabslastfileinfo:=fileinfo;
  701. end;
  702. procedure TInternalAssembler.StartFileLineInfo;
  703. var
  704. fileinfo : tfileposinfo;
  705. begin
  706. FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
  707. n_line:=n_textline;
  708. funcname:=nil;
  709. linecount:=1;
  710. includecount:=0;
  711. fileinfo.fileindex:=1;
  712. fileinfo.line:=1;
  713. WriteFileLineInfo(fileinfo);
  714. end;
  715. procedure TInternalAssembler.EndFileLineInfo;
  716. var
  717. hp : tasmsymbol;
  718. store_sec : tsection;
  719. begin
  720. if not ((cs_debuginfo in aktmoduleswitches) or
  721. (cs_gdb_lineinfo in aktglobalswitches)) then
  722. exit;
  723. store_sec:=objectalloc.currsec;
  724. objectalloc.setsection(sec_code);
  725. hp:=newasmsymboltype('Letext',AB_LOCAL,AT_FUNCTION);
  726. if currpass=1 then
  727. begin
  728. hp.setaddress(currpass,objectalloc.currsec,objectalloc.sectionsize,0);
  729. UsedAsmSymbolListInsert(hp);
  730. end
  731. else
  732. objectdata.writesymbol(hp);
  733. EmitStabs('"",'+tostr(n_sourcefile)+',0,0,Letext');
  734. objectalloc.setsection(store_sec);
  735. end;
  736. {$endif GDB}
  737. function TInternalAssembler.MaybeNextList(var hp:Tai):boolean;
  738. begin
  739. { maybe end of list }
  740. while not assigned(hp) do
  741. begin
  742. if currlistidx<lists then
  743. begin
  744. inc(currlistidx);
  745. currlist:=list[currlistidx];
  746. hp:=Tai(currList.first);
  747. end
  748. else
  749. begin
  750. MaybeNextList:=false;
  751. exit;
  752. end;
  753. end;
  754. MaybeNextList:=true;
  755. end;
  756. function TInternalAssembler.TreePass0(hp:Tai):Tai;
  757. var
  758. l : longint;
  759. begin
  760. while assigned(hp) do
  761. begin
  762. case hp.typ of
  763. ait_align :
  764. begin
  765. { always use the maximum fillsize in this pass to avoid possible
  766. short jumps to become out of range }
  767. Tai_align(hp).fillsize:=Tai_align(hp).aligntype;
  768. objectalloc.sectionalloc(Tai_align(hp).fillsize);
  769. end;
  770. ait_datablock :
  771. begin
  772. if not SmartAsm then
  773. begin
  774. if not Tai_datablock(hp).is_global then
  775. begin
  776. l:=Tai_datablock(hp).size;
  777. if l>2 then
  778. objectalloc.sectionalign(4)
  779. else if l>1 then
  780. objectalloc.sectionalign(2);
  781. objectalloc.sectionalloc(Tai_datablock(hp).size);
  782. end;
  783. end
  784. else
  785. begin
  786. l:=Tai_datablock(hp).size;
  787. if l>2 then
  788. objectalloc.sectionalign(4)
  789. else if l>1 then
  790. objectalloc.sectionalign(2);
  791. objectalloc.sectionalloc(Tai_datablock(hp).size);
  792. end;
  793. end;
  794. ait_const_32bit :
  795. objectalloc.sectionalloc(4);
  796. ait_const_16bit :
  797. objectalloc.sectionalloc(2);
  798. ait_const_8bit :
  799. objectalloc.sectionalloc(1);
  800. ait_real_80bit :
  801. objectalloc.sectionalloc(10);
  802. ait_real_64bit :
  803. objectalloc.sectionalloc(8);
  804. ait_real_32bit :
  805. objectalloc.sectionalloc(4);
  806. ait_comp_64bit :
  807. objectalloc.sectionalloc(8);
  808. ait_const_rva,
  809. ait_const_symbol :
  810. objectalloc.sectionalloc(4);
  811. ait_section:
  812. objectalloc.setsection(Tai_section(hp).sec);
  813. ait_symbol :
  814. Tai_symbol(hp).sym.setaddress(currpass,objectalloc.currsec,objectalloc.sectionsize,0);
  815. ait_label :
  816. Tai_label(hp).l.setaddress(currpass,objectalloc.currsec,objectalloc.sectionsize,0);
  817. ait_string :
  818. objectalloc.sectionalloc(Tai_string(hp).len);
  819. ait_instruction :
  820. begin
  821. {$ifdef i386}
  822. {$ifndef NOAG386BIN}
  823. { reset instructions which could change in pass 2 }
  824. Taicpu(hp).resetpass2;
  825. objectalloc.sectionalloc(Taicpu(hp).Pass1(objectalloc.sectionsize));
  826. {$endif NOAG386BIN}
  827. {$endif i386}
  828. end;
  829. ait_cut :
  830. if SmartAsm then
  831. break;
  832. end;
  833. hp:=Tai(hp.next);
  834. end;
  835. TreePass0:=hp;
  836. end;
  837. function TInternalAssembler.TreePass1(hp:Tai):Tai;
  838. var
  839. i,l : longint;
  840. begin
  841. while assigned(hp) do
  842. begin
  843. {$ifdef GDB}
  844. { write stabs }
  845. if ((cs_debuginfo in aktmoduleswitches) or
  846. (cs_gdb_lineinfo in aktglobalswitches)) then
  847. begin
  848. if (objectalloc.currsec<>sec_none) and
  849. not(hp.typ in [
  850. ait_label,
  851. ait_regalloc,ait_tempalloc,
  852. ait_stabn,ait_stabs,ait_section,
  853. ait_cut,ait_marker,ait_align,ait_stab_function_name]) then
  854. WriteFileLineInfo(hp.fileinfo);
  855. end;
  856. {$endif GDB}
  857. case hp.typ of
  858. ait_align :
  859. begin
  860. { here we must determine the fillsize which is used in pass2 }
  861. Tai_align(hp).fillsize:=align(objectalloc.sectionsize,Tai_align(hp).aligntype)-
  862. objectalloc.sectionsize;
  863. objectalloc.sectionalloc(Tai_align(hp).fillsize);
  864. end;
  865. ait_datablock :
  866. begin
  867. if objectalloc.currsec<>sec_bss then
  868. Message(asmw_e_alloc_data_only_in_bss);
  869. if not SmartAsm then
  870. begin
  871. if Tai_datablock(hp).is_global then
  872. begin
  873. Tai_datablock(hp).sym.setaddress(currpass,sec_none,Tai_datablock(hp).size,Tai_datablock(hp).size);
  874. { force to be common/external, must be after setaddress as that would
  875. set it to AS_GLOBAL }
  876. Tai_datablock(hp).sym.bind:=AB_COMMON;
  877. end
  878. else
  879. begin
  880. l:=Tai_datablock(hp).size;
  881. if l>2 then
  882. objectalloc.sectionalign(4)
  883. else if l>1 then
  884. objectalloc.sectionalign(2);
  885. Tai_datablock(hp).sym.setaddress(currpass,objectalloc.currsec,objectalloc.sectionsize,
  886. Tai_datablock(hp).size);
  887. objectalloc.sectionalloc(Tai_datablock(hp).size);
  888. end;
  889. end
  890. else
  891. begin
  892. l:=Tai_datablock(hp).size;
  893. if l>2 then
  894. objectalloc.sectionalign(4)
  895. else if l>1 then
  896. objectalloc.sectionalign(2);
  897. Tai_datablock(hp).sym.setaddress(currpass,objectalloc.currsec,objectalloc.sectionsize,Tai_datablock(hp).size);
  898. objectalloc.sectionalloc(Tai_datablock(hp).size);
  899. end;
  900. UsedAsmSymbolListInsert(Tai_datablock(hp).sym);
  901. end;
  902. ait_const_32bit :
  903. objectalloc.sectionalloc(4);
  904. ait_const_16bit :
  905. objectalloc.sectionalloc(2);
  906. ait_const_8bit :
  907. objectalloc.sectionalloc(1);
  908. ait_real_80bit :
  909. objectalloc.sectionalloc(10);
  910. ait_real_64bit :
  911. objectalloc.sectionalloc(8);
  912. ait_real_32bit :
  913. objectalloc.sectionalloc(4);
  914. ait_comp_64bit :
  915. objectalloc.sectionalloc(8);
  916. ait_const_rva,
  917. ait_const_symbol :
  918. begin
  919. objectalloc.sectionalloc(4);
  920. UsedAsmSymbolListInsert(Tai_const_symbol(hp).sym);
  921. end;
  922. ait_section:
  923. begin
  924. objectalloc.setsection(Tai_section(hp).sec);
  925. {$ifdef GDB}
  926. case Tai_section(hp).sec of
  927. sec_code : n_line:=n_textline;
  928. sec_data : n_line:=n_dataline;
  929. sec_bss : n_line:=n_bssline;
  930. else
  931. n_line:=n_dataline;
  932. end;
  933. stabslastfileinfo.line:=-1;
  934. {$endif GDB}
  935. end;
  936. {$ifdef GDB}
  937. ait_stabn :
  938. convertstabs(Tai_stabn(hp).str);
  939. ait_stabs :
  940. convertstabs(Tai_stabs(hp).str);
  941. ait_stab_function_name :
  942. begin
  943. if assigned(Tai_stab_function_name(hp).str) then
  944. begin
  945. funcname:=getasmsymbol(strpas(Tai_stab_function_name(hp).str));
  946. UsedAsmSymbolListInsert(funcname);
  947. end
  948. else
  949. funcname:=nil;
  950. end;
  951. ait_force_line :
  952. stabslastfileinfo.line:=0;
  953. {$endif}
  954. ait_symbol :
  955. begin
  956. Tai_symbol(hp).sym.setaddress(currpass,objectalloc.currsec,objectalloc.sectionsize,0);
  957. UsedAsmSymbolListInsert(Tai_symbol(hp).sym);
  958. end;
  959. ait_symbol_end :
  960. begin
  961. if target_info.target=target_i386_linux then
  962. begin
  963. Tai_symbol(hp).sym.size:=objectalloc.sectionsize-Tai_symbol(hp).sym.address;
  964. UsedAsmSymbolListInsert(Tai_symbol(hp).sym);
  965. end;
  966. end;
  967. ait_label :
  968. begin
  969. Tai_label(hp).l.setaddress(currpass,objectalloc.currsec,objectalloc.sectionsize,0);
  970. UsedAsmSymbolListInsert(Tai_label(hp).l);
  971. end;
  972. ait_string :
  973. objectalloc.sectionalloc(Tai_string(hp).len);
  974. ait_instruction :
  975. begin
  976. {$ifdef i386}
  977. {$ifndef NOAG386BIN}
  978. objectalloc.sectionalloc(Taicpu(hp).Pass1(objectalloc.sectionsize));
  979. { fixup the references }
  980. for i:=1 to Taicpu(hp).ops do
  981. begin
  982. with Taicpu(hp).oper[i-1] do
  983. begin
  984. case typ of
  985. top_ref :
  986. begin
  987. if assigned(ref^.symbol) then
  988. UsedAsmSymbolListInsert(ref^.symbol);
  989. end;
  990. top_symbol :
  991. begin
  992. if sym=nil then
  993. sym:=sym;
  994. UsedAsmSymbolListInsert(sym);
  995. end;
  996. end;
  997. end;
  998. end;
  999. {$endif NOAG386BIN}
  1000. {$endif i386}
  1001. end;
  1002. ait_direct :
  1003. Message(asmw_f_direct_not_supported);
  1004. ait_cut :
  1005. if SmartAsm then
  1006. break;
  1007. end;
  1008. hp:=Tai(hp.next);
  1009. end;
  1010. TreePass1:=hp;
  1011. end;
  1012. function TInternalAssembler.TreePass2(hp:Tai):Tai;
  1013. var
  1014. l : longint;
  1015. {$ifdef i386}
  1016. co : comp;
  1017. {$endif i386}
  1018. begin
  1019. { main loop }
  1020. while assigned(hp) do
  1021. begin
  1022. {$ifdef GDB}
  1023. { write stabs }
  1024. if ((cs_debuginfo in aktmoduleswitches) or
  1025. (cs_gdb_lineinfo in aktglobalswitches)) then
  1026. begin
  1027. if (objectdata.currsec<>sec_none) and
  1028. not(hp.typ in [
  1029. ait_label,
  1030. ait_regalloc,ait_tempalloc,
  1031. ait_stabn,ait_stabs,ait_section,
  1032. ait_cut,ait_marker,ait_align,ait_stab_function_name]) then
  1033. WriteFileLineInfo(hp.fileinfo);
  1034. end;
  1035. {$endif GDB}
  1036. case hp.typ of
  1037. ait_align :
  1038. begin
  1039. if objectdata.currsec=sec_bss then
  1040. objectdata.alloc(Tai_align(hp).fillsize)
  1041. else
  1042. objectdata.writebytes(Tai_align(hp).getfillbuf^,Tai_align(hp).fillsize);
  1043. end;
  1044. ait_section :
  1045. begin
  1046. objectdata.defaultsection(Tai_section(hp).sec);
  1047. {$ifdef GDB}
  1048. case Tai_section(hp).sec of
  1049. sec_code : n_line:=n_textline;
  1050. sec_data : n_line:=n_dataline;
  1051. sec_bss : n_line:=n_bssline;
  1052. else
  1053. n_line:=n_dataline;
  1054. end;
  1055. stabslastfileinfo.line:=-1;
  1056. {$endif GDB}
  1057. end;
  1058. ait_symbol :
  1059. begin
  1060. objectdata.writesymbol(Tai_symbol(hp).sym);
  1061. objectoutput.exportsymbol(Tai_symbol(hp).sym);
  1062. end;
  1063. ait_datablock :
  1064. begin
  1065. objectdata.writesymbol(Tai_datablock(hp).sym);
  1066. objectoutput.exportsymbol(Tai_datablock(hp).sym);
  1067. if SmartAsm or (not Tai_datablock(hp).is_global) then
  1068. begin
  1069. l:=Tai_datablock(hp).size;
  1070. if l>2 then
  1071. objectdata.allocalign(4)
  1072. else if l>1 then
  1073. objectdata.allocalign(2);
  1074. objectdata.alloc(Tai_datablock(hp).size);
  1075. end;
  1076. end;
  1077. ait_const_32bit :
  1078. objectdata.writebytes(Tai_const(hp).value,4);
  1079. ait_const_16bit :
  1080. objectdata.writebytes(Tai_const(hp).value,2);
  1081. ait_const_8bit :
  1082. objectdata.writebytes(Tai_const(hp).value,1);
  1083. ait_real_80bit :
  1084. objectdata.writebytes(Tai_real_80bit(hp).value,10);
  1085. ait_real_64bit :
  1086. objectdata.writebytes(Tai_real_64bit(hp).value,8);
  1087. ait_real_32bit :
  1088. objectdata.writebytes(Tai_real_32bit(hp).value,4);
  1089. ait_comp_64bit :
  1090. begin
  1091. {$ifdef i386}
  1092. {$ifdef FPC}
  1093. co:=comp(Tai_comp_64bit(hp).value);
  1094. {$else}
  1095. co:=Tai_comp_64bit(hp).value;
  1096. {$endif}
  1097. objectdata.writebytes(co,8);
  1098. {$endif i386}
  1099. end;
  1100. ait_string :
  1101. objectdata.writebytes(Tai_string(hp).str^,Tai_string(hp).len);
  1102. ait_const_rva :
  1103. objectdata.writereloc(Tai_const_symbol(hp).offset,4,
  1104. Tai_const_symbol(hp).sym,relative_rva);
  1105. ait_const_symbol :
  1106. objectdata.writereloc(Tai_const_symbol(hp).offset,4,
  1107. Tai_const_symbol(hp).sym,relative_false);
  1108. ait_label :
  1109. begin
  1110. objectdata.writesymbol(Tai_label(hp).l);
  1111. { exporting shouldn't be necessary as labels are local,
  1112. but it's better to be on the safe side (PFV) }
  1113. objectoutput.exportsymbol(Tai_label(hp).l);
  1114. end;
  1115. {$ifdef i386}
  1116. {$ifndef NOAG386BIN}
  1117. ait_instruction :
  1118. Taicpu(hp).Pass2;
  1119. {$endif NOAG386BIN}
  1120. {$endif i386}
  1121. {$ifdef GDB}
  1122. ait_stabn :
  1123. convertstabs(Tai_stabn(hp).str);
  1124. ait_stabs :
  1125. convertstabs(Tai_stabs(hp).str);
  1126. ait_stab_function_name :
  1127. if assigned(Tai_stab_function_name(hp).str) then
  1128. funcname:=getasmsymbol(strpas(Tai_stab_function_name(hp).str))
  1129. else
  1130. funcname:=nil;
  1131. ait_force_line :
  1132. stabslastfileinfo.line:=0;
  1133. {$endif}
  1134. ait_cut :
  1135. if SmartAsm then
  1136. break;
  1137. end;
  1138. hp:=Tai(hp.next);
  1139. end;
  1140. TreePass2:=hp;
  1141. end;
  1142. procedure TInternalAssembler.writetree;
  1143. var
  1144. hp : Tai;
  1145. label
  1146. doexit;
  1147. begin
  1148. objectalloc.resetsections;
  1149. objectalloc.setsection(sec_code);
  1150. objectoutput.initwriting(ObjFile);
  1151. objectdata:=objectoutput.data;
  1152. objectdata.defaultsection(sec_code);
  1153. { reset the asmsymbol list }
  1154. CreateUsedAsmsymbolList;
  1155. {$ifdef MULTIPASS}
  1156. { Pass 0 }
  1157. currpass:=0;
  1158. objectalloc.setsection(sec_code);
  1159. { start with list 1 }
  1160. currlistidx:=1;
  1161. currlist:=list[currlistidx];
  1162. hp:=Tai(currList.first);
  1163. while assigned(hp) do
  1164. begin
  1165. hp:=TreePass0(hp);
  1166. MaybeNextList(hp);
  1167. end;
  1168. { leave if errors have occured }
  1169. if errorcount>0 then
  1170. goto doexit;
  1171. {$endif}
  1172. { Pass 1 }
  1173. currpass:=1;
  1174. objectalloc.resetsections;
  1175. objectalloc.setsection(sec_code);
  1176. {$ifdef GDB}
  1177. StartFileLineInfo;
  1178. {$endif GDB}
  1179. { start with list 1 }
  1180. currlistidx:=1;
  1181. currlist:=list[currlistidx];
  1182. hp:=Tai(currList.first);
  1183. while assigned(hp) do
  1184. begin
  1185. hp:=TreePass1(hp);
  1186. MaybeNextList(hp);
  1187. end;
  1188. {$ifdef GDB}
  1189. EndFileLineInfo;
  1190. {$endif GDB}
  1191. { check for undefined labels and reset }
  1192. UsedAsmSymbolListCheckUndefined;
  1193. { set section sizes }
  1194. objectdata.setsectionsizes(objectalloc.secsize);
  1195. { leave if errors have occured }
  1196. if errorcount>0 then
  1197. goto doexit;
  1198. { Pass 2 }
  1199. currpass:=2;
  1200. {$ifdef GDB}
  1201. StartFileLineInfo;
  1202. {$endif GDB}
  1203. { start with list 1 }
  1204. currlistidx:=1;
  1205. currlist:=list[currlistidx];
  1206. hp:=Tai(currList.first);
  1207. while assigned(hp) do
  1208. begin
  1209. hp:=TreePass2(hp);
  1210. MaybeNextList(hp);
  1211. end;
  1212. {$ifdef GDB}
  1213. EndFileLineInfo;
  1214. {$endif GDB}
  1215. { leave if errors have occured }
  1216. if errorcount>0 then
  1217. goto doexit;
  1218. { write last objectfile }
  1219. objectoutput.donewriting;
  1220. objectdata:=nil;
  1221. doexit:
  1222. { reset the used symbols back, must be after the .o has been
  1223. written }
  1224. UsedAsmsymbolListReset;
  1225. DestroyUsedAsmsymbolList;
  1226. end;
  1227. procedure TInternalAssembler.writetreesmart;
  1228. var
  1229. hp : Tai;
  1230. startsec : tsection;
  1231. place: tcutplace;
  1232. begin
  1233. objectalloc.resetsections;
  1234. objectalloc.setsection(sec_code);
  1235. NextSmartName(cut_normal);
  1236. objectoutput.initwriting(ObjFile);
  1237. objectdata:=objectoutput.data;
  1238. objectdata.defaultsection(sec_code);
  1239. startsec:=sec_code;
  1240. { start with list 1 }
  1241. currlistidx:=1;
  1242. currlist:=list[currlistidx];
  1243. hp:=Tai(currList.first);
  1244. while assigned(hp) do
  1245. begin
  1246. { reset the asmsymbol list }
  1247. CreateUsedAsmSymbolList;
  1248. {$ifdef MULTIPASS}
  1249. { Pass 0 }
  1250. currpass:=0;
  1251. objectalloc.resetsections;
  1252. objectalloc.setsection(startsec);
  1253. TreePass0(hp);
  1254. { leave if errors have occured }
  1255. if errorcount>0 then
  1256. exit;
  1257. {$endif MULTIPASS}
  1258. { Pass 1 }
  1259. currpass:=1;
  1260. objectalloc.resetsections;
  1261. objectalloc.setsection(startsec);
  1262. {$ifdef GDB}
  1263. StartFileLineInfo;
  1264. {$endif GDB}
  1265. TreePass1(hp);
  1266. {$ifdef GDB}
  1267. EndFileLineInfo;
  1268. {$endif GDB}
  1269. { check for undefined labels }
  1270. UsedAsmSymbolListCheckUndefined;
  1271. { set section sizes }
  1272. objectdata.setsectionsizes(objectalloc.secsize);
  1273. { leave if errors have occured }
  1274. if errorcount>0 then
  1275. exit;
  1276. { Pass 2 }
  1277. currpass:=2;
  1278. objectdata.defaultsection(startsec);
  1279. {$ifdef GDB}
  1280. StartFileLineInfo;
  1281. {$endif GDB}
  1282. hp:=TreePass2(hp);
  1283. {$ifdef GDB}
  1284. EndFileLineInfo;
  1285. {$endif GDB}
  1286. { leave if errors have occured }
  1287. if errorcount>0 then
  1288. exit;
  1289. { if not end then write the current objectfile }
  1290. objectoutput.donewriting;
  1291. objectdata:=nil;
  1292. { reset the used symbols back, must be after the .o has been
  1293. written }
  1294. UsedAsmsymbolListReset;
  1295. DestroyUsedAsmsymbolList;
  1296. { end of lists? }
  1297. if not MaybeNextList(hp) then
  1298. break;
  1299. { save section for next loop }
  1300. { this leads to a problem if startsec is sec_none !! PM }
  1301. startsec:=objectalloc.currsec;
  1302. { we will start a new objectfile so reset everything }
  1303. { The place can still change in the next while loop, so don't init }
  1304. { the writer yet (JM) }
  1305. if (hp.typ=ait_cut) then
  1306. place := Tai_cut(hp).place
  1307. else
  1308. place := cut_normal;
  1309. { avoid empty files }
  1310. while assigned(hp) and
  1311. (Tai(hp).typ in [ait_marker,ait_comment,ait_section,ait_cut]) do
  1312. begin
  1313. if Tai(hp).typ=ait_section then
  1314. startsec:=Tai_section(hp).sec
  1315. else if (Tai(hp).typ=ait_cut) then
  1316. place := Tai_cut(hp).place;
  1317. hp:=Tai(hp.next);
  1318. end;
  1319. NextSmartName(place);
  1320. objectoutput.initwriting(ObjFile);
  1321. objectdata:=objectoutput.data;
  1322. { there is a problem if startsec is sec_none !! PM }
  1323. if startsec=sec_none then
  1324. startsec:=sec_code;
  1325. if not MaybeNextList(hp) then
  1326. break;
  1327. end;
  1328. end;
  1329. procedure TInternalAssembler.MakeObject;
  1330. procedure addlist(p:TAAsmoutput);
  1331. begin
  1332. inc(lists);
  1333. list[lists]:=p;
  1334. end;
  1335. begin
  1336. if cs_debuginfo in aktmoduleswitches then
  1337. addlist(debuglist);
  1338. addlist(codesegment);
  1339. addlist(datasegment);
  1340. addlist(consts);
  1341. addlist(rttilist);
  1342. if assigned(resourcestringlist) then
  1343. addlist(resourcestringlist);
  1344. addlist(bsssegment);
  1345. if assigned(importssection) then
  1346. addlist(importssection);
  1347. if assigned(exportssection) and not UseDeffileForExport then
  1348. addlist(exportssection);
  1349. if assigned(resourcesection) then
  1350. addlist(resourcesection);
  1351. if SmartAsm then
  1352. writetreesmart
  1353. else
  1354. writetree;
  1355. end;
  1356. {*****************************************************************************
  1357. Generate Assembler Files Main Procedure
  1358. *****************************************************************************}
  1359. Procedure GenerateAsm(smart:boolean);
  1360. var
  1361. a : TAssembler;
  1362. begin
  1363. if not assigned(CAssembler[target_asm.id]) then
  1364. Message(asmw_f_assembler_output_not_supported);
  1365. a:=CAssembler[target_asm.id].Create(smart);
  1366. a.MakeObject;
  1367. a.Free;
  1368. end;
  1369. Procedure OnlyAsm;
  1370. var
  1371. a : TExternalAssembler;
  1372. begin
  1373. a:=TExternalAssembler.Create(false);
  1374. a.DoAssemble;
  1375. a.Free;
  1376. end;
  1377. {*****************************************************************************
  1378. Init/Done
  1379. *****************************************************************************}
  1380. procedure RegisterAssembler(const r:tasminfo;c:TAssemblerClass);
  1381. var
  1382. t : tasm;
  1383. begin
  1384. t:=r.id;
  1385. if assigned(asminfos[t]) then
  1386. writeln('Warning: Assembler is already registered!')
  1387. else
  1388. Getmem(asminfos[t],sizeof(tasminfo));
  1389. asminfos[t]^:=r;
  1390. CAssembler[t]:=c;
  1391. end;
  1392. procedure InitAssembler;
  1393. begin
  1394. { target_asm is already set by readarguments }
  1395. initoutputformat:=target_asm.id;
  1396. aktoutputformat:=target_asm.id;
  1397. end;
  1398. procedure DoneAssembler;
  1399. begin
  1400. end;
  1401. end.
  1402. {
  1403. $Log$
  1404. Revision 1.26 2001-08-30 20:57:09 peter
  1405. * asbsd merged
  1406. Revision 1.25 2001/08/30 19:43:50 peter
  1407. * detect duplicate labels
  1408. Revision 1.24 2001/08/26 13:36:35 florian
  1409. * some cg reorganisation
  1410. * some PPC updates
  1411. Revision 1.23 2001/08/07 18:47:12 peter
  1412. * merged netbsd start
  1413. * profile for win32
  1414. Revision 1.22 2001/07/01 20:16:15 peter
  1415. * alignmentinfo record added
  1416. * -Oa argument supports more alignment settings that can be specified
  1417. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  1418. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  1419. required alignment and the maximum usefull alignment. The final
  1420. alignment will be choosen per variable size dependent on these
  1421. settings
  1422. Revision 1.21 2001/06/18 20:36:23 peter
  1423. * -Ur switch (merged)
  1424. * masm fixes (merged)
  1425. * quoted filenames for go32v2 and win32
  1426. Revision 1.20 2001/06/13 18:31:57 peter
  1427. * smartlink with dll fixed (merged)
  1428. Revision 1.19 2001/04/21 15:34:49 peter
  1429. * used target_asm.id instead of target_info.assem
  1430. Revision 1.18 2001/04/18 22:01:53 peter
  1431. * registration of targets and assemblers
  1432. Revision 1.17 2001/04/13 01:22:06 peter
  1433. * symtable change to classes
  1434. * range check generation and errors fixed, make cycle DEBUG=1 works
  1435. * memory leaks fixed
  1436. Revision 1.16 2001/03/13 18:42:39 peter
  1437. * don't create temporary smartlink dir for internalassembler
  1438. Revision 1.15 2001/03/05 21:39:11 peter
  1439. * changed to class with common TAssembler also for internal assembler
  1440. Revision 1.14 2001/02/26 08:08:16 michael
  1441. * bug correction: pipes must be closed by pclose (not close);
  1442. There was too many not closed processes under Linux before patch.
  1443. Test this by making a compiler under Linux with command
  1444. OPT="-P" make
  1445. and check a list of processes in another shell with
  1446. ps -xa
  1447. Revision 1.13 2001/02/20 21:36:39 peter
  1448. * tasm/masm fixes merged
  1449. Revision 1.12 2001/02/09 23:06:17 peter
  1450. * fixed uninited var
  1451. Revision 1.11 2001/02/05 20:46:59 peter
  1452. * support linux unit for ver1_0 compilers
  1453. Revision 1.10 2001/01/21 20:32:45 marco
  1454. * Renamefest. Compiler part. Not that hard.
  1455. Revision 1.9 2001/01/12 19:19:44 peter
  1456. * fixed searching for utils
  1457. Revision 1.8 2000/12/25 00:07:25 peter
  1458. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1459. tlinkedlist objects)
  1460. Revision 1.7 2000/11/13 15:26:12 marco
  1461. * Renamefest
  1462. Revision 1.6 2000/10/01 19:48:23 peter
  1463. * lot of compile updates for cg11
  1464. Revision 1.5 2000/09/24 15:06:11 peter
  1465. * use defines.inc
  1466. Revision 1.4 2000/08/27 16:11:49 peter
  1467. * moved some util functions from globals,cobjects to cutils
  1468. * splitted files into finput,fmodule
  1469. Revision 1.3 2000/07/13 12:08:24 michael
  1470. + patched to 1.1.0 with former 1.09patch from peter
  1471. Revision 1.2 2000/07/13 11:32:32 michael
  1472. + removed logs
  1473. }