| Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/plugin/qlibrary.cpp |
| Switch to Source code | Preprocessed file |
| Line | Source | Count | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | - | |||||||||||||
| 2 | - | |||||||||||||
| 3 | - | |||||||||||||
| 4 | - | |||||||||||||
| 5 | - | |||||||||||||
| 6 | - | |||||||||||||
| 7 | - | |||||||||||||
| 8 | - | |||||||||||||
| 9 | - | |||||||||||||
| 10 | - | |||||||||||||
| 11 | static long qt_find_pattern(const char *s, ulong s_len, | - | ||||||||||||
| 12 | const char *pattern, ulong p_len) | - | ||||||||||||
| 13 | { | - | ||||||||||||
| 14 | if (! s || ! pattern || p_len > s_len) return -1; | - | ||||||||||||
| 15 | ulong i, hs = 0, hp = 0, delta = s_len - p_len; | - | ||||||||||||
| 16 | - | |||||||||||||
| 17 | for (i = 0; i < p_len; ++i) { | - | ||||||||||||
| 18 | hs += s[delta + i]; | - | ||||||||||||
| 19 | hp += pattern[i]; | - | ||||||||||||
| 20 | } | - | ||||||||||||
| 21 | i = delta; | - | ||||||||||||
| 22 | for (;;) { | - | ||||||||||||
| 23 | if (hs == hp && qstrncmp(s + i, pattern, p_len) == 0) | - | ||||||||||||
| 24 | return i; | - | ||||||||||||
| 25 | if (i == 0) | - | ||||||||||||
| 26 | break; | - | ||||||||||||
| 27 | --i; | - | ||||||||||||
| 28 | hs -= s[i + p_len]; | - | ||||||||||||
| 29 | hs += s[i]; | - | ||||||||||||
| 30 | } | - | ||||||||||||
| 31 | - | |||||||||||||
| 32 | return -1; | - | ||||||||||||
| 33 | } | - | ||||||||||||
| 34 | static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) | - | ||||||||||||
| 35 | { | - | ||||||||||||
| 36 | QFile file(library); | - | ||||||||||||
| 37 | if (!file.open(QIODevice::ReadOnly)
| 0-1396 | ||||||||||||
| 38 | if (lib
| 0 | ||||||||||||
| 39 | lib->errorString = file.errorString(); never executed: lib->errorString = file.errorString(); | 0 | ||||||||||||
| 40 | if (qt_debug_component()
| 0 | ||||||||||||
| 41 | QMessageLogger(__FILE__, 234240, __PRETTY_FUNCTION__).warning("%s: %s", (const char*) QFile::encodeName(library), | - | ||||||||||||
| 42 | QString(qt_error_string((*__errno_location ()))).toLocal8Bit().constData()); | - | ||||||||||||
| 43 | } never executed: end of block | 0 | ||||||||||||
| 44 | return never executed: false;return false;never executed: return false; | 0 | ||||||||||||
| 45 | } | - | ||||||||||||
| 46 | - | |||||||||||||
| 47 | QByteArray data; | - | ||||||||||||
| 48 | const char *filedata = 0; | - | ||||||||||||
| 49 | ulong fdlen = file.size(); | - | ||||||||||||
| 50 | filedata = (char *) file.map(0, fdlen); | - | ||||||||||||
| 51 | if (filedata == 0
| 0-1396 | ||||||||||||
| 52 | - | |||||||||||||
| 53 | data = file.readAll(); | - | ||||||||||||
| 54 | filedata = data.constData(); | - | ||||||||||||
| 55 | fdlen = data.size(); | - | ||||||||||||
| 56 | } never executed: end of block | 0 | ||||||||||||
| 57 | - | |||||||||||||
| 58 | - | |||||||||||||
| 59 | - | |||||||||||||
| 60 | - | |||||||||||||
| 61 | bool hasMetaData = false; | - | ||||||||||||
| 62 | long pos = 0; | - | ||||||||||||
| 63 | char pattern[] = "qTMETADATA "; | - | ||||||||||||
| 64 | pattern[0] = 'Q'; | - | ||||||||||||
| 65 | const ulong plen = qstrlen(pattern); | - | ||||||||||||
| 66 | - | |||||||||||||
| 67 | int r = QElfParser().parse(filedata, fdlen, library, lib, &pos, &fdlen); | - | ||||||||||||
| 68 | if (r == QElfParser::Corrupt
| 3-1393 | ||||||||||||
| 69 | if (lib
| 0-719 | ||||||||||||
| 70 | QMessageLogger(__FILE__, 263269, __PRETTY_FUNCTION__).warning("QElfParser: %s",QString(lib->errorString).toLocal8Bit().constData()); | - | ||||||||||||
| 71 | } never executed: end of block | 0 | ||||||||||||
| 72 | return executed 719 times by 112 tests: false;return false;Executed by:
executed 719 times by 112 tests: return false;Executed by:
| 719 | ||||||||||||
| 73 | } else if (r == QElfParser::QtMetaDataSection
| 1-676 | ||||||||||||
| 74 | long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); | - | ||||||||||||
| 75 | if (rel < 0
| 0-676 | ||||||||||||
| 76 | pos = -1; never executed: pos = -1; | 0 | ||||||||||||
| 77 | else | - | ||||||||||||
| 78 | pos += rel; executed 676 times by 111 tests: pos += rel;Executed by:
| 676 | ||||||||||||
| 79 | hasMetaData = true; | - | ||||||||||||
| 80 | } executed 676 times by 111 tests: end of blockExecuted by:
| 676 | ||||||||||||
| 81 | bool ret = false; | - | ||||||||||||
| 82 | - | |||||||||||||
| 83 | if (pos >= 0
| 0-677 | ||||||||||||
| 84 | if (hasMetaData
| 1-676 | ||||||||||||
| 85 | const char *data = filedata + pos; | - | ||||||||||||
| 86 | QJsonDocument doc = QLibraryPrivate::fromRawMetaDataqJsonFromRawLibraryMetaData(data); | - | ||||||||||||
| 87 | lib->metaData = doc.object(); | - | ||||||||||||
| 88 | if (qt_debug_component()
| 0-676 | ||||||||||||
| 89 | QMessageLogger(__FILE__, 308314, __PRETTY_FUNCTION__).warning("Found metadata in lib %s, metadata=\n%s\n", never executed: QMessageLogger(__FILE__, 314, __PRETTY_FUNCTION__).warning("Found metadata in lib %s, metadata=\n%s\n", library.toLocal8Bit().constData(), doc.toJson().constData()); | 0 | ||||||||||||
| 90 | library.toLocal8Bit().constData(), doc.toJson().constData()); never executed: QMessageLogger(__FILE__, 314, __PRETTY_FUNCTION__).warning("Found metadata in lib %s, metadata=\n%s\n", library.toLocal8Bit().constData(), doc.toJson().constData()); | 0 | ||||||||||||
| 91 | ret = !doc.isNull(); | - | ||||||||||||
| 92 | } executed 676 times by 111 tests: end of blockExecuted by:
| 676 | ||||||||||||
| 93 | } executed 677 times by 111 tests: end of blockExecuted by:
| 677 | ||||||||||||
| 94 | - | |||||||||||||
| 95 | if (!ret
| 0-676 | ||||||||||||
| 96 | lib->errorString = QLibrary::tr("Failed to extract plugin meta data from '%1'").arg(library); executed 1 time by 1 test: lib->errorString = QLibrary::tr("Failed to extract plugin meta data from '%1'").arg(library);Executed by:
| 1 | ||||||||||||
| 97 | file.close(); | - | ||||||||||||
| 98 | return executed 677 times by 111 tests: ret;return ret;Executed by:
executed 677 times by 111 tests: return ret;Executed by:
| 677 | ||||||||||||
| 99 | } | - | ||||||||||||
| 100 | - | |||||||||||||
| 101 | static void installCoverageTool(QLibraryPrivate *libPrivate) | - | ||||||||||||
| 102 | { | - | ||||||||||||
| 103 | int ret = __coveragescanner_register_library(libPrivate->fileName.toLocal8Bit()); | - | ||||||||||||
| 104 | - | |||||||||||||
| 105 | if (qt_debug_component()) { | - | ||||||||||||
| 106 | if (ret >= 0) { | - | ||||||||||||
| 107 | QMessageLogger(__FILE__, 340346, __PRETTY_FUNCTION__).debug("coverage data for %s registered", | - | ||||||||||||
| 108 | QString(libPrivate->fileName).toLocal8Bit().constData()); | - | ||||||||||||
| 109 | } else { | - | ||||||||||||
| 110 | QMessageLogger(__FILE__, 343349, __PRETTY_FUNCTION__).warning("could not register %s: error %d; coverage data may be incomplete", | - | ||||||||||||
| 111 | QString(libPrivate->fileName).toLocal8Bit().constData(), | - | ||||||||||||
| 112 | ret); | - | ||||||||||||
| 113 | } | - | ||||||||||||
| 114 | } | - | ||||||||||||
| 115 | - | |||||||||||||
| 116 | - | |||||||||||||
| 117 | - | |||||||||||||
| 118 | } | - | ||||||||||||
| 119 | - | |||||||||||||
| 120 | class QLibraryStore | - | ||||||||||||
| 121 | { | - | ||||||||||||
| 122 | public: | - | ||||||||||||
| 123 | inline ~QLibraryStore(); | - | ||||||||||||
| 124 | static inline QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version, QLibrary::LoadHints loadHints); | - | ||||||||||||
| 125 | static inline void releaseLibrary(QLibraryPrivate *lib); | - | ||||||||||||
| 126 | - | |||||||||||||
| 127 | static inline void cleanup(); | - | ||||||||||||
| 128 | - | |||||||||||||
| 129 | private: | - | ||||||||||||
| 130 | static inline QLibraryStore *instance(); | - | ||||||||||||
| 131 | - | |||||||||||||
| 132 | - | |||||||||||||
| 133 | typedef QMap<QString, QLibraryPrivate*> LibraryMap; | - | ||||||||||||
| 134 | LibraryMap libraryMap; | - | ||||||||||||
| 135 | }; | - | ||||||||||||
| 136 | - | |||||||||||||
| 137 | static QBasicMutex qt_library_mutex; | - | ||||||||||||
| 138 | static QLibraryStore *qt_library_data = 0; | - | ||||||||||||
| 139 | static bool qt_library_data_once; | - | ||||||||||||
| 140 | - | |||||||||||||
| 141 | QLibraryStore::~QLibraryStore() | - | ||||||||||||
| 142 | { | - | ||||||||||||
| 143 | qt_library_data = 0; | - | ||||||||||||
| 144 | } | - | ||||||||||||
| 145 | - | |||||||||||||
| 146 | inline void QLibraryStore::cleanup() | - | ||||||||||||
| 147 | { | - | ||||||||||||
| 148 | QLibraryStore *data = qt_library_data; | - | ||||||||||||
| 149 | if (!data
| 0 | ||||||||||||
| 150 | return; never executed: return; | 0 | ||||||||||||
| 151 | - | |||||||||||||
| 152 | - | |||||||||||||
| 153 | LibraryMap::Iterator it = data->libraryMap.begin(); | - | ||||||||||||
| 154 | for (; it != data->libraryMap.end()
| 0 | ||||||||||||
| 155 | QLibraryPrivate *lib = it.value(); | - | ||||||||||||
| 156 | if (lib->libraryRefCount.load() == 1
| 0 | ||||||||||||
| 157 | if (lib->libraryUnloadCount.load() > 0
| 0 | ||||||||||||
| 158 | ((!(lib->pHnd)) ? qt_assert("lib->pHnd",__FILE__,391397) : qt_noop()); | - | ||||||||||||
| 159 | lib->libraryUnloadCount.store(1); | - | ||||||||||||
| 160 | - | |||||||||||||
| 161 | - | |||||||||||||
| 162 | - | |||||||||||||
| 163 | - | |||||||||||||
| 164 | lib->unload(QLibraryPrivate::NoUnloadSys); | - | ||||||||||||
| 165 | - | |||||||||||||
| 166 | - | |||||||||||||
| 167 | - | |||||||||||||
| 168 | } never executed: end of block | 0 | ||||||||||||
| 169 | delete lib; | - | ||||||||||||
| 170 | it.value() = 0; | - | ||||||||||||
| 171 | } never executed: end of block | 0 | ||||||||||||
| 172 | } never executed: end of block | 0 | ||||||||||||
| 173 | - | |||||||||||||
| 174 | if (qt_debug_component()
| 0 | ||||||||||||
| 175 | - | |||||||||||||
| 176 | for (QForeachContainer<typename QtPrivate::remove_reference<decltypeQLibraryPrivate *lib : qAsConst(data->libraryMap)>::type> _container_((data->libraryMap)); _container_.control && _container_.i != _container_.e; ++_container_.i, _container_.control ^= 1) for (QLibraryPrivate *lib = *_container_.i; _container_.control; _container_.control = 0))) { | - | ||||||||||||
| 177 | if (lib
| 0 | ||||||||||||
| 178 | QMessageLogger(__FILE__, 411417, __PRETTY_FUNCTION__).debug() << "On QtCore unload," << lib->fileName << "was leaked, with" never executed: QMessageLogger(__FILE__, 417, __PRETTY_FUNCTION__).debug() << "On QtCore unload," << lib->fileName << "was leaked, with" << lib->libraryRefCount.load() << "users"; | 0 | ||||||||||||
| 179 | << lib->libraryRefCount.load() << "users"; never executed: QMessageLogger(__FILE__, 417, __PRETTY_FUNCTION__).debug() << "On QtCore unload," << lib->fileName << "was leaked, with" << lib->libraryRefCount.load() << "users"; | 0 | ||||||||||||
| 180 | } never executed: end of block | 0 | ||||||||||||
| 181 | } never executed: end of block | 0 | ||||||||||||
| 182 | - | |||||||||||||
| 183 | delete data; | - | ||||||||||||
| 184 | } never executed: end of block | 0 | ||||||||||||
| 185 | - | |||||||||||||
| 186 | static void qlibraryCleanup() | - | ||||||||||||
| 187 | { | - | ||||||||||||
| 188 | QLibraryStore::cleanup(); | - | ||||||||||||
| 189 | } | - | ||||||||||||
| 190 | namespace { static const struct qlibraryCleanup_dtor_class_ { inline qlibraryCleanup_dtor_class_() { } inline ~ qlibraryCleanup_dtor_class_() { qlibraryCleanup(); } } qlibraryCleanup_dtor_instance_; } | - | ||||||||||||
| 191 | - | |||||||||||||
| 192 | - | |||||||||||||
| 193 | QLibraryStore *QLibraryStore::instance() | - | ||||||||||||
| 194 | { | - | ||||||||||||
| 195 | if (__builtin_expect(!!(!qt_library_data_once && !qt_library_data), false)) { | - | ||||||||||||
| 196 | - | |||||||||||||
| 197 | qt_library_data = new QLibraryStore; | - | ||||||||||||
| 198 | qt_library_data_once = true; | - | ||||||||||||
| 199 | } | - | ||||||||||||
| 200 | return qt_library_data; | - | ||||||||||||
| 201 | } | - | ||||||||||||
| 202 | - | |||||||||||||
| 203 | inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version, | - | ||||||||||||
| 204 | QLibrary::LoadHints loadHints) | - | ||||||||||||
| 205 | { | - | ||||||||||||
| 206 | QMutexLocker locker(&qt_library_mutex); | - | ||||||||||||
| 207 | QLibraryStore *data = instance(); | - | ||||||||||||
| 208 | - | |||||||||||||
| 209 | - | |||||||||||||
| 210 | QLibraryPrivate *lib = 0; | - | ||||||||||||
| 211 | if (__builtin_expect(!!(data), true)) { | - | ||||||||||||
| 212 | lib = data->libraryMap.value(fileName); | - | ||||||||||||
| 213 | if (lib) | - | ||||||||||||
| 214 | lib->mergeLoadHints(loadHints); | - | ||||||||||||
| 215 | } | - | ||||||||||||
| 216 | if (!lib) | - | ||||||||||||
| 217 | lib = new QLibraryPrivate(fileName, version, loadHints); | - | ||||||||||||
| 218 | - | |||||||||||||
| 219 | - | |||||||||||||
| 220 | if (__builtin_expect(!!(data), true) && !fileName.isEmpty()) | - | ||||||||||||
| 221 | data->libraryMap.insert(fileName, lib); | - | ||||||||||||
| 222 | - | |||||||||||||
| 223 | lib->libraryRefCount.ref(); | - | ||||||||||||
| 224 | return lib; | - | ||||||||||||
| 225 | } | - | ||||||||||||
| 226 | - | |||||||||||||
| 227 | inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib) | - | ||||||||||||
| 228 | { | - | ||||||||||||
| 229 | QMutexLocker locker(&qt_library_mutex); | - | ||||||||||||
| 230 | QLibraryStore *data = instance(); | - | ||||||||||||
| 231 | - | |||||||||||||
| 232 | if (lib->libraryRefCount.deref()) { | - | ||||||||||||
| 233 | - | |||||||||||||
| 234 | return; | - | ||||||||||||
| 235 | } | - | ||||||||||||
| 236 | - | |||||||||||||
| 237 | - | |||||||||||||
| 238 | ((!(lib->libraryUnloadCount.load() == 0)) ? qt_assert("lib->libraryUnloadCount.load() == 0",__FILE__,471477) : qt_noop()); | - | ||||||||||||
| 239 | - | |||||||||||||
| 240 | if (__builtin_expect(!!(data), true) && !lib->fileName.isEmpty()) { | - | ||||||||||||
| 241 | QLibraryPrivate *that = data->libraryMap.take(lib->fileName); | - | ||||||||||||
| 242 | ((!(lib == that)) ? qt_assert("lib == that",__FILE__,475481) : qt_noop()); | - | ||||||||||||
| 243 | (void)that;; | - | ||||||||||||
| 244 | } | - | ||||||||||||
| 245 | delete lib; | - | ||||||||||||
| 246 | } | - | ||||||||||||
| 247 | - | |||||||||||||
| 248 | QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints) | - | ||||||||||||
| 249 | : pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0), | - | ||||||||||||
| 250 | libraryRefCount(0), libraryUnloadCount(0), pluginState(MightBeAPlugin) | - | ||||||||||||
| 251 | { | - | ||||||||||||
| 252 | loadHintsInt.store(loadHints); | - | ||||||||||||
| 253 | if (canonicalFileName.isEmpty()) | - | ||||||||||||
| 254 | errorString = QLibrary::tr("The shared library was not found."); | - | ||||||||||||
| 255 | } | - | ||||||||||||
| 256 | - | |||||||||||||
| 257 | QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version, | - | ||||||||||||
| 258 | QLibrary::LoadHints loadHints) | - | ||||||||||||
| 259 | { | - | ||||||||||||
| 260 | return QLibraryStore::findOrCreate(fileName, version, loadHints); | - | ||||||||||||
| 261 | } | - | ||||||||||||
| 262 | - | |||||||||||||
| 263 | QLibraryPrivate::~QLibraryPrivate() | - | ||||||||||||
| 264 | { | - | ||||||||||||
| 265 | } | - | ||||||||||||
| 266 | - | |||||||||||||
| 267 | void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh) | - | ||||||||||||
| 268 | { | - | ||||||||||||
| 269 | - | |||||||||||||
| 270 | if (pHnd) | - | ||||||||||||
| 271 | return; | - | ||||||||||||
| 272 | - | |||||||||||||
| 273 | loadHintsInt.store(lh); | - | ||||||||||||
| 274 | } | - | ||||||||||||
| 275 | - | |||||||||||||
| 276 | QFunctionPointer QLibraryPrivate::resolve(const char *symbol) | - | ||||||||||||
| 277 | { | - | ||||||||||||
| 278 | if (!pHnd) | - | ||||||||||||
| 279 | return 0; | - | ||||||||||||
| 280 | return resolve_sys(symbol); | - | ||||||||||||
| 281 | } | - | ||||||||||||
| 282 | - | |||||||||||||
| 283 | void QLibraryPrivate::setLoadHints(QLibrary::LoadHints lh) | - | ||||||||||||
| 284 | { | - | ||||||||||||
| 285 | - | |||||||||||||
| 286 | QMutexLocker lock(&qt_library_mutex); | - | ||||||||||||
| 287 | mergeLoadHints(lh); | - | ||||||||||||
| 288 | } | - | ||||||||||||
| 289 | - | |||||||||||||
| 290 | bool QLibraryPrivate::load() | - | ||||||||||||
| 291 | { | - | ||||||||||||
| 292 | if (pHnd
| 2-530 | ||||||||||||
| 293 | libraryUnloadCount.ref(); | - | ||||||||||||
| 294 | return executed 2 times by 2 tests: true;return true;Executed by:
executed 2 times by 2 tests: return true;Executed by:
| 2 | ||||||||||||
| 295 | } | - | ||||||||||||
| 296 | if (fileName.isEmpty()
| 0-530 | ||||||||||||
| 297 | return never executed: false;return false;never executed: return false; | 0 | ||||||||||||
| 298 | - | |||||||||||||
| 299 | bool ret = load_sys(); | - | ||||||||||||
| 300 | if (qt_debug_component()
| 0-530 | ||||||||||||
| 301 | if (ret
| 0 | ||||||||||||
| 302 | QMessageLogger(__FILE__, 534541, __PRETTY_FUNCTION__).debug() << "loaded library" << fileName; | - | ||||||||||||
| 303 | } never executed: else {end of block | 0 | ||||||||||||
| 304 | QMessageLogger(__FILE__, 543, __PRETTY_FUNCTION__).debug() << QString(errorString).toUtf8().constData(); | - | ||||||||||||
| 305 | } never executed: end of block | 0 | ||||||||||||
| 306 | } | - | ||||||||||||
| 307 | if (ret
| 6-524 | ||||||||||||
| 308 | - | |||||||||||||
| 309 | - | |||||||||||||
| 310 | libraryUnloadCount.ref(); | - | ||||||||||||
| 311 | libraryRefCount.ref(); | - | ||||||||||||
| 312 | installCoverageTool(this); | - | ||||||||||||
| 313 | } executed 524 times by 134 tests: end of blockExecuted by:
| 524 | ||||||||||||
| 314 | - | |||||||||||||
| 315 | return executed 530 times by 134 tests: ret;return ret;Executed by:
executed 530 times by 134 tests: return ret;Executed by:
| 530 | ||||||||||||
| 316 | } | - | ||||||||||||
| 317 | - | |||||||||||||
| 318 | bool QLibraryPrivate::unload(UnloadFlag flag) | - | ||||||||||||
| 319 | { | - | ||||||||||||
| 320 | if (!pHnd) | - | ||||||||||||
| 321 | return false; | - | ||||||||||||
| 322 | if (libraryUnloadCount.load() > 0 && !libraryUnloadCount.deref()) { | - | ||||||||||||
| 323 | delete inst.data(); | - | ||||||||||||
| 324 | if (flag == NoUnloadSys || unload_sys()) { | - | ||||||||||||
| 325 | if (qt_debug_component()) | - | ||||||||||||
| 326 | QMessageLogger(__FILE__, 554565, __PRETTY_FUNCTION__).warning() << "QLibraryPrivate::unload succeeded on" << fileName | - | ||||||||||||
| 327 | << (flag == NoUnloadSys ? "(faked)" : ""); | - | ||||||||||||
| 328 | - | |||||||||||||
| 329 | - | |||||||||||||
| 330 | libraryRefCount.deref(); | - | ||||||||||||
| 331 | pHnd = 0; | - | ||||||||||||
| 332 | instance = 0; | - | ||||||||||||
| 333 | } | - | ||||||||||||
| 334 | } | - | ||||||||||||
| 335 | - | |||||||||||||
| 336 | return (pHnd == 0); | - | ||||||||||||
| 337 | } | - | ||||||||||||
| 338 | - | |||||||||||||
| 339 | void QLibraryPrivate::release() | - | ||||||||||||
| 340 | { | - | ||||||||||||
| 341 | QLibraryStore::releaseLibrary(this); | - | ||||||||||||
| 342 | } | - | ||||||||||||
| 343 | - | |||||||||||||
| 344 | bool QLibraryPrivate::loadPlugin() | - | ||||||||||||
| 345 | { | - | ||||||||||||
| 346 | if (instance) { | - | ||||||||||||
| 347 | libraryUnloadCount.ref(); | - | ||||||||||||
| 348 | return true; | - | ||||||||||||
| 349 | } | - | ||||||||||||
| 350 | if (pluginState == IsNotAPlugin) | - | ||||||||||||
| 351 | return false; | - | ||||||||||||
| 352 | if (load()) { | - | ||||||||||||
| 353 | instance = (QtPluginInstanceFunction)resolve("qt_plugin_instance"); | - | ||||||||||||
| 354 | return instance; | - | ||||||||||||
| 355 | } | - | ||||||||||||
| 356 | if (qt_debug_component()) | - | ||||||||||||
| 357 | QMessageLogger(__FILE__, 585596, __PRETTY_FUNCTION__).warning() << "QLibraryPrivate::loadPlugin failed on" << fileName << ":" << errorString; | - | ||||||||||||
| 358 | pluginState = IsNotAPlugin; | - | ||||||||||||
| 359 | return false; | - | ||||||||||||
| 360 | } | - | ||||||||||||
| 361 | bool QLibrary::isLibrary(const QString &fileName) | - | ||||||||||||
| 362 | { | - | ||||||||||||
| 363 | - | |||||||||||||
| 364 | - | |||||||||||||
| 365 | - | |||||||||||||
| 366 | QString completeSuffix = QFileInfo(fileName).completeSuffix(); | - | ||||||||||||
| 367 | if (completeSuffix.isEmpty()) | - | ||||||||||||
| 368 | return false; | - | ||||||||||||
| 369 | QStringList suffixes = completeSuffix.split(QLatin1Char('.')); | - | ||||||||||||
| 370 | QStringList validSuffixList; | - | ||||||||||||
| 371 | validSuffixList << QLatin1String("so"); | - | ||||||||||||
| 372 | int suffix; | - | ||||||||||||
| 373 | int suffixPos = -1; | - | ||||||||||||
| 374 | for (suffix = 0; suffix < validSuffixList.count() && suffixPos == -1; ++suffix) | - | ||||||||||||
| 375 | suffixPos = suffixes.indexOf(validSuffixList.at(suffix)); | - | ||||||||||||
| 376 | - | |||||||||||||
| 377 | bool valid = suffixPos != -1; | - | ||||||||||||
| 378 | for (int i = suffixPos + 1; i < suffixes.count() && valid; ++i) | - | ||||||||||||
| 379 | if (i != suffixPos) | - | ||||||||||||
| 380 | suffixes.at(i).toInt(&valid); | - | ||||||||||||
| 381 | return valid; | - | ||||||||||||
| 382 | - | |||||||||||||
| 383 | - | |||||||||||||
| 384 | - | |||||||||||||
| 385 | } | - | ||||||||||||
| 386 | - | |||||||||||||
| 387 | typedef const char * (*QtPluginQueryVerificationDataFunction)(); | - | ||||||||||||
| 388 | - | |||||||||||||
| 389 | static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv) | - | ||||||||||||
| 390 | { | - | ||||||||||||
| 391 | const char *szData = 0; | - | ||||||||||||
| 392 | if (!pfn
| 2 | ||||||||||||
| 393 | return executed 2 times by 1 test: false;return false;Executed by:
executed 2 times by 1 test: return false;Executed by:
| 2 | ||||||||||||
| 394 | - | |||||||||||||
| 395 | szData = pfn(); | - | ||||||||||||
| 396 | if (!szData
| 0-2 | ||||||||||||
| 397 | return never executed: false;return false;never executed: return false; | 0 | ||||||||||||
| 398 | - | |||||||||||||
| 399 | QJsonDocument doc = QLibraryPrivate::fromRawMetaDataqJsonFromRawLibraryMetaData(szData); | - | ||||||||||||
| 400 | if (doc.isNull()
| 0-2 | ||||||||||||
| 401 | return never executed: false;return false;never executed: return false; | 0 | ||||||||||||
| 402 | priv->metaData = doc.object(); | - | ||||||||||||
| 403 | return executed 2 times by 1 test: true;return true;Executed by:
executed 2 times by 1 test: return true;Executed by:
| 2 | ||||||||||||
| 404 | } | - | ||||||||||||
| 405 | - | |||||||||||||
| 406 | bool QLibraryPrivate::isPlugin() | - | ||||||||||||
| 407 | { | - | ||||||||||||
| 408 | if (pluginState == MightBeAPlugin) | - | ||||||||||||
| 409 | updatePluginState(); | - | ||||||||||||
| 410 | - | |||||||||||||
| 411 | return pluginState == IsAPlugin; | - | ||||||||||||
| 412 | } | - | ||||||||||||
| 413 | - | |||||||||||||
| 414 | void QLibraryPrivate::updatePluginState() | - | ||||||||||||
| 415 | { | - | ||||||||||||
| 416 | errorString.clear(); | - | ||||||||||||
| 417 | if (pluginState != MightBeAPlugin) | - | ||||||||||||
| 418 | return; | - | ||||||||||||
| 419 | - | |||||||||||||
| 420 | bool success = false; | - | ||||||||||||
| 421 | - | |||||||||||||
| 422 | - | |||||||||||||
| 423 | if (fileName.endsWith(QLatin1String(".debug"))) { | - | ||||||||||||
| 424 | - | |||||||||||||
| 425 | - | |||||||||||||
| 426 | - | |||||||||||||
| 427 | - | |||||||||||||
| 428 | - | |||||||||||||
| 429 | - | |||||||||||||
| 430 | errorString = QLibrary::tr("The shared library was not found."); | - | ||||||||||||
| 431 | pluginState = IsNotAPlugin; | - | ||||||||||||
| 432 | return; | - | ||||||||||||
| 433 | } | - | ||||||||||||
| 434 | - | |||||||||||||
| 435 | - | |||||||||||||
| 436 | if (!pHnd) { | - | ||||||||||||
| 437 | - | |||||||||||||
| 438 | success = findPatternUnloaded(fileName, this); | - | ||||||||||||
| 439 | } else { | - | ||||||||||||
| 440 | - | |||||||||||||
| 441 | - | |||||||||||||
| 442 | QtPluginQueryVerificationDataFunction getMetaData = __null; | - | ||||||||||||
| 443 | getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata"); | - | ||||||||||||
| 444 | success = qt_get_metadata(getMetaData, this); | - | ||||||||||||
| 445 | } | - | ||||||||||||
| 446 | - | |||||||||||||
| 447 | if (!success) { | - | ||||||||||||
| 448 | if (errorString.isEmpty()){ | - | ||||||||||||
| 449 | if (fileName.isEmpty()) | - | ||||||||||||
| 450 | errorString = QLibrary::tr("The shared library was not found."); | - | ||||||||||||
| 451 | else | - | ||||||||||||
| 452 | errorString = QLibrary::tr("The file '%1' is not a valid Qt plugin.").arg(fileName); | - | ||||||||||||
| 453 | } | - | ||||||||||||
| 454 | pluginState = IsNotAPlugin; | - | ||||||||||||
| 455 | return; | - | ||||||||||||
| 456 | } | - | ||||||||||||
| 457 | - | |||||||||||||
| 458 | pluginState = IsNotAPlugin; | - | ||||||||||||
| 459 | - | |||||||||||||
| 460 | uint qt_version = (uint)metaData.value(QLatin1String("version")).toDouble(); | - | ||||||||||||
| 461 | bool debug = metaData.value(QLatin1String("debug")).toBool(); | - | ||||||||||||
| 462 | if ((qt_version & 0x00ff00) > (((5<<16)|(67<<8)|(41)) & 0x00ff00) || (qt_version & 0xff0000) != (((5<<16)|(67<<8)|(41)) & 0xff0000)) { | - | ||||||||||||
| 463 | if (qt_debug_component()) { | - | ||||||||||||
| 464 | QMessageLogger(__FILE__, 743754, __PRETTY_FUNCTION__).warning("In %s:\n" | - | ||||||||||||
| 465 | " Plugin uses incompatible Qt library (%d.%d.%d) [%s]", | - | ||||||||||||
| 466 | (const char*) QFile::encodeName(fileName), | - | ||||||||||||
| 467 | (qt_version&0xff0000) >> 16, (qt_version&0xff00) >> 8, qt_version&0xff, | - | ||||||||||||
| 468 | debug ? "debug" : "release"); | - | ||||||||||||
| 469 | } | - | ||||||||||||
| 470 | errorString = QLibrary::tr("The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5]") | - | ||||||||||||
| 471 | .arg(fileName) | - | ||||||||||||
| 472 | .arg((qt_version&0xff0000) >> 16) | - | ||||||||||||
| 473 | .arg((qt_version&0xff00) >> 8) | - | ||||||||||||
| 474 | .arg(qt_version&0xff) | - | ||||||||||||
| 475 | .arg(debug ? QLatin1String("debug") : QLatin1String("release")); | - | ||||||||||||
| 476 | - | |||||||||||||
| 477 | - | |||||||||||||
| 478 | - | |||||||||||||
| 479 | - | |||||||||||||
| 480 | - | |||||||||||||
| 481 | - | |||||||||||||
| 482 | } else { | - | ||||||||||||
| 483 | pluginState = IsAPlugin; | - | ||||||||||||
| 484 | } | - | ||||||||||||
| 485 | } | - | ||||||||||||
| 486 | bool QLibrary::load() | - | ||||||||||||
| 487 | { | - | ||||||||||||
| 488 | if (!d) | - | ||||||||||||
| 489 | return false; | - | ||||||||||||
| 490 | if (did_load) | - | ||||||||||||
| 491 | return d->pHnd; | - | ||||||||||||
| 492 | did_load = true; | - | ||||||||||||
| 493 | return d->load(); | - | ||||||||||||
| 494 | } | - | ||||||||||||
| 495 | bool QLibrary::unload() | - | ||||||||||||
| 496 | { | - | ||||||||||||
| 497 | if (did_load) { | - | ||||||||||||
| 498 | did_load = false; | - | ||||||||||||
| 499 | return d->unload(); | - | ||||||||||||
| 500 | } | - | ||||||||||||
| 501 | return false; | - | ||||||||||||
| 502 | } | - | ||||||||||||
| 503 | - | |||||||||||||
| 504 | - | |||||||||||||
| 505 | - | |||||||||||||
| 506 | - | |||||||||||||
| 507 | - | |||||||||||||
| 508 | - | |||||||||||||
| 509 | bool QLibrary::isLoaded() const | - | ||||||||||||
| 510 | { | - | ||||||||||||
| 511 | return d && d->pHnd; | - | ||||||||||||
| 512 | } | - | ||||||||||||
| 513 | - | |||||||||||||
| 514 | - | |||||||||||||
| 515 | - | |||||||||||||
| 516 | - | |||||||||||||
| 517 | - | |||||||||||||
| 518 | QLibrary::QLibrary(QObject *parent) | - | ||||||||||||
| 519 | :QObject(parent), d(0), did_load(false) | - | ||||||||||||
| 520 | { | - | ||||||||||||
| 521 | } | - | ||||||||||||
| 522 | QLibrary::QLibrary(const QString& fileName, QObject *parent) | - | ||||||||||||
| 523 | :QObject(parent), d(0), did_load(false) | - | ||||||||||||
| 524 | { | - | ||||||||||||
| 525 | setFileName(fileName); | - | ||||||||||||
| 526 | } | - | ||||||||||||
| 527 | QLibrary::QLibrary(const QString& fileName, int verNum, QObject *parent) | - | ||||||||||||
| 528 | :QObject(parent), d(0), did_load(false) | - | ||||||||||||
| 529 | { | - | ||||||||||||
| 530 | setFileNameAndVersion(fileName, verNum); | - | ||||||||||||
| 531 | } | - | ||||||||||||
| 532 | QLibrary::QLibrary(const QString& fileName, const QString &version, QObject *parent) | - | ||||||||||||
| 533 | :QObject(parent), d(0), did_load(false) | - | ||||||||||||
| 534 | { | - | ||||||||||||
| 535 | setFileNameAndVersion(fileName, version); | - | ||||||||||||
| 536 | } | - | ||||||||||||
| 537 | QLibrary::~QLibrary() | - | ||||||||||||
| 538 | { | - | ||||||||||||
| 539 | if (d) | - | ||||||||||||
| 540 | d->release(); | - | ||||||||||||
| 541 | } | - | ||||||||||||
| 542 | void QLibrary::setFileName(const QString &fileName) | - | ||||||||||||
| 543 | { | - | ||||||||||||
| 544 | QLibrary::LoadHints lh; | - | ||||||||||||
| 545 | if (d) { | - | ||||||||||||
| 546 | lh = d->loadHints(); | - | ||||||||||||
| 547 | d->release(); | - | ||||||||||||
| 548 | d = 0; | - | ||||||||||||
| 549 | did_load = false; | - | ||||||||||||
| 550 | } | - | ||||||||||||
| 551 | d = QLibraryPrivate::findOrCreate(fileName, QString(), lh); | - | ||||||||||||
| 552 | } | - | ||||||||||||
| 553 | - | |||||||||||||
| 554 | QString QLibrary::fileName() const | - | ||||||||||||
| 555 | { | - | ||||||||||||
| 556 | if (d) | - | ||||||||||||
| 557 | return d->qualifiedFileName.isEmpty() ? d->fileName : d->qualifiedFileName; | - | ||||||||||||
| 558 | return QString(); | - | ||||||||||||
| 559 | } | - | ||||||||||||
| 560 | void QLibrary::setFileNameAndVersion(const QString &fileName, int verNum) | - | ||||||||||||
| 561 | { | - | ||||||||||||
| 562 | QLibrary::LoadHints lh; | - | ||||||||||||
| 563 | if (d) { | - | ||||||||||||
| 564 | lh = d->loadHints(); | - | ||||||||||||
| 565 | d->release(); | - | ||||||||||||
| 566 | d = 0; | - | ||||||||||||
| 567 | did_load = false; | - | ||||||||||||
| 568 | } | - | ||||||||||||
| 569 | d = QLibraryPrivate::findOrCreate(fileName, verNum >= 0 ? QString::number(verNum) : QString(), lh); | - | ||||||||||||
| 570 | } | - | ||||||||||||
| 571 | void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &version) | - | ||||||||||||
| 572 | { | - | ||||||||||||
| 573 | QLibrary::LoadHints lh; | - | ||||||||||||
| 574 | if (d) { | - | ||||||||||||
| 575 | lh = d->loadHints(); | - | ||||||||||||
| 576 | d->release(); | - | ||||||||||||
| 577 | d = 0; | - | ||||||||||||
| 578 | did_load = false; | - | ||||||||||||
| 579 | } | - | ||||||||||||
| 580 | d = QLibraryPrivate::findOrCreate(fileName, version, lh); | - | ||||||||||||
| 581 | } | - | ||||||||||||
| 582 | QFunctionPointer QLibrary::resolve(const char *symbol) | - | ||||||||||||
| 583 | { | - | ||||||||||||
| 584 | if (!isLoaded() && !load()) | - | ||||||||||||
| 585 | return 0; | - | ||||||||||||
| 586 | return d->resolve(symbol); | - | ||||||||||||
| 587 | } | - | ||||||||||||
| 588 | QFunctionPointer QLibrary::resolve(const QString &fileName, const char *symbol) | - | ||||||||||||
| 589 | { | - | ||||||||||||
| 590 | QLibrary library(fileName); | - | ||||||||||||
| 591 | return library.resolve(symbol); | - | ||||||||||||
| 592 | } | - | ||||||||||||
| 593 | QFunctionPointer QLibrary::resolve(const QString &fileName, int verNum, const char *symbol) | - | ||||||||||||
| 594 | { | - | ||||||||||||
| 595 | QLibrary library(fileName, verNum); | - | ||||||||||||
| 596 | return library.resolve(symbol); | - | ||||||||||||
| 597 | } | - | ||||||||||||
| 598 | QFunctionPointer QLibrary::resolve(const QString &fileName, const QString &version, const char *symbol) | - | ||||||||||||
| 599 | { | - | ||||||||||||
| 600 | QLibrary library(fileName, version); | - | ||||||||||||
| 601 | return library.resolve(symbol); | - | ||||||||||||
| 602 | } | - | ||||||||||||
| 603 | - | |||||||||||||
| 604 | - | |||||||||||||
| 605 | - | |||||||||||||
| 606 | - | |||||||||||||
| 607 | - | |||||||||||||
| 608 | - | |||||||||||||
| 609 | - | |||||||||||||
| 610 | QString QLibrary::errorString() const | - | ||||||||||||
| 611 | { | - | ||||||||||||
| 612 | return (!d || d->errorString.isEmpty()) ? tr("Unknown error") : d->errorString; | - | ||||||||||||
| 613 | } | - | ||||||||||||
| 614 | void QLibrary::setLoadHints(LoadHints hints) | - | ||||||||||||
| 615 | { | - | ||||||||||||
| 616 | if (!d) { | - | ||||||||||||
| 617 | d = QLibraryPrivate::findOrCreate(QString()); | - | ||||||||||||
| 618 | d->errorString.clear(); | - | ||||||||||||
| 619 | } | - | ||||||||||||
| 620 | d->setLoadHints(hints); | - | ||||||||||||
| 621 | } | - | ||||||||||||
| 622 | - | |||||||||||||
| 623 | QLibrary::LoadHints QLibrary::loadHints() const | - | ||||||||||||
| 624 | { | - | ||||||||||||
| 625 | return d ? d->loadHints() : QLibrary::LoadHints(); | - | ||||||||||||
| 626 | } | - | ||||||||||||
| 627 | - | |||||||||||||
| 628 | - | |||||||||||||
| 629 | bool qt_debug_component() | - | ||||||||||||
| 630 | { | - | ||||||||||||
| 631 | static int debug_env = ::qEnvironmentVariableIntValue("QT_DEBUG_PLUGINS"); | - | ||||||||||||
| 632 | return debug_env != 0; | - | ||||||||||||
| 633 | } | - | ||||||||||||
| 634 | - | |||||||||||||
| 635 | - | |||||||||||||
| Switch to Source code | Preprocessed file |