llvm.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb+git@google.com>
To: linux-kernel@vger.kernel.org
Cc: Ard Biesheuvel <ardb@kernel.org>,
	x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
	 Andy Lutomirski <luto@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Uros Bizjak <ubizjak@gmail.com>,  Dennis Zhou <dennis@kernel.org>,
	Tejun Heo <tj@kernel.org>, Christoph Lameter <cl@linux.com>,
	 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	 Vitaly Kuznetsov <vkuznets@redhat.com>,
	Juergen Gross <jgross@suse.com>,
	 Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	 Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Arnd Bergmann <arnd@arndb.de>,
	 Masahiro Yamada <masahiroy@kernel.org>,
	Kees Cook <kees@kernel.org>,
	 Nathan Chancellor <nathan@kernel.org>,
	Keith Packard <keithp@keithp.com>,
	 Justin Stitt <justinstitt@google.com>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	 Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
	 Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	 Kan Liang <kan.liang@linux.intel.com>,
	linux-doc@vger.kernel.org,  linux-pm@vger.kernel.org,
	kvm@vger.kernel.org, xen-devel@lists.xenproject.org,
	 linux-efi@vger.kernel.org, linux-arch@vger.kernel.org,
	 linux-sparse@vger.kernel.org, linux-kbuild@vger.kernel.org,
	 linux-perf-users@vger.kernel.org,
	rust-for-linux@vger.kernel.org,  llvm@lists.linux.dev
Subject: [RFC PATCH 04/28] x86/boot: Permit GOTPCREL relocations for x86_64 builds
Date: Wed, 25 Sep 2024 17:01:04 +0200	[thread overview]
Message-ID: <20240925150059.3955569-34-ardb+git@google.com> (raw)
In-Reply-To: <20240925150059.3955569-30-ardb+git@google.com>

From: Ard Biesheuvel <ardb@kernel.org>

Some of the early x86_64 startup code is written in C, and executes in
the early 1:1 mapping of the kernel, which is not the address it was
linked at, and this requires special care when accessing global
variables. This is currently being dealt with on an ad-hoc basis,
primarily in head64.c, using explicit pointer fixups, but it would be
better to rely on the compiler for this, by using -fPIE to generate code
that can run at any address, and uses RIP-relative accesses to refer to
global variables.

While it is possible to avoid most GOT based symbol references that the
compiler typically emits when running in -fPIE mode, by using 'hidden'
visibility, there are cases where the compiler will always rely on the
GOT, for instance, for weak external references (which may remain
unsatisfied at link time).

This means the build may produce a small number of GOT entries
nonetheless. So update the reloc processing host tool to add support for
this, and place the GOT in the .text section rather than discard it.

Note that multiple GOT based references to the same symbol will share a
single GOT entry, and so naively emitting a relocation for the GOT entry
each time a reference to it is encountered could result in duplicates.
Work around this by relying on the fact that the relocation lists are
sorted, and deduplicate 64-bit relocations as they are emitted by
comparing each entry with the previous one.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/x86/Makefile                 |  4 +++
 arch/x86/kernel/vmlinux.lds.S     |  5 +++
 arch/x86/tools/relocs.c           | 33 ++++++++++++++++++--
 include/asm-generic/vmlinux.lds.h |  7 +++++
 4 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 801fd85c3ef6..6b3fe6e2aadd 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -192,6 +192,10 @@ else
         KBUILD_CFLAGS += -mcmodel=kernel
         KBUILD_RUSTFLAGS += -Cno-redzone=y
         KBUILD_RUSTFLAGS += -Ccode-model=kernel
+
+        # Don't emit relaxable GOTPCREL relocations
+        KBUILD_AFLAGS_KERNEL += -Wa,-mrelax-relocations=no
+        KBUILD_CFLAGS_KERNEL += -Wa,-mrelax-relocations=no
 endif
 
 #
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 6e73403e874f..7f060d873f75 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -20,6 +20,9 @@
 #define RUNTIME_DISCARD_EXIT
 #define EMITS_PT_NOTE
 #define RO_EXCEPTION_TABLE_ALIGN	16
+#ifdef CONFIG_X86_64
+#define GOT_IN_RODATA
+#endif
 
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/asm-offsets.h>
@@ -464,10 +467,12 @@ SECTIONS
 	 * Sections that should stay zero sized, which is safer to
 	 * explicitly check instead of blindly discarding.
 	 */
+#ifdef CONFIG_X86_32
 	.got : {
 		*(.got) *(.igot.*)
 	}
 	ASSERT(SIZEOF(.got) == 0, "Unexpected GOT entries detected!")
