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 block Executed 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 block Executed by:
| 676 | ||||||||||||
93 | } executed 677 times by 111 tests: end of block Executed 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 block Executed 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 |