Subversion Repositories Kolibri OS

Rev

Rev 7983 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7983 Rev 8097
Line 1... Line 1...
1
(*
1
(*
2
    BSD 2-Clause License
2
    BSD 2-Clause License
Line 3... Line 3...
3
 
3
 
4
    Copyright (c) 2018-2019, Anton Krotov
4
    Copyright (c) 2018-2020, Anton Krotov
5
    All rights reserved.
5
    All rights reserved.
Line 6... Line 6...
6
*)
6
*)
Line 100... Line 100...
100
        Characteristics*:       WORD
100
        Characteristics*:       WORD
Line 101... Line 101...
101
 
101
 
Line 102... Line -...
102
    END;
-
 
103
 
-
 
104
 
-
 
105
    IMAGE_NT_HEADERS = RECORD
-
 
106
 
-
 
107
        Signature:       ARRAY 4 OF BYTE;
-
 
108
        FileHeader:      IMAGE_FILE_HEADER;
-
 
109
        OptionalHeader:  IMAGE_OPTIONAL_HEADER
-
 
110
 
-
 
111
    END;
102
    END;
Line 112... Line 103...
112
 
103
 
Line 113... Line 104...
113
 
104
 
Line 145... Line 136...
145
        AddressOfNameOrdinals: DWORD
136
        AddressOfNameOrdinals: DWORD
Line 146... Line 137...
146
 
137
 
Line 147... Line 138...
147
    END;
138
    END;
Line 148... Line 139...
148
 
139
 
Line 149... Line 140...
149
 
140
 
Line 150... Line -...
150
    VIRTUAL_ADDR = RECORD
-
 
151
 
-
 
152
        Code, Data, Bss, Import: INTEGER
-
 
153
 
141
    VIRTUAL_ADDR* = RECORD
Line -... Line 142...
-
 
142
 
-
 
143
        Code*, Data*, Bss*, Import*: INTEGER
-
 
144
 
-
 
145
    END;
154
    END;
146
 
155
 
-
 
156
 
147
 
157
    FILE = WR.FILE;
-
 
158
 
-
 
159
 
148
VAR
160
VAR
149
 
Line 161... Line 150...
161
 
150
    Signature:       ARRAY 4 OF BYTE;
162
    msdos:           ARRAY 128 OF BYTE;
151
    FileHeader:      IMAGE_FILE_HEADER;
Line 163... Line 152...
163
    PEHeader:        IMAGE_NT_HEADERS;
152
    OptionalHeader:  IMAGE_OPTIONAL_HEADER;
164
    SectionHeaders:  ARRAY 16 OF IMAGE_SECTION_HEADER;
153
 
165
    Relocations:     LISTS.LIST;
154
    msdos:           ARRAY 128 OF BYTE;
166
    bit64:           BOOLEAN;
155
    SectionHeaders:  ARRAY 16 OF IMAGE_SECTION_HEADER;
167
    libcnt:          INTEGER;
156
    libcnt:          INTEGER;
168
    SizeOfWord:      INTEGER;
157
    SizeOfWord:      INTEGER;
169
 
158
 
170
 
159
 
171
PROCEDURE Export (program: BIN.PROGRAM; DataRVA: INTEGER; VAR ExportDir: IMAGE_EXPORT_DIRECTORY): INTEGER;
160
PROCEDURE Export (program: BIN.PROGRAM; name: INTEGER; VAR ExportDir: IMAGE_EXPORT_DIRECTORY): INTEGER;
172
BEGIN
161
BEGIN
Line 185... Line 174...
185
 
174
 
186
    RETURN SIZE_OF_IMAGE_EXPORT_DIRECTORY + ExportDir.NumberOfFunctions * (2 * SIZE_OF_DWORD + SIZE_OF_WORD)
175
    RETURN SIZE_OF_IMAGE_EXPORT_DIRECTORY + ExportDir.NumberOfFunctions * (2 * SIZE_OF_DWORD + SIZE_OF_WORD)
Line 187... Line -...
187
END Export;
-
 
188
 
-
 
189
 
-
 
190
PROCEDURE align (n, _align: INTEGER): INTEGER;
-
 
191
BEGIN
-
 
192
    IF n MOD _align # 0 THEN
-
 
193
        n := n + _align - (n MOD _align)
-
 
194
    END
-
 
195
 
-
 
196
    RETURN n
-
 
197
END align;
176
END Export;
198
 
177
 
199
 
178
 
200
PROCEDURE GetProcCount (lib: BIN.IMPRT): INTEGER;
179
PROCEDURE GetProcCount (lib: BIN.IMPRT): INTEGER;
Line 201... Line 180...
201
VAR
180
VAR
202
    import: BIN.IMPRT;
181
    imp: BIN.IMPRT;
203
    res:    INTEGER;
182
    res: INTEGER;
204
 
183
 
205
BEGIN
184
BEGIN
206
    res := 0;
185
    res := 0;
207
    import := lib.next(BIN.IMPRT);
186
    imp := lib.next(BIN.IMPRT);
