diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2021-09-14 14:19:15 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2021-10-04 14:01:43 -0700 |
commit | 279176aa5d6dc10641a54a06e9cf4d6a4041da16 (patch) | |
tree | de01febe20d733008048e2bfce8abb65d8eb5fa7 /src/corelib/plugin/qlibrary.cpp | |
parent | 461084b6c483c0dc90415d4f16868e194fcd6f0a (diff) |
QPlugin: simplify handling of exact results from Q{Elf,Mach}Parser
Those two scanners always return exact results, if the metadata is
present, so we don't need to re-scan (haven't needed since Qt
5.0). Especially since we scan from the end, we were spending cycles
doing unnecessary work.
Change-Id: I42eb903a916645db9900fffd16a4ccfdc7342278
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/plugin/qlibrary.cpp')
-rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 65 |
1 files changed, 26 insertions, 39 deletions
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index a99ee57a92..142047e530 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -182,7 +182,7 @@ QT_BEGIN_NAMESPACE \sa loadHints */ -static qsizetype qt_find_pattern(const char *s, qsizetype s_len) +static QLibraryScanResult qt_find_pattern(const char *s, qsizetype s_len, QString *errMsg) { /* We used to search from the end of the file so we'd skip the code and find @@ -193,9 +193,19 @@ static qsizetype qt_find_pattern(const char *s, qsizetype s_len) More importantly, the pattern string may exist in the debug information due to it being used in the plugin in the first place. */ +#if defined (Q_OF_ELF) + return QElfParser().parse(s, s_len, errMsg); +#elif defined(Q_OF_MACH_O) + return QMachOParser::parse(s, s_len, errMsg); +#endif QByteArrayView pattern = QPluginMetaData::MagicString; static const QByteArrayMatcher matcher(pattern.toByteArray()); - return matcher.indexIn(s, s_len); + qsizetype i = matcher.indexIn(s, s_len); + if (i < 0) { + *errMsg = QLibrary::tr("'%1' is not a Qt plugin").arg(*errMsg); + return QLibraryScanResult{}; + } + return { i, s_len - i }; } /* @@ -226,10 +236,8 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) constexpr qint64 MaxMemoryMapSize = Q_INT64_C(1) << (sizeof(qsizetype) > 4 ? 40 : 29); - QLibraryScanResult r; - r.pos = 0; - r.length = qMin(file.size(), MaxMemoryMapSize); - const char *filedata = reinterpret_cast<char *>(file.map(0, r.length)); + qsizetype fdlen = qMin(file.size(), MaxMemoryMapSize); + const char *filedata = reinterpret_cast<char *>(file.map(0, fdlen)); #ifdef Q_OS_UNIX if (filedata == nullptr) { @@ -248,53 +256,32 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) // the side of doing a regular read into memory (up to 64 MB). data = file.read(64 * 1024 * 1024); filedata = data.constData(); - r.length = data.size(); + fdlen = data.size(); } #endif - /* - ELF and Mach-O binaries with GCC have .qtmetadata sections. Find them. - */ QString errMsg = library; -#if defined (Q_OF_ELF) - r = QElfParser().parse(filedata, r.length, &errMsg); - if (r.length == 0) { - if (lib && qt_debug_component()) - qWarning("QElfParser: %ls", qUtf16Printable(errMsg)); - if (lib) - lib->errorString = errMsg; - return false; - } -#elif defined(Q_OF_MACH_O) - r = QMachOParser::parse(filedata, r.length, &errMsg); - if (r.length == 0) { - if (qt_debug_component()) - qWarning("QMachOParser: %ls", qUtf16Printable(errMsg)); - if (lib) - lib->errorString = errMsg; - return false; - } -#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU) - - if (qsizetype rel = qt_find_pattern(filedata + r.pos, r.length); - rel >= 0) { - const char *data = filedata + r.pos + rel; - QJsonDocument doc = qJsonFromRawLibraryMetaData(data, r.length, &errMsg); + QLibraryScanResult r = qt_find_pattern(filedata, fdlen, &errMsg); + if (r.length) { + QJsonDocument doc = qJsonFromRawLibraryMetaData(filedata + r.pos, r.length, &errMsg); if (doc.isNull()) { qWarning("Found invalid metadata in lib %ls: %ls", qUtf16Printable(library), qUtf16Printable(errMsg)); } else { lib->metaData = doc.object(); - if (qt_debug_component()) + if (qt_debug_component()) { qWarning("Found metadata in lib %s, metadata=\n%s\n", library.toLocal8Bit().constData(), doc.toJson().constData()); - if (!doc.isNull()) - return true; + } + return true; } + } else if (qt_debug_component()) { + qWarning("Failed to find metadata in lib %ls: %ls", + qUtf16Printable(library), qUtf16Printable(errMsg)); } - if (lib) - lib->errorString = QLibrary::tr("Failed to extract plugin meta data from '%1'").arg(library); + lib->errorString = QLibrary::tr("Failed to extract plugin meta data from '%1': %2") + .arg(library, errMsg); return false; } |