/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 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$
**
****************************************************************************/
#include "qplatformdefs.h"
#include "qlibrary.h"

#include "qfactoryloader_p.h"
#include "qlibrary_p.h"
#include <qstringlist.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qmutex.h>
#include <qmap.h>
#include <private/qcoreapplication_p.h>
#include <private/qsystemerror_p.h>
#ifdef Q_OS_MAC
#  include <private/qcore_mac_p.h>
#endif
#ifndef NO_ERRNO_H
#include <errno.h>
#endif // NO_ERROR_H
#include <qdebug.h>
#include <qvector.h>
#include <qdir.h>
#include <qendian.h>
#include <qjsondocument.h>
#include <qjsonvalue.h>
#include "qelfparser_p.h"
#include "qmachparser_p.h"

#include <qtcore_tracepoints_p.h>

QT_BEGIN_NAMESPACE

#ifdef QT_NO_DEBUG
#  define QLIBRARY_AS_DEBUG false
#else
#  define QLIBRARY_AS_DEBUG true
#endif

#if defined(Q_OS_UNIX) || (defined(Q_CC_MINGW) && !QT_CONFIG(debug_and_release))
// We don't use separate debug and release libs on UNIX, so we want
// to allow loading plugins, regardless of how they were built.
#  define QT_NO_DEBUG_PLUGIN_CHECK
#endif

/*!
    \class QLibrary
    \inmodule QtCore
    \reentrant
    \brief The QLibrary class loads shared libraries at runtime.


    \ingroup plugins

    An instance of a QLibrary object operates on a single shared
    object file (which we call a "library", but is also known as a
    "DLL"). A QLibrary provides access to the functionality in the
    library in a platform independent way. You can either pass a file
    name in the constructor, or set it explicitly with setFileName().
    When loading the library, QLibrary searches in all the
    system-specific library locations (e.g. \c LD_LIBRARY_PATH on
    Unix), unless the file name has an absolute path.

    If the file name is an absolute path then an attempt is made to
    load this path first. If the file cannot be found, QLibrary tries
    the name with different platform-specific file prefixes, like
    "lib" on Unix and Mac, and suffixes, like ".so" on Unix, ".dylib"
    on the Mac, or ".dll" on Windows.

    If the file path is not absolute then QLibrary modifies the search
    order to try the system-specific prefixes and suffixes first,
    followed by the file path specified.

    This makes it possible to specify shared libraries that are only
    identified by their basename (i.e. without their suffix), so the
    same code will work on different operating systems yet still
    minimise the number of attempts to find the library.

    The most important functions are load() to dynamically load the
    library file, isLoaded() to check whether loading was successful,
    and resolve() to resolve a symbol in the library. The resolve()
    function implicitly tries to load the library if it has not been
    loaded yet. Multiple instances of QLibrary can be used to access
    the same physical library. Once loaded, libraries remain in memory
    until the application terminates. You can attempt to unload a
    library using unload(), but if other instances of QLibrary are
    using the same library, the call will fail, and unloading will
    only happen when every instance has called unload().

    A typical use of QLibrary is to resolve an exported symbol in a
    library, and to call the C function that this symbol represents.
    This is called "explicit linking" in contrast to "implicit
    linking", which is done by the link step in the build process when
    linking an executable against a library.

    The following code snippet loads a library, resolves the symbol
    "mysymbol", and calls the function if everything succeeded. If
    something goes wrong, e.g. the library file does not exist or the
    symbol is not defined, the function pointer will be \nullptr and
    won't be called.

    \snippet code/src_corelib_plugin_qlibrary.cpp 0

    The symbol must be exported as a C function from the library for
    resolve() to work. This means that the function must be wrapped in
    an \c{extern "C"} block if the library is compiled with a C++
    compiler. On Windows, this also requires the use of a \c dllexport
    macro; see resolve() for the details of how this is done. For
    convenience, there is a static resolve() function which you can
    use if you just want to call a function in a library without
    explicitly loading the library first:

    \snippet code/src_corelib_plugin_qlibrary.cpp 1

    \sa QPluginLoader
*/