Line 208... Line 187...
208
    WHILE (import # NIL) & (import.label # 0) DO
187
    WHILE (imp # NIL) & (imp.label # 0) DO
209
        INC(res);
188
        INC(res);
Line 210... Line 189...
210
        import := import.next(BIN.IMPRT)
189
        imp := imp.next(BIN.IMPRT)
211
    END
190
    END
212
 
191
 
213
    RETURN res
192
    RETURN res
214
END GetProcCount;
193
END GetProcCount;
215
 
194
 
216
 
195
 
Line 217... Line 196...
217
PROCEDURE GetImportSize (imp_list: LISTS.LIST): INTEGER;
196
PROCEDURE GetImportSize (imp_list: LISTS.LIST): INTEGER;
218
VAR
197
VAR
219
    import: BIN.IMPRT;
198
    imp: BIN.IMPRT;
220
    proccnt: INTEGER;
199
    proccnt: INTEGER;
221
    procoffs: INTEGER;
200
    procoffs: INTEGER;
222
    OriginalCurrentThunk,
201
    OriginalCurrentThunk,
223
    CurrentThunk: INTEGER;
202
    CurrentThunk: INTEGER;
224
 
203
 
225
BEGIN
204
BEGIN
226
    libcnt  := 0;
205
    libcnt  := 0;
227
    proccnt := 0;
206
    proccnt := 0;
228
    import  := imp_list.first(BIN.IMPRT);
207
    imp  := imp_list.first(BIN.IMPRT);
Line 229... Line 208...
229
    WHILE import # NIL DO
208
    WHILE imp # NIL DO
Line 230... Line 209...
230
        IF import.label = 0 THEN
209
        IF imp.label = 0 THEN
231
            INC(libcnt)
210
            INC(libcnt)
232
        ELSE
211
        ELSE
233
            INC(proccnt)
212
            INC(proccnt)
234
        END;
213
        END;
235
        import := import.next(BIN.IMPRT)
214
        imp := imp.next(BIN.IMPRT)
236
    END;
215
    END;
237
 
216
 
238
    procoffs := 0;
217
    procoffs := 0;
239
 
218
 
240
    import  := imp_list.first(BIN.IMPRT);
219
    imp  := imp_list.first(BIN.IMPRT);
241
    WHILE import # NIL DO
220
    WHILE imp # NIL DO
242
        IF import.label = 0 THEN
221
        IF imp.label = 0 THEN
243
            import.OriginalFirstThunk := procoffs;
222
            imp.OriginalFirstThunk := procoffs;
244
            import.FirstThunk := procoffs + (GetProcCount(import) + 1);
223
            imp.FirstThunk := procoffs + (GetProcCount(imp) + 1);
245
            OriginalCurrentThunk := import.OriginalFirstThunk;
224
            OriginalCurrentThunk := imp.OriginalFirstThunk;
Line 246... Line 225...
246
            CurrentThunk := import.FirstThunk;
225
            CurrentThunk := imp.FirstThunk;
247
            procoffs := procoffs + (GetProcCount(import) + 1) * 2
226
            INC(procoffs, (GetProcCount(imp) + 1) * 2)
Line 248... Line 227...
248
        ELSE
227
        ELSE
249
            import.OriginalFirstThunk := OriginalCurrentThunk;
228
            imp.OriginalFirstThunk := OriginalCurrentThunk;
250
            import.FirstThunk := CurrentThunk;
229
            imp.FirstThunk := CurrentThunk;
251
            INC(OriginalCurrentThunk);
230
            INC(OriginalCurrentThunk);
252
            INC(CurrentThunk)
231
            INC(CurrentThunk)
253
        END;
232
        END;
Line 254... Line 233...
254
        import := import.next(BIN.IMPRT)
233
        imp := imp.next(BIN.IMPRT)
255
    END
234
    END
256
 
235
 
257
    RETURN (libcnt + 1) * 5 * SIZE_OF_DWORD + (proccnt + libcnt) * 2 * SizeOfWord
236
    RETURN (libcnt + 1) * 5 * SIZE_OF_DWORD + (proccnt + libcnt) * 2 * SizeOfWord
258
END GetImportSize;
237
END GetImportSize;
Line 259... Line 238...
259
 
238
 
Line -... Line 239...
-
 
239
 
260
 
240
PROCEDURE fixup* (program: BIN.PROGRAM; Address: VIRTUAL_ADDR; amd64: BOOLEAN);
261
PROCEDURE fixup (program: BIN.PROGRAM; Address: VIRTUAL_ADDR);
241
VAR
Line 262... Line 242...
262
VAR
242
    reloc: BIN.RELOC;
263
    reloc: BIN.RELOC;
-
 
264
    iproc: BIN.IMPRT;
243
    iproc: BIN.IMPRT;
265
    code:  CHL.BYTELIST;
244
    code:  CHL.BYTELIST;
Line 266... Line 245...
266
    L, delta, delta0, AdrImp: INTEGER;
245
    L, delta, delta0, AdrImp, offset: INTEGER;
267
 
246
 
Line 268... Line 247...
268
BEGIN
247
BEGIN
269
    AdrImp := Address.Import + (libcnt + 1) * 5 * SIZE_OF_DWORD;
248
    AdrImp := Address.Import + (libcnt + 1) * 5 * SIZE_OF_DWORD;
Line 270... Line 249...
270
    code := program.code;
249
    code := program.code;
271
    reloc := program.rel_list.first(BIN.RELOC);
250
    reloc := program.rel_list.first(BIN.RELOC);
272
    delta0 := 3 - 7 * ORD(bit64);
251
    delta0 := 3 - 7 * ORD(amd64) - Address.Code;
273
 
-
 
274
    WHILE reloc # NIL DO
252
 
-
 
253
    WHILE reloc # NIL DO
Line 275... Line 254...
275
 
254
 
276
        L := BIN.get32le(code, reloc.offset);
255
        offset := reloc.offset;
277
        delta := delta0 - reloc.offset - Address.Code;
256
        L := BIN.get32le(code, offset);
Line 278... Line 257...
278
 
257
        delta := delta0 - offset;
279
        CASE reloc.opcode OF
258
 
280
 
259
        CASE reloc.opcode OF
281
        |BIN.PICDATA:
260
        |BIN.PICDATA:
Line 282... Line 261...
282
              BIN.put32le(code, reloc.offset, L + Address.Data + delta)
261
            INC(delta, L + Address.Data)
283
 
262
 
284
        |BIN.PICCODE:
263
        |BIN.PICCODE:
Line 285... Line 264...
285
              BIN.put32le(code, reloc.offset, BIN.GetLabel(program, L) + Address.Code + delta)
264
            INC(delta, BIN.GetLabel(program, L) + Address.Code)
286
 
265
 
Line 287... Line 266...
287
        |BIN.PICBSS:
266
        |BIN.PICBSS:
288
              BIN.put32le(code, reloc.offset, L + Address.Bss + delta)
267
            INC(delta, L + Address.Bss)
289
 
268
 
Line 290... Line 269...
290
        |BIN.PICIMP:
269
        |BIN.PICIMP:
291
              iproc := BIN.GetIProc(program, L);
270
            iproc := BIN.GetIProc(program, L);
292
              BIN.put32le(code, reloc.offset, iproc.FirstThunk * SizeOfWord + AdrImp + delta)
271
            INC(delta, iproc.FirstThunk * SizeOfWord + AdrImp)
293
 
272
        END;
294
        END;
273
        BIN.put32le(code, offset, delta);
Line 295... Line 274...
295
 
274
 
Line 296... Line 275...
296
        reloc := reloc.next(BIN.RELOC)
275
        reloc := reloc.next(BIN.RELOC)
297
    END
276
    END
298
END fixup;
277
END fixup;
Line 299... Line 278...
299
 
278
 
300
 
279
 
Line 301... Line 280...
301
PROCEDURE WriteWord (file: FILE; w: WORD);
280
PROCEDURE WriteWord (w: WORD);
302
BEGIN
281
BEGIN
303
    WR.Write16LE(file, ORD(w))
282
    WR.Write16LE(ORD(w))
Line 304... Line 283...
304
END WriteWord;
283
END WriteWord;
305
 
284
 
306
 
285
 
307
PROCEDURE WriteName* (File: FILE; name: NAME);
286
PROCEDURE WriteName* (name: NAME);
308
VAR
287
VAR
Line 309... Line 288...
309
    i, nameLen: INTEGER;
288
    i, nameLen: INTEGER;
310
 
289
 
311
BEGIN
290
BEGIN
312
    nameLen := LENGTH(name);
291
    nameLen := LENGTH(name);
313
 
292
 
314
    FOR i := 0 TO nameLen - 1 DO
293
    FOR i := 0 TO nameLen - 1 DO
Line 315... Line 294...
315
        WR.WriteByte(File, ORD(name[i]))
294
        WR.WriteByte(ORD(name[i]))
316
    END;
295
    END;
Line 317... Line 296...
317
 
296
 
318
    i := LEN(name) - nameLen;
297
    i := LEN(name) - nameLen;
Line 319... Line 298...
319
    WHILE i > 0 DO
298
    WHILE i > 0 DO
320
        WR.WriteByte(File, 0);
299
        WR.WriteByte(0);
321
        DEC(i)
300
        DEC(i)
322
    END
301
    END
Line 323... Line 302...
323
 
302
 
324
END WriteName;
303
END WriteName;
325
 
304
 
Line 326... Line 305...
326
 
305
 
327
PROCEDURE WriteSectionHeader* (file: FILE; h: IMAGE_SECTION_HEADER);
306
PROCEDURE WriteSectionHeader* (h: IMAGE_SECTION_HEADER);
328
VAR
307
VAR
Line 329... Line 308...
329
    i, nameLen: INTEGER;
308
    i, nameLen: INTEGER;
330
 
309
 
331
BEGIN
310
BEGIN
Line 332... Line 311...
332
    nameLen := LENGTH(h.Name);
311
    nameLen := LENGTH(h.Name);
Line 333... Line 312...
333
 
312
 
Line 334... Line 313...
334
    FOR i := 0 TO nameLen - 1 DO
313
    FOR i := 0 TO nameLen - 1 DO
Line 335... Line 314...
335
        WR.WriteByte(file, ORD(h.Name[i]))
314
        WR.WriteByte(ORD(h.Name[i]))
Line 336... Line 315...
336
    END;
315
    END;
Line 337... Line -...
337
 
-
 
338
    i := LEN(h.Name) - nameLen;
-
 
339
    WHILE i > 0 DO
316
 
340
        WR.WriteByte(file, 0);
317
    i := LEN(h.Name) - nameLen;
Line 341... Line 318...
341
        DEC(i)
318
    WHILE i > 0 DO
342
    END;
319
        WR.WriteByte(0);
Line 343... Line 320...
343
 
320
        DEC(i)
344
    WR.Write32LE(file, h.VirtualSize);
321
    END;
345
    WR.Write32LE(file, h.VirtualAddress);
322
 
346
    WR.Write32LE(file, h.SizeOfRawData);
323
    WR.Write32LE(h.VirtualSize);
Line 347... Line 324...
347
    WR.Write32LE(file, h.PointerToRawData);
324
    WR.Write32LE(h.VirtualAddress);
348
    WR.Write32LE(file, h.PointerToRelocations);
325
    WR.Write32LE(h.SizeOfRawData);
Line 349... Line 326...
349
    WR.Write32LE(file, h.PointerToLinenumbers);
326
    WR.Write32LE(h.PointerToRawData);
350
 
327
    WR.Write32LE(h.PointerToRelocations);
351
    WriteWord(file, h.NumberOfRelocations);
328
    WR.Write32LE(h.PointerToLinenumbers);
352
    WriteWord(file, h.NumberOfLinenumbers);
329
 
353
 
330
    WriteWord(h.NumberOfRelocations);
354
    WR.Write32LE(file, h.Characteristics)
331
    WriteWord(h.NumberOfLinenumbers);
355
END WriteSectionHeader;
332
 
356
 
333
    WR.Write32LE(h.Characteristics)
Line 357... Line 334...
357
 
334
END WriteSectionHeader;
358
PROCEDURE WriteFileHeader* (file: FILE; h: IMAGE_FILE_HEADER);
335
 
359
BEGIN
336
 
Line 360... Line 337...
360
    WriteWord(file, h.Machine);
337
PROCEDURE WriteFileHeader* (h: IMAGE_FILE_HEADER);
361
    WriteWord(file, h.NumberOfSections);
338
BEGIN
Line 362... Line 339...
362
 
339
    WriteWord(h.Machine);
363
    WR.Write32LE(file, h.TimeDateStamp);
340
    WriteWord(h.NumberOfSections);
Line 364... Line 341...
364
    WR.Write32LE(file, h.PointerToSymbolTable);
341
 
365
    WR.Write32LE(file, h.NumberOfSymbols);
342
    WR.Write32LE(h.TimeDateStamp);
366
 
343
    WR.Write32LE(h.PointerToSymbolTable);
367
    WriteWord(file, h.SizeOfOptionalHeader);
344
    WR.Write32LE(h.NumberOfSymbols);
368
    WriteWord(file, h.Characteristics)
345
 
Line 369... Line 346...
369
END WriteFileHeader;
346
    WriteWord(h.SizeOfOptionalHeader);
370
 
347
    WriteWord(h.Characteristics)
371
 
348
END WriteFileHeader;
372
PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR; console, dll, amd64: BOOLEAN);
349
 
373
VAR
350
 
374
    i, n: INTEGER;
351
PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR; console, dll, amd64: BOOLEAN);
Line 375... Line 352...
375
 
