assemble.pas 48 KB

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