/*!
    \enum QLibrary::LoadHint

    This enum describes the possible hints that can be used to change the way
    libraries are handled when they are loaded. These values indicate how
    symbols are resolved when libraries are loaded, and are specified using
    the setLoadHints() function.

    \value ResolveAllSymbolsHint
    Causes all symbols in a library to be resolved when it is loaded, not
    simply when resolve() is called.
    \value ExportExternalSymbolsHint
    Exports unresolved and external symbols in the library so that they can be
    resolved in other dynamically-loaded libraries loaded later.
    \value LoadArchiveMemberHint
    Allows the file name of the library to specify a particular object file
    within an archive file.
    If this hint is given, the filename of the library consists of
    a path, which is a reference to an archive file, followed by
    a reference to the archive member.
    \value PreventUnloadHint
    Prevents the library from being unloaded from the address space if close()
    is called. The library's static variables are not reinitialized if open()
    is called at a later time.
    \value DeepBindHint
    Instructs the linker to prefer definitions in the loaded library
    over exported definitions in the loading application when resolving
    external symbols in the loaded library. This option is only supported
    on Linux.

    \sa loadHints
*/


static qsizetype qt_find_pattern(const char *s, qsizetype s_len,
                             const char *pattern, ulong p_len)
{
    /*
      we search from the end of the file because on the supported
      systems, the read-only data/text segments are placed at the end
      of the file.  HOWEVER, when building with debugging enabled, all
      the debug symbols are placed AFTER the data/text segments.

      what does this mean?  when building in release mode, the search
      is fast because the data we are looking for is at the end of the
      file... when building in debug mode, the search is slower
      because we have to skip over all the debugging symbols first
    */

    if (!s || !pattern || qsizetype(p_len) > s_len)
        return -1;

    size_t i, hs = 0, hp = 0, delta = s_len - p_len;

    for (i = 0; i < p_len; ++i) {
        hs += s[delta + i];
        hp += pattern[i];
    }
    i = delta;
    for (;;) {
        if (hs == hp && qstrncmp(s + i, pattern, p_len) == 0)
            return i;   // can't overflow, by construction
        if (i == 0)
            break;
        --i;
        hs -= s[i + p_len];
        hs += s[i];
    }

    return -1;
}

/*
  This opens the specified library, mmaps it into memory, and searches
  for the QT_PLUGIN_VERIFICATION_DATA.  The advantage of this approach is that
  we can get the verification data without have to actually load the library.
  This lets us detect mismatches more safely.

  Returns \c false if version information is not present, or if the
                information could not be read.
  Returns  true if version information is present and successfully read.
*/
static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
{
    QFile file(library);
    if (!file.open(QIODevice::ReadOnly)) {
        if (lib)
            lib->errorString = file.errorString();
        if (qt_debug_component()) {
            qWarning("%s: %ls", QFile::encodeName(library).constData(),
                     qUtf16Printable(QSystemError::stdString()));
        }
        return false;
    }

    // Files can be bigger than the virtual memory size on 32-bit systems, so
    // we limit to 512 MB there. For 64-bit, we allow up to 2^40 bytes.
    constexpr qint64 MaxMemoryMapSize =
            Q_INT64_C(1) << (sizeof(qsizetype) > 4 ? 40 : 29);

    QByteArray data;
    qsizetype fdlen = qMin(file.size(), MaxMemoryMapSize);
    const char *filedata = reinterpret_cast<char *>(file.map(0, fdlen));

    if (filedata == nullptr) {
        // Try reading the data into memory instead (up to 64 MB).
        data = file.read(64 * 1024 * 1024);
        filedata = data.constData();
        fdlen = data.size();
    }

    /*
       ELF and Mach-O binaries with GCC have .qplugin sections.
    */
    bool hasMetaData = false;
    qsizetype pos = 0;
    char pattern[] = "qTMETADATA ";
    pattern[0] = 'Q'; // Ensure the pattern "QTMETADATA" is not found in this library should QPluginLoader ever encounter it.
    const ulong plen = qstrlen(pattern);
#if defined (Q_OF_ELF) && defined(Q_CC_GNU)
    int r = QElfParser().parse(filedata, fdlen, library, lib, &pos, &fdlen);
    if (r == QElfParser::Corrupt || r == QElfParser::NotElf) {
            if (lib && qt_debug_component()) {
                qWarning("QElfParser: %ls", qUtf16Printable(lib->errorString));
            }
            return false;
    } else if (r == QElfParser::QtMetaDataSection) {
        qsizetype rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
        if (rel < 0)
            pos = -1;
        else
            pos += rel;
        hasMetaData = true;
    }
#elif defined (Q_OF_MACH_O)
    {
        QString errorString;
        int r = QMachOParser::parse(filedata, fdlen, library, &errorString, &pos, &fdlen);
        if (r == QMachOParser::NotSuitable) {
            if (qt_debug_component())
                qWarning("QMachOParser: %ls", qUtf16Printable(errorString));
            if (lib)
                lib->errorString = errorString;
            return false;
        }
        // even if the metadata section was not found, the Mach-O parser will
        // at least return the boundaries of the right architecture
        qsizetype rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
        if (rel < 0)
            pos = -1;
        else
            pos += rel;
        hasMetaData = true;
    }
#else
    pos = qt_find_pattern(filedata, fdlen, pattern, plen);
    if (pos > 0)
        hasMetaData = true;
#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)

    bool ret = false;

    if (pos >= 0 && hasMetaData) {
        const char *data = filedata + pos;
        QString errMsg;
        QJsonDocument doc = qJsonFromRawLibraryMetaData(data, fdlen, &errMsg);
        if (doc.isNull()) {
            qWarning("Found invalid metadata in lib %ls: %ls",
                     qUtf16Printable(library), qUtf16Printable(errMsg));
        } else {
            lib->metaData = doc.object();
            if (qt_debug_component())
                qWarning("Found metadata in lib %s, metadata=\n%s\n",
                         library.toLocal8Bit().constData(), doc.toJson().constData());
            ret = !doc.isNull();
        }
    }

    if (!ret && lib)
        lib->errorString = QLibrary::tr("Failed to extract plugin meta data from '%1'").arg(library);
    file.close();
    return ret;
}

