summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin/qlibrary.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QLibraryStore: cut out the QMap middle-manMarc Mutz2024-02-161-10/+9
| | | | | | | | | | | | | | | | | | | | | | In Qt 6, QMap is just a shared pointer to a std::map. QLibraryStore::libraryMap is never copied, though, so the implicit sharing that QMap adds on top of std::map is useless. Use the underlying std::map directly. Yes, the std::map API is a bit raw around the edges (std::pair value_type), but we're professionals here. This one saves more than 3.7KiB in TEXT size on optimized AMD64 GCC 11 C++20 Linux builds. As a drive-by, port iterator- to range-based loops, and take advantage of loop variables being real references now. Change-Id: I1a8970b21e34a69d88a122f31699a51fd982feb9 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Avoid double-lookup in QLibraryStore::findOrCreate()Marc Mutz2024-02-151-5/+2
| | | | | | | | | | | | | The code is in a critical section, so don't waste time traversing the QMap twice. Now that two previous commits have re-arranged the code such that lookup and insertion are symmetric, we can combine them into a single lookup using operator[]. Pick-to: 6.7 6.6 6.5 Change-Id: I4a10cece65b8c35d05a9b80967bf15d2e15bd73f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Add fast-path in QLibraryStore::findOrCreate() for !instance()Marc Mutz2024-02-121-11/+12
| | | | | | | | | | | | | | | | | If there's no QLibraryStore::instance(), then there's no LibraryMap, so no need to construct a mapName we know we'll just throw away. We must keep locking the qt_library_mutex to check instance(), but we can drop it immediately if we find there isn't, and construct the QLibraryPrivate object outside the critical section (the hope is that the compiler sees this as an opportunity to tail-call). The final goal of this exercise is to get rid of the double-lookup in LibraryMap. Pick-to: 6.7 6.6 6.5 Change-Id: I181dd2657e831a37e2d6f1c5d4df7e2a25ac48cd Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Add fast-path in QLibraryStore::findOrCreate() for empty fileNameMarc Mutz2024-02-091-4/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The LibraryMap can never contain an object whose fileName is empty. To see that, observe that the only insertion into LibraryMap is in findOrCreate() and that refuses to add such objects there. But if LibraryMap cannot contain such an object, and findOrCreate({}) is just an ugly way to get a default-constructed QLibraryPrivate (a new one for each call), then we don't need to lock the qt_library_mutex to produce one, and neither do we need to construct a mapName that we know we'll not find, anyway. So drag this case to before the mutex locking and the construction of mapName. It took me more coffee than I'm ready to admit to figure this out, so leave a comment for the next reader indicating that an empty fileName is actually a valid argument. To avoid repeating the new-expression, wrap it in a lambda, together with the ref() call. Move the remaining ref() call to where it's still needed. The final goal of this exercise is to get rid of the double-lookup in LibraryMap. Pick-to: 6.7 6.6 6.5 Change-Id: I781eafdb9516410d7a262ad27f52c38ad2742292 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Doc: Generalize statement about QLibrary::unload() and macOSKai Köhne2023-07-271-1/+3
| | | | | | | | | | | We dropped support for macOS 10.3 in Qt 4.6, 14 years ago. But the logic to only 'fake' the unloading on Q_OS_DARWIN remains. Also, add a statement explaining the behavior in more detail. Pick-to: 6.5 6.6 Change-Id: I62ec7df7c4b807f84c96619f78b3cef704c51335 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* QLibrary: make isLoaded() report whether this object has load()edThiago Macieira2023-07-101-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit c2a92199b57b195176d2a0d68d140d72c1cbfb71 "QLibrary::setFileNameAndVersion: reset the tag after findOrCreate". This restores the behavior of resolve() and compatibility with Qt 4 and 5, which is documented to imply a call to load(). Do note that if you call load() or resolve() and don't call unload(), the library you've loaded can never be unloaded now. So don't leak! [ChangeLog][Important Behavior Changes] QLibrary::isLoaded() now reports whether this instance of QLibrary has succeeded in loading the library, via direct or indirect call to load(). Previously, it used to reported whether the actual library was loaded by any QLibrary instance. The change to QLibrary::resolve() itself is effectively a no-op in this patch, because isLoaded() would have returned false, but it ensures that the implementation does what it says it will do. Fixes: QTBUG-114977 Pick-to: 6.6 Change-Id: I907aa7aea8ef48469498fffd176d7a76ae73e04a Reviewed-by: Ievgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QLibraryPrivate: Actually merge load hintsIevgenii Meshcheriakov2023-06-201-1/+12
| | | | | | | | | | | | | | | | | | | Or old and new load hints in mergeLoadHints() instead of just storing new ones. Andjust QLibraryPrivate::setLoadHints() to handle objects with no file name differently and just set load hints directly. Mention that load hints are merged once the file name is set in the documentation for QLibrary::setLoadHints(). Add a regression test into tst_qfactoryloader. Update and extend tst_QPluginLoader::loadHints() to take into account load hints merging. Fixes: QTBUG-114480 Change-Id: I3b9afaec7acde1f5ff992d913f8d7217392c7e00 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Q{Plugin,Factory}Loader: downgrade warnings to debug messagesThiago Macieira2023-05-051-2/+2
| | | | | | | | | | | | | | | | Since we don't have different environment variables for the plugin paths, users have to set QT_PLUGIN_PATH to where plugins for both Qt 5 and 6 (and future versions) are located. This causes Qt to print warnings that those couldn't be loaded because the major version mismatches. So don't print them any more. QT_DEBUG_PLUGINS and the category logging filter can still be used to enable them. Fixes: QTBUG-107459 Pick-to: 6.5 Change-Id: Idd5e1bb52be047d7b4fffffd175318ca1f8017bd Reviewed-by: Lars Knoll <lars@knoll.priv.no>
* Corelib: s/Q_OS_MAC/Q_OS_DARWIN/wg except for doc and definitionEdward Welbourne2023-03-201-2/+2
| | | | | | | | | | I got tired of being told off by the inanity 'bot for faithfully reflecting existing #if-ery in new #if-ery. Retain only the documentation and definition of the deprecated define. Change-Id: I47f47b76bd239a360f27ae5afe593dfad8746538 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Darwin: Ensure encrypted library is loaded before parsing plugin metadataTor Arne Vestbø2023-02-171-6/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Application delivered via the macOS or iOS App Store might have their libraries encrypted, in which case we can not read any of the sections of the binary until it has been dlopened. This was causing issues for our plugin loading code, which assumed we could read the .qtmetadata section of a yet to be loaded plugin to determine its suitability, before loading it. We now detect whether a library is encrypted during the Mach-O parsing, and propagate this back to QLibraryPrivate::updatePluginState(), which can handle the case by explicitly loading the library before continuing with metadata validation. We still ensure that the library has a .qtmetadata section, so that we don't need to dlopen any random library in our path. This does mean that we will potentially load more plugins than we need, and since the Qt version validation happens as part of meta data validation, we might dlopen() incompatible plugins, but it's expected that in an App Store deployment scenario you control both the versioning and set of shipped plugins, so this should not be an issue in practice. As encrypted libraries are only produced for apps that are fully published to the App Store, and then deployed via MDM, VPP, or Apple Configurator 2, we don't have an easy way to test this, but the existing code paths should be unaffected, and hopefully this patch improves the situation for the encrypted library case. Pick-to: 6.5 6.4 6.2 5.15 Change-Id: Iff733505f7067ce5571854ea978bc95e8376e347 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
* Trace: Convert qtcore module to use tracepointgen toolAntti Määttä2023-02-101-0/+3
| | | | | | | | Pick-to: 6.5 Change-Id: I379896280a16cd0b94d7ee9d0cfcca4afe64b9fe Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Janne Koskinen <janne.p.koskinen@qt.io>
* QLibrary: fix loading multiple versions of a libraryThiago Macieira2022-10-201-5/+9
| | | | | | | | | | | | | | | | | The libraryMap only stored the file path, so we couldn't load two versions of the same library as we'd find the other version already loaded. Change the map to index by file name and version (using a NUL as separator, since that can't appear in file names). [ChangeLog][QtCore][QLibrary] Fixed a bug that caused QLibrary to be unable to load two different versions of a library of a given name at the same time. Note that this is often inadviseable and loading the second library may cause a crash. Pick-to: 6.4 Change-Id: I12a088d1ae424825abd3fffd171ce3bb0590978d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QLibrary: fix load() after a failed load()Thiago Macieira2022-10-181-2/+4
| | | | | | | | | | | Regression introduced by commit 8d4eb292b2e8fc14437db97febdc2eebe36ed3ce in 6.0, when QTaggedPointer was introduced. We set the tag even when the loading failed and failed to reset it because d = {} retains the tag. Pick-to: 6.2 6.4 Fixes: QTBUG-103387 Change-Id: Ie4bb662dcb274440ab8bfffd170a07aa9c9ecfca Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QLibrary::setFileNameAndVersion: reset the tag after findOrCreateThiago Macieira2022-10-171-2/+3
| | | | | | | | | If the library we've found is already loaded, set the tag to Loaded. Pick-to: 6.4 Change-Id: I12a088d1ae424825abd3fffd171ce3831b884eee Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QLibrary: merge duplicated setFileName{,AndVersion} codeThiago Macieira2022-10-141-14/+2
| | | | | | | | | The code was in triplicate. Once is enough. Pick-to: 6.4 Change-Id: I12a088d1ae424825abd3fffd171ce375892457fc Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Port from qAsConst() to std::as_const()Marc Mutz2022-10-111-1/+1
| | | | | | | | | | | | | | | | We've been requiring C++17 since Qt 6.0, and our qAsConst use finally starts to bother us (QTBUG-99313), so time to port away from it now. Since qAsConst has exactly the same semantics as std::as_const (down to rvalue treatment, constexpr'ness and noexcept'ness), there's really nothing more to it than a global search-and-replace, with manual unstaging of the actual definition and documentation in dist/, src/corelib/doc/ and src/corelib/global/. Task-number: QTBUG-99313 Change-Id: I4c7114444a325ad4e62d0fcbfd347d2bbfb21541 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* [Linux] Remove workaround for glibc to actually unload a libraryFushan Wen2022-10-101-6/+1
| | | | | | | | | | | | | | The workaround was added to fix a bug in glibc prior to 2.25, which was released on 2017-02-05. Since the supported platforms of Qt6 at least have glibc 2.26 (SUSE Linux Enterprise Server 15 SP2), it's time to remove the workaround. See also: http://sourceware.org/bugzilla/show_bug.cgi?id=11941 Pick-to: 6.4 Change-Id: Ia2aab5b0a512c44d4a4312877a0177b6b5df6428 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QLibrary: fix use of deprecated QByteArrayMatcher::indexIn(p, n)Marc Mutz2022-06-141-1/+1
| | | | | | | | | | Use the QByteArrayView overload instead. Deprecated since 6.3, so backporting: Pick-to: 6.4 6.3 Change-Id: I529104cad59260eed371cedb1ae84a7e9086bbf6 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-161-39/+3
| | | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* Short live Q_CONSTINIT!Marc Mutz2022-03-261-3/+3
| | | | | | | | | | | | | | | | | | It expands to the first available of - constinit (C++20) - [[clang::require_constant_initialization]] (Clang) - __constinit (GCC >= 10) Use it around the code (on and near static QBasicAtomic; this patch makes no attempt to find all statics in qtbase). [ChangeLog][QtCore][QtGlobal] Added macro Q_CONSTINIT. Fixes: QTBUG-100484 Change-Id: I11e0363a7acb3464476859d12ec7f94319d82be7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QtCore: Replace remaining uses of QLatin1String with QLatin1StringViewSona Kurazyan2022-03-261-1/+1
| | | | | | | Task-number: QTBUG-98434 Change-Id: Ib7c5fc0aaca6ef33b93c7486e99502c555bf20bc Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QtCore: replace QLatin1String/QLatin1Char with _L1/u'' where applicableSona Kurazyan2022-03-251-11/+13
| | | | | | | | | | | As a drive-by, did also minor refactorings/improvements. Task-number: QTBUG-98434 Change-Id: I81964176ae2f07ea63674c96f47f9c6aa046854f Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru>
* QLibrary: restore translated stringMarc Mutz2022-03-171-6/+6
| | | | | | | | | | | | | | | | | We want to pick this change to LTS branches, so we cannot change the translated string. Instead of fixing the order of placeholders, use multi-arg, which performs only a single pass over the input and doesn't suffer from placeholder injection by interpolation the way .arg() chaining does. Requires to use QString::number(), though. Amends 3636325946b471d48043540e309bf6f52be45331. Pick-to: 6.3 6.2 5.15 Change-Id: I6484a052115096c609edfea27dfd36b196efc1b6 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QLibrary: fix possible arg() format clobberingMarc Mutz2022-03-151-3/+3
| | | | | | | | | | | | | The fileName could potentially contain the string "%n", n ≤ 5, in which case the following .arg() calls would interpolate their arguments at the wrong position. Fix by interpolating fileName last. Pick-to: 6.3 6.2 5.15 Change-Id: I1a75a7671cbfe85ba3b2df240c3ef74482fc848d Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QLibrary: add a #warning if the fall-back plugin-meta-data parser is usedMarc Mutz2022-02-161-0/+2
| | | | | Change-Id: I4b42f8dbc9fb03fc6e7243ed4914acfb1bdfe62a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QLibrary: use QStaticByteArrayMatcherMarc Mutz2022-02-151-2/+10
| | | | | | | | | | | | Because of code-after-return style, I don't actually know what the code is used for, but since it's compiled, make sure to not leave a dynamically-initialized static variable lying around, even if control never reaches it. Pick-to: 6.3 Change-Id: I6ce30d8c060f96a2d819ed85f79d18a7ef7e9b05 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QLibrary: Suppress GCC 12 warning about dangling pointer accessThiago Macieira2022-02-111-12/+13
| | | | | | | | | | | | | | | | | | | | | | Introduced in commit d07742f333df89dc399fc5d9cabf2bdef0b346c5. Reported by GCC 12: qlibrary.cpp:672:9: error: dangling pointer to ‘candidates’ may be used [-Werror=dangling-pointer=] 672 | if (isValidSuffix(*it++)) | ^~ qlibrary.cpp:634:29: note: ‘candidates’ declared here 634 | const QLatin1String candidates[] = { | ^~~~~~~~~~ This is a false positive report because the lambda does not return a pointer or iterator. But it's a good update anyway to keep the array outside the lambda, so it won't be recreated every time. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104492 Pick-to: 6.3 Change-Id: I74249c52dc02478ba93cfffd16d230abd1bf6166 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QNX: check and use elf.h from alternative locationJanne Juntunen2021-11-301-1/+1
| | | | | | | | | | | In QNX, instead of #include <elf.h>, we have to use #include <sys/elf.h> since that file is placed in a subdirectory. Also removed the previous workaround. Fixes: QTBUG-97833 Change-Id: Id932a5eeb618a42c8778459cdfd8bb5bf903523c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QPluginLoader: add COFF PE file parserThiago Macieira2021-11-191-0/+3
| | | | | | | | Fixes: QTBUG-67461 Docs: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format Change-Id: I5e52dc5b093c43a3b678fffd16b77bf9a8f2b17e Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QLibrary/QPlugin/QFactoryLoader: convert to category loggingThiago Macieira2021-11-111-38/+28
| | | | | | | | | | | | | | | | | | | | | | | | This adds three categories: - qt.core.library - qt.core.plugin.loader - qt.core.plugin.factoryloader plus the "qt.core.plugin.elfparser" category (only available in developer builds). All three use the new Q_LOGGING_CATEGORY_WITH_ENV_OVERRIDE technique which enables their debugging if the QT_DEBUG_PLUGINS=1 variable is set. As a consequence, some warnings were downgraded to debug messages. I've only left as warnings situations where a real problem occurred, since they now get printed by default: failures to open or mmap a file, corrupt plugin metadata (but not scan of non-plugins), use of QPluginLoader with a static build of Qt. Drive-by update of some messages to make them prettier and/or use qUtf16Printable(). Change-Id: I3eb1bd30e0124f89a052fffd16a752acfe89c19e Reviewed-by: Kai Koehne <kai.koehne@qt.io>
* QPlugin: keep the CBOR data as CBORThiago Macieira2021-10-201-12/+9
| | | | | | | | | | Since QJsonValue and QCborValue use the same backend, we may as well use the CBOR frontend classes, which means we avoid an unnecessary conversion until later. Change-Id: I2de1b4dfacd443148279fffd16a3e2f56cd74c0b Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QPluginLoader: use constexpr variables for detecting debug pluginsThiago Macieira2021-10-181-10/+14
| | | | | | | | | | | For MSVC it's clear that the plugin and Qt must match, since they would be linking to different runtime assemblies otherwise. For all other systems, including MinGW on Windows, there's no such thing. But we insist on MinGW debug-and-release builds matching. Change-Id: I3eb1bd30e0124f89a052fffd16a6aa52c7f8b9c0 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QPlugin: add qt_plugin_query_metadata_v2() to dynamic pluginsThiago Macieira2021-10-111-9/+22
| | | | | | | | | | 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>
* QElfParser: rewrite using elf.hThiago Macieira2021-10-061-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This rewrite uses the actual structures supplied by the system's C library, so it should be easier to read. It removes hardcoded constants with little evident meaning in favor of sizeof() and the macros from that header. It also removes advancing the data pointer in favor of having absolute offsets. The resulting implementation is stricter than the original, checking more fields in the header. Because the QPluginLoader and QFactoryLoader users may make decisions based on availability of plugins before attempting to load them, it's better to be stricter here than to fail later when trying to dlopen() them. Debugging and testing are much improved. Instead of stored artifacts, I added a routine to modify a valid plugin to make it invalid, given the conditions we've found so far. If you turn debugging on for this category, you'll see things like: not-elf.fcqdMq.so : Not an ELF file (invalid signature) wrong-word-size.QrnSAx.so : ELF 32-bit LSB (GNU/Linux), version 1, shared library or PIC executable, x86-64 invalid-word-size.bOkXvp.so : Invalid ELF file (class 0), LSB (GNU/Linux) unknown-word-size.ogYKeF.so : Invalid ELF file (class 66), LSB (GNU/Linux) wrong-endian.owiElX.so : ELF 64-bit MSB (GNU/Linux), version 1, shared library or PIC executable, x86-64 invalid-endian.FRxClR.so : ELF 64-bit invalid endianness (0) (GNU/Linux) unknown-endian.FfvRrP.so : ELF 64-bit invalid endianness (65) (GNU/Linux) elf-version-0.gPTdpQ.so : ELF 64-bit LSB (GNU/Linux), file version 0 elf-version-2.jlIUUg.so : ELF 64-bit LSB (GNU/Linux), file version 2 executable.LlXiFp.so : ELF 64-bit LSB (GNU/Linux), version 1, executable, x86-64 relocatable.UsOYuy.so : ELF 64-bit LSB (GNU/Linux), version 1, relocatable, x86-64 core-file.hqvNRz.so : ELF 64-bit LSB (GNU/Linux), version 1, core dump, x86-64 invalid-type.CIJgfS.so : ELF 64-bit LSB (GNU/Linux), version 1, unknown type 259, x86-64 wrong-arch.UcNmgz.so : ELF 64-bit LSB (GNU/Linux), version 1, shared library or PIC executable, AArch64 file-version-0.lZYuda.so : ELF 64-bit LSB (GNU/Linux), version 0, shared library or PIC executable, x86-64 file-version-2.ucfdwL.so : ELF 64-bit LSB (GNU/Linux), version 2, shared library or PIC executable, x86-64 no-sections.rSjsHh.so : ELF 64-bit LSB (GNU/Linux), version 1, shared library or PIC executable, x86-64 no-sections.rSjsHh.so : contains 0 sections of 64 bytes at offset 0 ; section header string table (shstrtab) is entry 0 no-sections.rSjsHh.so : no section table present, not able to find Qt metadata qtmetadata-executable.vrxcIf.so : ELF 64-bit LSB (GNU/Linux), version 1, shared library or PIC executable, x86-64 qtmetadata-executable.vrxcIf.so : contains 42 sections of 64 bytes at offset 997256 ; section header string table (shstrtab) is entry 41 qtmetadata-executable.vrxcIf.so : shstrtab section is located at offset 996831 size 423 qtmetadata-executable.vrxcIf.so : section 0 name "" type NULL flags X offset 0x0 size 0x0 qtmetadata-executable.vrxcIf.so : section 1 name ".note.gnu.property" type NOTE flags AX offset 0x2a8 size 0x30 qtmetadata-executable.vrxcIf.so : section 2 name ".note.gnu.build-id" type NOTE flags AX offset 0x2d8 size 0x24 qtmetadata-executable.vrxcIf.so : section 3 name ".hash" type HASH flags AX offset 0x300 size 0x44c qtmetadata-executable.vrxcIf.so : section 4 name ".gnu.hash" type 0x6ffffff6 flags AX offset 0x750 size 0x3b8 qtmetadata-executable.vrxcIf.so : section 5 name ".dynsym" type DYNSYM flags AX offset 0xb08 size 0xd50 qtmetadata-executable.vrxcIf.so : section 6 name ".dynstr" type STRTAB flags AX offset 0x1858 size 0x15d8 qtmetadata-executable.vrxcIf.so : section 7 name ".gnu.version" type 0x6fffffff flags AX offset 0x2e30 size 0x11c qtmetadata-executable.vrxcIf.so : section 8 name ".gnu.version_r" type 0x6ffffffe flags AX offset 0x2f50 size 0xb0 qtmetadata-executable.vrxcIf.so : section 9 name ".rela.dyn" type RELA flags AX offset 0x3000 size 0x480 qtmetadata-executable.vrxcIf.so : section 10 name ".rela.plt" type RELA flags AX offset 0x3480 size 0x7e0 qtmetadata-executable.vrxcIf.so : section 11 name ".init" type PROGBITS flags AX offset 0x4000 size 0x1b qtmetadata-executable.vrxcIf.so : section 12 name ".plt" type PROGBITS flags AX offset 0x4020 size 0x550 qtmetadata-executable.vrxcIf.so : section 13 name ".plt.got" type PROGBITS flags AX offset 0x4570 size 0x8 qtmetadata-executable.vrxcIf.so : section 14 name ".text" type PROGBITS flags AX offset 0x4580 size 0x110e qtmetadata-executable.vrxcIf.so : section 15 name ".fini" type PROGBITS flags AX offset 0x5690 size 0xd qtmetadata-executable.vrxcIf.so : section 16 name ".rodata" type PROGBITS flags AX offset 0x6000 size 0x473 qtmetadata-executable.vrxcIf.so : section 17 name ".qtversion" type PROGBITS flags AX offset 0x6478 size 0x10 qtmetadata-executable.vrxcIf.so : section 18 name ".qtmetadata" type PROGBITS flags AX offset 0x64a0 size 0x19b qtmetadata-executable.vrxcIf.so : found .qtmetadata section qtmetadata-writable.stzwrk.so : ELF 64-bit LSB (GNU/Linux), version 1, shared library or PIC executable, x86-64 Change-Id: I42eb903a916645db9900fffd16a4437af9728eea Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QPlugin: pass the direct header to qJsonFromRawLibraryMetaData()Thiago Macieira2021-10-041-1/+8
| | | | | | | | This is done in preparation for storing the metadata without the magic string in static plugins and in ELF notes. Change-Id: I3eb1bd30e0124f89a052fffd16a820454dd56d3e Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QPlugin: add error messages to the qt_get_metadata()Thiago Macieira2021-10-041-6/+7
| | | | | | | This is the already-loaded counterpart to the file scanning code Change-Id: I3eb1bd30e0124f89a052fffd16a81f518fa95f0d Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QPlugin: simplify handling of exact results from Q{Elf,Mach}ParserThiago Macieira2021-10-041-39/+26
| | | | | | | | | | 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>
* Q{Elf,Mach}Parser: harmonize the arguments passedThiago Macieira2021-10-041-13/+12
| | | | | | | | | | | | | | Both functions took a QString for the input file name, but while the ELF parser had an optional QLibrary pointer (which was never null) where to store the error string, the Mach-O parser received a pointer to a QString. So make both of them take a single in/out QString pointer, which has the file name on input and is cheap for us because of COW. Drive-by fix the name of the static function in qmachparser.cpp from "ns" (which stood for "not suitable") to "notfound". Change-Id: I3eb1bd30e0124f89a052fffd16a8182f4f8541c3 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QPlugin: use one global metadata magic stringThiago Macieira2021-10-041-11/+6
| | | | | | | And use QByteArrayView where applicable. Change-Id: I2de1b4dfacd443148279fffd16a39ec22908f75f Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QPlugin: change the generic metadata scan to forwardsThiago Macieira2021-10-041-30/+10
| | | | | | | | | | | The reason it scanned backwards was valid, but unfortunately that doesn't work if the metadata magic appears in the debug info that comes after the metadata. Task-number: QTBUG-67461 Change-Id: I2bbf422288924c198645fffd16a9276767ca2589 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* src/corelib/plugin: sort #includesThiago Macieira2021-10-041-18/+12
| | | | | Change-Id: I2de1b4dfacd443148279fffd16a3e4bdb1a49f88 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QPlugin: reorganize findPatternUnloaded and remove two bool variablesThiago Macieira2021-09-241-16/+9
| | | | | | | | The compiler ought to figure them out, but we can just help it. Change-Id: I42eb903a916645db9900fffd16a4981ac966f982 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
* Q{Elf,Mach}Parser: simplify the return codesThiago Macieira2021-09-241-35/+21
| | | | | | | | | | | | | | | | | The multi-state return code was a legacy of how Arvid wrote the ELF parser code back in the day, the fact that it scanned for two different types of plugins in Qt 4 and that the metadata could exist in different places. None of that matters nowadays: who cares if the file is a corrupt binary, not a valid binary, does not have the right architecture, or has no suitable section? It's not a plugin, period. The Qt 4 plugin mechanism was removed for Qt 5.0 in commit 7443895857fdaee132c8efc643e471f02b3d0fa4 ("Remove support for Qt 4 style plugins"). Change-Id: I42eb903a916645db9900fffd16a442d800399b98 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
* QPlugin: don't use QFile::read() if map() fails on UnixThiago Macieira2021-09-241-2/+15
| | | | | | | | If we can't mmap(), then libdl won't be able to either. Pick-to: 6.2 Change-Id: I42eb903a916645db9900fffd16a492a1ac25903f Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Switch a comma operator to a IILEGiuseppe D'Angelo2021-09-191-1/+1
| | | | | | | | | A comma operator results in a discarded-value expression, meaning the compiler is going to complain the moment we mark QMutexLocker as nodiscard. Turn the comma into a functionally equivalent IILE. Change-Id: I33826902c8471016490aac25160b70c609dafd90 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Don't unload libraries on Darwin-based operating systemsTor Arne Vestbø2021-09-171-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can't guarantee that the library didn't define Objective-C classes that still have lingering references, resulting in warnings such as: Attempt to use unknown class 0x10e52e110. And possibly crashes such as: thread #1, queue = 'com.apple.main-thread' frame #0: 0x00007fff203829ee libsystem_kernel.dylib`__ulock_wait + 10 frame #1: 0x00007fff203fa0c5 libsystem_platform.dylib`_os_unfair_lock_lock_slow + 162 frame #2: 0x00007fff2026226b libobjc.A.dylib`unmap_image + 85 frame #3: 0x000000010001e11f dyld`dyld::removeImage(ImageLoader*) + 557 frame #4: 0x000000010002291d dyld`dyld::garbageCollectImages() + 956 frame #5: 0x000000010002e35d dyld`dlclose + 191 frame #6: 0x00007fff203cf1c9 libdyld.dylib`dlclose + 183 frame #7: 0x0000000103f9f2f1 libQt6Core_debug.6.dylib`QLibraryPrivate::unload_sys(this=0x000000011ba2c7d0) at qlibrary_unix.cpp:294:9 frame #8: 0x0000000103f93f3f libQt6Core_debug.6.dylib`QLibraryPrivate::unload(this=0x000000011ba2c7d0, flag=UnloadSys) at qlibrary.cpp:614:36 frame #9: 0x0000000103f971fb libQt6Core_debug.6.dylib`QLibraryStore::cleanup() at qlibrary.cpp:425:22 frame #10: 0x0000000103f970f9 libQt6Core_debug.6.dylib`qlibraryCleanup() at qlibrary.cpp:447:5 frame #11: 0x0000000103f970d1 libQt6Core_debug.6.dylib`(anonymous namespace)::qlibraryCleanup_dtor_class_::~qlibraryCleanup_dtor_class_(this=0x00000001041edd38) at qlibrary.cpp:449:1 frame #12: 0x0000000103f930f5 libQt6Core_debug.6.dylib`(anonymous namespace)::qlibraryCleanup_dtor_class_::~qlibraryCleanup_dtor_class_(this=0x00000001041edd38) at qlibrary.cpp:449:1 frame #13: 0x00007fff202e5d25 libsystem_c.dylib`__cxa_finalize_ranges + 316 frame #14: 0x00007fff202e6010 libsystem_c.dylib`exit + 53 frame #15: 0x00007fff203d1f44 libdyld.dylib`start + 8 frame #16: 0x00007fff203d1f3d libdyld.dylib`start + 1 thread #5, queue = 'com.apple.root.user-interactive-qos', stop reason = signal SIGABRT frame #0: 0x00007fff203a356e libsystem_kernel.dylib`__abort_with_payload + 10 frame #1: 0x00007fff203a4fbd libsystem_kernel.dylib`abort_with_payload_wrapper_internal + 80 frame #2: 0x00007fff203a4f6d libsystem_kernel.dylib`abort_with_reason + 19 frame #3: 0x00007fff202749e3 libobjc.A.dylib`_objc_fatalv(unsigned long long, unsigned long long, char const*, __va_list_tag*) + 114 frame #4: 0x00007fff20274971 libobjc.A.dylib`_objc_fatal(char const*, ...) + 135 frame #5: 0x00007fff20255ccb libobjc.A.dylib`lookUpImpOrForward + 881 frame #6: 0x00007fff2025539b libobjc.A.dylib`_objc_msgSend_uncached + 75 frame #7: 0x00007fff22f368d6 AppKit`-[_NSWindowTransformAnimation setCurrentProgress:] + 42 frame #8: 0x00007fff22f37a8a AppKit`__55-[NSAnimation(NSInternal) _advanceTimeWithDisplayLink:]_block_invoke + 31 frame #9: 0x00007fff22d0774f AppKit`NSPerformVisuallyAtomicChange + 132 frame #10: 0x00007fff22f379dc AppKit`-[NSAnimation(NSInternal) _advanceTimeWithDisplayLink:] + 172 frame #11: 0x00007fff22e9a184 AppKit`-[NSScreenDisplayLink _fire] + 180 frame #12: 0x00007fff2362f0b4 AppKit`___NSRunLoopTimerCreateWithHandler_block_invoke + 34 frame #13: 0x00007fff204c6be9 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20 frame #14: 0x00007fff204c66dd CoreFoundation`__CFRunLoopDoTimer + 927 frame #15: 0x00007fff204c623a CoreFoundation`__CFRunLoopDoTimers + 307 frame #16: 0x00007fff204ace13 CoreFoundation`__CFRunLoopRun + 1988 frame #17: 0x00007fff204abf8c CoreFoundation`CFRunLoopRunSpecific + 563 frame #18: 0x00007fff2123d607 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212 frame #19: 0x00007fff22f378f0 AppKit`-[NSAnimation(NSInternal) _runBlocking] + 453 frame #20: 0x00007fff22f376ae AppKit`__42-[NSAnimation(NSInternal) _runInNewThread]_block_invoke + 97 frame #21: 0x0000000104edb032 libdispatch.dylib`_dispatch_call_block_and_release + 12 frame #22: 0x0000000104edc264 libdispatch.dylib`_dispatch_client_callout + 8 frame #23: 0x0000000104ef04ac libdispatch.dylib`_dispatch_root_queue_drain + 828 frame #24: 0x0000000104ef0d3f libdispatch.dylib`_dispatch_worker_thread2 + 127 frame #25: 0x0000000104f7eac7 libsystem_pthread.dylib`_pthread_wqthread + 244 frame #26: 0x0000000104f7dae3 libsystem_pthread.dylib`start_wqthread + 15 This has been e.g. observed when a QNSWindow isn't closed and released at application quit as expected. Although that is a corner case that shouldn't happen, the general case is still valid. Fixes: QTBUG-96208 Pick-to: 6.2 5.15 Change-Id: I6c9d220e6f5389707baf7ae983f3156e8e51c316 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* QPlugin: make the macros match the scanning code for ELF systemsThiago Macieira2021-09-141-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | For ELF platforms with a GCC-compatible compiler, the QElfParser has been ignoring the .rodata section ever since Qt 5.0 commit 7443895857fdaee132c8efc643e471f02b3d0fa4 ("Remove support for Qt 4 style plugins"). That change removed handling of return value QElfParser::NoQtSection from the ELF parser, which meant that the plugins without a .qtmetadata section were never considered plugins. In other words, for those systems, the __attribute__ macro is mandatory. For systems with a GCC-incompatible compiler, there were only two in Qt 5.x's lifetime: Oracle/Sun Solaris with SunCC and IBM AIX with IBM xlC compiler. Neither compiler supports C++17 according to [1], so they can't be in use in Qt 6. IBM xlC now comes with a Clang-based front-end for users who need Qt 6 and the OpenIndiana distribution of Open Source Solaris has been using GCC since 2012. So make the macros mandatory from now on. [1] https://en.cppreference.com/w/cpp/compiler_support#C.2B.2B17_features Change-Id: I42eb903a916645db9900fffd16a443745446cc64 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QElfParser: don't use int for the enumThiago Macieira2021-09-131-1/+1
| | | | | | | | An enum shows the proper values in the debugger... Pick-to: 6.2 Change-Id: I2de1b4dfacd443148279fffd16a3a5848196983c Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
* QLibrary: use QStringTokenizer in isLibrary()Marc Mutz2021-08-211-15/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rewrite the whole function for readability _and_ performance: - Extract Method isValidSuffix() as a lambda - Extract Method isNumeric() as a lambda - Use a C array of QLatin1String instead of a QStringList to hold the statically-sized list of candidate suffixes. This has the nice side-effect that the compiler will now throw an error in case the #ifdef'ery yields zero candidates (C arrays cannot have no elements), e.g. when porting to a new platform. - Last, not least, replace the parsing with a loop that makes clear what's going on and which is forward-iteration-only-compatible, so we can use QStringTokenizer directly, without toContainer() to get a random-access sequence. Need to use the C++20 version of all_of(), since QStringTokenizer uses sentinels instead of end-iterators. Even though we use higher-level constructs now, the code is still more efficient than the index-twisting we had before. Change-Id: I9f3faf3e30f58c9eb8a1487a7ca190681e87767b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QLibrary: remove dead checkMarc Mutz2021-08-181-2/+1
| | | | | | | | | | The variable `i` is initially `suffixPos + 1` and is then incremented further. It therefore can never be equal to `suffixPos` (ints don't overflow, that would be UB, and suffixPos doesn't change its value), so don't check for that. Change-Id: I3870ddf6ee550cad6c24fececf2a0b662a33d750 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>