| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | // -------------------------------------------------------------------------------- |
| 5 | // PEDecoder.h |
| 6 | // |
| 7 | |
| 8 | // -------------------------------------------------------------------------------- |
| 9 | |
| 10 | // -------------------------------------------------------------------------------- |
| 11 | // PEDecoder - Utility class for reading and verifying PE files. |
| 12 | // |
| 13 | // Note that the Check step is optional if you are willing to trust the |
| 14 | // integrity of the image. |
| 15 | // (Or at any rate can be factored into an initial verification step.) |
| 16 | // |
| 17 | // Functions which access the memory of the PE file take a "flat" flag - this |
| 18 | // indicates whether the PE images data has been loaded flat the way it resides in the file, |
| 19 | // or if the sections have been mapped into memory at the proper base addresses. |
| 20 | // |
| 21 | // Finally, some functions take an optional "size" argument, which can be used for |
| 22 | // range verification. This is an optional parameter, but if you omit it be sure |
| 23 | // you verify the size in some other way. |
| 24 | // -------------------------------------------------------------------------------- |
| 25 | |
| 26 | |
| 27 | #ifndef PEDECODER_H_ |
| 28 | #define PEDECODER_H_ |
| 29 | |
| 30 | // -------------------------------------------------------------------------------- |
| 31 | // Required headers |
| 32 | // -------------------------------------------------------------------------------- |
| 33 | |
| 34 | #include "windows.h" |
| 35 | #include "clrtypes.h" |
| 36 | #include "check.h" |
| 37 | #include "contract.h" |
| 38 | #include "cor.h" |
| 39 | #include "corhdr.h" |
| 40 | |
| 41 | #ifdef FEATURE_PREJIT |
| 42 | #include "corcompile.h" |
| 43 | #else // FEATURE_PREJIT |
| 44 | typedef DPTR(struct COR_ILMETHOD) PTR_COR_ILMETHOD; |
| 45 | struct CORCOMPILE_HEADER { int dummy_field; }; |
| 46 | typedef DPTR(struct CORCOMPILE_HEADER) PTR_CORCOMPILE_HEADER; |
| 47 | #define CORCOMPILE_IS_POINTER_TAGGED(fixup) (false) |
| 48 | #endif // FEATURE_PREJIT |
| 49 | |
| 50 | #include "readytorun.h" |
| 51 | typedef DPTR(struct READYTORUN_HEADER) ; |
| 52 | |
| 53 | typedef DPTR(IMAGE_COR20_HEADER) ; |
| 54 | |
| 55 | // -------------------------------------------------------------------------------- |
| 56 | // Forward declared types |
| 57 | // -------------------------------------------------------------------------------- |
| 58 | |
| 59 | class Module; |
| 60 | |
| 61 | // -------------------------------------------------------------------------------- |
| 62 | // RVA definition |
| 63 | // -------------------------------------------------------------------------------- |
| 64 | |
| 65 | // Needs to be DWORD to avoid conflict with <imagehlp.h> |
| 66 | typedef DWORD RVA; |
| 67 | |
| 68 | #ifdef _MSC_VER |
| 69 | // Wrapper to suppress ambigous overload problems with MSVC. |
| 70 | inline CHECK CheckOverflow(RVA value1, COUNT_T value2) |
| 71 | { |
| 72 | WRAPPER_NO_CONTRACT; |
| 73 | CHECK(CheckOverflow((UINT32) value1, (UINT32) value2)); |
| 74 | CHECK_OK; |
| 75 | } |
| 76 | #endif // _MSC_VER |
| 77 | |
| 78 | // -------------------------------------------------------------------------------- |
| 79 | // IMAGE_FILE_MACHINE_NATIVE |
| 80 | // -------------------------------------------------------------------------------- |
| 81 | |
| 82 | #if defined(_TARGET_X86_) |
| 83 | #define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_I386 |
| 84 | #elif defined(_TARGET_AMD64_) |
| 85 | #define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_AMD64 |
| 86 | #elif defined(_TARGET_ARM_) |
| 87 | #define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_ARMNT |
| 88 | #elif defined(_TARGET_ARM64_) |
| 89 | #define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_ARM64 |
| 90 | #else |
| 91 | #error "port me" |
| 92 | #endif |
| 93 | |
| 94 | // Machine code for native images |
| 95 | #if defined(__APPLE__) |
| 96 | #define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0x4644 |
| 97 | #elif defined(__FreeBSD__) |
| 98 | #define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0xADC4 |
| 99 | #elif defined(__linux__) |
| 100 | #define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0x7B79 |
| 101 | #elif defined(__NetBSD__) |
| 102 | #define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0x1993 |
| 103 | #else |
| 104 | #define IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE 0 |
| 105 | #endif |
| 106 | |
| 107 | #define IMAGE_FILE_MACHINE_NATIVE_NI (IMAGE_FILE_MACHINE_NATIVE ^ IMAGE_FILE_MACHINE_NATIVE_OS_OVERRIDE) |
| 108 | |
| 109 | // -------------------------------------------------------------------------------- |
| 110 | // Types |
| 111 | // -------------------------------------------------------------------------------- |
| 112 | |
| 113 | typedef DPTR(class PEDecoder) PTR_PEDecoder; |
| 114 | |
| 115 | class PEDecoder |
| 116 | { |
| 117 | public: |
| 118 | |
| 119 | // ------------------------------------------------------------ |
| 120 | // Public API |
| 121 | // ------------------------------------------------------------ |
| 122 | |
| 123 | // Access functions are divided into 3 categories: |
| 124 | // Has - check if the element is present |
| 125 | // Check - Do consistency checks on the element (requires Has). |
| 126 | // This step is optional if you are willing to trust the integrity of the |
| 127 | // image. (It is asserted in a checked build.) |
| 128 | // Get - Access the element (requires Has and Check) |
| 129 | |
| 130 | PEDecoder(); |
| 131 | PEDecoder(void *flatBase, COUNT_T size); // flatBase is the raw disk layout data (using MapViewOfFile) |
| 132 | PEDecoder(PTR_VOID mappedBase, bool relocated = FALSE); // mappedBase is the mapped/expanded file (using LoadLibrary) |
| 133 | |
| 134 | void Init(void *flatBase, COUNT_T size); |
| 135 | HRESULT Init(void *mappedBase, bool relocated = FALSE); |
| 136 | void Reset(); //make sure you don't have a thread race |
| 137 | |
| 138 | PTR_VOID GetBase() const; // Currently loaded base, as opposed to GetPreferredBase() |
| 139 | BOOL IsMapped() const; |
| 140 | BOOL IsRelocated() const; |
| 141 | BOOL IsFlat() const; |
| 142 | BOOL HasContents() const; |
| 143 | COUNT_T GetSize() const; // size of file on disk, as opposed to GetVirtualSize() |
| 144 | |
| 145 | // High level image checks: |
| 146 | |
| 147 | CHECK CheckFormat() const; // Check whatever is present |
| 148 | CHECK CheckNTFormat() const; // Check a PE file image |
| 149 | CHECK CheckCORFormat() const; // Check a COR image (IL or native) |
| 150 | CHECK CheckILFormat() const; // Check a managed image |
| 151 | CHECK CheckILOnlyFormat() const; // Check an IL only image |
| 152 | CHECK CheckNativeFormat() const; // Check a native image |
| 153 | |
| 154 | // NT header access |
| 155 | |
| 156 | BOOL () const; |
| 157 | CHECK () const; |
| 158 | |
| 159 | IMAGE_NT_HEADERS32 *() const; |
| 160 | IMAGE_NT_HEADERS64 *() const; |
| 161 | BOOL () const; |
| 162 | |
| 163 | const void *(COUNT_T *pSize = NULL) const; |
| 164 | |
| 165 | BOOL IsDll() const; |
| 166 | BOOL HasBaseRelocations() const; |
| 167 | const void *GetPreferredBase() const; // OptionalHeaders.ImageBase |
| 168 | COUNT_T GetVirtualSize() const; // OptionalHeaders.SizeOfImage - size of mapped/expanded image in memory |
| 169 | WORD GetSubsystem() const; |
| 170 | WORD GetDllCharacteristics() const; |
| 171 | DWORD GetTimeDateStamp() const; |
| 172 | DWORD GetCheckSum() const; |
| 173 | WORD GetMachine() const; |
| 174 | WORD GetCharacteristics() const; |
| 175 | DWORD GetFileAlignment() const; |
| 176 | DWORD GetSectionAlignment() const; |
| 177 | SIZE_T GetSizeOfStackReserve() const; |
| 178 | SIZE_T GetSizeOfStackCommit() const; |
| 179 | SIZE_T GetSizeOfHeapReserve() const; |
| 180 | SIZE_T GetSizeOfHeapCommit() const; |
| 181 | UINT32 GetLoaderFlags() const; |
| 182 | UINT32 GetWin32VersionValue() const; |
| 183 | COUNT_T GetNumberOfRvaAndSizes() const; |
| 184 | COUNT_T GetNumberOfSections() const; |
| 185 | PTR_IMAGE_SECTION_HEADER FindFirstSection() const; |
| 186 | IMAGE_SECTION_HEADER *FindSection(LPCSTR sectionName) const; |
| 187 | |
| 188 | DWORD GetImageIdentity() const; |
| 189 | |
| 190 | BOOL HasWriteableSections() const; |
| 191 | |
| 192 | // Directory entry access |
| 193 | |
| 194 | BOOL HasDirectoryEntry(int entry) const; |
| 195 | CHECK CheckDirectoryEntry(int entry, int forbiddenFlags = 0, IsNullOK ok = NULL_NOT_OK) const; |
| 196 | IMAGE_DATA_DIRECTORY *GetDirectoryEntry(int entry) const; |
| 197 | TADDR GetDirectoryEntryData(int entry, COUNT_T *pSize = NULL) const; |
| 198 | |
| 199 | // IMAGE_DATA_DIRECTORY access |
| 200 | |
| 201 | CHECK CheckDirectory(IMAGE_DATA_DIRECTORY *pDir, int forbiddenFlags = 0, IsNullOK ok = NULL_NOT_OK) const; |
| 202 | TADDR GetDirectoryData(IMAGE_DATA_DIRECTORY *pDir) const; |
| 203 | TADDR GetDirectoryData(IMAGE_DATA_DIRECTORY *pDir, COUNT_T *pSize) const; |
| 204 | |
| 205 | // Basic RVA access |
| 206 | |
| 207 | CHECK CheckRva(RVA rva, IsNullOK ok = NULL_NOT_OK) const; |
| 208 | CHECK CheckRva(RVA rva, COUNT_T size, int forbiddenFlags=0, IsNullOK ok = NULL_NOT_OK) const; |
| 209 | TADDR GetRvaData(RVA rva, IsNullOK ok = NULL_NOT_OK) const; |
| 210 | // Called with ok=NULL_OK only for mapped fields (RVA statics) |
| 211 | |
| 212 | CHECK CheckData(const void *data, IsNullOK ok = NULL_NOT_OK) const; |
| 213 | CHECK CheckData(const void *data, COUNT_T size, IsNullOK ok = NULL_NOT_OK) const; |
| 214 | RVA GetDataRva(const TADDR data) const; |
| 215 | BOOL PointerInPE(PTR_CVOID data) const; |
| 216 | |
| 217 | // Flat mapping utilities - using PointerToRawData instead of (Relative)VirtualAddress |
| 218 | CHECK CheckOffset(COUNT_T fileOffset, IsNullOK ok = NULL_NOT_OK) const; |
| 219 | CHECK CheckOffset(COUNT_T fileOffset, COUNT_T size, IsNullOK ok = NULL_NOT_OK) const; |
| 220 | TADDR GetOffsetData(COUNT_T fileOffset, IsNullOK ok = NULL_NOT_OK) const; |
| 221 | // Called with ok=NULL_OK only for mapped fields (RVA statics) |
| 222 | |
| 223 | // Mapping between RVA and file offsets |
| 224 | COUNT_T RvaToOffset(RVA rva) const; |
| 225 | RVA OffsetToRva(COUNT_T fileOffset) const; |
| 226 | |
| 227 | // Base intra-image pointer access |
| 228 | // (These are for pointers retrieved out of the PE image) |
| 229 | |
| 230 | CHECK CheckInternalAddress(SIZE_T address, IsNullOK ok = NULL_NOT_OK) const; |
| 231 | CHECK CheckInternalAddress(SIZE_T address, COUNT_T size, IsNullOK ok = NULL_NOT_OK) const; |
| 232 | TADDR GetInternalAddressData(SIZE_T address) const; |
| 233 | |
| 234 | // CLR loader IL Image verification - these checks apply to IL_ONLY images. |
| 235 | |
| 236 | BOOL IsILOnly() const; |
| 237 | CHECK CheckILOnly() const; |
| 238 | |
| 239 | void LayoutILOnly(void *base, BOOL allowFullPE = FALSE) const; |
| 240 | |
| 241 | // Strong name & hashing support |
| 242 | |
| 243 | BOOL HasStrongNameSignature() const; |
| 244 | CHECK CheckStrongNameSignature() const; |
| 245 | PTR_CVOID GetStrongNameSignature(COUNT_T *pSize = NULL) const; |
| 246 | |
| 247 | // CorHeader flag support |
| 248 | |
| 249 | // IsStrongNameSigned indicates whether the signature has been filled in. |
| 250 | // (otherwise if it has a signature it is delay signed.) |
| 251 | BOOL IsStrongNameSigned() const; // TRUE if the COMIMAGE_FLAGS_STRONGNAMESIGNED flag is set |
| 252 | |
| 253 | // TLS |
| 254 | |
| 255 | BOOL HasTls() const; |
| 256 | CHECK CheckTls() const; |
| 257 | PTR_VOID GetTlsRange(COUNT_T *pSize = NULL) const; |
| 258 | UINT32 GetTlsIndex() const; |
| 259 | |
| 260 | #ifndef FEATURE_PAL |
| 261 | // Win32 resources |
| 262 | void *GetWin32Resource(LPCWSTR lpName, LPCWSTR lpType, COUNT_T *pSize = NULL) const; |
| 263 | #endif // FEATURE_PAL |
| 264 | |
| 265 | // COR header fields |
| 266 | |
| 267 | BOOL () const; |
| 268 | CHECK () const; |
| 269 | IMAGE_COR20_HEADER *() const; |
| 270 | |
| 271 | PTR_CVOID GetMetadata(COUNT_T *pSize = NULL) const; |
| 272 | |
| 273 | const void *GetResources(COUNT_T *pSize = NULL) const; |
| 274 | CHECK CheckResource(COUNT_T offset) const; |
| 275 | const void *GetResource(COUNT_T offset, COUNT_T *pSize = NULL) const; |
| 276 | |
| 277 | BOOL HasManagedEntryPoint() const; |
| 278 | ULONG GetEntryPointToken() const; |
| 279 | IMAGE_COR_VTABLEFIXUP *GetVTableFixups(COUNT_T *pCount = NULL) const; |
| 280 | |
| 281 | // Native header access |
| 282 | BOOL () const; |
| 283 | CHECK () const; |
| 284 | CORCOMPILE_HEADER *() const; |
| 285 | BOOL IsNativeMachineFormat() const; |
| 286 | BOOL IsI386() const; |
| 287 | |
| 288 | void GetPEKindAndMachine(DWORD * pdwPEKind, DWORD *pdwMachine); // Returns CorPEKind flags |
| 289 | BOOL IsPlatformNeutral(); // Returns TRUE for IL-only platform neutral images |
| 290 | |
| 291 | // |
| 292 | // Verifies that the IL is within the bounds of the image. |
| 293 | // |
| 294 | CHECK CheckILMethod(RVA rva); |
| 295 | |
| 296 | // |
| 297 | // Compute size of IL blob. Assumes that the IL is within the bounds of the image - make sure |
| 298 | // to call CheckILMethod before calling this method. |
| 299 | // |
| 300 | static SIZE_T ComputeILMethodSize(TADDR pIL); |
| 301 | |
| 302 | // Debug directory access, returns NULL if no such entry |
| 303 | PTR_IMAGE_DEBUG_DIRECTORY GetDebugDirectoryEntry(UINT index) const; |
| 304 | |
| 305 | #ifdef FEATURE_PREJIT |
| 306 | CHECK () const; |
| 307 | |
| 308 | // ManagedNative fields |
| 309 | CORCOMPILE_CODE_MANAGER_ENTRY *GetNativeCodeManagerTable() const; |
| 310 | CORCOMPILE_EE_INFO_TABLE *GetNativeEEInfoTable() const; |
| 311 | void *GetNativeHelperTable(COUNT_T *pSize = NULL) const; |
| 312 | CORCOMPILE_VERSION_INFO *GetNativeVersionInfo() const; |
| 313 | CORCOMPILE_VERSION_INFO *GetNativeVersionInfoMaybeNull(bool = false) const; |
| 314 | BOOL HasNativeDebugMap() const; |
| 315 | TADDR GetNativeDebugMap(COUNT_T *pSize = NULL) const; |
| 316 | Module *GetPersistedModuleImage(COUNT_T *pSize = NULL) const; |
| 317 | PCODE GetNativeHotCode(COUNT_T * pSize = NULL) const; |
| 318 | PCODE GetNativeCode(COUNT_T * pSize = NULL) const; |
| 319 | PCODE GetNativeColdCode(COUNT_T * pSize = NULL) const; |
| 320 | |
| 321 | CORCOMPILE_METHOD_PROFILE_LIST *GetNativeProfileDataList(COUNT_T *pSize = NULL) const; |
| 322 | PTR_CVOID GetNativeManifestMetadata(COUNT_T *pSize = NULL) const; |
| 323 | const void *GetNativePreferredBase() const; |
| 324 | BOOL GetNativeILHasSecurityDirectory() const; |
| 325 | BOOL GetNativeILIsIbcOptimized() const; |
| 326 | BOOL () const; |
| 327 | BOOL IsNativeILILOnly() const; |
| 328 | BOOL IsNativeILDll() const; |
| 329 | void GetNativeILPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine) const; |
| 330 | CORCOMPILE_DEPENDENCY * GetNativeDependencies(COUNT_T *pCount = NULL) const; |
| 331 | |
| 332 | PTR_CORCOMPILE_IMPORT_SECTION GetNativeImportSections(COUNT_T *pCount = NULL) const; |
| 333 | PTR_CORCOMPILE_IMPORT_SECTION GetNativeImportSectionFromIndex(COUNT_T index) const; |
| 334 | PTR_CORCOMPILE_IMPORT_SECTION GetNativeImportSectionForRVA(RVA rva) const; |
| 335 | |
| 336 | TADDR GetStubsTable(COUNT_T *pSize = NULL) const; |
| 337 | TADDR GetVirtualSectionsTable(COUNT_T *pSize = NULL) const; |
| 338 | #endif // FEATURE_PREJIT |
| 339 | |
| 340 | BOOL () const; |
| 341 | READYTORUN_HEADER *() const; |
| 342 | |
| 343 | void GetEXEStackSizes(SIZE_T *PE_SizeOfStackReserve, SIZE_T *PE_SizeOfStackCommit) const; |
| 344 | |
| 345 | CHECK CheckWillCreateGuardPage() const; |
| 346 | |
| 347 | // Native DLLMain Entrypoint |
| 348 | BOOL HasNativeEntryPoint() const; |
| 349 | void *GetNativeEntryPoint() const; |
| 350 | |
| 351 | #ifdef _DEBUG |
| 352 | // Stress mode for relocations |
| 353 | static BOOL GetForceRelocs(); |
| 354 | static BOOL ForceRelocForDLL(LPCWSTR lpFileName); |
| 355 | #endif |
| 356 | |
| 357 | #ifdef DACCESS_COMPILE |
| 358 | void EnumMemoryRegions(CLRDataEnumMemoryFlags flags, bool enumThis); |
| 359 | #endif |
| 360 | |
| 361 | protected: |
| 362 | |
| 363 | // ------------------------------------------------------------ |
| 364 | // Protected API for subclass use |
| 365 | // ------------------------------------------------------------ |
| 366 | |
| 367 | // Checking utilites |
| 368 | static CHECK CheckBounds(RVA rangeBase, COUNT_T rangeSize, RVA rva); |
| 369 | static CHECK CheckBounds(RVA rangeBase, COUNT_T rangeSize, RVA rva, COUNT_T size); |
| 370 | |
| 371 | static CHECK CheckBounds(const void *rangeBase, COUNT_T rangeSize, const void *pointer); |
| 372 | static CHECK CheckBounds(PTR_CVOID rangeBase, COUNT_T rangeSize, PTR_CVOID pointer, COUNT_T size); |
| 373 | |
| 374 | protected: |
| 375 | |
| 376 | // Flat mapping utilities - using PointerToRawData instead of (Relative)VirtualAddress |
| 377 | IMAGE_SECTION_HEADER *RvaToSection(RVA rva) const; |
| 378 | IMAGE_SECTION_HEADER *OffsetToSection(COUNT_T fileOffset) const; |
| 379 | |
| 380 | void SetRelocated(); |
| 381 | |
| 382 | private: |
| 383 | |
| 384 | // ------------------------------------------------------------ |
| 385 | // Internal functions |
| 386 | // ------------------------------------------------------------ |
| 387 | |
| 388 | enum METADATA_SECTION_TYPE |
| 389 | { |
| 390 | METADATA_SECTION_FULL, |
| 391 | #ifdef FEATURE_PREJIT |
| 392 | METADATA_SECTION_MANIFEST |
| 393 | #endif |
| 394 | }; |
| 395 | |
| 396 | IMAGE_DATA_DIRECTORY *GetMetaDataHelper(METADATA_SECTION_TYPE type) const; |
| 397 | |
| 398 | static PTR_IMAGE_SECTION_HEADER (IMAGE_NT_HEADERS * ); |
| 399 | |
| 400 | IMAGE_NT_HEADERS *() const; |
| 401 | IMAGE_COR20_HEADER *() const; |
| 402 | CORCOMPILE_HEADER *() const; |
| 403 | READYTORUN_HEADER *() const; |
| 404 | |
| 405 | // Flat mapping utilities |
| 406 | RVA InternalAddressToRva(SIZE_T address) const; |
| 407 | |
| 408 | // NT header subchecks |
| 409 | CHECK CheckSection(COUNT_T previousAddressEnd, COUNT_T addressStart, COUNT_T addressSize, |
| 410 | COUNT_T previousOffsetEnd, COUNT_T offsetStart, COUNT_T offsetSize) const; |
| 411 | |
| 412 | // Pure managed subchecks |
| 413 | CHECK CheckILOnlyImportDlls() const; |
| 414 | CHECK CheckILOnlyImportByNameTable(RVA rva) const; |
| 415 | CHECK CheckILOnlyBaseRelocations() const; |
| 416 | CHECK CheckILOnlyEntryPoint() const; |
| 417 | |
| 418 | // ------------------------------------------------------------ |
| 419 | // Instance members |
| 420 | // ------------------------------------------------------------ |
| 421 | |
| 422 | enum |
| 423 | { |
| 424 | FLAG_MAPPED = 0x01, // the file is mapped/hydrated (vs. the raw disk layout) |
| 425 | FLAG_CONTENTS = 0x02, // the file has contents |
| 426 | FLAG_RELOCATED = 0x04, // relocs have been applied |
| 427 | FLAG_NT_CHECKED = 0x10, |
| 428 | FLAG_COR_CHECKED = 0x20, |
| 429 | FLAG_IL_ONLY_CHECKED = 0x40, |
| 430 | FLAG_NATIVE_CHECKED = 0x80, |
| 431 | |
| 432 | = 0x100, |
| 433 | }; |
| 434 | |
| 435 | TADDR m_base; |
| 436 | COUNT_T m_size; // size of file on disk, as opposed to OptionalHeaders.SizeOfImage |
| 437 | ULONG m_flags; |
| 438 | |
| 439 | PTR_IMAGE_NT_HEADERS ; |
| 440 | PTR_IMAGE_COR20_HEADER ; |
| 441 | PTR_CORCOMPILE_HEADER ; |
| 442 | PTR_READYTORUN_HEADER ; |
| 443 | }; |
| 444 | |
| 445 | // |
| 446 | // MethodSectionIterator class is used to iterate hot (or) cold method section in an ngen image. |
| 447 | // It can also iterate nibble maps generated by the JIT in a regular HeapList. |
| 448 | // |
| 449 | class MethodSectionIterator |
| 450 | { |
| 451 | private: |
| 452 | PTR_DWORD m_codeTableStart; |
| 453 | PTR_DWORD m_codeTable; |
| 454 | PTR_DWORD m_codeTableEnd; |
| 455 | |
| 456 | BYTE *m_code; |
| 457 | |
| 458 | DWORD m_dword; |
| 459 | DWORD m_index; |
| 460 | |
| 461 | BYTE *m_current; |
| 462 | |
| 463 | public: |
| 464 | |
| 465 | //If code is a target pointer, then GetMethodCode and FindMethodCode return |
| 466 | //target pointers. codeTable may be a pointer of either type, since it is |
| 467 | //converted internally into a host pointer. |
| 468 | MethodSectionIterator(const void *code, SIZE_T codeSize, |
| 469 | const void *codeTable, SIZE_T codeTableSize); |
| 470 | BOOL Next(); |
| 471 | BYTE *GetMethodCode() { return m_current; } // Get the start of method code of the current method in the iterator |
| 472 | }; |
| 473 | |
| 474 | #include "pedecoder.inl" |
| 475 | |
| 476 | #endif // PEDECODER_H_ |
| 477 | |