352
VAR
376
    Size: RECORD
353
    i, n, temp: INTEGER;
-
 
354
 
-
 
355
    Size: RECORD
-
 
356
 
-
 
357
        Code, Data, Bss, Import, Reloc, Export: INTEGER
-
 
358
 
-
 
359
    END;
-
 
360
 
-
 
361
    BaseAddress: INTEGER;
-
 
362
 
-
 
363
    Address: VIRTUAL_ADDR;
-
 
364
 
-
 
365
    _import:      BIN.IMPRT;
Line 377... Line -...
377
 
-
 
378
        Code, Data, Bss, Stack, Import, Reloc, Export: INTEGER
-
 
379
 
-
 
380
    END;
-
 
381
 
-
 
382
    BaseAddress: INTEGER;
-
 
383
 
-
 
384
    Address: VIRTUAL_ADDR;
-
 
385
 
-
 
386
    File: FILE;
-
 
387
 
-
 
388
    import:       BIN.IMPRT;
-
 
389
    ImportTable:  CHL.INTLIST;
366
    ImportTable:  CHL.INTLIST;
390
 
367
 
391
    ExportDir:  IMAGE_EXPORT_DIRECTORY;
368
    ExportDir:  IMAGE_EXPORT_DIRECTORY;
392
    export:     BIN.EXPRT;
