Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:07:33

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