Skip to content

Commit

Permalink
Merge pull request dotnet#4021 from dotnet-bot/from-tfs
Browse files Browse the repository at this point in the history
Merge changes from TFS
  • Loading branch information
jkotas committed Mar 31, 2016
2 parents 0cce34c + c4378e7 commit d3502c2
Show file tree
Hide file tree
Showing 45 changed files with 289 additions and 114 deletions.
4 changes: 4 additions & 0 deletions src/ToolBox/SOS/Strike/platformspecific.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ struct DT_UNICODE_STRING
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
#endif

#ifndef IMAGE_FILE_MACHINE_ARM64
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
#endif

#ifdef _TARGET_WIN64_
typedef ULONG DT_GDI_HANDLE_BUFFER[DT_GDI_HANDLE_BUFFER_SIZE64];
#else
Expand Down
2 changes: 2 additions & 0 deletions src/ToolBox/SOS/Strike/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4557,6 +4557,8 @@ class SOSDataTarget : public ICorDebugMutableDataTarget
*pPlatform = CORDB_PLATFORM_WINDOWS_AMD64;
else if(platformKind == IMAGE_FILE_MACHINE_ARMNT)
*pPlatform = CORDB_PLATFORM_WINDOWS_ARM;
else if(platformKind == IMAGE_FILE_MACHINE_ARM64)
*pPlatform = CORDB_PLATFORM_WINDOWS_ARM64;
else
return E_FAIL;
#endif
Expand Down
16 changes: 8 additions & 8 deletions src/debug/daccess/fntableaccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_JIT(IN ReadMemoryFunction
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
OUT PRUNTIME_FUNCTION* ppFunctions)
OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }
Expand Down Expand Up @@ -179,7 +179,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_JIT(IN ReadMemoryFunction
DWORD nEntries;
DWORD index;
DWORD_PTR pUnwindInfo;
PRUNTIME_FUNCTION pFunctions;
PT_RUNTIME_FUNCTION pFunctions;
LONG64 lSmallestOffset;

//
Expand Down Expand Up @@ -217,7 +217,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_JIT(IN ReadMemoryFunction
OutOfProcessFindHeader(fpReadMemory, pUserContext, Hp.pHdrMap, hdrOffset, hdrOffset);
}

pFunctions = (PRUNTIME_FUNCTION)ClrHeapAlloc(ClrGetProcessHeap(), HEAP_ZERO_MEMORY, S_SIZE_T(nEntries) * S_SIZE_T(sizeof(RUNTIME_FUNCTION)));
pFunctions = (PT_RUNTIME_FUNCTION)ClrHeapAlloc(ClrGetProcessHeap(), HEAP_ZERO_MEMORY, S_SIZE_T(nEntries) * S_SIZE_T(sizeof(T_RUNTIME_FUNCTION)));
*ppFunctions = pFunctions;
*pnEntries = nEntries;

Expand Down Expand Up @@ -274,7 +274,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_Stub(IN ReadMemoryFunction
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
OUT PRUNTIME_FUNCTION* ppFunctions)
OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }
Expand All @@ -292,7 +292,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_Stub(IN ReadMemoryFunction

UINT nEntries = 0;
UINT nEntriesAllocated = 0;
RUNTIME_FUNCTION *rgFunctions = NULL;
PT_RUNTIME_FUNCTION rgFunctions = NULL;

for (int pass = 1; pass <= 2; pass++)
{
Expand Down Expand Up @@ -371,7 +371,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_Stub(IN ReadMemoryFunction

_ASSERTE(!nEntriesAllocated);
nEntriesAllocated = nEntries;
rgFunctions = (PRUNTIME_FUNCTION)ClrHeapAlloc(ClrGetProcessHeap(), HEAP_ZERO_MEMORY, S_SIZE_T(nEntries) * S_SIZE_T(sizeof(RUNTIME_FUNCTION)));
rgFunctions = (PT_RUNTIME_FUNCTION)ClrHeapAlloc(ClrGetProcessHeap(), HEAP_ZERO_MEMORY, S_SIZE_T(nEntries) * S_SIZE_T(sizeof(T_RUNTIME_FUNCTION)));
nEntries = 0;
}
else
Expand All @@ -397,7 +397,7 @@ BOOL ReadMemory(PVOID pUserContext, LPCVOID lpBaseAddress, PVOID lpBuffer, SIZE_
extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess,
IN PVOID TableAddress,
OUT PULONG pnEntries,
OUT PRUNTIME_FUNCTION* ppFunctions)
OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
return OutOfProcessFunctionTableCallbackEx(&ReadMemory, hProcess, TableAddress, pnEntries, ppFunctions);
}
Expand All @@ -406,7 +406,7 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
OUT PRUNTIME_FUNCTION* ppFunctions)
OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }
Expand Down
8 changes: 4 additions & 4 deletions src/debug/daccess/fntableaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ typedef struct _FakeHpRealCodeHdr
LPVOID phdrJitGCInfo; // changed from BYTE*
LPVOID hdrMDesc; // changed from MethodDesc*
DWORD nUnwindInfos;
RUNTIME_FUNCTION unwindInfos[0];
T_RUNTIME_FUNCTION unwindInfos[0];
} FakeRealCodeHeader;

