summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin/qlibrary_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/plugin/qlibrary_unix.cpp')
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp145
1 files changed, 47 insertions, 98 deletions
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index c119bee2fc..a6fb5403cd 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -1,42 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2020 Intel Corporation
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2020 Intel Corporation
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformdefs.h"
@@ -48,7 +12,7 @@
#include <dlfcn.h>
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
# include <private/qcore_mac_p.h>
#endif
@@ -59,11 +23,7 @@
QT_BEGIN_NAMESPACE
-static QString qdlerror()
-{
- const char *err = dlerror();
- return err ? QLatin1Char('(') + QString::fromLocal8Bit(err) + QLatin1Char(')') : QString();
-}
+using namespace Qt::StringLiterals;
QStringList QLibraryPrivate::suffixes_sys(const QString &fullVersion)
{
@@ -82,36 +42,36 @@ QStringList QLibraryPrivate::suffixes_sys(const QString &fullVersion)
// .so is preferred.
# if defined(__ia64)
if (!fullVersion.isEmpty()) {
- suffixes << QLatin1String(".so.%1").arg(fullVersion);
+ suffixes << ".so.%1"_L1.arg(fullVersion);
} else {
- suffixes << QLatin1String(".so");
+ suffixes << ".so"_L1;
}
# endif
if (!fullVersion.isEmpty()) {
- suffixes << QLatin1String(".sl.%1").arg(fullVersion);
- suffixes << QLatin1String(".%1").arg(fullVersion);
+ suffixes << ".sl.%1"_L1.arg(fullVersion);
+ suffixes << ".%1"_L1.arg(fullVersion);
} else {
- suffixes << QLatin1String(".sl");
+ suffixes << ".sl"_L1;
}
#elif defined(Q_OS_AIX)
suffixes << ".a";
#else
if (!fullVersion.isEmpty()) {
- suffixes << QLatin1String(".so.%1").arg(fullVersion);
+ suffixes << ".so.%1"_L1.arg(fullVersion);
} else {
- suffixes << QLatin1String(".so");
+ suffixes << ".so"_L1;
# ifdef Q_OS_ANDROID
suffixes << QStringLiteral(LIBS_SUFFIX);
# endif
}
#endif
-# ifdef Q_OS_MAC
+# ifdef Q_OS_DARWIN
if (!fullVersion.isEmpty()) {
- suffixes << QLatin1String(".%1.bundle").arg(fullVersion);
- suffixes << QLatin1String(".%1.dylib").arg(fullVersion);
+ suffixes << ".%1.bundle"_L1.arg(fullVersion);
+ suffixes << ".%1.dylib"_L1.arg(fullVersion);
} else {
- suffixes << QLatin1String(".bundle") << QLatin1String(".dylib");
+ suffixes << ".bundle"_L1 << ".dylib"_L1;
}
#endif
return suffixes;
@@ -119,21 +79,26 @@ QStringList QLibraryPrivate::suffixes_sys(const QString &fullVersion)
QStringList QLibraryPrivate::prefixes_sys()
{
- return QStringList() << QLatin1String("lib");
+ return QStringList() << "lib"_L1;
}
bool QLibraryPrivate::load_sys()
{
+#if defined(Q_OS_WASM) && defined(QT_STATIC)
+ // emscripten does not support dlopen when using static linking
+ return false;
+#endif
+
QMutexLocker locker(&mutex);
QString attempt;
QFileSystemEntry fsEntry(fileName);
QString path = fsEntry.path();
QString name = fsEntry.fileName();
- if (path == QLatin1String(".") && !fileName.startsWith(path))
+ if (path == "."_L1 && !fileName.startsWith(path))
path.clear();
else
- path += QLatin1Char('/');
+ path += u'/';
QStringList suffixes;
QStringList prefixes;
@@ -198,7 +163,7 @@ bool QLibraryPrivate::load_sys()
QStringList tmp;
qSwap(tmp, list);
list.reserve(tmp.size() * 2);
- for (const QString &s : qAsConst(tmp)) {
+ for (const QString &s : std::as_const(tmp)) {
QString modifiedPath = s;
f(&modifiedPath);
list.append(modifiedPath);
@@ -207,10 +172,10 @@ bool QLibraryPrivate::load_sys()
};
if (pluginState == IsAPlugin) {
// add ".avx2" to each suffix in the list
- transform(suffixes, [](QString *s) { s->append(QLatin1String(".avx2")); });
+ transform(suffixes, [](QString *s) { s->append(".avx2"_L1); });
} else {
// prepend "haswell/" to each prefix in the list
- transform(prefixes, [](QString *s) { s->prepend(QLatin1String("haswell/")); });
+ transform(prefixes, [](QString *s) { s->prepend("haswell/"_L1); });
}
}
#endif
@@ -222,15 +187,15 @@ bool QLibraryPrivate::load_sys()
for (int suffix = 0; retry && !hnd && suffix < suffixes.size(); suffix++) {
if (!prefixes.at(prefix).isEmpty() && name.startsWith(prefixes.at(prefix)))
continue;
- if (path.isEmpty() && prefixes.at(prefix).contains(QLatin1Char('/')))
+ if (path.isEmpty() && prefixes.at(prefix).contains(u'/'))
continue;
if (!suffixes.at(suffix).isEmpty() && name.endsWith(suffixes.at(suffix)))
continue;
if (loadHints & QLibrary::LoadArchiveMemberHint) {
attempt = name;
- int lparen = attempt.indexOf(QLatin1Char('('));
+ qsizetype lparen = attempt.indexOf(u'(');
if (lparen == -1)
- lparen = attempt.count();
+ lparen = attempt.size();
attempt = path + prefixes.at(prefix) + attempt.insert(lparen, suffixes.at(suffix));
} else {
attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix);
@@ -240,19 +205,11 @@ bool QLibraryPrivate::load_sys()
#ifdef Q_OS_ANDROID
if (!hnd) {
auto attemptFromBundle = attempt;
- hnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags);
- }
- if (hnd) {
- using JniOnLoadPtr = jint (*)(JavaVM *vm, void *reserved);
- JniOnLoadPtr jniOnLoad = reinterpret_cast<JniOnLoadPtr>(dlsym(hnd, "JNI_OnLoad"));
- if (jniOnLoad && jniOnLoad(QJniEnvironment::javaVM(), nullptr) == JNI_ERR) {
- dlclose(hnd);
- hnd = nullptr;
- }
+ hnd = dlopen(QFile::encodeName(attemptFromBundle.replace(u'/', u'_')), dlFlags);
}
#endif
- if (!hnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
+ if (!hnd && fileName.startsWith(u'/') && QFile::exists(attempt)) {
// We only want to continue if dlopen failed due to that the shared library did not exist.
// However, we are only able to apply this check for absolute filenames (since they are
// not influenced by the content of LD_LIBRARY_PATH, /etc/ld.so.cache, DT_RPATH etc...)
@@ -262,7 +219,7 @@ bool QLibraryPrivate::load_sys()
}
}
-#ifdef Q_OS_MAC
+#ifdef Q_OS_DARWIN
if (!hnd) {
QByteArray utf8Bundle = fileName.toUtf8();
QCFType<CFURLRef> bundleUrl = CFURLCreateFromFileSystemRepresentation(NULL, reinterpret_cast<const UInt8*>(utf8Bundle.data()), utf8Bundle.length(), true);
@@ -279,7 +236,8 @@ bool QLibraryPrivate::load_sys()
locker.relock();
if (!hnd) {
- errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName, qdlerror());
+ errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName,
+ QLatin1StringView(dlerror()));
}
if (hnd) {
qualifiedFileName = attempt;
@@ -291,36 +249,27 @@ bool QLibraryPrivate::load_sys()
bool QLibraryPrivate::unload_sys()
{
- if (dlclose(pHnd.loadAcquire())) {
-#if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in
- char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance
+ bool doTryUnload = true;
+#ifndef RTLD_NODELETE
+ if (loadHints() & QLibrary::PreventUnloadHint)
+ doTryUnload = false;
+#endif
+ if (doTryUnload && dlclose(pHnd.loadAcquire())) {
+ const char *error = dlerror();
+#if defined (Q_OS_QNX)
+ // Workaround until fixed in QNX; fixes crash in
+ // QtDeclarative auto test "qqmlenginecleanup" for instance
if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative"
return true;
- errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName,
- QLatin1String(error));
-#else
- errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName, qdlerror());
#endif
+ errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName,
+ QLatin1StringView(error));
return false;
}
errorString.clear();
return true;
}
-#if defined(Q_OS_LINUX)
-Q_CORE_EXPORT QFunctionPointer qt_linux_find_symbol_sys(const char *symbol)
-{
- return QFunctionPointer(dlsym(RTLD_DEFAULT, symbol));
-}
-#endif
-
-#ifdef Q_OS_MAC
-Q_CORE_EXPORT QFunctionPointer qt_mac_resolve_sys(void *handle, const char *symbol)
-{
- return QFunctionPointer(dlsym(handle, symbol));
-}
-#endif
-
QFunctionPointer QLibraryPrivate::resolve_sys(const char *symbol)
{
QFunctionPointer address = QFunctionPointer(dlsym(pHnd.loadAcquire(), symbol));