Skip to content
This repository was archived by the owner on Nov 1, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/Native/Runtime/AsmOffsets.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#ifdef _ARM_

#define PLAT_ASM_OFFSET(offset, cls, member) OFFSETOF__##cls##__##member equ 0x##offset
#define PLAT_ASM_SIZEOF(size, cls ) SIZEOF__##cls equ 0x##size
#define PLAT_ASM_CONST(constant, expr) expr equ 0x##constant

#else

#define PLAT_ASM_OFFSET(offset, cls, member) OFFSETOF__##cls##__##member equ 0##offset##h
#define PLAT_ASM_SIZEOF(size, cls ) SIZEOF__##cls equ 0##size##h
#define PLAT_ASM_CONST(constant, expr) expr equ 0##constant##h

#endif

#include "AsmOffsets.h"
171 changes: 171 additions & 0 deletions src/Native/Runtime/AsmOffsets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

//
// This file is used by AsmOffsets.cpp to validate that our
// assembly-code offsets always match their C++ counterparts.
//
// You must #define PLAT_ASM_OFFSET and PLAT_ASM_SIZEOF before you #include this file
//

#if defined(_X86_)
#define ASM_OFFSET(x86_offset, arm_offset, amd64_offset, cls, member) PLAT_ASM_OFFSET(x86_offset, cls, member)
#define ASM_SIZEOF(x86_offset, arm_offset, amd64_offset, cls ) PLAT_ASM_SIZEOF(x86_offset, cls)
#define ASM_CONST(x86_const, arm_const, amd64_const, expr) PLAT_ASM_CONST(x86_const, expr)
#elif defined(_AMD64_)
#define ASM_OFFSET(x86_offset, arm_offset, amd64_offset, cls, member) PLAT_ASM_OFFSET(amd64_offset, cls, member)
#define ASM_SIZEOF(x86_offset, arm_offset, amd64_offset, cls ) PLAT_ASM_SIZEOF(amd64_offset, cls)
#define ASM_CONST(x86_const, arm_const, amd64_const, expr) PLAT_ASM_CONST(amd64_const, expr)
#elif defined(_ARM_)
#define ASM_OFFSET(x86_offset, arm_offset, amd64_offset, cls, member) PLAT_ASM_OFFSET(arm_offset, cls, member)
#define ASM_SIZEOF(x86_offset, arm_offset, amd64_offset, cls ) PLAT_ASM_SIZEOF(arm_offset, cls)
#define ASM_CONST(x86_const, arm_const, amd64_const, expr) PLAT_ASM_CONST(arm_const, expr)
#else
#error unknown architecture
#endif

#if !defined(USE_PORTABLE_HELPERS) // no asm helpers to keep in sync with

//
// NOTE: the offsets MUST be in hex notation WITHOUT the 0x prefix
//
// x86, arm,amd64, constant symbol
ASM_CONST(14c08,14c08,14c08, RH_LARGE_OBJECT_SIZE)
ASM_CONST( 400, 400, 800, CLUMP_SIZE)
ASM_CONST( a, a, b, LOG2_CLUMP_SIZE)

// x86, arm,amd64, class, member

ASM_OFFSET( 0, 0, 0, Object, m_pEEType)

ASM_OFFSET( 4, 4, 8, Array, m_Length)

ASM_OFFSET( 0, 0, 0, EEType, m_usComponentSize)
ASM_OFFSET( 2, 2, 2, EEType, m_usFlags)
ASM_OFFSET( 4, 4, 4, EEType, m_uBaseSize)
ASM_OFFSET( 14, 14, 18, EEType, m_VTable)

ASM_OFFSET( 0, 0, 0, Thread, m_rgbAllocContextBuffer)
ASM_OFFSET( 28, 28, 38, Thread, m_ThreadStateFlags)
ASM_OFFSET( 2c, 2c, 40, Thread, m_pTransitionFrame)
ASM_OFFSET( 30, 30, 48, Thread, m_pHackPInvokeTunnel)
ASM_OFFSET( 40, 40, 68, Thread, m_ppvHijackedReturnAddressLocation)
ASM_OFFSET( 44, 44, 70, Thread, m_pvHijackedReturnAddress)
ASM_OFFSET( 48, 48, 78, Thread, m_pExInfoStackHead)