static void installCoverageTool(QLibraryPrivate *libPrivate)
{
#ifdef __COVERAGESCANNER__
    /*
      __COVERAGESCANNER__ is defined when Qt has been instrumented for code
      coverage by TestCocoon. CoverageScanner is the name of the tool that
      generates the code instrumentation.
      This code is required here when code coverage analysis with TestCocoon
      is enabled in order to allow the loading application to register the plugin
      and then store its execution report. The execution report gathers information
      about each part of the plugin's code that has been used when
      the plugin was loaded by the launching application.
      The execution report for the plugin will go to the same execution report
      as the one defined for the application loading it.
    */

    int ret = __coveragescanner_register_library(libPrivate->fileName.toLocal8Bit());

    if (qt_debug_component()) {
        if (ret >= 0) {
            qDebug("coverage data for %ls registered",
                   qUtf16Printable(libPrivate->fileName));
        } else {
            qWarning("could not register %ls: error %d; coverage data may be incomplete",
                     qUtf16Printable(libPrivate->fileName),
                     ret);
        }
    }
#else
    Q_UNUSED(libPrivate);
#endif
}

class QLibraryStore
{
public:
    inline ~QLibraryStore();
    static inline QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version, QLibrary::LoadHints loadHints);
    static inline void releaseLibrary(QLibraryPrivate *lib);

    static inline void cleanup();

private:
    static inline QLibraryStore *instance();

    // all members and instance() are protected by qt_library_mutex
    typedef QMap<QString, QLibraryPrivate*> LibraryMap;
    LibraryMap libraryMap;
};

static QBasicMutex qt_library_mutex;
static QLibraryStore *qt_library_data = nullptr;
static bool qt_library_data_once;

QLibraryStore::~QLibraryStore()
{
    qt_library_data = nullptr;
}

inline void QLibraryStore::cleanup()
{
    QLibraryStore *data = qt_library_data;
    if (!data)
        return;

    // find any libraries that are still loaded but have a no one attached to them
    LibraryMap::Iterator it = data->libraryMap.begin();
    for (; it != data->libraryMap.end(); ++it) {
        QLibraryPrivate *lib = it.value();
        if (lib->libraryRefCount.loadRelaxed() == 1) {
            if (lib->libraryUnloadCount.loadRelaxed() > 0) {
                Q_ASSERT(lib->pHnd.loadRelaxed());
                lib->libraryUnloadCount.storeRelaxed(1);
#ifdef __GLIBC__
                // glibc has a bug in unloading from global destructors
                // see https://bugzilla.novell.com/show_bug.cgi?id=622977
                // and http://sourceware.org/bugzilla/show_bug.cgi?id=11941
                lib->unload(QLibraryPrivate::NoUnloadSys);
#else
                lib->unload();
#endif
            }
            delete lib;
            it.value() = 0;
        }
    }

    if (qt_debug_component()) {
        // dump all objects that remain
        for (QLibraryPrivate *lib : qAsConst(data->libraryMap)) {
            if (lib)
                qDebug() << "On QtCore unload," << lib->fileName << "was leaked, with"
                         << lib->libraryRefCount.loadRelaxed() << "users";
        }
    }

    delete data;
}

static void qlibraryCleanup()
{
    QLibraryStore::cleanup();
}
Q_DESTRUCTOR_FUNCTION(qlibraryCleanup)

