[PATCH v2 05/21] kbuild: only emit vmlinux relocations when required

From: Lorenzo Stoakes (ARM)

Date: Mon Sep 14 2026 - 05:31:37 EST


A kernel build consists of more than one linking pass on vmlinux.o and
vmlinux, at minimum two, and with CONFIG_KALLSYMS and BTF enabled on x86-64
for example there are 5 such stages.

For architectures that build their own relocation tables (x86, riscv, mips,
s390), vmlinux is linked with the --emit-relocs parameter specified.

However, this is only required on the final vmlinux link.

Symbol tables of trial links preceding it don't need it because they
already check that System.map matches kallsyms symbols on each build.

GNU ld is slow at emitting relocation tables, so this results in a
reduction in build time.

Whole build, 128-thread Threadripper 9980X, best of N runs:

before after delta
-------------------------------
x86 defconfig, touch mm/vma.c, gcc 9.5s 9.1s -0.42s (-4%)
x86 defconfig, clean, gcc 30.1s 29.5s -0.59s (-2%)
x86 allmodconfig, touch mm/vma.c, gcc 37.2s 35.8s -1.4s (-4%)

Note that this has little impact on LLVM ld which performs this operation
more efficiently.

Assisted-by: LLM
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
---
Makefile | 2 +-
scripts/link-vmlinux.sh | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 0f1b80100b47..dd4c10afbb7f 100644
--- a/Makefile
+++ b/Makefile
@@ -1263,7 +1263,7 @@ LDFLAGS_vmlinux += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
endif

ifneq ($(CONFIG_ARCH_VMLINUX_NEEDS_RELOCS),)
-LDFLAGS_vmlinux += --emit-relocs --discard-none
+LDFLAGS_vmlinux += --discard-none
endif

# Align the architecture of userspace programs with the kernel
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 970ca10f8fa9..ed5ff97c0667 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -96,6 +96,11 @@ vmlinux_link()
ldflags="${ldflags} ${wl}--strip-debug"
fi

+ # Only the final link actually requires the relocations.
+ if [ "${output}" = "${VMLINUX}" ] && is_enabled CONFIG_ARCH_VMLINUX_NEEDS_RELOCS; then
+ ldflags="${ldflags} ${wl}--emit-relocs"
+ fi
+
if [ -n "${generate_map}" ]; then
ldflags="${ldflags} ${wl}-Map=vmlinux.map"
fi

--
2.55.0