369
    export:     BIN.EXPRT;
393
 
370
 
394
 
371
 
395
    PROCEDURE WriteExportDir (file: FILE; e: IMAGE_EXPORT_DIRECTORY);
372
    PROCEDURE WriteExportDir (e: IMAGE_EXPORT_DIRECTORY);
396
    BEGIN
373
    BEGIN
397
        WR.Write32LE(file, e.Characteristics);
374
        WR.Write32LE(e.Characteristics);
398
        WR.Write32LE(file, e.TimeDateStamp);
375
        WR.Write32LE(e.TimeDateStamp);
399
 
376
 
400
        WriteWord(file, e.MajorVersion);
377
        WriteWord(e.MajorVersion);
401
        WriteWord(file, e.MinorVersion);
378
        WriteWord(e.MinorVersion);
402
 
379
 
Line 403... Line 380...
403
        WR.Write32LE(file, e.Name);
380
        WR.Write32LE(e.Name);
404
        WR.Write32LE(file, e.Base);
381
        WR.Write32LE(e.Base);
Line 405... Line 382...
405
        WR.Write32LE(file, e.NumberOfFunctions);
382
        WR.Write32LE(e.NumberOfFunctions);
406
        WR.Write32LE(file, e.NumberOfNames);
383
        WR.Write32LE(e.NumberOfNames);
407
        WR.Write32LE(file, e.AddressOfFunctions);
384
        WR.Write32LE(e.AddressOfFunctions);
408
        WR.Write32LE(file, e.AddressOfNames);
385
        WR.Write32LE(e.AddressOfNames);
Line 409... Line 386...
409
        WR.Write32LE(file, e.AddressOfNameOrdinals)
386
        WR.Write32LE(e.AddressOfNameOrdinals)
Line 410... Line -...
410
    END WriteExportDir;
-
 
411
 
-
 
412
 
-
 
413
    PROCEDURE WriteOptHeader (file: FILE; h: IMAGE_OPTIONAL_HEADER);
-
 
414
    VAR
-
 
415
        i: INTEGER;
-
 
416
 
-
 
417
    BEGIN
-
 
418
        WriteWord(file, h.Magic);
387
    END WriteExportDir;
419
 
388
 
420
        WR.WriteByte(file, h.MajorLinkerVersion);
389
 
-
 
390
    PROCEDURE WriteOptHeader (h: IMAGE_OPTIONAL_HEADER; amd64: BOOLEAN);
-
 
391
    VAR
421
        WR.WriteByte(file, h.MinorLinkerVersion);
392
        i: INTEGER;
422
 
393
 
423
        WR.Write32LE(file, h.SizeOfCode);
394
    BEGIN
424
        WR.Write32LE(file, h.SizeOfInitializedData);
395
        WriteWord(h.Magic);
425
        WR.Write32LE(file, h.SizeOfUninitializedData);
396
 
426
        WR.Write32LE(file, h.AddressOfEntryPoint);
397
        WR.WriteByte(h.MajorLinkerVersion);
Line 427... Line 398...
427
        WR.Write32LE(file, h.BaseOfCode);
398
        WR.WriteByte(h.MinorLinkerVersion);
428
 
-
 
429
        IF bit64 THEN
399
 
430
            WR.Write64LE(file, h.ImageBase)
-
 
Line 431... Line 400...
431
        ELSE
400
        WR.Write32LE(h.SizeOfCode);
432
            WR.Write32LE(file, h.BaseOfData);
401
        WR.Write32LE(h.SizeOfInitializedData);
433
            WR.Write32LE(file, h.ImageBase)
402
        WR.Write32LE(h.SizeOfUninitializedData);
434
        END;
-
 
Line 435... Line 403...
435
 
403
        WR.Write32LE(h.AddressOfEntryPoint);
436
        WR.Write32LE(file, h.SectionAlignment);
404
        WR.Write32LE(h.BaseOfCode);
437
        WR.Write32LE(file, h.FileAlignment);
405
 
438
 
406
        IF amd64 THEN
439
        WriteWord(file, h.MajorOperatingSystemVersion);
