og386elf.pas 22 KB

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