diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2021-09-25 11:01:57 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2021-10-11 18:59:52 -0700 |
commit | 8e5fcf02bdf3395071b3174777d059faf76a03c6 (patch) | |
tree | 09e468d006a4bbb0fbd89e5485043145b42cc0c8 | |
parent | c89286b26abd7bad5918359e2f6fe7c5785dc94d (diff) |
QPlugin: add qt_plugin_query_metadata_v2() to dynamic plugins
They return a pointer to the actual header, skipping the magic string.
This is done in preparation for the header located in an ELF note, which
won't have the magic.
Change-Id: I3eb1bd30e0124f89a052fffd16a8229bec2ad588
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 31 | ||||
-rw-r--r-- | src/corelib/plugin/qplugin.h | 11 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp | 2 | ||||
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 13 |
4 files changed, 32 insertions, 25 deletions
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index a8c6644bfd..e18a5080f5 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -682,18 +682,31 @@ static bool qt_get_metadata(QLibraryPrivate *priv, QString *errMsg) return false; }; - QFunctionPointer pfn = priv->resolve("qt_plugin_query_metadata"); - if (!pfn) - return error(QLibrary::tr("entrypoint 'qt_plugin_query_metadata' not found")); + QPluginMetaData metaData; + QFunctionPointer pfn = priv->resolve("qt_plugin_query_metadata_v2"); + if (pfn) { + metaData = reinterpret_cast<QPluginMetaData (*)()>(pfn)(); +#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0) + } else if ((pfn = priv->resolve("qt_plugin_query_metadata"))) { + metaData = reinterpret_cast<QPluginMetaData (*)()>(pfn)(); + if (metaData.size < sizeof(QPluginMetaData::MagicHeader)) + return error(QLibrary::tr("metadata too small")); + + // adjust the meta data to point to the header + auto data = reinterpret_cast<const char *>(metaData.data); + data += sizeof(QPluginMetaData::MagicString); + metaData.data = data; + metaData.size -= sizeof(QPluginMetaData::MagicString); +#endif + } else { + return error(QLibrary::tr("entrypoint to query the plugin meta data not found")); + } - auto metaData = reinterpret_cast<QPluginMetaData (*)()>(pfn)(); - auto data = reinterpret_cast<const char *>(metaData.data); - if (metaData.size < sizeof(QPluginMetaData::MagicHeader)) + if (metaData.size < sizeof(QPluginMetaData::Header)) return error(QLibrary::tr("metadata too small")); - data += sizeof(QPluginMetaData::MagicString); - metaData.size -= sizeof(QPluginMetaData::MagicString); - QJsonDocument doc = qJsonFromRawLibraryMetaData(data, metaData.size, errMsg); + QJsonDocument doc = qJsonFromRawLibraryMetaData(reinterpret_cast<const char *>(metaData.data), + metaData.size, errMsg); if (doc.isNull()) return false; // error message already set diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h index 884f510541..d70324b560 100644 --- a/src/corelib/plugin/qplugin.h +++ b/src/corelib/plugin/qplugin.h @@ -155,13 +155,14 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin); // Since Qt 6.3 template <auto (&PluginMetaData)> class QPluginMetaDataV2 { - struct RegularPayload { - QPluginMetaData::MagicHeader header = {}; + struct RegularPayload : QPluginMetaData::MagicHeader { + static constexpr size_t HeaderOffset = offsetof(QPluginMetaData::MagicHeader, header); quint8 payload[sizeof(PluginMetaData)] = {}; constexpr RegularPayload() { QPluginMetaData::copy(payload, PluginMetaData); } }; struct StaticPayload { + static constexpr size_t HeaderOffset = 0; QPluginMetaData::Header header = {}; quint8 payload[sizeof(PluginMetaData)] = {}; constexpr StaticPayload() { QPluginMetaData::copy(payload, PluginMetaData); } @@ -180,7 +181,9 @@ template <auto (&PluginMetaData)> class QPluginMetaDataV2 public: operator QPluginMetaData() const { - return { &payload, sizeof(payload) }; + Q_ASSERT(reinterpret_cast<const char *>(&payload) + Payload::HeaderOffset == + reinterpret_cast<const char *>(&payload.header)); + return { &payload.header, sizeof(payload) - Payload::HeaderOffset }; } }; @@ -242,7 +245,7 @@ public: QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, PLUGINCLASSNAME) # define QT_MOC_EXPORT_PLUGIN_V2(PLUGINCLASS, MANGLEDNAME, MD) \ - extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata() \ + extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata_v2()\ { static constexpr QT_PLUGIN_METADATAV2_SECTION QPluginMetaDataV2<MD> md{}; return md; } \ QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME) #endif diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index e55fbf2137..ec7f7dc0dc 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -1021,7 +1021,7 @@ void tst_QGuiApplication::genericPluginsAndWindowSystemEvents() QCoreApplication::postEvent(&testReceiver, new QEvent(QEvent::User)); QCOMPARE(testReceiver.customEvents, 0); - QStaticPlugin testPluginInfo(qt_plugin_instance, qt_plugin_query_metadata); + QStaticPlugin testPluginInfo(qt_plugin_instance, qt_plugin_query_metadata_v2); qRegisterStaticPluginFunction(testPluginInfo); int argc = 3; char *argv[] = { const_cast<char*>(QTest::currentAppName()), const_cast<char*>("-plugin"), const_cast<char*>("testplugin") }; diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 6776b6e509..cd69ea893c 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1468,20 +1468,11 @@ 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(); -extern "C" QPluginMetaData qt_plugin_query_metadata(); +extern "C" QPluginMetaData qt_plugin_query_metadata_v2(); class StaticPluginInstance{ public: StaticPluginInstance() { - 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<const char *>(md.data) + delta; - md.size -= delta; - return md; - }; - QStaticPlugin plugin(qt_plugin_instance, queryFn); + QStaticPlugin plugin(qt_plugin_instance, qt_plugin_query_metadata_v2); qRegisterStaticPluginFunction(plugin); } }; |