libqt5-qtbase/Add-an-automatic-use-of-the-ELF-versioned-QtCore-symbol.patch

146 lines
5.6 KiB
Diff

From 7a2d2a1c3b66308cf03a00757f8fd97f043ccde4 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
Date: Tue, 2 Jun 2015 11:30:57 -0700
Subject: [PATCH] Add an automatic use of the ELF-versioned QtCore symbol
See the comment in the header for an explanation of what it does.
This trick is enabled for every single .o that is compiled, unless
QT_NO_VERSION_TAGGING is defined. The assembly expands to a COMDAT
section, which is mergeable by the linker, so only one copy of the
output is present in the ELF module.
The next commit will add a configure-time option to set
QT_NO_VERSION_TAGGING to qconfig.h.
This is enabled only for Linux and x86 / x86-64 / x32 due to the
requirement of writing assembly and relocations, so it needs to be
tested on each platform, which I have not done. It probably works on the
BSDs too and might work on Solaris/x86, but again it requires
testing. Support for other architectures requires different assembly
output and relocations and can be added as needed, but they are not as
important since this trick is has most value on desktop systems.
Change-Id: I049a653beeb5454c9539ffff13e3ff5782a8cb86
---
src/corelib/global/global.pri | 3 +-
src/corelib/global/qglobal.h | 1 +
src/corelib/global/qversiontagging.h | 80 ++++++++++++++++++++++++++++++++++++
3 files changed, 83 insertions(+), 1 deletion(-)
create mode 100644 src/corelib/global/qversiontagging.h
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index fdbebca..9f31fb9 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -17,7 +17,8 @@ HEADERS += \
global/qisenum.h \
global/qtypetraits.h \
global/qflags.h \
- global/qhooks_p.h
+ global/qhooks_p.h \
+ global/qversiontagging.h
SOURCES += \
global/archdetect.cpp \
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index c4e2f76..e7995ac 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1103,6 +1103,7 @@ QT_END_NAMESPACE
#include <QtCore/qatomic.h>
#include <QtCore/qglobalstatic.h>
#include <QtCore/qnumeric.h>
+#include <QtCore/qversiontagging.h>
#endif /* __cplusplus */
diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h
new file mode 100644
index 0000000..94246dd
--- /dev/null
+++ b/src/corelib/global/qversiontagging.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// qglobal.h includes this header, so keep it outside of our include guards
+#include <QtCore/qglobal.h>
+
+#if !defined(QVERSIONTAGGING_H) && !defined(QT_NO_VERSION_TAGGING)
+#define QVERSIONTAGGING_H
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * Ugly hack warning and explanation:
+ *
+ * This file causes all ELF modules, be they libraries or applications, to use the
+ * qt_version_tag symbol that is present in QtCore. Such symbol is versioned,
+ * so the linker will automatically pull the current Qt version and add it to
+ * the ELF header of the library/application. The assembly produces one section
+ * called ".qtversion" containing two pointer-sized values. The first is a
+ * relocation to the qt_version_tag symbol (which is what causes the ELF
+ * version to get used). The second value is the current Qt version at the time
+ * of compilation.
+ *
+ * There will only be one copy of the section in the output library or application.
+ */
+
+#if defined(QT_BUILD_CORE_LIB)
+// skip
+#elif defined(Q_CC_GNU)
+# if defined(Q_PROCESSOR_X86) && defined(Q_OS_LINUX)
+asm (
+".section .qtversion, \"aG\", @progbits, qt_version_tag, comdat\n"
+".align 8\n"
+# ifdef __LP64__
+".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(qt_version_tag)) "@GOTPCREL\n"
+# elif defined(Q_PROCESSOR_X86_64) // x32
+".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(qt_version_tag)) "@GOTPCREL\n"
+# else // x86
+".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(qt_version_tag)) "@GOT\n"
+#endif
+".long " QT_STRINGIFY(QT_VERSION) "\n"
+".align 8\n"
+".previous"
+);
+# endif
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QVERSIONTAGGING_H && !QT_NO_VERSION_TAGGING
--
2.3.5