summaryrefslogtreecommitdiff
path: root/packaging/0004-Fix-funclet-unwinding-on-x86-Linux-17144.patch
blob: f799927faa2b60a116465536fb9d2b886b7b6053 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
From 0a8faa1c58f1a60c3ff60e89b7bd1ae36afa1733 Mon Sep 17 00:00:00 2001
From: Igor Kulaychuk <igor.kulaychuk@gmail.com>
Date: Mon, 26 Mar 2018 20:58:16 +0300
Subject: [PATCH 4/5] Fix funclet unwinding on x86 Linux (#17144)

---
 src/vm/eetwain.cpp | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
index 4a02be7..fbf669b 100644
--- a/src/vm/eetwain.cpp
+++ b/src/vm/eetwain.cpp
@@ -3832,8 +3832,27 @@ bool UnwindEbpDoubleAlignFrame(
             baseSP = curESP;
             // Set baseSP as initial SP
             baseSP += GetPushedArgSize(info, table, curOffs);
+
             // 16-byte stack alignment padding (allocated in genFuncletProlog)
-            baseSP += 12;
+            // Current funclet frame layout (see CodeGen::genFuncletProlog() and genFuncletEpilog()):
+            //   prolog: sub esp, 12
+            //   epilog: add esp, 12
+            //           ret
+            // SP alignment padding should be added for all instructions except the first one and the last one.
+            TADDR funcletStart = pCodeInfo->GetJitManager()->GetFuncletStartAddress(pCodeInfo);
+
+            const ULONG32 funcletLastInstSize = 1; // 0xc3, ret
+            BOOL atFuncletLastInst = (pCodeInfo->GetRelOffset() + funcletLastInstSize) >= info->methodSize;
+            if (!atFuncletLastInst)
+            {
+                EECodeInfo nextCodeInfo;
+                nextCodeInfo.Init(pCodeInfo->GetCodeAddress() + funcletLastInstSize);
+                atFuncletLastInst = !nextCodeInfo.IsValid() || !nextCodeInfo.IsFunclet() ||
+                    nextCodeInfo.GetJitManager()->GetFuncletStartAddress(&nextCodeInfo) != funcletStart;
+            }
+
+            if (!atFuncletLastInst && funcletStart != pCodeInfo->GetCodeAddress())
+                baseSP += 12;
 
             pContext->PCTAddr = baseSP;
             pContext->ControlPC = *PTR_PCODE(pContext->PCTAddr);
-- 
2.7.4