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 <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2021-09-25 10:23:57 -07:00
parent 326b91ea78
commit c89286b26a
3 changed files with 27 additions and 18 deletions

View File

@ -155,13 +155,26 @@ void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
// Since Qt 6.3 // Since Qt 6.3
template <auto (&PluginMetaData)> class QPluginMetaDataV2 template <auto (&PluginMetaData)> class QPluginMetaDataV2
{ {
struct Payload { struct RegularPayload {
QPluginMetaData::MagicHeader header = {}; QPluginMetaData::MagicHeader header = {};
quint8 payload[sizeof(PluginMetaData)] = {}; 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 = {}; Payload payload = {};
public: public:

View File

@ -477,12 +477,10 @@ QList<QStaticPlugin> QPluginLoader::staticPlugins()
*/ */
QJsonObject QStaticPlugin::metaData() const QJsonObject QStaticPlugin::metaData() const
{ {
Q_ASSERT(rawMetaDataSize >= qsizetype(sizeof(QPluginMetaData::MagicHeader)));
auto ptr = static_cast<const char *>(rawMetaData); auto ptr = static_cast<const char *>(rawMetaData);
ptr += sizeof(QPluginMetaData::MagicString);
QString errMsg; QString errMsg;
QJsonDocument doc = qJsonFromRawLibraryMetaData(ptr, rawMetaDataSize - sizeof(QPluginMetaData::MagicString), &errMsg); QJsonDocument doc = qJsonFromRawLibraryMetaData(ptr, rawMetaDataSize, &errMsg);
Q_ASSERT(doc.isObject()); Q_ASSERT(doc.isObject());
Q_ASSERT(errMsg.isEmpty()); Q_ASSERT(errMsg.isEmpty());
return doc.object(); return doc.object();

View File

@ -1468,25 +1468,23 @@ void tst_Moc::environmentIncludePaths()
// plugin_metadata.h contains a plugin which we register here. Since we're not building this // 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: // 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" QObject *qt_plugin_instance();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
extern "C" QPluginMetaData qt_plugin_query_metadata(); extern "C" QPluginMetaData qt_plugin_query_metadata();
class StaticPluginInstance{ class StaticPluginInstance{
public: public:
StaticPluginInstance() { 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<const char *>(md.data) + delta;
md.size -= delta;
return md;
};
QStaticPlugin plugin(qt_plugin_instance, queryFn);
qRegisterStaticPluginFunction(plugin); 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; static StaticPluginInstance staticInstance;
void tst_Moc::specifyMetaTagsFromCmdline() { void tst_Moc::specifyMetaTagsFromCmdline() {