407
            WR.Write64LE(h.ImageBase)
Line 440... Line 408...
440
        WriteWord(file, h.MinorOperatingSystemVersion);
408
        ELSE
441
        WriteWord(file, h.MajorImageVersion);
409
            WR.Write32LE(h.BaseOfData);
442
        WriteWord(file, h.MinorImageVersion);
410
            WR.Write32LE(h.ImageBase)
443
        WriteWord(file, h.MajorSubsystemVersion);
411
        END;
Line 444... Line 412...
444
        WriteWord(file, h.MinorSubsystemVersion);
412
 
445
 
413
        WR.Write32LE(h.SectionAlignment);
446
        WR.Write32LE(file, h.Win32VersionValue);
414
        WR.Write32LE(h.FileAlignment);
447
        WR.Write32LE(file, h.SizeOfImage);
415
 
448
        WR.Write32LE(file, h.SizeOfHeaders);
416
        WriteWord(h.MajorOperatingSystemVersion);
Line 449... Line 417...
449
        WR.Write32LE(file, h.CheckSum);
417
        WriteWord(h.MinorOperatingSystemVersion);
Line 450... Line 418...
450
 
418
        WriteWord(h.MajorImageVersion);
451
        WriteWord(file, h.Subsystem);
419
        WriteWord(h.MinorImageVersion);
452
        WriteWord(file, h.DllCharacteristics);
420
        WriteWord(h.MajorSubsystemVersion);
453
 
421
        WriteWord(h.MinorSubsystemVersion);
454
        IF bit64 THEN
422
 
455
            WR.Write64LE(file, h.SizeOfStackReserve);
423
        WR.Write32LE(h.Win32VersionValue);
456
            WR.Write64LE(file, h.SizeOfStackCommit);
424
        WR.Write32LE(h.SizeOfImage);
457
            WR.Write64LE(file, h.SizeOfHeapReserve);
425
        WR.Write32LE(h.SizeOfHeaders);
458
            WR.Write64LE(file, h.SizeOfHeapCommit)
426
        WR.Write32LE(h.CheckSum);
459
        ELSE
427
 
460
            WR.Write32LE(file, h.SizeOfStackReserve);
428
        WriteWord(h.Subsystem);
461
            WR.Write32LE(file, h.SizeOfStackCommit);
429
        WriteWord(h.DllCharacteristics);
462
            WR.Write32LE(file, h.SizeOfHeapReserve);
430
 
463
            WR.Write32LE(file, h.SizeOfHeapCommit)
431
        IF amd64 THEN
464
        END;
432
            WR.Write64LE(h.SizeOfStackReserve);
465
 
433
            WR.Write64LE(h.SizeOfStackCommit);
466
        WR.Write32LE(file, h.LoaderFlags);
434
            WR.Write64LE(h.SizeOfHeapReserve);
467
        WR.Write32LE(file, h.NumberOfRvaAndSizes);
435
            WR.Write64LE(h.SizeOfHeapCommit)
468
 
436
        ELSE
469
        FOR i := 0 TO LEN(h.DataDirectory) - 1 DO
437
            WR.Write32LE(h.SizeOfStackReserve);
470
            WR.Write32LE(file, h.DataDirectory[i].VirtualAddress);
438
            WR.Write32LE(h.SizeOfStackCommit);
471
            WR.Write32LE(file, h.DataDirectory[i].Size)
439
            WR.Write32LE(h.SizeOfHeapReserve);
472
        END
440
            WR.Write32LE(h.SizeOfHeapCommit)
473
 
441
        END;
474
    END WriteOptHeader;
442
 
475
 
443
        WR.Write32LE(h.LoaderFlags);
476
 
444
        WR.Write32LE(h.NumberOfRvaAndSizes);
477
    PROCEDURE WritePEHeader (file: FILE; h: IMAGE_NT_HEADERS);
445
 
478
    BEGIN
446
        FOR i := 0 TO LEN(h.DataDirectory) - 1 DO
479
        WR.Write(file, h.Signature, LEN(h.Signature));
447
            WR.Write32LE(h.DataDirectory[i].VirtualAddress);
480
        WriteFileHeader(file, h.FileHeader);
448
            WR.Write32LE(h.DataDirectory[i].Size)
481
        WriteOptHeader(file, h.OptionalHeader)
449
        END
482
    END WritePEHeader;
450
 
483
 
451
    END WriteOptHeader;
484
 
452
 
485
    PROCEDURE InitSection (VAR section: IMAGE_SECTION_HEADER; Name: NAME; Characteristics: DWORD);
453
 
Line -... Line 454...
-
 
454
    PROCEDURE InitSection (VAR section: IMAGE_SECTION_HEADER; Name: NAME; VirtualSize: INTEGER; Characteristics: DWORD);
-
 
455
    BEGIN
486
    BEGIN
456
        section.Name                  :=  Name;
-
 
457
        section.VirtualSize           :=  VirtualSize;
-
 
458
        section.SizeOfRawData         :=  WR.align(VirtualSize, FileAlignment);
487
        section.Name                  :=  Name;
459
        section.PointerToRelocations  :=  0;
488
        section.PointerToRelocations  :=  0;
460
        section.PointerToLinenumbers  :=  0;
489
        section.PointerToLinenumbers  :=  0;
-
 
490
        section.NumberOfRelocations   :=  0X;
461
        section.NumberOfRelocations   :=  0X;
Line 491... Line 462...
491
        section.NumberOfLinenumbers   :=  0X;
462
        section.NumberOfLinenumbers   :=  0X;
492
        section.Characteristics       :=  Characteristics
-
 
493
    END InitSection;
463
        section.Characteristics       :=  Characteristics
494
 
-
 
495
 
464
    END InitSection;
Line 496... Line 465...
496
BEGIN
465
 
497
    bit64 := amd64;
-
 
498
    SizeOfWord := SIZE_OF_DWORD * (ORD(bit64) + 1);
466
 
499
    Relocations := LISTS.create(NIL);
-
 
500
 
467
BEGIN
-
 