// must be called with a locked mutex
QLibraryStore *QLibraryStore::instance()
{
    if (Q_UNLIKELY(!qt_library_data_once && !qt_library_data)) {
        // only create once per process lifetime
        qt_library_data = new QLibraryStore;
        qt_library_data_once = true;
    }
    return qt_library_data;
}

inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version,
                                                    QLibrary::LoadHints loadHints)
{
    QMutexLocker locker(&qt_library_mutex);
    QLibraryStore *data = instance();

    // check if this library is already loaded
    QLibraryPrivate *lib = nullptr;
    if (Q_LIKELY(data)) {
        lib = data->libraryMap.value(fileName);
        if (lib)
            lib->mergeLoadHints(loadHints);
    }
    if (!lib)
        lib = new QLibraryPrivate(fileName, version, loadHints);

    // track this library
    if (Q_LIKELY(data) && !fileName.isEmpty())
        data->libraryMap.insert(fileName, lib);

    lib->libraryRefCount.ref();
    return lib;
}

inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib)
{
    QMutexLocker locker(&qt_library_mutex);
    QLibraryStore *data = instance();

    if (lib->libraryRefCount.deref()) {
        // still in use
        return;
    }

    // no one else is using
    Q_ASSERT(lib->libraryUnloadCount.loadRelaxed() == 0);

    if (Q_LIKELY(data) && !lib->fileName.isEmpty()) {
        QLibraryPrivate *that = data->libraryMap.take(lib->fileName);
        Q_ASSERT(lib == that);
        Q_UNUSED(that);
    }
    delete lib;
}

QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints)
    : fileName(canonicalFileName), fullVersion(version), pluginState(MightBeAPlugin)
{
    loadHintsInt.storeRelaxed(loadHints);
    if (canonicalFileName.isEmpty())
        errorString = QLibrary::tr("The shared library was not found.");
}

QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version,
                                               QLibrary::LoadHints loadHints)
{
    return QLibraryStore::findOrCreate(fileName, version, loadHints);
}

QLibraryPrivate::~QLibraryPrivate()
{
}

void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
{
    // if the library is already loaded, we can't change the load hints
    if (pHnd.loadRelaxed())
        return;

    loadHintsInt.storeRelaxed(lh);
}

QFunctionPointer QLibraryPrivate::resolve(const char *symbol)
{
    if (!pHnd.loadRelaxed())
        return nullptr;
    return resolve_sys(symbol);
}

void QLibraryPrivate::setLoadHints(QLibrary::LoadHints lh)
{
    // this locks a global mutex
    QMutexLocker lock(&qt_library_mutex);
    mergeLoadHints(lh);
}

QObject *QLibraryPrivate::pluginInstance()
{
    // first, check if the instance is cached and hasn't been deleted
    QObject *obj = (QMutexLocker(&mutex), inst.data());
    if (obj)
        return obj;

    // We need to call the plugin's factory function. Is that cached?
    // skip increasing the reference count (why? -Thiago)
    QtPluginInstanceFunction factory = instanceFactory.loadAcquire();
    if (!factory)
        factory = loadPlugin();

    if (!factory)
        return nullptr;

    obj = factory();

    // cache again
    QMutexLocker locker(&mutex);
    if (inst)
        obj = inst;
    else
        inst = obj;
    return obj;
}

bool QLibraryPrivate::load()
{
    if (pHnd.loadRelaxed()) {
        libraryUnloadCount.ref();
        return true;
    }
    if (fileName.isEmpty())
        return false;

    Q_TRACE(QLibraryPrivate_load_entry, fileName);

    bool ret = load_sys();
    if (qt_debug_component()) {
        if (ret) {
            qDebug() << "loaded library" << fileName;
        } else {
            qDebug() << qUtf8Printable(errorString);
        }
    }
    if (ret) {
        //when loading a library we add a reference to it so that the QLibraryPrivate won't get deleted
        //this allows to unload the library at a later time
        libraryUnloadCount.ref();
        libraryRefCount.ref();
        installCoverageTool(this);
    }

    Q_TRACE(QLibraryPrivate_load_exit, ret);

    return ret;
}

bool QLibraryPrivate::unload(UnloadFlag flag)
{
    if (!pHnd.loadRelaxed())
        return false;
    if (libraryUnloadCount.loadRelaxed() > 0 && !libraryUnloadCount.deref()) { // only unload if ALL QLibrary instance wanted to
        QMutexLocker locker(&mutex);
        delete inst.data();
        if (flag == NoUnloadSys || unload_sys()) {
            if (qt_debug_component())
                qWarning() << "QLibraryPrivate::unload succeeded on" << fileName
                           << (flag == NoUnloadSys ? "(faked)" : "");
            //when the library is unloaded, we release the reference on it so that 'this'
            //can get deleted
            libraryRefCount.deref();
            pHnd.storeRelaxed(nullptr);
            instanceFactory.storeRelaxed(nullptr);
            return true;
        }
    }

    return false;
}

