1 {
2  ---------------------------------------------------------------------------
3  dbgpetypes.pp
4  ---------------------------------------------------------------------------
5 
6  This unit contains the types needed for reading PE images.
7  At some time this may go to be part of the rtl ?
8 
9  ---------------------------------------------------------------------------
10 
11  @created(Thu May 4th WET 2006)
12  @author(Marc Weustink <marc@@dommelstein.nl>)
13 
14  @update (2th july 2009). Removed "Uses Windows" by dmitry boyarintsev.
15 
16  *****************************************************************************
17  *                                                                           *
18  *  This file is part of the Lazarus Project                                 *
19  *                                                                           *
20  *  See the file COPYING.modifiedLGPL.txt, included in this distribution,    *
21  *  for details about the copyright.                                         *
22  *                                                                           *
23  *  This program is distributed in the hope that it will be useful,          *
24  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
25  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     *
26  *                                                                           *
27  *****************************************************************************
28 }
29 unit FpImgReaderWinPETypes;
30 
31 {$ifdef fpc}{$mode delphi}{$H+}{$inline on}{$endif}
32 
33 interface
34 
35 {$ifndef fpc}
36 type
37   QWord = Int64;
38   DWORD = LongWord;
39 {$endif}
40 
41 type
42   ULONGLONG = QWord;
43   CLSID     = TGUID;
44   SHORT     = Word;
45 
46 const
47 {$ifdef ENDIAN_LITTLE}
48 
49   IMAGE_DOS_SIGNATURE                = $5A4D;      // MZ
50   IMAGE_OS2_SIGNATURE                = $454E;      // NE
51   IMAGE_OS2_SIGNATURE_LE             = $454C;      // LE
52   IMAGE_VXD_SIGNATURE                = $454C;      // LE
53   IMAGE_NT_SIGNATURE                 = $00004550;  // PE00
54 
55 {$else}
56 
57   IMAGE_DOS_SIGNATURE                = $4D5A;      // MZ
58   IMAGE_OS2_SIGNATURE                = $4E45;      // NE
59   IMAGE_OS2_SIGNATURE_LE             = $4C45;      // LE
60   IMAGE_NT_SIGNATURE                 = $50450000;  // PE00
61 
62 {$endif}
63 
64 {$ifdef fpc}
65 {$packrecords 2}
66 {$endif}
67 
68 type
69   _IMAGE_DOS_HEADER = {$ifndef fpc} packed {$endif} record     // DOS .EXE header
70     e_magic:    WORD;            // Magic number
71     e_cblp:     WORD;            // Bytes on last page of file
72     e_cp:       WORD;            // Pages in file
73     e_crlc:     WORD;            // Relocations
74     e_cparhdr:  WORD;            // Size of header in paragraphs
75     e_minalloc: WORD;            // Minimum extra paragraphs needed
76     e_maxalloc: WORD;            // Maximum extra paragraphs needed
77     e_ss:       WORD;            // Initial (relative) SS value
78     e_sp:       WORD;            // Initial SP value
79     e_csum:     WORD;            // Checksum
80     e_ip:       WORD;            // Initial IP value
81     e_cs:       WORD;            // Initial (relative) CS value
82     e_lfarlc:   WORD;            // File address of relocation table
83     e_ovno:     WORD;            // Overlay number
84     e_res: array[0..3] of WORD;  // Reserved words
85     e_oemid:    WORD;            // OEM identifier (for e_oeminfo)
86     e_oeminfo:  WORD;            // OEM information: e_oemid specific
87     e_res2: array[0..9] of WORD; // Reserved words
88     e_lfanew:   LongWord;            // File address of new exe header
89   end;
90   IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
91   TImageDosHeader = _IMAGE_DOS_HEADER;
92   PImageDosHeader = ^TImageDosHeader;
93 
94 type
95   _IMAGE_OS2_HEADER = {$ifndef fpc} packed {$endif} record // OS/2 .EXE header
96     ne_magic:         WORD;  // Magic number
97     ne_ver:           CHAR;  // Version number
98     ne_rev:           CHAR;  // Revision number
99     ne_enttab:        WORD;  // Offset of Entry Table
100     ne_cbenttab:      WORD;  // Number of bytes in Entry Table
101     ne_crc:           LongWord;  // Checksum of whole file
102     ne_flags:         WORD;  // Flag word
103     ne_autodata:      WORD;  // Automatic data segment number
104     ne_heap:          WORD;  // Initial heap allocation
105     ne_stack:         WORD;  // Initial stack allocation
106     ne_csip:          LongWord;  // Initial CS:IP setting
107     ne_sssp:          LongWord;  // Initial SS:SP setting
108     ne_cseg:          WORD;  // Count of file segments
109     ne_cmod:          WORD;  // Entries in Module Reference Table
110     ne_cbnrestab:     WORD;  // Size of non-resident name table
111     ne_segtab:        WORD;  // Offset of Segment Table
112     ne_rsrctab:       WORD;  // Offset of Resource Table
113     ne_restab:        WORD;  // Offset of resident name table
114     ne_modtab:        WORD;  // Offset of Module Reference Table
115     ne_imptab:        WORD;  // Offset of Imported Names Table
116     ne_nrestab:       LongWord;  // Offset of Non-resident Names Table
117     ne_cmovent:       WORD;  // Count of movable entries
118     ne_align:         WORD;  // Segment alignment shift count
119     ne_cres:          WORD;  // Count of resource segments
120     ne_exetyp:        BYTE;  // Target Operating system
121     ne_flagsothers:   BYTE;  // Other .EXE flags
122     ne_pretthunks:    WORD;  // offset to return thunks
123     ne_psegrefbytes:  WORD;  // offset to segment ref. bytes
124     ne_swaparea:      WORD;  // Minimum code swap area size
125     ne_expver:        WORD;  // Expected Windows version number
126   end;
127   IMAGE_OS2_HEADER = _IMAGE_OS2_HEADER;
128   TImageOS2Header = _IMAGE_OS2_HEADER;
129   PImageOS2Header = ^TImageOS2Header;
130 
131 type
132   _IMAGE_VXD_HEADER = {$ifndef fpc} packed {$endif} record      // Windows VXD header
133     e32_magic:        WORD;          // Magic number
134     e32_border:       BYTE;          // The byte ordering for the VXD
135     e32_worder:       BYTE;          // The word ordering for the VXD
136     e32_level:        DWORD;         // The EXE format level for now = 0
137     e32_cpu:          WORD;          // The CPU type
138     e32_os:           WORD;          // The OS type
139     e32_ver:          DWORD;         // Module version
140     e32_mflags:       DWORD;         // Module flags
141     e32_mpages:       DWORD;         // Module # pages
142     e32_startobj:     DWORD;         // Object # for instruction pointer
143     e32_eip:          DWORD;         // Extended instruction pointer
144     e32_stackobj:     DWORD;         // Object # for stack pointer
145     e32_esp:          DWORD;         // Extended stack pointer
146     e32_pagesize:     DWORD;         // VXD page size
147     e32_lastpagesize: DWORD;         // Last page size in VXD
148     e32_fixupsize:    DWORD;         // Fixup section size
149     e32_fixupsum:     DWORD;         // Fixup section checksum
150     e32_ldrsize:      DWORD;         // Loader section size
151     e32_ldrsum:       DWORD;         // Loader section checksum
152     e32_objtab:       DWORD;         // Object table offset
153     e32_objcnt:       DWORD;         // Number of objects in module
154     e32_objmap:       DWORD;         // Object page map offset
155     e32_itermap:      DWORD;         // Object iterated data map offset
156     e32_rsrctab:      DWORD;         // Offset of Resource Table
157     e32_rsrccnt:      DWORD;         // Number of resource entries
158     e32_restab:       DWORD;         // Offset of resident name table
159     e32_enttab:       DWORD;         // Offset of Entry Table
160     e32_dirtab:       DWORD;         // Offset of Module Directive Table
161     e32_dircnt:       DWORD;         // Number of module directives
162     e32_fpagetab:     DWORD;         // Offset of Fixup Page Table
163     e32_frectab:      DWORD;         // Offset of Fixup Record Table
164     e32_impmod:       DWORD;         // Offset of Import Module Name Table
165     e32_impmodcnt:    DWORD;         // Number of entries in Import Module Name Table
166     e32_impproc:      DWORD;         // Offset of Import Procedure Name Table
167     e32_pagesum:      DWORD;         // Offset of Per-Page Checksum Table
168     e32_datapage:     DWORD;         // Offset of Enumerated Data Pages
169     e32_preload:      DWORD;         // Number of preload pages
170     e32_nrestab:      DWORD;         // Offset of Non-resident Names Table
171     e32_cbnrestab:    DWORD;         // Size of Non-resident Name Table
172     e32_nressum:      DWORD;         // Non-resident Name Table Checksum
173     e32_autodata:     DWORD;         // Object # for automatic data object
174     e32_debuginfo:    DWORD;         // Offset of the debugging information
175     e32_debuglen:     DWORD;         // The length of the debugging info. in bytes
176     e32_instpreload:  DWORD;         // Number of instance pages in preload section of VXD file
177     e32_instdemand:   DWORD;         // Number of instance pages in demand load section of VXD file
178     e32_heapsize:     DWORD;         // Size of heap - for 16-bit apps
179     e32_res3: array[0..11] of BYTE;  // Reserved words
180     e32_winresoff:    DWORD;
181     e32_winreslen:    DWORD;
182     e32_devid:        WORD;          // Device ID for VxD
183     e32_ddkver:       WORD;          // DDK version for VxD
184   end;
185   IMAGE_VXD_HEADER = _IMAGE_VXD_HEADER;
186   TImageVXDHeader = _IMAGE_VXD_HEADER;
187   PImageVXDHeader = ^TImageVXDHeader;
188 
189 {$ifdef fpc}
190 {$packrecords 4}
191 {$endif}
192 
193 //
194 // File header format.
195 //
196 
197 type
198   _IMAGE_FILE_HEADER = record
199     Machine:              WORD;
200     NumberOfSections:     WORD;
201     TimeDateStamp:        DWORD;
202     PointerToSymbolTable: DWORD;
203     NumberOfSymbols:      DWORD;
204     SizeOfOptionalHeader: WORD;
205     Characteristics:      WORD;
206   end;
207   IMAGE_FILE_HEADER = _IMAGE_FILE_HEADER;
208   TImageFileHeader = _IMAGE_FILE_HEADER;
209   PImageFileHeader = ^TImageFileHeader;
210 
211 const
212   IMAGE_SIZEOF_FILE_HEADER            = 20;
213 
214 
215   IMAGE_FILE_RELOCS_STRIPPED          = $0001;  // Relocation info stripped from file.
216   IMAGE_FILE_EXECUTABLE_IMAGE         = $0002;  // File is executable  (i.e. no unresolved externel references).
217   IMAGE_FILE_LINE_NUMS_STRIPPED       = $0004;  // Line nunbers stripped from file.
218   IMAGE_FILE_LOCAL_SYMS_STRIPPED      = $0008;  // Local symbols stripped from file.
219   IMAGE_FILE_AGGRESIVE_WS_TRIM        = $0010;  // Agressively trim working set
220   IMAGE_FILE_LARGE_ADDRESS_AWARE      = $0020;  // App can handle >2gb addresses
221   IMAGE_FILE_BYTES_REVERSED_LO        = $0080;  // Bytes of machine word are reversed.
222   IMAGE_FILE_32BIT_MACHINE            = $0100;  // 32 bit word machine.
223   IMAGE_FILE_DEBUG_STRIPPED           = $0200;  // Debugging info stripped from file in .DBG file
224   IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP  = $0400;  // If Image is on removable media, copy and run from the swap file.
225   IMAGE_FILE_NET_RUN_FROM_SWAP        = $0800;  // If Image is on Net, copy and run from the swap file.
226   IMAGE_FILE_SYSTEM                   = $1000;  // System File.
227   IMAGE_FILE_DLL                      = $2000;  // File is a DLL.
228   IMAGE_FILE_UP_SYSTEM_ONLY           = $4000;  // File should only be run on a UP machine
229   IMAGE_FILE_BYTES_REVERSED_HI        = $8000;  // Bytes of machine word are reversed.
230 
231   IMAGE_FILE_MACHINE_UNKNOWN          = 0;
232   IMAGE_FILE_MACHINE_I386             = $014c;  // Intel 386.
233   IMAGE_FILE_MACHINE_R3000            = $0162;  // MIPS little-endian, $160 big-endian
234   IMAGE_FILE_MACHINE_R4000            = $0166;  // MIPS little-endian
235   IMAGE_FILE_MACHINE_R10000           = $0168;  // MIPS little-endian
236   IMAGE_FILE_MACHINE_WCEMIPSV2        = $0169;  // MIPS little-endian WCE v2
237   IMAGE_FILE_MACHINE_ALPHA            = $0184;  // Alpha_AXP
238   IMAGE_FILE_MACHINE_SH3              = $01a2;  // SH3 little-endian
239   IMAGE_FILE_MACHINE_SH3DSP           = $01a3;
240   IMAGE_FILE_MACHINE_SH3E             = $01a4;  // SH3E little-endian
241   IMAGE_FILE_MACHINE_SH4              = $01a6;  // SH4 little-endian
242   IMAGE_FILE_MACHINE_SH5              = $01a8;  // SH5
243   IMAGE_FILE_MACHINE_ARM              = $01c0;  // ARM Little-Endian
244   IMAGE_FILE_MACHINE_THUMB            = $01c2;
245   IMAGE_FILE_MACHINE_AM33             = $01d3;
246   IMAGE_FILE_MACHINE_POWERPC          = $01F0;  // IBM PowerPC Little-Endian
247   IMAGE_FILE_MACHINE_POWERPCFP        = $01f1;
248   IMAGE_FILE_MACHINE_IA64             = $0200;  // Intel 64
249   IMAGE_FILE_MACHINE_MIPS16           = $0266;  // MIPS
250   IMAGE_FILE_MACHINE_ALPHA64          = $0284;  // ALPHA64
251   IMAGE_FILE_MACHINE_MIPSFPU          = $0366;  // MIPS
252   IMAGE_FILE_MACHINE_MIPSFPU16        = $0466;  // MIPS
253   IMAGE_FILE_MACHINE_AXP64            = IMAGE_FILE_MACHINE_ALPHA64;
254   IMAGE_FILE_MACHINE_TRICORE          = $0520;  // Infineon
255   IMAGE_FILE_MACHINE_CEF              = $0CEF;
256   IMAGE_FILE_MACHINE_EBC              = $0EBC;  // EFI Byte Code
257   IMAGE_FILE_MACHINE_AMD64            = $8664;  // AMD64 (K8)
258   IMAGE_FILE_MACHINE_M32R             = $9041;  // M32R little-endian
259   IMAGE_FILE_MACHINE_CEE              = $C0EE;
260 
261 //
262 // Directory format.
263 //
264 
265 type
266   _IMAGE_DATA_DIRECTORY = record
267     VirtualAddress: DWORD;
268     Size:           DWORD;
269   end;
270   IMAGE_DATA_DIRECTORY = _IMAGE_DATA_DIRECTORY;
271   TImageDataDirectory = _IMAGE_DATA_DIRECTORY;
272   PImageDataDirectory = ^TImageDataDirectory;
273 
274 
275 const
276   IMAGE_NUMBEROF_DIRECTORY_ENTRIES    = 16;
277 
278 //
279 // Optional header format.
280 //
281 
282 type
283   _IMAGE_OPTIONAL_HEADER = record
284     //
285     // Standard fields.
286     //
287 
288     Magic:                       WORD;
289     MajorLinkerVersion:          BYTE;
290     MinorLinkerVersion:          BYTE;
291     SizeOfCode:                  DWORD;
292     SizeOfInitializedData:       DWORD;
293     SizeOfUninitializedData:     DWORD;
294     AddressOfEntryPoint:         DWORD;
295     BaseOfCode:                  DWORD;
296     BaseOfData:                  DWORD;
297 
298     //
299     // NT additional fields.
300     //
301 
302     ImageBase:                   DWORD;
303     SectionAlignment:            DWORD;
304     FileAlignment:               DWORD;
305     MajorOperatingSystemVersion: WORD;
306     MinorOperatingSystemVersion: WORD;
307     MajorImageVersion:           WORD;
308     MinorImageVersion:           WORD;
309     MajorSubsystemVersion:       WORD;
310     MinorSubsystemVersion:       WORD;
311     Win32VersionValue:           DWORD;
312     SizeOfImage:                 DWORD;
313     SizeOfHeaders:               DWORD;
314     CheckSum:                    DWORD;
315     Subsystem:                   WORD;
316     DllCharacteristics:          WORD;
317     SizeOfStackReserve:          DWORD;
318     SizeOfStackCommit:           DWORD;
319     SizeOfHeapReserve:           DWORD;
320     SizeOfHeapCommit:            DWORD;
321     LoaderFlags:                 DWORD;
322     NumberOfRvaAndSizes:         DWORD;
323     DataDirectory: packed array[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of TImageDataDirectory;
324   end;
325   IMAGE_OPTIONAL_HEADER32 = _IMAGE_OPTIONAL_HEADER;
326   TImageOptionalHeader32 = _IMAGE_OPTIONAL_HEADER;
327   PImageOptionalHeader32 = ^TImageOptionalHeader32;
328 
329 type
330   _IMAGE_ROM_OPTIONAL_HEADER = record
331     Magic:                   WORD;
332     MajorLinkerVersion:      BYTE;
333     MinorLinkerVersion:      BYTE;
334     SizeOfCode:              DWORD;
335     SizeOfInitializedData:   DWORD;
336     SizeOfUninitializedData: DWORD;
337     AddressOfEntryPoint:     DWORD;
338     BaseOfCode:              DWORD;
339     BaseOfData:              DWORD;
340     BaseOfBss:               DWORD;
341     GprMask:                 DWORD;
342     CprMask: array[0..3] of  DWORD;
343     GpValue:                 DWORD;
344   end;
345   IMAGE_ROM_OPTIONAL_HEADER = _IMAGE_ROM_OPTIONAL_HEADER;
346   TImageRomOptionalHeader = _IMAGE_ROM_OPTIONAL_HEADER;
347   PImageRomOptionalHeader = ^TImageRomOptionalHeader;
348 
349 type
350   _IMAGE_OPTIONAL_HEADER64 = record
351     Magic:                       WORD;
352     MajorLinkerVersion:          BYTE;
353     MinorLinkerVersion:          BYTE;
354     SizeOfCode:                  DWORD;
355     SizeOfInitializedData:       DWORD;
356     SizeOfUninitializedData:     DWORD;
357     AddressOfEntryPoint:         DWORD;
358     BaseOfCode:                  DWORD;
359     ImageBase:                   ULONGLONG;
360     SectionAlignment:            DWORD;
361     FileAlignment:               DWORD;
362     MajorOperatingSystemVersion: WORD;
363     MinorOperatingSystemVersion: WORD;
364     MajorImageVersion:           WORD;
365     MinorImageVersion:           WORD;
366     MajorSubsystemVersion:       WORD;
367     MinorSubsystemVersion:       WORD;
368     Win32VersionValue:           DWORD;
369     SizeOfImage:                 DWORD;
370     SizeOfHeaders:               DWORD;
371     CheckSum:                    DWORD;
372     Subsystem:                   WORD;
373     DllCharacteristics:          WORD;
374     SizeOfStackReserve:          ULONGLONG;
375     SizeOfStackCommit:           ULONGLONG;
376     SizeOfHeapReserve:           ULONGLONG;
377     SizeOfHeapCommit:            ULONGLONG;
378     LoaderFlags:                 DWORD;
379     NumberOfRvaAndSizes:         DWORD;
380     DataDirectory: packed array[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of TImageDataDirectory;
381   end;
382   IMAGE_OPTIONAL_HEADER64 = _IMAGE_OPTIONAL_HEADER64;
383   TImageOptionalHeader64 = _IMAGE_OPTIONAL_HEADER64;
384   PImageOptionalHeader64 = ^TImageOptionalHeader64;
385 
386 const
387   IMAGE_SIZEOF_ROM_OPTIONAL_HEADER  =   56;
388   IMAGE_SIZEOF_STD_OPTIONAL_HEADER  =   28;
389   IMAGE_SIZEOF_NT_OPTIONAL32_HEADER =  224;
390   IMAGE_SIZEOF_NT_OPTIONAL64_HEADER =  240;
391 
392   IMAGE_NT_OPTIONAL_HDR32_MAGIC     = $10b;
393   IMAGE_NT_OPTIONAL_HDR64_MAGIC     = $20b;
394   IMAGE_ROM_OPTIONAL_HDR_MAGIC      = $107;
395 
396 {$ifdef WIN64}
397 type
398   IMAGE_OPTIONAL_HEADER             = IMAGE_OPTIONAL_HEADER64;
399   TImageOptionalHeader              = TImageOptionalHeader64;
400   PImagePptionalHeader              = PImageOptionalHeader64;
401 const
402   IMAGE_SIZEOF_NT_OPTIONAL_HEADER   = IMAGE_SIZEOF_NT_OPTIONAL64_HEADER;
403   IMAGE_NT_OPTIONAL_HDR_MAGIC       = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
404 {$else}
405 type
406   IMAGE_OPTIONAL_HEADER             = IMAGE_OPTIONAL_HEADER32;
407   TImageOptionalHeader              = TImageOptionalHeader32;
408   PImagePptionalHeader              = PImageOptionalHeader32;
409 const
410   IMAGE_SIZEOF_NT_OPTIONAL_HEADER   = IMAGE_SIZEOF_NT_OPTIONAL32_HEADER;
411   IMAGE_NT_OPTIONAL_HDR_MAGIC       = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
412 {$endif}
413 
414 type
415   _IMAGE_NT_HEADERS64 = record
416     Signature: DWORD;
417     FileHeader: TImageFileHeader;
418     OptionalHeader: TImageOptionalHeader64;
419   end;
420   IMAGE_NT_HEADERS64 = _IMAGE_NT_HEADERS64;
421   TImageNtHeaders64 = _IMAGE_NT_HEADERS64;
422   PImageNtHeaders64 = ^TImageNtHeaders64;
423 
424   _IMAGE_NT_HEADERS32 = record
425     Signature: DWORD;
426     FileHeader: TImageFileHeader;
427     OptionalHeader: TImageOptionalHeader32;
428   end;
429   IMAGE_NT_HEADERS32 = _IMAGE_NT_HEADERS32;
430   TImageNtHeaders32 = _IMAGE_NT_HEADERS32;
431   PImageNtHeaders32 = ^TImageNtHeaders32;
432 
433   _IMAGE_ROM_HEADERS = record
434     FileHeader: TImageFileHeader;
435     OptionalHeader: TImageRomOptionalHeader;
436   end;
437   IMAGE_ROM_HEADERS = _IMAGE_ROM_HEADERS;
438   TImageRomHeaders = _IMAGE_ROM_HEADERS;
439   PImageRomHeaders = ^TImageRomHeaders;
440 
441 {$ifdef WIN64}
442   IMAGE_NT_HEADERS             = IMAGE_NT_HEADERS64;
443   TImageNtHeaders             = TImageNtHeaders64;
444   PImageNtHeaders             = PImageNtHeaders64;
445 {$else}
446   IMAGE_NT_HEADERS             = IMAGE_NT_HEADERS32;
447   TImageNtHeaders             = TImageNtHeaders32;
448   PImageNtHeaders             = PImageNtHeaders32;
449 {$endif}
450 
451 const
452 // Subsystem Values
453   IMAGE_SUBSYSTEM_UNKNOWN                 = 0;   // Unknown subsystem.
454   IMAGE_SUBSYSTEM_NATIVE                  = 1;   // Image doesn't require a subsystem.
455   IMAGE_SUBSYSTEM_WINDOWS_GUI             = 2;   // Image runs in the Windows GUI subsystem.
456   IMAGE_SUBSYSTEM_WINDOWS_CUI             = 3;   // Image runs in the Windows character subsystem.
457   IMAGE_SUBSYSTEM_OS2_CUI                 = 5;   // image runs in the OS/2 character subsystem.
458   IMAGE_SUBSYSTEM_POSIX_CUI               = 7;   // image runs in the Posix character subsystem.
459   IMAGE_SUBSYSTEM_NATIVE_WINDOWS          = 8;   // image is a native Win9x driver.
460   IMAGE_SUBSYSTEM_WINDOWS_CE_GUI          = 9;   // Image runs in the Windows CE subsystem.
461   IMAGE_SUBSYSTEM_EFI_APPLICATION         = 10;  //
462   IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11;  //
463   IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER      = 12;  //
464   IMAGE_SUBSYSTEM_EFI_ROM                 = 13;
465   IMAGE_SUBSYSTEM_XBOX                    = 14;
466 
467 // DllCharacteristics Entries
468 
469   IMAGE_LIBRARY_PROCESS_INIT            = $0001;     // Reserved.
470   IMAGE_LIBRARY_PROCESS_TERM            = $0002;     // Reserved.
471   IMAGE_LIBRARY_THREAD_INIT             = $0004;     // Reserved.
472   IMAGE_LIBRARY_THREAD_TERM             = $0008;     // Reserved.
473   IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = $0200;    // Image understands isolation and doesn't want it
474   IMAGE_DLLCHARACTERISTICS_NO_SEH       = $0400;     // Image does not use SEH.  No SE handler may reside in this image
475   IMAGE_DLLCHARACTERISTICS_NO_BIND      = $0800;     // Do not bind this image.
476 //                                          = $1000;     // Reserved.
477   IMAGE_DLLCHARACTERISTICS_WDM_DRIVER   = $2000;     // Driver uses WDM model
478 //                                          = $4000;     // Reserved.
479   IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE    = $8000;
480 
481 // Directory Entries
482 
483   IMAGE_DIRECTORY_ENTRY_EXPORT         = 0;   // Export Directory
484   IMAGE_DIRECTORY_ENTRY_IMPORT         = 1;   // Import Directory
485   IMAGE_DIRECTORY_ENTRY_RESOURCE       = 2;   // Resource Directory
486   IMAGE_DIRECTORY_ENTRY_EXCEPTION      = 3;   // Exception Directory
487   IMAGE_DIRECTORY_ENTRY_SECURITY       = 4;   // Security Directory
488   IMAGE_DIRECTORY_ENTRY_BASERELOC      = 5;   // Base Relocation Table
489   IMAGE_DIRECTORY_ENTRY_DEBUG          = 6;   // Debug Directory
490   IMAGE_DIRECTORY_ENTRY_COPYRIGHT      = 7;   // (X86 usage)
491   IMAGE_DIRECTORY_ENTRY_ARCHITECTURE   = 7;   // Architecture Specific Data
492   IMAGE_DIRECTORY_ENTRY_GLOBALPTR      = 8;   // RVA of GP
493   IMAGE_DIRECTORY_ENTRY_TLS            = 9;   // TLS Directory
494   IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    = 10;  // Load Configuration Directory
495   IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   = 11;  // Bound Import Directory in headers
496   IMAGE_DIRECTORY_ENTRY_IAT            = 12;  // Import Address Table
497   IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   = 13;  // Delay Load Import Descriptors
498   IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14;  // COM Runtime descriptor
499 
500 //
501 // Non-COFF Object file header
502 //
503 
504 type
505   ANON_OBJECT_HEADER = record
506     Sig1:          WORD;     // Must be IMAGE_FILE_MACHINE_UNKNOWN
507     Sig2:          WORD;     // Must be $ffff;
508     Version:       WORD;     // >= 1 (implies the CLSID field is present)
509     Machine:       WORD;
510     TimeDateStamp: DWORD;
511     ClassID:       CLSID;    // Used to invoke CoCreateInstance
512     SizeOfData:    DWORD;    // Size of data that follows the header
513   end;
514   TAnonObjectHeader = ANON_OBJECT_HEADER;
515   PAnonObjectHeader = ^TAnonObjectHeader;
516 
517 //
518 // Section header format.
519 //
520 
521 const
522   IMAGE_SIZEOF_SHORT_NAME             = 8;
523 
524 type
525   TISHMisc = record
526     case Boolean of
527       False: (PhysicalAddress: DWORD);
528       True:  (VirtualSize:     DWORD);
529   end;
530 
531   _IMAGE_SECTION_HEADER = record
532     Name: array[0..IMAGE_SIZEOF_SHORT_NAME-1] of BYTE;
533     Misc:                 TISHMisc;
534     VirtualAddress:       DWORD;
535     SizeOfRawData:        DWORD;
536     PointerToRawData:     DWORD;
537     PointerToRelocations: DWORD;
538     PointerToLinenumbers: DWORD;
539     NumberOfRelocations:  WORD;
540     NumberOfLinenumbers:  WORD;
541     Characteristics:      DWORD;
542   end;
543   IMAGE_SECTION_HEADER = _IMAGE_SECTION_HEADER;
544   TImageSectionHeader = _IMAGE_SECTION_HEADER;
545   PImageSectionHeader = ^TImageSectionHeader;
546 
547 const
548   IMAGE_SIZEOF_SECTION_HEADER         = 40;
549 
550 //
551 // Section characteristics.
552 //
553   IMAGE_SCN_TYPE_REG                  = $00000000;  // Reserved.
554   IMAGE_SCN_TYPE_DSECT                = $00000001;  // Reserved.
555   IMAGE_SCN_TYPE_NOLOAD               = $00000002;  // Reserved.
556   IMAGE_SCN_TYPE_GROUP                = $00000004;  // Reserved.
557   IMAGE_SCN_TYPE_NO_PAD               = $00000008;  // Reserved.
558   IMAGE_SCN_TYPE_COPY                 = $00000010;  // Reserved.
559 
560   IMAGE_SCN_CNT_CODE                  = $00000020;  // Section contains code.
561   IMAGE_SCN_CNT_INITIALIZED_DATA      = $00000040;  // Section contains initialized data.
562   IMAGE_SCN_CNT_UNINITIALIZED_DATA    = $00000080;  // Section contains uninitialized data.
563 
564   IMAGE_SCN_LNK_OTHER                 = $00000100;  // Reserved.
565   IMAGE_SCN_LNK_INFO                  = $00000200;  // Section contains comments or some other type of information.
566   IMAGE_SCN_TYPE_OVER                 = $00000400;  // Reserved.
567   IMAGE_SCN_LNK_REMOVE                = $00000800;  // Section contents will not become part of image.
568   IMAGE_SCN_LNK_COMDAT                = $00001000;  // Section contents comdat.
569 //                                          = $00002000;  // Reserved.
570   IMAGE_SCN_MEM_PROTECTED             = $00004000;  // Obsolete
571   IMAGE_SCN_NO_DEFER_SPEC_EXC         = $00004000;  // Reset speculative exceptions handling bits in the TLB entries for this section.
572   IMAGE_SCN_GPREL                     = $00008000;  // Section content can be accessed relative to GP
573   IMAGE_SCN_MEM_FARDATA               = $00008000;
574   IMAGE_SCN_MEM_SYSHEAP               = $00010000;  // Obsolete
575   IMAGE_SCN_MEM_PURGEABLE             = $00020000;
576   IMAGE_SCN_MEM_16BIT                 = $00020000;
577   IMAGE_SCN_MEM_LOCKED                = $00040000;
578   IMAGE_SCN_MEM_PRELOAD               = $00080000;
579 
580   IMAGE_SCN_ALIGN_1BYTES              = $00100000;  //
581   IMAGE_SCN_ALIGN_2BYTES              = $00200000;  //
582   IMAGE_SCN_ALIGN_4BYTES              = $00300000;  //
583   IMAGE_SCN_ALIGN_8BYTES              = $00400000;  //
584   IMAGE_SCN_ALIGN_16BYTES             = $00500000;  // Default alignment if no others are specified.
585   IMAGE_SCN_ALIGN_32BYTES             = $00600000;  //
586   IMAGE_SCN_ALIGN_64BYTES             = $00700000;  //
587   IMAGE_SCN_ALIGN_128BYTES            = $00800000;  //
588   IMAGE_SCN_ALIGN_256BYTES            = $00900000;  //
589   IMAGE_SCN_ALIGN_512BYTES            = $00A00000;  //
590   IMAGE_SCN_ALIGN_1024BYTES           = $00B00000;  //
591   IMAGE_SCN_ALIGN_2048BYTES           = $00C00000;  //
592   IMAGE_SCN_ALIGN_4096BYTES           = $00D00000;  //
593   IMAGE_SCN_ALIGN_8192BYTES           = $00E00000;  //
594 // Unused                                   = $00F00000;
595   IMAGE_SCN_ALIGN_MASK                = $00F00000;
596 
597   IMAGE_SCN_LNK_NRELOC_OVFL           = $01000000;  // Section contains extended relocations.
598   IMAGE_SCN_MEM_DISCARDABLE           = $02000000;  // Section can be discarded.
599   IMAGE_SCN_MEM_NOT_CACHED            = $04000000;  // Section is not cachable.
600   IMAGE_SCN_MEM_NOT_PAGED             = $08000000;  // Section is not pageable.
601   IMAGE_SCN_MEM_SHARED                = $10000000;  // Section is shareable.
602   IMAGE_SCN_MEM_EXECUTE               = $20000000;  // Section is executable.
603   IMAGE_SCN_MEM_READ                  = $40000000;  // Section is readable.
604   IMAGE_SCN_MEM_WRITE                 = $80000000;  // Section is writeable.
605 
606   //
607   // TLS Chaacteristic Flags
608   //
609   IMAGE_SCN_SCALE_INDEX               = $00000001;  // Tls index is scaled
610 
611 {$ifdef fpc}
612 {$packrecords 2}
613 {$endif}
614 
615   //
616   // Symbol format.
617   //
618 type
619   TISName = {$ifndef fpc}packed{$endif} record
620     case Byte of
621       0: (ShortName: array[0..7] of Char);
622       1: (Name: record
623             Short: DWORD;
624             Long:  DWORD;
625           end);
626       2: (LongName: array[0..1] of DWORD)    ;
627   end;
628 
629   _IMAGE_SYMBOL = {$ifndef fpc}packed{$endif} record
630       N:                  TISName;
631       Value:              DWORD;
632       SectionNumber:      SHORT;
633       _Type:              WORD;
634       StorageClass:       BYTE;
635       NumberOfAuxSymbols: BYTE;
636   end;
637   IMAGE_SYMBOL = _IMAGE_SYMBOL;
638   TImageSymbol = _IMAGE_SYMBOL;
639   PImageSymbol = ^TImageSymbol;
640 
641 const
642   IMAGE_SIZEOF_SYMBOL                 = 18;
643 
644   //
645   // Section values.
646   //
647   // Symbols have a section number of the section in which they are
648   // defined. Otherwise, section numbers have the following meanings:
649   //
650 
651   IMAGE_SYM_UNDEFINED           = SHORT(0);          // Symbol is undefined or is common.
652   IMAGE_SYM_ABSOLUTE            = SHORT(-1);         // Symbol is an absolute value.
653   IMAGE_SYM_DEBUG               = SHORT(-2);         // Symbol is a special debug item.
654   IMAGE_SYM_SECTION_MAX         = $FEFF;             // Values = $FF00-= $FFFF are special
655 
656   //
657   // Type (fundamental) values.
658   //
659 
660   IMAGE_SYM_TYPE_NULL       = $0000;  // no type.
661   IMAGE_SYM_TYPE_VOID       = $0001;  //
662   IMAGE_SYM_TYPE_CHAR       = $0002;  // type character.
663   IMAGE_SYM_TYPE_SHORT      = $0003;  // type short integer.
664   IMAGE_SYM_TYPE_INT        = $0004;  //
665   IMAGE_SYM_TYPE_LONG       = $0005;  //
666   IMAGE_SYM_TYPE_FLOAT      = $0006;  //
667   IMAGE_SYM_TYPE_DOUBLE     = $0007;  //
668   IMAGE_SYM_TYPE_STRUCT     = $0008;  //
669   IMAGE_SYM_TYPE_UNION      = $0009;  //
670   IMAGE_SYM_TYPE_ENUM       = $000A;  // enumeration.
671   IMAGE_SYM_TYPE_MOE        = $000B;  // member of enumeration.
672   IMAGE_SYM_TYPE_BYTE       = $000C;  //
673   IMAGE_SYM_TYPE_WORD       = $000D;  //
674   IMAGE_SYM_TYPE_UINT       = $000E;  //
675   IMAGE_SYM_TYPE_DWORD      = $000F;  //
676   IMAGE_SYM_TYPE_PCODE      = $8000;  //
677   //
678   // Type (derived) values.
679   //
680 
681   IMAGE_SYM_DTYPE_NULL      = 0;       // no derived type.
682   IMAGE_SYM_DTYPE_POINTER   = 1;       // pointer.
683   IMAGE_SYM_DTYPE_FUNCTION  = 2;       // function.
684   IMAGE_SYM_DTYPE_ARRAY     = 3;       // array.
685 
686   //
687   // Storage classes.
688   //
689   IMAGE_SYM_CLASS_END_OF_FUNCTION     = High(BYTE);
690   IMAGE_SYM_CLASS_NULL                = $0000;
691   IMAGE_SYM_CLASS_AUTOMATIC           = $0001;
692   IMAGE_SYM_CLASS_EXTERNAL            = $0002;
693   IMAGE_SYM_CLASS_STATIC              = $0003;
694   IMAGE_SYM_CLASS_REGISTER            = $0004;
695   IMAGE_SYM_CLASS_EXTERNAL_DEF        = $0005;
696   IMAGE_SYM_CLASS_LABEL               = $0006;
697   IMAGE_SYM_CLASS_UNDEFINED_LABEL     = $0007;
698   IMAGE_SYM_CLASS_MEMBER_OF_STRUCT    = $0008;
699   IMAGE_SYM_CLASS_ARGUMENT            = $0009;
700   IMAGE_SYM_CLASS_STRUCT_TAG          = $000A;
701   IMAGE_SYM_CLASS_MEMBER_OF_UNION     = $000B;
702   IMAGE_SYM_CLASS_UNION_TAG           = $000C;
703   IMAGE_SYM_CLASS_TYPE_DEFINITION     = $000D;
704   IMAGE_SYM_CLASS_UNDEFINED_STATIC    = $000E;
705   IMAGE_SYM_CLASS_ENUM_TAG            = $000F;
706   IMAGE_SYM_CLASS_MEMBER_OF_ENUM      = $0010;
707   IMAGE_SYM_CLASS_REGISTER_PARAM      = $0011;
708   IMAGE_SYM_CLASS_BIT_FIELD           = $0012;
709 
710   IMAGE_SYM_CLASS_FAR_EXTERNAL        = $0044;  //
711 
712   IMAGE_SYM_CLASS_BLOCK               = $0064;
713   IMAGE_SYM_CLASS_FUNCTION            = $0065;
714   IMAGE_SYM_CLASS_END_OF_STRUCT       = $0066;
715   IMAGE_SYM_CLASS_FILE                = $0067;
716   // new
717   IMAGE_SYM_CLASS_SECTION             = $0068;
718   IMAGE_SYM_CLASS_WEAK_EXTERNAL       = $0069;
719 
720   IMAGE_SYM_CLASS_CLR_TOKEN           = $006B;
721 
722   // type packing constants
723 
724   N_BTMASK = $000F;
725   N_TMASK  = $0030;
726   N_TMASK1 = $00C0;
727   N_TMASK2 = $00F0;
728   N_BTSHFT = 4;
729   N_TSHIFT = 2;
730 
731   // MACROS
732 
733   // Basic Type of  x
BTYPEnull734   function BTYPE(x: Byte): Byte; {$ifdef fpc}inline;{$endif}
735 
736   // Is x a pointer?
ISPTRnull737   function ISPTR(x: Byte): Boolean; {$ifdef fpc}inline;{$endif}
738 
739   // Is x a function?
functionnull740   function ISFCN(x: Byte): Boolean; {$ifdef fpc}inline;{$endif}
741 
742   // Is x an array?
ISARYnull743   function ISARY(x: Byte): Boolean; {$ifdef fpc}inline;{$endif}
744 
745   // Is x a structure, union, or enumeration TAG?
ISTAGnull746   function ISTAG(x: Byte): Boolean; {$ifdef fpc}inline;{$endif}
747 
INCREFnull748   function INCREF(x: Byte): Byte; {$ifdef fpc}inline;{$endif}
749 
DECREFnull750   function DECREF(x: Byte): Byte; {$ifdef fpc}inline;{$endif}
751 
752   //
753   // Auxiliary entry format.
754   //
755 type
756   TIASMisc = record
757     case Byte of
758       0: (
759         Linenumber: WORD;             // declaration line number
760         Size:       WORD;             // size of struct, union, or enum
761       );
762       1: (
763         LnSz: record
764           Linenumber: WORD;             // declaration line number
765           Size:       WORD;             // size of struct, union, or enum
766         end;
767       );
768       2: (TotalSize: DWORD);
769   end;
770 
771   TIASFcnAry = packed record
772     case Byte of
773       0: (
recordnull774         _Function: record               // if ISFCN, tag, or .bb
775           PointerToLinenumber:   DWORD;
DWORDnull776           PointerToNextFunction: DWORD;
777         end;
778       );
779       1: (
780         _Array: packed record                  // if ISARY, up to 4 dimen.
781           Dimension: array[0..3] of WORD;
782         end;
783       );
784   end;
785 
786   _IMAGE_AUX_SYMBOL = record
787     case Byte of
788       0: (
789         Sym: record
790           TagIndex: DWORD;                       // struct, union, or enum tag index
791           Misc:     TIASMisc;
792           FcnAry:   TIASFcnAry;
793           TvIndex:  WORD;                        // tv index
794         end;
795       );
796       1: (
797         _File: record
798           Name: array[0..IMAGE_SIZEOF_SYMBOL-1] of BYTE;
799         end;
800       );
801       2: (
802         Section: record
803           Length:              DWORD;              // section length
804           NumberOfRelocations: WORD;               // number of relocation entries
805           NumberOfLinenumbers: WORD;               // number of line numbers
806           CheckSum:            DWORD;              // checksum for communal
807           Number:              SHORT;              // section number to associate with
808           Selection:           BYTE;               // communal selection type
809         end;
810       );
811   end;
812   IMAGE_AUX_SYMBOL = _IMAGE_AUX_SYMBOL;
813   TImageAuxSymbol = _IMAGE_AUX_SYMBOL;
814   PImageAuxSymbol = ^TImageAuxSymbol;
815 
816 
817 const
818   IMAGE_SIZEOF_AUX_SYMBOL             = 18;
819 
820 type
821   IMAGE_AUX_SYMBOL_TYPE = (
822     IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1
823   );
824   TImageAuxSymbolType = IMAGE_AUX_SYMBOL_TYPE;
825 
826   {$ifdef fpc}{$packRecords 2}{$endif}
827 
828 type
829   IMAGE_AUX_SYMBOL_TOKEN_DEF = packed record
830     bAuxType:         BYTE;           // IMAGE_AUX_SYMBOL_TYPE
831     bReserved:        BYTE;           // Must be 0
832     SymbolTableIndex: DWORD;
833     rgbReserved: array [0..11] of BYTE;           // Must be 0
834   end;
835   TImageAuxSymbolTokenDef = IMAGE_AUX_SYMBOL_TOKEN_DEF;
836   PImageAuxSymbolTokenDef = ^TImageAuxSymbolTokenDef;
837 
838 {$ifdef fpc}{$packRecords 2}{$endif}
839 
840 implementation
841 
BTYPEnull842 function BTYPE(x: Byte): Byte; {$ifdef fpc}inline;{$endif}
843 begin
844   Result := x and N_BTMASK;
845 end;
846 
ISPTRnull847 function ISPTR(x: Byte): Boolean; {$ifdef fpc}inline;{$endif}
848 begin
849   Result := (x and N_TMASK) = (IMAGE_SYM_DTYPE_POINTER shl N_BTSHFT);
850 end;
851 
ISFCNnull852 function ISFCN(x: Byte): Boolean; {$ifdef fpc}inline;{$endif}
853 begin
shlnull854   Result := (x and N_TMASK) = (IMAGE_SYM_DTYPE_FUNCTION shl N_BTSHFT);
855 end;
856 
ISARYnull857 function ISARY(x: Byte): Boolean; {$ifdef fpc}inline;{$endif}
858 begin
859   Result := (x and N_TMASK) = (IMAGE_SYM_DTYPE_ARRAY shl N_BTSHFT);
860 end;
861 
ISTAGnull862 function ISTAG(x: Byte): Boolean; {$ifdef fpc}inline;{$endif}
863 begin
864   Result := (x = IMAGE_SYM_CLASS_STRUCT_TAG) or (x = IMAGE_SYM_CLASS_UNION_TAG) or (x = IMAGE_SYM_CLASS_ENUM_TAG);
865 end;
866 
INCREFnull867 function INCREF(x: Byte): Byte; {$ifdef fpc}inline;{$endif}
868 begin
869   Result := ((x and not N_BTMASK) shl N_TSHIFT) or (IMAGE_SYM_DTYPE_POINTER shl N_BTSHFT) or (x and N_BTMASK);
870 end;
871 
DECREFnull872 function DECREF(x: Byte): Byte; {$ifdef fpc}inline;{$endif}
873 begin
874   Result := ((x shr N_TSHIFT) and not N_BTMASK) or (x and N_BTMASK);
875 end;
876 
877 
878 end.
879