468
    SizeOfWord := SIZE_OF_DWORD * (ORD(amd64) + 1);
Line 501... Line 469...
501
    Size.Code  := CHL.Length(program.code);
469
 
Line 502... Line -...
502
    Size.Data  := CHL.Length(program.data);
-
 
503
    Size.Bss   := program.bss;
470
    Size.Code  := CHL.Length(program.code);
504
    Size.Stack := program.stack;
471
    Size.Data  := CHL.Length(program.data);
505
 
-
 
506
    IF dll THEN
472
    Size.Bss   := program.bss;
Line 507... Line 473...
507
        BaseAddress := 10000000H
473
 
508
    ELSE
474
    IF dll THEN
509
        BaseAddress := 400000H
475
        BaseAddress := 10000000H
510
    END;
476
    ELSE
Line 511... Line 477...
511
 
477
        BaseAddress := 400000H
Line 512... Line 478...
512
    PEHeader.Signature[0] := 50H;
478
    END;
513
    PEHeader.Signature[1] := 45H;
479
 
Line 514... Line -...
514
    PEHeader.Signature[2] := 0;
-
 
515
    PEHeader.Signature[3] := 0;
480
    Signature[0] := 50H;
516
 
481
    Signature[1] := 45H;
517
    IF amd64 THEN
-
 
518
        PEHeader.FileHeader.Machine := 08664X
482
    Signature[2] := 0;
519
    ELSE
-
 
Line 520... Line -...
520
        PEHeader.FileHeader.Machine := 014CX
-
 
521
    END;
483
    Signature[3] := 0;
522
 
484
 
523
    PEHeader.FileHeader.NumberOfSections := WCHR(4 + ORD(dll));
485
    IF amd64 THEN
Line 524... Line -...
524
 
-
 
525
    PEHeader.FileHeader.TimeDateStamp         :=  UTILS.UnixTime();
486
        FileHeader.Machine := 08664X
526
    PEHeader.FileHeader.PointerToSymbolTable  :=  0H;
487
    ELSE
527
    PEHeader.FileHeader.NumberOfSymbols       :=  0H;
-
 
Line 528... Line -...
528
    PEHeader.FileHeader.SizeOfOptionalHeader  :=  WCHR(0E0H + 10H * ORD(amd64));
-
 
529
    PEHeader.FileHeader.Characteristics       :=  WCHR(010EH + (20H - 100H) * ORD(amd64) + 2000H * ORD(dll));
-
 
530
 
-
 
531
    PEHeader.OptionalHeader.Magic                        :=  WCHR(010BH + 100H * ORD(amd64));
488
        FileHeader.Machine := 014CX
532
    PEHeader.OptionalHeader.MajorLinkerVersion           :=  UTILS.vMajor;
489
    END;
533
    PEHeader.OptionalHeader.MinorLinkerVersion           :=  UTILS.vMinor;
490
 
Line 534... Line -...
534
    PEHeader.OptionalHeader.SizeOfCode                   :=  align(Size.Code, FileAlignment);
-
 
535
    PEHeader.OptionalHeader.SizeOfInitializedData        :=  0;
-
 
536
    PEHeader.OptionalHeader.SizeOfUninitializedData      :=  0;
-
 
537
    PEHeader.OptionalHeader.AddressOfEntryPoint          :=  SectionAlignment;
491
    FileHeader.NumberOfSections := WCHR(4 + ORD(dll));
Line 538... Line 492...
538
    PEHeader.OptionalHeader.BaseOfCode                   :=  SectionAlignment;
492
 
539
    PEHeader.OptionalHeader.BaseOfData                   :=  PEHeader.OptionalHeader.BaseOfCode + align(Size.Code, SectionAlignment);
493
    FileHeader.TimeDateStamp         :=  UTILS.UnixTime();
540
    PEHeader.OptionalHeader.ImageBase                    :=  BaseAddress;
494
    FileHeader.PointerToSymbolTable  :=  0H;
Line 541... Line 495...
541
    PEHeader.OptionalHeader.SectionAlignment             :=  SectionAlignment;
495
    FileHeader.NumberOfSymbols       :=  0H;
542
    PEHeader.OptionalHeader.FileAlignment                :=  FileAlignment;
496
    FileHeader.SizeOfOptionalHeader  :=  WCHR(0E0H + 10H * ORD(amd64));
543
    PEHeader.OptionalHeader.MajorOperatingSystemVersion  :=  1X;
497
    FileHeader.Characteristics       :=  WCHR(010EH + (20H - 100H) * ORD(amd64) + 2000H * ORD(dll));
544
    PEHeader.OptionalHeader.MinorOperatingSystemVersion  :=  0X;
498
 
545
    PEHeader.OptionalHeader.MajorImageVersion            :=  0X;
499
    OptionalHeader.Magic                        :=  WCHR(010BH + 100H * ORD(amd64));
Line 546... Line 500...
546
    PEHeader.OptionalHeader.MinorImageVersion            :=  0X;
500
    OptionalHeader.MajorLinkerVersion           :=  UTILS.vMajor;
Line 547... Line 501...
547
    PEHeader.OptionalHeader.MajorSubsystemVersion        :=  4X;
501
    OptionalHeader.MinorLinkerVersion           :=  UTILS.vMinor;
Line -... Line 502...
-
 
502
    OptionalHeader.SizeOfCode                   :=  WR.align(Size.Code, FileAlignment);
548
    PEHeader.OptionalHeader.MinorSubsystemVersion        :=  0X;
503
    OptionalHeader.SizeOfInitializedData        :=  0;
-
 
504
    OptionalHeader.SizeOfUninitializedData      :=  0;
Line 549... Line 505...
549
    PEHeader.OptionalHeader.Win32VersionValue            :=  0H;
505
    OptionalHeader.AddressOfEntryPoint          :=  SectionAlignment;
550
    PEHeader.OptionalHeader.SizeOfImage                  :=  SectionAlignment;
506
    OptionalHeader.BaseOfCode                   :=  SectionAlignment;
551
    PEHeader.OptionalHeader.SizeOfHeaders                :=  400H;