void QLibraryPrivate::release()
{
    QLibraryStore::releaseLibrary(this);
}

QtPluginInstanceFunction QLibraryPrivate::loadPlugin()
{
    if (auto ptr = instanceFactory.loadAcquire()) {
        libraryUnloadCount.ref();
        return ptr;
    }
    if (pluginState == IsNotAPlugin)
        return nullptr;
    if (load()) {
        auto ptr = reinterpret_cast<QtPluginInstanceFunction>(resolve("qt_plugin_instance"));
        instanceFactory.storeRelease(ptr); // two threads may store the same value
        return ptr;
    }
    if (qt_debug_component())
        qWarning() << "QLibraryPrivate::loadPlugin failed on" << fileName << ":" << errorString;
    pluginState = IsNotAPlugin;
    return nullptr;
}

/*!
    Returns \c true if \a fileName has a valid suffix for a loadable
    library; otherwise returns \c false.

    \table
    \header \li Platform \li Valid suffixes
    \row \li Windows     \li \c .dll, \c .DLL
    \row \li Unix/Linux  \li \c .so
    \row \li AIX  \li \c .a
    \row \li HP-UX       \li \c .sl, \c .so (HP-UXi)
    \row \li \macos and iOS   \li \c .dylib, \c .bundle, \c .so
    \endtable

    Trailing versioning numbers on Unix are ignored.
 */
bool QLibrary::isLibrary(const QString &fileName)
{
#if defined(Q_OS_WIN)
    return fileName.endsWith(QLatin1String(".dll"), Qt::CaseInsensitive);
#else // Generic Unix
    QString completeSuffix = QFileInfo(fileName).completeSuffix();
    if (completeSuffix.isEmpty())
        return false;
    const QVector<QStringRef> suffixes = completeSuffix.splitRef(QLatin1Char('.'));
    QStringList validSuffixList;

# if defined(Q_OS_HPUX)
/*
    See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF":
    "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit),
    the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix."
 */
    validSuffixList << QLatin1String("sl");
#  if defined __ia64
    validSuffixList << QLatin1String("so");
#  endif
# elif defined(Q_OS_AIX)
    validSuffixList << QLatin1String("a") << QLatin1String("so");
# elif defined(Q_OS_DARWIN)
    // On Apple platforms, dylib look like libmylib.1.0.0.dylib
    if (suffixes.last() == QLatin1String("dylib"))
        return true;

    validSuffixList << QLatin1String("so") << QLatin1String("bundle");
# elif defined(Q_OS_UNIX)
    validSuffixList << QLatin1String("so");
# endif

    // Examples of valid library names:
    //  libfoo.so
    //  libfoo.so.0
    //  libfoo.so.0.3
    //  libfoo-0.3.so
    //  libfoo-0.3.so.0.3.0

    int suffix;
    int suffixPos = -1;
    for (suffix = 0; suffix < validSuffixList.count() && suffixPos == -1; ++suffix)
        suffixPos = suffixes.indexOf(QStringRef(&validSuffixList.at(suffix)));

    bool valid = suffixPos != -1;
    for (int i = suffixPos + 1; i < suffixes.count() && valid; ++i)
        if (i != suffixPos)
            suffixes.at(i).toInt(&valid);
    return valid;
#endif
}

static bool qt_get_metadata(QLibraryPrivate *priv, QString *errMsg)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    auto getMetaData = [](QFunctionPointer fptr) {
        auto f = reinterpret_cast<const char * (*)()>(fptr);
        return qMakePair<const char *, size_t>(f(), INT_MAX);
    };
#else
    auto getMetaData = [](QFunctionPointer fptr) {
        auto f = reinterpret_cast<QPair<const char *, size_t> (*)()>(fptr);
        return f();
    };
#endif

    QFunctionPointer pfn = priv->resolve("qt_plugin_query_metadata");
    if (!pfn)
        return false;

    auto metaData = getMetaData(pfn);
    QJsonDocument doc = qJsonFromRawLibraryMetaData(metaData.first, metaData.second, errMsg);
    if (doc.isNull())
        return false;
    priv->metaData = doc.object();
    return true;
}

