From c89286b26abd7bad5918359e2f6fe7c5785dc94d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 25 Sep 2021 10:23:57 -0700 Subject: [PATCH] QPlugin: suppress the "QTMETADATA !" magic in static plugins The .qtmetadata section is already suppressed for static plugins, but we carried this unnecessary magic string. For library file formats where we don't have a scanner (Windows COFF PE), a library that linked multiple static plugins could end up with multiple metadata found. We can't suppress the header because the version of moc could be different to the version of Qt, so we need to read the header version too. Right now, the version isn't output by moc (all the logic is in qplugin.h), but this could change again in the future. In any case, 4 extra bytes are not a big deal, so the header stays. Change-Id: I3eb1bd30e0124f89a052fffd16a82088d8303081 Reviewed-by: Lars Knoll --- src/corelib/plugin/qplugin.h | 19 ++++++++++++++++--- src/corelib/plugin/qpluginloader.cpp | 4 +--- tests/auto/tools/moc/tst_moc.cpp | 22 ++++++++++------------ 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h index affe3f5412..884f510541 100644 --- a/src/corelib/plugin/qplugin.h +++ b/src/corelib/plugin/qplugin.h @@ -155,13 +155,26 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin); // Since Qt 6.3 template class QPluginMetaDataV2 { - struct Payload { + struct RegularPayload { QPluginMetaData::MagicHeader header = {}; quint8 payload[sizeof(PluginMetaData)] = {}; - constexpr Payload() { QPluginMetaData::copy(payload, PluginMetaData); } + constexpr RegularPayload() { QPluginMetaData::copy(payload, PluginMetaData); } }; -#define QT_PLUGIN_METADATAV2_SECTION QT_PLUGIN_METADATA_SECTION + struct StaticPayload { + QPluginMetaData::Header header = {}; + quint8 payload[sizeof(PluginMetaData)] = {}; + constexpr StaticPayload() { QPluginMetaData::copy(payload, PluginMetaData); } + }; + +#if defined(QT_STATICPLUGIN) +# define QT_PLUGIN_METADATAV2_SECTION + using Payload = StaticPayload; +#else +# define QT_PLUGIN_METADATAV2_SECTION QT_PLUGIN_METADATA_SECTION + using Payload = RegularPayload; +#endif + Payload payload = {}; public: diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index e0cd8e7c45..9afdf0e537 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -477,12 +477,10 @@ QList QPluginLoader::staticPlugins() */ QJsonObject QStaticPlugin::metaData() const { - Q_ASSERT(rawMetaDataSize >= qsizetype(sizeof(QPluginMetaData::MagicHeader))); auto ptr = static_cast(rawMetaData); - ptr += sizeof(QPluginMetaData::MagicString); QString errMsg; - QJsonDocument doc = qJsonFromRawLibraryMetaData(ptr, rawMetaDataSize - sizeof(QPluginMetaData::MagicString), &errMsg); + QJsonDocument doc = qJsonFromRawLibraryMetaData(ptr, rawMetaDataSize, &errMsg); Q_ASSERT(doc.isObject()); Q_ASSERT(errMsg.isEmpty()); return doc.object(); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 49053e8d0e..6776b6e509 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1468,25 +1468,23 @@ void tst_Moc::environmentIncludePaths() // plugin_metadata.h contains a plugin which we register here. Since we're not building this // application as a plugin, we need top copy some of the initializer code found in qplugin.h: extern "C" QObject *qt_plugin_instance(); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) extern "C" QPluginMetaData qt_plugin_query_metadata(); class StaticPluginInstance{ public: StaticPluginInstance() { - QStaticPlugin plugin(qt_plugin_instance, qt_plugin_query_metadata); + decltype(&qt_plugin_query_metadata) queryFn; + queryFn = []() { + // Static plugins don't carry the magic string (since Qt 6.3) + QPluginMetaData md = qt_plugin_query_metadata(); + int delta = sizeof(QPluginMetaData::MagicString); + md.data = static_cast(md.data) + delta; + md.size -= delta; + return md; + }; + QStaticPlugin plugin(qt_plugin_instance, queryFn); qRegisterStaticPluginFunction(plugin); } }; -#else -extern "C" const char *qt_plugin_query_metadata(); -class StaticPluginInstance{ -public: - StaticPluginInstance() { - QStaticPlugin plugin = { &qt_plugin_instance, &qt_plugin_query_metadata }; - qRegisterStaticPluginFunction(plugin); - } -}; -#endif static StaticPluginInstance staticInstance; void tst_Moc::specifyMetaTagsFromCmdline() {