void ZapImage::CopyWin32VersionResource() { #ifndef FEATURE_PAL // Copy the version resource over so it is easy to see in the dumps where the ngened module came from COUNT_T cbResourceData; PVOID pResourceData = m_ModuleDecoder.GetWin32Resource(MAKEINTRESOURCE(1), RT_VERSION, &cbResourceData); if (!pResourceData || !cbResourceData) return; ZapBlob * pVersionData = new (GetHeap()) ZapBlobPtr(pResourceData, cbResourceData); ZapVersionResource * pVersionResource = new (GetHeap()) ZapVersionResource(pVersionData); m_pWin32ResourceSection->Place(pVersionResource); m_pWin32ResourceSection->Place(pVersionData); SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_RESOURCE, m_pWin32ResourceSection); #endif }
void ZapImage::CopyDebugDirEntry() { // Insert an NGEN PDB debug directory entry *before* the IL PDB debug directory entry // (if one exists), so that we don't break tools that look for an IL PDB. { // This entry is initially empty. It is filled in ZapImage::GenerateFile. RSDS rsds = {0}; m_pNGenPdbDebugData = ZapBlob::NewBlob(static_cast<ZapWriter *>(this), &rsds, sizeof rsds); } // IL PDB entry: copy of the (first of possibly many) IMAGE_DEBUG_DIRECTORY entry // in the IL image DWORD nDebugEntry = 0; PIMAGE_DEBUG_DIRECTORY pDebugDir = NULL; ZapNode **ppDebugData = NULL; if (m_ModuleDecoder.HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG)) { COUNT_T debugEntrySize; TADDR pDebugEntry = m_ModuleDecoder.GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_DEBUG, &debugEntrySize); if (debugEntrySize != 0) { if (debugEntrySize < sizeof(IMAGE_DEBUG_DIRECTORY) || 0 != (debugEntrySize % sizeof(IMAGE_DEBUG_DIRECTORY))) { m_zapper->Warning(W("IMAGE_DIRECTORY_ENTRY_DEBUG size (%d) should be a multiple of %d\n"), debugEntrySize, sizeof(IMAGE_DEBUG_DIRECTORY)); } else { // Since pDebugEntry is an array of IMAGE_DEBUG_DIRECTORYs, debugEntrySize // should be a multiple of sizeof(IMAGE_DEBUG_DIRECTORY). _ASSERTE(0 == (debugEntrySize % sizeof(IMAGE_DEBUG_DIRECTORY))); nDebugEntry = DWORD(debugEntrySize / sizeof(IMAGE_DEBUG_DIRECTORY)); pDebugDir = new (GetHeap()) IMAGE_DEBUG_DIRECTORY[nDebugEntry]; memcpy(pDebugDir, (const void *)pDebugEntry, sizeof(IMAGE_DEBUG_DIRECTORY) * nDebugEntry); ppDebugData = new (GetHeap()) ZapNode*[nDebugEntry]; memset(ppDebugData, 0, nDebugEntry * sizeof(ZapNode*)); for (DWORD i = 0; i < nDebugEntry; i++) { // Some compilers set PointerToRawData but not AddressOfRawData as they put the // data at the end of the file in an unmapped part of the file RVA rvaOfRawData = (pDebugDir[i].AddressOfRawData != NULL) ? pDebugDir[i].AddressOfRawData : m_ModuleDecoder.OffsetToRva(pDebugDir[i].PointerToRawData); ULONG cbDebugData = pDebugDir[i].SizeOfData; if (cbDebugData != 0) { if (!m_ModuleDecoder.CheckRva(rvaOfRawData, cbDebugData)) m_zapper->Warning(W("IMAGE_DIRECTORY_ENTRY_DEBUG points to bad data\n")); else ppDebugData[i] = new (GetHeap()) ZapBlobPtr((PVOID)m_ModuleDecoder.GetRvaData(rvaOfRawData), cbDebugData); } } } } } ZapDebugDirectory * pDebugDirectory = new (GetHeap()) ZapDebugDirectory(m_pNGenPdbDebugData, nDebugEntry, pDebugDir, ppDebugData); m_pDebugSection->Place(pDebugDirectory); m_pDebugSection->Place(m_pNGenPdbDebugData); if (ppDebugData) { for (DWORD i = 0; i < nDebugEntry; i++) { if (ppDebugData[i] != nullptr) m_pDebugSection->Place(ppDebugData[i]); } } SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG, pDebugDirectory); }
void ZapImage::CopyDebugDirEntry() { // Insert an NGEN PDB debug directory entry *before* the IL PDB debug directory entry // (if one exists), so that we don't break tools that look for an IL PDB. { // This entry is initially empty. It is filled in ZapImage::GenerateFile. RSDS rsds = {0}; m_pNGenPdbDebugData = ZapBlob::NewBlob(static_cast<ZapWriter *>(this), &rsds, sizeof rsds); } // IL PDB entry: copy of the (first of possibly many) IMAGE_DEBUG_DIRECTORY entry // in the IL image PIMAGE_DEBUG_DIRECTORY pDebugDir = NULL; ZapBlob *pDebugData = NULL; if (m_ModuleDecoder.HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG)) { COUNT_T debugEntrySize; TADDR pDebugEntry = m_ModuleDecoder.GetDirectoryEntryData(IMAGE_DIRECTORY_ENTRY_DEBUG, &debugEntrySize); if (debugEntrySize != 0) { if (debugEntrySize < sizeof(IMAGE_DEBUG_DIRECTORY) || 0 != (debugEntrySize % sizeof(IMAGE_DEBUG_DIRECTORY))) { m_zapper->Warning(W("IMAGE_DIRECTORY_ENTRY_DEBUG size (%d) should be a multiple of %d\n"), debugEntrySize, sizeof(IMAGE_DEBUG_DIRECTORY)); } else { // Since pDebugEntry is an array of IMAGE_DEBUG_DIRECTORYs, debugEntrySize // should be a multiple of sizeof(IMAGE_DEBUG_DIRECTORY). _ASSERTE(0 == (debugEntrySize % sizeof(IMAGE_DEBUG_DIRECTORY))); // @TODO: pDebugEntry is an array of IMAGE_DEBUG_DIRECTORYs. Some tools // (like ibcmerge) add an extra dummy IMAGE_DEBUG_DIRECTORY to indicate // that the image was modified post-link. // We need to copy all the IMAGE_DEBUG_DIRECTORYs. For now, we only copy // the first one as it holds the relevant debug information. pDebugDir = PIMAGE_DEBUG_DIRECTORY(pDebugEntry); // Some compilers set PointerToRawData but not AddressOfRawData as they put the // data at the end of the file in an unmapped part of the file RVA rvaOfRawData = (pDebugDir->AddressOfRawData != NULL) ? pDebugDir->AddressOfRawData : m_ModuleDecoder.OffsetToRva(pDebugDir->PointerToRawData); ULONG cbDebugData = pDebugDir->SizeOfData; if (cbDebugData != 0) { if (!m_ModuleDecoder.CheckRva(rvaOfRawData, cbDebugData)) m_zapper->Warning(W("IMAGE_DIRECTORY_ENTRY_DEBUG points to bad data\n")); else pDebugData = new (GetHeap()) ZapBlobPtr((PVOID)m_ModuleDecoder.GetRvaData(rvaOfRawData), cbDebugData); } } } } ZapDebugDirectory * pDebugDirectory = new (GetHeap()) ZapDebugDirectory(m_pNGenPdbDebugData, pDebugData ? pDebugDir : NULL, pDebugData); m_pDebugSection->Place(pDebugDirectory); m_pDebugSection->Place(m_pNGenPdbDebugData); if (pDebugData) m_pDebugSection->Place(pDebugData); SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG, pDebugDirectory); }