19# include <private/qcore_mac_p.h>
21#include <private/qcoreapplication_p.h>
22#include <private/qloggingregistry_p.h>
23#include <private/qsystemerror_p.h>
30#include <qtcore_tracepoints_p.h>
32#include <QtCore/q20map.h>
46#if defined(Q_CC_MINGW)
178#elif defined(Q_OF_MACH_O)
180#elif defined(Q_OS_WIN)
183# warning "Qt does not know how to efficiently parse your platform's binary format; using slow fall-back."
185 static constexpr auto matcher = [] {
189 constexpr auto &
pattern =
"QTMETADATA !";
197 *
errMsg = QLibrary::tr(
"'%1' is not a Qt plugin").arg(*
errMsg);
227 constexpr qint64 MaxMemoryMapSize =
231 const char *filedata =
reinterpret_cast<char *
>(
file.
map(0, fdlen));
234 if (filedata ==
nullptr) {
237 qCWarning(qt_lcDebugPlugins,
"%ls: failed to map to memory: %ls",
243 if (filedata ==
nullptr) {
248 filedata =
data.constData();
256#if defined(Q_OF_MACH_O)
262 qCDebug(qt_lcDebugPlugins,
"Found invalid metadata in lib %ls: %ls",
265 qCDebug(qt_lcDebugPlugins,
"Found metadata in lib %ls, metadata=\n%s\n",
271 qCDebug(qt_lcDebugPlugins,
"Failed to find metadata in lib %ls: %ls",
275 lib->
errorString = QLibrary::tr(
"Failed to extract plugin meta data from '%1': %2")
282#ifdef __COVERAGESCANNER__
296 int ret = __coveragescanner_register_library(libPrivate->fileName.toLocal8Bit());
299 qDebug(
"coverage data for %ls registered",
302 qWarning(
"could not register %ls: error %d; coverage data may be incomplete",
325 typedef std::map<QString, QLibraryPrivate *> LibraryMap;
326 LibraryMap libraryMap;
345 for (
auto &[_, lib] :
data->libraryMap) {
346 if (lib->libraryRefCount.loadRelaxed() == 1) {
347 if (lib->libraryUnloadCount.loadRelaxed() > 0) {
349 lib->libraryUnloadCount.storeRelaxed(1);
350#if defined(Q_OS_DARWIN)
359 delete std::exchange(lib,
nullptr);
364 if (lcDebugLibrary().isDebugEnabled()) {
365 for (
auto &[_, lib] :
data->libraryMap) {
368 <<
"On QtCore unload," << lib->fileName <<
"was leaked, with"
369 << lib->libraryRefCount.loadRelaxed() <<
"users";
394 QLibrary::LoadHints loadHints)
396 auto lazyNewLib = [&] {
398 result->libraryRefCount.ref();
418 lib->libraryRefCount.
ref();
419 lib->mergeLoadHints(loadHints);
432 if (lib->libraryRefCount.
deref()) {
442 const auto n =
erase_if(
data->libraryMap, [lib](
const auto &e) {
443 return e.second == lib;
445 Q_ASSERT_X(
n,
"~QLibrary",
"Did not find this library in the library map");
451QLibraryPrivate::QLibraryPrivate(
const QString &canonicalFileName,
const QString &version, QLibrary::LoadHints loadHints)
452 :
fileName(canonicalFileName), fullVersion(version), pluginState(MightBeAPlugin)
454 loadHintsInt.storeRelaxed(loadHints.toInt());
455 if (canonicalFileName.isEmpty())
456 errorString = QLibrary::tr(
"The shared library was not found.");
460 QLibrary::LoadHints loadHints)
465QLibraryPrivate::~QLibraryPrivate()
469void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
482 return resolve_sys(symbol);
529 libraryUnloadCount.
ref();
537 bool ret = load_sys();
544 libraryUnloadCount.
ref();
545 libraryRefCount.
ref();
566 libraryRefCount.
deref();
584 libraryUnloadCount.
ref();
587 if (pluginState == IsNotAPlugin)
595 pluginState = IsNotAPlugin;
619# if defined(Q_OS_DARWIN)
630# if defined(Q_OS_HPUX)
640# elif defined(Q_OS_AIX)
643# elif defined(Q_OS_DARWIN)
646# elif defined(Q_OS_UNIX)
652 return std::find(std::begin(candidates), std::end(candidates),
s) != std::end(candidates);
662 auto suffixes =
qTokenize(completeSuffix, u
'.');
664 const auto end = suffixes.end();
669 if (isValidSuffix(*
it++))
679 *
errMsg = QLibrary::tr(
"'%1' is not a Qt plugin (%2)").arg(
priv->fileName, std::move(explanation));
684 QFunctionPointer pfn =
priv->resolve(
"qt_plugin_query_metadata_v2");
687#if QT_VERSION <= QT_VERSION_CHECK(7, 0, 0)
688 }
else if ((pfn =
priv->resolve(
"qt_plugin_query_metadata"))) {
691 return error(QLibrary::tr(
"metadata too small"));
694 auto data =
reinterpret_cast<const char *
>(metaData.
data);
700 return error(QLibrary::tr(
"entrypoint to query the plugin meta data not found"));
704 return error(QLibrary::tr(
"metadata too small"));
706 if (
priv->metaData.parse(metaData))
714 if (pluginState == MightBeAPlugin)
717 return pluginState == IsAPlugin;
724 if (pluginState != MightBeAPlugin)
727 bool success =
false;
729#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
737 errorString = QLibrary::tr(
"The shared library was not found.");
738 pluginState = IsNotAPlugin;
746#if defined(Q_OF_MACH_O)
751 qCDebug(qt_lcDebugPlugins,
"Library is encrypted. Doing prospective load before parsing metadata");
759 success =
result.length != 0;
770 errorString = QLibrary::tr(
"The shared library was not found.");
774 pluginState = IsNotAPlugin;
778 pluginState = IsNotAPlugin;
782 if ((qt_version & 0x00ff00) > (
QT_VERSION & 0x00ff00) || (qt_version & 0xff0000) != (
QT_VERSION & 0xff0000)) {
783 qCDebug(qt_lcDebugPlugins,
"In %s:\n"
784 " Plugin uses incompatible Qt library (%d.%d.%d) [%s]",
786 (qt_version&0xff0000) >> 16, (qt_version&0xff00) >> 8, qt_version&0xff,
787 debug ?
"debug" :
"release");
788 errorString = QLibrary::tr(
"The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5]")
793 debug ?
"debug"_L1 :
"release"_L1);
796 errorString = QLibrary::tr(
"The plugin '%1' uses incompatible Qt library."
797 " (Cannot mix debug and release libraries.)").
arg(
fileName);
799 pluginState = IsAPlugin;
817 if (d.
tag() == Loaded)
845 if (d.
tag() == Loaded) {
863 return d.
tag() == Loaded;
994 QLibrary::LoadHints lh;
1046 return library.
resolve(symbol);
1066 return library.
resolve(symbol);
1087 return library.
resolve(symbol);
1156 return d ? d->
loadHints() : QLibrary::LoadHints();
1163 return debug_env != 0;
1168#include "moc_qlibrary.cpp"
T fetchAndOrRelaxed(T valueToAdd) noexcept
void storeRelaxed(T newValue) noexcept
T loadRelaxed() const noexcept
Type loadAcquire() const noexcept
Type loadRelaxed() const noexcept
void storeRelaxed(Type newValue) noexcept
void storeRelease(Type newValue) noexcept
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
qint64 toInteger(qint64 defaultValue=0) const
Returns the integer value stored in this QCborValue, if it is of the integer type.
bool toBool(bool defaultValue=false) const
Returns the boolean value stored in this QCborValue, if it is of a boolean type.
uchar * map(qint64 offset, qint64 size, MemoryMapFlags flags=NoOptions)
Maps size bytes of the file into memory starting at offset.
QString completeSuffix() const
Returns the complete suffix (extension) of the file.
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
qint64 size() const override
\reimp
QString errorString() const
Returns a human-readable description of the last device error that occurred.
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
\inmodule QtCore\reentrant
QByteArray toJson(JsonFormat format=Indented) const
bool unload(UnloadFlag flag=UnloadSys)
QString qualifiedFileName
QtPluginInstanceFunction loadPlugin()
QAtomicPointer< std::remove_pointer< Handle >::type > pHnd
void setLoadHints(QLibrary::LoadHints lh)
QAtomicPointer< std::remove_pointer< QtPluginInstanceFunction >::type > instanceFactory
QPluginParsedMetaData metaData
QFunctionPointer resolve(const char *)
QObject * pluginInstance()
static QLibraryPrivate * findOrCreate(const QString &fileName, const QString &version=QString(), QLibrary::LoadHints loadHints={ })
QLibrary::LoadHints loadHints() const
static void releaseLibrary(QLibraryPrivate *lib)
static QLibraryPrivate * findOrCreate(const QString &fileName, const QString &version, QLibrary::LoadHints loadHints)
\inmodule QtCore \reentrant
bool load()
Loads the library and returns true if the library was loaded successfully; otherwise returns false.
LoadHints loadHints
Give the load() function some hints on how it should behave.
QString fileName
the file name of the library
static bool isLibrary(const QString &fileName)
Returns true if fileName has a valid suffix for a loadable library; otherwise returns false.
void setFileNameAndVersion(const QString &fileName, int verNum)
Sets the fileName property and major version number to fileName and versionNumber respectively.
void setFileName(const QString &fileName)
bool isLoaded() const
Returns true if load() succeeded; otherwise returns false.
bool unload()
Unloads the library and returns true if the library could be unloaded; otherwise returns false.
void setLoadHints(LoadHints hints)
QLibrary(QObject *parent=nullptr)
Constructs a library with the given parent.
QFunctionPointer resolve(const char *symbol)
Returns the address of the exported symbol symbol.
~QLibrary()
Destroys the QLibrary object.
QString errorString() const
void unlock() noexcept
Unlocks this mutex locker.
void relock() noexcept
Relocks an unlocked mutex locker.
static constexpr OSType currentType()
Returns the current OS type without constructing a QOperatingSystemVersion instance.
T * data() const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
void clear()
Clears the contents of the string and makes it null.
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QSet< QString >::iterator it
Combined button and popup list for selecting options.
constexpr struct q20::ranges::@5 all_of
constexpr std::vector< T, std::allocator< T > >::size_type erase_if(std::vector< T, std::allocator< T > > &c, Pred pred)
qsizetype erase_if(QByteArray &ba, Predicate pred)
constexpr QStaticByteArrayMatcher< N > qMakeStaticByteArrayMatcher(const char(&pattern)[N]) noexcept
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError * error
static void installCoverageTool(QLibraryPrivate *libPrivate)
static Q_CONSTINIT bool qt_library_data_once
bool qt_debug_component()
qsizetype QString * errMsg
static constexpr bool QtBuildIsDebug
static bool qt_get_metadata(QLibraryPrivate *priv, QString *errMsg)
static Q_CONSTINIT QLibraryStore * qt_library_data
static QLibraryScanResult findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
static Q_CONSTINIT QBasicMutex qt_library_mutex
static constexpr bool PluginMustMatchQtDebug
static void qlibraryCleanup()
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_LOGGING_CATEGORY_WITH_ENV_OVERRIDE(name, env, categoryName)
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qMin(const T &a, const T &b)
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
QObject *(* QtPluginInstanceFunction)()
#define Q_ASSERT_X(cond, x, msg)
#define qUtf8Printable(string)
#define qUtf16Printable(string)
constexpr auto qTokenize(Haystack &&h, Needle &&n, Flags...flags) noexcept(QtPrivate::Tok::is_nothrow_constructible_from< Haystack, Needle >::value) -> decltype(QtPrivate::Tok::TokenizerResult< Haystack, Needle >{std::forward< Haystack >(h), std::forward< Needle >(n), flags...})
#define QT_CONFIG(feature)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
#define Q_TRACE_POINT(provider, tracepoint,...)
static const uchar magic[MagicLength]
static const auto matcher
[0]
QItemEditorFactory * factory