MSCOFF.ob07 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. MODULE MSCOFF;
  2. IMPORT BIN, PE32, KOS, WR := WRITER, UTILS, ERRORS, LISTS, CHL := CHUNKLISTS;
  3. CONST
  4. SIZE_OF_DWORD = 4;
  5. (* SectionHeader.Characteristics *)
  6. SHC_flat = 040500020H;
  7. SHC_data = 0C0500040H;
  8. SHC_bss = 0C03000C0H;
  9. TYPE
  10. FH = PE32.IMAGE_FILE_HEADER;
  11. SH = PE32.IMAGE_SECTION_HEADER;
  12. PROCEDURE WriteReloc (VirtualAddress, SymbolTableIndex, Type: INTEGER);
  13. BEGIN
  14. WR.Write32LE(VirtualAddress);
  15. WR.Write32LE(SymbolTableIndex);
  16. WR.Write16LE(Type)
  17. END WriteReloc;
  18. PROCEDURE Reloc (program: BIN.PROGRAM);
  19. VAR
  20. reloc: BIN.RELOC;
  21. offset: INTEGER;
  22. BEGIN
  23. reloc := program.rel_list.first(BIN.RELOC);
  24. WHILE reloc # NIL DO
  25. offset := reloc.offset;
  26. CASE reloc.opcode OF
  27. |BIN.RIMP,
  28. BIN.IMPTAB: WriteReloc(offset, 4, 6)
  29. |BIN.RBSS: WriteReloc(offset, 5, 6)
  30. |BIN.RDATA: WriteReloc(offset, 2, 6)
  31. |BIN.RCODE: WriteReloc(offset, 1, 6)
  32. END;
  33. reloc := reloc.next(BIN.RELOC)
  34. END;
  35. END Reloc;
  36. PROCEDURE RelocCount (program: BIN.PROGRAM): INTEGER;
  37. VAR
  38. reloc: BIN.RELOC;
  39. iproc: BIN.IMPRT;
  40. res, L: INTEGER;
  41. offset: INTEGER;
  42. code: CHL.BYTELIST;
  43. BEGIN
  44. res := 0;
  45. code := program.code;
  46. reloc := program.rel_list.first(BIN.RELOC);
  47. WHILE reloc # NIL DO
  48. INC(res);
  49. offset := reloc.offset;
  50. IF reloc.opcode = BIN.RIMP THEN
  51. L := BIN.get32le(code, offset);
  52. iproc := BIN.GetIProc(program, L);
  53. BIN.put32le(code, offset, iproc.label)
  54. END;
  55. IF reloc.opcode = BIN.RCODE THEN
  56. L := BIN.get32le(code, offset);
  57. BIN.put32le(code, offset, BIN.GetLabel(program, L))
  58. END;
  59. reloc := reloc.next(BIN.RELOC)
  60. END
  61. RETURN res
  62. END RelocCount;
  63. PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR; ver: INTEGER);
  64. VAR
  65. exp: BIN.EXPRT;
  66. n, i: INTEGER;
  67. szversion: PE32.NAME;
  68. ImportTable: CHL.INTLIST;
  69. ILen, LibCount, isize: INTEGER;
  70. ExpCount: INTEGER;
  71. icount, ecount, dcount, ccount: INTEGER;
  72. FileHeader: FH;
  73. flat, data, edata, idata, bss: SH;
  74. PROCEDURE ICount (ImportTable: CHL.INTLIST; ILen: INTEGER): INTEGER;
  75. VAR
  76. i, res: INTEGER;
  77. BEGIN
  78. res := 0;
  79. FOR i := 0 TO ILen - 1 DO
  80. IF CHL.GetInt(ImportTable, i) # 0 THEN
  81. INC(res)
  82. END
  83. END
  84. RETURN res
  85. END ICount;
  86. PROCEDURE SetNumberOfRelocations (VAR section: SH; NumberOfRelocations: INTEGER);
  87. BEGIN
  88. IF NumberOfRelocations >= 65536 THEN
  89. ERRORS.Error(202)
  90. END;
  91. section.NumberOfRelocations := WCHR(NumberOfRelocations)
  92. END SetNumberOfRelocations;
  93. BEGIN
  94. szversion := "version";
  95. ASSERT(LENGTH(szversion) = 7);
  96. KOS.Import(program, 0, ImportTable, ILen, LibCount, isize);
  97. ExpCount := LISTS.count(program.exp_list);
  98. icount := CHL.Length(program._import);
  99. dcount := CHL.Length(program.data);
  100. ccount := CHL.Length(program.code);
  101. ecount := CHL.Length(program.export);
  102. FileHeader.Machine := 014CX;
  103. FileHeader.NumberOfSections := 5X;
  104. FileHeader.TimeDateStamp := UTILS.UnixTime();
  105. (* FileHeader.PointerToSymbolTable := 0; *)
  106. FileHeader.NumberOfSymbols := 6;
  107. FileHeader.SizeOfOptionalHeader := 0X;
  108. FileHeader.Characteristics := 0184X;
  109. flat.Name := ".flat";
  110. flat.VirtualSize := 0;
  111. flat.VirtualAddress := 0;
  112. flat.SizeOfRawData := ccount;
  113. flat.PointerToRawData := ORD(FileHeader.NumberOfSections) * PE32.SIZE_OF_IMAGE_SECTION_HEADER + PE32.SIZE_OF_IMAGE_FILE_HEADER;
  114. (* flat.PointerToRelocations := 0; *)
  115. flat.PointerToLinenumbers := 0;
  116. SetNumberOfRelocations(flat, RelocCount(program));
  117. flat.NumberOfLinenumbers := 0X;
  118. flat.Characteristics := SHC_flat;
  119. data.Name := ".data";
  120. data.VirtualSize := 0;
  121. data.VirtualAddress := 0;
  122. data.SizeOfRawData := dcount;
  123. data.PointerToRawData := flat.PointerToRawData + flat.SizeOfRawData;
  124. data.PointerToRelocations := 0;
  125. data.PointerToLinenumbers := 0;
  126. data.NumberOfRelocations := 0X;
  127. data.NumberOfLinenumbers := 0X;
  128. data.Characteristics := SHC_data;
  129. edata.Name := ".edata";
  130. edata.VirtualSize := 0;
  131. edata.VirtualAddress := 0;
  132. edata.SizeOfRawData := ((ExpCount + 1) * 2 + 1) * SIZE_OF_DWORD + LENGTH(szversion) + 1 + ecount;
  133. edata.PointerToRawData := data.PointerToRawData + data.SizeOfRawData;
  134. (* edata.PointerToRelocations := 0; *)
  135. edata.PointerToLinenumbers := 0;
  136. SetNumberOfRelocations(edata, ExpCount * 2 + 1);
  137. edata.NumberOfLinenumbers := 0X;
  138. edata.Characteristics := SHC_data;
  139. idata.Name := ".idata";
  140. idata.VirtualSize := 0;
  141. idata.VirtualAddress := 0;
  142. idata.SizeOfRawData := isize;
  143. idata.PointerToRawData := edata.PointerToRawData + edata.SizeOfRawData;
  144. (* idata.PointerToRelocations := 0; *)
  145. idata.PointerToLinenumbers := 0;
  146. SetNumberOfRelocations(idata, ICount(ImportTable, ILen));
  147. idata.NumberOfLinenumbers := 0X;
  148. idata.Characteristics := SHC_data;
  149. bss.Name := ".bss";
  150. bss.VirtualSize := 0;
  151. bss.VirtualAddress := 0;
  152. bss.SizeOfRawData := program.bss;
  153. bss.PointerToRawData := 0;
  154. bss.PointerToRelocations := 0;
  155. bss.PointerToLinenumbers := 0;
  156. bss.NumberOfRelocations := 0X;
  157. bss.NumberOfLinenumbers := 0X;
  158. bss.Characteristics := SHC_bss;
  159. flat.PointerToRelocations := idata.PointerToRawData + idata.SizeOfRawData;
  160. edata.PointerToRelocations := flat.PointerToRelocations + ORD(flat.NumberOfRelocations) * 10;
  161. idata.PointerToRelocations := edata.PointerToRelocations + ORD(edata.NumberOfRelocations) * 10;
  162. FileHeader.PointerToSymbolTable := idata.PointerToRelocations + ORD(idata.NumberOfRelocations) * 10;
  163. WR.Create(FileName);
  164. PE32.WriteFileHeader(FileHeader);
  165. PE32.WriteSectionHeader(flat);
  166. PE32.WriteSectionHeader(data);
  167. PE32.WriteSectionHeader(edata);
  168. PE32.WriteSectionHeader(idata);
  169. PE32.WriteSectionHeader(bss);
  170. CHL.WriteToFile(program.code);
  171. CHL.WriteToFile(program.data);
  172. exp := program.exp_list.first(BIN.EXPRT);
  173. WHILE exp # NIL DO
  174. WR.Write32LE(exp.nameoffs + edata.SizeOfRawData - ecount);
  175. WR.Write32LE(exp.label);
  176. exp := exp.next(BIN.EXPRT)
  177. END;
  178. WR.Write32LE(((ExpCount + 1) * 2 + 1) * SIZE_OF_DWORD);
  179. WR.Write32LE(ver);
  180. WR.Write32LE(0);
  181. PE32.WriteName(szversion);
  182. CHL.WriteToFile(program.export);
  183. FOR i := 0 TO ILen - 1 DO
  184. WR.Write32LE(CHL.GetInt(ImportTable, i))
  185. END;
  186. CHL.WriteToFile(program._import);
  187. Reloc(program);
  188. n := 0;
  189. exp := program.exp_list.first(BIN.EXPRT);
  190. WHILE exp # NIL DO
  191. WriteReloc(n, 3, 6);
  192. INC(n, 4);
  193. WriteReloc(n, 1, 6);
  194. INC(n, 4);
  195. exp := exp.next(BIN.EXPRT)
  196. END;
  197. WriteReloc(n, 3, 6);
  198. FOR i := 0 TO LibCount * 2 - 1 DO
  199. WriteReloc(i * SIZE_OF_DWORD, 4, 6)
  200. END;
  201. FOR i := LibCount * 2 TO ILen - 1 DO
  202. IF CHL.GetInt(ImportTable, i) # 0 THEN
  203. WriteReloc(i * SIZE_OF_DWORD, 4, 6)
  204. END
  205. END;
  206. PE32.WriteName("EXPORTS");
  207. WriteReloc(0, 3, 2);
  208. PE32.WriteName(".flat");
  209. WriteReloc(0, 1, 3);
  210. PE32.WriteName(".data");
  211. WriteReloc(0, 2, 3);
  212. PE32.WriteName(".edata");
  213. WriteReloc(0, 3, 3);
  214. PE32.WriteName(".idata");
  215. WriteReloc(0, 4, 3);
  216. PE32.WriteName(".bss");
  217. WriteReloc(0, 5, 3);
  218. WR.Write32LE(4);
  219. WR.Close
  220. END write;
  221. END MSCOFF.