typedef struct _FakeHpCodeHdr
Expand All @@ -75,7 +75,7 @@ struct FakeStubUnwindInfoHeaderSuffix
struct FakeStubUnwindInfoHeader
{
FakeStubUnwindInfoHeader *pNext;
RUNTIME_FUNCTION FunctionEntry;
T_RUNTIME_FUNCTION FunctionEntry;
UNWIND_INFO UnwindInfo; // variable length
};

Expand Down Expand Up @@ -200,7 +200,7 @@ static_assert_no_msg( FAKEDYNFNTABLE_STUB

BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD dwReason, LPVOID pReserved);
//NTSTATUS OutOfProcessFindHeader(HANDLE hProcess, DWORD_PTR pMapIn, DWORD_PTR addr, DWORD_PTR &codeHead);
extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PRUNTIME_FUNCTION* ppFunctions);
extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PT_RUNTIME_FUNCTION* ppFunctions);


// OutOfProcessFunctionTableCallbackEx is like the standard OS-defined OutOfProcessFunctionTableCallback, but rather
Expand All @@ -209,7 +209,7 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess, IN
// pUserContext is passed directly to fpReadMemory, and the semantics of all other ReadMemoryFunction arguments (and return value) are
// the same as those for kernel32!ReadProcessMemory.
typedef BOOL (ReadMemoryFunction)(PVOID pUserContext, LPCVOID lpBaseAddress, PVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction fpReadMemory, IN PVOID pUserContext, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PRUNTIME_FUNCTION* ppFunctions);
extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction fpReadMemory, IN PVOID pUserContext, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PT_RUNTIME_FUNCTION* ppFunctions);

#endif // CHECK_DUPLICATED_STRUCT_LAYOUTS

Expand Down
2 changes: 1 addition & 1 deletion src/debug/daccess/nidump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9315,7 +9315,7 @@ void NativeImageDumper::DumpReadyToRun()
if (pRuntimeFunctionsDir != NULL)
{
m_pRuntimeFunctions = dac_cast<PTR_RUNTIME_FUNCTION>(m_decoder.GetDirectoryData(pRuntimeFunctionsDir));
m_nRuntimeFunctions = pRuntimeFunctionsDir->Size / sizeof(RUNTIME_FUNCTION);
m_nRuntimeFunctions = pRuntimeFunctionsDir->Size / sizeof(T_RUNTIME_FUNCTION);
}
else
{
Expand Down
23 changes: 19 additions & 4 deletions src/gcdump/gcdumpnonx86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,27 @@ PCSTR GetRegName (UINT32 regnum)

return "???";
#elif defined(_TARGET_ARM64_)
if (regnum > 28)
return "???";

static CHAR szRegName[16];
_snprintf_s(szRegName, _countof(szRegName), sizeof(szRegName), "X%u", regnum);
return szRegName;
if (regnum < 29)
{
_snprintf_s(szRegName, _countof(szRegName), sizeof(szRegName), "X%u", regnum);
return szRegName;
}
else if(regnum == 29)
{
return "Fp";
}
else if(regnum == 30)
{
return "Lr";
}
else if(regnum == 31)
{
return "Sp";
}

return "???";
#elif defined(_TARGET_ARM_)
if (regnum > 128)
return "???";
Expand Down
79 changes: 71 additions & 8 deletions src/gcinfo/gcinfodumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ void GcInfoDumper::FreePointerRecords (LivePointerRecord *pRecords)
}
}

