summaryrefslogtreecommitdiff
path: root/src/vm/amd64/gmsamd64.cpp
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2015-02-16 15:43:50 +0100
committerJan Vorlicek <janvorli@microsoft.com>2015-02-16 15:43:50 +0100
commitfb11bcafc8bae0924b51ed4483ed35d884852dc4 (patch)
treed3433a943bcf8e277cd2618be3e411e17a1db617 /src/vm/amd64/gmsamd64.cpp
parent0e20a9e34ad2b861460c2772865653082ca06dfd (diff)
downloadcoreclr-fb11bcafc8bae0924b51ed4483ed35d884852dc4.tar.gz
coreclr-fb11bcafc8bae0924b51ed4483ed35d884852dc4.tar.bz2
coreclr-fb11bcafc8bae0924b51ed4483ed35d884852dc4.zip
Implement native stack unwinding for Linux
This change implements native stack unwinding using the libunwind on Linux. I have also fixed bunch of issues / details in the related code: 1) 0x in front of %p inside format string 2) Subtraction of -1 from dl_info.dli_sname 3) Added .cfi_xxxx annotation to the CallDescrWorkerInternal and the LEAF_ENTRY / LEAF_END macros. 4) Changed local labels in the CallDescrWorkerInternal to be prefixed by .L to see the CallDescrWorkerInternal in the stack trace 5) Changed moveOWord to use movdqu - it was being called with one of the parameters unaligned
Diffstat (limited to 'src/vm/amd64/gmsamd64.cpp')
-rw-r--r--src/vm/amd64/gmsamd64.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/vm/amd64/gmsamd64.cpp b/src/vm/amd64/gmsamd64.cpp
index 8f59388410..6b0fd3aa9c 100644
--- a/src/vm/amd64/gmsamd64.cpp
+++ b/src/vm/amd64/gmsamd64.cpp
@@ -30,8 +30,10 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
ctx.Rip = baseState->m_CaptureRip;
ctx.Rsp = baseState->m_CaptureRsp + 8; // +8 for return addr pushed before calling LazyMachStateCaptureState
+#ifndef UNIX_AMD64_ABI
ctx.Rdi = unwoundState->m_CaptureRdi = baseState->m_CaptureRdi;
ctx.Rsi = unwoundState->m_CaptureRsi = baseState->m_CaptureRsi;
+#endif
ctx.Rbx = unwoundState->m_CaptureRbx = baseState->m_CaptureRbx;
ctx.Rbp = unwoundState->m_CaptureRbp = baseState->m_CaptureRbp;
ctx.R12 = unwoundState->m_CaptureR12 = baseState->m_CaptureR12;
@@ -42,8 +44,10 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
#if !defined(DACCESS_COMPILE)
// For DAC, if we get here, it means that the LazyMachState is uninitialized and we have to unwind it.
// The API we use to unwind in DAC is StackWalk64(), which does not support the context pointers.
+#ifndef UNIX_AMD64_ABI
nonVolRegPtrs.Rdi = &unwoundState->m_CaptureRdi;
nonVolRegPtrs.Rsi = &unwoundState->m_CaptureRsi;
+#endif
nonVolRegPtrs.Rbx = &unwoundState->m_CaptureRbx;
nonVolRegPtrs.Rbp = &unwoundState->m_CaptureRbp;
nonVolRegPtrs.R12 = &unwoundState->m_CaptureR12;
@@ -58,7 +62,13 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
do
{
+
+#ifndef FEATURE_PAL
pvControlPc = Thread::VirtualUnwindCallFrame(&ctx, &nonVolRegPtrs);
+#else // !FEATURE_PAL
+ VirtualUnwind(&ctx, &nonVolRegPtrs);
+ pvControlPc = GetIP(&ctx);
+#endif // !FEATURE_PAL
if (funCallDepth > 0)
{
@@ -105,8 +115,10 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
#if defined(DACCESS_COMPILE)
// For DAC, we have to update the registers directly, since we don't have context pointers.
+#ifndef UNIX_AMD64_ABI
unwoundState->m_CaptureRdi = ctx.Rdi;
unwoundState->m_CaptureRsi = ctx.Rsi;
+#endif
unwoundState->m_CaptureRbx = ctx.Rbx;
unwoundState->m_CaptureRbp = ctx.Rbp;
unwoundState->m_CaptureR12 = ctx.R12;
@@ -115,8 +127,10 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
unwoundState->m_CaptureR15 = ctx.R15;
#else // !DACCESS_COMPILE
+#ifndef UNIX_AMD64_ABI
unwoundState->m_pRdi = PTR_ULONG64(nonVolRegPtrs.Rdi);
unwoundState->m_pRsi = PTR_ULONG64(nonVolRegPtrs.Rsi);
+#endif
unwoundState->m_pRbx = PTR_ULONG64(nonVolRegPtrs.Rbx);
unwoundState->m_pRbp = PTR_ULONG64(nonVolRegPtrs.Rbp);
unwoundState->m_pR12 = PTR_ULONG64(nonVolRegPtrs.R12);