aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-01-04 15:30:49 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2018-01-05 12:44:17 +0000
commit781caafe1fde71b059c0e3a42bda77ce0d7e4c2a (patch)
treed26d68d5948b8ee1516520baebad17ef36d2b244 /src/qml/compiler
parent5f777705b73ad1d4a11c59ad1468621360658820 (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')
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp8
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h16
2 files changed, 12 insertions, 12 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;
}
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index a9de71e7ad..789f875ba7 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -366,9 +366,9 @@ QT_BEGIN_NAMESPACE
MOTH_ADJUST_CODE(int, nargs); \
MOTH_DECODE_ARGS(name, int, nargs, __VA_ARGS__) \
goto op_main_##name; \
- op_char_##name: \
- MOTH_ADJUST_CODE(char, nargs); \
- MOTH_DECODE_ARGS(name, char, nargs, __VA_ARGS__) \
+ op_byte_##name: \
+ MOTH_ADJUST_CODE(qint8, nargs); \
+ MOTH_DECODE_ARGS(name, qint8, nargs, __VA_ARGS__) \
op_main_##name: \
; \
@@ -380,10 +380,10 @@ QT_BEGIN_NAMESPACE
MOTH_ADJUST_CODE(int, nargs); \
MOTH_DECODE_ARGS(name, int, nargs, __VA_ARGS__) \
goto op_main_##name; \
- op_char_##name: \
+ op_byte_##name: \
base_ptr = code; \
- MOTH_ADJUST_CODE(char, nargs); \
- MOTH_DECODE_ARGS(name, char, nargs, __VA_ARGS__) \
+ MOTH_ADJUST_CODE(qint8, nargs); \
+ MOTH_DECODE_ARGS(name, qint8, nargs, __VA_ARGS__) \
op_main_##name: \
; \
@@ -408,7 +408,7 @@ QT_BEGIN_NAMESPACE
#define COLLECT_LABELS(instr) \
INSTR_##instr(GET_LABEL)
#define GET_LABEL_INSTRUCTION(name, ...) \
- &&op_char_##name,
+ &&op_byte_##name,
#define COLLECT_LABELS_WIDE(instr) \
INSTR_##instr(GET_LABEL_WIDE)
#define GET_LABEL_WIDE_INSTRUCTION(name, ...) \
@@ -428,7 +428,7 @@ QT_BEGIN_NAMESPACE
#define MOTH_INSTR_CASE_AND_JUMP(instr) \
INSTR_##instr(GET_CASE_AND_JUMP)
#define GET_CASE_AND_JUMP_INSTRUCTION(name, ...) \
- case static_cast<uchar>(Instr::Type::name): goto op_char_##name;
+ case static_cast<uchar>(Instr::Type::name): goto op_byte_##name;
#define MOTH_INSTR_CASE_AND_JUMP_WIDE(instr) \
INSTR_##instr(GET_CASE_AND_JUMP_WIDE)
#define GET_CASE_AND_JUMP_WIDE_INSTRUCTION(name, ...) \