Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-23 09:21:58

0001 // Copyright (C) 2020 The Qt Company Ltd.
0002 // Copyright (C) 2021 Intel Corporation.
0003 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0004 // Qt-Security score:significant reason:default
0005 
0006 #ifndef QPLUGIN_H
0007 #define QPLUGIN_H
0008 
0009 #if 0
0010 #pragma qt_class(QtPlugin)
0011 #endif
0012 
0013 #include <QtCore/qobject.h>
0014 #include <QtCore/qpointer.h>
0015 #include <QtCore/qjsonobject.h>
0016 
0017 #include <QtCore/q20algorithm.h>
0018 
0019 QT_BEGIN_NAMESPACE
0020 
0021 // Used up to Qt 6.2
0022 inline constexpr unsigned char qPluginArchRequirements()
0023 {
0024     return 0
0025 #ifndef QT_NO_DEBUG
0026             | 1
0027 #endif
0028 #ifdef __AVX2__
0029             | 2
0030 #  ifdef __AVX512F__
0031             | 4
0032 #  endif
0033 #endif
0034     ;
0035 }
0036 
0037 typedef QObject *(*QtPluginInstanceFunction)();
0038 struct QPluginMetaData
0039 {
0040     static constexpr quint8 CurrentMetaDataVersion = 1;
0041     static constexpr char MagicString[] = {
0042         'Q', 'T', 'M', 'E', 'T', 'A', 'D', 'A', 'T', 'A', ' ', '!'
0043     };
0044 
0045     template <size_t OSize, typename OO, size_t ISize, typename II>
0046     static constexpr void copy(OO (&out)[OSize], II (&in)[ISize])
0047     {
0048         static_assert(OSize <= ISize, "Output would not be fully initialized");
0049         q20::copy_n(in, OSize, out);
0050     }
0051 
0052     static constexpr quint8 archRequirements()
0053     {
0054         quint8 v = 0;
0055 #if defined(__AVX512F__)
0056         v = 4;      // x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ and AVX512VL
0057 #elif defined(__AVX__) || defined(__BMI__) || defined(__BMI2__) || defined(__MOVBE__)
0058         v = 3;      // x86-64-v3: AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE
0059 #elif defined(__SSE3__)
0060         v = 2;      // x86-64-v2: POPCNT, SSE3, SSSE3, SSE4.1 and SSE4.2.
0061 #elif defined(__SSE__) || defined(__MMX___)
0062         v = 1;      // x86-64 baseline: SSE and SSE2
0063 #endif
0064 #ifndef QT_NO_DEBUG
0065         v |= 0x80;
0066 #endif
0067         return v;
0068     }
0069 
0070     struct Header {
0071         quint8 version = CurrentMetaDataVersion;
0072         quint8 qt_major_version = QT_VERSION_MAJOR;
0073         quint8 qt_minor_version = QT_VERSION_MINOR;
0074         quint8 plugin_arch_requirements = archRequirements();
0075     };
0076     static_assert(alignof(Header) == 1, "Alignment of header incorrect with this compiler");
0077 
0078     struct MagicHeader {
0079         char magic[sizeof(QPluginMetaData::MagicString)] = {};
0080         constexpr MagicHeader()     { copy(magic, QPluginMetaData::MagicString); }
0081         Header header = {};
0082     };
0083     static_assert(alignof(MagicHeader) == 1, "Alignment of header incorrect with this compiler");
0084 
0085     struct ElfNoteHeader {
0086         static constexpr quint32 NoteType = 0x74510001;
0087         static constexpr char NoteName[] = "qt-project!";
0088 
0089         // ELF note header
0090         quint32 n_namesz = sizeof(name);
0091         quint32 n_descsz;
0092         quint32 n_type = NoteType;
0093         char name[sizeof(NoteName)] = {};
0094 
0095         // payload
0096         alignas(void *)         // mandatory alignment as per ELF note requirements
0097         Header header = {};
0098         constexpr ElfNoteHeader(quint32 payloadSize) : n_descsz(sizeof(header) + payloadSize)
0099         { QPluginMetaData::copy(name, NoteName); }
0100     };
0101     static_assert(alignof(ElfNoteHeader) == alignof(void*), "Alignment of header incorrect with this compiler");
0102     static_assert((sizeof(ElfNoteHeader::name) % 4) == 0, "ELF note name length not a multiple of 4");
0103 
0104     const void *data;
0105     size_t size;
0106 };
0107 typedef QPluginMetaData (*QtPluginMetaDataFunction)();
0108 
0109 
0110 struct Q_CORE_EXPORT QStaticPlugin
0111 {
0112 public:
0113     constexpr QStaticPlugin(QtPluginInstanceFunction i, QtPluginMetaDataFunction m)
0114         : instance(i), rawMetaDataSize(m().size), rawMetaData(m().data)
0115     {}
0116     QtPluginInstanceFunction instance;
0117     QJsonObject metaData() const;
0118 
0119 private:
0120     qsizetype rawMetaDataSize;
0121     const void *rawMetaData;
0122     friend class QFactoryLoader;
0123 };
0124 Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);
0125 
0126 void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
0127 
0128 #if defined(Q_OF_ELF) || (defined(Q_OS_WIN) && (defined (Q_CC_GNU) || defined(Q_CC_CLANG)))
0129 #  define QT_PLUGIN_METADATA_SECTION \
0130     __attribute__ ((section (".qtmetadata"))) __attribute__((used))
0131 #elif defined(Q_OS_DARWIN)
0132 #  define QT_PLUGIN_METADATA_SECTION \
0133     __attribute__ ((section ("__TEXT,qtmetadata"))) __attribute__((used))
0134 #elif defined(Q_CC_MSVC)
0135 // TODO: Implement section parsing for MSVC
0136 #pragma section(".qtmetadata",read,shared)
0137 #  define QT_PLUGIN_METADATA_SECTION \
0138     __declspec(allocate(".qtmetadata"))
0139 #else
0140 #  define QT_PLUGIN_METADATA_SECTION
0141 #endif
0142 
0143 // Since Qt 6.3
0144 template <auto (&PluginMetaData)> class QPluginMetaDataV2
0145 {
0146     struct ElfNotePayload : QPluginMetaData::ElfNoteHeader {
0147         static constexpr size_t HeaderOffset = offsetof(QPluginMetaData::ElfNoteHeader, header);
0148         quint8 payload[sizeof(PluginMetaData)] = {};
0149         constexpr ElfNotePayload() : ElfNoteHeader(sizeof(PluginMetaData))
0150         { QPluginMetaData::copy(payload, PluginMetaData); }
0151     };
0152 
0153     struct RegularPayload : QPluginMetaData::MagicHeader {
0154         static constexpr size_t HeaderOffset = offsetof(QPluginMetaData::MagicHeader, header);
0155         quint8 payload[sizeof(PluginMetaData)] = {};
0156         constexpr RegularPayload() { QPluginMetaData::copy(payload, PluginMetaData); }
0157     };
0158 
0159     struct StaticPayload {
0160         static constexpr size_t HeaderOffset = 0;
0161         QPluginMetaData::Header header = {};
0162         quint8 payload[sizeof(PluginMetaData)] = {};
0163         constexpr StaticPayload() { QPluginMetaData::copy(payload, PluginMetaData); }
0164     };
0165 
0166 #if defined(QT_STATICPLUGIN)
0167 #  define QT_PLUGIN_METADATAV2_SECTION
0168     using Payload = StaticPayload;
0169 #elif defined(Q_OF_ELF)
0170 #  ifdef Q_CC_CLANG
0171 #    define QT_PLUGIN_METADATAV2_SECTION                                                            \
0172             __attribute__((section(".note.qt.metadata"), used, aligned(alignof(void *)),            \
0173                            no_sanitize("address")))
0174 #  else
0175 #    define QT_PLUGIN_METADATAV2_SECTION                                                            \
0176             __attribute__((section(".note.qt.metadata"), used, aligned(alignof(void *))))
0177 #  endif
0178     using Payload = ElfNotePayload;
0179 #else
0180 #  define QT_PLUGIN_METADATAV2_SECTION      QT_PLUGIN_METADATA_SECTION
0181     using Payload = RegularPayload;
0182 #endif
0183 
0184     Payload payload = {};
0185 
0186 public:
0187     operator QPluginMetaData() const
0188     {
0189         Q_ASSERT(reinterpret_cast<const char *>(&payload) + Payload::HeaderOffset ==
0190                  reinterpret_cast<const char *>(&payload.header));
0191         return { &payload.header, sizeof(payload) - Payload::HeaderOffset };
0192     }
0193 };
0194 
0195 #define Q_IMPORT_PLUGIN(PLUGIN)                                                                            \
0196         extern const QT_PREPEND_NAMESPACE(QStaticPlugin) QT_MANGLE_NAMESPACE(qt_static_plugin_##PLUGIN)(); \
0197         namespace {                                                                                        \
0198             struct Static##PLUGIN##PluginInstance {                                                        \
0199                 Static##PLUGIN##PluginInstance() {                                                         \
0200                     qRegisterStaticPluginFunction(QT_MANGLE_NAMESPACE(qt_static_plugin_##PLUGIN)());       \
0201                 }                                                                                          \
0202             };                                                                                             \
0203         } /* namespace */                                                                                  \
0204         /* QTBUG-139615: static, to work around bug in clazy-non-pod-global-static */                      \
0205         static Static##PLUGIN##PluginInstance static##PLUGIN##Instance;                                    \
0206 
0207 #if defined(QT_PLUGIN_RESOURCE_INIT_FUNCTION)
0208 #  define QT_PLUGIN_RESOURCE_INIT \
0209           extern void QT_PLUGIN_RESOURCE_INIT_FUNCTION(); \
0210           QT_PLUGIN_RESOURCE_INIT_FUNCTION();
0211 #else
0212 #  define QT_PLUGIN_RESOURCE_INIT
0213 #endif
0214 
0215 #define Q_PLUGIN_INSTANCE(IMPLEMENTATION) \
0216         { \
0217             static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance; \
0218             if (!_instance) {    \
0219                 QT_PLUGIN_RESOURCE_INIT \
0220                 _instance = new IMPLEMENTATION; \
0221             } \
0222             return _instance; \
0223         }
0224 
0225 #if defined(QT_STATICPLUGIN)
0226 #  define QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)                                     \
0227     static QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance_##MANGLEDNAME()                        \
0228     Q_PLUGIN_INSTANCE(PLUGINCLASS)                                                                  \
0229     const QT_PREPEND_NAMESPACE(QStaticPlugin) QT_MANGLE_NAMESPACE(qt_static_plugin_##MANGLEDNAME)() \
0230     { return { qt_plugin_instance_##MANGLEDNAME, qt_plugin_query_metadata_##MANGLEDNAME}; }         \
0231     /**/
0232 
0233 #  define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME) \
0234     static QPluginMetaData qt_plugin_query_metadata_##PLUGINCLASSNAME() \
0235         { return { qt_pluginMetaData_##PLUGINCLASSNAME, sizeof qt_pluginMetaData_##PLUGINCLASSNAME }; } \
0236     QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, PLUGINCLASSNAME)
0237 
0238 #  define QT_MOC_EXPORT_PLUGIN_V2(PLUGINCLASS, MANGLEDNAME, MD)                                 \
0239     static QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata_##MANGLEDNAME()       \
0240     { static constexpr QPluginMetaDataV2<MD> md{}; return md; }                                 \
0241     QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
0242 #else
0243 #  define QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)                                 \
0244     extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance()                \
0245     Q_PLUGIN_INSTANCE(PLUGINCLASS)                                                              \
0246     /**/
0247 
0248 #  define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME)      \
0249             extern "C" Q_DECL_EXPORT \
0250             QPluginMetaData qt_plugin_query_metadata() \
0251             { return { qt_pluginMetaData_##PLUGINCLASSNAME, sizeof qt_pluginMetaData_##PLUGINCLASSNAME }; } \
0252             QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, PLUGINCLASSNAME)
0253 
0254 #  define QT_MOC_EXPORT_PLUGIN_V2(PLUGINCLASS, MANGLEDNAME, MD)                                 \
0255     extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata_v2()\
0256     { static constexpr QT_PLUGIN_METADATAV2_SECTION QPluginMetaDataV2<MD> md{}; return md; }    \
0257     QT_MOC_EXPORT_PLUGIN_COMMON(PLUGINCLASS, MANGLEDNAME)
0258 #endif
0259 
0260 #define Q_EXPORT_PLUGIN(PLUGIN) \
0261             Q_EXPORT_PLUGIN2(PLUGIN, PLUGIN)
0262 #  define Q_EXPORT_PLUGIN2(PLUGIN, PLUGINCLASS)      \
0263     static_assert(false, "Old plugin system used")
0264 
0265 #  define Q_EXPORT_STATIC_PLUGIN2(PLUGIN, PLUGINCLASS) \
0266     static_assert(false, "Old plugin system used")
0267 
0268 
0269 QT_END_NAMESPACE
0270 
0271 #endif // Q_PLUGIN_H