summaryrefslogtreecommitdiff
path: root/packaging/0031-Port-to-2.0.0-Fix-ARM32-secure-delegate-bug.patch
blob: 71c07441d52bbe37b54f32eacd5f4740d2a308ea (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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
From d1a968702e2fec725255ec77de254293104b191f Mon Sep 17 00:00:00 2001
From: Jan Vorlicek <janvorli@microsoft.com>
Date: Wed, 13 Sep 2017 08:16:39 -0700
Subject: [PATCH] Port to 2.0.0 - Fix ARM32 secure delegate bug

This change fixes a bug that causes crashes when secure delegate is
invoked on ARM32 with legacy codegen. Register R4 was loaded with
indirection slot address and immediatelly marked as trashed, so the JIT
compiler reused it before the call that was supposed to have that value
in R4.
The fix was to move the reg trashing after the call.
There was also an incorrect marking of that address as EA_PTRSIZE
while it should be EA_BYREF, so I've fixed that too.
---
 src/jit/codegenlegacy.cpp | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp
index d653511..b8a239a 100644
--- a/src/jit/codegenlegacy.cpp
+++ b/src/jit/codegenlegacy.cpp
@@ -18632,12 +18632,20 @@ regMaskTP CodeGen::genCodeForCall(GenTreeCall* call, bool valUsed)
         firstTgtOffs = pInfo->offsetOfDelegateFirstTarget;
 
 #ifdef _TARGET_ARM_
+        // Ensure that we don't trash any of these registers if we have to load
+        // the helper call target into a register to invoke it.
+        regMaskTP regsUsed = 0;
+
         if ((call->gtCallMoreFlags & GTF_CALL_M_SECURE_DELEGATE_INV))
         {
-            getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, REG_VIRTUAL_STUB_PARAM, regThis,
+            getEmitter()->emitIns_R_R_I(INS_add, EA_BYREF, REG_VIRTUAL_STUB_PARAM, regThis,
                                         pInfo->offsetOfSecureDelegateIndirectCell);
             regTracker.rsTrackRegTrash(REG_VIRTUAL_STUB_PARAM);
+
+            // Ensure that the virtual stub param info register doesn't get reused before the call is taken
+            regSet.rsLockReg(RBM_VIRTUAL_STUB_PARAM, &regsUsed);
         }
+
 #endif // _TARGET_ARM_
 
         // Grab an available register to use for the CALL indirection
@@ -18661,6 +18669,13 @@ regMaskTP CodeGen::genCodeForCall(GenTreeCall* call, bool valUsed)
                                    INDEBUG_LDISASM_COMMA(sigInfo) NULL, // addr
                                    args, retSize, gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
                                    gcInfo.gcRegByrefSetCur, ilOffset, indCallReg);
+
+#ifdef _TARGET_ARM_
+        if ((call->gtCallMoreFlags & GTF_CALL_M_SECURE_DELEGATE_INV))
+        {
+            regSet.rsUnlockReg(RBM_VIRTUAL_STUB_PARAM, regsUsed);
+        }
+#endif // _TARGET_ARM_
     }
     else
 
-- 
2.7.4