ASM_SIZEOF( 14, 14, 20, EHEnum)

ASM_SIZEOF( b0, 128, 250, ExInfo)
ASM_OFFSET( 0, 0, 0, ExInfo, m_pPrevExInfo)
ASM_OFFSET( 4, 4, 8, ExInfo, m_pExContext)
ASM_OFFSET( 8, 8, 10, ExInfo, m_exception)
ASM_OFFSET( 0c, 0c, 18, ExInfo, m_kind)
ASM_OFFSET( 0d, 0d, 19, ExInfo, m_passNumber)
ASM_OFFSET( 10, 10, 1c, ExInfo, m_idxCurClause)
ASM_OFFSET( 14, 18, 20, ExInfo, m_frameIter)
ASM_OFFSET( ac, 120, 240, ExInfo, m_notifyDebuggerSP)

ASM_OFFSET( 0, 0, 0, alloc_context, alloc_ptr)
ASM_OFFSET( 4, 4, 8, alloc_context, alloc_limit)


ASM_OFFSET( 4, 4, 8, RuntimeInstance, m_pThreadStore)

ASM_OFFSET( 0, 4, 0, PInvokeTransitionFrame, m_RIP)
ASM_OFFSET( 4, 8, 8, PInvokeTransitionFrame, m_FramePointer)
ASM_OFFSET( 8, 0C, 10, PInvokeTransitionFrame, m_pThread)
ASM_OFFSET( 0C, 10, 18, PInvokeTransitionFrame, m_dwFlags)
ASM_OFFSET( 10, 14, 20, PInvokeTransitionFrame, m_PreservedRegs)

ASM_SIZEOF( 98, 108, 220, StackFrameIterator)
ASM_OFFSET( 08, 08, 10, StackFrameIterator, m_FramePointer)
ASM_OFFSET( 0C, 0C, 18, StackFrameIterator, m_ControlPC)
ASM_OFFSET( 10, 10, 20, StackFrameIterator, m_RegDisplay)

ASM_SIZEOF( 1c, 70, 100, PAL_LIMITED_CONTEXT)
ASM_OFFSET( 0, 24, 0, PAL_LIMITED_CONTEXT, IP)
#ifdef _ARM_
ASM_OFFSET( 0, 0, 0, PAL_LIMITED_CONTEXT, R0)
ASM_OFFSET( 0, 4, 0, PAL_LIMITED_CONTEXT, R4)
ASM_OFFSET( 0, 8, 0, PAL_LIMITED_CONTEXT, R5)
ASM_OFFSET( 0, 0c, 0, PAL_LIMITED_CONTEXT, R6)
ASM_OFFSET( 0, 10, 0, PAL_LIMITED_CONTEXT, R7)
ASM_OFFSET( 0, 14, 0, PAL_LIMITED_CONTEXT, R8)
ASM_OFFSET( 0, 18, 0, PAL_LIMITED_CONTEXT, R9)
ASM_OFFSET( 0, 1c, 0, PAL_LIMITED_CONTEXT, R10)
ASM_OFFSET( 0, 20, 0, PAL_LIMITED_CONTEXT, R11)
ASM_OFFSET( 0, 28, 0, PAL_LIMITED_CONTEXT, SP)
ASM_OFFSET( 0, 2c, 0, PAL_LIMITED_CONTEXT, LR)
#else // _ARM_
ASM_OFFSET( 4, 0, 8, PAL_LIMITED_CONTEXT, Rsp)
ASM_OFFSET( 8, 0, 10, PAL_LIMITED_CONTEXT, Rbp)
ASM_OFFSET( 0c, 0, 18, PAL_LIMITED_CONTEXT, Rdi)
ASM_OFFSET( 10, 0, 20, PAL_LIMITED_CONTEXT, Rsi)
ASM_OFFSET( 14, 0, 28, PAL_LIMITED_CONTEXT, Rax)
ASM_OFFSET( 18, 0, 30, PAL_LIMITED_CONTEXT, Rbx)
#ifdef _AMD64_
ASM_OFFSET( 0, 0, 38, PAL_LIMITED_CONTEXT, R12)
ASM_OFFSET( 0, 0, 40, PAL_LIMITED_CONTEXT, R13)
ASM_OFFSET( 0, 0, 48, PAL_LIMITED_CONTEXT, R14)
ASM_OFFSET( 0, 0, 50, PAL_LIMITED_CONTEXT, R15)
ASM_OFFSET( 0, 0, 60, PAL_LIMITED_CONTEXT, Xmm6)
ASM_OFFSET( 0, 0, 70, PAL_LIMITED_CONTEXT, Xmm7)
ASM_OFFSET( 0, 0, 80, PAL_LIMITED_CONTEXT, Xmm8)
ASM_OFFSET( 0, 0, 90, PAL_LIMITED_CONTEXT, Xmm9)
ASM_OFFSET( 0, 0, 0a0, PAL_LIMITED_CONTEXT, Xmm10)
ASM_OFFSET( 0, 0, 0b0, PAL_LIMITED_CONTEXT, Xmm11)
ASM_OFFSET( 0, 0, 0c0, PAL_LIMITED_CONTEXT, Xmm12)
ASM_OFFSET( 0, 0, 0d0, PAL_LIMITED_CONTEXT, Xmm13)
ASM_OFFSET( 0, 0, 0e0, PAL_LIMITED_CONTEXT, Xmm14)
ASM_OFFSET( 0, 0, 0f0, PAL_LIMITED_CONTEXT, Xmm15)
#endif // _AMD64_
#endif // _ARM_

