qDebug() << "++++" << i << shnam;
#endif
- if (qstrcmp(shnam, ".qtmetadata") == 0 || qstrcmp(shnam, ".qtplugin") == 0 || qstrcmp(shnam, ".rodata") == 0) {
+ if (qstrcmp(shnam, ".qtmetadata") == 0 || qstrcmp(shnam, ".rodata") == 0) {
if (!(sh.type & 0x1)) {
if (shnam[1] == 'r') {
if (lib)
*pos = sh.offset;
*sectionlen = sh.size - 1;
if (shnam[1] == 'q')
- return shnam[3] == 'm' ? QtMetaDataSection : QtPluginSection;
+ return QtMetaDataSection;
}
s += e_shentsize;
}
class QElfParser
{
public:
- enum { QtMetaDataSection, QtPluginSection, NoQtSection, NotElf, Corrupt };
+ enum { QtMetaDataSection, NoQtSection, NotElf, Corrupt };
enum {ElfLittleEndian = 0, ElfBigEndian = 1};
struct ElfSectionHeader
QStringList keys;
bool metaDataOk = false;
- if (library->compatPlugin) {
- qWarning("Qt plugin loader: Compatibility plugin '%s', need to load for accessing meta data.",
- qPrintable(QDir::toNativeSeparators(fileName)));
- if (!library->loadPlugin()) {
- if (qt_debug_component()) {
- qDebug() << library->errorString;
- qDebug() << " could not load";
- }
- library->release();
- continue;
- }
- if (!library->inst)
- library->inst = library->instance();
- QObject *instance = library->inst.data();
- if (!instance) {
- library->release();
- // ignore plugins that have a valid signature but cannot be loaded.
- continue;
- }
- QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
- if (instance && factory && instance->qt_metacast(d->iid))
- keys = factory->keys();
-
- if (!keys.isEmpty()) {
- metaDataOk = true;
- QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
- object.insert(QLatin1String("Keys"), QJsonArray::fromStringList(keys));
- library->metaData[QLatin1String("MetaData")] = object;
- }
+ QString iid = library->metaData.value(QLatin1String("IID")).toString();
+ if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
+ QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
+ metaDataOk = true;
- } else {
- QString iid = library->metaData.value(QLatin1String("IID")).toString();
- if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
- QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
- metaDataOk = true;
-
- QJsonArray k = object.value(QLatin1String("Keys")).toArray();
- for (int i = 0; i < k.size(); ++i) {
- QString s = k.at(i).toString();
- keys += s;
- }
+ QJsonArray k = object.value(QLatin1String("Keys")).toArray();
+ for (int i = 0; i < k.size(); ++i) {
+ QString s = k.at(i).toString();
+ keys += s;
}
- if (qt_debug_component())
- qDebug() << "Got keys from plugin meta data" << keys;
}
+ if (qt_debug_component())
+ qDebug() << "Got keys from plugin meta data" << keys;
+
if (!metaDataOk) {
- if (library->compatPlugin)
- library->unload();
library->release();
continue;
}
qt_factory_loaders()->removeAll(this);
}
-QStringList QFactoryLoader::keys() const
-{
- Q_D(const QFactoryLoader);
- QMutexLocker locker(&d->mutex);
- QStringList keys = d->keyList;
- QVector<QStaticPlugin> staticPlugins = QLibraryPrivate::staticPlugins();
- for (int i = 0; i < staticPlugins.count(); ++i) {
- if (staticPlugins.at(i).metaData) {
- const char *rawMetaData = staticPlugins.at(i).metaData();
- QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
- if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
- continue;
-
- QJsonObject meta = object.value(QLatin1String("MetaData")).toObject();
- QJsonArray a = meta.value(QLatin1String("Keys")).toArray();
- for (int i = 0; i < a.size(); ++i) {
- QString s = a.at(i).toString();
- if (!s.isEmpty())
- keys += s;
- }
- } else {
- // compat plugin
- QObject *instance = staticPlugins.at(i).instance();
- QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
- if (instance && factory && instance->qt_metacast(d->iid))
- keys += factory->keys();
- }
- }
- return keys;
-}
-
QList<QJsonObject> QFactoryLoader::metaData() const
{
Q_D(const QFactoryLoader);
QVector<QStaticPlugin> staticPlugins = QLibraryPrivate::staticPlugins();
for (int i = 0; i < staticPlugins.count(); ++i) {
- if (staticPlugins.at(i).metaData) {
- const char *rawMetaData = staticPlugins.at(i).metaData();
- QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
- if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
- continue;
+ const char *rawMetaData = staticPlugins.at(i).metaData();
+ QJsonObject object = QLibraryPrivate::fromRawMetaData(rawMetaData).object();
+ if (object.value(QLatin1String("IID")) != QLatin1String(d->iid.constData(), d->iid.size()))
+ continue;
- QJsonObject meta = object.value(QLatin1String("MetaData")).toObject();
+ QJsonObject meta = object.value(QLatin1String("MetaData")).toObject();
metaData.append(meta);
- } else {
- // compat plugins
- QObject *instance = staticPlugins.at(i).instance();
- QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
- if (instance && factory && instance->qt_metacast(d->iid)) {
- QJsonObject meta;
- QJsonArray a = QJsonArray::fromStringList(factory->keys());
- meta.insert(QLatin1String("Keys"), a);
- metaData.append(meta);
- }
- }
}
return metaData;
}
-QObject *QFactoryLoader::instance(const QString &key) const
-{
- Q_D(const QFactoryLoader);
- QMutexLocker locker(&d->mutex);
- QVector<QStaticPlugin> staticPlugins = QLibraryPrivate::staticPlugins();
- for (int i = 0; i < staticPlugins.count(); ++i) {
- QObject *instance = staticPlugins.at(i).instance();
- if (QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance))
- if (instance->qt_metacast(d->iid) && factory->keys().contains(key, Qt::CaseInsensitive))
- return instance;
- }
-
- QString lowered = d->cs ? key : key.toLower();
- if (QLibraryPrivate* library = d->keyMap.value(lowered)) {
- if (library->instance || library->loadPlugin()) {
- if (!library->inst)
- library->inst = library->instance();
- QObject *obj = library->inst.data();
- if (obj) {
- if (!obj->parent())
- obj->moveToThread(QCoreApplicationPrivate::mainThread());
- return obj;
- }
- }
- }
- return 0;
-}
-
QObject *QFactoryLoader::instance(int index) const
{
Q_D(const QFactoryLoader);
Qt::CaseSensitivity = Qt::CaseSensitive);
~QFactoryLoader();
- QT_DEPRECATED QStringList keys() const;
QList<QJsonObject> metaData() const;
-
- QT_DEPRECATED QObject *instance(const QString &key) const;
QObject *instance(int index) const;
#if defined(Q_OS_UNIX) && !defined (Q_OS_MAC)
*/
-#ifndef QT_NO_PLUGIN_CHECK
-struct qt_token_info
-{
- qt_token_info(const char *f, const ulong fc)
- : fields(f), field_count(fc), results(fc), lengths(fc)
- {
- results.fill(0);
- lengths.fill(0);
- }
-
- const char *fields;
- const ulong field_count;
-
- QVector<const char *> results;
- QVector<ulong> lengths;
-};
-
-/*
- return values:
- 1 parse ok
- 0 eos
- -1 parse error
-*/
-static int qt_tokenize(const char *s, ulong s_len, ulong *advance,
- qt_token_info &token_info)
-{
- ulong pos = 0, field = 0, fieldlen = 0;
- char current;
- int ret = -1;
- *advance = 0;
- for (;;) {
- current = s[pos];
-
- // next char
- ++pos;
- ++fieldlen;
- ++*advance;
-
- if (! current || pos == s_len + 1) {
- // save result
- token_info.results[(int)field] = s;
- token_info.lengths[(int)field] = fieldlen - 1;
-
- // end of string
- ret = 0;
- break;
- }
-
- if (current == token_info.fields[field]) {
- // save result
- token_info.results[(int)field] = s;
- token_info.lengths[(int)field] = fieldlen - 1;
-
- // end of field
- fieldlen = 0;
- ++field;
- if (field == token_info.field_count - 1) {
- // parse ok
- ret = 1;
- }
- if (field == token_info.field_count) {
- // done parsing
- break;
- }
-
- // reset string and its length
- s = s + pos;
- s_len -= pos;
- pos = 0;
- }
- }
-
- return ret;
-}
-
-/*
- returns true if the string s was correctly parsed, false otherwise.
-*/
-static bool qt_parse_pattern(const char *s, uint *version, bool *debug)
-{
- bool ret = true;
-
- qt_token_info pinfo("=\n", 2);
- int parse;
- ulong at = 0, advance, parselen = qstrlen(s);
- do {
- parse = qt_tokenize(s + at, parselen, &advance, pinfo);
- if (parse == -1) {
- ret = false;
- break;
- }
-
- at += advance;
- parselen -= advance;
-
- if (qstrncmp("version", pinfo.results[0], pinfo.lengths[0]) == 0) {
- // parse version string
- qt_token_info pinfo2("..-", 3);
- if (qt_tokenize(pinfo.results[1], pinfo.lengths[1],
- &advance, pinfo2) != -1) {
- QByteArray m(pinfo2.results[0], pinfo2.lengths[0]);
- QByteArray n(pinfo2.results[1], pinfo2.lengths[1]);
- QByteArray p(pinfo2.results[2], pinfo2.lengths[2]);
- *version = (m.toUInt() << 16) | (n.toUInt() << 8) | p.toUInt();
- } else {
- ret = false;
- break;
- }
- } else if (qstrncmp("debug", pinfo.results[0], pinfo.lengths[0]) == 0) {
- *debug = qstrncmp("true", pinfo.results[1], pinfo.lengths[1]) == 0;
- }
- } while (parse == 1 && parselen > 0);
-
- return ret;
-}
-#endif // QT_NO_PLUGIN_CHECK
-
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(QT_NO_PLUGIN_CHECK)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
static long qt_find_pattern(const char *s, ulong s_len,
const char *pattern, ulong p_len)
*/
bool hasMetaData = false;
long pos = 0;
- const char oldPattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA";
- const ulong oldPlen = qstrlen(oldPattern);
const char pattern[] = "QTMETADATA ";
const ulong plen = qstrlen(pattern);
#if defined (Q_OF_ELF) && defined(Q_CC_GNU)
qWarning("QElfParser: %s",qPrintable(lib->errorString));
}
return false;
- } else if (r == QElfParser::NoQtSection || r == QElfParser::QtPluginSection) {
- if (pos > 0) {
- // find inside .rodata
- long rel = qt_find_pattern(filedata + pos, fdlen, oldPattern, oldPlen);
- if (rel < 0) {
- pos = -1;
- } else {
- pos += rel;
- }
- } else {
- pos = qt_find_pattern(filedata, fdlen, oldPattern, oldPlen);
- }
} else if (r == QElfParser::QtMetaDataSection) {
long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
if (rel < 0)
pos = qt_find_pattern(filedata, fdlen, pattern, plen);
if (pos > 0)
hasMetaData = true;
- else
- pos = qt_find_pattern(filedata, fdlen, oldPattern, oldPlen);
#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)
bool ret = false;
const char *data = filedata + pos;
QJsonDocument doc = QLibraryPrivate::fromRawMetaData(data);
lib->metaData = doc.object();
- lib->compatPlugin = false;
if (qt_debug_component())
qWarning("Found metadata in lib %s, metadata=\n%s\n",
library.toLocal8Bit().constData(), doc.toJson().constData());
ret = !doc.isNull();
- } else {
- qWarning("Old plugin format found in lib %s", library.toLocal8Bit().constData());
- uint version;
- bool isDebug;
- ret = qt_parse_pattern(filedata + pos, &version, &isDebug);
- if (ret) {
- lib->metaData.insert(QLatin1String("version"), (int)version);
- lib->metaData.insert(QLatin1String("debug"), isDebug);
- lib->compatPlugin = true;
- }
}
}
return ret;
}
-#endif // Q_OS_UNIX && !Q_OS_MAC && !defined(QT_NO_PLUGIN_CHECK)
+#endif // Q_OS_UNIX && !Q_OS_MAC
static void installCoverageTool(QLibraryPrivate *libPrivate)
{
QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version)
: pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0),
- compatPlugin(false), loadHints(0),
+ loadHints(0),
libraryRefCount(1), libraryUnloadCount(0), pluginState(MightBeAPlugin)
{ libraryMap()->insert(canonicalFileName, this); }
typedef const char * (*QtPluginQueryVerificationDataFunction)();
-bool qt_get_verificationdata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv, bool *exceptionThrown)
-{
- *exceptionThrown = false;
- const char *szData = 0;
- if (!pfn)
- return false;
-#ifdef QT_USE_MS_STD_EXCEPTION
- szData = qt_try_versioninfo((void *)pfn, exceptionThrown);
- if (*exceptionThrown)
- return false;
-#else
- szData = pfn();
-#endif
- uint qt_version;
- bool debug;
- if (qt_parse_pattern(szData, &qt_version, &debug)) {
- priv->metaData.insert(QLatin1String("version"), (int)qt_version);
- priv->metaData.insert(QLatin1String("debug"), debug);
- priv->compatPlugin = true;
- return true;
- }
- return false;
-}
-
bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv, bool *exceptionThrown)
{
*exceptionThrown = false;
if (doc.isNull())
return false;
priv->metaData = doc.object();
- priv->compatPlugin = false;
return true;
}
if (pluginState != MightBeAPlugin)
return pluginState == IsAPlugin;
-#ifndef QT_NO_PLUGIN_CHECK
bool success = false;
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata");
}
- if (getMetaData) {
+ if (getMetaData)
ret = qt_get_metadata(getMetaData, this, &exceptionThrown);
- } else {
- // try the old plugin style
- QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = NULL;
-#ifdef Q_OS_WIN
- if (hTempModule) {
- qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction)
-#ifdef Q_OS_WINCE
- ::GetProcAddress(hTempModule, L"qt_plugin_query_verification_data")
-#else
- ::GetProcAddress(hTempModule, "qt_plugin_query_verification_data")
-#endif
- ;
- } else
-#endif
- {
- qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
- }
-
- ret = qt_get_verificationdata(qtPluginQueryVerificationDataFunction, this, &exceptionThrown);
- }
if (!exceptionThrown) {
if (!ret) {
}
return pluginState == IsAPlugin;
-#else
- Q_UNUSED(settings);
- return pluginState == MightBeAPlugin;
-#endif
}
/*!
QPointer<QObject> inst;
QtPluginInstanceFunction instance;
QJsonObject metaData;
- bool compatPlugin;
QString errorString;
QLibrary::LoadHints loadHints;
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
#if defined (Q_OF_ELF) && (defined (Q_CC_GNU) || defined(Q_CC_CLANG))
-# define QT_PLUGIN_VERIFICATION_SECTION \
- __attribute__ ((section (".qtplugin"))) __attribute__((used))
# define QT_PLUGIN_METADATA_SECTION \
__attribute__ ((section (".qtmetadata"))) __attribute__((used))
#elif defined(Q_OS_MAC)
// TODO: Implement section parsing on Mac
-# define QT_PLUGIN_VERIFICATION_SECTION \
- __attribute__((section("__TEXT,qtplugin"))) __attribute__((used))
# define QT_PLUGIN_METADATA_SECTION \
__attribute__ ((section ("__TEXT,qtmetadata"))) __attribute__((used))
#elif defined(Q_CC_MSVC)
// TODO: Implement section parsing for MSVC
-#pragma section(".qtplugin",read,shared)
#pragma section(".qtmetadata",read,shared)
-# define QT_PLUGIN_VERIFICATION_SECTION \
- __declspec(allocate(".qtplugin"))
# define QT_PLUGIN_METADATA_SECTION \
__declspec(allocate(".qtmetadata"))
#else
#define Q_EXPORT_PLUGIN(PLUGIN) \
Q_EXPORT_PLUGIN2(PLUGIN, PLUGIN)
-#define Q_EXPORT_STATIC_PLUGIN(PLUGIN)
-#define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS)
-
-#if defined(QT_STATICPLUGIN)
-
-# define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS) \
- static QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance() \
- Q_PLUGIN_INSTANCE(PLUGINCLASS) \
- const QT_PREPEND_NAMESPACE(QStaticPlugin) qt_static_plugin_##PLUGIN() { \
- QT_PREPEND_NAMESPACE(QStaticPlugin) plugin = { qt_plugin_instance, 0 }; \
- return plugin; \
- }
-
-#else
-// NOTE: if you change pattern, you MUST change the pattern in
-// qlibrary.cpp as well. changing the pattern will break all
-// backwards compatibility as well (no old plugins will be loaded).
-# ifdef QPLUGIN_DEBUG_STR
-# undef QPLUGIN_DEBUG_STR
-# endif
-# ifdef QT_NO_DEBUG
-# define QPLUGIN_DEBUG_STR "false"
-# define QPLUGIN_SECTION_DEBUG_STR ""
-# else
-# define QPLUGIN_DEBUG_STR "true"
-# define QPLUGIN_SECTION_DEBUG_STR ".debug"
-# endif
-# define Q_PLUGIN_VERIFICATION_DATA \
- static const char qt_plugin_verification_data[] = \
- "pattern=" "QT_PLUGIN_VERIFICATION_DATA" "\n" \
- "version=" QT_VERSION_STR "\n" \
- "debug=" QPLUGIN_DEBUG_STR;
-
-
# define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS) \
- QT_PLUGIN_VERIFICATION_SECTION Q_PLUGIN_VERIFICATION_DATA \
- Q_EXTERN_C Q_DECL_EXPORT \
- const char * qt_plugin_query_verification_data() \
- { return qt_plugin_verification_data; } \
- Q_EXTERN_C Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) * qt_plugin_instance() \
- Q_PLUGIN_INSTANCE(PLUGINCLASS)
+ Q_STATIC_ASSERT_X(false, "Old plugin system used")
-# define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS)
+# define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS) \
+ Q_STATIC_ASSERT_X(false, "Old plugin system used")
-#endif
QT_END_NAMESPACE