ogcoff.pas 24 KB

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