Enable Debug IPC in CoreCLR.
Apply the following patches from upstream:
https://github.com/dotnet/coreclr/pull/13316
https://github.com/dotnet/coreclr/pull/13944
https://github.com/dotnet/coreclr/pull/17143
https://github.com/dotnet/coreclr/pull/17144
https://github.com/dotnet/coreclr/pull/16141
https://github.com/dotnet/coreclr/pull/17436
https://github.com/dotnet/coreclr/pull/17458
https://github.com/dotnet/coreclr/pull/15993
https://github.com/dotnet/coreclr/pull/14296
https://github.com/dotnet/coreclr/pull/14254
https://github.com/dotnet/coreclr/pull/12646
https://github.com/dotnet/coreclr/pull/14078
Also includes 2 fixes (x86/Linux):
* Crash in EECodeManager::GetAmbientSP when SP is not available
* Crash in OOPStackUnwinderX86::Unwind when Eip is invalid
Change-Id: Ic87943a1ae5728cbb853b558a1f313749b7a3131
--- /dev/null
+From a181764876c53aab4e1842ad0af3a3d56d8142c7 Mon Sep 17 00:00:00 2001
+From: Igor Kulaychuk <igor.kulaychuk@gmail.com>
+Date: Tue, 15 Aug 2017 00:30:56 +0300
+Subject: [PATCH 1/5] [Linux/ARM] Fix managed breakpoints (#13316)
+
+* [Linux/ARM] Fix managed breakpoints
+
+This commit introduces the following changes in order to enable
+ICorDebug-based debuggers to use breakpoints on ARM Linux:
+
+* Use 0xde01 as breakpoint instruction on ARM Linux.
+ ARM reference recommends to use 0xdefe as a breakpoint instruction,
+ but Linux kernel generates SIGILL for this instruction.
+ The 0xde01 instruction causes the kernel to generate SIGTRAP.
+
+* Fix SIGTRAP handling on ARM Linux.
+ Unlike x86, when SIGTRAP happens on ARM Linux, the PC points
+ at the break instruction. But the rest of the code expects
+ that it points to an instruction after the break,
+ so we adjust the PC at the start of HandleHardwareException().
+
+* Enable ARM single stepping for PAL.
+ Handle single stepping for PAL path the same way as for non-PAL path.
+ Also enable ArmSingleStepper executable buffer by allocating it
+ from system global loader executable heap.
+
+* Hande ARM single step only when debugger is attached, fix comments and code style
+
+* Pass existing Thread object to HandleArmSingleStep
+---
+ src/debug/inc/arm/primitives.h | 4 ++++
+ src/vm/arm/armsinglestepper.cpp | 12 ++++++++++--
+ src/vm/arm/cgencpu.h | 4 ++++
+ src/vm/armsinglestepper.h | 4 ++++
+ src/vm/exceptionhandling.cpp | 35 +++++++++++++++++++++++++++++++++++
+ 5 files changed, 57 insertions(+), 2 deletions(-)
+
+diff --git a/src/debug/inc/arm/primitives.h b/src/debug/inc/arm/primitives.h
+index 0bac542..1cceeff 100644
+--- a/src/debug/inc/arm/primitives.h
++++ b/src/debug/inc/arm/primitives.h
+@@ -30,7 +30,11 @@ typedef DPTR(CORDB_ADDRESS_TYPE) PTR_CORDB_ADDRESS_TYPE;
+ #define STACKWALK_CONTROLPC_ADJUST_OFFSET 2
+
+ #define CORDbg_BREAK_INSTRUCTION_SIZE 2
++#ifdef __linux__
++#define CORDbg_BREAK_INSTRUCTION (USHORT)0xde01
++#else
+ #define CORDbg_BREAK_INSTRUCTION (USHORT)0xdefe
++#endif
+
+ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr)
+ {
+diff --git a/src/vm/arm/armsinglestepper.cpp b/src/vm/arm/armsinglestepper.cpp
+index e000959..bfe8824 100644
+--- a/src/vm/arm/armsinglestepper.cpp
++++ b/src/vm/arm/armsinglestepper.cpp
+@@ -97,17 +97,25 @@ ArmSingleStepper::ArmSingleStepper()
+
+ ArmSingleStepper::~ArmSingleStepper()
+ {
+-#if !defined(DACCESS_COMPILE) && !defined(FEATURE_PAL)
++#if !defined(DACCESS_COMPILE)
++#ifdef FEATURE_PAL
++ SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()->BackoutMem(m_rgCode, kMaxCodeBuffer * sizeof(WORD));
++#else
+ DeleteExecutable(m_rgCode);
+ #endif
++#endif
+ }
+
+ void ArmSingleStepper::Init()
+ {
+-#if !defined(DACCESS_COMPILE) && !defined(FEATURE_PAL)
++#if !defined(DACCESS_COMPILE)
+ if (m_rgCode == NULL)
+ {
++#ifdef FEATURE_PAL
++ m_rgCode = (WORD *)(void *)SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap()->AllocMem(S_SIZE_T(kMaxCodeBuffer * sizeof(WORD)));
++#else
+ m_rgCode = new (executable) WORD[kMaxCodeBuffer];
++#endif
+ }
+ #endif
+ }
+diff --git a/src/vm/arm/cgencpu.h b/src/vm/arm/cgencpu.h
+index 6f128f6..2a369d8 100644
+--- a/src/vm/arm/cgencpu.h
++++ b/src/vm/arm/cgencpu.h
+@@ -566,7 +566,11 @@ public:
+ // a reasonable breakpoint substitute (it's what DebugBreak uses). Bkpt #0, on the other hand, always
+ // seems to flow directly to the kernel debugger (even if we ignore it there it doesn't seem to be
+ // picked up by the user mode debugger).
++#ifdef __linux__
++ Emit16(0xde01);
++#else
+ Emit16(0xdefe);
++#endif
+ }
+
+ void ThumbEmitMovConstant(ThumbReg dest, int constant)
+diff --git a/src/vm/armsinglestepper.h b/src/vm/armsinglestepper.h
+index 53a1019..8893525 100644
+--- a/src/vm/armsinglestepper.h
++++ b/src/vm/armsinglestepper.h
+@@ -88,7 +88,11 @@ private:
+ kMaxCodeBuffer = 2 + 3 + 1, // WORD slots in our redirect buffer (2 for current instruction, 3 for
+ // breakpoint instructions used to pad out slots in an IT block and one
+ // for the final breakpoint)
++#ifdef __linux__
++ kBreakpointOp = 0xde01, // Opcode for the breakpoint instruction used on ARM Linux
++#else
+ kBreakpointOp = 0xdefe, // Opcode for the breakpoint instruction used on CoreARM
++#endif
+ };
+
+ // Bit numbers of the condition flags in the CPSR.
+diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
+index 2802f73..7ed4375 100644
+--- a/src/vm/exceptionhandling.cpp
++++ b/src/vm/exceptionhandling.cpp
+@@ -5176,6 +5176,38 @@ BOOL IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD e
+ IsIPInMarkedJitHelper(controlPc));
+ }
+
++#ifdef _TARGET_ARM_
++static inline BOOL HandleArmSingleStep(PCONTEXT pContext, PEXCEPTION_RECORD pExceptionRecord, Thread *pThread)
++{
++#ifdef __linux__
++ // On ARM Linux exception point to the break instruction,
++ // but the rest of the code expects that it points to an instruction after the break
++ if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
++ {
++ SetIP(pContext, GetIP(pContext) + CORDbg_BREAK_INSTRUCTION_SIZE);
++ pExceptionRecord->ExceptionAddress = (void *)GetIP(pContext);
++ }
++#endif
++ // On ARM we don't have any reliable hardware support for single stepping so it is emulated in software.
++ // The implementation will end up throwing an EXCEPTION_BREAKPOINT rather than an EXCEPTION_SINGLE_STEP
++ // and leaves other aspects of the thread context in an invalid state. Therefore we use this opportunity
++ // to fixup the state before any other part of the system uses it (we do it here since only the debugger
++ // uses single step functionality).
++
++ // First ask the emulation itself whether this exception occurred while single stepping was enabled. If so
++ // it will fix up the context to be consistent again and return true. If so and the exception was
++ // EXCEPTION_BREAKPOINT then we translate it to EXCEPTION_SINGLE_STEP (otherwise we leave it be, e.g. the
++ // instruction stepped caused an access violation).
++ if (pThread->HandleSingleStep(pContext, pExceptionRecord->ExceptionCode) && (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT))
++ {
++ pExceptionRecord->ExceptionCode = EXCEPTION_SINGLE_STEP;
++ pExceptionRecord->ExceptionAddress = (void *)GetIP(pContext);
++ return TRUE;
++ }
++ return FALSE;
++}
++#endif // _TARGET_ARM_
++
+ BOOL HandleHardwareException(PAL_SEHException* ex)
+ {
+ _ASSERTE(IsSafeToHandleHardwareException(ex->GetContextRecord(), ex->GetExceptionRecord()));
+@@ -5239,6 +5271,9 @@ BOOL HandleHardwareException(PAL_SEHException* ex)
+ Thread *pThread = GetThread();
+ if (pThread != NULL && g_pDebugInterface != NULL)
+ {
++#ifdef _TARGET_ARM_
++ HandleArmSingleStep(ex->GetContextRecord(), ex->GetExceptionRecord(), pThread);
++#endif
+ if (ex->GetExceptionRecord()->ExceptionCode == STATUS_BREAKPOINT)
+ {
+ // If this is breakpoint context, it is set up to point to an instruction after the break instruction.
+--
+2.7.4
+
--- /dev/null
+From e42ba780f56c26a5e4ec35a1070d3313f0c45998 Mon Sep 17 00:00:00 2001
+From: Bruce Forstall <brucefo@microsoft.com>
+Date: Fri, 15 Sep 2017 10:25:01 -0700
+Subject: [PATCH 2/5] Merge pull request #13944 from
+ ayuckhulk/fix-arm-set-debuggerregdisplay-from-context
+
+[ARM] Fix SetDebuggerREGDISPLAYFromREGDISPLAY() function
+---
+ src/debug/shared/arm/primitives.cpp | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/src/debug/shared/arm/primitives.cpp b/src/debug/shared/arm/primitives.cpp
+index e9d0bbd..8771dd9 100644
+--- a/src/debug/shared/arm/primitives.cpp
++++ b/src/debug/shared/arm/primitives.cpp
+@@ -80,8 +80,15 @@ void CORDbgSetDebuggerREGDISPLAYFromContext(DebuggerREGDISPLAY *pDRD,
+ void SetDebuggerREGDISPLAYFromREGDISPLAY(DebuggerREGDISPLAY* pDRD, REGDISPLAY* pRD)
+ {
+ SUPPORTS_DAC_HOST_ONLY;
+-
++ // CORDbgSetDebuggerREGDISPLAYFromContext() checks the context flags. In cases where we don't have a filter
++ // context from the thread, we initialize a CONTEXT on the stack and use that to do our stack walking. We never
++ // initialize the context flags in such cases. Since this function is called from the stackwalker, we can
++ // guarantee that the integer, control, and floating point sections are valid. So we set the flags here and
++ // restore them afterwards.
++ DWORD contextFlags = pRD->pCurrentContext->ContextFlags;
++ pRD->pCurrentContext->ContextFlags = CONTEXT_FULL;
+ CORDbgSetDebuggerREGDISPLAYFromContext(pDRD, reinterpret_cast<DT_CONTEXT*>(pRD->pCurrentContext));
++ pRD->pCurrentContext->ContextFlags = contextFlags;
+
+ pDRD->SP = pRD->SP;
+ pDRD->PC = (SIZE_T)*(pRD->pPC);
+--
+2.7.4
+
--- /dev/null
+From 2a6ac3cb557019c31d70510cf0ce5277d3eedd6d Mon Sep 17 00:00:00 2001
+From: Igor Kulaychuk <igor.kulaychuk@gmail.com>
+Date: Fri, 23 Mar 2018 14:12:54 +0300
+Subject: [PATCH 3/5] Fix Linux/x86 FuncEvalHijack stack alignment (#17143)
+
+---
+ src/debug/ee/i386/dbghelpers.S | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/debug/ee/i386/dbghelpers.S b/src/debug/ee/i386/dbghelpers.S
+index d0a1101..f15ca5a 100644
+--- a/src/debug/ee/i386/dbghelpers.S
++++ b/src/debug/ee/i386/dbghelpers.S
+@@ -9,10 +9,14 @@
+
+ // @dbgtodo- once we port Funceval, use the ExceptionHijack stub instead of this func-eval stub.
+ NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix
++#define STK_ALIGN_PADDING 12
++ sub esp, STK_ALIGN_PADDING
+ push eax // the ptr to the DebuggerEval
++ CHECK_STACK_ALIGNMENT
+ call C_FUNC(FuncEvalHijackWorker)
++ add esp, (4 + STK_ALIGN_PADDING)
+ jmp eax // return is the patch addresss to jmp to
+-
++#undef STK_ALIGN_PADDING
+ NESTED_END FuncEvalHijack, _TEXT
+
+ //
+--
+2.7.4
+
--- /dev/null
+From 0a8faa1c58f1a60c3ff60e89b7bd1ae36afa1733 Mon Sep 17 00:00:00 2001
+From: Igor Kulaychuk <igor.kulaychuk@gmail.com>
+Date: Mon, 26 Mar 2018 20:58:16 +0300
+Subject: [PATCH 4/5] Fix funclet unwinding on x86 Linux (#17144)
+
+---
+ src/vm/eetwain.cpp | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
+index 4a02be7..fbf669b 100644
+--- a/src/vm/eetwain.cpp
++++ b/src/vm/eetwain.cpp
+@@ -3832,8 +3832,27 @@ bool UnwindEbpDoubleAlignFrame(
+ baseSP = curESP;
+ // Set baseSP as initial SP
+ baseSP += GetPushedArgSize(info, table, curOffs);
++
+ // 16-byte stack alignment padding (allocated in genFuncletProlog)
+- baseSP += 12;
++ // Current funclet frame layout (see CodeGen::genFuncletProlog() and genFuncletEpilog()):
++ // prolog: sub esp, 12
++ // epilog: add esp, 12
++ // ret
++ // SP alignment padding should be added for all instructions except the first one and the last one.
++ TADDR funcletStart = pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo);
++
++ const ULONG32 funcletLastInstSize = 1; // 0xc3, ret
++ BOOL atFuncletLastInst = (pCodeInfo->GetRelOffset() + funcletLastInstSize) >= info->methodSize;
++ if (!atFuncletLastInst)
++ {
++ EECodeInfo nextCodeInfo;
++ nextCodeInfo.Init(pCodeInfo->GetCodeAddress() + funcletLastInstSize);
++ atFuncletLastInst = !nextCodeInfo.IsValid() || !nextCodeInfo.IsFunclet() ||
++ nextCodeInfo.GetJitManager()->GetFuncletStartAddress(&nextCodeInfo) != funcletStart;
++ }
++
++ if (!atFuncletLastInst && funcletStart != pCodeInfo->GetCodeAddress())
++ baseSP += 12;
+
+ pContext->PCTAddr = baseSP;
+ pContext->ControlPC = *PTR_PCODE(pContext->PCTAddr);
+--
+2.7.4
+
--- /dev/null
+From 5ef830ea09d6e0794427f78ea3564cc7c4b6c121 Mon Sep 17 00:00:00 2001
+From: Igor Kulaychuk <i.kulaychuk@samsung.com>
+Date: Mon, 19 Feb 2018 16:09:31 +0300
+Subject: [PATCH 5/5] Add environment variable (COMPlus_EnableDiagnostics) to
+ disable debugging and profiling.
+
+To disable the named pipes and semaphores created on linux execute "export COMPlus_EnableDiagnostics=0" before start the .NET Core program.
+
+On Windows execute "set COMPlus_EnableDiagnostics=0" and on Linux execute "export "COMPlus_EnableDiagnostics=0"
+
+Removed the "Telesto" registry entry (old unnecessary Silverlight code) and Watson (always true) checks.
+
+For issues #11769 and #8844.
+
+Backport of PR #15878
+
+Change-Id: I39ffaaef0bcaff4e9efb9675c6f2834a343faea3
+---
+ src/debug/daccess/enummem.cpp | 19 +++++----
+ src/debug/ee/debugger.cpp | 92 ++++++++++++++-----------------------------
+ src/debug/ee/debugger.h | 4 +-
+ src/inc/clrconfigvalues.h | 3 +-
+ 4 files changed, 44 insertions(+), 74 deletions(-)
+
+diff --git a/src/debug/daccess/enummem.cpp b/src/debug/daccess/enummem.cpp
+index ebe0fc8..f9fa29a 100644
+--- a/src/debug/daccess/enummem.cpp
++++ b/src/debug/daccess/enummem.cpp
+@@ -281,10 +281,10 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_runtimeLoadedBaseAddress.EnumMem(); )
+ #endif // !FEATURE_PAL
+
+- // These are the structures that are pointed by global pointers and we care.
+- // Some may reside in heap and some may reside as a static byte array in mscorwks.dll
+- // That is ok. We will report them explicitly.
+- //
++ // These are the structures that are pointed by global pointers and we care.
++ // Some may reside in heap and some may reside as a static byte array in mscorwks.dll
++ // That is ok. We will report them explicitly.
++ //
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pConfig.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pPredefinedArrayTypes.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pObjectClass.EnumMem(); )
+@@ -304,14 +304,17 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pObjectCtorMD.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_fHostConfig.EnumMem(); )
+
+- // These two static pointers are pointed to static data of byte[]
+- // then run constructor in place
+- //
++ // These two static pointers are pointed to static data of byte[]
++ // then run constructor in place
++ //
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( SystemDomain::m_pSystemDomain.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( SharedDomain::m_pSharedDomain.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pDebugger.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pEEInterface.EnumMem(); )
+- CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pDebugInterface.EnumMem(); )
++ if (g_pDebugInterface != nullptr)
++ {
++ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED(g_pDebugInterface.EnumMem(); )
++ }
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pEEDbgInterfaceImpl.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_CORDebuggerControlFlags.EnumMem(); )
+ CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_Mscorlib.EnumMem(); )
+diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp
+index ae698e2..d3f35df 100644
+--- a/src/debug/ee/debugger.cpp
++++ b/src/debug/ee/debugger.cpp
+@@ -1886,29 +1886,6 @@ CLR_ENGINE_METRICS g_CLREngineMetrics = {
+ CorDebugVersion_4_0,
+ &g_hContinueStartupEvent};
+
+-
+-bool IsTelestoDebugPackInstalled()
+-{
+- RegKeyHolder hKey;
+- if (ERROR_SUCCESS != WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, FRAMEWORK_REGISTRY_KEY_W, 0, KEY_READ, &hKey))
+- return false;
+-
+- bool debugPackInstalled = false;
+-
+- DWORD cbValue = 0;
+-
+- if (ERROR_SUCCESS == WszRegQueryValueEx(hKey, CLRConfig::EXTERNAL_DbgPackShimPath, NULL, NULL, NULL, &cbValue))
+- {
+- if (cbValue != 0)
+- {
+- debugPackInstalled = true;
+- }
+- }
+-
+- // RegCloseKey called by holder
+- return debugPackInstalled;
+-}
+-
+ #define StartupNotifyEventNamePrefix W("TelestoStartupEvent_")
+ const int cchEventNameBufferSize = sizeof(StartupNotifyEventNamePrefix)/sizeof(WCHAR) + 8; // + hex DWORD (8). NULL terminator is included in sizeof(StartupNotifyEventNamePrefix)
+ HANDLE OpenStartupNotificationEvent()
+@@ -1920,7 +1897,7 @@ HANDLE OpenStartupNotificationEvent()
+ return WszOpenEvent(EVENT_ALL_ACCESS, FALSE, szEventName);
+ }
+
+-void NotifyDebuggerOfTelestoStartup()
++void NotifyDebuggerOfStartup()
+ {
+ // Create the continue event first so that we guarantee that any
+ // enumeration of this process will get back a valid continue event
+@@ -1981,26 +1958,9 @@ HRESULT Debugger::Startup(void)
+ _ASSERTE(g_pEEInterface != NULL);
+
+ #if !defined(FEATURE_PAL)
+- if (IsWatsonEnabled() || IsTelestoDebugPackInstalled())
+- {
+- // Iff the debug pack is installed, then go through the telesto debugging pipeline.
+- LOG((LF_CORDB, LL_INFO10, "Debugging service is enabled because debug pack is installed or Watson support is enabled)\n"));
+-
+- // This may block while an attach occurs.
+- NotifyDebuggerOfTelestoStartup();
+- }
+- else
+- {
+- // On Windows, it's actually safe to finish the initialization here even without the debug pack.
+- // However, doing so causes a perf regression because we used to bail out early if the debug
+- // pack is not installed.
+- //
+- // Unlike Windows, we can't continue executing this function if the debug pack is not installed.
+- // The transport requires the debug pack to be present. Otherwise it'll raise a fatal error.
+- return S_FALSE;
+- }
++ // This may block while an attach occurs.
++ NotifyDebuggerOfStartup();
+ #endif // !FEATURE_PAL
+-
+ {
+ DebuggerLockHolder dbgLockHolder(this);
+
+@@ -2011,7 +1971,6 @@ HRESULT Debugger::Startup(void)
+ // threads running and throwing debug events. Keep these stress procs separate so that
+ // we can focus on certain problem areas.
+ #ifdef _DEBUG
+-
+ g_DbgShouldntUseDebugger = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgNoDebugger) != 0;
+
+
+@@ -2079,6 +2038,29 @@ HRESULT Debugger::Startup(void)
+
+ InitializeHijackFunctionAddress();
+
++ // Also initialize the AppDomainEnumerationIPCBlock
++ #if !defined(FEATURE_IPCMAN) || defined(FEATURE_DBGIPC_TRANSPORT_VM)
++ m_pAppDomainCB = new (nothrow) AppDomainEnumerationIPCBlock();
++ #else
++ m_pAppDomainCB = g_pIPCManagerInterface->GetAppDomainBlock();
++ #endif
++
++ if (m_pAppDomainCB == NULL)
++ {
++ LOG((LF_CORDB, LL_INFO100, "D::S: Failed to get AppDomain IPC block from IPCManager.\n"));
++ ThrowHR(E_FAIL);
++ }
++
++ hr = InitAppDomainIPC();
++ _ASSERTE(SUCCEEDED(hr)); // throws on error.
++
++ // Allows the debugger (and profiler) diagnostics to be disabled so resources like
++ // the named pipes and semaphores are not created.
++ if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableDiagnostics) == 0)
++ {
++ return S_OK;
++ }
++
+ // Create the runtime controller thread, a.k.a, the debug helper thread.
+ // Don't use the interop-safe heap b/c we don't want to lazily create it.
+ m_pRCThread = new DebuggerRCThread(this);
+@@ -2104,22 +2086,6 @@ HRESULT Debugger::Startup(void)
+
+ RaiseStartupNotification();
+
+- // Also initialize the AppDomainEnumerationIPCBlock
+- #if !defined(FEATURE_IPCMAN) || defined(FEATURE_DBGIPC_TRANSPORT_VM)
+- m_pAppDomainCB = new (nothrow) AppDomainEnumerationIPCBlock();
+- #else
+- m_pAppDomainCB = g_pIPCManagerInterface->GetAppDomainBlock();
+- #endif
+-
+- if (m_pAppDomainCB == NULL)
+- {
+- LOG((LF_CORDB, LL_INFO100, "D::S: Failed to get AppDomain IPC block from IPCManager.\n"));
+- ThrowHR(E_FAIL);
+- }
+-
+- hr = InitAppDomainIPC();
+- _ASSERTE(SUCCEEDED(hr)); // throws on error.
+-
+ // See if we need to spin up the helper thread now, rather than later.
+ DebuggerIPCControlBlock* pIPCControlBlock = m_pRCThread->GetDCB();
+ (void)pIPCControlBlock; //prevent "unused variable" error from GCC
+@@ -7192,7 +7158,8 @@ void Debugger::JitAttach(Thread * pThread, EXCEPTION_POINTERS * pExceptionInfo,
+ }
+ CONTRACTL_END;
+
+- if (IsDebuggerPresent())
++ // Don't do anything if there is a native debugger already attached or the debugging support has been disabled.
++ if (IsDebuggerPresent() || m_pRCThread == NULL)
+ return;
+
+ GCX_PREEMP_EEINTERFACE_TOGGLE_IFTHREAD();
+@@ -14140,8 +14107,7 @@ DWORD Debugger::GetHelperThreadID(void )
+ {
+ LIMITED_METHOD_CONTRACT;
+
+- return m_pRCThread->GetDCB()
+- ->m_temporaryHelperThreadId;
++ return m_pRCThread ? m_pRCThread->GetDCB()->m_temporaryHelperThreadId : 0;
+ }
+
+
+diff --git a/src/debug/ee/debugger.h b/src/debug/ee/debugger.h
+index f99931e..6758c92 100644
+--- a/src/debug/ee/debugger.h
++++ b/src/debug/ee/debugger.h
+@@ -3944,10 +3944,10 @@ protected:
+ #if _DEBUG
+
+ #define MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT \
+- if (!m_pRCThread->IsRCThreadReady()) { THROWS; } else { NOTHROW; }
++ if ((m_pRCThread == NULL) || !m_pRCThread->IsRCThreadReady()) { THROWS; } else { NOTHROW; }
+
+ #define MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT \
+- if (!m_pRCThread->IsRCThreadReady() || (GetThread() != NULL)) { GC_TRIGGERS; } else { GC_NOTRIGGER; }
++ if ((m_pRCThread == NULL) || !m_pRCThread->IsRCThreadReady() || (GetThread() != NULL)) { GC_TRIGGERS; } else { GC_NOTRIGGER; }
+
+ #define GC_TRIGGERS_FROM_GETJITINFO if (GetThreadNULLOk() != NULL) { GC_TRIGGERS; } else { GC_NOTRIGGER; }
+
+diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h
+index c4722bc..86046d9 100644
+--- a/src/inc/clrconfigvalues.h
++++ b/src/inc/clrconfigvalues.h
+@@ -199,7 +199,8 @@ CONFIG_DWORD_INFO_EX(INTERNAL_D__FCE, W("D::FCE"), 0, "allows an assert when cra
+ //
+ // Debugger
+ //
+-CONFIG_DWORD_INFO_EX(INTERNAL_DbgBreakIfLocksUnavailable, W("DbgBreakIfLocksUnavailable"), 0, "allows an assert when the debugger can't take a lock ", CLRConfig::REGUTIL_default)
++RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_EnableDiagnostics, W("EnableDiagnostics"), 1, "allows the debugger and profiler diagnostics to be disabled", CLRConfig::REGUTIL_default)
++CONFIG_DWORD_INFO_EX(INTERNAL_DbgBreakIfLocksUnavailable, W("DbgBreakIfLocksUnavailable"), 0, "allows an assert when the debugger can't take a lock", CLRConfig::REGUTIL_default)
+ CONFIG_DWORD_INFO_EX(INTERNAL_DbgBreakOnErr, W("DbgBreakOnErr"), 0, "allows an assert when we get a failing hresult", CLRConfig::REGUTIL_default)
+ CONFIG_DWORD_INFO_EX(INTERNAL_DbgBreakOnMapPatchToDJI, W("DbgBreakOnMapPatchToDJI"), 0, "allows an assert when mapping a patch to an address", CLRConfig::REGUTIL_default)
+ CONFIG_DWORD_INFO_EX(INTERNAL_DbgBreakOnRawInt3, W("DbgBreakOnRawInt3"), 0, "allows an assert for test coverage for debug break or other int3 breaks", CLRConfig::REGUTIL_default)
+--
+2.7.4
+
--- /dev/null
+From 89471c935995146d2079bd830dd85839caad660a Mon Sep 17 00:00:00 2001
+From: Igor Kulaychuk <i.kulaychuk@samsung.com>
+Date: Thu, 5 Apr 2018 22:02:48 +0300
+Subject: [PATCH 6/7] Fix x86/Linux ICorDebug frames API
+
+---
+ src/debug/di/rspriv.h | 4 ++--
+ src/debug/di/rsthread.cpp | 30 +++++++++++++++---------------
+ 2 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/src/debug/di/rspriv.h b/src/debug/di/rspriv.h
+index d714517..a28e7d9 100644
+--- a/src/debug/di/rspriv.h
++++ b/src/debug/di/rspriv.h
+@@ -7113,10 +7113,10 @@ public:
+ bool IsFunclet();
+ bool IsFilterFunclet();
+
+-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
++#ifdef WIN64EXCEPTIONS
+ // return the offset of the parent method frame at which an exception occurs
+ SIZE_T GetParentIP();
+-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
++#endif // WIN64EXCEPTIONS
+
+ TADDR GetAmbientESP() { return m_taAmbientESP; }
+ TADDR GetReturnRegisterValue();
+diff --git a/src/debug/di/rsthread.cpp b/src/debug/di/rsthread.cpp
+index aa85de8..f027e11 100644
+--- a/src/debug/di/rsthread.cpp
++++ b/src/debug/di/rsthread.cpp
+@@ -5867,11 +5867,11 @@ const DT_CONTEXT * CordbRuntimeUnwindableFrame::GetContext() const
+ // default constructor to make the compiler happy
+ CordbMiscFrame::CordbMiscFrame()
+ {
+-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
++#ifdef WIN64EXCEPTIONS
+ this->parentIP = 0;
+ this->fpParentOrSelf = LEAF_MOST_FRAME;
+ this->fIsFilterFunclet = false;
+-#endif // _WIN64
++#endif // WIN64EXCEPTIONS
+ }
+
+ // the real constructor which stores the funclet-related information in the CordbMiscFrame
+@@ -6341,7 +6341,7 @@ HRESULT CordbNativeFrame::IsMatchingParentFrame(ICorDebugNativeFrame2 * pPotenti
+ ThrowHR(CORDBG_E_NOT_CHILD_FRAME);
+ }
+
+-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
++#ifdef WIN64EXCEPTIONS
+ CordbNativeFrame * pFrameToCheck = static_cast<CordbNativeFrame *>(pPotentialParentFrame);
+ if (pFrameToCheck->IsFunclet())
+ {
+@@ -6355,7 +6355,7 @@ HRESULT CordbNativeFrame::IsMatchingParentFrame(ICorDebugNativeFrame2 * pPotenti
+ IDacDbiInterface * pDAC = GetProcess()->GetDAC();
+ *pIsParent = pDAC->IsMatchingParentFrame(fpToCheck, fpParent);
+ }
+-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
++#endif // WIN64EXCEPTIONS
+ }
+ EX_CATCH_HRESULT(hr);
+
+@@ -7444,14 +7444,14 @@ bool CordbNativeFrame::IsLeafFrame() const
+
+ SIZE_T CordbNativeFrame::GetInspectionIP()
+ {
+-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
++#ifdef WIN64EXCEPTIONS
+ // On 64-bit, if this is a funclet, then return the offset of the parent method frame at which
+ // the exception occurs. Otherwise just return the normal offset.
+ return (IsFunclet() ? GetParentIP() : m_ip);
+ #else
+ // Always return the normal offset on all other platforms.
+ return m_ip;
+-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
++#endif // WIN64EXCEPTIONS
+ }
+
+ //---------------------------------------------------------------------------------------
+@@ -7464,11 +7464,11 @@ SIZE_T CordbNativeFrame::GetInspectionIP()
+
+ bool CordbNativeFrame::IsFunclet()
+ {
+-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
++#ifdef WIN64EXCEPTIONS
+ return (m_misc.parentIP != NULL);
+-#else // !DBG_TARGET_WIN64 && !DBG_TARGET_ARM
++#else
+ return false;
+-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
++#endif // WIN64EXCEPTIONS
+ }
+
+ //---------------------------------------------------------------------------------------
+@@ -7481,15 +7481,15 @@ bool CordbNativeFrame::IsFunclet()
+
+ bool CordbNativeFrame::IsFilterFunclet()
+ {
+-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
++#ifdef WIN64EXCEPTIONS
+ return (IsFunclet() && m_misc.fIsFilterFunclet);
+-#else // !DBG_TARGET_WIN64 && !DBG_TARGET_ARM
++#else
+ return false;
+-#endif // DBG_TARGET_WIN64
++#endif // WIN64EXCEPTIONS
+ }
+
+
+-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
++#ifdef WIN64EXCEPTIONS
+ //---------------------------------------------------------------------------------------
+ //
+ // Return the offset of the parent method frame at which the exception occurs.
+@@ -7502,7 +7502,7 @@ SIZE_T CordbNativeFrame::GetParentIP()
+ {
+ return m_misc.parentIP;
+ }
+-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
++#endif // WIN64EXCEPTIONS
+
+ // Accessor for the shim private hook code:CordbThread::ConvertFrameForILMethodWithoutMetadata.
+ // Refer to that function for comments on the return value, the argument, etc.
+@@ -8530,7 +8530,7 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type,
+
+ HRESULT hr = S_OK;
+
+-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
++#ifdef WIN64EXCEPTIONS
+ if (m_nativeFrame->IsFunclet())
+ {
+ if ( (pNativeVarInfo->loc.vlType != ICorDebugInfo::VLT_STK) &&
+--
+2.7.4
+
--- /dev/null
+From 965675df0087f4570dc4cfdbab9ddf99623a3186 Mon Sep 17 00:00:00 2001
+From: Igor Kulaychuk <i.kulaychuk@samsung.com>
+Date: Fri, 6 Apr 2018 18:11:37 +0300
+Subject: [PATCH 7/7] Fix unwinding of funclet with no epilog on x86/Linux
+
+---
+ src/vm/eetwain.cpp | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
+index fbf669b..a2ceb19 100644
+--- a/src/vm/eetwain.cpp
++++ b/src/vm/eetwain.cpp
+@@ -36,7 +36,8 @@
+ #define X86_INSTR_PUSH_EBP 0x55 // push ebp
+ #define X86_INSTR_W_MOV_EBP_ESP 0xEC8B // mov ebp, esp
+ #define X86_INSTR_POP_ECX 0x59 // pop ecx
+-#define X86_INSTR_RET 0xC2 // ret
++#define X86_INSTR_RET 0xC2 // ret imm16
++#define X86_INSTR_RETN 0xC3 // ret
+ #define X86_INSTR_w_LEA_ESP_EBP_BYTE_OFFSET 0x658d // lea esp, [ebp-bOffset]
+ #define X86_INSTR_w_LEA_ESP_EBP_DWORD_OFFSET 0xa58d // lea esp, [ebp-dwOffset]
+ #define X86_INSTR_JMP_NEAR_REL32 0xE9 // near jmp rel32
+@@ -3839,19 +3840,9 @@ bool UnwindEbpDoubleAlignFrame(
+ // epilog: add esp, 12
+ // ret
+ // SP alignment padding should be added for all instructions except the first one and the last one.
+- TADDR funcletStart = pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo);
+-
+- const ULONG32 funcletLastInstSize = 1; // 0xc3, ret
+- BOOL atFuncletLastInst = (pCodeInfo->GetRelOffset() + funcletLastInstSize) >= info->methodSize;
+- if (!atFuncletLastInst)
+- {
+- EECodeInfo nextCodeInfo;
+- nextCodeInfo.Init(pCodeInfo->GetCodeAddress() + funcletLastInstSize);
+- atFuncletLastInst = !nextCodeInfo.IsValid() || !nextCodeInfo.IsFunclet() ||
+- nextCodeInfo.GetJitManager()->GetFuncletStartAddress(&nextCodeInfo) != funcletStart;
+- }
+-
+- if (!atFuncletLastInst && funcletStart != pCodeInfo->GetCodeAddress())
++ // Epilog may not exist (unreachable), so we need to check the instruction code.
++ const TADDR funcletStart = pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo);
++ if (funcletStart != pCodeInfo->GetCodeAddress() && methodStart[pCodeInfo->GetRelOffset()] != X86_INSTR_RETN)
+ baseSP += 12;
+
+ pContext->PCTAddr = baseSP;
+--
+2.7.4
+
--- /dev/null
+From 8792e6c5e558d871524dc1c98b558934d8eb125c Mon Sep 17 00:00:00 2001
+From: Konstantin Baladurin <k.baladurin@partner.samsung.com>
+Date: Wed, 24 Jan 2018 13:26:37 +0300
+Subject: [PATCH 8/8] Fix HelperMethodFrame::UpdateRegDisplay
+
+For DAC after initialization MachState using InsureInit method,
+register pointers are NULL so we cannot use them to restore register
+values.
+---
+ src/vm/i386/cgenx86.cpp | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/src/vm/i386/cgenx86.cpp b/src/vm/i386/cgenx86.cpp
+index b4277db..08d0236 100644
+--- a/src/vm/i386/cgenx86.cpp
++++ b/src/vm/i386/cgenx86.cpp
+@@ -391,9 +391,11 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
+ pRD->pCurrentContext->Eip = pRD->ControlPC = pUnwoundState->GetRetAddr();
+ pRD->pCurrentContext->Esp = pRD->SP = pUnwoundState->esp();
+
+-#define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContext->regname = *((DWORD*) pUnwoundState->p##regname());
+- ENUM_CALLEE_SAVED_REGISTERS();
+-#undef CALLEE_SAVED_REGISTER
++ // Do not use pUnwoundState->p##regname() here because it returns NULL in this case
++ pRD->pCurrentContext->Edi = pUnwoundState->_edi;
++ pRD->pCurrentContext->Esi = pUnwoundState->_esi;
++ pRD->pCurrentContext->Ebx = pUnwoundState->_ebx;
++ pRD->pCurrentContext->Ebp = pUnwoundState->_ebp;
+
+ #define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContextPointers->regname = (DWORD*) pUnwoundState->p##regname();
+ ENUM_CALLEE_SAVED_REGISTERS();
+--
+2.7.4
+
--- /dev/null
+From e54eebdd33964dd48eb781b46acf79c7460c731c Mon Sep 17 00:00:00 2001
+From: Konstantin Baladurin <k.baladurin@partner.samsung.com>
+Date: Tue, 3 Oct 2017 10:36:34 +0300
+Subject: [PATCH 09/10] Fix regdisplay initialization in case of
+ WIN64EXCEPTIONS
+
+Method Debugger::IsThreadAtSafePlaceWorker for x86 sets values only
+for ControlPC and PCTAddr fields of REGDISPLAY but there is assert
+in StackFrameIterator::Init that checks that field pCurrentContext
+is not NULL if WIN64EXCEPTIONS is defined.
+
+This patch uses FillRegDisplay function to correctly initialize
+regdisplay in case of WIN64EXCEPTIONS.
+---
+ src/debug/ee/debugger.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp
+index d3f35df..944c5ba 100644
+--- a/src/debug/ee/debugger.cpp
++++ b/src/debug/ee/debugger.cpp
+@@ -12532,7 +12532,7 @@ bool Debugger::IsThreadAtSafePlaceWorker(Thread *thread)
+ CONTEXT ctx;
+ ZeroMemory(&rd, sizeof(rd));
+ ZeroMemory(&ctx, sizeof(ctx));
+-#if defined(_TARGET_X86_)
++#if defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS)
+ rd.ControlPC = ctx.Eip;
+ rd.PCTAddr = (TADDR)&(ctx.Eip);
+ #else
+--
+2.7.4
+
--- /dev/null
+From 33e3ecb696dd352fae67dc9a5568c903bed2a867 Mon Sep 17 00:00:00 2001
+From: Konstantin Baladurin <k.baladurin@partner.samsung.com>
+Date: Fri, 29 Sep 2017 15:42:30 +0300
+Subject: [PATCH 10/10] Fix CopyREGDISPLAY for WIN64EXCEPTIONS
+
+When WIN64EXCEPTIONS is defined, fields pCurrentContextPointers,
+pCallerContextPointers, pCurrentContext and pCallerContext of the
+REGDISPLAY are used. So we need to fix their values after coping.
+---
+ src/debug/ee/i386/debuggerregdisplayhelper.cpp | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/src/debug/ee/i386/debuggerregdisplayhelper.cpp b/src/debug/ee/i386/debuggerregdisplayhelper.cpp
+index 576fdeb..86927b7 100644
+--- a/src/debug/ee/i386/debuggerregdisplayhelper.cpp
++++ b/src/debug/ee/i386/debuggerregdisplayhelper.cpp
+@@ -15,4 +15,28 @@
+ void CopyREGDISPLAY(REGDISPLAY* pDst, REGDISPLAY* pSrc)
+ {
+ *pDst = *pSrc;
++
++#ifdef WIN64EXCEPTIONS
++ if (pSrc->pCurrentContextPointers == &(pSrc->ctxPtrsOne))
++ {
++ pDst->pCurrentContextPointers = &(pDst->ctxPtrsOne);
++ pDst->pCallerContextPointers = &(pDst->ctxPtrsTwo);
++ }
++ else
++ {
++ pDst->pCurrentContextPointers = &(pDst->ctxPtrsTwo);
++ pDst->pCallerContextPointers = &(pDst->ctxPtrsOne);
++ }
++
++ if (pSrc->pCurrentContext == &(pSrc->ctxOne))
++ {
++ pDst->pCurrentContext = &(pDst->ctxOne);
++ pDst->pCallerContext = &(pDst->ctxTwo);
++ }
++ else
++ {
++ pDst->pCurrentContext = &(pDst->ctxTwo);
++ pDst->pCallerContext = &(pDst->ctxOne);
++ }
++#endif
+ }
+--
+2.7.4
+
--- /dev/null
+From d37538bb656ba27f008c00f3eb3adf1a5a221be1 Mon Sep 17 00:00:00 2001
+From: Jonghyun Park <parjong@gmail.com>
+Date: Tue, 4 Jul 2017 17:25:20 +0900
+Subject: [PATCH 11/12] Enable thread-abort reraise loop prevention
+
+---
+ src/vm/exceptionhandling.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
+index 7ed4375..a35f009 100644
+--- a/src/vm/exceptionhandling.cpp
++++ b/src/vm/exceptionhandling.cpp
+@@ -1482,7 +1482,7 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
+ #endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
+ }
+
+-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
++#ifdef ADJUST_PC_UNWOUND_TO_CALL
+ // Further below, we will adjust the ControlPC based upon whether we are at a callsite or not.
+ // We need to do this for "RegDisplay.ControlPC" field as well so that when data structures like
+ // EECodeInfo initialize themselves using this field, they will have the correct absolute value
+@@ -1501,12 +1501,12 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
+ fAdjustRegdisplayControlPC = true;
+
+ }
++#endif // ADJUST_PC_UNWOUND_TO_CALL
+
+ #if defined(_TARGET_ARM_)
+ // Remove the Thumb bit
+ ControlPCForEHSearch = ThumbCodeToDataPointer<DWORD_PTR, DWORD_PTR>(ControlPCForEHSearch);
+ #endif
+-#endif // _TARGET_ARM_ || _TARGET_ARM64_
+
+ #ifdef ADJUST_PC_UNWOUND_TO_CALL
+ // If the OS indicated that the IP is a callsite, then adjust the ControlPC by decrementing it
+--
+2.7.4
+
--- /dev/null
+From 960d37a40a4c2d95df3c39b2e161631b1897eb52 Mon Sep 17 00:00:00 2001
+From: Jonghyun Park <parjong@gmail.com>
+Date: Wed, 20 Sep 2017 11:21:21 +0900
+Subject: [PATCH 12/12] 16-byte Stack Aligned StubDispatchFixupStub
+
+---
+ src/vm/i386/asmhelpers.S | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/vm/i386/asmhelpers.S b/src/vm/i386/asmhelpers.S
+index 75f4a26..480eb2d 100644
+--- a/src/vm/i386/asmhelpers.S
++++ b/src/vm/i386/asmhelpers.S
+@@ -757,13 +757,16 @@ NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler
+ .att_syntax
+ pushl $0
+ pushl $0
++ pushl $0
+ .intel_syntax noprefix
+
+ push eax // siteAddrForRegisterIndirect (for tailcalls)
+ push esi // pTransitionBlock
+
++ CHECK_STACK_ALIGNMENT
+ call C_FUNC(StubDispatchFixupWorker)
+
++ mov esp, esi
+ STUB_EPILOG
+
+ PATCH_LABEL StubDispatchFixupPatchLabel
+--
+2.7.4
+
--- /dev/null
+From 4168f754bbb8d559de00f5a0d45660784968a1f9 Mon Sep 17 00:00:00 2001
+From: Igor Kulaychuk <i.kulaychuk@samsung.com>
+Date: Fri, 20 Apr 2018 23:52:57 +0300
+Subject: [PATCH 13/13] Fix EECodeManager::GetAmbientSP on x86/Linux
+
+---
+ src/vm/eetwain.cpp | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
+index a2ceb19..4fb43a9 100644
+--- a/src/vm/eetwain.cpp
++++ b/src/vm/eetwain.cpp
+@@ -5940,7 +5940,8 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext,
+ #endif // _DEBUG && !DACCESS_COMPILE
+
+ if ((stateBuf->hdrInfoBody.prologOffs != hdrInfo::NOT_IN_PROLOG) ||
+- (stateBuf->hdrInfoBody.epilogOffs != hdrInfo::NOT_IN_EPILOG))
++ (stateBuf->hdrInfoBody.epilogOffs != hdrInfo::NOT_IN_EPILOG) ||
++ (GetRegdisplayFPAddress(pContext) == NULL))
+ {
+ return NULL;
+ }
+--
+2.7.4
+
--- /dev/null
+From e832e5ca7bc9b7c2bf3ccbc4333dcb0044d3543c Mon Sep 17 00:00:00 2001
+From: Igor Kulaychuk <i.kulaychuk@samsung.com>
+Date: Wed, 25 Apr 2018 21:31:59 +0300
+Subject: [PATCH 14/14] Fix OOPStackUnwinderX86::Unwind crash when Eip is
+ invalid
+
+---
+ src/unwinder/i386/unwinder_i386.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/unwinder/i386/unwinder_i386.cpp b/src/unwinder/i386/unwinder_i386.cpp
+index 42c19cb..8cd8f48 100644
+--- a/src/unwinder/i386/unwinder_i386.cpp
++++ b/src/unwinder/i386/unwinder_i386.cpp
+@@ -30,7 +30,7 @@ BOOL OOPStackUnwinderX86::Unwind(T_CONTEXT* pContextRecord, T_KNONVOLATILE_CONTE
+ EECodeInfo codeInfo;
+ codeInfo.Init((PCODE) ControlPc);
+
+- if (!UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL))
++ if (!codeInfo.IsValid() || !UnwindStackFrame(&rd, &codeInfo, UpdateAllRegs, &codeManState, NULL))
+ {
+ return FALSE;
+ }
+--
+2.7.4
+
Source1001: %{name}.manifest
Source1002: libicu.tar.gz
Source1003: dep_libs.tar.gz
-# Gbp-Ignore-Patches: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
+# Gbp-Ignore-Patches: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
Patch0: 0001-Add-project.assets.json-files.patch
Patch1: 0001-ARM-Linux-Support-unaligned-struct-read-write-11290.patch
Patch2: 0002-x86-Linux-Thread-safe-UMThunkMarshInfo-RunTimeInit-1.patch
Patch75: 0030-Remove-relocations-for-MethodTable-m_pParentMethodTa.patch
Patch76: 0031-Fix-build-break-with-older-VS-versions-16522.patch
Patch77: 0032-Fix-handling-of-incorrect-assemblies-on-Unix-16747.patch
+Patch78: 0001-Linux-ARM-Fix-managed-breakpoints-13316.patch
+Patch79: 0002-Merge-pull-request-13944-from-ayuckhulk-fix-arm-set-.patch
+Patch80: 0003-Fix-Linux-x86-FuncEvalHijack-stack-alignment-17143.patch
+Patch81: 0004-Fix-funclet-unwinding-on-x86-Linux-17144.patch
+Patch82: 0005-Add-environment-variable-COMPlus_EnableDiagnostics-t.patch
+Patch83: 0006-Fix-x86-Linux-ICorDebug-frames-API.patch
+Patch84: 0007-Fix-unwinding-of-funclet-with-no-epilog-on-x86-Linux.patch
+Patch85: 0008-Fix-HelperMethodFrame-UpdateRegDisplay.patch
+Patch86: 0009-Fix-regdisplay-initialization-in-case-of-WIN64EXCEPT.patch
+Patch87: 0010-Fix-CopyREGDISPLAY-for-WIN64EXCEPTIONS.patch
+Patch88: 0011-Enable-thread-abort-reraise-loop-prevention.patch
+Patch89: 0012-16-byte-Stack-Aligned-StubDispatchFixupStub.patch
+Patch90: 0013-Fix-EECodeManager-GetAmbientSP-on-x86-Linux.patch
+Patch91: 0014-Fix-OOPStackUnwinderX86-Unwind-crash-when-Eip-is-inv.patch
ExcludeArch: aarch64
%patch76 -p1
%patch77 -p1
+
%if 0%{skipmscorlib}
%else
cp %{SOURCE1000} ./
# No build native and mscorlib.
%else
# Build native only.
-./build.sh %{_barch} %{_buildtype} clang3.8 skipmscorlib skipgenerateversion skipnuget %{testopt} cmakeargs "-DFEATURE_GDBJIT=TRUE -DFEATURE_DBGIPC=0 -DFEATURE_NI_BIND_FALLBACK=false -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,relro -DCMAKE_EXE_LINKER_FLAGS=-Wl,-z,relro"
+./build.sh %{_barch} %{_buildtype} clang3.8 skipmscorlib skipgenerateversion skipnuget %{testopt} cmakeargs "-DFEATURE_GDBJIT=TRUE -DFEATURE_NI_BIND_FALLBACK=false -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,relro -DCMAKE_EXE_LINKER_FLAGS=-Wl,-z,relro"
%endif
%else
%if 0%{skipnative}
./build.sh %{_barch} %{_buildtype} -skiprestore skipnative skipnuget %{testopt}
%else
# Build native and mscorlib.
-./build.sh %{_barch} %{_buildtype} clang3.8 skipgenerateversion -skiprestore skipnuget %{testopt} cmakeargs "-DFEATURE_GDBJIT=TRUE -DFEATURE_DBGIPC=0 -DFEATURE_NI_BIND_FALLBACK=false -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,relro -DCMAKE_EXE_LINKER_FLAGS=-Wl,-z,relro"
+./build.sh %{_barch} %{_buildtype} clang3.8 skipgenerateversion -skiprestore skipnuget %{testopt} cmakeargs "-DFEATURE_GDBJIT=TRUE -DFEATURE_NI_BIND_FALLBACK=false -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_SHARED_LINKER_FLAGS=-Wl,-z,relro -DCMAKE_EXE_LINKER_FLAGS=-Wl,-z,relro"
%endif
%endif