This contains informative text only. |
The file format for CLI components is a strict extension of the current Portable Executable (PE) file format. This extended PE format enables the operating system to recognize runtime images, accommodates code emitted as CIL or native code, and accommodates runtime metadata as an integral part of the emitted code. There are also specifications for a subset of the full Windows PE/COFF file format, in sufficient detail that a tool or compiler can use the specifications to emit valid CLI images. The PE format frequently uses the term RVA (Relative Virtual Address). An RVA is the address of an item once loaded into memory, with the base address of the image file subtracted from it (i.e., the offset from the base address where the file is loaded). The RVA of an item will almost always differ from its position within the file on disk. To compute the file position of an item with RVA r, search all the sections in the PE file to find the section with RVA s, length l, and file position p in which the RVA lies i.e., s s+l. The file position of the item is then given by p+(r s). Unless stated otherwise, all binary values are stored in little-endian format. 24.1 Structure of the Runtime File Format The figure below provides a high-level view of the CLI file format. All runtime images contain the following: PE headers, with specific guidelines on how field values should be set in a runtime file. A CLI header that contains all of the runtime-specific data entries. The runtime header is read-only and shall be placed in any read-only section. The sections that contain the actual data as described by the headers, including imports/exports, data, and code. The CLI header (see Partition II, section 24.3.3) is found using the "CLI Header" directory entry in the PE header. The CLI header in turn contains the address and sizes of the runtime data (metadata, see Partition II, section 23; and CIL, see Partition II, section 24.4) in the rest of the image. Note that the runtime data can be merged into other areas of the PE format with the other data based on the attributes of the sections (such as read-only versus execute, etc.). 24.2 PE Headers A PE image starts with an MS-DOS header followed by a PE signature, followed by the PE file header, and then the PE optional header followed by PE section headers. ANNOTATION Many of the entries in the tables in this whole section 24 are prescribed, and certain values are required. In some cases, the value is 0, or marked "to be ignored," in which case it is not relevant to managed code. If you write the values specified, a PE file so created will run. Great care has been taken to ensure the accuracy of these values. Some errors have been found and corrected, but so far, all errors are in the direction of a differing value not causing a problem. In general, if you write what we tell you, it will run. |
24.2.1 MS-DOS Header The PE format starts with an MS-DOS stub of exactly the following 128 bytes to be placed at the front of the module. At offset 0x3c in the DOS header is a 4-byte unsigned integer, offset lfanew to the PE signature (shall be "PE\0\0"), immediately followed by the PE file header. 0x4d | 0x5a | 0x90 | 0x00 | 0x03 | 0x00 | 0x00 | 0x00 | 0x04 | 0x00 | 0x00 | 0x00 | 0xFF | 0xFF | 0x00 | 0x00 | 0xb8 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x40 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | lfanew | 0x0e | 0x1f | 0xba | 0x0e | 0x00 | 0xb4 | 0x09 | 0xcd | 0x21 | 0xb8 | 0x01 | 0x4c | 0xcd | 0x21 | 0x54 | 0x68 | 0x69 | 0x73 | 0x20 | 0x70 | 0x72 | 0x6f | 0x67 | 0x72 | 0x61 | 0x6d | 0x20 | 0x63 | 0x61 | 0x6e | 0x6e | 0x6f | 0x74 | 0x20 | 0x62 | 0x65 | 0x20 | 0x72 | 0x75 | 0x6e | 0x20 | 0x69 | 0x6e | 0x20 | 0x44 | 0x4f | 0x53 | 0x20 | 0x6d | 0x6f | 0x64 | 0x65 | 0x2e | 0x0d | 0x0d | 0x0a | 0x24 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 24.2.2 PE File Header Immediately after the PE signature is the PE file header consisting of the following: Offset | Size | Field | Description |
---|
0 | 2 | Machine | Always 0x14c | 2 | 2 | Number of Sections | Number of sections; indicates size of the section table, which immediately follows the headers. | 4 | 4 | Time/Date Stamp | Time and date the file was created in seconds since January 1st 1970 00:00:00 or 0. | 8 | 4 | Pointer to Symbol Table | Always 0 | 12 | 4 | Number of Symbols | Always 0 | 16 | 2 | Optional Header Size | Size of the optional header; the format is described below. | 18 | 2 | Characteristics | Flags indicating attributes of the file, see section 24.2.2.1. | ANNOTATION Notice that Pointer to Symbol Table and Number of Symbols are always 0. These symbol tables are for unmanaged code and data. |
24.2.2.1 Characteristics A CIL-only DLL sets flag 0x2000 to 1, while a CIL-only .exe has flag 0x2000 set to zero: Flag | Value | Description |
---|
IMAGE_FILE_DLL | 0x2000 | The image file is a dynamic-link library (DLL). | Except for the IMAGE_FILE_DLL flag (0x2000), flags 0x0002, 0x0004, 0x008, and 0x0100 shall all be set, while all others shall always be zero. ANNOTATION The value of the characteristics field shall be either 0x210D or 0x10D. |
24.2.3 PE Optional Header Immediately after the PE header is the PE optional header. This header contains the following information: Offset | Size | Header Part | Description |
---|
0 | 28 | Standard fields | These define general properties of the PE file, see Partition II, section 24.2.3.1. | 28 | 68 | NT-specific fields | These include additional fields to support specific features of Windows, see Partition II, section 24.2.3.2. | 96 | 128 | Data directories | These fields are address/size pairs for special tables, found in the image file (for example, Import Table and Export Table). | 24.2.3.1 PE Header Standard Fields These fields are required for all PE files and contain the following information: Offset | Size | Field | Description |
---|
| | | | 0 | 2 | Magic | Always 0x10B | 2 | 1 | LMajor | Always 6 | 3 | 1 | LMinor | Always 0 | 4 | 4 | Code Size | Size of the code (text) section, or the sum of all code sections if there are multiple sections. | 8 | 4 | Initialized Data Size | Size of the initialized data section, or the sum of all such sections if there are multiple data sections. | 12 | 4 | Uninitialized Data Size | Size of the uninitialized data section, or the sum of all such sections if there are multiple uninitialized data sections. | 16 | 4 | Entry Point RVA | RVA of entry point; needs to point to bytes 0xFF25 followed by the RVA in a section marked execute/read for EXEs or 0 for DLLs. | 20 | 4 | Base Of Code | RVA of the code section, always 0x00400000 for EXEs and 0x10000000 for DLLs. | 24 | 4 | Base Of Data | RVA of the data section. | ANNOTATION The first three values in this table must be as specified here, or the file is invalid. Managed code always starts at a given entry point within the file mscoree.dll. See Chapter 4 of this book for an example. |
This contains informative text only. |
The entry point RVA shall always be either the x86 entry point stub or 0. On non-CLI-aware platforms, this stub will call the entry point API of mscoree (_CorExeMain or _CorDllMain). The mscoree entry point will use the module handle to load the metadata from the image, and invoke the entry point specified in the CLI header. 24.2.3.2 PE Header Windows NT Specific Fields These fields are Windows NT specific: Offset | Size | Field | Description |
---|
28 | 4 | Image Base | Always 0x400000. | 32 | 4 | Section Alignment | Always 0x2000. | 36 | 4 | File Alignment | Either 0x200 or 0x1000. | 40 | 2 | OS Major | Always 4. | 42 | 2 | OS Minor | Always 0. | 44 | 2 | User Major | Always 0. | 46 | 2 | User Minor | Always 0. | 48 | 2 | SubSys Major | Always 4. | 50 | 2 | SubSys Minor | Always 0. | 52 | 4 | Reserved | Always 0. | 56 | 4 | Image Size | Size, in bytes, of image, including all headers and padding; shall be a multiple of Section Alignment. | 60 | 4 | Header Size | Combined size of MS-DOS header, PE header, PE optional header and padding; shall be a multiple of the file alignment. | 64 | 4 | File Checksum | Always 0. | 68 | 2 | SubSystem | Subsystem required to run this image. Shall be either IMAGE_SUBSYSTEM_WINDOWS_CE_GUI (0x3) or IMAGE_SUBSYSTEM_WINDOWS_GUI (0x2). | 70 | 2 | DLL Flags | Always 0. | 72 | 4 | Stack Reserve Size | Always 0x100000 (1Mb). | 76 | 4 | Stack Commit Size | Always 0x1000 (4Kb). | 80 | 4 | Heap Reserve Size | Always 0x100000 (1Mb). | 84 | 4 | Heap Commit Size | Always 0x1000 (4Kb). | 88 | 4 | Loader Flags | Always 0. | 92 | 4 | Number of Data Directories | Always 0x10. | ANNOTATION The specified values are standard values that work, and should continue to work in the future. Setting other values removes the guarantee that they will work, although alternative values may also work on some operating systems. The number of data directories is set at 0x10, and the last of these is the data directory that contains the IL metadata pointer. |
24.2.3.3 PE Header Data Directories The optional header data directories give the address and size of several tables that appear in the sections of the PE file. Each data directory entry contains the RVA and Size of the structure it describes. Offset | Size | Field | Description |
---|
96 | 8 | Export Table | Always 0. | 104 | 8 | Import Table | RVA of Import Table (see Partition II, section 24.3.1). | 112 | 8 | Resource Table | Always 0. | 120 | 8 | Exception Table | Always 0. | 128 | 8 | Certificate Table | Always 0. | 136 | 8 | Base Relocation Table | Relocation Table; set to 0 if unused (see Partition II, section 24.3.2). | 144 | 8 | Debug | Always 0. | 152 | 8 | Copyright | Always 0. | 160 | 8 | Global Ptr | Always 0. | 168 | 8 | TLS Table | Always 0. | 176 | 8 | Load Config Table | Always 0. | 184 | 8 | Bound Import | Always 0. | 192 | 8 | IAT | RVA of Import Address Table (see Partition II, section 24.3.1). | 200 | 8 | Delay Import Descriptor | Always 0. | 208 | 8 | CLI Header | CLI header with directories for runtime data, (see Partition II, section 24.3.3). | 216 | 8 | Reserved | Always 0. | The tables pointed to by the directory entries are stored in one of the PE file's sections; these sections themselves are described by section headers. ANNOTATION The CLI header, if present and non-zero, always indicates that the file contains managed code. It specifies where the metadata information is. |
24.3 Section Headers Immediately following the optional header is the section table, which contains a number of section headers. This positioning is required because the file header does not contain a direct pointer to the section table; the location of the section table is determined by calculating the location of the first byte after the headers. Each section header has the following format, for a total of 40 bytes per entry: Offset | Size | Field | Description |
---|
0 | 8 | Name | An 8-byte, null-padded ASCII string. There is no terminating null if the string is exactly eight characters long. | 8 | 4 | VirtualSize | Total size of the section when loaded into memory in bytes rounded to Section Alignment. If this value is greater than SizeofRawData, the section is zero-padded. | 12 | 4 | VirtualAddress | For executable images this is the address of the first byte of the section, when loaded into memory, relative to the image base. | 16 | 4 | SizeOfRawData | Size of the initialized data on disk in bytes; shall be a multiple of File Alignment from the PE header. If this is less than VirtualSize, the remainder of the section is zero-filled. Because this field is rounded while the VirtualSize field is not, it is possible for this to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be 0. | 20 | 4 | PointerToRawData | Offset of section's first page within the PE file. This shall be a multiple of File Alignment from the optional header. When a section contains only uninitialized data, this field should be 0. | 24 | 4 | PointerToRelocations | RVA of Relocation section [see Partition II, section 24.3.2]. | 28 | 4 | PointerToLinenumbers | Always 0. | 32 | 2 | NumberOfRelocations | Number of relocations, set to 0 if unused. | 34 | 2 | NumberOfLinenumbers | Always 0. | 36 | 4 | Characteristics | Flags describing section's characteristics; see below. | The following table defines the possible characteristics of the section. Flag | Value | Description |
---|
IMAGE_SCN_CNT_CODE | 0x00000020 | Section contains executable code. | IMAGE_SCN_CNT_INITIALIZED_DATA | 0x00000040 | Section contains initialized data. | IMAGE_SCN_CNT_UNINITIALIZED_DATA | 0x00000080 | Section contains uninitialized data. | IMAGE_SCN_MEM_EXECUTE | 0x20000000 | Section can be executed as code. | IMAGE_SCN_MEM_READ | 0x40000000 | Section can be read. | IMAGE_SCN_MEM_WRITE | 0x80000000 | Section can be written to. | 24.3.1 Import Table and Import Address Table (IAT) The Import Table and the Import Address Table (IAT) are used to import the _CorExeMain (for a .exe) or _CorDllMain (for a .dll) entries of the runtime engine (mscoree.dll). The Import Table directory entry points to a one-element, zero-terminated array of Import Directory entries (in a general PE file there is one entry for each imported DLL): Offset | Size | Field | Description |
---|
0 | 4 | ImportLookupTable | RVA of the Import Lookup Table. | 4 | 4 | DateTimeStamp | Always 0. | 8 | 4 | ForwarderChain | Always 0. | 12 | 4 | Name | RVA of null-terminated ASCII string "mscoree.dll". | 16 | 4 | ImportAddressTable | RVA of Import Address Table (this is the same as the RVA of the IAT descriptor in the optional header). | 20 | 20 | | End of Import Table; shall be filled with zeros. | The Import Lookup Table and the Import Address Table (IAT) are both one-element, zero-terminated arrays of RVAs into the Hint/Name table. Bit 31 of the RVA shall be set to 0. In a general PE file there is one entry in this table for every imported symbol. Offset | Size | Field | Description |
---|
0 | 4 | Hint/Name Table RVA | A 31-bit RVA into the Hint/Name table. Bit 31 shall be set to 0, indicating import by name. | 4 | 4 | | End of table; shall be filled with zeros. | The IAT should be in an executable and writable section, as the loader will replace the pointers into the Hint/Name table by the actual entry points of the imported symbols. The Hint/Name table contains the name of the dll entry that is imported. Offset | Size | Field | Description |
---|
0 | 2 | Hint | Shall be 0. | 2 | variable | Name | Case-sensitive, null-terminated ASCII string containing name to import. Shall be "_CorExeMain" for a .exe file and "_CorDllMain" for a .dll file. | ANNOTATION In short, the previous section is saying that for managed code, the Import Table (the first table in this section) imports only the single file mscoree.dll, which executes the VES software. The Import Address Table (IAT) then says which routine to run. If your PE file is a .exe file, it must be _CorExeMain; if it is a .dll, it must be _CorDllMain. From the point of view of the operating system, it loads mscoree.dll, calls one of the two routines, and stops. From the point of view of the VES, the call to one of those two routines is where the managed code starts running. When the managed code finishes executing the program and returns, it hands off to the operating system. |
24.3.2 Relocations In a pure CIL image, a single fixup of type IMAGE_REL_BASED_HIGHLOW (0x3) is required for the x86 startup stub which accesses the IAT to load the runtime engine on down-level loaders. When building a mixed CIL/native image or when the image contains embedded RVAs in user data, the relocation section contains relocations for these as well. The relocations shall be in their own section, named ".reloc", which shall be the final section in the PE file. The relocation section contains a fixup table. The fixup table is broken into blocks of fixups. Each block represents the fixups for a 4K page, and each block shall start on a 32-bit boundary. Each fixup block starts with the following structure: Offset | Size | Field | Description |
---|
0 | 4 | PageRVA | The RVA of the block in which the fixup needs to be applied. The low 12 bits shall be zero. | 4 | 4 | Block Size | Total number of bytes in the fixup block, including the PageRVA and Block Size fields, as well as the Type/Offset fields that follow, rounded up to the next multiple of 4. | The Block Size field is then followed by (BlockSize 8)/2 Type/Offset. Each entry is a word (2 bytes) and has the following structure (if necessary, insert 2 bytes of 0 to pad to a multiple of 4 bytes in length): Offset | Size | Field | Description |
---|
0 | 4 bits | Type | Stored in high 4 bits of word. Value indicating which type of fixup is to be applied (described below). | 0 | 12 bits | Offset | Stored in remaining 12 bits of word. Offset from starting address specified in the PageRVA field for the block. This offset specifies where the fixup is to be applied. | 24.3.3 CLI Header The CLI header contains all of the runtime-specific data entries and other information. The header should be placed in a read-only, sharable section of the image. This header is defined as follows: Offset | Size | Field | Description |
---|
0 | 4 | Cb | Size of the header in bytes. | 4 | 2 | MajorRuntimeVersion | The minimum version of the runtime required to run this program, currently 2. | 6 | 2 | MinorRuntimeVersion | The minor portion of the version, currently 0. | 8 | 8 | MetaData | RVA and size of the physical metadata (see Partition II, section 23). | 16 | 4 | Flags | Flags describing this runtime image. (see Partition II, section 24.3.3.1). | 20 | 4 | EntryPointToken | Token for the MethodDef or File of the entry point for the image. | 24 | 8 | Resources | Location of CLI resources (see Partition V). | 32 | 8 | StrongNameSignature | RVA of the hash data for this PE file used by the CLI loader for binding and versioning, | 40 | 8 | CodeManagerTable | Always 0. | 48 | 8 | VTableFixups | RVA of an array of locations in the file that contain an array of function pointers (e.g., vtable slots); see below. | 56 | 8 | ExportAddressTableJumps | Always 0. | 64 | 8 | ManagedNativeHeader | Always 0. | ANNOTATION The CLI header is what distinguishes a managed executable file. It is through this header that the metadata of the image is located. |
24.3.3.1 Runtime Flags The following flags describe this runtime image and are used by the loader. Flag | Value | Description |
---|
COMIMAGE_FLAGS_ILONLY | 0x00000001 | Always 1. | COMIMAGE_FLAGS_32BITREQUIRED | 0x00000002 | Image may only be loaded into a 32-bit process for instance, if there are 32-bit vtable fixups, or casts from native integers to int32. CLI implementations that have 64-bit native integers shall refuse loading binaries with this flag set. | COMIMAGE_FLAGS_STRONGNAMESIGNED | 0x00000008 | Image has a strong name signature. | COMIMAGE_FLAGS_TRACKDEBUGDATA | 0x00010000 | Always 0. | 24.3.3.2 Entry Point Metadata Token The entry point token (see Partition II, section 14.4.1.2) is always a MethodDef token (see Partition II, section 21.24) or File token (see Partition II, section 21.19) when the entry point for a multi-module assembly is not in the manifest assembly. The signature and implementation flags in metadata for the method indicate how the entry is run. ANNOTATION If you have a managed entry point, the entry point token is either the method that is the entry point, or if the entry point method is in another file in the assembly, a file token for that file. That file must have the entry point. For more information, see Partition II, section 14.4.1.2, on the ilasm .entrypoint directive. Do not confuse the EntryPointToken with the Entry Point RVA in the CLI header portion of the PE file, which tells the operating system to load the mscoree.dll file, which loads the VES. |
24.3.3.3 Vtable Fixup Certain languages, which choose not to follow the common type system runtime model, may have virtual functions which need to be represented in a vtable. These vtables are laid out by the compiler, not by the runtime. Finding the correct vtable slot and calling indirectly through the value held in that slot is also done by the compiler. The VtableFixups field in the runtime header contains the location and size of an array of vtable fixups (see Partition II, section 14.5.1). Vtables shall be emitted into a read-write section of the PE file. Each entry in this array describes a contiguous array of vtable slots of the specified size. Each slot starts out initialized to the metadata token value for the method they need to call. At image load time, the runtime loader will turn each entry into a pointer to machine code for the CPU and can be called directly. Offset | Size | Field | Description |
---|
0 | 4 | VirtualAddress | RVA of Vtable | 4 | 2 | Size | Number of entries in Vtable | 6 | 2 | Type | Type of the entries, as defined in table below | Constant | Value | Description |
---|
COR_VTABLE_32BIT | 0x01 | Vtable slots are 32 bits. | COR_VTABLE_64BIT | 0x02 | Vtable slots are 64 bits. | COR_VTABLE_FROM_UNMANAGED | 0x04 | Transition from unmanaged to managed code. | COR_VTABLE_CALL_MOST_DERIVED | 0x10 | Call most derived method described by the token (only valid for virtual methods). | 24.3.3.4 Strong Name Signature This header entry points to the strong name hash for an image that can be used to deterministically identify a module from a referencing point (see Partition II, section 6.2.1.3). 24.4 Common Intermediate Language Physical Layout This section contains the layout of the data structures used to describe a CIL method and its exceptions. Method bodies can be stored in any read-only section of a PE file. The MethodDef (see Partition II, section 21.24) records in metadata carry each method's RVA. A method consists of a method header immediately followed by the method body, possible followed by extra method data sections (see Partition II, section 24.4.5), typically exception handling data. If exception handling data is present, then the CorILMethod_MoreSects flag (see Partition II, section 24.4.4) shall be specified in the method header and for each chained item after that. There are two flavors of method headers tiny (see Partition II, section 24.4.2) and fat (see Partition II, section 24.4.3). The three least significant bits in a method header indicate which type is present (see Partition II, section 24.4.1). The tiny header is 1 byte long and represents only the method's code size. A method is given a tiny header if it has no local variables, maxstack is 8 or less, the method has no exceptions, the method size is less than 64 bytes, and the method has no flags above 0x7. Fat headers carry full information local vars signature token, maxstack, code size, flag. Method headers shall be 4-byte aligned. 24.4.1 Method Header Type Values The three least significant bits of the first byte of the method header indicate what type of header is present. These 3 bits will be one, and only one, of the following: Value | Value | Description |
---|
CorILMethod_TinyFormat | 0x2 | The method header is tiny (see Partition II, section 24.4.2). | CorILMethod_FatFormat | 0x3 | The method header is fat (see Partition II, section 24.4.3). | 24.4.2 Tiny Format Tiny headers use a 5-bit length encoding. The following is true for all tiny headers: The first encoding has the following format: Start Bit | Count of Bits | Description |
---|
0 | 2 | Flags (CorILMethod_TinyFormat shall be set; see Partition II, section 24.4.4). | 2 | 6 | Size of the method body immediately following this header. Used only when the size of the method is less than 26 bytes. | 24.4.3 Fat Format The fat format is used whenever the tiny format is not sufficient. This may be true for one or more of the following reasons: The method is too large to encode the size. There are exceptions. There are extra data sections. There are local variables. The operand stack needs more than eight entries. A fat header has the following structure: Offset | Size | Field | Description |
---|
0 | 12 (bits) | Flags | Flags (CorILMethod_FatFormat shall be set; see Partition II, section 24.4.4). | 12 (bits) | 4 (bits) | Size | Size of this header expressed as the count of 4-byte integers occupied. | 2 | 2 | MaxStack | Maximum number of items on the operand stack. | 4 | 4 | CodeSize | Size in bytes of the actual method body. | 8 | 4 | LocalVarSigTok | Metadata token for a signature describing the layout of the local variables for the method. 0 means there are no local variables present. | 24.4.4 Flags for Method Headers The first byte of a method header may also contain the following flags, valid only for the fat format, that indicate how the method is to be executed: Flag | Value | Description |
---|
CorILMethod_FatFormat | 0x3 | Method header is fat. | CorILMethod_TinyFormat | 0x2 | Method header is tiny. | CorILMethod_MoreSects | 0x8 | More sections follow after this header (see Partition II, section 24.4.5). | CorILMethod_InitLocals | 0x10 | Call default constructor on all local variables. | 24.4.5 Method Data Section At the next 4-byte boundary following the method body can be extra method data sections. These method data sections start with a 2-byte header (1 byte for flags, 1 byte for the length of the actual data) or a 4-byte header (1 byte for flags, and 3 bytes for length of the actual data). The first byte determines the kind of the header, and what data is in the actual section: Flag | Value | Description |
---|
CorILMethod_Sect_EHTable | 0x1 | Exception handling data. | CorILMethod_Sect_OptILTable | 0x2 | Reserved, shall be 0. | CorILMethod_Sect_FatFormat | 0x40 | Data format is of the fat variety, meaning there is a 3-byte length. If not set, the header is small, with a 1-byte length. | CorILMethod_Sect_MoreSects | 0x80 | Another data section occurs after this current section. | Currently, the method data sections are only used for exception tables (see Partition II, section 18). The layout of a small exception header structure as is a follows: Offset | Size | Field | Description |
---|
0 | 1 | Kind | Flags as described above. | 1 | 1 | DataSize | Size of the data for the block, including the header say, n*12+4. | 2 | 2 | Reserved | Padding, always 0. | 4 | n | Clauses | n small exception clauses (see Partition II, section 24.4.6). | The layout of a fat exception header structure is as follows: Offset | Size | Field | Description |
---|
0 | 1 | Kind | Which type of exception block is being used | 1 | 3 | DataSize | Size of the data for the block, including the header say, n*24+4. | 4 | n | Clauses | n fat exception clauses (see Partition II, section 24.4.6). | 24.4.6 Exception Handling Clauses Exception handling clauses also come in small and fat versions. The small form of the exception clause should be used whenever the code size for the try block and handler code is smaller than or equal to 256 bytes. The format for a small exception clause is as follows: Offset | Size | Field | Description |
---|
0 | 2 | Flags | Flags; see below | 2 | 2 | TryOffset | Offset in bytes of try block from start of the header | 4 | 1 | TryLength | Length in bytes of the try block | 5 | 2 | HandlerOffset | Location of the handler for this try block | 7 | 1 | HandlerLength | Size of the handler code in bytes | 8 | 4 | ClassToken | Metadata token for a type-based exception handler | 8 | 4 | FilterOffset | Offset in method body for filter-based exception handler | The layout of fat form of exception handling clauses is as follows: Offset | Size | Field | Description |
---|
| | | | 0 | 4 | Flags | Flags; see below | 4 | 4 | TryOffset | Offset in bytes of try block from start of the header | 8 | 4 | TryLength | Length in bytes of the try block | 12 | 4 | HandlerOffset | Location of the handler for this try block | 16 | 4 | HandlerLength | Size of the handler code in bytes | 20 | 4 | ClassToken | Metadata token for a type-based exception handler | 20 | 4 | FilterOffset | Offset in method body for filter-based exception handler | The following flag values are used for each exception handling clause: Flag | Value | Description |
---|
COR_ILEXCEPTION_CLAUSE_EXCEPTION | 0x0000 | A typed exception clause | COR_ILEXCEPTION_CLAUSE_FILTER | 0x0001 | An exception filter and handler clause | COR_ILEXCEPTION_CLAUSE_FINALLY | 0x0002 | A finally clause | COR_ILEXCEPTION_CLAUSE_FAULT | 0x0004 | Fault clause (finally [clause] that is called on exception only) | |