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/compiler/qv4bytecodegenerator.cpp | |
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/compiler/qv4bytecodegenerator.cpp')
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator.cpp | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp index 05bbf25292..03105d2b71 100644 --- a/src/qml/compiler/qv4bytecodegenerator.cpp +++ b/src/qml/compiler/qv4bytecodegenerator.cpp @@ -82,7 +82,7 @@ void BytecodeGenerator::packInstruction(I &i) Wide } width = Normal; for (int n = 0; n < nMembers; ++n) { - if (width == Normal && (static_cast<char>(instructionsAsInts[n]) != instructionsAsInts[n])) + if (width == Normal && (static_cast<qint8>(instructionsAsInts[n]) != instructionsAsInts[n])) width = Wide; } char *code = i.packed; @@ -91,7 +91,7 @@ void BytecodeGenerator::packInstruction(I &i) *reinterpret_cast<uchar *>(code) = type; ++code; for (int n = 0; n < nMembers; ++n) { - char v = static_cast<char>(instructionsAsInts[n]); + qint8 v = static_cast<qint8>(instructionsAsInts[n]); memcpy(code, &v, 1); code += 1; } @@ -113,7 +113,7 @@ void BytecodeGenerator::adjustJumpOffsets() continue; Q_ASSERT(i.linkedLabel != -1 && labels.at(i.linkedLabel) != -1); const auto &linkedInstruction = instructions.at(labels.at(i.linkedLabel)); - char *c = i.packed + i.offsetForJump; + qint8 *c = reinterpret_cast<qint8*>(i.packed + i.offsetForJump); int jumpOffset = linkedInstruction.position - (i.position + i.size); // qDebug() << "adjusting jump offset for instruction" << index << i.position << i.size << "offsetForJump" << i.offsetForJump << "target" // << labels.at(i.linkedLabel) << linkedInstruction.position << "jumpOffset" << jumpOffset; @@ -123,7 +123,7 @@ void BytecodeGenerator::adjustJumpOffsets() memcpy(c, &jumpOffset, sizeof(int)); } else { Q_ASSERT(i.offsetForJump == i.size - 1); - char o = jumpOffset; + qint8 o = jumpOffset; Q_ASSERT(o == jumpOffset); *c = o; } |