og386elf.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Peter Vreman
  4. Contains the binary elf 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 og386elf;
  22. interface
  23. uses
  24. cobjects,og386,cpubase,aasm;
  25. const
  26. R_386_32 = 1; { ordinary absolute relocation }
  27. R_386_PC32 = 2; { PC-relative relocation }
  28. R_386_GOT32 = 3; { an offset into GOT }
  29. R_386_PLT32 = 4; { a PC-relative offset into PLT }
  30. R_386_GOTOFF = 9; { an offset from GOT base }
  31. R_386_GOTPC = 10; { a PC-relative offset _to_ GOT }
  32. SHT_PROGBITS = 1;
  33. SHT_NOBITS = 8;
  34. SHF_WRITE = 1;
  35. SHF_ALLOC = 2;
  36. SHF_EXECINSTR = 4;
  37. type
  38. telf32header=packed record
  39. magic0123 : longint;
  40. file_class : byte;
  41. data_encoding : byte;
  42. file_version : byte;
  43. padding : array[$07..$0f] of byte;
  44. e_type : word;
  45. e_machine : word;
  46. e_version : longint;
  47. e_entry : longint; // entrypoint
  48. e_phoff : longint; // program header offset
  49. e_shoff : longint; // sections header offset
  50. e_flags : longint;
  51. e_ehsize : word; // elf header size in bytes
  52. e_phentsize : word; // size of an entry in the program header array
  53. e_phnum : word; // 0..e_phnum-1 of entrys
  54. e_shentsize : word; // size of an entry in sections header array
  55. e_shnum : word; // 0..e_shnum-1 of entrys
  56. e_shstrndx : word; // index of string section header
  57. end;
  58. telf32sechdr=packed record
  59. sh_name : longint;
  60. sh_type : longint;
  61. sh_flags : longint;
  62. sh_addr : longint;
  63. sh_offset : longint;
  64. sh_size : longint;
  65. sh_link : longint;
  66. sh_info : longint;
  67. sh_addralign : longint;
  68. sh_entsize : longint;
  69. end;
  70. preloc = ^treloc;
  71. treloc = packed record
  72. next : preloc;
  73. address : longint;
  74. symbol : pasmsymbol;
  75. {section : tsection;} { only used if symbol=nil }
  76. typ : byte;
  77. end;
  78. psymbol = ^tsymbol;
  79. tsymbol = packed record
  80. strpos : longint;
  81. section : longint;
  82. value : longint;
  83. typ : TAsmsymtype;
  84. size : longint;
  85. globnum : longint;
  86. next,
  87. nextfwd : psymbol;
  88. end;
  89. pelfsection = ^telfsection;
  90. telfsection = object
  91. index : tsection;
  92. name : string[16];
  93. elftype,
  94. elfflags,
  95. align : longint;
  96. data : PDynamicArray;
  97. len,
  98. pos,
  99. nrelocs : longint;
  100. relochead : PReloc;
  101. reloctail : ^PReloc;
  102. rel : PDynamicArray;
  103. gsyms : PSymbol;
  104. constructor init(sec:TSection;Atype,Aflags,Aalign:longint);
  105. constructor initname(const Aname:string;Atype,Aflags,Aalign:longint);
  106. destructor done;
  107. procedure write(var d;l:longint);
  108. procedure alloc(l:longint);
  109. procedure addsymreloc(ofs:longint;p:pasmsymbol;relative:relative_type);
  110. procedure addsectionreloc(ofs:longint;sec:tsection);
  111. end;
  112. pelfoutput = ^telfoutput;
  113. telfoutput = object(tobjectoutput)
  114. sects : array[TSection] of PElfSection;
  115. symtab_sect,
  116. strtab_sect,
  117. shstrtab_sect,
  118. gotpc_sect,
  119. gotoff_sect,
  120. got_sect,
  121. plt_sect,
  122. sym_sect : PElfSection;
  123. strs,
  124. syms : Pdynamicarray;
  125. initsym : longint;
  126. constructor init;
  127. destructor done;virtual;
  128. procedure initwriting;virtual;
  129. procedure donewriting;virtual;
  130. procedure writebytes(var data;len:longint);virtual;
  131. procedure writealloc(len:longint);virtual;
  132. procedure writereloc(data,len:longint;p:pasmsymbol;relative:relative_type);virtual;
  133. procedure writesymbol(p:pasmsymbol);virtual;
  134. procedure writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc:boolean);virtual;
  135. private
  136. procedure createsection(sec:tsection;const name:string);
  137. procedure write_relocs(s:pcoffsection);
  138. procedure write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  139. procedure write_symbols;
  140. procedure writetodisk;
  141. end;
  142. implementation
  143. uses
  144. strings,verbose,
  145. globtype,globals,files;
  146. type
  147. { Structures which are written directly to the output file }
  148. const
  149. sec_2_str : array[tsection] of string[8]=('',
  150. '.text','.data','.bss',
  151. '.stab','.stabstr',
  152. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  153. ''
  154. );
  155. {****************************************************************************
  156. TSection
  157. ****************************************************************************}
  158. constructor telfsection.init(sec:TSection;Atype,Aflags,Aalign:longint);
  159. begin
  160. index:=sec;
  161. name:=sec_2_str[sec];
  162. elftype:=AType;
  163. elfflags:=AFlags;
  164. align:=Aalign;
  165. relocHead:=nil;
  166. relocTail:=@relocHead;
  167. Len:=0;
  168. Pos:=0;
  169. NRelocs:=0;
  170. if sec=sec_bss then
  171. data:=nil
  172. else
  173. new(Data,Init(1,8192));
  174. new(rel,Init(1,8192));
  175. gsyms:=nil;
  176. end;
  177. constructor initname(const Aname:string;Atype,Aflags,Aalign:longint);
  178. begin
  179. index:=sec_none;
  180. name:=Aname;
  181. elftype:=AType;
  182. elfflags:=AFlags;
  183. align:=Aalign;
  184. relocHead:=nil;
  185. relocTail:=@relocHead;
  186. Len:=0;
  187. Pos:=0;
  188. NRelocs:=0;
  189. new(Data,Init(1,8192));
  190. new(rel,Init(1,8192));
  191. gsyms:=nil;
  192. end;
  193. destructor telfsection.done;
  194. begin
  195. if assigned(Data) then
  196. dispose(Data,done);
  197. if assigned(rel) then
  198. dispose(rel,done);
  199. end;
  200. procedure telfsection.write(var d;l:longint);
  201. begin
  202. if not assigned(Data) then
  203. Internalerror(3334441);
  204. Data^.write(d,l);
  205. inc(len,l);
  206. end;
  207. procedure telfsection.alloc(l:longint);
  208. begin
  209. if assigned(Data) then
  210. Internalerror(3334442);
  211. inc(len,l);
  212. end;
  213. procedure telfsection.addsymreloc(ofs:longint;p:pasmsymbol;typ:byte);
  214. var
  215. r : PReloc;
  216. begin
  217. new(r);
  218. reloctail^:=r;
  219. reloctail:=@r^.next;
  220. r^.next:=nil;
  221. r^.address:=ofs;
  222. r^.symbol:=p;
  223. {r^.section:=sec_none;}
  224. r^.typ:=typ;
  225. inc(nrelocs);
  226. end;
  227. { procedure telfsection.addsectionreloc(ofs:longint;sec:tsection);
  228. var
  229. r : PReloc;
  230. begin
  231. new(r);
  232. reloctail^:=r;
  233. reloctail:=@r^.next;
  234. r^.next:=nil;
  235. r^.address:=ofs;
  236. r^.symbol:=nil;
  237. r^.section:=sec;
  238. r^.relative:=relative_false;
  239. inc(nrelocs);
  240. end; }
  241. {****************************************************************************
  242. Genericcoffoutput
  243. ****************************************************************************}
  244. const
  245. {$ifdef TP}
  246. symbolresize = 50;
  247. strsresize = 200;
  248. {$else}
  249. symbolresize = 200;
  250. strsresize = 8192;
  251. {$endif}
  252. constructor telfoutputput.init;
  253. begin
  254. inherited init;
  255. end;
  256. destructor telfoutputput.done;
  257. begin
  258. inherited done;
  259. end;
  260. procedure telfoutputput.initwriting;
  261. var
  262. s : string;
  263. begin
  264. inherited initwriting;
  265. { reset }
  266. initsym:=0;
  267. new(syms,init(sizeof(TSymbol),symbolresize));
  268. FillChar(Sects,sizeof(Sects),0);
  269. { default sections }
  270. new(symtab_sect,initname('.symtab',2,4));
  271. new(strtab_sect,initname('.strtab',3,1));
  272. new(shstrtab_sect,initname('.shstrtab',3,1));
  273. { we need at least the following sections }
  274. createsection(sec_code);
  275. createsection(sec_data);
  276. createsection(sec_bss);
  277. { create stabs sections if debugging }
  278. if (cs_debuginfo in aktmoduleswitches) then
  279. begin
  280. createsection(sec_stab);
  281. createsection(sec_stabstr);
  282. writestabs(sec_none,0,nil,0,0,0,false);
  283. { write zero pchar and name together (PM) }
  284. s:=#0+SplitFileName(current_module^.mainsource^)+#0;
  285. sects[sec_stabstr]^.write(s[1],length(s));
  286. end;
  287. end;
  288. procedure telfoutputput.donewriting;
  289. var
  290. sec : tsection;
  291. begin
  292. writetodisk;
  293. dispose(syms,done);
  294. dispose(strs,done);
  295. for sec:=low(tsection) to high(tsection) do
  296. if assigned(sects[sec]) then
  297. dispose(sects[sec],done);
  298. inherited donewriting;
  299. end;
  300. procedure telfoutputput.createsection(sec:tsection);
  301. var
  302. Aflags,AType,AAlign : longint;
  303. begin
  304. Aflags:=0;
  305. Atype:=0;
  306. case sec of
  307. sec_code :
  308. begin
  309. Aflags:=SHF_ALLOC or SHF_EXECINSTR;
  310. AType:=SHT_PROGBITS;
  311. AAlign:=16;
  312. end;
  313. sec_data :
  314. begin
  315. Aflags:=SHF_ALLOC or SHF_WRITE;
  316. AType:=SHT_PROGBITS;
  317. AAlign:=4;
  318. end;
  319. sec_bss :
  320. begin
  321. Aflags:=SHF_ALLOC or SHF_WRITE;
  322. AType:=SHT_NOBITS;
  323. AAlign:=4;
  324. end;
  325. end;
  326. sects[sec]:=new(PElfSection,init(Sec,AType,Aflags,AAlign));
  327. end;
  328. procedure telfoutputput.writesymbol(p:pasmsymbol);
  329. var
  330. pos : longint;
  331. sym : tsymbol;
  332. c : char;
  333. s : string;
  334. begin
  335. { already written ? }
  336. if p^.idx<>-1 then
  337. exit;
  338. { be sure that the section will exists }
  339. if (p^.section<>sec_none) and not(assigned(sects[p^.section])) then
  340. createsection(p^.section);
  341. { symbolname }
  342. pos:=strs^.usedsize+4;
  343. c:=#0;
  344. s:=p^.name;
  345. if length(s)>8 then
  346. begin
  347. s:=s+#0;
  348. strs^.write(s[1],length(s));
  349. end
  350. else
  351. pos:=-1;
  352. FillChar(sym,sizeof(sym),0);
  353. sym.strpos:=pos;
  354. if pos=-1 then
  355. sym.name:=s;
  356. sym.value:=p^.size;
  357. sym.typ:=p^.typ;
  358. { if local of global then set the section value to the address
  359. of the symbol }
  360. if p^.typ in [AS_LOCAL,AS_GLOBAL] then
  361. begin
  362. sym.section:=ord(p^.section);
  363. sym.value:=p^.address;
  364. end;
  365. { update the asmsymbol index }
  366. p^.idx:=syms^.count;
  367. { store the symbol, but not the local ones (PM) }
  368. if (p^.typ<>AS_LOCAL) or ((copy(s,1,2)<>'.L') and
  369. ((copy(s,1,1)<>'L') or not win32)) then
  370. syms^.write(sym,1);
  371. { make the exported syms known to the objectwriter
  372. (needed for .a generation) }
  373. if (p^.typ=AS_GLOBAL) or
  374. ((p^.typ=AS_EXTERNAL) and (sym.value=p^.size) and (sym.value>0)) then
  375. writer^.writesym(p^.name);
  376. end;
  377. procedure telfoutputput.writebytes(var data;len:longint);
  378. begin
  379. if not assigned(sects[currsec]) then
  380. createsection(currsec);
  381. sects[currsec]^.write(data,len);
  382. end;
  383. procedure telfoutputput.writealloc(len:longint);
  384. begin
  385. if not assigned(sects[currsec]) then
  386. createsection(currsec);
  387. sects[currsec]^.alloc(len);
  388. end;
  389. procedure telfoutputput.writereloc(data,len:longint;p:pasmsymbol;relative:relative_type);
  390. begin
  391. if not assigned(sects[currsec]) then
  392. createsection(currsec);
  393. if assigned(p) then
  394. begin
  395. { no symbol relocation need inside a section }
  396. if p^.section=currsec then
  397. begin
  398. if relative=relative_false then
  399. begin
  400. sects[currsec]^.addsectionreloc(sects[currsec]^.len,currsec);
  401. inc(data,p^.address);
  402. end
  403. else if relative=relative_true then
  404. begin
  405. inc(data,p^.address-len-sects[currsec]^.len);
  406. end
  407. else if relative=relative_rva then
  408. begin
  409. { don't know if this can happens !! }
  410. { does this work ?? }
  411. sects[currsec]^.addsectionreloc(sects[currsec]^.len,currsec);
  412. inc(data,p^.address);
  413. end;
  414. end
  415. else
  416. begin
  417. writesymbol(p);
  418. if (p^.section<>sec_none) and (relative=relative_false) then
  419. begin
  420. sects[currsec]^.addsectionreloc(sects[currsec]^.len,p^.section);
  421. end
  422. else
  423. sects[currsec]^.addsymreloc(sects[currsec]^.len,p,relative);
  424. if not win32 then {seems wrong to me (PM) }
  425. begin
  426. {if p^.section<>sec_none then
  427. this is the cause of the strange
  428. feature see Note (5) before
  429. address contains the size for
  430. global vars switched to common }
  431. inc(data,p^.address);
  432. end
  433. else
  434. if (relative<>relative_true) and (p^.section<>sec_none) then
  435. inc(data,p^.address);
  436. if relative=relative_true then
  437. begin
  438. if win32 then
  439. {inc(data,4-len)}
  440. dec(data,len-4{+p^.address})
  441. else
  442. dec(data,len+sects[currsec]^.len);
  443. end;
  444. end;
  445. end;
  446. sects[currsec]^.write(data,len);
  447. end;
  448. procedure telfoutputput.writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc : boolean);
  449. var
  450. stab : coffstab;
  451. s : tsection;
  452. begin
  453. if section=sec_none then
  454. s:=currsec
  455. else
  456. s:=section;
  457. { local var can be at offset -1 !! PM }
  458. if (offset=-1) and reloc then
  459. begin
  460. if s=sec_none then
  461. offset:=0
  462. else
  463. offset:=sects[s]^.len;
  464. end;
  465. fillchar(stab,sizeof(coffstab),0);
  466. if assigned(p) and (p[0]<>#0) then
  467. begin
  468. stab.strpos:=sects[sec_stabstr]^.len;
  469. sects[sec_stabstr]^.write(p^,strlen(p)+1);
  470. end;
  471. stab.ntype:=nidx;
  472. stab.ndesc:=line;
  473. stab.nother:=nother;
  474. stab.nvalue:=offset;
  475. sects[sec_stab]^.write(stab,sizeof(stab));
  476. { when the offset is not 0 then write a relocation, take also the
  477. hdrstab into account with the offset }
  478. if reloc then
  479. sects[sec_stab]^.addsectionreloc(sects[sec_stab]^.len-4,s);
  480. end;
  481. procedure telfoutputput.write_relocs(s:pcoffsection);
  482. var
  483. rel : coffreloc;
  484. hr,r : preloc;
  485. begin
  486. r:=s^.relochead;
  487. while assigned(r) do
  488. begin
  489. rel.address:=r^.address;
  490. if assigned(r^.symbol) then
  491. begin
  492. if (r^.symbol^.typ=AS_LOCAL) then
  493. rel.sym:=2*ord(r^.symbol^.section)
  494. else
  495. rel.sym:=r^.symbol^.idx+initsym;
  496. end
  497. else
  498. rel.sym:=2*ord(r^.section);
  499. case r^.relative of
  500. relative_true : rel.relative:=$14;
  501. relative_false : rel.relative:=$6;
  502. relative_rva : rel.relative:=$7;
  503. end;
  504. writer^.write(rel,sizeof(rel));
  505. { goto next and dispose this reloc }
  506. hr:=r;
  507. r:=r^.next;
  508. dispose(hr);
  509. end;
  510. end;
  511. procedure telfoutputput.write_symbol(const name:string;strpos,value,section,typ,aux:longint);
  512. var
  513. sym : coffsymbol;
  514. begin
  515. FillChar(sym,sizeof(sym),0);
  516. if strpos=-1 then
  517. move(name[1],sym.name,length(name))
  518. else
  519. sym.strpos:=strpos;
  520. sym.value:=value;
  521. sym.section:=section;
  522. sym.typ:=typ;
  523. sym.aux:=aux;
  524. writer^.write(sym,sizeof(sym));
  525. end;
  526. procedure telfoutputput.write_symbols;
  527. var
  528. filename : string[18];
  529. sec : tsection;
  530. i : longint;
  531. globalval : byte;
  532. secrec : coffsectionrec;
  533. sym : tsymbol;
  534. begin
  535. { The `.file' record, and the file name auxiliary record. }
  536. write_symbol ('.file', -1, 0, -2, $67, 1);
  537. fillchar(filename,sizeof(filename),0);
  538. filename:=SplitFileName(current_module^.mainsource^);
  539. writer^.write(filename[1],sizeof(filename)-1);
  540. { The section records, with their auxiliaries }
  541. i:=0;
  542. for sec:=low(tsection) to high(tsection) do
  543. if assigned(sects[sec]) then
  544. begin
  545. inc(i);
  546. write_symbol(sec_2_str[sec],-1,{sects[sec]^.pos}0,i,3,1);
  547. fillchar(secrec,sizeof(secrec),0);
  548. secrec.len:=sects[sec]^.len;
  549. secrec.nrelocs:=sects[sec]^.nrelocs;
  550. writer^.write(secrec,sizeof(secrec));
  551. end;
  552. { The real symbols. }
  553. syms^.seek(0);
  554. for i:=1 to syms^.count do
  555. begin
  556. syms^.read(sym,1);
  557. if sym.typ=AS_LOCAL then
  558. globalval:=3
  559. else
  560. globalval:=2;
  561. write_symbol(sym.name,sym.strpos,sym.value,sym.section,globalval,0);
  562. end;
  563. end;
  564. procedure telfoutputput.writetodisk;
  565. var
  566. datapos,
  567. nsects,pos,sympos,i,fillsize : longint;
  568. sec : tsection;
  569. header : coffheader;
  570. sechdr : coffsechdr;
  571. empty : array[0..15] of byte;
  572. begin
  573. { calc amount of sections we have and align sections at 4 bytes }
  574. fillchar(empty,sizeof(empty),0);
  575. nsects:=0;
  576. for sec:=low(tsection) to high(tsection) do
  577. { .stabstr section length must be without alignment !! }
  578. if assigned(sects[sec]) then
  579. begin
  580. { fill with zero }
  581. fillsize:=4-(sects[sec]^.len and 3);
  582. if fillsize<>4 then
  583. begin
  584. if assigned(sects[sec]^.data) then
  585. sects[sec]^.write(empty,fillsize)
  586. else
  587. sects[sec]^.alloc(fillsize);
  588. { .stabstr section length must be without alignment !! }
  589. if (sec=sec_stabstr) then
  590. dec(sects[sec]^.len,fillsize);
  591. end;
  592. inc(nsects);
  593. end;
  594. { Calculate the filepositions }
  595. datapos:=sizeof(coffheader)+sizeof(coffsechdr)*nsects;
  596. pos:=0;
  597. initsym:=2; { 2 for the file }
  598. { sections first }
  599. for sec:=low(tsection) to high(tsection) do
  600. if assigned(sects[sec]) then
  601. begin
  602. sects[sec]^.pos:=pos;
  603. sects[sec]^.datapos:=datapos;
  604. inc(pos,sects[sec]^.len);
  605. if assigned(sects[sec]^.data) then
  606. inc(datapos,sects[sec]^.len);
  607. { align after stabstr section !! }
  608. if (sec=sec_stabstr) and ((sects[sec]^.len and 3)<>0) then
  609. inc(datapos,4-(sects[sec]^.len and 3));
  610. inc(initsym,2); { 2 for each section }
  611. end;
  612. { relocs }
  613. for sec:=low(tsection) to high(tsection) do
  614. if assigned(sects[sec]) then
  615. begin
  616. sects[sec]^.relocpos:=datapos;
  617. inc(datapos,10*sects[sec]^.nrelocs);
  618. end;
  619. { symbols }
  620. sympos:=datapos;
  621. { COFF header }
  622. fillchar(header,sizeof(coffheader),0);
  623. header.mach:=$14c;
  624. header.nsects:=nsects;
  625. header.sympos:=sympos;
  626. header.syms:=syms^.count+initsym;
  627. if not win32 then
  628. header.flag:=$104;
  629. writer^.write(header,sizeof(header));
  630. { Section headers }
  631. for sec:=low(tsection) to high(tsection) do
  632. if assigned(sects[sec]) then
  633. begin
  634. fillchar(sechdr,sizeof(sechdr),0);
  635. move(sec_2_str[sec][1],sechdr.name,length(sec_2_str[sec]));
  636. if not win32 then
  637. sechdr.vsize:=sects[sec]^.pos
  638. else if sec=sec_bss then
  639. sechdr.vsize:=sects[sec]^.len;
  640. sechdr.datalen:=sects[sec]^.len;
  641. { apparently win32 asw leaves section at datapos zero }
  642. { this was an error by me (PM) }
  643. if (sects[sec]^.len>0) and assigned(sects[sec]^.data) then
  644. sechdr.datapos:=sects[sec]^.datapos;
  645. sechdr.relocpos:=sects[sec]^.relocpos;
  646. sechdr.nrelocs:=sects[sec]^.nrelocs;
  647. sechdr.flags:=sects[sec]^.flags;
  648. writer^.write(sechdr,sizeof(sechdr));
  649. end;
  650. { Sections }
  651. for sec:=low(tsection) to high(tsection) do
  652. if assigned(sects[sec]) and
  653. assigned(sects[sec]^.data) then
  654. begin
  655. { For the stab section we need an HdrSym which can now be
  656. calculated more easily }
  657. if sec=sec_stab then
  658. begin
  659. pcoffstab(sects[sec_stab]^.data^.data)^.nvalue:=sects[sec_stabstr]^.len;
  660. pcoffstab(sects[sec_stab]^.data^.data)^.strpos:=1;
  661. pcoffstab(sects[sec_stab]^.data^.data)^.ndesc:=
  662. (sects[sec_stab]^.len div sizeof(coffstab))-1{+1 according to gas output PM};
  663. end;
  664. writer^.write(sects[sec]^.data^.data^,sects[sec]^.data^.usedsize);
  665. end;
  666. { Relocs }
  667. for sec:=low(tsection) to high(tsection) do
  668. if assigned(sects[sec]) then
  669. write_relocs(sects[sec]);
  670. { Symbols }
  671. write_symbols;
  672. { Strings }
  673. i:=strs^.usedsize+4;
  674. writer^.write(i,4);
  675. writer^.write(strs^.data^,strs^.usedsize);
  676. end;
  677. {****************************************************************************
  678. DJGppcoffoutput
  679. ****************************************************************************}
  680. constructor tdjgppcoffoutput.init;
  681. begin
  682. inherited init;
  683. win32:=false;
  684. end;
  685. function tdjgppcoffoutput.text_flags : longint;
  686. begin
  687. text_flags:=$20;
  688. end;
  689. function tdjgppcoffoutput.data_flags : longint;
  690. begin
  691. data_flags:=$40;
  692. end;
  693. function tdjgppcoffoutput.bss_flags : longint;
  694. begin
  695. bss_flags:=$80;
  696. end;
  697. function tdjgppcoffoutput.info_flags : longint;
  698. begin
  699. writeln('djgpp coff doesn''t support info sections');
  700. info_flags:=$40;
  701. end;
  702. {****************************************************************************
  703. Win32coffoutput
  704. ****************************************************************************}
  705. constructor twin32coffoutput.init;
  706. begin
  707. inherited init;
  708. win32:=true;
  709. end;
  710. function twin32coffoutput.text_flags : longint;
  711. begin
  712. text_flags:={ $60500020}$60300020{changed to get same as asw.exe (PM)};
  713. end;
  714. function twin32coffoutput.data_flags : longint;
  715. begin
  716. data_flags:=$c0300040;
  717. end;
  718. function twin32coffoutput.bss_flags : longint;
  719. begin
  720. bss_flags:=$c0300080;
  721. end;
  722. function twin32coffoutput.info_flags : longint;
  723. begin
  724. info_flags:=$100a00;
  725. end;
  726. end.
  727. {
  728. $Log$
  729. Revision 1.2 2000-07-13 11:32:43 michael
  730. + removed logs
  731. }