bool QLibraryPrivate::isPlugin()
{
    if (pluginState == MightBeAPlugin)
        updatePluginState();

    return pluginState == IsAPlugin;
}

void QLibraryPrivate::updatePluginState()
{
    QMutexLocker locker(&mutex);
    errorString.clear();
    if (pluginState != MightBeAPlugin)
        return;

    bool success = false;

#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
    if (fileName.endsWith(QLatin1String(".debug"))) {
        // refuse to load a file that ends in .debug
        // these are the debug symbols from the libraries
        // the problem is that they are valid shared library files
        // and dlopen is known to crash while opening them

        // pretend we didn't see the file
        errorString = QLibrary::tr("The shared library was not found.");
        pluginState = IsNotAPlugin;
        return;
    }
#endif

    if (!pHnd.loadRelaxed()) {
        // scan for the plugin metadata without loading
        success = findPatternUnloaded(fileName, this);
    } else {
        // library is already loaded (probably via QLibrary)
        // simply get the target function and call it.
        success = qt_get_metadata(this, &errorString);
    }

    if (!success) {
        if (errorString.isEmpty()){
            if (fileName.isEmpty())
                errorString = QLibrary::tr("The shared library was not found.");
            else
                errorString = QLibrary::tr("The file '%1' is not a valid Qt plugin.").arg(fileName);
        }
        pluginState = IsNotAPlugin;
        return;
    }

    pluginState = IsNotAPlugin; // be pessimistic

    uint qt_version = (uint)metaData.value(QLatin1String("version")).toDouble();
    bool debug = metaData.value(QLatin1String("debug")).toBool();
    if ((qt_version & 0x00ff00) > (QT_VERSION & 0x00ff00) || (qt_version & 0xff0000) != (QT_VERSION & 0xff0000)) {
        if (qt_debug_component()) {
            qWarning("In %s:\n"
                 "  Plugin uses incompatible Qt library (%d.%d.%d) [%s]",
                 QFile::encodeName(fileName).constData(),
                 (qt_version&0xff0000) >> 16, (qt_version&0xff00) >> 8, qt_version&0xff,
                 debug ? "debug" : "release");
        }
        errorString = QLibrary::tr("The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5]")
            .arg(fileName)
            .arg((qt_version&0xff0000) >> 16)
            .arg((qt_version&0xff00) >> 8)
            .arg(qt_version&0xff)
            .arg(debug ? QLatin1String("debug") : QLatin1String("release"));
#ifndef QT_NO_DEBUG_PLUGIN_CHECK
    } else if(debug != QLIBRARY_AS_DEBUG) {
        //don't issue a qWarning since we will hopefully find a non-debug? --Sam
        errorString = QLibrary::tr("The plugin '%1' uses incompatible Qt library."
                 " (Cannot mix debug and release libraries.)").arg(fileName);
#endif
    } else {
        pluginState = IsAPlugin;
    }
}

/*!
    Loads the library and returns \c true if the library was loaded
    successfully; otherwise returns \c false. Since resolve() always
    calls this function before resolving any symbols it is not
    necessary to call it explicitly. In some situations you might want
    the library loaded in advance, in which case you would use this
    function.

    \sa unload()
*/
bool QLibrary::load()
{
    if (!d)
        return false;
    if (did_load)
        return d->pHnd.loadRelaxed();
    did_load = true;
    return d->load();
}

/*!
    Unloads the library and returns \c true if the library could be
    unloaded; otherwise returns \c false.

    This happens automatically on application termination, so you
    shouldn't normally need to call this function.

    If other instances of QLibrary are using the same library, the
    call will fail, and unloading will only happen when every instance
    has called unload().

    Note that on Mac OS X 10.3 (Panther), dynamic libraries cannot be unloaded.

    \sa resolve(), load()
*/
bool QLibrary::unload()
{
    if (did_load) {
        did_load = false;
        return d->unload();
    }
    return false;
}

/*!
    Returns \c true if the library is loaded; otherwise returns \c false.

    \sa load()
 */
bool QLibrary::isLoaded() const
{
    return d && d->pHnd.loadRelaxed();
}


/*!
    Constructs a library with the given \a parent.
 */
QLibrary::QLibrary(QObject *parent)
    :QObject(parent), d(nullptr), did_load(false)
{
}


/*!
    Constructs a library object with the given \a parent that will
    load the library specified by \a fileName.

    We recommend omitting the file's suffix in \a fileName, since
    QLibrary will automatically look for the file with the appropriate
    suffix in accordance with the platform, e.g. ".so" on Unix,
    ".dylib" on \macos and iOS, and ".dll" on Windows. (See \l{fileName}.)
 */
