summaryrefslogtreecommitdiff
path: root/src/vm/arm64
diff options
context:
space:
mode:
authorSwaroop Sridhar <swaroops@microsoft.com>2016-06-09 14:23:35 -0700
committerSwaroop Sridhar <swaroops@microsoft.com>2016-06-09 14:23:35 -0700
commit40150200e231eb3d5c5eee9ee9173abf7ecb15a1 (patch)
tree2ea1574e5a95edc9dbf79ce91bc33a519b18e245 /src/vm/arm64
parent3a4711b18816c4acd526d63cc1690a5f87dd58a9 (diff)
downloadcoreclr-40150200e231eb3d5c5eee9ee9173abf7ecb15a1.tar.gz
coreclr-40150200e231eb3d5c5eee9ee9173abf7ecb15a1.tar.bz2
coreclr-40150200e231eb3d5c5eee9ee9173abf7ecb15a1.zip
ARM64: Don't track LR as part of NV-Context
The _pc and _sp fields actually refer to the caller's PC and SP values. So, remove read/writes of LR in captureX19_X29 array of ARM64 MachState. This change fixes a buffer overflow problem.
Diffstat (limited to 'src/vm/arm64')
-rw-r--r--src/vm/arm64/gmscpu.h4
-rw-r--r--src/vm/arm64/stubs.cpp14
2 files changed, 8 insertions, 10 deletions
diff --git a/src/vm/arm64/gmscpu.h b/src/vm/arm64/gmscpu.h
index eb813f892e..e95ef63d7d 100644
--- a/src/vm/arm64/gmscpu.h
+++ b/src/vm/arm64/gmscpu.h
@@ -23,8 +23,8 @@
struct MachState {
ULONG64 captureX19_X29[NUM_NONVOLATILE_CONTEXT_POINTERS]; // preserved registers
PTR_ULONG64 ptrX19_X29[NUM_NONVOLATILE_CONTEXT_POINTERS]; // pointers to preserved registers
- TADDR _pc;
- TADDR _sp;
+ TADDR _pc; // program counter after the function returns
+ TADDR _sp; // stack pointer after the function returns
BOOL _isValid;
BOOL isValid() { LIMITED_METHOD_DAC_CONTRACT; return _isValid; }
diff --git a/src/vm/arm64/stubs.cpp b/src/vm/arm64/stubs.cpp
index 8feae86dda..7c2afa115e 100644
--- a/src/vm/arm64/stubs.cpp
+++ b/src/vm/arm64/stubs.cpp
@@ -288,7 +288,7 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
context.X27 = unwoundstate->captureX19_X29[8] = baseState->captureX19_X29[8];
context.X28 = unwoundstate->captureX19_X29[9] = baseState->captureX19_X29[9];
context.Fp = unwoundstate->captureX19_X29[10] = baseState->captureX19_X29[10];
- context.Lr = unwoundstate->captureX19_X29[11] = baseState->captureX19_X29[11];
+ context.Lr = NULL; // Filled by the unwinder
context.Sp = baseState->captureSp;
context.Pc = baseState->captureIp;
@@ -309,7 +309,7 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
nonVolContextPtrs.X27 = &unwoundstate->captureX19_X29[8];
nonVolContextPtrs.X28 = &unwoundstate->captureX19_X29[9];
nonVolContextPtrs.Fp = &unwoundstate->captureX19_X29[10];
- nonVolContextPtrs.Lr = &unwoundstate->captureX19_X29[11];
+ nonVolContextPtrs.Lr = NULL; // Filled by the unwinder
#endif // DACCESS_COMPILE
@@ -370,7 +370,6 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
unwoundstate->captureX19_X29[8] = context.X27;
unwoundstate->captureX19_X29[9] = context.X28;
unwoundstate->captureX19_X29[10] = context.Fp;
- unwoundstate->captureX19_X29[11] = context.Lr;
#else // !DACCESS_COMPILE
// For non-DAC builds, update the register state from context pointers
unwoundstate->ptrX19_X29[0] = nonVolContextPtrs.X19;
@@ -384,7 +383,6 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
unwoundstate->ptrX19_X29[8] = nonVolContextPtrs.X27;
unwoundstate->ptrX19_X29[9] = nonVolContextPtrs.X28;
unwoundstate->ptrX19_X29[10] = nonVolContextPtrs.Fp;
- unwoundstate->ptrX19_X29[11] = nonVolContextPtrs.Lr;
#endif // DACCESS_COMPILE
unwoundstate->_pc = context.Pc;
@@ -437,14 +435,14 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContext->X27 = (DWORD64)(pUnwoundState->captureX19_X29[8]);
pRD->pCurrentContext->X28 = (DWORD64)(pUnwoundState->captureX19_X29[9]);
pRD->pCurrentContext->Fp = (DWORD64)(pUnwoundState->captureX19_X29[10]);
- pRD->pCurrentContext->Lr = (DWORD64)(pUnwoundState->captureX19_X29[11]);
+ pRD->pCurrentContext->Lr = NULL; // Unwind again to get Caller's PC
return;
}
#endif // DACCESS_COMPILE
// reset pContext; it's only valid for active (top-most) frame
pRD->pContext = NULL;
- pRD->ControlPC = GetReturnAddress();
+ pRD->ControlPC = GetReturnAddress(); // m_MachState._pc;
pRD->SP = (DWORD64)(size_t)m_MachState._sp;
pRD->pCurrentContext->Pc = pRD->ControlPC;
@@ -461,7 +459,7 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContext->X27 = *m_MachState.ptrX19_X29[8];
pRD->pCurrentContext->X28 = *m_MachState.ptrX19_X29[9];
pRD->pCurrentContext->Fp = *m_MachState.ptrX19_X29[10];
- pRD->pCurrentContext->Lr = *m_MachState.ptrX19_X29[11];
+ pRD->pCurrentContext->Lr = NULL; // Unwind again to get Caller's PC
#if !defined(DACCESS_COMPILE)
pRD->pCurrentContextPointers->X19 = m_MachState.ptrX19_X29[0];
@@ -475,7 +473,7 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContextPointers->X27 = m_MachState.ptrX19_X29[8];
pRD->pCurrentContextPointers->X28 = m_MachState.ptrX19_X29[9];
pRD->pCurrentContextPointers->Fp = m_MachState.ptrX19_X29[10];
- pRD->pCurrentContextPointers->Lr = m_MachState.ptrX19_X29[11];
+ pRD->pCurrentContextPointers->Lr = NULL; // Unwind again to get Caller's PC
#endif
}
#endif // CROSSGEN_COMPILE