+#endif
 
 	.plt : {
 		*(.plt) *(.plt.*) *(.iplt)
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index 35a73e4aa74d..880f0f2e465e 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -223,6 +223,8 @@ static const char *rel_type(unsigned type)
 		REL_TYPE(R_X86_64_JUMP_SLOT),
 		REL_TYPE(R_X86_64_RELATIVE),
 		REL_TYPE(R_X86_64_GOTPCREL),
+		REL_TYPE(R_X86_64_GOTPCRELX),
+		REL_TYPE(R_X86_64_REX_GOTPCRELX),
 		REL_TYPE(R_X86_64_32),
 		REL_TYPE(R_X86_64_32S),
 		REL_TYPE(R_X86_64_16),
@@ -843,6 +845,7 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
 	case R_X86_64_32:
 	case R_X86_64_32S:
 	case R_X86_64_64:
+	case R_X86_64_GOTPCREL:
 		/*
 		 * References to the percpu area don't need to be adjusted.
 		 */
@@ -861,6 +864,31 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
 			break;
 		}
 
+		if (r_type == R_X86_64_GOTPCREL) {
+			Elf_Shdr *s = &secs[sec->shdr.sh_info].shdr;
+			unsigned file_off = offset - s->sh_addr + s->sh_offset;
+
+			/*
+			 * GOTPCREL relocations refer to instructions that load
+			 * a 64-bit address via a 32-bit relative reference to
+			 * the GOT.  In this case, it is the GOT entry that
+			 * needs to be fixed up, not the immediate offset in
+			 * the opcode. Note that the linker will have applied an
+			 * addend of -4 to compensate for the delta between the
+			 * relocation offset and the value of RIP when the
+			 * instruction executes, and this needs to be backed out
+			 * again. (Addends other than -4 are permitted in
+			 * principle, but make no sense in practice so they are
+			 * not supported.)
+                         */
+			if (rel->r_addend != -4) {
+				die("invalid addend (%ld) for %s relocation: %s\n",
+				    rel->r_addend, rel_type(r_type), symname);
+				break;
+			}
+			offset += 4 + (int32_t)get_unaligned_le32(elf_image + file_off);
+		}
+
 		/*
 		 * Relocation offsets for 64 bit kernels are output
 		 * as 32 bits and sign extended back to 64 bits when
@@ -870,7 +898,7 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
 		if ((int32_t)offset != (int64_t)offset)
 			die("Relocation offset doesn't fit in 32 bits\n");
 
-		if (r_type == R_X86_64_64)
+		if (r_type == R_X86_64_64 || r_type == R_X86_64_GOTPCREL)
 			add_reloc(&relocs64, offset);
 		else
 			add_reloc(&relocs32, offset);
@@ -1085,7 +1113,8 @@ static void emit_relocs(int as_text, int use_real_mode)
 
 		/* Now print each relocation */
 		for (i = 0; i < relocs64.count; i++)
-			write_reloc(relocs64.offset[i], stdout);
+			if (!i || relocs64.offset[i] != relocs64.offset[i - 1])
+				write_reloc(relocs64.offset[i], stdout);
 
 		/* Print a stop */
 		write_reloc(0, stdout);
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 19ec49a9179b..cc14d780c70d 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -443,6 +443,12 @@
 #endif
 #endif
 
+#ifdef GOT_IN_RODATA
+#define GOT_RODATA	*(.got .igot*)
+#else
+#define GOT_RODATA
+#endif
+
 /*
  * Read only Data
  */
@@ -454,6 +460,7 @@
 		SCHED_DATA						\
 		RO_AFTER_INIT_DATA	/* Read only after init */	\
 		. = ALIGN(8);						\
+		GOT_RODATA						\
 		BOUNDED_SECTION_BY(__tracepoints_ptrs, ___tracepoints_ptrs) \
 		*(__tracepoints_strings)/* Tracepoints: strings */	\
 	}								\
-- 
2.46.0.792.g87dc391469-goog


  parent reply	other threads:[~2024-09-25 15:02 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-25 15:01 [RFC PATCH 00/28] x86: Rely on toolchain for relocatable code Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 01/28] x86/pvh: Call C code via the kernel virtual mapping Ard Biesheuvel
