summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorEgor Chesakov <Egor.Chesakov@microsoft.com>2019-06-05 16:24:12 -0700
committerGitHub <noreply@github.com>2019-06-05 16:24:12 -0700
commit10df20ed3ff0208b3f16f79d5062662a8827f579 (patch)
tree43d2a1e58fd64960a96f6328b5fa42e40152122a /src/jit
parenta64cb0a41a4ebeb4a61b8b0f1f2eeeff8dd539c9 (diff)
downloadcoreclr-10df20ed3ff0208b3f16f79d5062662a8827f579.tar.gz
coreclr-10df20ed3ff0208b3f16f79d5062662a8827f579.tar.bz2
coreclr-10df20ed3ff0208b3f16f79d5062662a8827f579.zip
Zero initReg in genSetGSSecurityCookie (#24371)
Fix an issue that is reproduced when 1) a register is used in the prolog for initializing GSSecurityCookie (i.e. the register contains a random non-zero value) and 2) the same register holds a must-init GC variable in the next basic block and 3) the variable is live at the beginning of this basic block. The register was not zeroed at the end of the prolog and this was causing segmentation fault during GC.Collect().
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/codegen.h3
-rw-r--r--src/jit/codegenarmarch.cpp38
-rw-r--r--src/jit/codegencommon.cpp56
-rw-r--r--src/jit/codegenxarch.cpp64
-rw-r--r--src/jit/instr.cpp33
5 files changed, 97 insertions, 97 deletions
diff --git a/src/jit/codegen.h b/src/jit/codegen.h
index fcbf4d8ec9..ef1443d0fa 100644
--- a/src/jit/codegen.h
+++ b/src/jit/codegen.h
@@ -1413,9 +1413,6 @@ public:
void instGen_Store_Reg_Into_Lcl(var_types dstType, regNumber srcReg, int varNum, int offs);
- void instGen_Store_Imm_Into_Lcl(
- var_types dstType, emitAttr sizeAttr, ssize_t imm, int varNum, int offs, regNumber regToUse = REG_NA);
-
#ifdef DEBUG
void __cdecl instDisp(instruction ins, bool noNL, const char* fmt, ...);
#endif
diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp
index 87cbd6d1d5..9476e6595d 100644
--- a/src/jit/codegenarmarch.cpp
+++ b/src/jit/codegenarmarch.cpp
@@ -568,6 +568,44 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla
}
//---------------------------------------------------------------------
+// genSetGSSecurityCookie: Set the "GS" security cookie in the prolog.
+//
+// Arguments:
+// initReg - register to use as a scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
+// this call sets 'initReg' to a non-zero value.
+//
+// Return Value:
+// None
+//
+void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed)
+{
+ assert(compiler->compGeneratingProlog);
+
+ if (!compiler->getNeedsGSSecurityCookie())
+ {
+ return;
+ }
+
+ if (compiler->gsGlobalSecurityCookieAddr == nullptr)
+ {
+ noway_assert(compiler->gsGlobalSecurityCookieVal != 0);
+ // initReg = #GlobalSecurityCookieVal; [frame.GSSecurityCookie] = initReg
+ genSetRegToIcon(initReg, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL);
+ getEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0);
+ }
+ else
+ {
+ instGen_Set_Reg_To_Imm(EA_PTR_DSP_RELOC, initReg, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, initReg, initReg, 0);
+ regSet.verifyRegUsed(initReg);
+ getEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0);
+ }
+
+ *pInitRegZeroed = false;
+}
+
+//---------------------------------------------------------------------
// genIntrinsic - generate code for a given intrinsic
//
// Arguments
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index 4edcda90b9..bb81361d9b 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -6483,62 +6483,6 @@ void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed
#endif // !ARM64 !ARM
}
-/*-----------------------------------------------------------------------------
- *
- * Set the "GS" security cookie in the prolog.
- */
-
-void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed)
-{
- assert(compiler->compGeneratingProlog);
-
- if (!compiler->getNeedsGSSecurityCookie())
- {
- return;
- }
-
- noway_assert(compiler->gsGlobalSecurityCookieAddr || compiler->gsGlobalSecurityCookieVal);
-
- if (compiler->gsGlobalSecurityCookieAddr == nullptr)
- {
-#ifdef _TARGET_AMD64_
- // eax = #GlobalSecurityCookieVal64; [frame.GSSecurityCookie] = eax
- getEmitter()->emitIns_R_I(INS_mov, EA_PTRSIZE, REG_RAX, compiler->gsGlobalSecurityCookieVal);
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_RAX, compiler->lvaGSSecurityCookie, 0);
-#else
- // mov dword ptr [frame.GSSecurityCookie], #GlobalSecurityCookieVal
- instGen_Store_Imm_Into_Lcl(TYP_I_IMPL, EA_PTRSIZE, compiler->gsGlobalSecurityCookieVal,
- compiler->lvaGSSecurityCookie, 0, initReg);
-#endif
- }
- else
- {
- regNumber reg;
-#ifdef _TARGET_XARCH_
- // Always use EAX on x86 and x64
- // On x64, if we're not moving into RAX, and the address isn't RIP relative, we can't encode it.
- reg = REG_EAX;
-#else
- // We will just use the initReg since it is an available register
- reg = initReg;
-#endif
-
- *pInitRegZeroed = false;
-
-#if CPU_LOAD_STORE_ARCH
- instGen_Set_Reg_To_Imm(EA_PTR_DSP_RELOC, reg, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
- getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg, reg, 0);
- regSet.verifyRegUsed(reg);
-#else
- // mov reg, dword ptr [compiler->gsGlobalSecurityCookieAddr]
- // mov dword ptr [frame.GSSecurityCookie], reg
- getEmitter()->emitIns_R_AI(INS_mov, EA_PTR_DSP_RELOC, reg, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
- regSet.verifyRegUsed(reg);
-#endif
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, reg, compiler->lvaGSSecurityCookie, 0);
- }
-}
-
#ifdef PROFILING_SUPPORTED
//-----------------------------------------------------------------------------------
diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp
index 9184c09b39..521aaca407 100644
--- a/src/jit/codegenxarch.cpp
+++ b/src/jit/codegenxarch.cpp
@@ -49,6 +49,61 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla
}
}
+//---------------------------------------------------------------------
+// genSetGSSecurityCookie: Set the "GS" security cookie in the prolog.
+//
+// Arguments:
+// initReg - register to use as a scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed is set to 'false' if and only if
+// this call sets 'initReg' to a non-zero value.
+//
+// Return Value:
+// None
+//
+void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed)
+{
+ assert(compiler->compGeneratingProlog);
+
+ if (!compiler->getNeedsGSSecurityCookie())
+ {
+ return;
+ }
+
+ if (compiler->gsGlobalSecurityCookieAddr == nullptr)
+ {
+ noway_assert(compiler->gsGlobalSecurityCookieVal != 0);
+#ifdef _TARGET_AMD64_
+ if ((int)compiler->gsGlobalSecurityCookieVal != compiler->gsGlobalSecurityCookieVal)
+ {
+ // initReg = #GlobalSecurityCookieVal64; [frame.GSSecurityCookie] = initReg
+ genSetRegToIcon(initReg, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL);
+ getEmitter()->emitIns_S_R(INS_mov, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0);
+ *pInitRegZeroed = false;
+ }
+ else
+#endif
+ {
+ // mov dword ptr [frame.GSSecurityCookie], #GlobalSecurityCookieVal
+ getEmitter()->emitIns_S_I(INS_mov, EA_PTRSIZE, compiler->lvaGSSecurityCookie, 0,
+ (int)compiler->gsGlobalSecurityCookieVal);
+ }
+ }
+ else
+ {
+ // Always use EAX on x86 and x64
+ // On x64, if we're not moving into RAX, and the address isn't RIP relative, we can't encode it.
+ // mov eax, dword ptr [compiler->gsGlobalSecurityCookieAddr]
+ // mov dword ptr [frame.GSSecurityCookie], eax
+ getEmitter()->emitIns_R_AI(INS_mov, EA_PTR_DSP_RELOC, REG_EAX, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
+ regSet.verifyRegUsed(REG_EAX);
+ getEmitter()->emitIns_S_R(INS_mov, EA_PTRSIZE, REG_EAX, compiler->lvaGSSecurityCookie, 0);
+ if (initReg == REG_EAX)
+ {
+ *pInitRegZeroed = false;
+ }
+ }
+}
+
/*****************************************************************************
*
* Generate code to check that the GS cookie wasn't thrashed by a buffer
@@ -325,10 +380,9 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
curNestingSlotOffs = (unsigned)(filterEndOffsetSlotOffs - ((finallyNesting + 1) * TARGET_POINTER_SIZE));
// Zero out the slot for the next nesting level
- instGen_Store_Imm_Into_Lcl(TYP_I_IMPL, EA_PTRSIZE, 0, compiler->lvaShadowSPslotsVar,
- curNestingSlotOffs - TARGET_POINTER_SIZE);
- instGen_Store_Imm_Into_Lcl(TYP_I_IMPL, EA_PTRSIZE, LCL_FINALLY_MARK, compiler->lvaShadowSPslotsVar,
- curNestingSlotOffs);
+ getEmitter()->emitIns_S_I(INS_mov, EA_PTRSIZE, compiler->lvaShadowSPslotsVar,
+ curNestingSlotOffs - TARGET_POINTER_SIZE, 0);
+ getEmitter()->emitIns_S_I(INS_mov, EA_PTRSIZE, compiler->lvaShadowSPslotsVar, curNestingSlotOffs, LCL_FINALLY_MARK);
// Now push the address where the finally funclet should return to directly.
if (!(block->bbFlags & BBF_RETLESS_CALL))
@@ -1914,7 +1968,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
unsigned curNestingSlotOffs;
curNestingSlotOffs = filterEndOffsetSlotOffs - ((finallyNesting + 1) * TARGET_POINTER_SIZE);
- instGen_Store_Imm_Into_Lcl(TYP_I_IMPL, EA_PTRSIZE, 0, compiler->lvaShadowSPslotsVar, curNestingSlotOffs);
+ getEmitter()->emitIns_S_I(INS_mov, EA_PTRSIZE, compiler->lvaShadowSPslotsVar, curNestingSlotOffs, 0);
break;
#endif // !FEATURE_EH_FUNCLETS
diff --git a/src/jit/instr.cpp b/src/jit/instr.cpp
index 020a783e66..dd3854600d 100644
--- a/src/jit/instr.cpp
+++ b/src/jit/instr.cpp
@@ -2365,39 +2365,6 @@ void CodeGen::instGen_Store_Reg_Into_Lcl(var_types dstType, regNumber srcReg, in
getEmitter()->emitIns_S_R(ins_Store(dstType), size, srcReg, varNum, offs);
}
-/*****************************************************************************
- *
- * Machine independent way to move an immediate into a stack based local variable
- */
-void CodeGen::instGen_Store_Imm_Into_Lcl(
- var_types dstType, emitAttr sizeAttr, ssize_t imm, int varNum, int offs, regNumber regToUse)
-{
-#ifdef _TARGET_XARCH_
-#ifdef _TARGET_AMD64_
- if ((EA_SIZE(sizeAttr) == EA_8BYTE) && (((int)imm != (ssize_t)imm) || EA_IS_CNS_RELOC(sizeAttr)))
- {
- assert(!"Invalid immediate for instGen_Store_Imm_Into_Lcl");
- }
- else
-#endif // _TARGET_AMD64_
- {
- getEmitter()->emitIns_S_I(ins_Store(dstType), sizeAttr, varNum, offs, (int)imm);
- }
-#elif defined(_TARGET_ARMARCH_)
- // Load imm into a register
- regNumber immReg = regToUse;
- assert(regToUse != REG_NA);
- instGen_Set_Reg_To_Imm(sizeAttr, immReg, (ssize_t)imm);
- instGen_Store_Reg_Into_Lcl(dstType, immReg, varNum, offs);
- if (EA_IS_RELOC(sizeAttr))
- {
- regSet.verifyRegUsed(immReg);
- }
-#else // _TARGET_*
-#error "Unknown _TARGET_"
-#endif // _TARGET_*
-}
-
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/