ogcoff.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 defines.inc}
  23. interface
  24. uses
  25. { common }
  26. cclasses,cobjects,
  27. { target }
  28. systems,
  29. { assembler }
  30. cpubase,aasm,
  31. { output }
  32. ogbase;
  33. type
  34. tcoffsection = class(tobjectsection)
  35. public
  36. flags : cardinal;
  37. relocpos : longint;
  38. constructor createsec(sec:TSection;AAlign,AFlags:cardinal);
  39. end;
  40. tcoffdata = class(tobjectdata)
  41. private
  42. win32 : boolean;
  43. procedure reset;
  44. public
  45. constructor createdjgpp;
  46. constructor createwin32;
  47. destructor destroy;override;
  48. procedure setsectionsizes(var s:tsecsize);override;
  49. procedure createsection(sec:tsection);override;
  50. procedure writereloc(data,len:longint;p:pasmsymbol;relative:relative_type);override;
  51. procedure writesymbol(p:pasmsymbol);override;
  52. procedure writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc:boolean);override;
  53. procedure writesymstabs(section:tsection;offset:longint;p:pchar;ps:pasmsymbol;nidx,nother,line:longint;reloc:boolean);override;
  54. strs,
  55. syms : Tdynamicarray;
  56. end;
  57. tcoffoutput = class(tobjectoutput)
  58. private
  59. win32 : boolean;
  60. initsym : longint;
  61. procedure write_relocs(s:tobjectsection);
  62. procedure write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  63. procedure write_symbols;
  64. protected
  65. procedure writetodisk;override;
  66. public
  67. constructor createdjgpp(smart:boolean);
  68. constructor createwin32(smart:boolean);
  69. function initwriting(Aplace:tcutplace):tobjectdata;override;
  70. end;
  71. implementation
  72. uses
  73. {$ifdef delphi}
  74. sysutils,
  75. {$else}
  76. strings,
  77. {$endif}
  78. cutils,verbose,
  79. globtype,globals,fmodule;
  80. const
  81. symbolresize = 200*18;
  82. strsresize = 8192;
  83. DataResize = 8192;
  84. type
  85. { Structures which are written directly to the output file }
  86. coffheader=packed record
  87. mach : word;
  88. nsects : word;
  89. time : longint;
  90. sympos : longint;
  91. syms : longint;
  92. opthdr : word;
  93. flag : word;
  94. end;
  95. coffsechdr=packed record
  96. name : array[0..7] of char;
  97. vsize : longint;
  98. rvaofs : longint;
  99. datasize : longint;
  100. datapos : longint;
  101. relocpos : longint;
  102. lineno1 : longint;
  103. nrelocs : word;
  104. lineno2 : word;
  105. flags : cardinal;
  106. end;
  107. coffsectionrec=packed record
  108. len : longint;
  109. nrelocs : word;
  110. empty : array[0..11] of char;
  111. end;
  112. coffreloc=packed record
  113. address : longint;
  114. sym : longint;
  115. relative : word;
  116. end;
  117. coffsymbol=packed record
  118. name : array[0..3] of char; { real is [0..7], which overlaps the strpos ! }
  119. strpos : longint;
  120. value : longint;
  121. section : smallint;
  122. empty : smallint;
  123. typ : byte;
  124. aux : byte;
  125. end;
  126. pcoffstab=^coffstab;
  127. coffstab=packed record
  128. strpos : longint;
  129. ntype : byte;
  130. nother : byte;
  131. ndesc : word;
  132. nvalue : longint;
  133. end;
  134. {****************************************************************************
  135. TCoffSection
  136. ****************************************************************************}
  137. constructor tcoffsection.createsec(sec:TSection;AAlign,AFlags:cardinal);
  138. begin
  139. inherited create(target_asm.secnames[sec],AAlign,(sec=sec_bss));
  140. Flags:=AFlags;
  141. end;
  142. {****************************************************************************
  143. TCoffData
  144. ****************************************************************************}
  145. constructor tcoffdata.createdjgpp;
  146. begin
  147. inherited create;
  148. win32:=false;
  149. reset;
  150. end;
  151. constructor tcoffdata.createwin32;
  152. begin
  153. inherited create;
  154. win32:=true;
  155. reset;
  156. end;
  157. destructor tcoffdata.destroy;
  158. begin
  159. inherited destroy;
  160. end;
  161. procedure tcoffdata.reset;
  162. var
  163. s : string;
  164. begin
  165. Syms:=TDynamicArray.Create(symbolresize);
  166. Strs:=TDynamicArray.Create(strsresize);
  167. { we need at least the following 3 sections }
  168. createsection(sec_code);
  169. createsection(sec_data);
  170. createsection(sec_bss);
  171. if (cs_gdb_lineinfo in aktglobalswitches) or
  172. (cs_debuginfo in aktmoduleswitches) then
  173. begin
  174. createsection(sec_stab);
  175. createsection(sec_stabstr);
  176. writestabs(sec_none,0,nil,0,0,0,false);
  177. { write zero pchar and name together (PM) }
  178. s:=#0+SplitFileName(current_module.mainsource^)+#0;
  179. sects[sec_stabstr].write(s[1],length(s));
  180. end;
  181. end;
  182. procedure tcoffdata.createsection(sec:TSection);
  183. var
  184. Flags,
  185. AAlign : cardinal;
  186. begin
  187. { defaults }
  188. Flags:=0;
  189. Aalign:=1;
  190. { alignment after section }
  191. case sec of
  192. sec_code :
  193. begin
  194. if win32 then
  195. Flags:=$60000020
  196. else
  197. Flags:=$20;
  198. Aalign:=4;
  199. end;
  200. sec_data :
  201. begin
  202. if win32 then
  203. Flags:=$c0300040
  204. else
  205. Flags:=$40;
  206. Aalign:=4;
  207. end;
  208. sec_bss :
  209. begin
  210. if win32 then
  211. Flags:=$c0300080
  212. else
  213. Flags:=$80;
  214. Aalign:=4;
  215. end;
  216. sec_idata2,
  217. sec_idata4,
  218. sec_idata5,
  219. sec_idata6,
  220. sec_idata7 :
  221. begin
  222. if win32 then
  223. Flags:=$40000000;
  224. end;
  225. sec_edata :
  226. begin
  227. if win32 then
  228. Flags:=$c0300040;
  229. end;
  230. end;
  231. sects[sec]:=tcoffSection.createsec(Sec,AAlign,Flags);
  232. end;
  233. procedure tcoffdata.writesymbol(p:pasmsymbol);
  234. var
  235. sym : toutputsymbol;
  236. s : string;
  237. begin
  238. { already written ? }
  239. if p^.idx<>-1 then
  240. exit;
  241. { be sure that the section will exists }
  242. if (p^.section<>sec_none) and not(assigned(sects[p^.section])) then
  243. createsection(p^.section);
  244. FillChar(sym,sizeof(sym),0);
  245. sym.value:=p^.size;
  246. sym.bind:=p^.bind;
  247. sym.typ:=AT_NONE;
  248. { if local of global then set the section value to the address
  249. of the symbol }
  250. if sym.bind in [AB_LOCAL,AB_GLOBAL] then
  251. begin
  252. sym.section:=p^.section;
  253. sym.value:=p^.address+sects[sym.section].mempos;
  254. end;
  255. { store the symbol, but not the local ones }
  256. if (sym.bind<>AB_LOCAL) then
  257. begin
  258. { symbolname }
  259. s:=p^.name;
  260. if length(s)>8 then
  261. begin
  262. sym.nameidx:=Strs.size+4;
  263. Strs.writestr(s);
  264. Strs.writestr(#0);
  265. end
  266. else
  267. begin
  268. sym.nameidx:=-1;
  269. sym.namestr:=s;
  270. end;
  271. { update the asmsymbol index }
  272. p^.idx:=Syms.size div sizeof(TOutputSymbol);
  273. { write the symbol }
  274. Syms.write(sym,sizeof(toutputsymbol));
  275. end
  276. else
  277. begin
  278. p^.idx:=-2; { local }
  279. end;
  280. end;
  281. procedure tcoffdata.writereloc(data,len:longint;p:pasmsymbol;relative:relative_type);
  282. var
  283. curraddr,
  284. symaddr : longint;
  285. begin
  286. if not assigned(sects[currsec]) then
  287. createsection(currsec);
  288. if assigned(p) then
  289. begin
  290. { current address }
  291. curraddr:=sects[currsec].mempos+sects[currsec].datasize;
  292. { real address of the symbol }
  293. symaddr:=p^.address;
  294. if p^.section<>sec_none then
  295. inc(symaddr,sects[p^.section].mempos);
  296. { no symbol relocation need inside a section }
  297. if p^.section=currsec then
  298. begin
  299. case relative of
  300. relative_false :
  301. begin
  302. sects[currsec].addsectionreloc(curraddr,currsec,relative_false);
  303. inc(data,symaddr);
  304. end;
  305. relative_true :
  306. begin
  307. inc(data,symaddr-len-sects[currsec].datasize);
  308. end;
  309. relative_rva :
  310. begin
  311. sects[currsec].addsectionreloc(curraddr,currsec,relative_rva);
  312. inc(data,symaddr);
  313. end;
  314. end;
  315. end
  316. else
  317. begin
  318. writesymbol(p);
  319. if (p^.section<>sec_none) and (relative<>relative_true) then
  320. sects[currsec].addsectionreloc(curraddr,p^.section,relative)
  321. else
  322. sects[currsec].addsymreloc(curraddr,p,relative);
  323. if not win32 then {seems wrong to me (PM) }
  324. inc(data,symaddr)
  325. else
  326. if (relative<>relative_true) and (p^.section<>sec_none) then
  327. inc(data,symaddr);
  328. if relative=relative_true then
  329. begin
  330. if win32 then
  331. dec(data,len-4)
  332. else
  333. dec(data,len+sects[currsec].datasize);
  334. end;
  335. end;
  336. end;
  337. sects[currsec].write(data,len);
  338. end;
  339. procedure tcoffdata.writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc : boolean);
  340. var
  341. stab : coffstab;
  342. s : tsection;
  343. curraddr : longint;
  344. begin
  345. s:=section;
  346. { local var can be at offset -1 !! PM }
  347. if reloc then
  348. begin
  349. if (offset=-1) then
  350. begin
  351. if s=sec_none then
  352. offset:=0
  353. else
  354. offset:=sects[s].datasize;
  355. end;
  356. if (s<>sec_none) then
  357. inc(offset,sects[s].datapos);
  358. end;
  359. if assigned(p) and (p[0]<>#0) then
  360. begin
  361. stab.strpos:=sects[sec_stabstr].datasize;
  362. sects[sec_stabstr].write(p^,strlen(p)+1);
  363. end
  364. else
  365. stab.strpos:=0;
  366. stab.ntype:=nidx;
  367. stab.ndesc:=line;
  368. stab.nother:=nother;
  369. stab.nvalue:=offset;
  370. sects[sec_stab].write(stab,sizeof(stab));
  371. { when the offset is not 0 then write a relocation, take also the
  372. hdrstab into account with the offset }
  373. if reloc then
  374. begin
  375. { current address }
  376. curraddr:=sects[sec_stab].mempos+sects[sec_stab].datasize;
  377. if DLLSource and RelocSection then
  378. { avoid relocation in the .stab section
  379. because it ends up in the .reloc section instead }
  380. sects[sec_stab].addsectionreloc(curraddr-4,s,relative_rva)
  381. else
  382. sects[sec_stab].addsectionreloc(curraddr-4,s,relative_false);
  383. end;
  384. end;
  385. procedure tcoffdata.writesymstabs(section:tsection;offset:longint;p:pchar;ps:pasmsymbol;
  386. nidx,nother,line:longint;reloc:boolean);
  387. var
  388. stab : coffstab;
  389. curraddr : longint;
  390. begin
  391. { do not use the size stored in offset field
  392. this is DJGPP specific ! PM }
  393. if win32 then
  394. offset:=0;
  395. { local var can be at offset -1 !! PM }
  396. if reloc then
  397. begin
  398. if (offset=-1) then
  399. begin
  400. if section=sec_none then
  401. offset:=0
  402. else
  403. offset:=sects[section].datasize;
  404. end;
  405. if (section<>sec_none) then
  406. inc(offset,sects[section].mempos);
  407. end;
  408. if assigned(p) and (p[0]<>#0) then
  409. begin
  410. stab.strpos:=sects[sec_stabstr].datasize;
  411. sects[sec_stabstr].write(p^,strlen(p)+1);
  412. end
  413. else
  414. stab.strpos:=0;
  415. stab.ntype:=nidx;
  416. stab.ndesc:=line;
  417. stab.nother:=nother;
  418. stab.nvalue:=offset;
  419. sects[sec_stab].write(stab,sizeof(stab));
  420. { when the offset is not 0 then write a relocation, take also the
  421. hdrstab into account with the offset }
  422. if reloc then
  423. begin
  424. { current address }
  425. curraddr:=sects[sec_stab].mempos+sects[sec_stab].datasize;
  426. if DLLSource and RelocSection then
  427. { avoid relocation in the .stab section
  428. because it ends up in the .reloc section instead }
  429. sects[sec_stab].addsymreloc(curraddr-4,ps,relative_rva)
  430. else
  431. sects[sec_stab].addsymreloc(curraddr-4,ps,relative_false);
  432. end;
  433. end;
  434. procedure tcoffdata.setsectionsizes(var s:tsecsize);
  435. var
  436. mempos : longint;
  437. sec : tsection;
  438. begin
  439. { multiply stab with real size }
  440. s[sec_stab]:=s[sec_stab]*sizeof(coffstab);
  441. { if debug then also count header stab }
  442. if (cs_debuginfo in aktmoduleswitches) then
  443. begin
  444. inc(s[sec_stab],sizeof(coffstab));
  445. inc(s[sec_stabstr],length(SplitFileName(current_module.mainsource^))+2);
  446. end;
  447. { calc mempos }
  448. mempos:=0;
  449. for sec:=low(tsection) to high(tsection) do
  450. begin
  451. if (s[sec]>0) and
  452. (not assigned(sects[sec])) then
  453. createsection(sec);
  454. if assigned(sects[sec]) then
  455. begin
  456. sects[sec].memsize:=s[sec];
  457. { memory position }
  458. if not win32 then
  459. begin
  460. sects[sec].mempos:=mempos;
  461. inc(mempos,align(sects[sec].memsize,sects[sec].addralign));
  462. end;
  463. end;
  464. end;
  465. end;
  466. {****************************************************************************
  467. TCoffOutput
  468. ****************************************************************************}
  469. constructor tcoffoutput.createdjgpp(smart:boolean);
  470. begin
  471. inherited create(smart);
  472. win32:=false;
  473. end;
  474. constructor tcoffoutput.createwin32(smart:boolean);
  475. begin
  476. inherited create(smart);
  477. win32:=true;
  478. end;
  479. function tcoffoutput.initwriting(Aplace:tcutplace):tobjectdata;
  480. begin
  481. inherited initwriting(Aplace);
  482. initsym:=0;
  483. if win32 then
  484. data:=tcoffdata.createwin32
  485. else
  486. data:=tcoffdata.createdjgpp;
  487. initwriting:=data;
  488. end;
  489. procedure tcoffoutput.write_relocs(s:tobjectsection);
  490. var
  491. rel : coffreloc;
  492. hr,r : poutputreloc;
  493. begin
  494. r:=s.relochead;
  495. while assigned(r) do
  496. begin
  497. rel.address:=r^.address;
  498. if assigned(r^.symbol) then
  499. begin
  500. if (r^.symbol^.bind=AB_LOCAL) then
  501. rel.sym:=2*data.sects[r^.symbol^.section].secsymidx
  502. else
  503. begin
  504. if r^.symbol^.idx=-1 then
  505. internalerror(4321);
  506. rel.sym:=r^.symbol^.idx+initsym;
  507. end;
  508. end
  509. else
  510. begin
  511. if r^.section<>sec_none then
  512. rel.sym:=2*data.sects[r^.section].secsymidx
  513. else
  514. rel.sym:=0;
  515. end;
  516. case r^.typ of
  517. relative_true : rel.relative:=$14;
  518. relative_false : rel.relative:=$6;
  519. relative_rva : rel.relative:=$7;
  520. end;
  521. writer.write(rel,sizeof(rel));
  522. { goto next and dispose this reloc }
  523. hr:=r;
  524. r:=r^.next;
  525. dispose(hr);
  526. end;
  527. end;
  528. procedure tcoffoutput.write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  529. var
  530. sym : coffsymbol;
  531. begin
  532. FillChar(sym,sizeof(sym),0);
  533. if strpos=-1 then
  534. move(name[1],sym.name,length(name))
  535. else
  536. sym.strpos:=strpos;
  537. sym.value:=value;
  538. sym.section:=section;
  539. sym.typ:=typ;
  540. sym.aux:=aux;
  541. writer.write(sym,sizeof(sym));
  542. end;
  543. procedure tcoffoutput.write_symbols;
  544. var
  545. filename : string[18];
  546. sec : tsection;
  547. sectionval,
  548. i : longint;
  549. globalval : byte;
  550. secrec : coffsectionrec;
  551. sym : toutputsymbol;
  552. begin
  553. with tcoffdata(data) do
  554. begin
  555. { The `.file' record, and the file name auxiliary record }
  556. write_symbol ('.file', -1, 0, -2, $67, 1);
  557. fillchar(filename,sizeof(filename),0);
  558. filename:=SplitFileName(current_module.mainsource^);
  559. writer.write(filename[1],sizeof(filename)-1);
  560. { The section records, with their auxiliaries, also store the
  561. symbol index }
  562. for sec:=low(tsection) to high(tsection) do
  563. if assigned(sects[sec]) then
  564. begin
  565. write_symbol(target_asm.secnames[sec],-1,sects[sec].mempos,sects[sec].secsymidx,3,1);
  566. fillchar(secrec,sizeof(secrec),0);
  567. secrec.len:=sects[sec].aligneddatasize;
  568. secrec.nrelocs:=sects[sec].nrelocs;
  569. writer.write(secrec,sizeof(secrec));
  570. end;
  571. { The real symbols }
  572. Syms.seek(0);
  573. for i:=1 to Syms.size div sizeof(TOutputSymbol) do
  574. begin
  575. Syms.read(sym,sizeof(TOutputSymbol));
  576. if sym.bind=AB_LOCAL then
  577. globalval:=3
  578. else
  579. globalval:=2;
  580. if assigned(sects[sym.section]) then
  581. sectionval:=sects[sym.section].secsymidx
  582. else
  583. sectionval:=0;
  584. write_symbol(sym.namestr,sym.nameidx,sym.value,sectionval,globalval,0);
  585. end;
  586. end;
  587. end;
  588. procedure tcoffoutput.writetodisk;
  589. var
  590. datapos,
  591. secsymidx,
  592. nsects,
  593. sympos,i : longint;
  594. hstab : coffstab;
  595. gotreloc : boolean;
  596. sec : tsection;
  597. header : coffheader;
  598. sechdr : coffsechdr;
  599. empty : array[0..15] of byte;
  600. hp : pdynamicblock;
  601. begin
  602. with tcoffdata(data) do
  603. begin
  604. { calc amount of sections we have }
  605. fillchar(empty,sizeof(empty),0);
  606. nsects:=0;
  607. initsym:=2; { 2 for the file }
  608. secsymidx:=0;
  609. for sec:=low(tsection) to high(tsection) do
  610. if assigned(sects[sec]) then
  611. begin
  612. inc(nsects);
  613. inc(secsymidx);
  614. sects[sec].secsymidx:=secsymidx;
  615. inc(initsym,2); { 2 for each section }
  616. end;
  617. { For the stab section we need an HdrSym which can now be
  618. calculated more easily }
  619. if assigned(sects[sec_stab]) then
  620. begin
  621. hstab.strpos:=1;
  622. hstab.ntype:=0;
  623. hstab.nother:=0;
  624. hstab.ndesc:=(sects[sec_stab].datasize div sizeof(coffstab))-1{+1 according to gas output PM};
  625. hstab.nvalue:=sects[sec_stabstr].datasize;
  626. sects[sec_stab].data.seek(0);
  627. sects[sec_stab].data.write(hstab,sizeof(hstab));
  628. end;
  629. { Calculate the filepositions }
  630. datapos:=sizeof(coffheader)+sizeof(coffsechdr)*nsects;
  631. { sections first }
  632. for sec:=low(tsection) to high(tsection) do
  633. if assigned(sects[sec]) then
  634. begin
  635. sects[sec].datapos:=datapos;
  636. if assigned(sects[sec].data) then
  637. inc(datapos,sects[sec].aligneddatasize);
  638. end;
  639. { relocs }
  640. gotreloc:=false;
  641. for sec:=low(tsection) to high(tsection) do
  642. if assigned(sects[sec]) then
  643. begin
  644. tcoffsection(sects[sec]).relocpos:=datapos;
  645. inc(datapos,10*sects[sec].nrelocs);
  646. if (not gotreloc) and (sects[sec].nrelocs>0) then
  647. gotreloc:=true;
  648. end;
  649. { symbols }
  650. sympos:=datapos;
  651. { COFF header }
  652. fillchar(header,sizeof(coffheader),0);
  653. header.mach:=$14c;
  654. header.nsects:=nsects;
  655. header.sympos:=sympos;
  656. header.syms:=(Syms.size div sizeof(TOutputSymbol))+initsym;
  657. if gotreloc then
  658. header.flag:=$104
  659. else
  660. header.flag:=$105;
  661. writer.write(header,sizeof(header));
  662. { Section headers }
  663. for sec:=low(tsection) to high(tsection) do
  664. if assigned(sects[sec]) then
  665. begin
  666. fillchar(sechdr,sizeof(sechdr),0);
  667. move(target_asm.secnames[sec][1],sechdr.name,length(target_asm.secnames[sec]));
  668. if not win32 then
  669. begin
  670. sechdr.rvaofs:=sects[sec].mempos;
  671. sechdr.vsize:=sects[sec].mempos;
  672. end
  673. else
  674. begin
  675. if sec=sec_bss then
  676. sechdr.vsize:=sects[sec].aligneddatasize;
  677. end;
  678. sechdr.datasize:=sects[sec].aligneddatasize;
  679. if (sects[sec].datasize>0) and assigned(sects[sec].data) then
  680. sechdr.datapos:=sects[sec].datapos;
  681. sechdr.nrelocs:=sects[sec].nrelocs;
  682. sechdr.relocpos:=TCoffSection(sects[sec]).relocpos;
  683. sechdr.flags:=TCoffSection(sects[sec]).flags;
  684. writer.write(sechdr,sizeof(sechdr));
  685. end;
  686. { Sections }
  687. for sec:=low(tsection) to high(tsection) do
  688. if assigned(sects[sec]) and
  689. assigned(sects[sec].data) then
  690. begin
  691. sects[sec].alignsection;
  692. hp:=sects[sec].data.firstblock;
  693. while assigned(hp) do
  694. begin
  695. writer.write(hp^.data,hp^.used);
  696. hp:=hp^.next;
  697. end;
  698. end;
  699. { Relocs }
  700. for sec:=low(tsection) to high(tsection) do
  701. if assigned(sects[sec]) then
  702. write_relocs(sects[sec]);
  703. { Symbols }
  704. write_symbols;
  705. { Strings }
  706. i:=Strs.size+4;
  707. writer.write(i,4);
  708. hp:=Strs.firstblock;
  709. while assigned(hp) do
  710. begin
  711. writer.write(hp^.data,hp^.used);
  712. hp:=hp^.next;
  713. end;
  714. end;
  715. end;
  716. {****************************************************************************
  717. TCoffInput
  718. ****************************************************************************}
  719. end.
  720. {
  721. $Log$
  722. Revision 1.8 2000-12-25 00:07:26 peter
  723. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  724. tlinkedlist objects)
  725. Revision 1.7 2000/12/24 12:25:31 peter
  726. + cstreams unit
  727. * dynamicarray object to class
  728. Revision 1.6 2000/12/23 19:59:35 peter
  729. * object to class for ow/og objects
  730. * split objectdata from objectoutput
  731. Revision 1.5 2000/12/21 12:06:38 jonas
  732. * changed type of all "flags" variables/parameters/fields to cardinal
  733. and removed longint typecasts around constants
  734. Revision 1.4 2000/12/20 15:59:04 jonas
  735. * fixed range check errors
  736. Revision 1.3 2000/12/18 21:56:35 peter
  737. * fixed stab reloc writing
  738. Revision 1.2 2000/12/07 17:19:42 jonas
  739. * new constant handling: from now on, hex constants >$7fffffff are
  740. parsed as unsigned constants (otherwise, $80000000 got sign extended
  741. and became $ffffffff80000000), all constants in the longint range
  742. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  743. are cardinals and the rest are int64's.
  744. * added lots of longint typecast to prevent range check errors in the
  745. compiler and rtl
  746. * type casts of symbolic ordinal constants are now preserved
  747. * fixed bug where the original resulttype wasn't restored correctly
  748. after doing a 64bit rangecheck
  749. Revision 1.1 2000/11/12 22:20:37 peter
  750. * create generic toutputsection for binary writers
  751. }