From aa82d295c8954a5d04fd446abc7452f007594422 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
Date: Tue, 12 Oct 2021 14:25:14 -0700
Subject: [PATCH] Move the ABI tag from minimum-linux.S to qlibraryinfo.cpp

We don't need the assembly file any more. According to a comment to
patchsets 2 in the Gerrit code review for commit
bb8a61866ec6a6de2426012f8c4219d41b3a414a, the section ended up as
SHT_PROGBITS instead of SHT_NOTE. I didn't know then that the section
type is not actually important, only whether it's present in the segment
pointed by a PT_NOTE is. That isn't recorded in the review.

Since we now depend on the linker properly placing the .note.* sections
for Qt plugins, we can rely on this working.

Change-Id: Icb2516126f674e7b8bb3fffd16ad659149e34a23
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
---
 src/corelib/CMakeLists.txt           | 17 ------
 src/corelib/global/minimum-linux.S   | 81 ----------------------------
 src/corelib/global/minimum-linux_p.h | 27 +++++-----
 src/corelib/global/qlibraryinfo.cpp  | 30 +++++++++++
 4 files changed, 44 insertions(+), 111 deletions(-)
 delete mode 100644 src/corelib/global/minimum-linux.S

diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index 680c79ad79..857ba2dc7f 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -573,23 +573,6 @@ qt_internal_extend_target(Core CONDITION LINUX AND QT_BUILD_SHARED_LIBS
         global/minimum-linux_p.h
 )
 