2024-09-25 21:12   ` Jason Andryuk
2024-09-25 15:01 ` [RFC PATCH 02/28] Documentation: Bump minimum GCC version to 8.1 Ard Biesheuvel
2024-09-25 15:58   ` Arnd Bergmann
2024-12-19 11:53     ` Mark Rutland
2024-12-19 12:02       ` Arnd Bergmann
2024-09-26 21:35   ` Miguel Ojeda
2024-09-27 16:22   ` Mark Rutland
2024-09-25 15:01 ` [RFC PATCH 03/28] x86/tools: Use mmap() to simplify relocs host tool Ard Biesheuvel
2024-09-25 15:01 ` Ard Biesheuvel [this message]
2024-10-01  5:33   ` [RFC PATCH 04/28] x86/boot: Permit GOTPCREL relocations for x86_64 builds Josh Poimboeuf
2024-10-01  6:56     ` Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 05/28] x86: Define the stack protector guard symbol explicitly Ard Biesheuvel
2024-09-25 15:53   ` Ian Rogers
2024-09-25 17:43     ` Ard Biesheuvel
2024-09-25 17:48       ` Ian Rogers
2024-09-25 18:32   ` Uros Bizjak
2024-09-28 13:41     ` Brian Gerst
2024-10-04 13:15       ` Ard Biesheuvel
2024-10-08 14:36         ` Brian Gerst
2024-10-04 10:01   ` Uros Bizjak
2024-09-25 15:01 ` [RFC PATCH 06/28] x86/percpu: Get rid of absolute per-CPU variable placement Ard Biesheuvel
2024-09-25 17:56   ` Christoph Lameter (Ampere)
2024-09-25 15:01 ` [RFC PATCH 07/28] scripts/kallsyms: Avoid 0x0 as the relative base Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 08/28] scripts/kallsyms: Remove support for absolute per-CPU variables Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 09/28] x86/tools: Remove special relocation handling for " Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 10/28] x86/xen: Avoid relocatable quantities in Xen ELF notes Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 11/28] x86/pvh: Avoid absolute symbol references in .head.text Ard Biesheuvel
2024-09-25 21:10   ` Jason Andryuk
2024-09-25 21:50     ` Ard Biesheuvel
2024-09-25 22:40       ` Jason Andryuk
2024-09-25 15:01 ` [RFC PATCH 12/28] x86/pm-trace: Use RIP-relative accesses for .tracedata Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 13/28] x86/kvm: Use RIP-relative addressing Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 14/28] x86/rethook: Use RIP-relative reference for return address Ard Biesheuvel
2024-09-25 16:39   ` Linus Torvalds
2024-09-25 16:45     ` Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 15/28] x86/sync_core: Use RIP-relative addressing Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 16/28] x86/entry_64: " Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 17/28] x86/hibernate: Prefer RIP-relative accesses Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 18/28] x86/boot/64: Determine VA/PA offset before entering C code Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 19/28] x86/boot/64: Avoid intentional absolute symbol references in .head.text Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 20/28] x64/acpi: Use PIC-compatible references in wakeup_64.S Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 21/28] x86/head: Use PIC-compatible symbol references in startup code Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 22/28] asm-generic: Treat PIC .data.rel.ro sections as .rodata Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 23/28] tools/objtool: Mark generated sections as writable Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 24/28] tools/objtool: Treat indirect ftrace calls as direct calls Ard Biesheuvel
2024-10-01  7:18   ` Josh Poimboeuf
2024-10-01  7:39     ` Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 25/28] x86: Use PIE codegen for the core kernel Ard Biesheuvel
2024-10-01 21:13   ` H. Peter Anvin
2024-10-02 15:25     ` Ard Biesheuvel
2024-10-02 20:01       ` Linus Torvalds
2024-10-03 11:13         ` Ard Biesheuvel
2024-10-04 21:06           ` H. Peter Anvin
2024-10-05  8:31             ` Uros Bizjak
2024-10-05 23:36               ` H. Peter Anvin
2024-10-06  0:00                 ` Linus Torvalds
2024-10-06  8:06                   ` Uros Bizjak
2024-10-06  7:59                 ` Uros Bizjak
2024-10-06 18:00                   ` David Laight
2024-10-06 19:17                     ` Uros Bizjak
2024-10-06 19:38                       ` H. Peter Anvin
2024-09-25 15:01 ` [RFC PATCH 26/28] x86/boot: Implement support for ELF RELA/RELR relocations Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 27/28] x86/kernel: Switch to PIE linking for the core kernel Ard Biesheuvel
2024-09-25 18:54   ` Uros Bizjak
2024-09-25 19:14     ` Ard Biesheuvel
2024-09-25 19:39       ` Uros Bizjak
2024-09-25 20:01         ` Ard Biesheuvel
2024-09-25 20:22           ` Uros Bizjak
2024-09-25 20:24   ` Vegard Nossum
2024-09-26 13:38     ` Ard Biesheuvel
2024-09-25 15:01 ` [RFC PATCH 28/28] x86/tools: Drop x86_64 support from 'relocs' tool Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240925150059.3955569-34-ardb+git@google.com \
    --to=ardb+git@google.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=boris.ostrovsky@oracle.com \
    --cc=cl@linux.com \
    --cc=dennis@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=hpa@zytor.com \
    --cc=irogers@google.com \
    --cc=jgross@suse.com \
    --cc=jolsa@kernel.org \
    --cc=jpoimboe@kernel.org \
    --cc=justinstitt@google.com \
    --cc=kan.liang@linux.intel.com \
    --cc=kees@kernel.org \
    --cc=keithp@keithp.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-sparse@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=luto@kernel.org \
    --cc=masahiroy@kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=namhyung@kernel.org \
    --cc=nathan@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tj@kernel.org \
    --cc=ubizjak@gmail.com \
    --cc=vkuznets@redhat.com \
    --cc=x86@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).