Rev 7597 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7597 | akron1 | 1 | (* |
2 | BSD 2-Clause License |
||
3 | |||
7693 | akron1 | 4 | Copyright (c) 2018, 2019, Anton Krotov |
7597 | akron1 | 5 | All rights reserved. |
6 | *) |
||
7 | |||
8 | MODULE MSCOFF; |
||
9 | |||
10 | IMPORT BIN, PE32, KOS, WR := WRITER, UTILS, ERRORS, LISTS, CHL := CHUNKLISTS; |
||
11 | |||
12 | |||
13 | CONST |
||
14 | |||
15 | SIZE_OF_DWORD = 4; |
||
16 | |||
17 | (* SectionHeader.Characteristics *) |
||
18 | |||
19 | SHC_flat = 040500020H; |
||
20 | SHC_data = 0C0500040H; |
||
21 | SHC_bss = 0C03000C0H; |
||
22 | |||
23 | |||
24 | TYPE |
||
25 | |||
26 | FH = PE32.IMAGE_FILE_HEADER; |
||
27 | |||
28 | SH = PE32.IMAGE_SECTION_HEADER; |
||
29 | |||
30 | |||
31 | PROCEDURE WriteReloc (File: WR.FILE; VirtualAddress, SymbolTableIndex, Type: INTEGER); |
||
32 | BEGIN |
||
33 | WR.Write32LE(File, VirtualAddress); |
||
34 | WR.Write32LE(File, SymbolTableIndex); |
||
35 | WR.Write16LE(File, Type) |
||
36 | END WriteReloc; |
||
37 | |||
38 | |||
39 | PROCEDURE Reloc (program: BIN.PROGRAM; File: WR.FILE); |
||
40 | VAR |
||
41 | reloc: BIN.RELOC; |
||
42 | |||
43 | BEGIN |
||
44 | reloc := program.rel_list.first(BIN.RELOC); |
||
45 | WHILE reloc # NIL DO |
||
46 | |||
47 | CASE reloc.opcode OF |
||
48 | |||
49 | |BIN.RIMP, BIN.IMPTAB: |
||
50 | WriteReloc(File, reloc.offset, 4, 6) |
||
51 | |||
52 | |BIN.RBSS: |
||
53 | WriteReloc(File, reloc.offset, 5, 6) |
||
54 | |||
55 | |BIN.RDATA: |
||
56 | WriteReloc(File, reloc.offset, 2, 6) |
||
57 | |||
58 | |BIN.RCODE: |
||
59 | WriteReloc(File, reloc.offset, 1, 6) |
||
60 | |||
61 | END; |
||
62 | |||
63 | reloc := reloc.next(BIN.RELOC) |
||
64 | END; |
||
65 | END Reloc; |
||
66 | |||
67 | |||
68 | PROCEDURE RelocCount (program: BIN.PROGRAM): INTEGER; |
||
69 | VAR |
||
70 | reloc: BIN.RELOC; |
||
71 | iproc: BIN.IMPRT; |
||
72 | res, L: INTEGER; |
||
73 | |||
74 | BEGIN |
||
75 | res := 0; |
||
76 | reloc := program.rel_list.first(BIN.RELOC); |
||
77 | WHILE reloc # NIL DO |
||
78 | |||
79 | INC(res); |
||
80 | |||
81 | IF reloc.opcode = BIN.RIMP THEN |
||
82 | L := BIN.get32le(program.code, reloc.offset); |
||
83 | iproc := BIN.GetIProc(program, L); |
||
84 | BIN.put32le(program.code, reloc.offset, iproc.label) |
||
85 | END; |
||
86 | |||
87 | IF reloc.opcode = BIN.RCODE THEN |
||
88 | L := BIN.get32le(program.code, reloc.offset); |
||
89 | BIN.put32le(program.code, reloc.offset, BIN.GetLabel(program, L)) |
||
90 | END; |
||
91 | |||
92 | reloc := reloc.next(BIN.RELOC) |
||
93 | END |
||
94 | |||
95 | RETURN res |
||
96 | END RelocCount; |
||
97 | |||
98 | |||
99 | PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR; ver: INTEGER); |
||
100 | VAR |
||
101 | File: WR.FILE; |
||
102 | exp: BIN.EXPRT; |
||
103 | n, i: INTEGER; |
||
104 | |||
105 | szversion: PE32.NAME; |
||
106 | |||
107 | ImportTable: CHL.INTLIST; |
||
108 | ILen, LibCount, isize: INTEGER; |
||
109 | |||
110 | ExpCount: INTEGER; |
||
111 | |||
112 | icount, ecount, dcount, ccount: INTEGER; |
||
113 | |||
114 | FileHeader: FH; |
||
115 | |||
116 | flat, data, edata, idata, bss: SH; |
||
117 | |||
118 | |||
119 | PROCEDURE ICount (ImportTable: CHL.INTLIST; ILen: INTEGER): INTEGER; |
||
120 | VAR |
||
121 | i, res: INTEGER; |
||
122 | |||
123 | BEGIN |
||
124 | res := 0; |
||
125 | |||
126 | FOR i := 0 TO ILen - 1 DO |
||
127 | IF CHL.GetInt(ImportTable, i) # 0 THEN |
||
128 | INC(res) |
||
129 | END |
||
130 | END |
||
131 | |||
132 | RETURN res |
||
133 | END ICount; |
||
134 | |||
135 | |||
136 | PROCEDURE SetNumberOfRelocations (VAR section: SH; NumberOfRelocations: INTEGER); |
||
137 | BEGIN |
||
138 | IF NumberOfRelocations >= 65536 THEN |
||
7693 | akron1 | 139 | ERRORS.Error(202) |
7597 | akron1 | 140 | END; |
141 | section.NumberOfRelocations := WCHR(NumberOfRelocations) |
||
142 | END SetNumberOfRelocations; |
||
143 | |||
144 | |||
145 | BEGIN |
||
146 | |||
147 | szversion := "version"; |
||
148 | |||
149 | ASSERT(LENGTH(szversion) = 7); |
||
150 | |||
151 | KOS.Import(program, 0, ImportTable, ILen, LibCount, isize); |
||
152 | ExpCount := LISTS.count(program.exp_list); |
||
153 | |||
154 | icount := CHL.Length(program.import); |
||
155 | dcount := CHL.Length(program.data); |
||
156 | ccount := CHL.Length(program.code); |
||
157 | ecount := CHL.Length(program.export); |
||
158 | |||
159 | FileHeader.Machine := 014CX; |
||
160 | FileHeader.NumberOfSections := 5X; |
||
161 | FileHeader.TimeDateStamp := UTILS.UnixTime(); |
||
162 | //FileHeader.PointerToSymbolTable := 0; |
||
163 | FileHeader.NumberOfSymbols := 6; |
||
164 | FileHeader.SizeOfOptionalHeader := 0X; |
||
165 | FileHeader.Characteristics := 0184X; |
||
166 | |||
167 | flat.Name := ".flat"; |
||
168 | flat.VirtualSize := 0; |
||
169 | flat.VirtualAddress := 0; |
||
170 | flat.SizeOfRawData := ccount; |
||
171 | flat.PointerToRawData := ORD(FileHeader.NumberOfSections) * PE32.SIZE_OF_IMAGE_SECTION_HEADER + PE32.SIZE_OF_IMAGE_FILE_HEADER; |
||
172 | //flat.PointerToRelocations := 0; |
||
173 | flat.PointerToLinenumbers := 0; |
||
174 | SetNumberOfRelocations(flat, RelocCount(program)); |
||
175 | flat.NumberOfLinenumbers := 0X; |
||
176 | flat.Characteristics := SHC_flat; |
||
177 | |||
178 | data.Name := ".data"; |
||
179 | data.VirtualSize := 0; |
||
180 | data.VirtualAddress := 0; |
||
181 | data.SizeOfRawData := dcount; |
||
182 | data.PointerToRawData := flat.PointerToRawData + flat.SizeOfRawData; |
||
183 | data.PointerToRelocations := 0; |
||
184 | data.PointerToLinenumbers := 0; |
||
185 | data.NumberOfRelocations := 0X; |
||
186 | data.NumberOfLinenumbers := 0X; |
||
187 | data.Characteristics := SHC_data; |
||
188 | |||
189 | edata.Name := ".edata"; |
||
190 | edata.VirtualSize := 0; |
||
191 | edata.VirtualAddress := 0; |
||
192 | edata.SizeOfRawData := ((ExpCount + 1) * 2 + 1) * SIZE_OF_DWORD + LENGTH(szversion) + 1 + ecount; |
||
193 | edata.PointerToRawData := data.PointerToRawData + data.SizeOfRawData; |
||
194 | //edata.PointerToRelocations := 0; |
||
195 | edata.PointerToLinenumbers := 0; |
||
196 | SetNumberOfRelocations(edata, ExpCount * 2 + 1); |
||
197 | edata.NumberOfLinenumbers := 0X; |
||
198 | edata.Characteristics := SHC_data; |
||
199 | |||
200 | idata.Name := ".idata"; |
||
201 | idata.VirtualSize := 0; |
||
202 | idata.VirtualAddress := 0; |
||
203 | idata.SizeOfRawData := isize; |
||
204 | idata.PointerToRawData := edata.PointerToRawData + edata.SizeOfRawData; |
||
205 | //idata.PointerToRelocations := 0; |
||
206 | idata.PointerToLinenumbers := 0; |
||
207 | SetNumberOfRelocations(idata, ICount(ImportTable, ILen)); |
||
208 | idata.NumberOfLinenumbers := 0X; |
||
209 | idata.Characteristics := SHC_data; |
||
210 | |||
211 | bss.Name := ".bss"; |
||
212 | bss.VirtualSize := 0; |
||
213 | bss.VirtualAddress := 0; |
||
214 | bss.SizeOfRawData := program.bss; |
||
215 | bss.PointerToRawData := 0; |
||
216 | bss.PointerToRelocations := 0; |
||
217 | bss.PointerToLinenumbers := 0; |
||
218 | bss.NumberOfRelocations := 0X; |
||
219 | bss.NumberOfLinenumbers := 0X; |
||
220 | bss.Characteristics := SHC_bss; |
||
221 | |||
222 | flat.PointerToRelocations := idata.PointerToRawData + idata.SizeOfRawData; |
||
223 | edata.PointerToRelocations := flat.PointerToRelocations + ORD(flat.NumberOfRelocations) * 10; |
||
224 | idata.PointerToRelocations := edata.PointerToRelocations + ORD(edata.NumberOfRelocations) * 10; |
||
225 | |||
226 | FileHeader.PointerToSymbolTable := idata.PointerToRelocations + ORD(idata.NumberOfRelocations) * 10; |
||
227 | |||
228 | File := WR.Create(FileName); |
||
229 | |||
230 | PE32.WriteFileHeader(File, FileHeader); |
||
231 | |||
232 | PE32.WriteSectionHeader(File, flat); |
||
233 | PE32.WriteSectionHeader(File, data); |
||
234 | PE32.WriteSectionHeader(File, edata); |
||
235 | PE32.WriteSectionHeader(File, idata); |
||
236 | PE32.WriteSectionHeader(File, bss); |
||
237 | |||
238 | CHL.WriteToFile(File, program.code); |
||
239 | CHL.WriteToFile(File, program.data); |
||
240 | |||
241 | exp := program.exp_list.first(BIN.EXPRT); |
||
242 | WHILE exp # NIL DO |
||
243 | WR.Write32LE(File, exp.nameoffs + edata.SizeOfRawData - ecount); |
||
244 | WR.Write32LE(File, exp.label); |
||
245 | exp := exp.next(BIN.EXPRT) |
||
246 | END; |
||
247 | |||
248 | WR.Write32LE(File, ((ExpCount + 1) * 2 + 1) * SIZE_OF_DWORD); |
||
249 | WR.Write32LE(File, ver); |
||
250 | |||
251 | WR.Write32LE(File, 0); |
||
252 | |||
253 | PE32.WriteName(File, szversion); |
||
254 | CHL.WriteToFile(File, program.export); |
||
255 | |||
256 | FOR i := 0 TO ILen - 1 DO |
||
257 | WR.Write32LE(File, CHL.GetInt(ImportTable, i)) |
||
258 | END; |
||
259 | |||
260 | CHL.WriteToFile(File, program.import); |
||
261 | |||
262 | Reloc(program, File); |
||
263 | |||
264 | n := 0; |
||
265 | exp := program.exp_list.first(BIN.EXPRT); |
||
266 | WHILE exp # NIL DO |
||
267 | WriteReloc(File, n, 3, 6); |
||
268 | INC(n, 4); |
||
269 | |||
270 | WriteReloc(File, n, 1, 6); |
||
271 | INC(n, 4); |
||
272 | |||
273 | exp := exp.next(BIN.EXPRT) |
||
274 | END; |
||
275 | |||
276 | WriteReloc(File, n, 3, 6); |
||
277 | |||
278 | i := 0; |
||
279 | WHILE i < LibCount * 2 DO |
||
280 | WriteReloc(File, i * SIZE_OF_DWORD, 4, 6); |
||
281 | INC(i); |
||
282 | WriteReloc(File, i * SIZE_OF_DWORD, 4, 6); |
||
283 | INC(i) |
||
284 | END; |
||
285 | |||
286 | FOR i := LibCount * 2 TO ILen - 1 DO |
||
287 | IF CHL.GetInt(ImportTable, i) # 0 THEN |
||
288 | WriteReloc(File, i * SIZE_OF_DWORD, 4, 6) |
||
289 | END |
||
290 | END; |
||
291 | |||
292 | PE32.WriteName(File, "EXPORTS"); |
||
293 | WriteReloc(File, 0, 3, 2); |
||
294 | |||
295 | PE32.WriteName(File, ".flat"); |
||
296 | WriteReloc(File, 0, 1, 3); |
||
297 | |||
298 | PE32.WriteName(File, ".data"); |
||
299 | WriteReloc(File, 0, 2, 3); |
||
300 | |||
301 | PE32.WriteName(File, ".edata"); |
||
302 | WriteReloc(File, 0, 3, 3); |
||
303 | |||
304 | PE32.WriteName(File, ".idata"); |
||
305 | WriteReloc(File, 0, 4, 3); |
||
306 | |||
307 | PE32.WriteName(File, ".bss"); |
||
308 | WriteReloc(File, 0, 5, 3); |
||
309 | |||
310 | WR.Write32LE(File, 4); |
||
311 | |||
312 | WR.Close(File) |
||
313 | END write; |
||
314 | |||
315 | |||
316 | END MSCOFF.> |