Index: bin/tools/mergebin.exe
==================================================================
--- bin/tools/mergebin.exe
+++ bin/tools/mergebin.exe
cannot compute difference between binary files
Index: tools/mergebin/mergebin.cpp
==================================================================
--- tools/mergebin/mergebin.cpp
+++ tools/mergebin/mergebin.cpp
@@ -12,10 +12,15 @@
void DumpCLRInfo(LPCTSTR pszFile);
void MergeModules(LPCTSTR pszAssembly, LPCTSTR pszNative, LPCTSTR pszSection);
void DumpCLRPragma(LPCTSTR pszAssembly, LPCTSTR pszSection);
+typedef struct EXTRA_STUFF
+{
+ DWORD dwNativeEntryPoint;
+} EXTRA_STUFF, *LPEXTRA_STUFF;
+
int _tmain(int argc, _TCHAR* argv[])
{
if (argc == 1)
{
_tprintf(_T(
@@ -173,11 +178,11 @@
{
_tprintf(_T("Unable to retrieve .NET assembly information for file %s\n"), pszFile);
return;
}
- _tprintf(_T("%d Bytes required to merge %s\n"), (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb, pszFile);
+ _tprintf(_T("%d Bytes required to merge %s\n"), (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb + sizeof(EXTRA_STUFF), pszFile);
}
void DumpCLRPragma(LPCTSTR pszAssembly, LPCTSTR pszSection)
{
CPEFile peFile;
@@ -202,23 +207,32 @@
#pragma data_seg(\"%s\")\n\
#pragma comment(linker, \"/SECTION:%s,ER\")\n\
char __ph[%d] = {0}; // The number of bytes to reserve\n\
#pragma data_seg()\n\n\
typedef BOOL (WINAPI *DLLMAIN)(HANDLE, DWORD, LPVOID);\n\
-extern BOOL WINAPI _DllMainCRTStartup(HANDLE, DWORD, LPVOID);\n\n\
+typedef struct EXTRA_STUFF\n\
+{\n\
+ DWORD dwNativeEntryPoint;\n\
+} EXTRA_STUFF, *LPEXTRA_STUFF;\n\n\
__declspec(dllexport) BOOL WINAPI _CorDllMainStub(HANDLE hModule, DWORD dwReason, LPVOID pvReserved)\n\
{\n\
HANDLE hMod;\n\
- DLLMAIN proc;\n\n\
+ DLLMAIN proc;\n\
+ LPEXTRA_STUFF pExtra;\n\n\
hMod = GetModuleHandle(_T(\"mscoree\"));\n\
if (hMod)\n\
proc = (DLLMAIN)GetProcAddress(hMod, _T(\"_CorDllMain\"));\n\
else\n\
- proc = _DllMainCRTStartup;\n\n\
+ {\n\
+ MEMORY_BASIC_INFORMATION mbi;\n\n\
+ VirtualQuery(_CorDllMainStub, &mbi, sizeof(mbi));\n\
+ pExtra = (LPEXTRA_STUFF)__ph;\n\
+ proc = (DLLMAIN)(pExtra->dwNativeEntryPoint + (DWORD)mbi.AllocationBase);\n\
+ }\n\
return proc(hModule, dwReason, pvReserved);\n\
}\n\
-"), pszAssembly, pszSection, pszSection, (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb);
+"), pszAssembly, pszSection, pszSection, (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb + sizeof(EXTRA_STUFF));
}
/* When merged, the native DLL's entrypoint must go to _CorDllMain in MSCOREE.DLL.
** In order to do this, we need to change the DLL's entrypoint to "something" that will
** call CorDllMain. Since its too much hassle to add imports to the DLL and make drastic
@@ -303,10 +317,11 @@
PIMAGE_NT_HEADERS64 pNT64;
int diffRVA;
CTableData *p;
DWORD *pdwRVA;
DWORD dwRows;
+ LPEXTRA_STUFF pExtra;
// Open the .NET assembly
hr = peFile.Open(pszAssembly);
if (FAILED(hr)) return;
@@ -330,13 +345,13 @@
_tprintf(_T("Unable to find section %s in file\n"), pszSection);
return;
}
// If the section isn't large enough, tell the user how large it needs to be
- if (pSection->Misc.VirtualSize < dwSize)
+ if (pSection->Misc.VirtualSize < (dwSize + sizeof(EXTRA_STUFF)))
{
- _tprintf(_T("Not enough room in section for data. Need %d bytes\n"), dwSize);
+ _tprintf(_T("Not enough room in section for data. Need %d bytes\n"), dwSize + sizeof(EXTRA_STUFF));
return;
}
/*
** Find a new entrypoint to use for the DLL. The old entrypoint is written into the .NET header
@@ -349,10 +364,13 @@
}
// Change this section's flags
pSection->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
dwDestRVA = pSection->VirtualAddress;
+
+ pExtra = (LPEXTRA_STUFF)peDest.GetPtrFromRVA(dwDestRVA);
+ dwDestRVA += sizeof(EXTRA_STUFF);
// If the native DLL has been merged with an assembly beforehand, we need to strip the .NET stuff and restore the entrypoint
pCor = peDest;
if (pCor)
{
@@ -378,16 +396,18 @@
pNT64 = peDest;
// Fixup the NT header on the native DLL to include the new .NET header
if (pNT)
{
- pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = pSection->VirtualAddress;
+ pExtra->dwNativeEntryPoint = pNT->OptionalHeader.AddressOfEntryPoint;
+ pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = dwDestRVA;
pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = dwSize;
}
else
{
- pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = pSection->VirtualAddress;
+ pExtra->dwNativeEntryPoint = pNT64->OptionalHeader.AddressOfEntryPoint;
+ pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = dwDestRVA;
pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = dwSize;
}
dwDestRVA += dwSize;
if (dwDestRVA % 4) dwDestRVA += (4 - (dwDestRVA % 4));
Index: tools/mergebin/mergebin.vcproj
==================================================================
--- tools/mergebin/mergebin.vcproj
+++ tools/mergebin/mergebin.vcproj
@@ -136,11 +136,11 @@