ASM_SIZEOF( 28, 88, 130, REGDISPLAY)
ASM_OFFSET( 1c, 38, 78, REGDISPLAY, SP)
#ifdef _ARM_
ASM_OFFSET( 0, 10, 0, REGDISPLAY, pR4)
ASM_OFFSET( 0, 14, 0, REGDISPLAY, pR5)
ASM_OFFSET( 0, 18, 0, REGDISPLAY, pR6)
ASM_OFFSET( 0, 1c, 0, REGDISPLAY, pR7)
ASM_OFFSET( 0, 20, 0, REGDISPLAY, pR8)
ASM_OFFSET( 0, 24, 0, REGDISPLAY, pR9)
ASM_OFFSET( 0, 28, 0, REGDISPLAY, pR10)
ASM_OFFSET( 0, 2c, 0, REGDISPLAY, pR11)
ASM_OFFSET( 0, 48, 0, REGDISPLAY, D)
#else // _ARM_
ASM_OFFSET( 0c, 0, 18, REGDISPLAY, pRbx)
ASM_OFFSET( 10, 0, 20, REGDISPLAY, pRbp)
ASM_OFFSET( 14, 0, 28, REGDISPLAY, pRsi)
ASM_OFFSET( 18, 0, 30, REGDISPLAY, pRdi)
#ifdef _AMD64_
ASM_OFFSET( 0, 0, 58, REGDISPLAY, pR12)
ASM_OFFSET( 0, 0, 60, REGDISPLAY, pR13)
ASM_OFFSET( 0, 0, 68, REGDISPLAY, pR14)
ASM_OFFSET( 0, 0, 70, REGDISPLAY, pR15)
ASM_OFFSET( 0, 0, 90, REGDISPLAY, Xmm)
#endif // _AMD64_
#endif // _ARM_

#ifdef FEATURE_CACHED_INTERFACE_DISPATCH
ASM_OFFSET( 4, 4, 8, InterfaceDispatchCell, m_pCache)
#ifndef _AMD64_
ASM_OFFSET( 8, 8, 10, InterfaceDispatchCache, m_pCell)
#endif
ASM_OFFSET( 10, 10, 20, InterfaceDispatchCache, m_rgEntries)
#endif

ASM_OFFSET( 4, 4, 8, StaticClassConstructionContext, m_initialized)

#ifdef FEATURE_DYNAMIC_CODE
ASM_OFFSET( 0, 0, 0, CallDescrData, pSrc)
ASM_OFFSET( 4, 4, 8, CallDescrData, numStackSlots)
ASM_OFFSET( 8, 8, C, CallDescrData, fpReturnSize)
ASM_OFFSET( C, C, 10, CallDescrData, pArgumentRegisters)
ASM_OFFSET( 10, 10, 18, CallDescrData, pFloatArgumentRegisters)
ASM_OFFSET( 14, 14, 20, CallDescrData, pTarget)
ASM_OFFSET( 18, 18, 28, CallDescrData, pReturnBuffer)
#endif
#endif // !defined(USE_PORTABLE_HELPERS)
42 changes: 42 additions & 0 deletions src/Native/Runtime/AsmOffsetsVerify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#include "commontypes.h"
#include "gcrhenvbase.h"
#include "eventtrace.h"
#include "gc.h"
#include "assert.h"
#include "redhawkwarnings.h"
#include "slist.h"
#include "gcrhinterface.h"
#include "varint.h"
#include "regdisplay.h"
#include "stackframeiterator.h"
#include "thread.h"
#include "rhbinder.h"
#include "holder.h"
#include "crst.h"
#include "rwlock.h"
#include "runtimeinstance.h"
#include "cachedinterfacedispatch.h"
#include "module.h"
#include "calldescr.h"

