From 3795904e3831722e222fa32a1e52aeb6b3e6ba87 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 8 Jan 2019 13:41:08 +0100 Subject: V4: Fix stack alignment in JITted code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helper calls done for to-integer and to-number conversions did not align the stack on 16byte boundaries, which could lead to crashes if somewhere in that call a vector instruction is used that expects such alignment. Task-number: QTBUG-71325 Change-Id: Ieec05a93a1f69b538e6c8930b8eb64cbe85c35d4 Reviewed-by: Jüri Valdmann Reviewed-by: Simon Hausmann --- src/qml/jit/qv4assemblercommon_p.h | 4 ++-- src/qml/jit/qv4baselineassembler.cpp | 42 ++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 13 deletions(-) (limited to 'src/qml/jit') diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h index bf239fcfd8..c17fdd3a23 100644 --- a/src/qml/jit/qv4assemblercommon_p.h +++ b/src/qml/jit/qv4assemblercommon_p.h @@ -320,14 +320,14 @@ public: void pushAligned(RegisterID reg) { - subPtr(TrustedImm32(PointerSize), StackPointerRegister); + subPtr(TrustedImm32(3 * PointerSize), StackPointerRegister); push(reg); } void popAligned(RegisterID reg) { pop(reg); - addPtr(TrustedImm32(PointerSize), StackPointerRegister); + addPtr(TrustedImm32(3 * PointerSize), StackPointerRegister); } }; diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp index c62d6e5388..5c08c42977 100644 --- a/src/qml/jit/qv4baselineassembler.cpp +++ b/src/qml/jit/qv4baselineassembler.cpp @@ -483,6 +483,7 @@ public: auto isNumber = branch32(GreaterThanOrEqual, ScratchRegister, TrustedImm32(Value::QT_Int)); if (ArgInRegCount < 2) { + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); // stack alignment push(AccumulatorRegisterTag); push(AccumulatorRegisterValue); } else { @@ -492,7 +493,7 @@ public: callRuntimeUnchecked("toNumberHelper", reinterpret_cast(&toNumberHelper)); saveReturnValueInAccumulator(); if (ArgInRegCount < 2) - addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); + addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); isNumber.link(this); } @@ -513,28 +514,36 @@ public: push(AccumulatorRegisterTag); push(AccumulatorRegisterValue); } + if (ArgInRegCount < 2) { + if (!accumulatorNeedsSaving) + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); push(lhsTarget); load32(lhs, lhsTarget); push(lhsTarget); } else { + if (accumulatorNeedsSaving) + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); move(lhsTarget, registerForArg(1)); load32(lhs, registerForArg(0)); } callHelper(toInt32Helper); move(ReturnValueRegisterValue, lhsTarget); - if (ArgInRegCount < 2) - addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); if (accumulatorNeedsSaving) { + addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); pop(AccumulatorRegisterValue); pop(AccumulatorRegisterTag); + } else if (ArgInRegCount < 2) { + addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); } + lhsIsInt.link(this); auto rhsIsInt = branch32(Equal, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag); pushAligned(lhsTarget); if (ArgInRegCount < 2) { + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); push(AccumulatorRegisterTag); push(AccumulatorRegisterValue); } else { @@ -544,7 +553,7 @@ public: callRuntimeUnchecked("toInt32Helper", reinterpret_cast(&toInt32Helper)); saveReturnValueInAccumulator(); if (ArgInRegCount < 2) - addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); + addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); popAligned(lhsTarget); rhsIsInt.link(this); @@ -556,6 +565,7 @@ public: auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister); if (ArgInRegCount < 2) { + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); // align the stack on a 16-byte boundary push(AccumulatorRegisterTag); push(AccumulatorRegisterValue); } else { @@ -565,7 +575,7 @@ public: callRuntimeUnchecked("toInt32Helper", reinterpret_cast(&toInt32Helper)); saveReturnValueInAccumulator(); if (ArgInRegCount < 2) - addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); + addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); isInt.link(this); } @@ -579,6 +589,8 @@ public: push(AccumulatorRegisterValue); } if (ArgInRegCount < 2) { + if (!accumulatorNeedsSaving) + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); srcReg.offset += 4; load32(srcReg, targetReg); push(targetReg); @@ -586,17 +598,20 @@ public: load32(srcReg, targetReg); push(targetReg); } else { + if (accumulatorNeedsSaving) + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); load32(srcReg, registerForArg(0)); srcReg.offset += 4; load32(srcReg, registerForArg(1)); } callHelper(toInt32Helper); move(ReturnValueRegisterValue, targetReg); - if (ArgInRegCount < 2) - addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); if (accumulatorNeedsSaving) { + addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); pop(AccumulatorRegisterValue); pop(AccumulatorRegisterTag); + } else if (ArgInRegCount < 2) { + addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); } } @@ -663,20 +678,24 @@ public: } if (ArgInRegCount < 2) { + if (!accumulatorNeedsSaving) + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); push(AccumulatorRegisterTag); push(AccumulatorRegisterValue); } else { + if (accumulatorNeedsSaving) + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); move(AccumulatorRegisterValue, registerForArg(0)); move(AccumulatorRegisterTag, registerForArg(1)); } callHelper(Value::toBooleanImpl); - if (ArgInRegCount < 2) - addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); - and32(TrustedImm32(1), ReturnValueRegisterValue, ScratchRegister); if (accumulatorNeedsSaving) { + addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); pop(AccumulatorRegisterValue); pop(AccumulatorRegisterTag); + } else if (ArgInRegCount < 2) { + addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); } continuation(ScratchRegister); @@ -775,6 +794,7 @@ public: void callWithAccumulatorByValueAsFirstArgument(std::function doCall) { if (ArgInRegCount < 2) { + subPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); push(AccumulatorRegisterTag); push(AccumulatorRegisterValue); } else { @@ -783,7 +803,7 @@ public: } doCall(); if (ArgInRegCount < 2) - addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister); + addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister); } }; -- cgit v1.2.3