507
    OptionalHeader.BaseOfData                   :=  OptionalHeader.BaseOfCode + WR.align(Size.Code, SectionAlignment);
Line 552... Line 508...
552
    PEHeader.OptionalHeader.CheckSum                     :=  0;
508
    OptionalHeader.ImageBase                    :=  BaseAddress;
Line 553... Line 509...
553
    PEHeader.OptionalHeader.Subsystem                    :=  WCHR((2 + ORD(console)) * ORD(~dll));
509
    OptionalHeader.SectionAlignment             :=  SectionAlignment;
554
    PEHeader.OptionalHeader.DllCharacteristics           :=  0040X;
510
    OptionalHeader.FileAlignment                :=  FileAlignment;
Line 555... Line 511...
555
    PEHeader.OptionalHeader.SizeOfStackReserve           :=  Size.Stack;
511
    OptionalHeader.MajorOperatingSystemVersion  :=  1X;
556
    PEHeader.OptionalHeader.SizeOfStackCommit            :=  Size.Stack DIV 16;
512
    OptionalHeader.MinorOperatingSystemVersion  :=  0X;
Line 557... Line 513...
557
    PEHeader.OptionalHeader.SizeOfHeapReserve            :=  100000H;
513
    OptionalHeader.MajorImageVersion            :=  0X;
558
    PEHeader.OptionalHeader.SizeOfHeapCommit             :=  10000H;
514
    OptionalHeader.MinorImageVersion            :=  0X;
Line 559... Line 515...
559
    PEHeader.OptionalHeader.LoaderFlags                  :=  0;
515
    OptionalHeader.MajorSubsystemVersion        :=  4X;
560
    PEHeader.OptionalHeader.NumberOfRvaAndSizes          :=  IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
516
    OptionalHeader.MinorSubsystemVersion        :=  0X;
561
 
517
    OptionalHeader.Win32VersionValue            :=  0H;
Line 562... Line 518...
562
    InitSection(SectionHeaders[0], ".text", SHC_text);
518
    OptionalHeader.SizeOfImage                  :=  SectionAlignment;
563
    SectionHeaders[0].VirtualSize      := Size.Code;
519
    OptionalHeader.SizeOfHeaders                :=  400H;
564
    SectionHeaders[0].VirtualAddress   := SectionAlignment;
520
    OptionalHeader.CheckSum                     :=  0;
565
    SectionHeaders[0].SizeOfRawData    := align(Size.Code, FileAlignment);
521
    OptionalHeader.Subsystem                    :=  WCHR((2 + ORD(console)) * ORD(~dll));
566
    SectionHeaders[0].PointerToRawData := PEHeader.OptionalHeader.SizeOfHeaders;
522
    OptionalHeader.DllCharacteristics           :=  0040X;
567
 
523
    OptionalHeader.SizeOfStackReserve           :=  100000H;
568
    InitSection(SectionHeaders[1], ".data", SHC_data);
524
    OptionalHeader.SizeOfStackCommit            :=  10000H;
569
    SectionHeaders[1].VirtualSize      := Size.Data;
525
    OptionalHeader.SizeOfHeapReserve            :=  100000H;
570
    SectionHeaders[1].VirtualAddress   := align(SectionHeaders[0].VirtualAddress + SectionHeaders[0].VirtualSize, SectionAlignment);
526
    OptionalHeader.SizeOfHeapCommit             :=  10000H;
571
    SectionHeaders[1].SizeOfRawData    := align(Size.Data, FileAlignment);
527
    OptionalHeader.LoaderFlags                  :=  0;
572
    SectionHeaders[1].PointerToRawData := SectionHeaders[0].PointerToRawData + SectionHeaders[0].SizeOfRawData;
528
    OptionalHeader.NumberOfRvaAndSizes          :=  IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
573
 
529
 
574
    InitSection(SectionHeaders[2], ".bss", SHC_bss);
530
    FOR i := 0 TO IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 DO
Line 575... Line 531...
575
    SectionHeaders[2].VirtualSize      := Size.Bss;
531
        OptionalHeader.DataDirectory[i].VirtualAddress := 0;
576
    SectionHeaders[2].VirtualAddress   := align(SectionHeaders[1].VirtualAddress + SectionHeaders[1].VirtualSize, SectionAlignment);
532
        OptionalHeader.DataDirectory[i].Size := 0
577
    SectionHeaders[2].SizeOfRawData    := 0;
533
    END;
578
    SectionHeaders[2].PointerToRawData := SectionHeaders[1].PointerToRawData + SectionHeaders[1].SizeOfRawData;
534
 
579
 
535
    InitSection(SectionHeaders[0], ".text", Size.Code, SHC_text);
Line 580... Line 536...
580
    Size.Import := GetImportSize(program.imp_list);
536
    SectionHeaders[0].VirtualAddress   := SectionAlignment;
581
 
537
    SectionHeaders[0].PointerToRawData := OptionalHeader.SizeOfHeaders;
582
    InitSection(SectionHeaders[3], ".idata", SHC_data);
538
 
583
    SectionHeaders[3].VirtualSize      := Size.Import + CHL.Length(program.import);
539
    InitSection(SectionHeaders[1], ".data", Size.Data, SHC_data);
-
 
540
    SectionHeaders[1].VirtualAddress   := WR.align(SectionHeaders[0].VirtualAddress + SectionHeaders[0].VirtualSize, SectionAlignment);
584
    SectionHeaders[3].VirtualAddress   := align(SectionHeaders[2].VirtualAddress + SectionHeaders[2].VirtualSize, SectionAlignment);
541
    SectionHeaders[1].PointerToRawData := SectionHeaders[0].PointerToRawData + SectionHeaders[0].SizeOfRawData;
585
    SectionHeaders[3].SizeOfRawData    := align(SectionHeaders[3].VirtualSize, FileAlignment);
542
 
586
    SectionHeaders[3].PointerToRawData := SectionHeaders[2].PointerToRawData + SectionHeaders[2].SizeOfRawData;
