System.Data.SQLite
Check-in [08f855ffb1]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Better generic entrypoint handling
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sourceforge
Files: files | file ages | folders
SHA1: 08f855ffb188e8a1865848160da8d5a93f2d0387
User & Date: rmsimpson 2006-01-27 22:21:50
Context
2006-01-27
22:41
Documentation updates check-in: 5b7117d61a user: rmsimpson tags: sourceforge
22:21
Better generic entrypoint handling check-in: 08f855ffb1 user: rmsimpson tags: sourceforge
06:13
Fixed a bug in aggregate functions with empty resultsets check-in: ab8b2729bb user: rmsimpson tags: sourceforge
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to bin/tools/mergebin.exe.

cannot compute difference between binary files

Changes to tools/mergebin/mergebin.cpp.

    10     10   #include "MetaDataTables.h"
    11     11   #include "TableData.h"
    12     12   
    13     13   void DumpCLRInfo(LPCTSTR pszFile);
    14     14   void MergeModules(LPCTSTR pszAssembly, LPCTSTR pszNative, LPCTSTR pszSection);
    15     15   void DumpCLRPragma(LPCTSTR pszAssembly, LPCTSTR pszSection);
    16     16   
           17  +typedef struct EXTRA_STUFF
           18  +{
           19  +  DWORD dwNativeEntryPoint;
           20  +} EXTRA_STUFF, *LPEXTRA_STUFF;
           21  +
    17     22   int _tmain(int argc, _TCHAR* argv[])
    18     23   {
    19     24     if (argc == 1)
    20     25     {
    21     26       _tprintf(_T(
    22     27   "MERGEBIN - Merges a pure .NET assembly with a native DLL\n \
    23     28   Syntax: MERGEBIN [/I:assembly] [/S:sectionname assembly nativedll]\n \
................................................................................
   171    176   
   172    177     if (!GetMinMaxCOR20RVA(peFile, dwMinRVA, dwMaxRVA))
   173    178     {
   174    179       _tprintf(_T("Unable to retrieve .NET assembly information for file %s\n"), pszFile);
   175    180       return;
   176    181     }
   177    182   
   178         -  _tprintf(_T("%d Bytes required to merge %s\n"), (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb, pszFile);
          183  +  _tprintf(_T("%d Bytes required to merge %s\n"), (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb + sizeof(EXTRA_STUFF), pszFile);
   179    184   }
   180    185   
   181    186   void DumpCLRPragma(LPCTSTR pszAssembly, LPCTSTR pszSection)
   182    187   {
   183    188     CPEFile peFile;
   184    189     HRESULT hr;
   185    190     DWORD dwMinRVA;
................................................................................
   200    205   // %s\n\n\
   201    206   #include <windef.h>\n\n\
   202    207   #pragma data_seg(\"%s\")\n\
   203    208   #pragma comment(linker, \"/SECTION:%s,ER\")\n\
   204    209     char __ph[%d] = {0}; // The number of bytes to reserve\n\
   205    210   #pragma data_seg()\n\n\
   206    211   typedef BOOL (WINAPI *DLLMAIN)(HANDLE, DWORD, LPVOID);\n\
   207         -extern BOOL WINAPI _DllMainCRTStartup(HANDLE, DWORD, LPVOID);\n\n\
          212  +typedef struct EXTRA_STUFF\n\
          213  +{\n\
          214  +  DWORD dwNativeEntryPoint;\n\
          215  +} EXTRA_STUFF, *LPEXTRA_STUFF;\n\n\
   208    216   __declspec(dllexport) BOOL WINAPI _CorDllMainStub(HANDLE hModule, DWORD dwReason, LPVOID pvReserved)\n\
   209    217   {\n\
   210    218     HANDLE hMod;\n\
   211         -  DLLMAIN proc;\n\n\
          219  +  DLLMAIN proc;\n\
          220  +  LPEXTRA_STUFF pExtra;\n\n\
   212    221     hMod = GetModuleHandle(_T(\"mscoree\"));\n\
   213    222     if (hMod)\n\
   214    223       proc = (DLLMAIN)GetProcAddress(hMod, _T(\"_CorDllMain\"));\n\
   215    224     else\n\
   216         -    proc = _DllMainCRTStartup;\n\n\
          225  +  {\n\
          226  +    MEMORY_BASIC_INFORMATION mbi;\n\n\
          227  +    VirtualQuery(_CorDllMainStub, &mbi, sizeof(mbi));\n\
          228  +    pExtra = (LPEXTRA_STUFF)__ph;\n\
          229  +    proc = (DLLMAIN)(pExtra->dwNativeEntryPoint + (DWORD)mbi.AllocationBase);\n\
          230  +  }\n\
   217    231     return proc(hModule, dwReason, pvReserved);\n\
   218    232   }\n\
   219         -"), pszAssembly, pszSection, pszSection, (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb);
          233  +"), pszAssembly, pszSection, pszSection, (dwMaxRVA - dwMinRVA) + ((PIMAGE_COR20_HEADER)peFile)->cb + sizeof(EXTRA_STUFF));
   220    234   }
   221    235   
   222    236   /*   When merged, the native DLL's entrypoint must go to _CorDllMain in MSCOREE.DLL.
   223    237     ** In order to do this, we need to change the DLL's entrypoint to "something" that will
   224    238     ** call CorDllMain.  Since its too much hassle to add imports to the DLL and make drastic
   225    239     ** changes to it, we rely on the native DLL to export a function that we can call which will
   226    240     ** forward to CorDllMain.  Exported functions are easy to identify and get an RVA for.
................................................................................
   301    315     PIMAGE_COR20_HEADER pCor;
   302    316     PIMAGE_NT_HEADERS32 pNT;
   303    317     PIMAGE_NT_HEADERS64 pNT64;
   304    318     int diffRVA;
   305    319     CTableData *p;
   306    320     DWORD *pdwRVA;
   307    321     DWORD dwRows;
          322  +  LPEXTRA_STUFF pExtra;
   308    323   
   309    324     // Open the .NET assembly
   310    325     hr = peFile.Open(pszAssembly);
   311    326     if (FAILED(hr)) return;
   312    327   
   313    328     // Scan the .NET assembly and find the block of .NET code specified in the .NET metadata
   314    329     if (!GetMinMaxCOR20RVA(peFile, dwMinRVA, dwMaxRVA))
................................................................................
   328    343     if (!pSection)
   329    344     {
   330    345       _tprintf(_T("Unable to find section %s in file\n"), pszSection);
   331    346       return;
   332    347     }
   333    348   
   334    349     // If the section isn't large enough, tell the user how large it needs to be
   335         -  if (pSection->Misc.VirtualSize < dwSize)
          350  +  if (pSection->Misc.VirtualSize < (dwSize + sizeof(EXTRA_STUFF)))
   336    351     {
   337         -    _tprintf(_T("Not enough room in section for data.  Need %d bytes\n"), dwSize);
          352  +    _tprintf(_T("Not enough room in section for data.  Need %d bytes\n"), dwSize + sizeof(EXTRA_STUFF));
   338    353       return;
   339    354     }
   340    355   
   341    356     /*
   342    357     ** Find a new entrypoint to use for the DLL.  The old entrypoint is written into the .NET header
   343    358     */
   344    359     dwNewEntrypoint = GetExportedCorDllMainRVA(peDest);
................................................................................
   347    362       _tprintf(_T("Native DLL must export a function that calls _CorDllMain, and its name must contain the word \"CorDllMain\".\n"));
   348    363       return;
   349    364     }
   350    365   
   351    366     // Change this section's flags
   352    367     pSection->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
   353    368     dwDestRVA = pSection->VirtualAddress;
          369  +
          370  +  pExtra = (LPEXTRA_STUFF)peDest.GetPtrFromRVA(dwDestRVA);
          371  +  dwDestRVA += sizeof(EXTRA_STUFF);
   354    372   
   355    373     // If the native DLL has been merged with an assembly beforehand, we need to strip the .NET stuff and restore the entrypoint
   356    374     pCor = peDest;
   357    375     if (pCor)
   358    376     {
   359    377       if (pCor->Flags & 0x10)
   360    378       {
................................................................................
   376    394   
   377    395     pNT = peDest;
   378    396     pNT64 = peDest;
   379    397   
   380    398     // Fixup the NT header on the native DLL to include the new .NET header
   381    399     if (pNT)
   382    400     {
   383         -    pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = pSection->VirtualAddress;
          401  +    pExtra->dwNativeEntryPoint = pNT->OptionalHeader.AddressOfEntryPoint;
          402  +    pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = dwDestRVA;
   384    403       pNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = dwSize;
   385    404     }
   386    405     else
   387    406     {
   388         -    pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = pSection->VirtualAddress;
          407  +    pExtra->dwNativeEntryPoint = pNT64->OptionalHeader.AddressOfEntryPoint;
          408  +    pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress = dwDestRVA;
   389    409       pNT64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size = dwSize;
   390    410     }
   391    411     dwDestRVA += dwSize;
   392    412     if (dwDestRVA % 4) dwDestRVA += (4 - (dwDestRVA % 4));
   393    413   
   394    414     // Copy the .NET block of code and metadata into the section, after the header
   395    415     dwSize = dwMaxRVA - dwMinRVA;

Changes to tools/mergebin/mergebin.vcproj.

   134    134   				Name="VCResourceCompilerTool"
   135    135   			/>
   136    136   			<Tool
   137    137   				Name="VCPreLinkEventTool"
   138    138   			/>
   139    139   			<Tool
   140    140   				Name="VCLinkerTool"
   141         -				OutputFile="$(ProjectName).exe"
          141  +				OutputFile="..\..\bin\tools\$(ProjectName).exe"
   142    142   				LinkIncremental="1"
   143    143   				GenerateManifest="false"
   144    144   				GenerateDebugInformation="true"
   145    145   				SubSystem="1"
   146    146   				OptimizeReferences="2"
   147    147   				EnableCOMDATFolding="2"
   148    148   				TargetMachine="1"