//This function tries to find the address of the managed object in the registers of the current function's context,
//failing which it checks if it is present in the stack of the current function. IF it finds one it reports appropriately
//
//For Amd64, this additionally tries to probe in the stack for the caller.
//This behavior largely seems to be present for legacy x64 jit and is not likely to be used anywhere else
BOOL GcInfoDumper::ReportPointerRecord (
UINT32 CodeOffset,
BOOL fLive,
Expand Down Expand Up @@ -146,7 +151,6 @@ BOOL GcInfoDumper::ReportPointerRecord (
{ FIELD_OFFSET(T_CONTEXT, Sp) },
{ FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, R7) },
#elif defined(_TARGET_ARM64_)
//ARM64TODO: Verify the correctness of the following for ARM64
#undef REG
#define REG(reg, field) { FIELD_OFFSET(Arm64VolatileContextPointer, field) }
REG(x0, X0),
Expand All @@ -167,7 +171,6 @@ BOOL GcInfoDumper::ReportPointerRecord (
REG(x15, X15),
REG(x16, X16),
REG(x17, X17),
{ FIELD_OFFSET(T_CONTEXT, X18) },
#undef REG
#define REG(reg, field) { FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, field) }
REG(x19, X19),
Expand All @@ -180,11 +183,14 @@ BOOL GcInfoDumper::ReportPointerRecord (
REG(x26, X26),
REG(x27, X27),
REG(x28, X28),
REG(Fp, Fp),
REG(Lr, Lr),
{ FIELD_OFFSET(T_CONTEXT, Sp) },
{ FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, Lr) },
#undef REG
#else
PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this platform.")
#endif

#undef REG
};

const UINT nCONTEXTRegisters = sizeof(rgRegisters)/sizeof(rgRegisters[0]);
Expand All @@ -199,13 +205,12 @@ BOOL GcInfoDumper::ReportPointerRecord (
iSPRegister = (FIELD_OFFSET(CONTEXT, Rsp) - FIELD_OFFSET(CONTEXT, Rax)) / sizeof(ULONGLONG);
#elif defined(_TARGET_ARM64_)
iSPRegister = (FIELD_OFFSET(T_CONTEXT, Sp) - FIELD_OFFSET(T_CONTEXT, X0)) / sizeof(ULONGLONG);
UINT iBFRegister = m_StackBaseRegister;
#elif defined(_TARGET_ARM_)
iSPRegister = (FIELD_OFFSET(T_CONTEXT, Sp) - FIELD_OFFSET(T_CONTEXT, R0)) / sizeof(ULONG);
UINT iBFRegister = m_StackBaseRegister;
#endif

#ifdef _TARGET_ARM_
#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
BYTE* pContext = (BYTE*)&(pRD->volatileCurrContextPointers);
#else
BYTE* pContext = (BYTE*)pRD->pCurrentContext;
Expand Down Expand Up @@ -254,6 +259,25 @@ BOOL GcInfoDumper::ReportPointerRecord (
{
break;
}
#elif defined (_TARGET_ARM64_)

if (ctx == 1)
{
if (iReg < 18 ) // skip volatile registers for second context
{
continue;
}

if (iReg == 30)
{
iEncodedReg = iSPRegister;
}
}

if (ctx == 0 && iReg > 17)
{
break;
}
#endif
{
_ASSERTE(iReg < nCONTEXTRegisters);
Expand All @@ -271,6 +295,13 @@ BOOL GcInfoDumper::ReportPointerRecord (
{
pReg = *(SIZE_T**)((BYTE*)pRD->pCurrentContextPointers + rgRegisters[iEncodedReg].cbContextOffset);
}

#elif defined(_TARGET_ARM64_)
pReg = *(SIZE_T**)(pContext + rgRegisters[iReg].cbContextOffset);
if (iEncodedReg == iSPRegister)
{
pReg = (SIZE_T*)((BYTE*)pRD->pCurrentContext + rgRegisters[iEncodedReg].cbContextOffset);
}
#else
pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
#endif
Expand All @@ -286,7 +317,7 @@ BOOL GcInfoDumper::ReportPointerRecord (
if (ptr == (SIZE_T)pReg)
{
// Make sure the register is in the current frame.
#ifndef _TARGET_ARM_
#if defined(_TARGET_AMD64_)
if (0 != ctx)
{
m_Error = REPORTED_REGISTER_IN_CALLERS_FRAME;
Expand Down Expand Up @@ -338,10 +369,14 @@ BOOL GcInfoDumper::ReportPointerRecord (
GcStackSlotBase base;
if (iSPRegister == iEncodedReg)
{
#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
base = GC_SP_REL;
#else
if (0 == ctx)
base = GC_SP_REL;
else
base = GC_CALLER_SP_REL;
#endif //defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
}
else
{
Expand All @@ -363,7 +398,7 @@ BOOL GcInfoDumper::ReportPointerRecord (
}
}

#ifdef _TARGET_ARM_
#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
pContext = (BYTE*)pRD->pCurrentContextPointers;
#else
pContext = (BYTE*)pRD->pCallerContext;
Expand Down Expand Up @@ -542,6 +577,34 @@ GcInfoDumper::EnumerateStateChangesResults GcInfoDumper::EnumerateStateChanges (
}
/// Set R12
*(ppVolatileReg+4) = &regdisp.pCurrentContext->R0+12;

#elif defined(_TARGET_ARM64_)
FILL_REGS(pCurrentContext->X0, 33);
FILL_REGS(pCallerContext->X0, 33);

regdisp.pCurrentContextPointers = &regdisp.ctxPtrsOne;
regdisp.pCallerContextPointers = &regdisp.ctxPtrsTwo;

ULONG64 **ppCurrentReg = &regdisp.pCurrentContextPointers->X19;
ULONG64 **ppCallerReg = &regdisp.pCallerContextPointers->X19;

for (iReg = 0; iReg < 11; iReg++)
{
*(ppCurrentReg + iReg) = &regdisp.pCurrentContext->X19 + iReg;
*(ppCallerReg + iReg) = &regdisp.pCallerContext->X19 + iReg;
}

/// Set Lr
*(ppCurrentReg + 11) = &regdisp.pCurrentContext->Lr;
*(ppCallerReg + 11) = &regdisp.pCallerContext->Lr;

ULONG64 **ppVolatileReg = &regdisp.volatileCurrContextPointers.X0;
for (iReg = 0; iReg < 18; iReg++)
{
*(ppVolatileReg+iReg) = &regdisp.pCurrentContext->X0 + iReg;
}
#else
PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on this platform.")
#endif

#undef FILL_REGS
Expand Down
13 changes: 7 additions & 6 deletions src/inc/clrnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ typedef enum _FUNCTION_TABLE_TYPE {

typedef struct _DYNAMIC_FUNCTION_TABLE {
LIST_ENTRY Links;
PRUNTIME_FUNCTION FunctionTable;
PT_RUNTIME_FUNCTION FunctionTable;
LARGE_INTEGER TimeStamp;

#ifdef _TARGET_ARM_
Expand Down Expand Up @@ -796,7 +796,7 @@ typedef struct _DYNAMIC_FUNCTION_TABLE {

#define RUNTIME_FUNCTION__GetUnwindInfoAddress(prf) (prf)->UnwindData
#define RUNTIME_FUNCTION__SetUnwindInfoAddress(prf,address) do { (prf)->UnwindData = (address); } while (0)
#define OFFSETOF__RUNTIME_FUNCTION__UnwindInfoAddress offsetof(RUNTIME_FUNCTION, UnwindData)
#define OFFSETOF__RUNTIME_FUNCTION__UnwindInfoAddress offsetof(T_RUNTIME_FUNCTION, UnwindData)


//
Expand Down Expand Up @@ -893,7 +893,7 @@ PEXCEPTION_ROUTINE
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
IN PRUNTIME_FUNCTION FunctionEntry,
IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
Expand All @@ -908,7 +908,7 @@ RtlVirtualUnwind_Unsafe(
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
IN PRUNTIME_FUNCTION FunctionEntry,
IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
Expand Down Expand Up @@ -951,7 +951,7 @@ typedef struct _DISPATCHER_CONTEXT {
FORCEINLINE
ULONG
RtlpGetFunctionEndAddress (
__in PRUNTIME_FUNCTION FunctionEntry,
__in PT_RUNTIME_FUNCTION FunctionEntry,
__in ULONG ImageBase
)
{
Expand Down Expand Up @@ -1011,6 +1011,7 @@ RtlVirtualUnwind (
#endif // _TARGET_ARM_

#ifdef _TARGET_ARM64_
#include "daccess.h"

#define UNW_FLAG_NHANDLER 0x0 /* any handler */
#define UNW_FLAG_EHANDLER 0x1 /* filter handler */
Expand All @@ -1031,7 +1032,7 @@ RtlpGetFunctionEndAddress (
if ((FunctionLength & 3) != 0) {
FunctionLength = (FunctionLength >> 2) & 0x7ff;
} else {
FunctionLength = *(ULONG64*)(ImageBase + FunctionLength) & 0x3ffff;
FunctionLength = *(PTR_ULONG64)(ImageBase + FunctionLength) & 0x3ffff;
}

return FunctionEntry->BeginAddress + 4 * FunctionLength;
Expand Down
Loading

0 comments on commit d3502c2

Please sign in to comment.