class AsmOffsets
{
#define PLAT_ASM_OFFSET(offset, cls, member) \
static_assert((offsetof(cls, member) == 0x##offset) || (offsetof(cls, member) > 0x##offset), "Bad asm offset for '" #cls "." #member "', the actual offset is smaller than 0x" #offset "."); \
static_assert((offsetof(cls, member) == 0x##offset) || (offsetof(cls, member) < 0x##offset), "Bad asm offset for '" #cls "." #member "', the actual offset is larger than 0x" #offset ".");

#define PLAT_ASM_SIZEOF(size, cls ) \
static_assert((sizeof(cls) == 0x##size) || (sizeof(cls) > 0x##size), "Bad asm size for '" #cls "', the actual size is smaller than 0x" #size "."); \
static_assert((sizeof(cls) == 0x##size) || (sizeof(cls) < 0x##size), "Bad asm size for '" #cls "', the actual size is larger than 0x" #size ".");

#define PLAT_ASM_CONST(constant, expr) \
static_assert(((expr) == 0x##constant) || ((expr) > 0x##constant), "Bad asm constant for '" #expr "', the actual value is smaller than 0x" #constant "."); \
static_assert(((expr) == 0x##constant) || ((expr) < 0x##constant), "Bad asm constant for '" #expr "', the actual value is larger than 0x" #constant ".");

#include "AsmOffsets.h"

};
48 changes: 48 additions & 0 deletions src/Native/Runtime/CachedInterfaceDispatch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
// ==--==
//
// Shared (non-architecture specific) portions of a mechanism to perform interface dispatch using an alternate
// mechanism to VSD that does not require runtime generation of code.
//
// ============================================================================

#ifdef FEATURE_CACHED_INTERFACE_DISPATCH

bool InitializeInterfaceDispatch();
void ReclaimUnusedInterfaceDispatchCaches();

// Interface dispatch caches contain an array of these entries. An instance of a cache is paired with a stub
// that implicitly knows how many entries are contained. These entries must be aligned to twice the alignment
// of a pointer due to the synchonization mechanism used to update them at runtime.
struct InterfaceDispatchCacheEntry
{
EEType * m_pInstanceType; // Potential type of the object instance being dispatched on
void * m_pTargetCode; // Method to dispatch to if the actual instance type matches the above
};

// The interface dispatch cache itself. As well as the entries we include the cache size (since logic such as
// cache miss processing needs to determine this value in a synchronized manner, so it can't be contained in
// the owning interface dispatch indirection cell) and a list entry used to link the caches in one of a couple
// of lists related to cache reclamation.
#pragma warning(push)
#pragma warning(disable:4200) // nonstandard extension used: zero-sized array in struct/union
struct InterfaceDispatchCell;
struct InterfaceDispatchCache
{
InterfaceDispatchCacheHeader m_cacheHeader;
union
{
InterfaceDispatchCache * m_pNextFree; // next in free list
#ifndef _AMD64_
InterfaceDispatchCell * m_pCell; // pointer back to interface dispatch cell - not used for AMD64
#endif
};
UInt32 m_cEntries;
InterfaceDispatchCacheEntry m_rgEntries[];
};
#pragma warning(pop)

#endif // FEATURE_CACHED_INTERFACE_DISPATCH
14 changes: 14 additions & 0 deletions src/Native/Runtime/CallDescr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
struct CallDescrData
{
BYTE* pSrc;
int numStackSlots;
int fpReturnSize;
BYTE* pArgumentRegisters;
BYTE* pFloatArgumentRegisters;
void* pTarget;
void* pReturnBuffer;
};
Loading