From a5737e235cf5df87cd61bfadcfea0b037d04c3c0 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 23 Aug 2018 23:01:34 +0200 Subject: [PATCH] Mask shift value for shift [mem], const The shift value needs to be masked as otherwise the emitter may end up believing it needs 4 bytes for constants >= 128. Since an encoding with 4-byte immediate does not exist for shifts, the last part of the immediate would be interpreted as code and executed. This was only a problem for constants between 128 and 256 as other constants are not currently contained. Fixes dotnet/coreclr#19601 Commit migrated from https://github.com/dotnet/coreclr/commit/bf31aae139d9bbdf9d1ba3232fea2b390b53ae27 --- src/coreclr/src/jit/emitxarch.cpp | 18 ++++++++++-- .../JitBlue/GitHub_19601/Github_19601.cs | 25 ++++++++++++++++ .../JitBlue/GitHub_19601/Github_19601.csproj | 34 ++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_19601/Github_19601.cs create mode 100644 src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_19601/Github_19601.csproj diff --git a/src/coreclr/src/jit/emitxarch.cpp b/src/coreclr/src/jit/emitxarch.cpp index 0886007..c8af313 100644 --- a/src/coreclr/src/jit/emitxarch.cpp +++ b/src/coreclr/src/jit/emitxarch.cpp @@ -3573,10 +3573,24 @@ void emitter::emitInsRMW(instruction ins, emitAttr attr, GenTreeStoreInd* storeI if (src->isContainedIntOrIImmed()) { GenTreeIntConCommon* intConst = src->AsIntConCommon(); - id = emitNewInstrAmdCns(attr, offset, (int)intConst->IconValue()); + int iconVal = (int)intConst->IconValue(); + switch (ins) + { + case INS_rcl_N: + case INS_rcr_N: + case INS_rol_N: + case INS_ror_N: + case INS_shl_N: + case INS_shr_N: + case INS_sar_N: + iconVal &= 0x7F; + break; + } + + id = emitNewInstrAmdCns(attr, offset, iconVal); emitHandleMemOp(storeInd, id, IF_ARW_CNS, ins); id->idIns(ins); - sz = emitInsSizeAM(id, insCodeMI(ins), (int)intConst->IconValue()); + sz = emitInsSizeAM(id, insCodeMI(ins), iconVal); } else { diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_19601/Github_19601.cs b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_19601/Github_19601.cs new file mode 100644 index 0000000..ff0c7b1 --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_19601/Github_19601.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +class GitHub_19601 +{ + static ushort s_2; + static short[] s_5 = new short[]{1}; + static ulong s_8; + public static int Main() + { + var vr2 = s_5[0]; + M9(); + return 100; + } + + // The JIT was emitting a 4-byte immediate for the shift in M9, but this form is invalid. + // This lead to NullReferenceException or AccessViolationException when the last part of + // the immediate was treated as instructions. + static void M9() + { + s_8 <<= (0 & s_2) + 186; + } +} + diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_19601/Github_19601.csproj b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_19601/Github_19601.csproj new file mode 100644 index 0000000..2cb4a16 --- /dev/null +++ b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_19601/Github_19601.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + $(MSBuildProjectName) + 2.0 + {ADEEA3D1-B67B-456E-8F2B-6DCCACC2D34C} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + + + + + + + False + + + + None + False + + + + + + + + + + -- 2.7.4