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>
bb10
Thiago Macieira 2021-09-25 11:01:57 -07:00
parent c89286b26a
commit 8e5fcf02bd
4 changed files with 32 additions and 25 deletions

View File

@ -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"));
auto metaData = reinterpret_cast<QPluginMetaData (*)()>(pfn)();
auto data = reinterpret_cast<const char *>(metaData.data);
if (metaData.size < sizeof(QPluginMetaData::MagicHeader))
// 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"));
}
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

View File

@ -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

View File

@ -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") };

View File

@ -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);
}
};