ogcoff.pas 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Peter Vreman and Pierre Muller
  4. Contains the binary coff reader and writer
  5. * This code was inspired by the NASM sources
  6. The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  7. Julian Hall. All rights reserved.
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. ****************************************************************************
  20. }
  21. unit ogcoff;
  22. {$i fpcdefs.inc}
  23. interface
  24. uses
  25. { common }
  26. cclasses,
  27. { target }
  28. systems,
  29. { assembler }
  30. cpubase,aasm,assemble,
  31. { output }
  32. ogbase,owbase;
  33. type
  34. tcoffsection = class(tobjectsection)
  35. public
  36. flags : cardinal;
  37. coffrelocs,
  38. coffrelocpos : longint;
  39. constructor createsec(sec:TSection;AAlign,AFlags:cardinal);
  40. end;
  41. tcoffdata = class(tobjectdata)
  42. private
  43. Fstrs,
  44. Fsyms : Tdynamicarray;
  45. win32 : boolean;
  46. procedure reset;
  47. public
  48. constructor createdjgpp;
  49. constructor createwin32;
  50. destructor destroy;override;
  51. procedure setsectionsizes(var s:tsecsize);override;
  52. procedure createsection(sec:tsection);override;
  53. procedure writereloc(data,len:longint;p:tasmsymbol;relative:relative_type);override;
  54. procedure writesymbol(p:tasmsymbol);override;
  55. procedure writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc:boolean);override;
  56. procedure writesymstabs(section:tsection;offset:longint;p:pchar;ps:tasmsymbol;nidx,nother,line:longint;reloc:boolean);override;
  57. end;
  58. tcoffobjectoutput = class(tobjectoutput)
  59. private
  60. win32 : boolean;
  61. initsym : longint;
  62. procedure write_relocs(s:tobjectsection);
  63. procedure write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  64. procedure write_symbols;
  65. protected
  66. procedure writetodisk;override;
  67. public
  68. constructor createdjgpp(smart:boolean);
  69. constructor createwin32(smart:boolean);
  70. function initwriting(const fn:string):boolean;override;
  71. end;
  72. tcoffexeoutput = class
  73. private
  74. FWriter : tobjectwriter;
  75. win32 : boolean;
  76. nsects,
  77. nsyms,
  78. sympos : longint;
  79. procedure write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  80. procedure write_symbols;
  81. public
  82. constructor createdjgpp;
  83. constructor createwin32;
  84. procedure calcoffsets;
  85. procedure writetodisk;
  86. function initwriting(const fn:string):boolean;
  87. end;
  88. ttasmsymbolarray = array[0..high(word)] of tasmsymbol;
  89. tcoffobjectinput = class(tobjectinput)
  90. private
  91. Fidx2sec : array[0..255] of tsection;
  92. FCoffsyms : tdynamicarray;
  93. FSymTbl : ^ttasmsymbolarray;
  94. win32 : boolean;
  95. procedure read_relocs(s:tcoffsection);
  96. procedure handle_symbols;
  97. public
  98. constructor createdjgpp(const fn:string);
  99. constructor createwin32(const fn:string);
  100. function initreading:boolean;override;
  101. procedure donereading;override;
  102. procedure readfromdisk;override;
  103. end;
  104. tcoffassembler = class(tinternalassembler)
  105. constructor create(smart:boolean);override;
  106. end;
  107. tpecoffassembler = class(tinternalassembler)
  108. constructor create(smart:boolean);override;
  109. end;
  110. implementation
  111. uses
  112. {$ifdef delphi}
  113. sysutils,
  114. {$else}
  115. strings,
  116. {$endif}
  117. cutils,verbose,
  118. globtype,globals,fmodule;
  119. const
  120. symbolresize = 200*sizeof(toutputsymbol);
  121. strsresize = 8192;
  122. const
  123. COFF_SYM_EXTERNAL = 2;
  124. COFF_SYM_STATIC = 3;
  125. COFF_SYM_LABEL = 6;
  126. COFF_SYM_FUNCTION = 101;
  127. COFF_SYM_FILE = 103;
  128. COFF_SYM_SECTION = 104;
  129. type
  130. { Structures which are written directly to the output file }
  131. coffheader=packed record
  132. mach : word;
  133. nsects : word;
  134. time : longint;
  135. sympos : longint;
  136. syms : longint;
  137. opthdr : word;
  138. flag : word;
  139. end;
  140. coffsechdr=packed record
  141. name : array[0..7] of char;
  142. vsize : longint;
  143. rvaofs : longint;
  144. datasize : longint;
  145. datapos : longint;
  146. relocpos : longint;
  147. lineno1 : longint;
  148. nrelocs : word;
  149. lineno2 : word;
  150. flags : cardinal;
  151. end;
  152. coffsectionrec=packed record
  153. len : longint;
  154. nrelocs : word;
  155. empty : array[0..11] of char;
  156. end;
  157. coffreloc=packed record
  158. address : longint;
  159. sym : longint;
  160. relative : word;
  161. end;
  162. coffsymbol=packed record
  163. name : array[0..3] of char; { real is [0..7], which overlaps the strpos ! }
  164. strpos : longint;
  165. value : longint;
  166. section : smallint;
  167. empty : smallint;
  168. typ : byte;
  169. aux : byte;
  170. end;
  171. coffstab=packed record
  172. strpos : longint;
  173. ntype : byte;
  174. nother : byte;
  175. ndesc : word;
  176. nvalue : longint;
  177. end;
  178. {****************************************************************************
  179. TCoffSection
  180. ****************************************************************************}
  181. constructor tcoffsection.createsec(sec:TSection;AAlign,AFlags:cardinal);
  182. begin
  183. inherited create(target_asm.secnames[sec],AAlign,(sec=sec_bss));
  184. Flags:=AFlags;
  185. end;
  186. {****************************************************************************
  187. TCoffData
  188. ****************************************************************************}
  189. constructor tcoffdata.createdjgpp;
  190. begin
  191. inherited create;
  192. win32:=false;
  193. reset;
  194. end;
  195. constructor tcoffdata.createwin32;
  196. begin
  197. inherited create;
  198. win32:=true;
  199. reset;
  200. end;
  201. destructor tcoffdata.destroy;
  202. begin
  203. FSyms.Free;
  204. FStrs.Free;
  205. inherited destroy;
  206. end;
  207. procedure tcoffdata.reset;
  208. var
  209. s : string;
  210. begin
  211. FSyms:=TDynamicArray.Create(symbolresize);
  212. FStrs:=TDynamicArray.Create(strsresize);
  213. { we need at least the following 3 sections }
  214. createsection(sec_code);
  215. createsection(sec_data);
  216. createsection(sec_bss);
  217. if (cs_gdb_lineinfo in aktglobalswitches) or
  218. (cs_debuginfo in aktmoduleswitches) then
  219. begin
  220. createsection(sec_stab);
  221. createsection(sec_stabstr);
  222. writestabs(sec_none,0,nil,0,0,0,false);
  223. { write zero pchar and name together (PM) }
  224. s:=#0+SplitFileName(current_module.mainsource^)+#0;
  225. sects[sec_stabstr].write(s[1],length(s));
  226. end;
  227. end;
  228. procedure tcoffdata.createsection(sec:TSection);
  229. var
  230. Flags,
  231. AAlign : cardinal;
  232. begin
  233. { defaults }
  234. Flags:=0;
  235. Aalign:=1;
  236. { alignment after section }
  237. case sec of
  238. sec_code :
  239. begin
  240. if win32 then
  241. Flags:=$60000020
  242. else
  243. Flags:=$20;
  244. Aalign:=16;
  245. end;
  246. sec_data :
  247. begin
  248. if win32 then
  249. Flags:=$c0300040
  250. else
  251. Flags:=$40;
  252. Aalign:=16;
  253. end;
  254. sec_bss :
  255. begin
  256. if win32 then
  257. Flags:=$c0300080
  258. else
  259. Flags:=$80;
  260. Aalign:=16;
  261. end;
  262. sec_idata2,
  263. sec_idata4,
  264. sec_idata5,
  265. sec_idata6,
  266. sec_idata7 :
  267. begin
  268. if win32 then
  269. Flags:=$40000000;
  270. end;
  271. sec_edata :
  272. begin
  273. if win32 then
  274. Flags:=$c0300040;
  275. end;
  276. end;
  277. sects[sec]:=tcoffSection.createsec(Sec,AAlign,Flags);
  278. end;
  279. procedure tcoffdata.writesymbol(p:tasmsymbol);
  280. var
  281. sym : toutputsymbol;
  282. s : string;
  283. begin
  284. { already written ? }
  285. if p.idx<>-1 then
  286. exit;
  287. { be sure that the section will exists }
  288. if (p.section<>sec_none) and not(assigned(sects[p.section])) then
  289. createsection(p.section);
  290. FillChar(sym,sizeof(sym),0);
  291. sym.value:=p.size;
  292. sym.bind:=p.bind;
  293. sym.typ:=AT_NONE;
  294. { if local of global then set the section value to the address
  295. of the symbol }
  296. if sym.bind in [AB_LOCAL,AB_GLOBAL] then
  297. begin
  298. sym.section:=p.section;
  299. sym.value:=p.address+sects[sym.section].mempos;
  300. end;
  301. { store the symbol, but not the local ones }
  302. if (sym.bind<>AB_LOCAL) then
  303. begin
  304. { symbolname }
  305. s:=p.name;
  306. if length(s)>8 then
  307. begin
  308. sym.nameidx:=FStrs.size+4;
  309. FStrs.writestr(s);
  310. FStrs.writestr(#0);
  311. end
  312. else
  313. begin
  314. sym.nameidx:=-1;
  315. sym.namestr:=s;
  316. end;
  317. { update the asmsymbol index }
  318. p.idx:=FSyms.size div sizeof(TOutputSymbol);
  319. { write the symbol }
  320. FSyms.write(sym,sizeof(toutputsymbol));
  321. end
  322. else
  323. begin
  324. p.idx:=-2; { local }
  325. end;
  326. end;
  327. procedure tcoffdata.writereloc(data,len:longint;p:tasmsymbol;relative:relative_type);
  328. var
  329. curraddr,
  330. symaddr : longint;
  331. begin
  332. if not assigned(sects[currsec]) then
  333. createsection(currsec);
  334. if assigned(p) then
  335. begin
  336. { current address }
  337. curraddr:=sects[currsec].mempos+sects[currsec].datasize;
  338. { real address of the symbol }
  339. symaddr:=p.address;
  340. if p.section<>sec_none then
  341. inc(symaddr,sects[p.section].mempos);
  342. { no symbol relocation need inside a section }
  343. if p.section=currsec then
  344. begin
  345. case relative of
  346. relative_false :
  347. begin
  348. sects[currsec].addsectionreloc(curraddr,currsec,relative_false);
  349. inc(data,symaddr);
  350. end;
  351. relative_true :
  352. begin
  353. inc(data,symaddr-len-sects[currsec].datasize);
  354. end;
  355. relative_rva :
  356. begin
  357. sects[currsec].addsectionreloc(curraddr,currsec,relative_rva);
  358. inc(data,symaddr);
  359. end;
  360. end;
  361. end
  362. else
  363. begin
  364. writesymbol(p);
  365. if (p.section<>sec_none) and (relative<>relative_true) then
  366. sects[currsec].addsectionreloc(curraddr,p.section,relative)
  367. else
  368. sects[currsec].addsymreloc(curraddr,p,relative);
  369. if not win32 then {seems wrong to me (PM) }
  370. inc(data,symaddr)
  371. else
  372. if (relative<>relative_true) and (p.section<>sec_none) then
  373. inc(data,symaddr);
  374. if relative=relative_true then
  375. begin
  376. if win32 then
  377. dec(data,len-4)
  378. else
  379. dec(data,len+sects[currsec].datasize);
  380. end;
  381. end;
  382. end;
  383. sects[currsec].write(data,len);
  384. end;
  385. procedure tcoffdata.writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc : boolean);
  386. var
  387. stab : coffstab;
  388. s : tsection;
  389. curraddr : longint;
  390. begin
  391. s:=section;
  392. { local var can be at offset -1 !! PM }
  393. if reloc then
  394. begin
  395. if (offset=-1) then
  396. begin
  397. if s=sec_none then
  398. offset:=0
  399. else
  400. offset:=sects[s].datasize;
  401. end;
  402. if (s<>sec_none) then
  403. inc(offset,sects[s].datapos);
  404. end;
  405. if assigned(p) and (p[0]<>#0) then
  406. begin
  407. stab.strpos:=sects[sec_stabstr].datasize;
  408. sects[sec_stabstr].write(p^,strlen(p)+1);
  409. end
  410. else
  411. stab.strpos:=0;
  412. stab.ntype:=nidx;
  413. stab.ndesc:=line;
  414. stab.nother:=nother;
  415. stab.nvalue:=offset;
  416. sects[sec_stab].write(stab,sizeof(stab));
  417. { when the offset is not 0 then write a relocation, take also the
  418. hdrstab into account with the offset }
  419. if reloc then
  420. begin
  421. { current address }
  422. curraddr:=sects[sec_stab].mempos+sects[sec_stab].datasize;
  423. if DLLSource and RelocSection then
  424. { avoid relocation in the .stab section
  425. because it ends up in the .reloc section instead }
  426. sects[sec_stab].addsectionreloc(curraddr-4,s,relative_rva)
  427. else
  428. sects[sec_stab].addsectionreloc(curraddr-4,s,relative_false);
  429. end;
  430. end;
  431. procedure tcoffdata.writesymstabs(section:tsection;offset:longint;p:pchar;ps:tasmsymbol;
  432. nidx,nother,line:longint;reloc:boolean);
  433. var
  434. stab : coffstab;
  435. curraddr : longint;
  436. begin
  437. { do not use the size stored in offset field
  438. this is DJGPP specific ! PM }
  439. if win32 then
  440. offset:=0;
  441. { local var can be at offset -1 !! PM }
  442. if reloc then
  443. begin
  444. if (offset=-1) then
  445. begin
  446. if section=sec_none then
  447. offset:=0
  448. else
  449. offset:=sects[section].datasize;
  450. end;
  451. if (section<>sec_none) then
  452. inc(offset,sects[section].mempos);
  453. end;
  454. if assigned(p) and (p[0]<>#0) then
  455. begin
  456. stab.strpos:=sects[sec_stabstr].datasize;
  457. sects[sec_stabstr].write(p^,strlen(p)+1);
  458. end
  459. else
  460. stab.strpos:=0;
  461. stab.ntype:=nidx;
  462. stab.ndesc:=line;
  463. stab.nother:=nother;
  464. stab.nvalue:=offset;
  465. sects[sec_stab].write(stab,sizeof(stab));
  466. { when the offset is not 0 then write a relocation, take also the
  467. hdrstab into account with the offset }
  468. if reloc then
  469. begin
  470. { current address }
  471. curraddr:=sects[sec_stab].mempos+sects[sec_stab].datasize;
  472. if DLLSource and RelocSection then
  473. { avoid relocation in the .stab section
  474. because it ends up in the .reloc section instead }
  475. sects[sec_stab].addsymreloc(curraddr-4,ps,relative_rva)
  476. else
  477. sects[sec_stab].addsymreloc(curraddr-4,ps,relative_false);
  478. end;
  479. end;
  480. procedure tcoffdata.setsectionsizes(var s:tsecsize);
  481. var
  482. mempos : longint;
  483. sec : tsection;
  484. begin
  485. { multiply stab with real size }
  486. s[sec_stab]:=s[sec_stab]*sizeof(coffstab);
  487. { if debug then also count header stab }
  488. if (cs_debuginfo in aktmoduleswitches) then
  489. begin
  490. inc(s[sec_stab],sizeof(coffstab));
  491. inc(s[sec_stabstr],length(SplitFileName(current_module.mainsource^))+2);
  492. end;
  493. { calc mempos }
  494. mempos:=0;
  495. for sec:=low(tsection) to high(tsection) do
  496. begin
  497. if (s[sec]>0) and
  498. (not assigned(sects[sec])) then
  499. createsection(sec);
  500. if assigned(sects[sec]) then
  501. begin
  502. sects[sec].memsize:=s[sec];
  503. { memory position }
  504. if not win32 then
  505. begin
  506. sects[sec].mempos:=mempos;
  507. inc(mempos,align(sects[sec].memsize,sects[sec].addralign));
  508. end;
  509. end;
  510. end;
  511. end;
  512. {****************************************************************************
  513. tcoffobjectoutput
  514. ****************************************************************************}
  515. constructor tcoffobjectoutput.createdjgpp(smart:boolean);
  516. begin
  517. inherited create(smart);
  518. win32:=false;
  519. end;
  520. constructor tcoffobjectoutput.createwin32(smart:boolean);
  521. begin
  522. inherited create(smart);
  523. win32:=true;
  524. end;
  525. function tcoffobjectoutput.initwriting(const fn:string):boolean;
  526. begin
  527. result:=inherited initwriting(fn);
  528. if result then
  529. begin
  530. initsym:=0;
  531. if win32 then
  532. FData:=tcoffdata.createwin32
  533. else
  534. FData:=tcoffdata.createdjgpp;
  535. end;
  536. end;
  537. procedure tcoffobjectoutput.write_relocs(s:tobjectsection);
  538. var
  539. rel : coffreloc;
  540. hr,r : poutputreloc;
  541. begin
  542. r:=s.relochead;
  543. while assigned(r) do
  544. begin
  545. rel.address:=r^.address;
  546. if assigned(r^.symbol) then
  547. begin
  548. if (r^.symbol.bind=AB_LOCAL) then
  549. rel.sym:=2*data.sects[r^.symbol.section].secsymidx
  550. else
  551. begin
  552. if r^.symbol.idx=-1 then
  553. internalerror(4321);
  554. rel.sym:=r^.symbol.idx+initsym;
  555. end;
  556. end
  557. else
  558. begin
  559. if r^.section<>sec_none then
  560. rel.sym:=2*data.sects[r^.section].secsymidx
  561. else
  562. rel.sym:=0;
  563. end;
  564. case r^.typ of
  565. relative_true : rel.relative:=$14;
  566. relative_false : rel.relative:=$6;
  567. relative_rva : rel.relative:=$7;
  568. end;
  569. FWriter.write(rel,sizeof(rel));
  570. { goto next and dispose this reloc }
  571. hr:=r;
  572. r:=r^.next;
  573. dispose(hr);
  574. end;
  575. end;
  576. procedure tcoffobjectoutput.write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  577. var
  578. sym : coffsymbol;
  579. begin
  580. FillChar(sym,sizeof(sym),0);
  581. if strpos=-1 then
  582. move(name[1],sym.name,length(name))
  583. else
  584. sym.strpos:=strpos;
  585. sym.value:=value;
  586. sym.section:=section;
  587. sym.typ:=typ;
  588. sym.aux:=aux;
  589. FWriter.write(sym,sizeof(sym));
  590. end;
  591. procedure tcoffobjectoutput.write_symbols;
  592. var
  593. filename : string[18];
  594. sec : tsection;
  595. sectionval,
  596. i : longint;
  597. globalval : byte;
  598. secrec : coffsectionrec;
  599. sym : toutputsymbol;
  600. begin
  601. with tcoffdata(data) do
  602. begin
  603. { The `.file' record, and the file name auxiliary record }
  604. write_symbol ('.file', -1, 0, -2, $67, 1);
  605. fillchar(filename,sizeof(filename),0);
  606. filename:=SplitFileName(current_module.mainsource^);
  607. FWriter.write(filename[1],sizeof(filename)-1);
  608. { The section records, with their auxiliaries, also store the
  609. symbol index }
  610. for sec:=low(tsection) to high(tsection) do
  611. if assigned(sects[sec]) then
  612. begin
  613. write_symbol(target_asm.secnames[sec],-1,sects[sec].mempos,sects[sec].secsymidx,3,1);
  614. fillchar(secrec,sizeof(secrec),0);
  615. secrec.len:=sects[sec].aligneddatasize;
  616. secrec.nrelocs:=sects[sec].nrelocs;
  617. FWriter.write(secrec,sizeof(secrec));
  618. end;
  619. { The real symbols }
  620. FSyms.seek(0);
  621. for i:=1 to FSyms.size div sizeof(TOutputSymbol) do
  622. begin
  623. FSyms.read(sym,sizeof(TOutputSymbol));
  624. if sym.bind=AB_LOCAL then
  625. globalval:=3
  626. else
  627. globalval:=2;
  628. if assigned(sects[sym.section]) then
  629. sectionval:=sects[sym.section].secsymidx
  630. else
  631. sectionval:=0;
  632. write_symbol(sym.namestr,sym.nameidx,sym.value,sectionval,globalval,0);
  633. end;
  634. end;
  635. end;
  636. procedure tcoffobjectoutput.writetodisk;
  637. var
  638. datapos,
  639. secsymidx,
  640. nsects,
  641. sympos,i : longint;
  642. hstab : coffstab;
  643. gotreloc : boolean;
  644. sec : tsection;
  645. header : coffheader;
  646. sechdr : coffsechdr;
  647. empty : array[0..15] of byte;
  648. hp : pdynamicblock;
  649. begin
  650. with tcoffdata(data) do
  651. begin
  652. { calc amount of sections we have }
  653. fillchar(empty,sizeof(empty),0);
  654. nsects:=0;
  655. initsym:=2; { 2 for the file }
  656. secsymidx:=0;
  657. for sec:=low(tsection) to high(tsection) do
  658. if assigned(sects[sec]) then
  659. begin
  660. inc(nsects);
  661. inc(secsymidx);
  662. sects[sec].secsymidx:=secsymidx;
  663. inc(initsym,2); { 2 for each section }
  664. end;
  665. { For the stab section we need an HdrSym which can now be
  666. calculated more easily }
  667. if assigned(sects[sec_stab]) then
  668. begin
  669. hstab.strpos:=1;
  670. hstab.ntype:=0;
  671. hstab.nother:=0;
  672. hstab.ndesc:=(sects[sec_stab].datasize div sizeof(coffstab))-1{+1 according to gas output PM};
  673. hstab.nvalue:=sects[sec_stabstr].datasize;
  674. sects[sec_stab].data.seek(0);
  675. sects[sec_stab].data.write(hstab,sizeof(hstab));
  676. end;
  677. { Calculate the filepositions }
  678. datapos:=sizeof(coffheader)+sizeof(coffsechdr)*nsects;
  679. { sections first }
  680. for sec:=low(tsection) to high(tsection) do
  681. if assigned(sects[sec]) then
  682. begin
  683. sects[sec].datapos:=datapos;
  684. if assigned(sects[sec].data) then
  685. inc(datapos,sects[sec].aligneddatasize);
  686. end;
  687. { relocs }
  688. gotreloc:=false;
  689. for sec:=low(tsection) to high(tsection) do
  690. if assigned(sects[sec]) then
  691. begin
  692. tcoffsection(sects[sec]).coffrelocpos:=datapos;
  693. inc(datapos,10*sects[sec].nrelocs);
  694. if (not gotreloc) and (sects[sec].nrelocs>0) then
  695. gotreloc:=true;
  696. end;
  697. { symbols }
  698. sympos:=datapos;
  699. { COFF header }
  700. fillchar(header,sizeof(coffheader),0);
  701. header.mach:=$14c;
  702. header.nsects:=nsects;
  703. header.sympos:=sympos;
  704. header.syms:=(FSyms.size div sizeof(TOutputSymbol))+initsym;
  705. if gotreloc then
  706. header.flag:=$104
  707. else
  708. header.flag:=$105;
  709. FWriter.write(header,sizeof(header));
  710. { Section headers }
  711. for sec:=low(tsection) to high(tsection) do
  712. if assigned(sects[sec]) then
  713. begin
  714. fillchar(sechdr,sizeof(sechdr),0);
  715. move(target_asm.secnames[sec][1],sechdr.name,length(target_asm.secnames[sec]));
  716. if not win32 then
  717. begin
  718. sechdr.rvaofs:=sects[sec].mempos;
  719. sechdr.vsize:=sects[sec].mempos;
  720. end
  721. else
  722. begin
  723. if sec=sec_bss then
  724. sechdr.vsize:=sects[sec].aligneddatasize;
  725. end;
  726. sechdr.datasize:=sects[sec].aligneddatasize;
  727. if (sects[sec].datasize>0) and assigned(sects[sec].data) then
  728. sechdr.datapos:=sects[sec].datapos;
  729. sechdr.nrelocs:=sects[sec].nrelocs;
  730. sechdr.relocpos:=TCoffSection(sects[sec]).coffrelocpos;
  731. sechdr.flags:=TCoffSection(sects[sec]).flags;
  732. FWriter.write(sechdr,sizeof(sechdr));
  733. end;
  734. { Sections }
  735. for sec:=low(tsection) to high(tsection) do
  736. if assigned(sects[sec]) and
  737. assigned(sects[sec].data) then
  738. begin
  739. sects[sec].alignsection;
  740. hp:=sects[sec].data.firstblock;
  741. while assigned(hp) do
  742. begin
  743. FWriter.write(hp^.data,hp^.used);
  744. hp:=hp^.next;
  745. end;
  746. end;
  747. { Relocs }
  748. for sec:=low(tsection) to high(tsection) do
  749. if assigned(sects[sec]) then
  750. write_relocs(sects[sec]);
  751. { Symbols }
  752. write_symbols;
  753. { Strings }
  754. i:=FStrs.size+4;
  755. FWriter.write(i,4);
  756. hp:=FStrs.firstblock;
  757. while assigned(hp) do
  758. begin
  759. FWriter.write(hp^.data,hp^.used);
  760. hp:=hp^.next;
  761. end;
  762. end;
  763. end;
  764. {****************************************************************************
  765. tcoffexeoutput
  766. ****************************************************************************}
  767. constructor tcoffexeoutput.createdjgpp;
  768. begin
  769. win32:=false;
  770. end;
  771. constructor tcoffexeoutput.createwin32;
  772. begin
  773. win32:=true;
  774. end;
  775. function tcoffexeoutput.initwriting(const fn:string):boolean;
  776. begin
  777. end;
  778. procedure tcoffexeoutput.write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  779. var
  780. sym : coffsymbol;
  781. begin
  782. FillChar(sym,sizeof(sym),0);
  783. if strpos=-1 then
  784. move(name[1],sym.name,length(name))
  785. else
  786. sym.strpos:=strpos;
  787. sym.value:=value;
  788. sym.section:=section;
  789. sym.typ:=typ;
  790. sym.aux:=aux;
  791. FWriter.write(sym,sizeof(sym));
  792. end;
  793. procedure tcoffexeoutput.write_symbols;
  794. var
  795. filename : string[18];
  796. sec : tsection;
  797. sectionval,
  798. i : longint;
  799. globalval : byte;
  800. secrec : coffsectionrec;
  801. sym : toutputsymbol;
  802. objdata : tobjectdata;
  803. begin
  804. objdata:=tobjectdata(objdatalist.first);
  805. while assigned(objdata) do
  806. begin
  807. with tcoffdata(objdata) do
  808. begin
  809. { The real symbols }
  810. FSyms.seek(0);
  811. for i:=1 to FSyms.size div sizeof(TOutputSymbol) do
  812. begin
  813. FSyms.read(sym,sizeof(TOutputSymbol));
  814. if sym.bind=AB_LOCAL then
  815. globalval:=3
  816. else
  817. globalval:=2;
  818. if assigned(sects[sym.section]) then
  819. sectionval:=sects[sym.section].secsymidx
  820. else
  821. sectionval:=0;
  822. write_symbol(sym.namestr,sym.nameidx,sym.value,sectionval,globalval,0);
  823. end;
  824. end;
  825. objdata:=tobjectdata(objdata.next);
  826. end;
  827. end;
  828. procedure tcoffexeoutput.calcoffsets;
  829. var
  830. objdata : tobjectdata;
  831. mempos,
  832. datapos : longint;
  833. sec : tsection;
  834. begin
  835. { calc header size }
  836. nsects:=0;
  837. for sec:=low(tsection) to high(tsection) do
  838. begin
  839. if objdatasections[sec].available then
  840. inc(nsects);
  841. end;
  842. datapos:=sizeof(coffheader)+sizeof(coffsechdr)*nsects;
  843. mempos:=$1800;
  844. { process first all .text, then all .data, etc. }
  845. for sec:=low(tsection) to high(tsection) do
  846. begin
  847. if objdatasections[sec].available then
  848. begin
  849. objdatasections[sec].datapos:=datapos;
  850. objdatasections[sec].mempos:=mempos;
  851. { update objectfiles }
  852. objdata:=tobjectdata(objdatalist.first);
  853. while assigned(objdata) do
  854. begin
  855. objdata.sects[sec].mempos:=mempos;
  856. inc(mempos,objdata.sects[sec].datasize);
  857. objdata.sects[sec].datapos:=datapos;
  858. if assigned(objdata.sects[sec].data) then
  859. inc(datapos,objdata.sects[sec].datasize);
  860. objdata:=tobjectdata(objdata.next);
  861. end;
  862. objdatasections[sec].datasize:=datapos-objdatasections[sec].datapos;
  863. objdatasections[sec].memsize:=mempos-objdatasections[sec].mempos;
  864. end;
  865. end;
  866. { symbols }
  867. nsyms:=0;
  868. sympos:=datapos;
  869. objdata:=tobjectdata(objdatalist.first);
  870. while assigned(objdata) do
  871. begin
  872. inc(nsyms,tcoffdata(objdata).FSyms.size div sizeof(TOutputSymbol));
  873. objdata:=tobjectdata(objdata.next);
  874. end;
  875. end;
  876. procedure tcoffexeoutput.writetodisk;
  877. var
  878. datapos,
  879. secsymidx,
  880. i : longint;
  881. hstab : coffstab;
  882. gotreloc : boolean;
  883. sec : tsection;
  884. header : coffheader;
  885. sechdr : coffsechdr;
  886. empty : array[0..15] of byte;
  887. hp : pdynamicblock;
  888. fn : string;
  889. objdata : tobjectdata;
  890. begin
  891. fn:='p.exe';
  892. FWriter:=tobjectwriter.create;
  893. if not FWriter.createfile(fn) then
  894. Comment(V_Fatal,'Can''t create executable '+fn);
  895. { COFF header }
  896. fillchar(header,sizeof(coffheader),0);
  897. header.mach:=$14c;
  898. header.nsects:=nsects;
  899. header.sympos:=sympos;
  900. header.syms:=nsyms;
  901. header.flag:=$132;
  902. FWriter.write(header,sizeof(header));
  903. { Section headers }
  904. for sec:=low(tsection) to high(tsection) do
  905. if objdatasections[sec].available then
  906. begin
  907. fillchar(sechdr,sizeof(sechdr),0);
  908. move(target_asm.secnames[sec][1],sechdr.name,length(target_asm.secnames[sec]));
  909. if not win32 then
  910. begin
  911. sechdr.rvaofs:=objdatasections[sec].mempos;
  912. sechdr.vsize:=objdatasections[sec].mempos;
  913. end
  914. else
  915. begin
  916. if sec=sec_bss then
  917. sechdr.vsize:=objdatasections[sec].memsize;
  918. end;
  919. sechdr.datasize:=objdatasections[sec].datasize;
  920. sechdr.datapos:=objdatasections[sec].datapos;
  921. sechdr.nrelocs:=0;
  922. sechdr.relocpos:=0;
  923. sechdr.flags:=objdatasections[sec].flags;
  924. FWriter.write(sechdr,sizeof(sechdr));
  925. end;
  926. { Sections }
  927. for sec:=low(tsection) to high(tsection) do
  928. if objdatasections[sec].available then
  929. begin
  930. { update objectfiles }
  931. objdata:=tobjectdata(objdatalist.first);
  932. while assigned(objdata) do
  933. begin
  934. if assigned(objdata.sects[sec]) and
  935. assigned(objdata.sects[sec].data) then
  936. begin
  937. hp:=objdata.sects[sec].data.firstblock;
  938. while assigned(hp) do
  939. begin
  940. FWriter.write(hp^.data,hp^.used);
  941. hp:=hp^.next;
  942. end;
  943. end;
  944. objdata:=tobjectdata(objdata.next);
  945. end;
  946. end;
  947. { Symbols }
  948. write_symbols;
  949. FWriter.closefile;
  950. FWriter.free;
  951. end;
  952. {****************************************************************************
  953. tcoffobjectinput
  954. ****************************************************************************}
  955. constructor tcoffobjectinput.createdjgpp(const fn:string);
  956. begin
  957. inherited create(fn);
  958. win32:=false;
  959. end;
  960. constructor tcoffobjectinput.createwin32(const fn:string);
  961. begin
  962. inherited create(fn);
  963. win32:=true;
  964. end;
  965. function tcoffobjectinput.initreading:boolean;
  966. begin
  967. result:=inherited initreading;
  968. if result then
  969. begin
  970. if win32 then
  971. FData:=tcoffdata.createwin32
  972. else
  973. FData:=tcoffdata.createdjgpp;
  974. FCoffSyms:=TDynamicArray.Create(symbolresize);
  975. end;
  976. end;
  977. procedure tcoffobjectinput.donereading;
  978. begin
  979. FCoffSyms.Free;
  980. end;
  981. procedure tcoffobjectinput.read_relocs(s:tcoffsection);
  982. var
  983. rel : coffreloc;
  984. rel_type : relative_type;
  985. i : longint;
  986. p : tasmsymbol;
  987. begin
  988. for i:=1 to s.coffrelocs do
  989. begin
  990. FReader.read(rel,sizeof(rel));
  991. case rel.relative of
  992. $14 : rel_type:=relative_true;
  993. $06 : rel_type:=relative_false;
  994. $07 : rel_type:=relative_rva;
  995. else
  996. begin
  997. Comment(V_Error,'Error reading coff file');
  998. exit;
  999. end;
  1000. end;
  1001. p:=FSymTbl^[rel.sym];
  1002. if assigned(p) then
  1003. begin
  1004. s.addsymreloc(rel.address,p,rel_type);
  1005. end
  1006. else
  1007. begin
  1008. Comment(V_Error,'Error reading coff file');
  1009. exit;
  1010. end;
  1011. end;
  1012. end;
  1013. procedure tcoffobjectinput.handle_symbols;
  1014. var
  1015. sec : tsection;
  1016. i,nsyms,
  1017. symidx : longint;
  1018. sym : coffsymbol;
  1019. strname : string;
  1020. p : tasmsymbol;
  1021. auxrec : array[0..17] of byte;
  1022. begin
  1023. with tcoffdata(data) do
  1024. begin
  1025. nsyms:=FCoffSyms.Size div sizeof(CoffSymbol);
  1026. { Allocate memory for symidx -> tasmsymbol table }
  1027. GetMem(FSymTbl,nsyms*sizeof(pointer));
  1028. FillChar(FSymTbl^,nsyms*sizeof(pointer),0);
  1029. { Loop all symbols }
  1030. FCoffSyms.Seek(0);
  1031. symidx:=0;
  1032. while (symidx<nsyms) do
  1033. begin
  1034. FCoffSyms.Read(sym,sizeof(sym));
  1035. if plongint(@sym.name)^<>0 then
  1036. begin
  1037. move(sym.name,strname[1],8);
  1038. strname[9]:=#0;
  1039. end
  1040. else
  1041. begin
  1042. FStrs.Seek(sym.strpos-4);
  1043. FStrs.Read(strname[1],255);
  1044. strname[255]:=#0;
  1045. end;
  1046. strname[0]:=chr(strlen(@strname[1]));
  1047. if strname='' then
  1048. Internalerror(341324310);
  1049. case sym.typ of
  1050. COFF_SYM_EXTERNAL :
  1051. begin
  1052. if sym.section=0 then
  1053. begin
  1054. { try to find external }
  1055. p:=tasmsymbol(globalsyms.search(strname));
  1056. if not assigned(p) then
  1057. begin
  1058. p:=tasmsymbol.create(strname,AB_EXTERNAL,AT_FUNCTION);
  1059. AddSymbol(p);
  1060. externalsyms.insert(p);
  1061. end;
  1062. end
  1063. else
  1064. begin
  1065. { try to find external }
  1066. p:=tasmsymbol(globalsyms.search(strname));
  1067. if not assigned(p) then
  1068. begin
  1069. p:=tasmsymbol.create(strname,AB_GLOBAL,AT_FUNCTION);
  1070. AddSymbol(p);
  1071. end
  1072. else
  1073. begin
  1074. if p.bind<>AB_EXTERNAL then
  1075. Comment(V_Error,'Multiple defined symbol '+strname);
  1076. p.bind:=AB_GLOBAL;
  1077. end;
  1078. sec:=Fidx2sec[sym.section];
  1079. if assigned(sects[sec]) then
  1080. begin
  1081. p.section:=sec;
  1082. if sym.value>=sects[sec].mempos then
  1083. p.address:=sym.value-sects[sec].mempos
  1084. else
  1085. internalerror(432432432);
  1086. end
  1087. else
  1088. internalerror(34243214);
  1089. end;
  1090. FSymTbl^[symidx]:=p
  1091. end;
  1092. COFF_SYM_STATIC :
  1093. begin
  1094. p:=tasmsymbol.create(strname,AB_LOCAL,AT_FUNCTION);
  1095. AddSymbol(p);
  1096. { do not resolve constants (section=-1) }
  1097. if sym.section<>-1 then
  1098. begin
  1099. sec:=Fidx2sec[sym.section];
  1100. if assigned(sects[sec]) then
  1101. begin
  1102. p.section:=sec;
  1103. if sym.value>=sects[sec].mempos then
  1104. p.address:=sym.value-sects[sec].mempos
  1105. else
  1106. begin
  1107. if Str2Sec(strname)<>sec then
  1108. internalerror(432432432);
  1109. end;
  1110. end
  1111. else
  1112. internalerror(34243214);
  1113. end;
  1114. FSymTbl^[symidx]:=p;
  1115. end;
  1116. COFF_SYM_SECTION,
  1117. COFF_SYM_LABEL,
  1118. COFF_SYM_FUNCTION,
  1119. COFF_SYM_FILE :
  1120. ;
  1121. else
  1122. internalerror(4342343);
  1123. end;
  1124. { read aux records }
  1125. for i:=1 to sym.aux do
  1126. begin
  1127. FCoffSyms.Read(auxrec,sizeof(auxrec));
  1128. inc(symidx);
  1129. end;
  1130. inc(symidx);
  1131. end;
  1132. end;
  1133. end;
  1134. procedure tcoffobjectinput.readfromdisk;
  1135. var
  1136. strsize,
  1137. i : longint;
  1138. sec : tsection;
  1139. header : coffheader;
  1140. sechdr : coffsechdr;
  1141. begin
  1142. with tcoffdata(data) do
  1143. begin
  1144. FillChar(Fidx2sec,sizeof(Fidx2sec),0);
  1145. { COFF header }
  1146. if not reader.read(header,sizeof(coffheader)) then
  1147. begin
  1148. Comment(V_Error,'Error reading coff file');
  1149. exit;
  1150. end;
  1151. if header.mach<>$14c then
  1152. begin
  1153. Comment(V_Error,'Not a coff file');
  1154. exit;
  1155. end;
  1156. if header.nsects>255 then
  1157. begin
  1158. Comment(V_Error,'To many sections');
  1159. exit;
  1160. end;
  1161. { header.mach:=$14c;
  1162. header.nsects:=nsects;
  1163. header.sympos:=sympos;
  1164. header.syms:=(Syms.size div sizeof(TOutputSymbol))+initsym;
  1165. if gotreloc then
  1166. header.flag:=$104
  1167. else
  1168. header.flag:=$105 }
  1169. { Section headers }
  1170. for i:=1 to header.nsects do
  1171. begin
  1172. if not reader.read(sechdr,sizeof(sechdr)) then
  1173. begin
  1174. Comment(V_Error,'Error reading coff file');
  1175. exit;
  1176. end;
  1177. sec:=str2sec(strpas(sechdr.name));
  1178. if sec<>sec_none then
  1179. begin
  1180. Fidx2sec[i]:=sec;
  1181. createsection(sec);
  1182. if not win32 then
  1183. sects[sec].mempos:=sechdr.rvaofs;
  1184. tcoffsection(sects[sec]).coffrelocs:=sechdr.nrelocs;
  1185. tcoffsection(sects[sec]).coffrelocpos:=sechdr.relocpos;
  1186. sects[sec].datapos:=sechdr.datapos;
  1187. sects[sec].datasize:=sechdr.datasize;
  1188. tcoffsection(sects[sec]).flags:=sechdr.flags;
  1189. objdatasections[sec].available:=true;
  1190. objdatasections[sec].flags:=sechdr.flags;
  1191. end
  1192. else
  1193. Comment(V_Warning,'skipping unsupported section '+strpas(sechdr.name));
  1194. end;
  1195. { Symbols }
  1196. Reader.Seek(header.sympos);
  1197. if not Reader.ReadArray(FCoffSyms,header.syms*sizeof(CoffSymbol)) then
  1198. begin
  1199. Comment(V_Error,'Error reading coff file');
  1200. exit;
  1201. end;
  1202. { Strings }
  1203. if not Reader.Read(strsize,4) then
  1204. begin
  1205. Comment(V_Error,'Error reading coff file');
  1206. exit;
  1207. end;
  1208. if strsize<4 then
  1209. begin
  1210. Comment(V_Error,'Error reading coff file');
  1211. exit;
  1212. end;
  1213. if not Reader.ReadArray(FStrs,Strsize-4) then
  1214. begin
  1215. Comment(V_Error,'Error reading coff file');
  1216. exit;
  1217. end;
  1218. { Insert all symbols }
  1219. handle_symbols;
  1220. { Sections }
  1221. for sec:=low(tsection) to high(tsection) do
  1222. if assigned(sects[sec]) and
  1223. (sec<>sec_bss) then
  1224. begin
  1225. Reader.Seek(sects[sec].datapos);
  1226. if not Reader.ReadArray(sects[sec].data,sects[sec].datasize) then
  1227. begin
  1228. Comment(V_Error,'Error reading coff file');
  1229. exit;
  1230. end;
  1231. end;
  1232. { Relocs }
  1233. for sec:=low(tsection) to high(tsection) do
  1234. if assigned(sects[sec]) and
  1235. (tcoffsection(sects[sec]).coffrelocs>0) then
  1236. begin
  1237. Reader.Seek(tcoffsection(sects[sec]).coffrelocpos);
  1238. read_relocs(tcoffsection(sects[sec]));
  1239. end;
  1240. end;
  1241. end;
  1242. {****************************************************************************
  1243. TCoffAssembler
  1244. ****************************************************************************}
  1245. constructor TCoffAssembler.Create(smart:boolean);
  1246. begin
  1247. inherited Create(smart);
  1248. objectoutput:=tcoffobjectoutput.createdjgpp(smart);
  1249. end;
  1250. {****************************************************************************
  1251. TPECoffAssembler
  1252. ****************************************************************************}
  1253. constructor TPECoffAssembler.Create(smart:boolean);
  1254. begin
  1255. inherited Create(smart);
  1256. objectoutput:=tcoffobjectoutput.createwin32(smart);
  1257. end;
  1258. {*****************************************************************************
  1259. Initialize
  1260. *****************************************************************************}
  1261. const
  1262. as_i386_coff_info : tasminfo =
  1263. (
  1264. id : as_i386_coff;
  1265. idtxt : 'COFF';
  1266. asmbin : '';
  1267. asmcmd : '';
  1268. supported_target : target_i386_go32v2;
  1269. outputbinary : true;
  1270. allowdirect : false;
  1271. externals : true;
  1272. needar : false;
  1273. labelprefix_only_inside_procedure: false;
  1274. labelprefix : '.L';
  1275. comment : '';
  1276. secnames : ('',
  1277. '.text','.data','.bss',
  1278. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  1279. '.stab','.stabstr')
  1280. );
  1281. const
  1282. as_i386_pecoff_info : tasminfo =
  1283. (
  1284. id : as_i386_pecoff;
  1285. idtxt : 'PECOFF';
  1286. asmbin : '';
  1287. asmcmd : '';
  1288. supported_target : target_i386_win32;
  1289. outputbinary : true;
  1290. allowdirect : false;
  1291. externals : true;
  1292. needar : false;
  1293. labelprefix_only_inside_procedure: false;
  1294. labelprefix : '.L';
  1295. comment : '';
  1296. secnames : ('',
  1297. '.text','.data','.bss',
  1298. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  1299. '.stab','.stabstr')
  1300. );
  1301. as_i386_pecoffwdosx_info : tasminfo =
  1302. (
  1303. id : as_i386_pecoffwdosx;
  1304. idtxt : 'PECOFFWDOSX';
  1305. asmbin : '';
  1306. asmcmd : '';
  1307. supported_target : target_i386_wdosx;
  1308. outputbinary : true;
  1309. allowdirect : false;
  1310. externals : true;
  1311. needar : false;
  1312. labelprefix_only_inside_procedure: false;
  1313. labelprefix : '.L';
  1314. comment : '';
  1315. secnames : ('',
  1316. '.text','.data','.bss',
  1317. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  1318. '.stab','.stabstr')
  1319. );
  1320. initialization
  1321. RegisterAssembler(as_i386_coff_info,TCoffAssembler);
  1322. RegisterAssembler(as_i386_pecoff_info,TPECoffAssembler);
  1323. RegisterAssembler(as_i386_pecoffwdosx_info,TPECoffAssembler);
  1324. end.
  1325. {
  1326. $Log$
  1327. Revision 1.21 2002-05-18 13:34:10 peter
  1328. * readded missing revisions
  1329. Revision 1.20 2002/05/16 19:46:39 carl
  1330. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1331. + try to fix temp allocation (still in ifdef)
  1332. + generic constructor calls
  1333. + start of tassembler / tmodulebase class cleanup
  1334. Revision 1.19 2002/05/14 19:34:43 peter
  1335. * removed old logs and updated copyright year
  1336. Revision 1.18 2002/04/04 19:05:58 peter
  1337. * removed unused units
  1338. * use tlocation.size in cg.a_*loc*() routines
  1339. Revision 1.17 2002/04/04 18:38:30 carl
  1340. + added wdosx support (patch from Pavel)
  1341. }