kbuild: Create intermediate vmlinux build with relocations preserved
authorArd Biesheuvel <ardb@kernel.org>
Tue, 11 Mar 2025 11:06:20 +0000 (12:06 +0100)
committerMasahiro Yamada <masahiroy@kernel.org>
Sun, 16 Mar 2025 15:29:50 +0000 (00:29 +0900)
The imperative paradigm used to build vmlinux, extract some info from it
or perform some checks on it, and subsequently modify it again goes
against the declarative paradigm that is usually employed for defining
make rules.

In particular, the Makefile.postlink files that consume their input via
an output rule result in some dodgy logic in the decompressor makefiles
for RISC-V and x86, given that the vmlinux.relocs input file needed to
generate the arch-specific relocation tables may not exist or be out of
date, but cannot be constructed using the ordinary Make dependency based
rules, because the info needs to be extracted while vmlinux is in its
ephemeral, non-stripped form.

So instead, for architectures that require the static relocations that
are emitted into vmlinux when passing --emit-relocs to the linker, and
are subsequently stripped out again, introduce an intermediate vmlinux
target called vmlinux.unstripped, and organize the reset of the build
logic accordingly:

- vmlinux.unstripped is created only once, and not updated again
- build rules under arch/*/boot can depend on vmlinux.unstripped without
  running the risk of the data disappearing or being out of date
- the final vmlinux generated by the build is not bloated with static
  relocations that are never needed again after the build completes.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
.gitignore
Makefile
arch/mips/Makefile.postlink
arch/riscv/Makefile.postlink
arch/riscv/boot/Makefile
arch/s390/Makefile.postlink
arch/x86/Makefile.postlink
scripts/Makefile.lib
scripts/Makefile.vmlinux

index 5937c74d3dc1e4ca56d93ea0b8d5ff9fc64ec839..f2f63e47fb88686d5d5ab17d480c9301184134a9 100644 (file)
@@ -65,6 +65,7 @@ modules.order
 /vmlinux.32
 /vmlinux.map
 /vmlinux.symvers
+/vmlinux.unstripped
 /vmlinux-gdb.py
 /vmlinuz
 /System.map
index 0904b73872cb5714621941c0d9ddd9814645045c..22593a774cf61ccdb2b245f46b743789c80e09d5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1569,7 +1569,7 @@ endif # CONFIG_MODULES
 # Directories & files removed with 'make clean'
 CLEAN_FILES += vmlinux.symvers modules-only.symvers \
               modules.builtin modules.builtin.modinfo modules.nsdeps \
-              modules.builtin.ranges vmlinux.o.map \
+              modules.builtin.ranges vmlinux.o.map vmlinux.unstripped \
               compile_commands.json rust/test \
               rust-project.json .vmlinux.objs .vmlinux.export.c \
                .builtin-dtbs-list .builtin-dtb.S
index 6cfdc149d3bcd580cb969a9f312f886776552dd7..ea0add7d56b23a0f79879b949852320e916c3757 100644 (file)
@@ -22,7 +22,7 @@ quiet_cmd_relocs = RELOCS  $@
 
 # `@true` prevents complaint when there is nothing to be done
 
-vmlinux: FORCE
+vmlinux vmlinux.unstripped: FORCE
        @true
 ifeq ($(CONFIG_CPU_LOONGSON3_WORKAROUNDS),y)
        $(call if_changed,ls3_llsc)
index 6b0580949b6a24ff34ea52518c37bf162dc4606a..0e4cf8ad2f14b2a74e65d16a0c5c6dc696451d01 100644 (file)
@@ -10,26 +10,17 @@ __archpost:
 
 -include include/config/auto.conf
 include $(srctree)/scripts/Kbuild.include
-include $(srctree)/scripts/Makefile.lib
 
 quiet_cmd_relocs_check = CHKREL  $@
 cmd_relocs_check =                                                     \
        $(CONFIG_SHELL) $(srctree)/arch/riscv/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@"
 
-ifdef CONFIG_RELOCATABLE
-quiet_cmd_cp_vmlinux_relocs = CPREL   vmlinux.relocs
-cmd_cp_vmlinux_relocs = cp vmlinux vmlinux.relocs
-
-endif
-
 # `@true` prevents complaint when there is nothing to be done
 
-vmlinux: FORCE
+vmlinux vmlinux.unstripped: FORCE
        @true
 ifdef CONFIG_RELOCATABLE
        $(call if_changed,relocs_check)
-       $(call if_changed,cp_vmlinux_relocs)
-       $(call if_changed,strip_relocs)
 endif
 
 clean:
index b25d524ce5eb436f17744e3fa61778e8c1391ea7..bfc3d0b75b9b2b416198ff80153ac231ebdbca3f 100644 (file)
@@ -32,10 +32,7 @@ $(obj)/xipImage: vmlinux FORCE
 endif
 
 ifdef CONFIG_RELOCATABLE
-vmlinux.relocs: vmlinux
-       @ (! [ -f vmlinux.relocs ] && echo "vmlinux.relocs can't be found, please remove vmlinux and try again") || true
-
-$(obj)/Image: vmlinux.relocs FORCE
+$(obj)/Image: vmlinux.unstripped FORCE
 else
 $(obj)/Image: vmlinux FORCE
 endif
index 1ae5478cd6aca4d29e8787ae8b7c7b32fc51c5a3..c2b737500a91d3eca391ec01bde45ab4188658cf 100644 (file)
@@ -11,7 +11,6 @@ __archpost:
 
 -include include/config/auto.conf
 include $(srctree)/scripts/Kbuild.include
-include $(srctree)/scripts/Makefile.lib
 
 CMD_RELOCS=arch/s390/tools/relocs
 OUT_RELOCS = arch/s390/boot
@@ -20,9 +19,8 @@ quiet_cmd_relocs = RELOCS  $(OUT_RELOCS)/relocs.S
        mkdir -p $(OUT_RELOCS); \
        $(CMD_RELOCS) $@ > $(OUT_RELOCS)/relocs.S
 
-vmlinux: FORCE
+vmlinux.unstripped: FORCE
        $(call cmd,relocs)
-       $(call cmd,strip_relocs)
 
 clean:
        @rm -f $(OUT_RELOCS)/relocs.S
index 8b8a68162c940c7c7705b2ed731569749a9a68c8..445fce66630f5f86ba159afe6b45c3367d332bd8 100644 (file)
@@ -11,23 +11,21 @@ __archpost:
 
 -include include/config/auto.conf
 include $(srctree)/scripts/Kbuild.include
-include $(srctree)/scripts/Makefile.lib
 
 CMD_RELOCS = arch/x86/tools/relocs
 OUT_RELOCS = arch/x86/boot/compressed
-quiet_cmd_relocs = RELOCS  $(OUT_RELOCS)/$@.relocs
+quiet_cmd_relocs = RELOCS  $(OUT_RELOCS)/vmlinux.relocs
       cmd_relocs = \
        mkdir -p $(OUT_RELOCS); \
-       $(CMD_RELOCS) $@ > $(OUT_RELOCS)/$@.relocs; \
+       $(CMD_RELOCS) $@ > $(OUT_RELOCS)/vmlinux.relocs; \
        $(CMD_RELOCS) --abs-relocs $@
 
 # `@true` prevents complaint when there is nothing to be done
 
-vmlinux: FORCE
+vmlinux vmlinux.unstripped: FORCE
        @true
 ifeq ($(CONFIG_X86_NEED_RELOCS),y)
        $(call cmd,relocs)
-       $(call cmd,strip_relocs)
 endif
 
 clean:
index 47f56ef719372b9d1735fe08001eb839c82c91dd..d1856a70c9195968962ad753cc2e63f073fa7e09 100644 (file)
@@ -371,9 +371,6 @@ quiet_cmd_ar = AR      $@
 quiet_cmd_objcopy = OBJCOPY $@
 cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
 
-quiet_cmd_strip_relocs = RSTRIP  $@
-cmd_strip_relocs = $(OBJCOPY) --remove-section='.rel*' $@
-
 # Gzip
 # ---------------------------------------------------------------------------
 
index 487f0bf716ad8523271913cb421249cf45cb2680..b0a6cd5b818c9fe19d20f5ddf4908eb14b888ea9 100644 (file)
@@ -9,6 +9,20 @@ include $(srctree)/scripts/Makefile.lib
 
 targets :=
 
+ifdef CONFIG_ARCH_VMLINUX_NEEDS_RELOCS
+vmlinux-final := vmlinux.unstripped
+
+quiet_cmd_strip_relocs = RSTRIP  $@
+      cmd_strip_relocs = $(OBJCOPY) --remove-section='.rel*' $< $@
+
+vmlinux: $(vmlinux-final) FORCE
+       $(call if_changed,strip_relocs)
+
+targets += vmlinux
+else
+vmlinux-final := vmlinux
+endif
+
 %.o: %.c FORCE
        $(call if_changed_rule,cc_o_c)
 
@@ -47,7 +61,7 @@ targets += .builtin-dtbs-list
 
 ifdef CONFIG_GENERIC_BUILTIN_DTB
 targets += .builtin-dtbs.S .builtin-dtbs.o
-vmlinux: .builtin-dtbs.o
+$(vmlinux-final): .builtin-dtbs.o
 endif
 
 # vmlinux
@@ -55,11 +69,11 @@ endif
 
 ifdef CONFIG_MODULES
 targets += .vmlinux.export.o
-vmlinux: .vmlinux.export.o
+$(vmlinux-final): .vmlinux.export.o
 endif
 
 ifdef CONFIG_ARCH_WANTS_PRE_LINK_VMLINUX
-vmlinux: arch/$(SRCARCH)/tools/vmlinux.arch.o
+$(vmlinux-final): arch/$(SRCARCH)/tools/vmlinux.arch.o
 
 arch/$(SRCARCH)/tools/vmlinux.arch.o: vmlinux.o FORCE
        $(Q)$(MAKE) $(build)=arch/$(SRCARCH)/tools $@
@@ -72,11 +86,11 @@ cmd_link_vmlinux =                                                  \
        $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)" "$@";       \
        $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
 
-targets += vmlinux
-vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
+targets += $(vmlinux-final)
+$(vmlinux-final): scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
        +$(call if_changed_dep,link_vmlinux)
 ifdef CONFIG_DEBUG_INFO_BTF
-vmlinux: $(RESOLVE_BTFIDS)
+$(vmlinux-final): $(RESOLVE_BTFIDS)
 endif
 
 ifdef CONFIG_BUILDTIME_TABLE_SORT
@@ -96,7 +110,7 @@ modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \
                        modules.builtin vmlinux.map vmlinux.o.map FORCE
        $(call if_changed,modules_builtin_ranges)
 
-vmlinux.map: vmlinux
+vmlinux.map: $(vmlinux-final)
        @:
 
 endif