QLibrary::QLibrary(const QString& fileName, QObject *parent)
    :QObject(parent), d(nullptr), did_load(false)
{
    setFileName(fileName);
}


/*!
    Constructs a library object with the given \a parent that will
    load the library specified by \a fileName and major version number \a verNum.
    Currently, the version number is ignored on Windows.

    We recommend omitting the file's suffix in \a fileName, since
    QLibrary will automatically look for the file with the appropriate
    suffix in accordance with the platform, e.g. ".so" on Unix,
    ".dylib" on \macos and iOS, and ".dll" on Windows. (See \l{fileName}.)
*/
QLibrary::QLibrary(const QString& fileName, int verNum, QObject *parent)
    :QObject(parent), d(nullptr), did_load(false)
{
    setFileNameAndVersion(fileName, verNum);
}

/*!
    Constructs a library object with the given \a parent that will
    load the library specified by \a fileName and full version number \a version.
    Currently, the version number is ignored on Windows.

    We recommend omitting the file's suffix in \a fileName, since
    QLibrary will automatically look for the file with the appropriate
    suffix in accordance with the platform, e.g. ".so" on Unix,
    ".dylib" on \macos and iOS, and ".dll" on Windows. (See \l{fileName}.)
 */
QLibrary::QLibrary(const QString& fileName, const QString &version, QObject *parent)
    :QObject(parent), d(nullptr), did_load(false)
{
    setFileNameAndVersion(fileName, version);
}

/*!
    Destroys the QLibrary object.

    Unless unload() was called explicitly, the library stays in memory
    until the application terminates.

    \sa isLoaded(), unload()
*/
QLibrary::~QLibrary()
{
    if (d)
        d->release();
}


/*!
    \property QLibrary::fileName
    \brief the file name of the library

    We recommend omitting the file's suffix in the file name, since
    QLibrary will automatically look for the file with the appropriate
    suffix (see isLibrary()).

    When loading the library, QLibrary searches in all system-specific
    library locations (for example, \c LD_LIBRARY_PATH on Unix), unless the
    file name has an absolute path. After loading the library
    successfully, fileName() returns the fully-qualified file name of
    the library, including the full path to the library if one was given
    in the constructor or passed to setFileName().

    For example, after successfully loading the "GL" library on Unix
    platforms, fileName() will return "libGL.so". If the file name was
    originally passed as "/usr/lib/libGL", fileName() will return
    "/usr/lib/libGL.so".
*/

void QLibrary::setFileName(const QString &fileName)
{
    QLibrary::LoadHints lh;
    if (d) {
        lh = d->loadHints();
        d->release();
        d = nullptr;
        did_load = false;
    }
    d = QLibraryPrivate::findOrCreate(fileName, QString(), lh);
}

QString QLibrary::fileName() const
{
    if (d) {
        QMutexLocker locker(&d->mutex);
        return d->qualifiedFileName.isEmpty() ? d->fileName : d->qualifiedFileName;
    }
    return QString();
}

/*!
    \fn void QLibrary::setFileNameAndVersion(const QString &fileName, int versionNumber)

    Sets the fileName property and major version number to \a fileName
    and \a versionNumber respectively.
    The \a versionNumber is ignored on Windows.

    \sa setFileName()
*/
void QLibrary::setFileNameAndVersion(const QString &fileName, int verNum)
{
    QLibrary::LoadHints lh;
    if (d) {
        lh = d->loadHints();
        d->release();
        d = nullptr;
        did_load = false;
    }
    d = QLibraryPrivate::findOrCreate(fileName, verNum >= 0 ? QString::number(verNum) : QString(), lh);
}

/*!
    \since 4.4

    Sets the fileName property and full version number to \a fileName
    and \a version respectively.
    The \a version parameter is ignored on Windows.

    \sa setFileName()
*/
void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &version)
{
    QLibrary::LoadHints lh;
    if (d) {
        lh = d->loadHints();
        d->release();
        d = nullptr;
        did_load = false;
    }
    d = QLibraryPrivate::findOrCreate(fileName, version, lh);
}