543
    InitSection(SectionHeaders[2], ".bss", Size.Bss, SHC_bss);
587
 
544
    SectionHeaders[2].VirtualAddress   := WR.align(SectionHeaders[1].VirtualAddress + SectionHeaders[1].VirtualSize, SectionAlignment);
Line 588... Line 545...
588
    Address.Code   := SectionHeaders[0].VirtualAddress + PEHeader.OptionalHeader.ImageBase;
545
    SectionHeaders[2].PointerToRawData := SectionHeaders[1].PointerToRawData + SectionHeaders[1].SizeOfRawData;
589
    Address.Data   := SectionHeaders[1].VirtualAddress + PEHeader.OptionalHeader.ImageBase;
546
    SectionHeaders[2].SizeOfRawData    := 0;
590
    Address.Bss    := SectionHeaders[2].VirtualAddress + PEHeader.OptionalHeader.ImageBase;
547
 
Line 591... Line 548...
591
    Address.Import := SectionHeaders[3].VirtualAddress + PEHeader.OptionalHeader.ImageBase;
548
    Size.Import := GetImportSize(program.imp_list);
592
 
549
 
593
    fixup(program, Address);
550
    InitSection(SectionHeaders[3], ".idata", Size.Import + CHL.Length(program._import), SHC_data);
594
 
551
    SectionHeaders[3].VirtualAddress   := WR.align(SectionHeaders[2].VirtualAddress + SectionHeaders[2].VirtualSize, SectionAlignment);
595
    IF dll THEN
552
    SectionHeaders[3].PointerToRawData := SectionHeaders[2].PointerToRawData + SectionHeaders[2].SizeOfRawData;
596
        Size.Export := Export(program, SectionHeaders[1].VirtualAddress, ExportDir);
553
 
597
 
554
    Address.Code   := SectionHeaders[0].VirtualAddress + OptionalHeader.ImageBase;
Line 598... Line 555...
598
        InitSection(SectionHeaders[4], ".edata", SHC_data);
555
    Address.Data   := SectionHeaders[1].VirtualAddress + OptionalHeader.ImageBase;
599
        SectionHeaders[4].VirtualSize      := Size.Export + CHL.Length(program.export);
556
    Address.Bss    := SectionHeaders[2].VirtualAddress + OptionalHeader.ImageBase;
Line 600... Line 557...
600
        SectionHeaders[4].VirtualAddress   := align(SectionHeaders[3].VirtualAddress + SectionHeaders[3].VirtualSize, SectionAlignment);
557
    Address.Import := SectionHeaders[3].VirtualAddress + OptionalHeader.ImageBase;
Line 601... Line 558...
601
        SectionHeaders[4].SizeOfRawData    := align(SectionHeaders[4].VirtualSize, FileAlignment);
558
 
602
        SectionHeaders[4].PointerToRawData := SectionHeaders[3].PointerToRawData + SectionHeaders[3].SizeOfRawData;
559
    fixup(program, Address, amd64);
603
    END;
560
 
Line 604... Line 561...
604
 
561
    IF dll THEN
Line 605... Line 562...
605
    FOR i := 0 TO IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1 DO
562
        Size.Export := Export(program, SectionHeaders[1].VirtualAddress + program.modname, ExportDir);
606
        PEHeader.OptionalHeader.DataDirectory[i].VirtualAddress := 0;
563
 
607
        PEHeader.OptionalHeader.DataDirectory[i].Size := 0
564
        InitSection(SectionHeaders[4], ".edata", Size.Export + CHL.Length(program.export), SHC_data);
608
    END;
565
        SectionHeaders[4].VirtualAddress   := WR.align(SectionHeaders[3].VirtualAddress + SectionHeaders[3].VirtualSize, SectionAlignment);
609
 
566
        SectionHeaders[4].PointerToRawData := SectionHeaders[3].PointerToRawData + SectionHeaders[3].SizeOfRawData;
Line 610... Line 567...
610
    IF dll THEN
567
 
611
        PEHeader.OptionalHeader.DataDirectory[0].VirtualAddress := SectionHeaders[4].VirtualAddress;
568
        OptionalHeader.DataDirectory[0].VirtualAddress := SectionHeaders[4].VirtualAddress;
612
        PEHeader.OptionalHeader.DataDirectory[0].Size := SectionHeaders[4].VirtualSize
569
        OptionalHeader.DataDirectory[0].Size := SectionHeaders[4].VirtualSize
613
    END;
570
    END;
614
 
571
 
Line 615... Line 572...
615
    PEHeader.OptionalHeader.DataDirectory[1].VirtualAddress := SectionHeaders[3].VirtualAddress;
572
    OptionalHeader.DataDirectory[1].VirtualAddress := SectionHeaders[3].VirtualAddress;
616
    PEHeader.OptionalHeader.DataDirectory[1].Size := SectionHeaders[3].VirtualSize;
573
    OptionalHeader.DataDirectory[1].Size := SectionHeaders[3].VirtualSize;
617
 
574
 
Line 618... Line 575...
618
    FOR i := 0 TO ORD(PEHeader.FileHeader.NumberOfSections) - 1 DO
575
    FOR i := 1 TO ORD(FileHeader.NumberOfSections) - 1 DO
619
        INC(PEHeader.OptionalHeader.SizeOfInitializedData, SectionHeaders[i].SizeOfRawData)
576
        INC(OptionalHeader.SizeOfInitializedData, SectionHeaders[i].SizeOfRawData)
620
    END;
577
    END;
Line 621... Line 578...
621
 
578
 
622
    DEC(PEHeader.OptionalHeader.SizeOfInitializedData, SectionHeaders[0].SizeOfRawData);
579
    OptionalHeader.SizeOfUninitializedData := WR.align(SectionHeaders[2].VirtualSize, FileAlignment);
Line 623... Line 580...
623
    DEC(PEHeader.OptionalHeader.SizeOfInitializedData, SectionHeaders[2].SizeOfRawData);
580
 
624
 
581
    FOR i := 0 TO ORD(FileHeader.NumberOfSections) - 1 DO