ogcoff.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  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 : cardinal;
  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. curraddr : longint;
  351. begin
  352. s:=section;
  353. { local var can be at offset -1 !! PM }
  354. if reloc then
  355. begin
  356. if (offset=-1) then
  357. begin
  358. if s=sec_none then
  359. offset:=0
  360. else
  361. offset:=sects[s]^.datasize;
  362. end;
  363. if (s<>sec_none) then
  364. inc(offset,sects[s]^.datapos);
  365. end;
  366. if assigned(p) and (p[0]<>#0) then
  367. begin
  368. stab.strpos:=sects[sec_stabstr]^.datasize;
  369. sects[sec_stabstr]^.write(p^,strlen(p)+1);
  370. end
  371. else
  372. stab.strpos:=0;
  373. stab.ntype:=nidx;
  374. stab.ndesc:=line;
  375. stab.nother:=nother;
  376. stab.nvalue:=offset;
  377. sects[sec_stab]^.write(stab,sizeof(stab));
  378. { when the offset is not 0 then write a relocation, take also the
  379. hdrstab into account with the offset }
  380. { current address }
  381. curraddr:=sects[sec_stab]^.mempos+sects[sec_stab]^.datasize;
  382. if reloc then
  383. if DLLSource and RelocSection then
  384. { avoid relocation in the .stab section
  385. because it ends up in the .reloc section instead }
  386. sects[sec_stab]^.addsectionreloc(curraddr-4,s,relative_rva)
  387. else
  388. sects[sec_stab]^.addsectionreloc(curraddr-4,s,relative_false);
  389. end;
  390. procedure tcoffoutput.writesymstabs(section:tsection;offset:longint;p:pchar;ps:pasmsymbol;
  391. nidx,nother,line:longint;reloc:boolean);
  392. var
  393. stab : coffstab;
  394. curraddr : longint;
  395. begin
  396. { do not use the size stored in offset field
  397. this is DJGPP specific ! PM }
  398. if win32 then
  399. offset:=0;
  400. { local var can be at offset -1 !! PM }
  401. if reloc then
  402. begin
  403. if (offset=-1) then
  404. begin
  405. if section=sec_none then
  406. offset:=0
  407. else
  408. offset:=sects[section]^.datasize;
  409. end;
  410. if (section<>sec_none) then
  411. inc(offset,sects[section]^.mempos);
  412. end;
  413. if assigned(p) and (p[0]<>#0) then
  414. begin
  415. stab.strpos:=sects[sec_stabstr]^.datasize;
  416. sects[sec_stabstr]^.write(p^,strlen(p)+1);
  417. end
  418. else
  419. stab.strpos:=0;
  420. stab.ntype:=nidx;
  421. stab.ndesc:=line;
  422. stab.nother:=nother;
  423. stab.nvalue:=offset;
  424. sects[sec_stab]^.write(stab,sizeof(stab));
  425. { when the offset is not 0 then write a relocation, take also the
  426. hdrstab into account with the offset }
  427. { current address }
  428. curraddr:=sects[sec_stab]^.mempos+sects[sec_stab]^.datasize;
  429. if reloc then
  430. begin
  431. if DLLSource and RelocSection then
  432. { avoid relocation in the .stab section
  433. because it ends up in the .reloc section instead }
  434. sects[sec_stab]^.addsymreloc(curraddr-4,ps,relative_rva)
  435. else
  436. sects[sec_stab]^.addsymreloc(curraddr-4,ps,relative_false);
  437. end;
  438. end;
  439. procedure tcoffoutput.setsectionsizes(var s:tsecsize);
  440. var
  441. mempos : longint;
  442. sec : tsection;
  443. begin
  444. { multiply stab with real size }
  445. s[sec_stab]:=s[sec_stab]*sizeof(coffstab);
  446. { if debug then also count header stab }
  447. if (cs_debuginfo in aktmoduleswitches) then
  448. begin
  449. inc(s[sec_stab],sizeof(coffstab));
  450. inc(s[sec_stabstr],length(SplitFileName(current_module^.mainsource^))+2);
  451. end;
  452. { calc mempos }
  453. mempos:=0;
  454. for sec:=low(tsection) to high(tsection) do
  455. begin
  456. if (s[sec]>0) and
  457. (not assigned(sects[sec])) then
  458. createsection(sec);
  459. if assigned(sects[sec]) then
  460. begin
  461. sects[sec]^.memsize:=s[sec];
  462. { memory position }
  463. if not win32 then
  464. begin
  465. sects[sec]^.mempos:=mempos;
  466. inc(mempos,align(sects[sec]^.memsize,sects[sec]^.addralign));
  467. end;
  468. end;
  469. end;
  470. end;
  471. {***********************************************
  472. Writing to disk
  473. ***********************************************}
  474. procedure tcoffoutput.write_relocs(s:poutputsection);
  475. var
  476. rel : coffreloc;
  477. hr,r : poutputreloc;
  478. begin
  479. r:=s^.relochead;
  480. while assigned(r) do
  481. begin
  482. rel.address:=r^.address;
  483. if assigned(r^.symbol) then
  484. begin
  485. if (r^.symbol^.bind=AB_LOCAL) then
  486. rel.sym:=2*sects[r^.symbol^.section]^.secsymidx
  487. else
  488. begin
  489. if r^.symbol^.idx=-1 then
  490. internalerror(4321);
  491. rel.sym:=r^.symbol^.idx+initsym;
  492. end;
  493. end
  494. else
  495. begin
  496. if r^.section<>sec_none then
  497. rel.sym:=2*sects[r^.section]^.secsymidx
  498. else
  499. rel.sym:=0;
  500. end;
  501. case r^.typ of
  502. relative_true : rel.relative:=$14;
  503. relative_false : rel.relative:=$6;
  504. relative_rva : rel.relative:=$7;
  505. end;
  506. writer^.write(rel,sizeof(rel));
  507. { goto next and dispose this reloc }
  508. hr:=r;
  509. r:=r^.next;
  510. dispose(hr);
  511. end;
  512. end;
  513. procedure tcoffoutput.write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  514. var
  515. sym : coffsymbol;
  516. begin
  517. FillChar(sym,sizeof(sym),0);
  518. if strpos=-1 then
  519. move(name[1],sym.name,length(name))
  520. else
  521. sym.strpos:=strpos;
  522. sym.value:=value;
  523. sym.section:=section;
  524. sym.typ:=typ;
  525. sym.aux:=aux;
  526. writer^.write(sym,sizeof(sym));
  527. end;
  528. procedure tcoffoutput.write_symbols;
  529. var
  530. filename : string[18];
  531. sec : tsection;
  532. value,
  533. sectionval,
  534. i : longint;
  535. globalval : byte;
  536. secrec : coffsectionrec;
  537. sym : toutputsymbol;
  538. begin
  539. { The `.file' record, and the file name auxiliary record }
  540. write_symbol ('.file', -1, 0, -2, $67, 1);
  541. fillchar(filename,sizeof(filename),0);
  542. filename:=SplitFileName(current_module^.mainsource^);
  543. writer^.write(filename[1],sizeof(filename)-1);
  544. { The section records, with their auxiliaries, also store the
  545. symbol index }
  546. for sec:=low(tsection) to high(tsection) do
  547. if assigned(sects[sec]) then
  548. begin
  549. write_symbol(target_asm.secnames[sec],-1,sects[sec]^.mempos,sects[sec]^.secsymidx,3,1);
  550. fillchar(secrec,sizeof(secrec),0);
  551. secrec.len:=sects[sec]^.aligneddatasize;
  552. secrec.nrelocs:=sects[sec]^.nrelocs;
  553. writer^.write(secrec,sizeof(secrec));
  554. end;
  555. { The real symbols }
  556. syms^.seek(0);
  557. for i:=1 to syms^.size div sizeof(TOutputSymbol) do
  558. begin
  559. syms^.read(sym,sizeof(TOutputSymbol));
  560. if sym.bind=AB_LOCAL then
  561. globalval:=3
  562. else
  563. globalval:=2;
  564. if assigned(sects[sym.section]) then
  565. sectionval:=sects[sym.section]^.secsymidx
  566. else
  567. sectionval:=0;
  568. write_symbol(sym.namestr,sym.nameidx,sym.value,sectionval,globalval,0);
  569. end;
  570. end;
  571. procedure tcoffoutput.writetodisk;
  572. var
  573. datapos,
  574. secsymidx,
  575. nsects,
  576. sympos,i : longint;
  577. hstab : coffstab;
  578. gotreloc : boolean;
  579. sec : tsection;
  580. header : coffheader;
  581. sechdr : coffsechdr;
  582. empty : array[0..15] of byte;
  583. hp : pdynamicblock;
  584. begin
  585. { calc amount of sections we have }
  586. fillchar(empty,sizeof(empty),0);
  587. nsects:=0;
  588. initsym:=2; { 2 for the file }
  589. secsymidx:=0;
  590. for sec:=low(tsection) to high(tsection) do
  591. if assigned(sects[sec]) then
  592. begin
  593. inc(nsects);
  594. inc(secsymidx);
  595. sects[sec]^.secsymidx:=secsymidx;
  596. inc(initsym,2); { 2 for each section }
  597. end;
  598. { For the stab section we need an HdrSym which can now be
  599. calculated more easily }
  600. if assigned(sects[sec_stab]) then
  601. begin
  602. hstab.strpos:=1;
  603. hstab.ntype:=0;
  604. hstab.nother:=0;
  605. hstab.ndesc:=(sects[sec_stab]^.datasize div sizeof(coffstab))-1{+1 according to gas output PM};
  606. hstab.nvalue:=sects[sec_stabstr]^.datasize;
  607. sects[sec_stab]^.data^.seek(0);
  608. sects[sec_stab]^.data^.write(hstab,sizeof(hstab));
  609. end;
  610. { Calculate the filepositions }
  611. datapos:=sizeof(coffheader)+sizeof(coffsechdr)*nsects;
  612. { sections first }
  613. for sec:=low(tsection) to high(tsection) do
  614. if assigned(sects[sec]) then
  615. begin
  616. sects[sec]^.datapos:=datapos;
  617. if assigned(sects[sec]^.data) then
  618. inc(datapos,sects[sec]^.aligneddatasize);
  619. end;
  620. { relocs }
  621. gotreloc:=false;
  622. for sec:=low(tsection) to high(tsection) do
  623. if assigned(sects[sec]) then
  624. begin
  625. PCoffSection(sects[sec])^.relocpos:=datapos;
  626. inc(datapos,10*sects[sec]^.nrelocs);
  627. if (not gotreloc) and (sects[sec]^.nrelocs>0) then
  628. gotreloc:=true;
  629. end;
  630. { symbols }
  631. sympos:=datapos;
  632. { COFF header }
  633. fillchar(header,sizeof(coffheader),0);
  634. header.mach:=$14c;
  635. header.nsects:=nsects;
  636. header.sympos:=sympos;
  637. header.syms:=(syms^.size div sizeof(TOutputSymbol))+initsym;
  638. if gotreloc then
  639. header.flag:=$104
  640. else
  641. header.flag:=$105;
  642. writer^.write(header,sizeof(header));
  643. { Section headers }
  644. for sec:=low(tsection) to high(tsection) do
  645. if assigned(sects[sec]) then
  646. begin
  647. fillchar(sechdr,sizeof(sechdr),0);
  648. move(target_asm.secnames[sec][1],sechdr.name,length(target_asm.secnames[sec]));
  649. if not win32 then
  650. begin
  651. sechdr.rvaofs:=sects[sec]^.mempos;
  652. sechdr.vsize:=sects[sec]^.mempos;
  653. end
  654. else
  655. begin
  656. if sec=sec_bss then
  657. sechdr.vsize:=sects[sec]^.aligneddatasize;
  658. end;
  659. sechdr.datasize:=sects[sec]^.aligneddatasize;
  660. if (sects[sec]^.datasize>0) and assigned(sects[sec]^.data) then
  661. sechdr.datapos:=sects[sec]^.datapos;
  662. sechdr.nrelocs:=sects[sec]^.nrelocs;
  663. sechdr.relocpos:=PCoffSection(sects[sec])^.relocpos;
  664. sechdr.flags:=PCoffSection(sects[sec])^.flags;
  665. writer^.write(sechdr,sizeof(sechdr));
  666. end;
  667. { Sections }
  668. for sec:=low(tsection) to high(tsection) do
  669. if assigned(sects[sec]) and
  670. assigned(sects[sec]^.data) then
  671. begin
  672. sects[sec]^.alignsection;
  673. hp:=sects[sec]^.data^.firstblock;
  674. while assigned(hp) do
  675. begin
  676. writer^.write(hp^.data,hp^.used);
  677. hp:=hp^.next;
  678. end;
  679. end;
  680. { Relocs }
  681. for sec:=low(tsection) to high(tsection) do
  682. if assigned(sects[sec]) then
  683. write_relocs(sects[sec]);
  684. { Symbols }
  685. write_symbols;
  686. { Strings }
  687. i:=strs^.size+4;
  688. writer^.write(i,4);
  689. hp:=strs^.firstblock;
  690. while assigned(hp) do
  691. begin
  692. writer^.write(hp^.data,hp^.used);
  693. hp:=hp^.next;
  694. end;
  695. end;
  696. end.
  697. {
  698. $Log$
  699. Revision 1.4 2000-12-20 15:59:04 jonas
  700. * fixed range check errors
  701. Revision 1.3 2000/12/18 21:56:35 peter
  702. * fixed stab reloc writing
  703. Revision 1.2 2000/12/07 17:19:42 jonas
  704. * new constant handling: from now on, hex constants >$7fffffff are
  705. parsed as unsigned constants (otherwise, $80000000 got sign extended
  706. and became $ffffffff80000000), all constants in the longint range
  707. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  708. are cardinals and the rest are int64's.
  709. * added lots of longint typecast to prevent range check errors in the
  710. compiler and rtl
  711. * type casts of symbolic ordinal constants are now preserved
  712. * fixed bug where the original resulttype wasn't restored correctly
  713. after doing a 64bit rangecheck
  714. Revision 1.1 2000/11/12 22:20:37 peter
  715. * create generic toutputsection for binary writers
  716. }