6#include "qplatformdefs.h"
8#include <qcoreapplication.h>
11#include <private/qfilesystementry_p.h>
12#include <private/qsimd_p.h>
17# include <private/qcore_mac_p.h>
26#include <private/qjnihelpers_p.h>
27#include <QtCore/qjnienvironment.h>
32using namespace Qt::StringLiterals;
50 if (!fullVersion.isEmpty()) {
51 suffixes <<
".so.%1"_L1.arg(fullVersion);
56 if (!fullVersion.isEmpty()) {
57 suffixes <<
".sl.%1"_L1.arg(fullVersion);
58 suffixes <<
".%1"_L1.arg(fullVersion);
62#elif defined(Q_OS_CYGWIN)
63 if (!fullVersion.isEmpty()) {
64 suffixes <<
"-%1.dll"_L1.arg(fullVersion);
66 suffixes << QStringLiteral(
".dll");
68#elif defined(Q_OS_AIX)
72 if (!fullVersion.isEmpty()) {
73 suffixes <<
".so.%1"_L1.arg(fullVersion);
77 suffixes << QStringLiteral(LIBS_SUFFIX);
82 if (!fullVersion.isEmpty()) {
83 suffixes <<
".%1.bundle"_L1.arg(fullVersion);
84 suffixes <<
".%1.dylib"_L1.arg(fullVersion);
86 suffixes <<
".bundle"_L1 <<
".dylib"_L1;
94#if defined(Q_OS_WASM) && defined(QT_STATIC)
99 QMutexLocker locker(&mutex);
101 QFileSystemEntry fsEntry(fileName);
104 QString name = fsEntry.fileName();
105 if (path ==
"."_L1 && !fileName.startsWith(path))
110 QStringList suffixes;
111 QStringList prefixes;
112 if (pluginState != IsAPlugin) {
113 prefixes << prefix_sys().toString();
114 suffixes = suffixes_sys(fullVersion);
117 auto loadHints =
this->loadHints();
118 if (loadHints & QLibrary::ResolveAllSymbolsHint) {
121 dlFlags |= RTLD_LAZY;
123 if (loadHints & QLibrary::ExportExternalSymbolsHint) {
124 dlFlags |= RTLD_GLOBAL;
126#if !defined(Q_OS_CYGWIN)
128 dlFlags |= RTLD_LOCAL;
131#if defined(RTLD_DEEPBIND
)
132 if (loadHints & QLibrary::DeepBindHint)
133 dlFlags |= RTLD_DEEPBIND;
141#if defined(RTLD_NODELETE
)
142 if (loadHints & QLibrary::PreventUnloadHint) {
144 if (QtAndroidPrivate::androidSdkVersion() > 22)
146 dlFlags |= RTLD_NODELETE;
151 if (loadHints & QLibrary::LoadArchiveMemberHint) {
152 dlFlags |= RTLD_MEMBER;
159 if (fsEntry.isAbsolute()) {
160 suffixes.prepend(QString());
161 prefixes.prepend(QString());
163 suffixes.append(QString());
164 prefixes.append(QString());
167#if defined(Q_PROCESSOR_X86) && !defined(Q_OS_DARWIN)
168 if (qCpuHasFeature(ArchHaswell)) {
169 auto transform = [](QStringList &list,
void (*f)(QString *)) {
172 list.reserve(tmp.size() * 2);
173 for (
const QString &s : std::as_const(tmp)) {
174 QString modifiedPath = s;
176 list.append(modifiedPath);
180 if (pluginState == IsAPlugin) {
182 transform(suffixes, [](QString *s) { s->append(
".avx2"_L1); });
186 transform(prefixes, [](QString *s) { s->prepend(
"glibc-hwcaps/x86-64-v3/"_L1); });
195 for (
int prefix = 0; retry && !hnd && prefix < prefixes.size(); prefix++) {
196 for (
int suffix = 0; retry && !hnd && suffix < suffixes.size(); suffix++) {
197 if (path.isEmpty() && prefixes.at(prefix).contains(u'/'))
199 if (!suffixes.at(suffix).isEmpty() && name.endsWith(suffixes.at(suffix)))
201 if (loadHints & QLibrary::LoadArchiveMemberHint) {
203 qsizetype lparen = attempt.indexOf(u'(');
205 lparen = attempt.size();
206 attempt = path + prefixes.at(prefix) + attempt.insert(lparen, suffixes.at(suffix));
208 attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix);
211 hnd = dlopen(QFile::encodeName(attempt), dlFlags);
214 auto attemptFromBundle = attempt;
215 hnd = dlopen(QFile::encodeName(attemptFromBundle.replace(u'/', u'_')), dlFlags);
219 if (!hnd && fileName.startsWith(u'/') && QFile::exists(attempt)) {
231 QByteArray utf8Bundle = fileName.toUtf8();
232 QCFType<CFURLRef> bundleUrl = CFURLCreateFromFileSystemRepresentation(NULL,
reinterpret_cast<
const UInt8*>(utf8Bundle.data()), utf8Bundle.length(),
true);
233 QCFType<CFBundleRef> bundle = CFBundleCreate(NULL, bundleUrl);
235 QCFType<CFURLRef> url = CFBundleCopyExecutableURL(bundle);
236 char executableFile[FILENAME_MAX];
237 CFURLGetFileSystemRepresentation(url,
true,
reinterpret_cast<UInt8*>(executableFile), FILENAME_MAX);
238 attempt = QString::fromUtf8(executableFile);
239 hnd = dlopen(QFile::encodeName(attempt), dlFlags);
246 errorString = QLibrary::tr(
"Cannot load library %1: %2")
247 .arg(fileName, QString::fromLocal8Bit(dlerror()));
250 qualifiedFileName = attempt;
253 pHnd.storeRelaxed(hnd);
254 return (hnd !=
nullptr);
259 bool doTryUnload =
true;
261 if (loadHints() & QLibrary::PreventUnloadHint)
264 if (doTryUnload && dlclose(pHnd.loadAcquire())) {
265 const char *error = dlerror();
266#if defined (Q_OS_QNX)
269 if (!qstrcmp(error,
"Shared objects still referenced"))
272 errorString = QLibrary::tr(
"Cannot unload library %1: %2")
273 .arg(fileName, QString::fromLocal8Bit(error));
282 QFunctionPointer address = QFunctionPointer(dlsym(pHnd.loadAcquire(), symbol));