if (m_pSharedPatchBypassBuffer == NULL)
{
- m_pSharedPatchBypassBuffer = new (interopsafeEXEC) SharedPatchBypassBuffer();
+ void *pSharedPatchBypassBufferRX = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer));
+ ExecutableWriterHolder<SharedPatchBypassBuffer> sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer));
+ new (sharedPatchBypassBufferWriterHolder.GetRW()) SharedPatchBypassBuffer();
+ m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX;
+
_ASSERTE(m_pSharedPatchBypassBuffer);
TRACE_ALLOC(m_pSharedPatchBypassBuffer);
}
LPVOID baseAddress = (LPVOID)(patch->address);
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#else // defined(HOST_OSX) && defined(HOST_ARM64)
+#if !defined(HOST_OSX) || !defined(HOST_ARM64)
DWORD oldProt;
if (!VirtualProtect(baseAddress,
_ASSERTE(!"VirtualProtect of code page failed");
return false;
}
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
patch->opcode = CORDbgGetInstruction(patch->address);
_ASSERTE(!"VirtualProtect of code page failed");
return false;
}
-#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
+#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
}
// TODO: : determine if this is needed for AMD64
#if defined(TARGET_X86) //REVISIT_TODO what is this?!
_ASSERTE(!"VirtualProtect of code page failed");
return false;
}
+
patch->opcode =
(unsigned int) *(unsigned short*)(patch->address+1);
_ASSERTE(patch->opcode != CEE_BREAK);
- *(unsigned short *) (patch->address+1) = CEE_BREAK;
+ ExecutableWriterHolder<BYTE> breakpointWriterHolder((BYTE*)patch->address, 2);
+ *(unsigned short *) (breakpointWriterHolder.GetRW()+1) = CEE_BREAK;
if (!VirtualProtect((void *) patch->address, 2, oldProt, &oldProt))
{
LPVOID baseAddress = (LPVOID)(patch->address);
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#else // defined(HOST_OSX) && defined(HOST_ARM64)
+#if !defined(HOST_OSX) || !defined(HOST_ARM64)
DWORD oldProt;
if (!VirtualProtect(baseAddress,
InitializePRD(&(patch->opcode));
return false;
}
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patch->address, patch->opcode);
_ASSERTE(!"VirtualProtect of code page failed");
return false;
}
-#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
+#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
}
else
{
#if defined(TARGET_X86)
_ASSERTE(*(unsigned short*)(patch->address+1) == CEE_BREAK);
- *(unsigned short *) (patch->address+1)
+ ExecutableWriterHolder<BYTE> breakpointWriterHolder((BYTE*)patch->address, 2);
+ *(unsigned short *) (breakpointWriterHolder.GetRW()+1)
= (unsigned short) patch->opcode;
#endif //this makes no sense on anything but X86
//VERY IMPORTANT to zero out opcode, else we might mistake
// The following instances are used for invoking overloaded new/delete
InteropSafe interopsafe;
-InteropSafeExecutable interopsafeEXEC;
#ifndef DACCESS_COMPILE
{
WRAPPER_NO_CONTRACT;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
// Allocate the breakpoint instruction info in executable memory.
- m_bpInfoSegment = new (interopsafeEXEC, nothrow) DebuggerEvalBreakpointInfoSegment(this);
+ void *bpInfoSegmentRX = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(DebuggerEvalBreakpointInfoSegment));
+ ExecutableWriterHolder<DebuggerEvalBreakpointInfoSegment> bpInfoSegmentWriterHolder((DebuggerEvalBreakpointInfoSegment*)bpInfoSegmentRX, sizeof(DebuggerEvalBreakpointInfoSegment));
+ new (bpInfoSegmentWriterHolder.GetRW()) DebuggerEvalBreakpointInfoSegment(this);
+ m_bpInfoSegment = (DebuggerEvalBreakpointInfoSegment*)bpInfoSegmentRX;
// This must be non-zero so that the saved opcode is non-zero, and on IA64 we want it to be 0x16
// so that we can have a breakpoint instruction in any slot in the bundle.
- m_bpInfoSegment->m_breakpointInstruction[0] = 0x16;
+ bpInfoSegmentWriterHolder.GetRW()->m_breakpointInstruction[0] = 0x16;
#if defined(TARGET_ARM)
USHORT *bp = (USHORT*)&m_bpInfoSegment->m_breakpointInstruction;
*bp = CORDbg_BREAK_INSTRUCTION;
inline void SetNextPage(DebuggerHeapExecutableMemoryPage* nextPage)
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
- chunks[0].bookkeeping.nextPage = nextPage;
+ ExecutableWriterHolder<DebuggerHeapExecutableMemoryPage> debuggerHeapPageWriterHolder(this, sizeof(DebuggerHeapExecutableMemoryPage));
+ debuggerHeapPageWriterHolder.GetRW()->chunks[0].bookkeeping.nextPage = nextPage;
}
inline uint64_t GetPageOccupancy() const
inline void SetPageOccupancy(uint64_t newOccupancy)
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
// Can't unset first bit of occupancy!
ASSERT((newOccupancy & 0x8000000000000000) != 0);
- chunks[0].bookkeeping.pageOccupancy = newOccupancy;
+ ExecutableWriterHolder<DebuggerHeapExecutableMemoryPage> debuggerHeapPageWriterHolder(this, sizeof(DebuggerHeapExecutableMemoryPage));
+ debuggerHeapPageWriterHolder.GetRW()->chunks[0].bookkeeping.pageOccupancy = newOccupancy;
}
inline void* GetPointerToChunk(int chunkNum) const
DebuggerHeapExecutableMemoryPage()
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+ ExecutableWriterHolder<DebuggerHeapExecutableMemoryPage> debuggerHeapPageWriterHolder(this, sizeof(DebuggerHeapExecutableMemoryPage));
SetPageOccupancy(0x8000000000000000); // only the first bit is set.
for (uint8_t i = 1; i < sizeof(chunks)/sizeof(chunks[0]); i++)
{
ASSERT(i != 0);
- chunks[i].data.startOfPage = this;
- chunks[i].data.chunkNumber = i;
+ debuggerHeapPageWriterHolder.GetRW()->chunks[i].data.startOfPage = this;
+ debuggerHeapPageWriterHolder.GetRW()->chunks[i].data.chunkNumber = i;
}
}
class InteropSafe {};
extern InteropSafe interopsafe;
-class InteropSafeExecutable {};
-extern InteropSafeExecutable interopsafeEXEC;
-
#ifndef DACCESS_COMPILE
inline void * __cdecl operator new(size_t n, const InteropSafe&)
{
}
}
-inline void * __cdecl operator new(size_t n, const InteropSafeExecutable&)
-{
- CONTRACTL
- {
- THROWS; // throw on OOM
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(g_pDebugger != NULL);
- void *result = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc((DWORD)n);
- if (result == NULL) {
- ThrowOutOfMemory();
- }
- return result;
-}
-
-inline void * __cdecl operator new(size_t n, const InteropSafeExecutable&, const NoThrow&) throw()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(g_pDebugger != NULL);
- DebuggerHeap * pHeap = g_pDebugger->GetInteropSafeExecutableHeap_NoThrow();
- if (pHeap == NULL)
- {
- return NULL;
- }
- void *result = pHeap->Alloc((DWORD)n);
- return result;
-}
-
-// Note: there is no C++ syntax for manually invoking this, but if a constructor throws an exception I understand that
-// this delete operator will be invoked automatically to destroy the object.
-inline void __cdecl operator delete(void *p, const InteropSafeExecutable&)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if (p != NULL)
- {
- _ASSERTE(g_pDebugger != NULL);
- DebuggerHeap * pHeap = g_pDebugger->GetInteropSafeExecutableHeap_NoThrow();
- _ASSERTE(pHeap != NULL); // should have had heap around if we're deleting
- pHeap->Free(p);
- }
-}
-
//
// Interop safe delete to match the interop safe new's above. There is no C++ syntax for actually invoking those interop
// safe delete operators above, so we use this method to accomplish the same thing.
#ifndef PRIMITIVES_H_
#define PRIMITIVES_H_
+#include "executableallocator.h"
+
#ifndef CORDB_ADDRESS_TYPE
typedef const BYTE CORDB_ADDRESS_TYPE;
typedef DPTR(CORDB_ADDRESS_TYPE) PTR_CORDB_ADDRESS_TYPE;
{
LIMITED_METHOD_CONTRACT;
- *((unsigned char*)address) = 0xCC; // int 3 (single byte patch)
+ ExecutableWriterHolder<void> breakpointWriterHolder((LPVOID)address, CORDbg_BREAK_INSTRUCTION_SIZE);
+
+ *((unsigned char*)breakpointWriterHolder.GetRW()) = 0xCC; // int 3 (single byte patch)
FlushInstructionCache(GetCurrentProcess(), address, 1);
}
// In a DAC build, this function assumes the input is an host address.
LIMITED_METHOD_DAC_CONTRACT;
- *((unsigned char*)address) =
+ ExecutableWriterHolder<void> instructionWriterHolder((LPVOID)address, sizeof(unsigned char));
+
+ *((unsigned char*)instructionWriterHolder.GetRW()) =
(unsigned char) instruction; // setting one byte is important
FlushInstructionCache(GetCurrentProcess(), address, 1);
#ifndef PRIMITIVES_H_
#define PRIMITIVES_H_
+#include "executableallocator.h"
+
#ifndef THUMB_CODE
#define THUMB_CODE 1
#endif
// In a DAC build, this function assumes the input is an host address.
LIMITED_METHOD_DAC_CONTRACT;
- CORDB_ADDRESS ptraddr = (CORDB_ADDRESS)address;
+ ExecutableWriterHolder<void> instructionWriterHolder((LPVOID)address, sizeof(PRD_TYPE));
+
+ CORDB_ADDRESS ptraddr = (CORDB_ADDRESS)instructionWriterHolder.GetRW();
_ASSERTE(ptraddr & THUMB_CODE);
ptraddr &= ~THUMB_CODE;
#ifndef PRIMITIVES_H_
#define PRIMITIVES_H_
+#include "executableallocator.h"
+
typedef NEON128 FPRegister64;
typedef const BYTE CORDB_ADDRESS_TYPE;
typedef DPTR(CORDB_ADDRESS_TYPE) PTR_CORDB_ADDRESS_TYPE;
// In a DAC build, this function assumes the input is an host address.
LIMITED_METHOD_DAC_CONTRACT;
- ULONGLONG ptraddr = dac_cast<ULONGLONG>(address);
+ ExecutableWriterHolder<void> instructionWriterHolder((LPVOID)address, sizeof(PRD_TYPE));
+
+ ULONGLONG ptraddr = dac_cast<ULONGLONG>(instructionWriterHolder.GetRW());
*(PRD_TYPE *)ptraddr = instruction;
FlushInstructionCache(GetCurrentProcess(),
address,
#ifndef PRIMITIVES_H_
#define PRIMITIVES_H_
+#include "executableallocator.h"
typedef const BYTE CORDB_ADDRESS_TYPE;
typedef DPTR(CORDB_ADDRESS_TYPE) PTR_CORDB_ADDRESS_TYPE;
{
LIMITED_METHOD_CONTRACT;
- *((unsigned char*)address) = 0xCC; // int 3 (single byte patch)
+ ExecutableWriterHolder<void> breakpointWriterHolder((LPVOID)address, CORDbg_BREAK_INSTRUCTION_SIZE);
+
+ *((unsigned char*)breakpointWriterHolder.GetRW()) = 0xCC; // int 3 (single byte patch)
FlushInstructionCache(GetCurrentProcess(), address, 1);
}
#PAL__open
#PAL__pread
#PAL__close
+#PAL_JitWriteProtect
#_wcsicmp
#_stricmp
void Unmap()
{
- // TODO: this will be added with the double mapped allocator addition
+ if (m_addressRX != NULL)
+ {
+ // TODO: mapping / unmapping for targets using double memory mapping will be added with the double mapped allocator addition
+#if defined(HOST_OSX) && defined(HOST_ARM64)
+ PAL_JitWriteProtect(false);
+#endif
+ }
}
public:
{
m_addressRX = addressRX;
m_addressRW = addressRX;
+#if defined(HOST_OSX) && defined(HOST_ARM64)
+ PAL_JitWriteProtect(true);
+#endif
}
~ExecutableWriterHolder()
{
WRAPPER_NO_CONTRACT;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
void *pResult;
TaggedMemAllocPtr tmap;
{
WRAPPER_NO_CONTRACT;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
CRITSEC_Holder csh(m_CriticalSection);
IN SIZE_T dwSize,
IN DWORD dwFreeType);
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-#ifdef __cplusplus
-extern "C++" {
-struct PAL_JITWriteEnableHolder
-{
-public:
- PAL_JITWriteEnableHolder(bool jitWriteEnable)
- {
- m_jitWriteEnableRestore = JITWriteEnable(jitWriteEnable);
- };
- ~PAL_JITWriteEnableHolder()
- {
- JITWriteEnable(m_jitWriteEnableRestore);
- }
+#if defined(HOST_OSX)
-private:
- bool JITWriteEnable(bool enable);
- bool m_jitWriteEnableRestore;
-};
+PALIMPORT
+VOID
+PALAPI
+PAL_JitWriteProtect(bool writeEnable);
-inline
-PAL_JITWriteEnableHolder
-PAL_JITWriteEnable(IN bool enable) { return PAL_JITWriteEnableHolder(enable); }
-}
-#endif // __cplusplus
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+#endif // defined(HOST_OSX)
PALIMPORT
BOOL
return bRetVal;
}
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-bool
-PAL_JITWriteEnableHolder::JITWriteEnable(bool writeEnable)
+#if defined(HOST_OSX)
+PALAPI VOID PAL_JitWriteProtect(bool writeEnable)
{
- // Use a thread local to track per thread JIT Write enable state
- // Per Apple, new threads start with MAP_JIT pages readable and executable (R-X) by default.
- thread_local bool enabled = false;
- bool result = enabled;
- if (enabled != writeEnable)
+#if defined(HOST_ARM64)
+ thread_local int enabledCount = 0;
+ if (writeEnable)
{
- pthread_jit_write_protect_np(writeEnable ? 0 : 1);
- enabled = writeEnable;
+ if (enabledCount++ == 0)
+ {
+ pthread_jit_write_protect_np(0);
+ }
+ }
+ else
+ {
+ if (--enabledCount == 0)
+ {
+ pthread_jit_write_protect_np(1);
+ }
+ _ASSERTE(enabledCount >= 0);
}
- return result;
+#endif // HOST_ARM64
}
-#endif
+#endif // HOST_OSX
#if HAVE_VM_ALLOCATE
//---------------------------------------------------------------------------------------
// control in the breakpoint fixup logic we can then reset the PC to its proper location.
unsigned int idxNextInstruction = 0;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+
+ ExecutableWriterHolder<DWORD> codeWriterHolder(m_rgCode, sizeof(m_rgCode));
if (TryEmulate(pCtx, opcode, false))
{
{
LOG((LF_CORDB, LL_INFO100000, "Arm64SingleStepper: Case 2: CopyInstruction.\n"));
// Case 2: In all other cases copy the instruction to the buffer and we'll run it directly.
- m_rgCode[idxNextInstruction++] = opcode;
+ codeWriterHolder.GetRW()[idxNextInstruction++] = opcode;
}
// Always terminate the redirection buffer with a breakpoint.
- m_rgCode[idxNextInstruction++] = kBreakpointOp;
+ codeWriterHolder.GetRW()[idxNextInstruction++] = kBreakpointOp;
_ASSERTE(idxNextInstruction <= kMaxCodeBuffer);
// Set the thread up so it will redirect to our buffer when execution resumes.
LEAF_END_MARKED \name, _TEXT
.endm
-// void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck)
+// void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck, size_t writeableOffset)
//
// Update shadow copies of the various state info required for barrier
//
// x12 will be used for pointers
mov x8, x0
+ mov x9, x1
PREPARE_EXTERNAL_VAR g_card_table, x12
ldr x0, [x12]
#ifdef FEATURE_WRITEBARRIER_COPY
PREPARE_EXTERNAL_VAR JIT_WriteBarrier_Table_Loc, x12
ldr x12, [x12]
+ add x12, x12, x9
#else // FEATURE_WRITEBARRIER_COPY
adr x12, LOCAL_LABEL(wbs_begin)
#endif // FEATURE_WRITEBARRIER_COPY
LEAF_END
;-----------------------------------------------------------------------------
-; void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck)
+; void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck, size_t writeableOffset)
;
; Update shadow copies of the various state info required for barrier
;
{
WRAPPER_NO_CONTRACT;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
int n = 0;
m_rgCode[n++] = 0x10000089; // adr x9, #16
{
WRAPPER_NO_CONTRACT;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
int n = 0;
m_rgCode[n++] = 0x1000008B; // adr x11, #16
{
WRAPPER_NO_CONTRACT;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
InitCommon();
// Initialize chunk indices only if they are not initialized yet. This is necessary to make MethodDesc::Reset work.
}
#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck);
+EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck, size_t writeableOffset);
+
+extern "C" void STDCALL JIT_PatchedCodeStart();
+extern "C" void STDCALL JIT_PatchedCodeLast();
static void UpdateWriteBarrierState(bool skipEphemeralCheck)
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
- JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap());
+ BYTE *writeBarrierCodeStart = GetWriteBarrierCodeLocation((void*)JIT_PatchedCodeStart);
+ ExecutableWriterHolder<BYTE> writeBarrierWriterHolder(writeBarrierCodeStart, (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart);
+ JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap(), writeBarrierWriterHolder.GetRW() - writeBarrierCodeStart);
}
void InitJITHelpers1()
void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam)
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
// adr x12, _label
// ldp x16, x12, [x12]
// br x16
void UMEntryThunkCode::Poison()
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
ExecutableWriterHolder<UMEntryThunkCode> thunkWriterHolder(this, sizeof(UMEntryThunkCode));
UMEntryThunkCode *pThisRW = thunkWriterHolder.GetRW();
#define DYNAMIC_HELPER_ALIGNMENT sizeof(TADDR)
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-#define BEGIN_DYNAMIC_HELPER_EMIT(size) \
- SIZE_T cb = size; \
- SIZE_T cbAligned = ALIGN_UP(cb, DYNAMIC_HELPER_ALIGNMENT); \
- BYTE * pStart = (BYTE *)(void *)pAllocator->GetDynamicHelpersHeap()->AllocAlignedMem(cbAligned, DYNAMIC_HELPER_ALIGNMENT); \
- BYTE * p = pStart; \
- static const size_t rxOffset = 0; \
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-
-#define END_DYNAMIC_HELPER_EMIT() \
- _ASSERTE(pStart + cb == p); \
- while (p < pStart + cbAligned) { *(DWORD*)p = 0xBADC0DF0; p += 4; }\
- ClrFlushInstructionCache(pStart, cbAligned); \
- return (PCODE)pStart
-#else // defined(HOST_OSX) && defined(HOST_ARM64)
#define BEGIN_DYNAMIC_HELPER_EMIT(size) \
SIZE_T cb = size; \
SIZE_T cbAligned = ALIGN_UP(cb, DYNAMIC_HELPER_ALIGNMENT); \
while (p < pStart + cbAligned) { *(DWORD*)p = 0xBADC0DF0; p += 4; }\
ClrFlushInstructionCache(pStartRX, cbAligned); \
return (PCODE)pStartRX
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
// Uses x8 as scratch register to store address of data label
// After load x8 is increment to point to next data
}
CONTRACTL_END;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
LoaderHeap *heap = m_heap;
if (heap == nullptr)
{
#endif
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(false);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
BEGIN_CALL_TO_MANAGEDEX(fCriticalCall ? EEToManagedCriticalCall : EEToManagedDefault);
CallDescrWorker(pCallDescrData);
Assembly::Initialize();
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
SystemDomain::System()->Init();
#ifdef PROFILING_SUPPORTED
{
CrstHolder ch(&m_CritSec);
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
dwRequestedSize = ALIGN_UP(dwRequestedSize, sizeof(TADDR));
// We will try to batch up allocation of small blocks into one large allocation
CrstHolder ch(&m_CritSec);
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
ExecutableWriterHolder<BYTE> memWriterHolder((BYTE*)pMem, dwSize);
ZeroMemory(memWriterHolder.GetRW(), dwSize);
}
pCodeHdr = ((CodeHeader *)pCode) - 1;
*pAllocatedSize = sizeof(CodeHeader) + totalSize;
+#define FEATURE_WXORX
#ifdef FEATURE_WXORX
pCodeHdrRW = (CodeHeader *)new BYTE[*pAllocatedSize];
#else
HostCodeHeap *pHeap = m_cleanupList;
m_cleanupList = NULL;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
while (pHeap)
{
HostCodeHeap *pNextHeap = pHeap->m_pNextHeapToRelease;
GC_NOTRIGGER;
} CONTRACTL_END;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
// a size of 0 is a signal to Nirvana to flush the entire cache
FlushInstructionCache(GetCurrentProcess(),0,0);
flags,
&fIsOpenDelegate))
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
// Initialize the delegate to point to the target method.
BindToMethod(&gc.refThis,
&gc.refFirstArg,
// try to catch the easy garbage.
_ASSERTE(isMemoryReadable(method, 1));
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
MethodTable *pMTTarg = NULL;
if (gc.target != NULL)
CrstHolder ch(&m_crst);
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
if (m_pHead == NULL)
{
m_pHead = pThunkRX;
else
{
// cache miss -> create a new thunk
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
pThunk = UMEntryThunk::CreateUMEntryThunk();
Holder<UMEntryThunk *, DoNothing, UMEntryThunk::FreeUMEntryThunk> umHolder;
umHolder.Assign(pThunk);
{
GCX_PREEMP();
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
ExecutableWriterHolder<UMEntryThunk> uMEntryThunkWriterHolder(pUMEntryThunk, sizeof(UMEntryThunk));
uMEntryThunkWriterHolder.GetRW()->RunTimeInit(pUMEntryThunk);
}
if (GetObjectHandle())
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
DestroyLongWeakHandle(GetObjectHandle());
thunkWriterHolder.GetRW()->m_pObjectHandle = 0;
}
}
CONTRACTL_END;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
m_pManagedTarget = pManagedTarget;
m_pObjectHandle = pObjectHandle;
m_pUMThunkMarshInfo = pUMThunkMarshInfo;
m_code.Encode(&pUMEntryThunkRX->m_code, (BYTE*)m_pUMThunkMarshInfo->GetExecStubEntryPoint(), pUMEntryThunkRX);
#ifdef _DEBUG
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
m_state = kRunTimeInited;
#endif // _DEBUG
}
LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap [0x%p] - Add to FreeList [%p, 0x%X]\n", this, pBlockToInsert, pBlockToInsert->size));
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
// append to the list in the proper position and coalesce if needed
if (m_pFreeList)
{
ep_rt_prepare_provider_invoke_callback (EventPipeProviderCallbackData *provider_callback_data)
{
STATIC_CONTRACT_NOTHROW;
-
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(false);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
}
static
void RemoveGcCoverageInterrupt(TADDR instrPtr, BYTE * savedInstrPtr, GCCoverageInfo* gcCover, DWORD offset)
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
ExecutableWriterHolder<void> instrPtrWriterHolder((void*)instrPtr, 4);
#ifdef TARGET_ARM
if (GetARMInstructionLength(savedInstrPtr) == 2)
_ASSERTE(entryPoint != NULL);
_ASSERTE(IS_ALIGNED((SIZE_T)slot, GetRequiredSlotAlignment(slotType)));
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
switch (slotType)
{
case SlotType_Normal:
{
WRAPPER_NO_CONTRACT;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
PrecodeType precodeType = GetType();
switch (precodeType)
{
if (fOnlyRedirectFromPrestub && !IsPointingToPrestub(expected))
return FALSE;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
g_IBCLogger.LogMethodPrecodeWriteAccess(GetMethodDesc());
PrecodeType precodeType = GetType();
{
STANDARD_VM_CONTRACT;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
// If other kinds of code need multi-versioning we could add more cases here,
// but for now generation of all other code/stubs occurs in other code paths
_ASSERTE(IsIL() || IsNoMetadata());
GCX_PREEMP_THREAD_EXISTS(CURRENT_THREAD);
{
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
pbRetVal = pMD->DoPrestub(pDispatchingMT, CallerGCMode::Coop);
}
}
#endif
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- // Initialize new threads to JIT Write disabled
- auto jitWriteEnableHolder = PAL_JITWriteEnable(false);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
// Normally, HasStarted is called from the thread's entrypoint to introduce it to
// the runtime. But sometimes that thread is used for DLL_THREAD_ATTACH notifications
// that call into managed code. In that case, a call to SetupThread here must
COMPlusThrowWin32();
}
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
- memcpy(s_barrierCopy, (BYTE*)JIT_PatchedCodeStart, (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart);
+ {
+ size_t writeBarrierSize = (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart;
+ ExecutableWriterHolder<void> barrierWriterHolder(s_barrierCopy, writeBarrierSize);
+ memcpy(barrierWriterHolder.GetRW(), (BYTE*)JIT_PatchedCodeStart, writeBarrierSize);
+ }
// Store the JIT_WriteBarrier copy location to a global variable so that helpers
// can jump to it.
assert(pbDestCode != NULL);
assert(pbSrcCode != NULL);
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
ExecutableWriterHolder<BYTE> destCodeWriterHolder(pbDestCode, sizeof(DWORD));
#if defined(TARGET_X86) || defined(TARGET_AMD64)
PRECONDITION(IsProtectedByGCFrame(protectedObj));
} CONTRACTL_END;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
MethodTable* objectType = (*protectedObj)->GetMethodTable();
CONSISTENCY_CHECK(CheckPointer(objectType));
POSTCONDITION(CheckPointer(RETVAL));
} CONTRACT_END;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
- auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
//allocate from the requisite heap and copy the template over it.
LookupHolder * holder = (LookupHolder*) (void*) lookup_heap->AllocAlignedMem(sizeof(LookupHolder), CODE_SIZE_ALIGN);
ExecutableWriterHolder<LookupHolder> lookupWriterHolder(holder, sizeof(LookupHolder));