-#### Keys ignored in scope 34:.:global:global/global.pri:precompile_header:
-# NO_PCH_ASM = "global/minimum-linux.S"
-# QMAKE_EXTRA_COMPILERS = "no_pch_assembler"
-# no_pch_assembler.commands = "$$QMAKE_CC" "-c" "$(CFLAGS)" "$(INCPATH)" "${QMAKE_FILE_IN}" "-o" "${QMAKE_FILE_OUT}"
-# no_pch_assembler.dependency_type = "TYPE_C"
-# no_pch_assembler.input = "NO_PCH_ASM"
-# no_pch_assembler.name = "compiling[no_pch]" "${QMAKE_FILE_IN}"
-# no_pch_assembler.output = "${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${firstQMAKE_EXT_OBJ}"
-
-#### Keys ignored in scope 35:.:global:global/global.pri:silent:
-# no_pch_assembler.commands = "@echo" "compiling[no_pch]" "${QMAKE_FILE_IN}" "&&"
-
-qt_internal_extend_target(Core CONDITION LINUX AND NOT precompile_header AND QT_BUILD_SHARED_LIBS
-    SOURCES
-        global/minimum-linux.S
-)
-
 qt_internal_extend_target(Core CONDITION QT_FEATURE_slog2
     LIBRARIES
         Slog2::Slog2
diff --git a/src/corelib/global/minimum-linux.S b/src/corelib/global/minimum-linux.S
deleted file mode 100644
index e324379efc..0000000000
--- a/src/corelib/global/minimum-linux.S
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "minimum-linux_p.h"
-
-/* Copied from #include <elf.h>:
- */
-#define ELF_NOTE_GNU            "GNU"
-#define NT_GNU_ABI_TAG          1
-#define ELF_NOTE_OS_LINUX       0
-
-#ifdef __arm__
-#  define progbits              %progbits
-#  define note                  %note
-#else
-#  define progbits              @progbits
-#  define note                  @note
-#endif
-
-/* Add information for the ELF dynamic linker what the minimum Linux version
- * required for Qt is.
- *
- * The .note.ABI-tag note section is defined at
- *  https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/noteabitag.html
- */
-
-    .section    ".note.GNU-stack", "", progbits
-    .section    ".note.ABI-tag", "a", note
-    .balign     4       /* we have 32-bit data */
-
-/*  * For the format of the note section's contents, see Elf32_Nhdr / Elf64_Nhdr */
-    .long       .Lnameend-.Lname        /* n_namesz */
-    .long       16                      /* n_descsz(16 bytes, normative) */
-    .long       NT_GNU_ABI_TAG          /* n_type */
-
-.Lname:
-    .asciz      ELF_NOTE_GNU
-.Lnameend:
-
-/* Operating systems: */
-    .long       ELF_NOTE_OS_LINUX
-
-    .long       MINLINUX_MAJOR
-    .long       MINLINUX_MINOR
-    .long       MINLINUX_PATCH
diff --git a/src/corelib/global/minimum-linux_p.h b/src/corelib/global/minimum-linux_p.h
index 5112015663..291e6965b8 100644
--- a/src/corelib/global/minimum-linux_p.h
+++ b/src/corelib/global/minimum-linux_p.h
@@ -83,24 +83,25 @@ QT_BEGIN_NAMESPACE
 // falls back to stat() for us.
 // (Using QT_CONFIG(glibc) instead of __GLIBC__ because the macros aren't
 // defined in assembler mode)
-#  define MINLINUX_MAJOR        4
-#  define MINLINUX_MINOR        11
-#  define MINLINUX_PATCH        0
+#  define QT_ELF_NOTE_OS_MAJOR      4
+#  define QT_ELF_NOTE_OS_MINOR      11
+#  define QT_ELF_NOTE_OS_PATCH      0
 #elif QT_CONFIG(getentropy)
-#  define MINLINUX_MAJOR        3
-#  define MINLINUX_MINOR        17
-#  define MINLINUX_PATCH        0
+#  define QT_ELF_NOTE_OS_MAJOR      3
+#  define QT_ELF_NOTE_OS_MINOR      17
+#  define QT_ELF_NOTE_OS_PATCH      0
 #elif QT_CONFIG(renameat2)
-#  define MINLINUX_MAJOR        3
-#  define MINLINUX_MINOR        16
-#  define MINLINUX_PATCH        0
+#  define QT_ELF_NOTE_OS_MAJOR      3
+#  define QT_ELF_NOTE_OS_MINOR      16
+#  define QT_ELF_NOTE_OS_PATCH      0
 #else
-#  define MINLINUX_MAJOR        2
-#  define MINLINUX_MINOR        6
-#  define MINLINUX_PATCH        28
+#  define QT_ELF_NOTE_OS_MAJOR      2
+#  define QT_ELF_NOTE_OS_MINOR      6
+#  define QT_ELF_NOTE_OS_PATCH      28
 #endif
 
-#define MINIMUM_LINUX_VERSION  QT_VERSION_CHECK(MINLINUX_MAJOR, MINLINUX_MINOR, MINLINUX_PATCH)
+/* you must include <elf.h> */
+#define QT_ELF_NOTE_OS_TYPE         ELF_NOTE_OS_LINUX
 
 QT_END_NAMESPACE
 
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index b0df718dc5..18a429fb6d 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -685,6 +685,7 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
 QT_END_NAMESPACE
 
 #if defined(Q_CC_GNU) && defined(ELF_INTERPRETER)
+#  include <elf.h>
 #  include <stdio.h>
 #  include <stdlib.h>
 
@@ -694,6 +695,35 @@ QT_WARNING_DISABLE_GCC("-Wattributes")
 QT_WARNING_DISABLE_CLANG("-Wattributes")
 QT_WARNING_DISABLE_INTEL(2621)
 
+#  if defined(Q_OS_LINUX)
+#    include "minimum-linux_p.h"
+#  endif
+#  ifdef QT_ELF_NOTE_OS_TYPE
+struct ElfNoteAbiTag
+{
+    static_assert(sizeof(Elf32_Nhdr) == sizeof(Elf64_Nhdr),
+        "The size of an ELF note is wrong (should be 12 bytes)");
+    struct Payload {
+        Elf32_Word ostype = QT_ELF_NOTE_OS_TYPE;
+        Elf32_Word major = QT_ELF_NOTE_OS_MAJOR;
+        Elf32_Word minor = QT_ELF_NOTE_OS_MINOR;
+#    ifdef QT_ELF_NOTE_OS_PATCH
+        Elf32_Word patch = QT_ELF_NOTE_OS_PATCH;
+#    endif
+    };
+
+    Elf32_Nhdr header = {
+        .n_namesz = sizeof(name),
+        .n_descsz = sizeof(Payload),
+        .n_type = NT_GNU_ABI_TAG
+    };
+    char name[sizeof ELF_NOTE_GNU] = ELF_NOTE_GNU;  // yes, include the null terminator
+    Payload payload = {};
+};
+__attribute__((section(".note.ABI-tag"), aligned(4), used))
+extern constexpr ElfNoteAbiTag QT_MANGLE_NAMESPACE(qt_abi_tag) = {};
+#  endif
+
 extern const char qt_core_interpreter[] __attribute__((section(".interp")))
     = ELF_INTERPRETER;