aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-09-05 13:24:51 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2017-09-05 13:41:40 +0000
commit4dbb3c7bc5829bcf699715157d3a82fb86f4ea5e (patch)
treebd8ac48d269548c08c734504170bc5b4777ba16c
parent2376f45f46e42cb78b46fb77b57e76ed55c734f9 (diff)
Fix QtQml crashing with GHS compiler when using AOT
In order to support compilers that do not support the packing attribute, replace the use of the pack macros with static assertions about the structure size, to ensure that what is generated by host tools (qmlcachegen, qqc) is compatible with what's loaded by the target at run-time. This requires padding and re-ordering some structures. Task-number: QTBUG-61468 Change-Id: I3d82457f086a9b066d1c6df4c46d9f154dd5f208 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/qml/compiler/qv4compileddata_p.h43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 5d71bc4ac6..815c1b92de 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -71,7 +71,7 @@
QT_BEGIN_NAMESPACE
// Bump this whenever the compiler data structures change in an incompatible way.
-#define QV4_DATA_STRUCTURE_VERSION 0x11
+#define QV4_DATA_STRUCTURE_VERSION 0x12
class QIODevice;
class QQmlPropertyCache;
@@ -122,10 +122,6 @@ struct TableIterator
bool operator!=(const TableIterator &rhs) const { return index != rhs.index; }
};
-#if defined(Q_CC_MSVC) || defined(Q_CC_GNU)
-#pragma pack(push, 1)
-#endif
-
struct Location
{
union {
@@ -140,6 +136,7 @@ struct Location
(line == other.line && column < other.column);
}
};
+static_assert(sizeof(Location) == 4, "Location structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct RegExp
{
@@ -155,6 +152,7 @@ struct RegExp
RegExp() { flags.val = 0; stringIndex.val = 0; }
};
+static_assert(sizeof(RegExp) == 4, "RegExp structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Lookup
{
@@ -173,6 +171,7 @@ struct Lookup
Lookup() { type_and_flags.val = 0; nameIndex.val = 0; }
};
+static_assert(sizeof(Lookup) == 4, "Lookup structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct JSClassMember
{
@@ -183,6 +182,7 @@ struct JSClassMember
JSClassMember() { nameOffset = 0; isAccessor = 0; }
};
+static_assert(sizeof(JSClassMember) == 4, "JSClassMember structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct JSClass
{
@@ -191,6 +191,7 @@ struct JSClass
static int calculateSize(int nMembers) { return (sizeof(JSClass) + nMembers * sizeof(JSClassMember) + 7) & ~7; }
};
+static_assert(sizeof(JSClass) == 4, "JSClass structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct String
{
@@ -201,6 +202,7 @@ struct String
return (sizeof(String) + str.length() * sizeof(quint16) + 7) & ~0x7;
}
};
+static_assert(sizeof(String) == 4, "String structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
// Function is aligned on an 8-byte boundary to make sure there are no bus errors or penalties
// for unaligned access. The ordering of the fields is also from largest to smallest.
@@ -243,6 +245,8 @@ struct Function
// Keep all unaligned data at the end
quint8 flags;
+ quint8 padding1;
+ LEUInt16 padding2;
const LEUInt32 *formalsTable() const { return reinterpret_cast<const LEUInt32 *>(reinterpret_cast<const char *>(this) + formalsOffset); }
const LEUInt32 *localsTable() const { return reinterpret_cast<const LEUInt32 *>(reinterpret_cast<const char *>(this) + localsOffset); }
@@ -261,6 +265,7 @@ struct Function
return (sizeof(Function) + (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies + 2 * nPropertyDependencies) * sizeof(quint32) + 7) & ~0x7;
}
};
+static_assert(sizeof(Function) == 72, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
// Qml data structures
@@ -268,6 +273,7 @@ struct Q_QML_EXPORT TranslationData {
LEUInt32 commentIndex;
LEInt32 number;
};
+static_assert(sizeof(TranslationData) == 8, "TranslationData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Q_QML_PRIVATE_EXPORT Binding
{
@@ -298,10 +304,7 @@ struct Q_QML_PRIVATE_EXPORT Binding
IsCustomParserBinding = 0x100,
};
- union {
- QJsonPrivate::qle_bitfield<0, 16> flags;
- QJsonPrivate::qle_bitfield<16, 16> type;
- };
+ LEUInt32 stringIndex; // Set for Type_String, Type_Translation and Type_Script (the latter because of script strings)
union {
bool b;
quint64 doubleValue; // do not access directly, needs endian protected access
@@ -309,11 +312,17 @@ struct Q_QML_PRIVATE_EXPORT Binding
LEUInt32 objectIndex;
TranslationData translationData; // used when Type_Translation
} value;
- LEUInt32 stringIndex; // Set for Type_String, Type_Translation and Type_Script (the latter because of script strings)
+
+ union {
+ QJsonPrivate::qle_bitfield<0, 16> flags;
+ QJsonPrivate::qle_bitfield<16, 16> type;
+ };
Location location;
Location valueLocation;
+ LEUInt32 padding;
+
bool isValueBinding() const
{
if (type == Type_AttachedProperty
@@ -392,6 +401,8 @@ struct Q_QML_PRIVATE_EXPORT Binding
};
+static_assert(sizeof(Binding) == 32, "Binding structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+
struct Parameter
{
LEUInt32 nameIndex;
@@ -399,6 +410,7 @@ struct Parameter
LEUInt32 customTypeNameIndex;
Location location;
};
+static_assert(sizeof(Parameter) == 16, "Parameter structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Signal
{
@@ -423,6 +435,7 @@ struct Signal
int parameterCount() const { return nParameters; }
// ---
};
+static_assert(sizeof(Signal) == 12, "Signal structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Property
{
@@ -443,6 +456,7 @@ struct Property
LEUInt32 customTypeNameIndex; // If type >= Custom
Location location;
};
+static_assert(sizeof(Property) == 16, "Property structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Alias {
enum Flags : unsigned int {
@@ -472,6 +486,7 @@ struct Alias {
return encodedMetaPropertyIndex == -1;
}
};
+static_assert(sizeof(Alias) == 20, "Alias structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Object
{
@@ -579,6 +594,7 @@ struct Object
int namedObjectsInComponentCount() const { return nNamedObjectsInComponent; }
// ---
};
+static_assert(sizeof(Object) == 72, "Object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Import
{
@@ -599,6 +615,7 @@ struct Import
Import() { type = 0; uriIndex = 0; qualifierIndex = 0; majorVersion = 0; minorVersion = 0; }
};
+static_assert(sizeof(Import) == 24, "Import structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
static const char magic_str[] = "qv4cdata";
@@ -651,6 +668,8 @@ struct Unit
LEUInt32 offsetToObjects;
LEUInt32 indexOfRootObject;
+ LEUInt32 padding;
+
const Import *importAt(int idx) const {
return reinterpret_cast<const Import*>((reinterpret_cast<const char *>(this)) + offsetToImports + idx * sizeof(Import));
}
@@ -715,9 +734,7 @@ struct Unit
}
};
-#if defined(Q_CC_MSVC) || defined(Q_CC_GNU)
-#pragma pack(pop)
-#endif
+static_assert(sizeof(Unit) == 152, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct TypeReference
{