Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qplugin.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2021 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6#ifndef QPLUGIN_H
7#define QPLUGIN_H
8
9#if 0
10#pragma qt_class(QtPlugin)
11#endif
12
13#include <QtCore/qobject.h>
14#include <QtCore/qpointer.h>
15#include <QtCore/qjsonobject.h>
16
17#include <QtCore/q20algorithm.h>
18
20
21// Used up to Qt 6.2
22inline constexpr unsigned char qPluginArchRequirements()
23{
24 return 0
25#ifndef QT_NO_DEBUG
26 | 1
27#endif
28#ifdef __AVX2__
29 | 2
30# ifdef __AVX512F__
31 | 4
32# endif
33#endif
34 ;
35}
36
39{
40 static constexpr quint8 CurrentMetaDataVersion = 1;
41 static constexpr char MagicString[] = {
42 'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!'
43 };
44
45 template <size_t OSize, typename OO, size_t ISize, typename II>
46 static constexpr void copy(OO (&out)[OSize], II (&in)[ISize])
47 {
48 static_assert(OSize <= ISize, "Output would not be fully initialized");
49 q20::copy_n(in, OSize, out);
50 }
51
52 static constexpr quint8 archRequirements()
53 {
54 quint8 v = 0;
55#if defined(__AVX512F__)
56 v = 4; // x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ and AVX512VL
57#elif defined(__AVX__) || defined(__BMI__) || defined(__BMI2__) || defined(__MOVBE__)
58 v = 3; // x86-64-v3: AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE
59#elif defined(__SSE3__)
60 v = 2; // x86-64-v2: POPCNT, SSE3, SSSE3, SSE4.1 and SSE4.2.
61#elif defined(__SSE__) || defined(__MMX___)
62 v = 1; // x86-64 baseline: SSE and SSE2
63#endif
64#ifndef QT_NO_DEBUG
65 v |= 0x80;
66#endif
67 return v;
68 }
69
76 static_assert(alignof(Header) == 1, "Alignment of header incorrect with this compiler");
77
83 static_assert(alignof(MagicHeader) == 1, "Alignment of header incorrect with this compiler");
84
86 static constexpr quint32 NoteType = 0x74510001;
87 static constexpr char NoteName[] = "qt-project!";
88
89 // ELF note header
93 char name[sizeof(NoteName)] = {};
94
95 // payload
96 alignas(void *) // mandatory alignment as per ELF note requirements
98 constexpr ElfNoteHeader(quint32 payloadSize) : n_descsz(sizeof(header) + payloadSize)
99 { QPluginMetaData::copy(name, NoteName); }
100 };
101 static_assert(alignof(ElfNoteHeader) == alignof(void*), "Alignment of header incorrect with this compiler");
102 static_assert((sizeof(ElfNoteHeader::name) % 4) == 0, "ELF note name length not a multiple of 4");
103
104 const void *data;
106};
107typedef QPluginMetaData (*QtPluginMetaDataFunction)();
108
109
110struct Q_CORE_EXPORT QStaticPlugin
111{
112public:
113 constexpr QStaticPlugin(QtPluginInstanceFunction i, QtPluginMetaDataFunction m)
114 : instance(i), rawMetaDataSize(m().size), rawMetaData(m().data)
115 {}
116 QtPluginInstanceFunction instance;
117 QJsonObject metaData() const;
118
119private:
120 qsizetype rawMetaDataSize;
121 const void *rawMetaData;
122 friend class QFactoryLoader;
123};
124Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);
125
126void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
127
128#if defined(Q_OF_ELF) || (defined(Q_OS_WIN) && (defined (Q_CC_GNU) || defined(Q_CC_CLANG)))
129# define QT_PLUGIN_METADATA_SECTION
130 __attribute__ ((section (".qtmetadata"))) __attribute__((used))
131#elif defined(Q_OS_DARWIN)
132# define QT_PLUGIN_METADATA_SECTION
133 __attribute__ ((section ("__TEXT,qtmetadata"))) __attribute__((used))
134#elif defined(Q_CC_MSVC)
135// TODO: Implement section parsing for MSVC
136#pragma section(".qtmetadata",read,shared)
137# define QT_PLUGIN_METADATA_SECTION
138 __declspec(allocate(".qtmetadata"))
139#else
140# define QT_PLUGIN_METADATA_SECTION
141#endif
142
143// Since Qt 6.3
144template <auto (&PluginMetaData)> class QPluginMetaDataV2
145{
146 struct ElfNotePayload : QPluginMetaData::ElfNoteHeader {
147 static constexpr size_t HeaderOffset = offsetof(QPluginMetaData::ElfNoteHeader, header);
148 quint8 payload[sizeof(PluginMetaData)] = {};
149 constexpr ElfNotePayload() : ElfNoteHeader(sizeof(PluginMetaData))
150 { QPluginMetaData::copy(payload, PluginMetaData); }
151 };
152
153 struct RegularPayload : QPluginMetaData::MagicHeader {
154 static constexpr size_t HeaderOffset = offsetof(QPluginMetaData::MagicHeader, header);
155 quint8 payload[sizeof(PluginMetaData)] = {};
156 constexpr RegularPayload() { QPluginMetaData::copy(payload, PluginMetaData); }
157 };
158
159 struct StaticPayload {
160 static constexpr size_t HeaderOffset = 0;
161 QPluginMetaData::Header header = {};
162 quint8 payload[sizeof(PluginMetaData)] = {};
163 constexpr StaticPayload() { QPluginMetaData::copy(payload, PluginMetaData); }
164 };
165
166#if defined(QT_STATICPLUGIN)
167# define QT_PLUGIN_METADATAV2_SECTION
168 using Payload = StaticPayload;
169#elif defined(Q_OF_ELF)
170# ifdef Q_CC_CLANG
171# define QT_PLUGIN_METADATAV2_SECTION
172 __attribute__((section(".note.qt.metadata"), used, aligned(alignof(void *)),
173 no_sanitize("address")))
174# else
175# define QT_PLUGIN_METADATAV2_SECTION
176 __attribute__((section(".note.qt.metadata"), used, aligned(alignof(void *))))
177# endif
178 using Payload = ElfNotePayload;
179#else
180# define QT_PLUGIN_METADATAV2_SECTION QT_PLUGIN_METADATA_SECTION
181 using Payload = RegularPayload;
182#endif
183
184 Payload payload = {};
185
186public:
188 {
189 Q_ASSERT(reinterpret_cast<const char *>(&payload) + Payload::HeaderOffset ==
190 reinterpret_cast<const char *>(&payload.header));
191 return { &payload.header, sizeof(payload) - Payload::HeaderOffset };
192 }
193};
194
195#define Q_IMPORT_PLUGIN(PLUGIN)
196 extern const QT_PREPEND_NAMESPACE(QStaticPlugin) QT_MANGLE_NAMESPACE(qt_static_plugin_##PLUGIN)();
197 namespace {
198 struct Static##PLUGIN##PluginInstance {
199 Static##PLUGIN##PluginInstance() {
200 qRegisterStaticPluginFunction(QT_MANGLE_NAMESPACE(qt_static_plugin_##PLUGIN)());
201 }
202 };
203 } /* namespace */
204 /* QTBUG-139615: static, to work around bug in clazy-non-pod-global-static */
205 static Static##PLUGIN##PluginInstance static##PLUGIN##Instance;
206
207#if defined(QT_PLUGIN_RESOURCE_INIT_FUNCTION)
208# define QT_PLUGIN_RESOURCE_INIT
209 extern void QT_PLUGIN_RESOURCE_INIT_FUNCTION();
210 QT_PLUGIN_RESOURCE_INIT_FUNCTION();
211#else
212# define QT_PLUGIN_RESOURCE_INIT
213#endif
214
215#define Q_PLUGIN_INSTANCE(IMPLEMENTATION)
216 {
217 static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance;
218 if (!_instance) {
220 _instance = new IMPLEMENTATION;
221 }
222 return _instance;
223 }
224
225#if defined(QT_STATICPLUGIN)
226# define QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
227 static QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance_##MANGLEDNAME()
228 Q_PLUGIN_INSTANCE(PLUGINCLASS)
229 const QT_PREPEND_NAMESPACE(QStaticPlugin) QT_MANGLE_NAMESPACE(qt_static_plugin_##MANGLEDNAME)()
230 { return { qt_plugin_instance_##MANGLEDNAME, qt_plugin_query_metadata_##MANGLEDNAME}; }
231 /**/
232
233# define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME)
234 static QPluginMetaData qt_plugin_query_metadata_##PLUGINCLASSNAME()
235 { return { qt_pluginMetaData_##PLUGINCLASSNAME, sizeof qt_pluginMetaData_##PLUGINCLASSNAME }; }
236 QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, PLUGINCLASSNAME)
237
238# define QT_MOC_EXPORT_PLUGIN_V2(PLUGINCLASS, MANGLEDNAME, MD)
239 static QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata_##MANGLEDNAME()
240 { static constexpr QPluginMetaDataV2<MD> md{}; return md; }
241 QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
242#else
243# define QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
244 extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance()
245 Q_PLUGIN_INSTANCE(PLUGINCLASS)
246 /**/
247
248# define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME)
249 extern "C" Q_DECL_EXPORT
250 QPluginMetaData qt_plugin_query_metadata()
251 { return { qt_pluginMetaData_##PLUGINCLASSNAME, sizeof qt_pluginMetaData_##PLUGINCLASSNAME }; }
252 QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, PLUGINCLASSNAME)
253
254# define QT_MOC_EXPORT_PLUGIN_V2(PLUGINCLASS, MANGLEDNAME, MD)
255 extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata_v2()
256 { static constexpr QT_PLUGIN_METADATAV2_SECTION QPluginMetaDataV2<MD> md{}; return md; }
257 QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
258#endif
259
260#define Q_EXPORT_PLUGIN(PLUGIN)
261 Q_EXPORT_PLUGIN2(PLUGIN, PLUGIN)
262# define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS)
263 static_assert(false, "Old plugin system used")
264
265# define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS)
266 static_assert(false, "Old plugin system used")
267
268
269QT_END_NAMESPACE
270
271#endif // Q_PLUGIN_H
\inmodule QtCore\reentrant
void setExtraSearchPath(const QString &path)
int indexOf(const QString &needle) const
QMultiMap< int, QString > keyMap() const
MetaDataList metaData() const
QList< QCborArray > metaDataKeys() const
QObject * instance(int index) const
operator QPluginMetaData() const
Definition qplugin.h:187
Combined button and popup list for selecting options.
Q_DECLARE_TYPEINFO(QByteArrayView, Q_PRIMITIVE_TYPE)
QT_REQUIRE_CONFIG(cborstreamreader)
Q_TRACE_POINT(qtcore, QFactoryLoader_update, const QString &fileName)
static bool isIidMatch(QByteArrayView raw, QLatin1StringView iid)
static IterationResult iterateInPluginMetaData(QByteArrayView raw, F &&f)
PluginInterface * qLoadPlugin(const QFactoryLoader *loader, const QString &key, Args &&...args)
#define Q_PLUGIN_INSTANCE(IMPLEMENTATION)
Definition qplugin.h:215
#define QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
Definition qplugin.h:243
QT_BEGIN_NAMESPACE constexpr unsigned char qPluginArchRequirements()
Definition qplugin.h:22
#define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS)
Definition qplugin.h:262
#define QT_PLUGIN_RESOURCE_INIT
Definition qplugin.h:212
#define QT_PLUGIN_METADATAV2_SECTION
Definition qplugin.h:180
QObject *(* QtPluginInstanceFunction)()
Definition qplugin.h:37
#define QT_PLUGIN_METADATA_SECTION
Definition qplugin.h:140
char name[sizeof(NoteName)]
Definition qplugin.h:93
constexpr ElfNoteHeader(quint32 payloadSize)
Definition qplugin.h:98
static constexpr quint32 NoteType
Definition qplugin.h:86
static constexpr char NoteName[]
Definition qplugin.h:87
quint8 plugin_arch_requirements
Definition qplugin.h:74
char magic[sizeof(QPluginMetaData::MagicString)]
Definition qplugin.h:79
static constexpr void copy(OO(&out)[OSize], II(&in)[ISize])
Definition qplugin.h:46
const void * data
Definition qplugin.h:104
static constexpr quint8 CurrentMetaDataVersion
Definition qplugin.h:40
static constexpr quint8 archRequirements()
Definition qplugin.h:52
static constexpr char MagicString[]
Definition qplugin.h:41
\inmodule QtCore
Definition qplugin.h:111