From 616d8261933e426423134c39a87ac9b08965cfe5 Mon Sep 17 00:00:00 2001 From: Alexander Soldatov Date: Mon, 3 Apr 2017 15:01:56 +0300 Subject: [PATCH] [RyuJIT/ARM32] GS Cookie check implementation. Implementation of GS Cookie check for RyuJIT/ARM32 almost the same as for ARM64. So this code was moved to codegencommon with. Also added optimization to use tmp register for emitting helper call. Commit migrated from https://github.com/dotnet/coreclr/commit/6f40552c88ac826647b787f6b433e359aacfe574 --- src/coreclr/src/jit/codegenarm.cpp | 8 ------- src/coreclr/src/jit/codegenarm64.cpp | 43 --------------------------------- src/coreclr/src/jit/codegencommon.cpp | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 51 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm.cpp b/src/coreclr/src/jit/codegenarm.cpp index 1a2c855..5f47cb7 100644 --- a/src/coreclr/src/jit/codegenarm.cpp +++ b/src/coreclr/src/jit/codegenarm.cpp @@ -40,14 +40,6 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla } //------------------------------------------------------------------------ -// genEmitGSCookieCheck: Generate code to check that the GS cookie wasn't thrashed by a buffer overrun. -// -void CodeGen::genEmitGSCookieCheck(bool pushReg) -{ - NYI("ARM genEmitGSCookieCheck"); -} - -//------------------------------------------------------------------------ // genCallFinally: Generate a call to the finally block. // BasicBlock* CodeGen::genCallFinally(BasicBlock* block) diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 5698be9..1b8d1c3 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -1283,49 +1283,6 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla instGen_Set_Reg_To_Imm(emitActualTypeSize(type), reg, val, flags); } -/***************************************************************************** - * - * Generate code to check that the GS cookie wasn't thrashed by a buffer - * overrun. On ARM64 we always use REG_TMP_0 and REG_TMP_1 as temp registers - * and this works fine in the case of tail calls - * Implementation Note: pushReg = true, in case of tail calls. - */ -void CodeGen::genEmitGSCookieCheck(bool pushReg) -{ - noway_assert(compiler->gsGlobalSecurityCookieAddr || compiler->gsGlobalSecurityCookieVal); - - // Make sure that the return register is reported as live GC-ref so that any GC that kicks in while - // executing GS cookie check will not collect the object pointed to by REG_INTRET (R0). - if (!pushReg && (compiler->info.compRetType == TYP_REF)) - gcInfo.gcRegGCrefSetCur |= RBM_INTRET; - - regNumber regGSConst = REG_TMP_0; - regNumber regGSValue = REG_TMP_1; - - if (compiler->gsGlobalSecurityCookieAddr == nullptr) - { - // load the GS cookie constant into a reg - // - genSetRegToIcon(regGSConst, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL); - } - else - { - // Ngen case - GS cookie constant needs to be accessed through an indirection. - instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regGSConst, (ssize_t)compiler->gsGlobalSecurityCookieAddr); - getEmitter()->emitIns_R_R_I(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSConst, regGSConst, 0); - } - // Load this method's GS value from the stack frame - getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSValue, compiler->lvaGSSecurityCookie, 0); - // Compare with the GC cookie constant - getEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regGSConst, regGSValue); - - BasicBlock* gsCheckBlk = genCreateTempLabel(); - emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED); - inst_JMP(jmpEqual, gsCheckBlk); - genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN); - genDefineTempLabel(gsCheckBlk); -} - BasicBlock* CodeGen::genCallFinally(BasicBlock* block) { // Generate a call to the finally, like this: diff --git a/src/coreclr/src/jit/codegencommon.cpp b/src/coreclr/src/jit/codegencommon.cpp index e9546f8..890c26b 100644 --- a/src/coreclr/src/jit/codegencommon.cpp +++ b/src/coreclr/src/jit/codegencommon.cpp @@ -2610,6 +2610,51 @@ emitJumpKind CodeGen::genJumpKindForOper(genTreeOps cmp, CompareKind compareKind return result; } +#ifndef LEGACY_BACKEND +#ifdef _TARGET_ARMARCH_ +//------------------------------------------------------------------------ +// genEmitGSCookieCheck: Generate code to check that the GS cookie +// wasn't thrashed by a buffer overrun. Coomon code for ARM32 and ARM64 +// +void CodeGen::genEmitGSCookieCheck(bool pushReg) +{ + noway_assert(compiler->gsGlobalSecurityCookieAddr || compiler->gsGlobalSecurityCookieVal); + + // Make sure that the return register is reported as live GC-ref so that any GC that kicks in while + // executing GS cookie check will not collect the object pointed to by REG_INTRET (R0). + if (!pushReg && (compiler->info.compRetType == TYP_REF)) + gcInfo.gcRegGCrefSetCur |= RBM_INTRET; + + regNumber regGSConst = REG_TMP_0; + regNumber regGSValue = REG_TMP_1; + + if (compiler->gsGlobalSecurityCookieAddr == nullptr) + { + // load the GS cookie constant into a reg + // + genSetRegToIcon(regGSConst, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL); + } + else + { + // Ngen case - GS cookie constant needs to be accessed through an indirection. + instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regGSConst, (ssize_t)compiler->gsGlobalSecurityCookieAddr); + getEmitter()->emitIns_R_R_I(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSConst, regGSConst, 0); + } + // Load this method's GS value from the stack frame + getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSValue, compiler->lvaGSSecurityCookie, 0); + // Compare with the GC cookie constant + getEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regGSConst, regGSValue); + + BasicBlock* gsCheckBlk = genCreateTempLabel(); + emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED); + inst_JMP(jmpEqual, gsCheckBlk); + // regGSConst and regGSValue aren't needed anymore, we can use them for helper call + genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN, regGSConst); + genDefineTempLabel(gsCheckBlk); +} +#endif // _TARGET_ARMARCH_ +#endif // !LEGACY_BACKEND + /***************************************************************************** * * Generate an exit sequence for a return from a method (note: when compiling -- 2.7.4