assemble.pas 49 KB

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