diff --git a/src/coreclr/debug/daccess/enummem.cpp b/src/coreclr/debug/daccess/enummem.cpp index fee3991e5ee9b5..2c7445bf99cf91 100644 --- a/src/coreclr/debug/daccess/enummem.cpp +++ b/src/coreclr/debug/daccess/enummem.cpp @@ -19,6 +19,7 @@ #include "daccess.h" #include "binder.h" #include "win32threadpool.h" +#include "runtimeinfo.h" #ifdef FEATURE_COMWRAPPERS #include @@ -1558,6 +1559,27 @@ HRESULT ClrDataAccess::EnumMemCLRMainModuleInfo() status = E_UNEXPECTED; } + if (pe.HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT)) + { + COUNT_T size = 0; + TADDR pExportTablesOffset = pe.GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_EXPORT, &size); + + ReportMem(pExportTablesOffset, size, true); + + PTR_VOID runtimeExport = pe.GetExport(RUNTIME_INFO_SIGNATURE); + const char *runtimeExportSignature = dac_cast(runtimeExport); + if (runtimeExport != NULL && + strcmp(runtimeExportSignature, RUNTIME_INFO_SIGNATURE) == 0) + { + ReportMem(dac_cast(runtimeExport), sizeof(RuntimeInfo), true); + } + } + else + { + // We always expect (attach state, metrics and such on windows, and dac table on mac and linux). + return E_UNEXPECTED; + } + return status; } diff --git a/src/coreclr/debug/inc/runtimeinfo.h b/src/coreclr/debug/inc/runtimeinfo.h index c66024e9eb3a51..a5484c6b81618b 100644 --- a/src/coreclr/debug/inc/runtimeinfo.h +++ b/src/coreclr/debug/inc/runtimeinfo.h @@ -5,7 +5,12 @@ // The first byte of the index is the count of bytes typedef unsigned char SYMBOL_INDEX; +#define RUNTIME_INFO_SIGNATURE "DotNetRuntimeInfo" +// Make sure that if you update this structure +// - You do so in a in a way that it is backwards compatible. For example, only tail append to this. +// - Rev the version. +// - Update the logic in ClrDataAccess::EnumMemCLRMainModuleInfo to ensure all needed state is in the dump. typedef struct _RuntimeInfo { const char Signature[18]; diff --git a/src/coreclr/debug/runtimeinfo/runtimeinfo.cpp b/src/coreclr/debug/runtimeinfo/runtimeinfo.cpp index 6fd43d8c331b53..3102f27375f2d7 100644 --- a/src/coreclr/debug/runtimeinfo/runtimeinfo.cpp +++ b/src/coreclr/debug/runtimeinfo/runtimeinfo.cpp @@ -17,7 +17,7 @@ DLLEXPORT #endif RuntimeInfo DotNetRuntimeInfo = { { - "DotNetRuntimeInfo" + RUNTIME_INFO_SIGNATURE }, 1, { diff --git a/src/coreclr/inc/daccess.h b/src/coreclr/inc/daccess.h index 399c5c57a74bdc..71c5d2f376025a 100644 --- a/src/coreclr/inc/daccess.h +++ b/src/coreclr/inc/daccess.h @@ -2387,6 +2387,7 @@ typedef DPTR(IMAGE_NT_HEADERS) PTR_IMAGE_NT_HEADERS; typedef DPTR(IMAGE_NT_HEADERS32) PTR_IMAGE_NT_HEADERS32; typedef DPTR(IMAGE_NT_HEADERS64) PTR_IMAGE_NT_HEADERS64; typedef DPTR(IMAGE_SECTION_HEADER) PTR_IMAGE_SECTION_HEADER; +typedef DPTR(IMAGE_EXPORT_DIRECTORY) PTR_IMAGE_EXPORT_DIRECTORY; typedef DPTR(IMAGE_TLS_DIRECTORY) PTR_IMAGE_TLS_DIRECTORY; #if defined(DACCESS_COMPILE) diff --git a/src/coreclr/inc/pedecoder.h b/src/coreclr/inc/pedecoder.h index d637835036dee1..b551bf02d62254 100644 --- a/src/coreclr/inc/pedecoder.h +++ b/src/coreclr/inc/pedecoder.h @@ -353,7 +353,7 @@ class PEDecoder void *GetNativeEntryPoint() const; // Look up a named symbol in the export directory - void *GetExport(LPCSTR exportName) const; + PTR_VOID GetExport(LPCSTR exportName) const; #ifdef _DEBUG // Stress mode for relocations diff --git a/src/coreclr/utilcode/pedecoder.cpp b/src/coreclr/utilcode/pedecoder.cpp index 5ec34fa070000f..3b46c56a415879 100644 --- a/src/coreclr/utilcode/pedecoder.cpp +++ b/src/coreclr/utilcode/pedecoder.cpp @@ -1769,7 +1769,7 @@ void PEDecoder::LayoutILOnly(void *base, bool enableExecution) const PAGE_READONLY, &oldProtection)) ThrowLastError(); - // Finally, apply proper protection to copied sections + // Finally, apply proper protection to copied sections for (section = sectionStart; section < sectionEnd; section++) { // Add appropriate page protection. @@ -2346,8 +2346,7 @@ READYTORUN_HEADER * PEDecoder::FindReadyToRunHeader() const return NULL; } -#ifndef DACCESS_COMPILE -void *PEDecoder::GetExport(LPCSTR exportName) const +PTR_VOID PEDecoder::GetExport(LPCSTR exportName) const { // Get the export directory entry PIMAGE_DATA_DIRECTORY pExportDirectoryEntry = GetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT); @@ -2356,30 +2355,30 @@ void *PEDecoder::GetExport(LPCSTR exportName) const return NULL; } - uint8_t *imageBase = (uint8_t *)GetBase(); - const IMAGE_EXPORT_DIRECTORY *pExportDir = (const IMAGE_EXPORT_DIRECTORY *)GetDirectoryData(pExportDirectoryEntry); + PTR_IMAGE_EXPORT_DIRECTORY pExportDir = dac_cast(GetDirectoryData(pExportDirectoryEntry)); uint32_t namePointerCount = VAL32(pExportDir->NumberOfNames); uint32_t addressTableRVA = VAL32(pExportDir->AddressOfFunctions); - uint32_t namePointersRVA = VAL32(pExportDir->AddressOfNames); + uint32_t ordinalTableRVA = VAL32(pExportDir->AddressOfNameOrdinals); + uint32_t nameTableRVA = VAL32(pExportDir->AddressOfNames); for (uint32_t nameIndex = 0; nameIndex < namePointerCount; nameIndex++) { - uint32_t namePointerRVA = VAL32(*(const uint32_t *)&imageBase[namePointersRVA + sizeof(uint32_t) * nameIndex]); + uint32_t namePointerRVA = *dac_cast(GetRvaData(nameTableRVA + sizeof(uint32_t) * nameIndex)); if (namePointerRVA != 0) { - const char *namePointer = (const char *)&imageBase[namePointerRVA]; + const char *namePointer = dac_cast(GetRvaData(namePointerRVA)); if (!strcmp(namePointer, exportName)) { - uint32_t exportRVA = VAL32(*(const uint32_t *)&imageBase[addressTableRVA + sizeof(uint32_t) * nameIndex]); - return &imageBase[exportRVA]; + uint16_t ordinalForNamedExport = *dac_cast(GetRvaData(ordinalTableRVA + sizeof(uint16_t) * nameIndex)); + uint32_t exportRVA = *dac_cast(GetRvaData(addressTableRVA + sizeof(uint32_t) * ordinalForNamedExport)); + return dac_cast(GetRvaData(exportRVA)); } } } return NULL; } -#endif // // code:PEDecoder::CheckILMethod and code:PEDecoder::ComputeILMethodSize really belong to diff --git a/src/native/corehost/apphost/static/singlefilehost.def b/src/native/corehost/apphost/static/singlefilehost.def index 311335d2d2093c..6052b832b0b054 100644 --- a/src/native/corehost/apphost/static/singlefilehost.def +++ b/src/native/corehost/apphost/static/singlefilehost.def @@ -10,8 +10,8 @@ g_CLREngineMetrics @2 data ; VS depends on CLRJitAttachState having a ordinal of 3. This cannot change. CLRJitAttachState @3 data -; needed by SOS -DotNetRuntimeInfo +; needed by SOS, WinDBG, and Watson. This must remain ordinal 4. +DotNetRuntimeInfo @4 data ; Used by profilers MetaDataGetDispenser