/*!
    Returns the address of the exported symbol \a symbol. The library is
    loaded if necessary. The function returns \nullptr if the symbol could
    not be resolved or if the library could not be loaded.

    Example:
    \snippet code/src_corelib_plugin_qlibrary.cpp 2

    The symbol must be exported as a C function from the library. This
    means that the function must be wrapped in an \c{extern "C"} if
    the library is compiled with a C++ compiler. On Windows you must
    also explicitly export the function from the DLL using the
    \c{__declspec(dllexport)} compiler directive, for example:

    \snippet code/src_corelib_plugin_qlibrary.cpp 3

    with \c MY_EXPORT defined as

    \snippet code/src_corelib_plugin_qlibrary.cpp 4
*/
QFunctionPointer QLibrary::resolve(const char *symbol)
{
    if (!isLoaded() && !load())
        return nullptr;
    return d->resolve(symbol);
}

/*!
    \overload

    Loads the library \a fileName and returns the address of the
    exported symbol \a symbol. Note that \a fileName should not
    include the platform-specific file suffix; (see \l{fileName}). The
    library remains loaded until the application exits.

    The function returns \nullptr if the symbol could not be resolved or if
    the library could not be loaded.

    \sa resolve()
*/
QFunctionPointer QLibrary::resolve(const QString &fileName, const char *symbol)
{
    QLibrary library(fileName);
    return library.resolve(symbol);
}

/*!
    \overload

    Loads the library \a fileName with major version number \a verNum and
    returns the address of the exported symbol \a symbol.
    Note that \a fileName should not include the platform-specific file suffix;
    (see \l{fileName}). The library remains loaded until the application exits.
    \a verNum is ignored on Windows.

    The function returns \nullptr if the symbol could not be resolved or if
    the library could not be loaded.

    \sa resolve()
*/
QFunctionPointer QLibrary::resolve(const QString &fileName, int verNum, const char *symbol)
{
    QLibrary library(fileName, verNum);
    return library.resolve(symbol);
}

/*!
    \overload
    \since 4.4

    Loads the library \a fileName with full version number \a version and
    returns the address of the exported symbol \a symbol.
    Note that \a fileName should not include the platform-specific file suffix;
    (see \l{fileName}). The library remains loaded until the application exits.
    \a version is ignored on Windows.

    The function returns \nullptr if the symbol could not be resolved or if
    the library could not be loaded.

    \sa resolve()
*/
QFunctionPointer QLibrary::resolve(const QString &fileName, const QString &version, const char *symbol)
{
    QLibrary library(fileName, version);
    return library.resolve(symbol);
}

/*!
    \since 4.2

    Returns a text string with the description of the last error that occurred.
    Currently, errorString will only be set if load(), unload() or resolve() for some reason fails.
*/
QString QLibrary::errorString() const
{
    QString str;
    if (d) {
        QMutexLocker locker(&d->mutex);
        str = d->errorString;
    }
    return str.isEmpty() ? tr("Unknown error") : str;
}

/*!
    \property QLibrary::loadHints
    \brief Give the load() function some hints on how it should behave.

    You can give some hints on how the symbols are resolved. Usually,
    the symbols are not resolved at load time, but resolved lazily,
    (that is, when resolve() is called). If you set the loadHints to
    ResolveAllSymbolsHint, then all symbols will be resolved at load time
    if the platform supports it.

    Setting ExportExternalSymbolsHint will make the external symbols in the
    library available for resolution in subsequent loaded libraries.

    If LoadArchiveMemberHint is set, the file name
    is composed of two components: A path which is a reference to an
    archive file followed by the second component which is the reference to
    the archive member. For instance, the fileName \c libGL.a(shr_64.o) will refer
    to the library \c shr_64.o in the archive file named \c libGL.a. This
    is only supported on the AIX platform.

    The interpretation of the load hints is platform dependent, and if
    you use it you are probably making some assumptions on which platform
    you are compiling for, so use them only if you understand the consequences
    of them.

    By default, none of these flags are set, so libraries will be loaded with
    lazy symbol resolution, and will not export external symbols for resolution
    in other dynamically-loaded libraries.

    \note Setting this property after the library has been loaded has no effect
    and loadHints() will not reflect those changes.

    \note This property is shared among all QLibrary instances that refer to
    the same library.
*/
void QLibrary::setLoadHints(LoadHints hints)
{
    if (!d) {
        d = QLibraryPrivate::findOrCreate(QString());   // ugly, but we need a d-ptr
        d->errorString.clear();
    }
    d->setLoadHints(hints);
}

QLibrary::LoadHints QLibrary::loadHints() const
{
    return d ? d->loadHints() : QLibrary::LoadHints();
}

/* Internal, for debugging */
bool qt_debug_component()
{
    static int debug_env = QT_PREPEND_NAMESPACE(qEnvironmentVariableIntValue)("QT_DEBUG_PLUGINS");
    return debug_env != 0;
}

QT_END_NAMESPACE

#include "moc_qlibrary.cpp"
