if(WIN32)
list(APPEND CLR_SOURCES
- comcallunmarshal.cpp
delayloadhook.cpp
Native.rc
)
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-// File: ComCallUnmarshal.cpp
-//
-
-//
-// Classes used to unmarshal all COM call wrapper IPs.
-//
-
-
-#include "stdafx.h" // Standard header.
-
-#ifdef FEATURE_COMINTEROP
-
-#include "ComCallUnmarshal.h"
-#include <utilcode.h> // Utility helpers.
-
-// For free-threaded marshaling, we must not be spoofed by out-of-process or cross-runtime marshal data.
-// Only unmarshal data that comes from our own runtime.
-extern BYTE g_UnmarshalSecret[sizeof(GUID)];
-extern bool g_fInitedUnmarshalSecret;
-
-STDMETHODIMP ComCallUnmarshal::QueryInterface(REFIID iid, void **ppv)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- PRECONDITION(CheckPointer(ppv, NULL_OK));
- } CONTRACTL_END;
-
- if (!ppv)
- return E_POINTER;
-
- *ppv = NULL;
- if (iid == IID_IUnknown)
- {
- *ppv = (IUnknown *)this;
- AddRef();
- } else if (iid == IID_IMarshal)
- {
- *ppv = (IMarshal *)this;
- AddRef();
- }
- return (*ppv != NULL) ? S_OK : E_NOINTERFACE;
-}
-
-STDMETHODIMP_(ULONG) ComCallUnmarshal::AddRef(void)
-{
- LIMITED_METHOD_CONTRACT;
- return 2;
-}
-
-STDMETHODIMP_(ULONG) ComCallUnmarshal::Release(void)
-{
- LIMITED_METHOD_CONTRACT;
- return 1;
-}
-
-STDMETHODIMP ComCallUnmarshal::GetUnmarshalClass (REFIID riid, void * pv, ULONG dwDestContext,
- void * pvDestContext, ULONG mshlflags,
- LPCLSID pclsid)
-{
- LIMITED_METHOD_CONTRACT;
- // Marshal side only.
- _ASSERTE(FALSE);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP ComCallUnmarshal::GetMarshalSizeMax (REFIID riid, void * pv, ULONG dwDestContext,
- void * pvDestContext, ULONG mshlflags,
- ULONG * pSize)
-{
- LIMITED_METHOD_CONTRACT;
- // Marshal side only.
- _ASSERTE(FALSE);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP ComCallUnmarshal::MarshalInterface (LPSTREAM pStm, REFIID riid, void * pv,
- ULONG dwDestContext, LPVOID pvDestContext,
- ULONG mshlflags)
-{
- LIMITED_METHOD_CONTRACT;
- // Marshal side only.
- _ASSERTE(FALSE);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP ComCallUnmarshal::UnmarshalInterface (LPSTREAM pStm, REFIID riid, void ** ppvObj)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_PREEMPTIVE;
- PRECONDITION(CheckPointer(pStm));
- PRECONDITION(CheckPointer(ppvObj));
- } CONTRACTL_END;
-
- ULONG bytesRead;
- ULONG mshlflags;
- HRESULT hr = E_FAIL;
-
- // The marshal code added a reference to the object, but we return a
- // reference to the object as well, so don't change the ref count on the
- // success path. Need to release on error paths though (if we manage to
- // retrieve the IP, that is). If the interface was marshalled
- // TABLESTRONG or TABLEWEAK, there is going to be a ReleaseMarshalData
- // in the future, so we should AddRef the IP we're about to give out.
- // Note also that OLE32 requires us to advance the stream pointer even
- // in failure cases.
-
- // Read the raw IP out of the marshalling stream.
- hr = pStm->Read (ppvObj, sizeof (void *), &bytesRead);
- if (FAILED (hr) || (bytesRead != sizeof (void *)))
- IfFailGo(RPC_E_INVALID_DATA);
-
- // And then the marshal flags.
- hr = pStm->Read (&mshlflags, sizeof (ULONG), &bytesRead);
- if (FAILED (hr) || (bytesRead != sizeof (ULONG)))
- IfFailGo(RPC_E_INVALID_DATA);
-
- // And then verify our secret, to be sure that cross-runtime clients aren't
- // trying to trick us into mis-interpreting their data as a ppvObj. Note that
- // it is guaranteed that the secret data is initialized, or else we certainly
- // haven't written it into this buffer!
- if (!g_fInitedUnmarshalSecret)
- IfFailGo(E_UNEXPECTED);
-
- BYTE secret[sizeof(GUID)];
-
- hr = pStm->Read(secret, sizeof(secret), &bytesRead);
- if (FAILED(hr) || (bytesRead != sizeof(secret)))
- IfFailGo(RPC_E_INVALID_DATA);
-
- if (memcmp(g_UnmarshalSecret, secret, sizeof(secret)) != 0)
- IfFailGo(E_UNEXPECTED);
-
- if (ppvObj && ((mshlflags == MSHLFLAGS_TABLESTRONG) || (mshlflags == MSHLFLAGS_TABLEWEAK)))
- {
- // For table access we can just QI for the correct interface (this
- // will addref the IP, but that's OK since we need to keep an extra
- // ref on the IP until ReleaseMarshalData is called).
- hr = ((IUnknown *)*ppvObj)->QueryInterface(riid, ppvObj);
- }
- else
- {
- // For normal access we QI for the correct interface then release
- // the old IP.
- NonVMComHolder<IUnknown> pOldUnk = (IUnknown *)*ppvObj;
- hr = pOldUnk->QueryInterface(riid, ppvObj);
- }
-ErrExit:
- return hr;
-}
-
-STDMETHODIMP ComCallUnmarshal::ReleaseMarshalData (LPSTREAM pStm)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_PREEMPTIVE;
- PRECONDITION(CheckPointer(pStm));
- } CONTRACTL_END;
-
- IUnknown *pUnk;
- ULONG bytesRead;
- ULONG mshlflags;
- HRESULT hr = S_OK;
-
- if (!pStm)
- return E_POINTER;
-
- // Read the raw IP out of the marshalling stream. Do this first since we
- // need to update the stream pointer even in case of failures.
- hr = pStm->Read (&pUnk, sizeof (pUnk), &bytesRead);
- if (FAILED (hr) || (bytesRead != sizeof (pUnk)))
- IfFailGo(RPC_E_INVALID_DATA);
-
- // Now read the marshal flags.
- hr = pStm->Read (&mshlflags, sizeof (mshlflags), &bytesRead);
- if (FAILED (hr) || (bytesRead != sizeof (mshlflags)))
- IfFailGo(RPC_E_INVALID_DATA);
-
- if (!g_fInitedUnmarshalSecret)
- {
- IfFailGo(E_UNEXPECTED);
- }
-
- BYTE secret[sizeof(GUID)];
-
- hr = pStm->Read(secret, sizeof(secret), &bytesRead);
- if (FAILED(hr) || (bytesRead != sizeof(secret)))
- IfFailGo(RPC_E_INVALID_DATA);
-
- if (memcmp(g_UnmarshalSecret, secret, sizeof(secret)) != 0)
- IfFailGo(E_UNEXPECTED);
-
- pUnk->Release ();
-
-ErrExit:
- return hr;
-}
-
-STDMETHODIMP ComCallUnmarshal::DisconnectObject (ULONG dwReserved)
-{
- LIMITED_METHOD_CONTRACT;
-
- // Nothing we can (or need to) do here. The client is using a raw IP to
- // access this server, so the server shouldn't go away until the client
- // Release()'s it.
-
- return S_OK;
-}
-
-CComCallUnmarshalFactory::CComCallUnmarshalFactory()
-{
- WRAPPER_NO_CONTRACT;
-}
-
-STDMETHODIMP CComCallUnmarshalFactory::QueryInterface(REFIID iid, void **ppv)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- PRECONDITION(CheckPointer(ppv));
- } CONTRACTL_END;
-
- if (!ppv)
- return E_POINTER;
-
- *ppv = NULL;
- if (iid == IID_IClassFactory || iid == IID_IUnknown) {
- *ppv = (IClassFactory *)this;
- AddRef();
- }
- return (*ppv != NULL) ? S_OK : E_NOINTERFACE;
-}
-
-STDMETHODIMP_(ULONG) CComCallUnmarshalFactory::AddRef(void)
-{
- LIMITED_METHOD_CONTRACT;
- return 2;
-}
-
-STDMETHODIMP_(ULONG) CComCallUnmarshalFactory::Release(void)
-{
- LIMITED_METHOD_CONTRACT;
- return 1;
-}
-
-STDMETHODIMP CComCallUnmarshalFactory::CreateInstance(LPUNKNOWN punkOuter, REFIID iid, LPVOID FAR *ppv)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- PRECONDITION(CheckPointer(ppv));
- } CONTRACTL_END;
-
- if (!ppv)
- return E_POINTER;
-
- *ppv = NULL;
-
- if (punkOuter != NULL)
- return CLASS_E_NOAGGREGATION;
-
- return m_Unmarshaller.QueryInterface(iid, ppv);
-}
-
-STDMETHODIMP CComCallUnmarshalFactory::LockServer(BOOL fLock)
-{
- LIMITED_METHOD_CONTRACT;
- return S_OK;
-}
-
-#endif // FEATURE_COMINTEROP
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-// File: ComCallUnmarshal.h
-//
-
-//
-// Classes used to unmarshal all COM call wrapper IPs.
-//
-
-
-#pragma once
-
-#ifndef FEATURE_COMINTEROP
-#error FEATURE_COMINTEROP is required for this file
-#endif // FEATURE_COMINTEROP
-
-// Class used to unmarshal all COM call wrapper IPs. In order for this to work in side-by-side
-// scenarios, the CLSID of this class has to be changed with every side-by-side release.
-//
-// The class is identified by the following CLSID:
-// CLR v1.0, v1.1, v2.0: 3F281000-E95A-11d2-886B-00C04F869F04
-// CLR v4.0: 45FB4600-E6E8-4928-B25E-50476FF79425
-//
-class ComCallUnmarshal : public IMarshal
-{
-public:
-
- // *** IUnknown methods ***
- STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
-
- // *** IMarshal methods ***
- STDMETHODIMP GetUnmarshalClass (REFIID riid, void * pv, ULONG dwDestContext,
- void * pvDestContext, ULONG mshlflags,
- LPCLSID pclsid);
-
- STDMETHODIMP GetMarshalSizeMax (REFIID riid, void * pv, ULONG dwDestContext,
- void * pvDestContext, ULONG mshlflags,
- ULONG * pSize);
-
- STDMETHODIMP MarshalInterface (LPSTREAM pStm, REFIID riid, void * pv,
- ULONG dwDestContext, LPVOID pvDestContext,
- ULONG mshlflags);
-
- STDMETHODIMP UnmarshalInterface (LPSTREAM pStm, REFIID riid, void ** ppvObj);
- STDMETHODIMP ReleaseMarshalData (LPSTREAM pStm);
- STDMETHODIMP DisconnectObject (ULONG dwReserved);
-};
-
-// Class factory for the COM call wrapper unmarshaller.
-class CComCallUnmarshalFactory : public IClassFactory
-{
- ComCallUnmarshal m_Unmarshaller;
-
- public:
-
- CComCallUnmarshalFactory();
-
- // *** IUnknown methods ***
- STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
-
- // *** IClassFactory methods ***
- STDMETHODIMP CreateInstance(LPUNKNOWN punkOuter, REFIID iid, LPVOID FAR *ppv);
- STDMETHODIMP LockServer(BOOL fLock);
-};
set(END_LIBRARY_GROUP)
else()
- add_definitions(-DNO_CRT_INIT)
-
set(EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/coreclr.exports)
generate_exports_file(${DEF_SOURCES} ${EXPORTS_FILE})
#include "product_version.h"
-#ifdef FEATURE_COMINTEROP
-#include "ComCallUnmarshal.h"
-#endif // FEATURE_COMINTEROP
-
#include <dbgenginemetrics.h>
// Locals.
#include <shlwapi.h>
-#include <process.h> // for __security_init_cookie()
-
extern "C" IExecutionEngine* IEE();
-#ifdef NO_CRT_INIT
-#define _CRT_INIT(hInstance, dwReason, lpReserved) (TRUE)
-#else
-extern "C" BOOL WINAPI _CRT_INIT(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);
-#endif
+#ifdef PLATFORM_WINDOWS
+
+#include <process.h> // for __security_init_cookie()
+extern "C" BOOL WINAPI _CRT_INIT(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);
extern "C" BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved);
// For the CoreClr, this is the real DLL entrypoint. We make ourselves the first entrypoint as
// we need to capture coreclr's hInstance before the C runtime initializes. This function
// will capture hInstance, let the C runtime initialize and then invoke the "classic"
// DllMain that initializes everything else.
-extern "C"
-#ifdef FEATURE_PAL
-DLLEXPORT // For Win32 PAL LoadLibrary emulation
-#endif
-BOOL WINAPI CoreDllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
+extern "C" BOOL WINAPI CoreDllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
{
STATIC_CONTRACT_NOTHROW;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
-#ifndef FEATURE_PAL
// Make sure the /GS security cookie is initialized before we call anything else.
// BinScope detects the call to __security_init_cookie in its "Has Non-GS-friendly
// Initialization" check and makes it pass.
__security_init_cookie();
-#endif // FEATURE_PAL
// It's critical that we invoke InitUtilCode() before the CRT initializes.
// We have a lot of global ctors that will break if we let the CRT initialize without
return result;
}
+#endif // PLATFORM_WINDOWS
+
+
extern "C"
#ifdef FEATURE_PAL
DLLEXPORT // For Win32 PAL LoadLibrary emulation
{
case DLL_PROCESS_ATTACH:
{
+#ifndef PLATFORM_WINDOWS
+ // It's critical that we invoke InitUtilCode() before the CRT initializes.
+ // We have a lot of global ctors that will break if we let the CRT initialize without
+ // this step having been done.
+
+ CoreClrCallbacks cccallbacks;
+ cccallbacks.m_hmodCoreCLR = (HINSTANCE)hInstance;
+ cccallbacks.m_pfnIEE = IEE;
+ cccallbacks.m_pfnGetCORSystemDirectory = GetCORSystemDirectoryInternaL;
+ InitUtilcode(cccallbacks);
+#endif
+
// Save the module handle.
g_hThisInst = (HINSTANCE)hInstance;
return TRUE;
}
-#ifdef FEATURE_COMINTEROP
-// ---------------------------------------------------------------------------
-// %%Function: DllCanUnloadNowInternal
-//
-// Returns:
-// S_FALSE - Indicating that COR, once loaded, may not be
-// unloaded.
-// ---------------------------------------------------------------------------
-STDAPI DllCanUnloadNowInternal(void)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_ENTRY_POINT;
-
- //we should never unload unless the process is dying
- return S_FALSE;
-} // DllCanUnloadNowInternal
-
-// ---------------------------------------------------------------------------
-// %%Function: DllRegisterServerInternal
-//
-// Description:
-// Registers
-// ---------------------------------------------------------------------------
-STDAPI DllRegisterServerInternal(HINSTANCE hMod, LPCWSTR version)
-{
-
- CONTRACTL{
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(version));
- } CONTRACTL_END;
-
- return S_OK;
-} // DllRegisterServerInternal
-
-// ---------------------------------------------------------------------------
-// %%Function: DllUnregisterServerInternal
-// ---------------------------------------------------------------------------
-STDAPI DllUnregisterServerInternal(void)
-{
-
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- return S_OK;
-
-} // DllUnregisterServerInternal
-#endif // FEATURE_COMINTEROP
-
#endif // CROSSGEN_COMPILE
HINSTANCE GetModuleInst()
coreclr_initialize
coreclr_shutdown
coreclr_shutdown_2
-
- ; il{d}asm
- MetaDataGetDispenser
- GetMetaDataInternalInterface
- GetMetaDataInternalInterfaceFromPublic
- GetMetaDataPublicInterfaceFromInternal
coreclr_shutdown
coreclr_shutdown_2
-; il{d}asm
-MetaDataGetDispenser
-GetMetaDataInternalInterface
-GetMetaDataInternalInterfaceFromPublic
-GetMetaDataPublicInterfaceFromInternal
-
-; PAL module registration
-PAL_RegisterModule
-PAL_UnregisterModule
-
; Functions exported by the coreclr
-CoreDllMain
DllMain
GetCLRRuntimeHost
#define DECLARE_DATA
#include "assembler.h"
-MetaDataGetDispenserFunc metaDataGetDispenser;
void indexKeywords(Indx* indx); // defined in asmparse.y
BOOL Assembler::Init()
{
- metaDataGetDispenser = (MetaDataGetDispenserFunc)MetaDataGetDispenser;
if (m_pCeeFileGen != NULL) {
if (m_pCeeFile)
m_pCeeFileGen->DestroyCeeFile(&m_pCeeFile);
#ifdef FEATURE_PAL
extern char *g_pszExeFile;
#endif
-typedef int(STDAPICALLTYPE *MetaDataGetDispenserFunc) (
- REFCLSID rclsid, // The class to desired.
- REFIID riid, // Interface wanted on class factory.
- LPVOID FAR *ppv); // Return interface pointer here.
-
-extern MetaDataGetDispenserFunc metaDataGetDispenser;
extern WCHAR wzUniBuf[]; // Unicode conversion global buffer (assem.cpp)
if(bClock) bClock->cMDInitBegin = GetTickCount();
- hr = metaDataGetDispenser(CLSID_CorMetaDataDispenser,
+ hr = MetaDataGetDispenser(CLSID_CorMetaDataDispenser,
IID_IMetaDataDispenserEx, (void **)&m_pDisp);
if (FAILED(hr))
goto exit;
getJit
jitStartup
-DllMain
-PAL_RegisterModule
-PAL_UnregisterModule
return;
}
+#ifdef FEATURE_PAL
+ int err = PAL_InitializeDLL();
+ if (err != 0)
+ {
+ return;
+ }
+#endif
+
g_jitHost = jitHost;
assert(!JitConfig.isInitialized());
#ifndef FEATURE_MERGE_JIT_AND_ENGINE
-extern "C"
-#ifdef FEATURE_PAL
- DLLEXPORT // For Win32 PAL LoadLibrary emulation
-#endif
- BOOL WINAPI
- DllMain(HANDLE hInstance, DWORD dwReason, LPVOID pvReserved)
+extern "C" DLLEXPORT BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID pvReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DLLEXPORT ICorJitCompiler* __stdcall getJit()
{
+ if (!g_jitInitialized)
+ {
+ return nullptr;
+ }
+
if (ILJitter == nullptr)
{
ILJitter = new (CILJitSingleton) CILJit();
ERROR("Can not load the PAL module\n");
return FALSE;
}
- PDLLMAIN pRuntimeDllMain = (PDLLMAIN)dlsym(module->dl_handle, "CoreDllMain");
- if (!pRuntimeDllMain)
- {
- ERROR("Can not find the CoreDllMain entry point\n");
- return FALSE;
- }
- return pRuntimeDllMain(module->hinstance, DLL_PROCESS_ATTACH, nullptr);
+ return TRUE;
}
/*++
private ExceptionDispatchInfo _lastException;
- [DllImport(JitLibrary)]
- private extern static IntPtr PAL_RegisterModule([MarshalAs(UnmanagedType.LPUTF8Str)] string moduleName);
-
[DllImport(JitLibrary, CallingConvention=CallingConvention.StdCall)] // stdcall in CoreCLR!
private extern static IntPtr jitStartup(IntPtr host);
NativeLibrary.SetDllImportResolver(typeof(CorInfoImpl).Assembly, JitLibraryResolver);
}
- if (Environment.OSVersion.Platform == PlatformID.Unix)
- {
- // TODO: The PAL_RegisterModule export should be removed from the JIT
- // and the call to PAL_InitializeDLL should be moved to jitStartup.
- // https://github.com/dotnet/coreclr/issues/27941
- PAL_RegisterModule("libclrjitilc.so");
- }
-
jitStartup(GetJitHost(jitConfig.UnmanagedInstance));
}