diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-01-04 15:30:49 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-01-05 12:44:17 +0000 |
commit | 781caafe1fde71b059c0e3a42bda77ce0d7e4c2a (patch) | |
tree | d26d68d5948b8ee1516520baebad17ef36d2b244 /src/qml/jit | |
parent | 5f777705b73ad1d4a11c59ad1468621360658820 (diff) |
Fix decoding of bytecode instructions on ARM generated on x86-64
Due to the difference of sign of the char type, byte code is encoded
differently on x86-64 than if it was on ARM and it also is decoded
differently. The problem at hand here was that negative jumps were
encoded as two-byte instructions (opcode and negative offset as byte) on
x86-64 when qmlcachegen is run. At run-time the negative offset was read
into a char type and consequently interpreted as a positive jump,
leading to crashes.
The explicit use of qint8 as signed byte type in encoding/decoding
sensitive parts avoids the decoding issue and should also result in
consistent encoding.
The added auto-test is (among other configurations) run in the CI under
qemu, which means the x86-64 host-built qmlcachegen will generate byte
code and the tst_qmlcachegen ARM binary will run under qemu and
reproduce this scenario.
Task-number: QTBUG-65521
Change-Id: I615628f53475dad38a41095c6e7ffea0c34d58ac
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/jit')
-rw-r--r-- | src/qml/jit/qv4jit.cpp | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp index 4922e60747..1ab45d6765 100644 --- a/src/qml/jit/qv4jit.cpp +++ b/src/qml/jit/qv4jit.cpp @@ -946,6 +946,11 @@ void BaselineJIT::collectLabelsInBytecode() { MOTH_JUMP_TABLE; + const auto addLabel = [&](int offset) { + Q_ASSERT(offset >= 0 && offset < static_cast<int>(function->compiledFunction->codeSize)); + labels.push_back(offset); + }; + const char *code = reinterpret_cast<const char *>(function->codeData); const char *start = code; const char *end = code + function->compiledFunction->codeSize; @@ -1083,7 +1088,7 @@ void BaselineJIT::collectLabelsInBytecode() MOTH_END_INSTR(CallGlobalLookup) MOTH_BEGIN_INSTR(SetExceptionHandler) - labels.push_back(code - start + offset); + addLabel(code - start + offset); MOTH_END_INSTR(SetExceptionHandler) MOTH_BEGIN_INSTR(ThrowException) @@ -1150,15 +1155,15 @@ void BaselineJIT::collectLabelsInBytecode() MOTH_END_INSTR(Construct) MOTH_BEGIN_INSTR(Jump) - labels.push_back(code - start + offset); + addLabel(code - start + offset); MOTH_END_INSTR(Jump) MOTH_BEGIN_INSTR(JumpTrue) - labels.push_back(code - start + offset); + addLabel(code - start + offset); MOTH_END_INSTR(JumpTrue) MOTH_BEGIN_INSTR(JumpFalse) - labels.push_back(code - start + offset); + addLabel(code - start + offset); MOTH_END_INSTR(JumpFalse) MOTH_BEGIN_INSTR(CmpEqNull) @@ -1204,11 +1209,11 @@ void BaselineJIT::collectLabelsInBytecode() MOTH_END_INSTR(CmpInstanceOf) MOTH_BEGIN_INSTR(JumpStrictEqualStackSlotInt) - labels.push_back(code - start + offset); + addLabel(code - start + offset); MOTH_END_INSTR(JumpStrictEqualStackSlotInt) MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt) - labels.push_back(code - start + offset); + addLabel(code - start + offset); MOTH_END_INSTR(JumpStrictNotEqualStackSlotInt) MOTH_BEGIN_INSTR(UNot) |