5#include "qplatformdefs.h"
7#include <qcoreapplication.h>
10#include <private/qfilesystementry_p.h>
11#include <private/qsimd_p.h>
16# include <private/qcore_mac_p.h>
20#include <private/qjnihelpers_p.h>
21#include <QtCore/qjnienvironment.h>
26using namespace Qt::StringLiterals;
44 if (!fullVersion.isEmpty()) {
45 suffixes <<
".so.%1"_L1.arg(fullVersion);
50 if (!fullVersion.isEmpty()) {
51 suffixes <<
".sl.%1"_L1.arg(fullVersion);
52 suffixes <<
".%1"_L1.arg(fullVersion);
56#elif defined(Q_OS_CYGWIN)
57 if (!fullVersion.isEmpty()) {
58 suffixes <<
"-%1.dll"_L1.arg(fullVersion);
60 suffixes << QStringLiteral(
".dll");
62#elif defined(Q_OS_AIX)
66 if (!fullVersion.isEmpty()) {
67 suffixes <<
".so.%1"_L1.arg(fullVersion);
71 suffixes << QStringLiteral(LIBS_SUFFIX);
76 if (!fullVersion.isEmpty()) {
77 suffixes <<
".%1.bundle"_L1.arg(fullVersion);
78 suffixes <<
".%1.dylib"_L1.arg(fullVersion);
80 suffixes <<
".bundle"_L1 <<
".dylib"_L1;
88#if defined(Q_OS_WASM) && defined(QT_STATIC)
93 QMutexLocker locker(&mutex);
95 QFileSystemEntry fsEntry(fileName);
98 QString name = fsEntry.fileName();
99 if (path ==
"."_L1 && !fileName.startsWith(path))
104 QStringList suffixes;
105 QStringList prefixes;
106 if (pluginState != IsAPlugin) {
107 prefixes << prefix_sys().toString();
108 suffixes = suffixes_sys(fullVersion);
111 auto loadHints =
this->loadHints();
112 if (loadHints & QLibrary::ResolveAllSymbolsHint) {
115 dlFlags |= RTLD_LAZY;
117 if (loadHints & QLibrary::ExportExternalSymbolsHint) {
118 dlFlags |= RTLD_GLOBAL;
120#if !defined(Q_OS_CYGWIN)
122 dlFlags |= RTLD_LOCAL;
125#if defined(RTLD_DEEPBIND
)
126 if (loadHints & QLibrary::DeepBindHint)
127 dlFlags |= RTLD_DEEPBIND;
135#if defined(RTLD_NODELETE
)
136 if (loadHints & QLibrary::PreventUnloadHint) {
138 if (QtAndroidPrivate::androidSdkVersion() > 22)
140 dlFlags |= RTLD_NODELETE;
145 if (loadHints & QLibrary::LoadArchiveMemberHint) {
146 dlFlags |= RTLD_MEMBER;
153 if (fsEntry.isAbsolute()) {
154 suffixes.prepend(QString());
155 prefixes.prepend(QString());
157 suffixes.append(QString());
158 prefixes.append(QString());
161#if defined(Q_PROCESSOR_X86) && !defined(Q_OS_DARWIN)
162 if (qCpuHasFeature(ArchHaswell)) {
163 auto transform = [](QStringList &list,
void (*f)(QString *)) {
166 list.reserve(tmp.size() * 2);
167 for (
const QString &s : std::as_const(tmp)) {
168 QString modifiedPath = s;
170 list.append(modifiedPath);
174 if (pluginState == IsAPlugin) {
176 transform(suffixes, [](QString *s) { s->append(
".avx2"_L1); });
180 transform(prefixes, [](QString *s) { s->prepend(
"glibc-hwcaps/x86-64-v3/"_L1); });
188 Handle hnd =
nullptr;
189 for (
int prefix = 0; retry && !hnd && prefix < prefixes.size(); prefix++) {
190 for (
int suffix = 0; retry && !hnd && suffix < suffixes.size(); suffix++) {
191 if (path.isEmpty() && prefixes.at(prefix).contains(u'/'))
193 if (!suffixes.at(suffix).isEmpty() && name.endsWith(suffixes.at(suffix)))
195 if (loadHints & QLibrary::LoadArchiveMemberHint) {
197 qsizetype lparen = attempt.indexOf(u'(');
199 lparen = attempt.size();
200 attempt = path + prefixes.at(prefix) + attempt.insert(lparen, suffixes.at(suffix));
202 attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix);
205 hnd = dlopen(QFile::encodeName(attempt), dlFlags);
208 auto attemptFromBundle = attempt;
209 hnd = dlopen(QFile::encodeName(attemptFromBundle.replace(u'/', u'_')), dlFlags);
213 if (!hnd && fileName.startsWith(u'/') && QFile::exists(attempt)) {
225 QByteArray utf8Bundle = fileName.toUtf8();
226 QCFType<CFURLRef> bundleUrl = CFURLCreateFromFileSystemRepresentation(NULL,
reinterpret_cast<
const UInt8*>(utf8Bundle.data()), utf8Bundle.length(),
true);
227 QCFType<CFBundleRef> bundle = CFBundleCreate(NULL, bundleUrl);
229 QCFType<CFURLRef> url = CFBundleCopyExecutableURL(bundle);
230 char executableFile[FILENAME_MAX];
231 CFURLGetFileSystemRepresentation(url,
true,
reinterpret_cast<UInt8*>(executableFile), FILENAME_MAX);
232 attempt = QString::fromUtf8(executableFile);
233 hnd = dlopen(QFile::encodeName(attempt), dlFlags);
240 errorString = QLibrary::tr(
"Cannot load library %1: %2")
241 .arg(fileName, QString::fromLocal8Bit(dlerror()));
244 qualifiedFileName = attempt;
247 pHnd.storeRelaxed(hnd);
248 return (hnd !=
nullptr);
253 bool doTryUnload =
true;
255 if (loadHints() & QLibrary::PreventUnloadHint)
258 if (doTryUnload && dlclose(pHnd.loadAcquire())) {
259 const char *error = dlerror();
260#if defined (Q_OS_QNX)
263 if (!qstrcmp(error,
"Shared objects still referenced"))
266 errorString = QLibrary::tr(
"Cannot unload library %1: %2")
267 .arg(fileName, QString::fromLocal8Bit(error));
276 QFunctionPointer address = QFunctionPointer(dlsym(pHnd.loadAcquire(), symbol));