Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qversiontagging.h
Go to the documentation of this file.
1
// Copyright (C) 2022 Intel Corporation.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
if
!
defined
(
QVERSIONTAGGING_H
)
6
#
define
QVERSIONTAGGING_H
7
8
#
if
0
9
#
pragma
qt_no_master_include
10
#
endif
11
12
#
include
<
QtCore
/
qcompilerdetection
.
h
>
13
#
include
<
QtCore
/
qtconfigmacros
.
h
>
14
#
include
<
QtCore
/
qtversionchecks
.
h
>
15
#
include
<
QtCore
/
qtypes
.
h
>
16
17
QT_REQUIRE_CONFIG
(
version_tagging
);
18
19
QT_BEGIN_NAMESPACE
20
21
/*
22
* Explanation
23
*
24
* This file causes all libraries, plugins, and applications that #include this
25
* file to automatically pull in a symbol found in QtCore that encodes the
26
* current Qt version number at the time of compilation. The relocation is
27
* designed so that it's impossible for the dynamic linker to perform lazy
28
* binding. Instead, it must resolve at load time or fail. That way, attempting
29
* to load such a library or plugin while an older QtCore is loaded will fail.
30
* Similarly, if an older QtCore is found when launching an application, the
31
* application will fail to launch.
32
*
33
* It's also possible to inspect which version is required by decoding the
34
* .qtversion section. The second pointer-sized variable is the required
35
* version, for example, for Qt 6.4.1:
36
*
37
* Hex dump of section [18] '.qtversion', 16 bytes at offset 0x1ee48:
38
* 0x00000000 b0ffffff ffffffff 01040600 00000000 ................
39
* ^^^^^^^^ ^^^^^^^^
40
*
41
* There will only be one copy of the section in the output library or application.
42
*
43
* This functionality can be disabled by defining QT_NO_VERSION_TAGGING. It's
44
* disabled if Qt was built statically.
45
*
46
* Windows notes:
47
*
48
* On Windows, the address of a __declspec(dllimport) variable is not a
49
* constant expression, unlike Unix systems. So we instead use the address of
50
* the import variable, which is created by prefixing the external name with
51
* "__imp_". Using that variable causes an import of the corresponding symbol
52
* from QtCore DLL.
53
*
54
* With MinGW (GCC and Clang), we use a C++17 inline variable, so the compiler
55
* and linker automatically merge the variables. The "used" __attribute__
56
* tells the compiler to always emit that variable, whether it's used or not.
57
*
58
* MSVC has no equivalent to that attribute, so instead we create an extern
59
* const variable and tell the linker to merge them all via
60
* __declspec(selectany).
61
*
62
* Unix notes:
63
*
64
* On Unix, we use the same C++17 inline variable solution as MinGW, but we
65
* don't need the "__imp_" trick.
66
*
67
* Additionally, on ELF systems like Linux and FreeBSD, the symbol in question
68
* is simply "qt_version_tag" in both QtCore and in this ELF module, but it
69
* has an ELF version attached to it (see qversiontagging.cpp and
70
* QtFlagHandlingHelpers.cmake). That way, the error message from the dynamic
71
* linker will say it can't find version "Qt_6.x".
72
*/
73
74
namespace
QtPrivate
{
75
struct
QVersionTag
76
{
77
const
void
*
symbol
;
78
quintptr
version
;
79
constexpr
QVersionTag
(
const
void
*sym,
int
currentVersion =
QT_VERSION
)
80
:
symbol
(sym),
version
(
currentVersion
)
81
{}
82
};
83
}
84
85
#
if
!
defined
(
QT_NO_VERSION_TAGGING
)
&&
(
defined
(
QT_BUILD_CORE_LIB
)
||
defined
(
QT_BOOTSTRAPPED
)
||
defined
(
QT_STATIC
)
)
86
// don't make tags in QtCore, bootstrapped systems or if the user asked not to
87
#
define
QT_NO_VERSION_TAGGING
88
#
endif
89
90
#
if
defined
(
Q_OS_WIN
)
91
#
ifdef
Q_PROCESSOR_X86_32
92
// 32-bit x86 convention does prepend a _
93
#
define
QT_MANGLE_IMPORT_PREFIX
_imp__
94
#
else
95
// Calling convention on other architectures does not prepend a _
96
#
define
QT_MANGLE_IMPORT_PREFIX
__imp_
97
#
endif
98
#
if
defined
(
Q_CC_MSVC_ONLY
)
99
#
pragma
section
(
".qtversion"
,
read
,
shared
)
100
#
define
QT_VERSION_TAG_SECTION
__declspec
(
allocate
(
".qtversion"
)
)
101
#
define
QT_VERSION_TAG_ATTRIBUTE
__declspec
(
selectany
)
extern
const
102
#
else
103
#
define
QT_VERSION_TAG_ATTRIBUTE
__attribute__
(
(
used
)
)
constexpr
inline
104
#
endif
105
#
define
QT_VERSION_TAG2
(
sym
,
imp
)
106
extern
"C"
const
char
*
const
imp
;
107
QT_VERSION_TAG_ATTRIBUTE
QT_VERSION_TAG_SECTION
QtPrivate
::
QVersionTag
sym
##
_used
(
&
imp
)
108
#
define
QT_VERSION_TAG
(
sym
,
imp
)
QT_VERSION_TAG2
(
sym
,
imp
)
109
#
elif
defined
(
Q_CC_GNU
)
&&
__has_attribute
(
used
)
110
#
ifdef
Q_OS_DARWIN
111
#
define
QT_VERSION_TAG_SECTION
__attribute__
(
(
section
(
"__DATA,.qtversion"
)
)
)
112
#
endif
113
#
define
QT_VERSION_TAG_ATTRIBUTE
__attribute__
(
(
visibility
(
"hidden"
)
,
used
)
)
114
#
define
QT_VERSION_TAG2
(
sym
,
imp
)
115
extern
"C"
Q_DECL_IMPORT
const
char
sym
;
116
QT_VERSION_TAG_ATTRIBUTE
QT_VERSION_TAG_SECTION
constexpr
inline
QtPrivate
::
QVersionTag
sym
##
_use
(
&
sym
)
117
#
define
QT_VERSION_TAG
(
sym
,
imp
)
QT_VERSION_TAG2
(
sym
,
imp
)
118
#
endif
119
120
#
ifdef
Q_OF_ELF
121
#
define
QT_VERSION_TAG_SYMBOL
(
prefix
,
sym
,
m
,
n
)
sym
122
#
else
123
#
define
QT_VERSION_TAG_SYMBOL2
(
prefix
,
sym
,
m
,
n
)
prefix
##
sym
##
_
##
m
##
_
##
n
124
#
define
QT_VERSION_TAG_SYMBOL
(
prefix
,
sym
,
m
,
n
)
QT_VERSION_TAG_SYMBOL2
(
prefix
,
sym
,
m
,
n
)
125
#
endif
126
127
#
if
defined
(
QT_VERSION_TAG
)
&&
!
defined
(
QT_NO_VERSION_TAGGING
)
128
#
ifndef
QT_VERSION_TAG_SECTION
129
#
define
QT_VERSION_TAG_SECTION
__attribute__
(
(
section
(
".qtversion"
)
)
)
130
#
endif
131
#
define
QT_MANGLED_VERSION_TAG_IMPORT
QT_VERSION_TAG_SYMBOL
(
QT_MANGLE_IMPORT_PREFIX
,
QT_MANGLE_NAMESPACE
(
qt_version_tag
)
,
QT_VERSION_MAJOR
,
QT_VERSION_MINOR
)
132
#
define
QT_MANGLED_VERSION_TAG
QT_VERSION_TAG_SYMBOL
(
,
QT_MANGLE_NAMESPACE
(
qt_version_tag
)
,
QT_VERSION_MAJOR
,
QT_VERSION_MINOR
)
133
134
QT_VERSION_TAG(QT_MANGLED_VERSION_TAG, QT_MANGLED_VERSION_TAG_IMPORT);
135
136
#
undef
QT_MANGLED_VERSION_TAG
137
#
undef
QT_MANGLED_VERSION_TAG_IMPORT
138
#
undef
QT_VERSION_TAG_SECTION
139
#
endif
140
141
QT_END_NAMESPACE
142
143
#
endif
// QVERSIONTAGGING_H
QtPrivate
Definition
qalloc.h:29
__has_attribute
#define __has_attribute(x)
Definition
qcompilerdetection.h:450
make_versioned_symbol
#define make_versioned_symbol(sym, m, n, separator)
Definition
qversiontagging.cpp:40
SSYM
#define SSYM
Definition
qversiontagging.cpp:10
make_versioned_symbol2
#define make_versioned_symbol2(sym, m, n, separator)
Definition
qversiontagging.cpp:37
SYM
#define SYM
Definition
qversiontagging.cpp:9
QT_REQUIRE_CONFIG
QT_REQUIRE_CONFIG(version_tagging)
QT_VERSION_TAG_SYMBOL2
#define QT_VERSION_TAG_SYMBOL2(prefix, sym, m, n)
Definition
qversiontagging.h:123
QtPrivate::QVersionTag
Definition
qversiontagging.h:76
QtPrivate::QVersionTag::version
quintptr version
Definition
qversiontagging.h:78
QtPrivate::QVersionTag::symbol
const void * symbol
Definition
qversiontagging.h:77
QtPrivate::QVersionTag::QVersionTag
constexpr QVersionTag(const void *sym, int currentVersion=QT_VERSION)
Definition
qversiontagging.h:79
qtbase
src
corelib
global
qversiontagging.h
Generated on
for Qt by
1.18.0