Re: [PATCH v3 23/28] kbuild: Do the per-module objtool pass right before linking
From: Nicolas Schier
Date: Thu Sep 24 2026 - 07:26:33 EST
On Mon, Sep 21, 2026 at 03:31:24PM -0700, Josh Poimboeuf wrote:
> With CONFIG_OBJTOOL_CONTROL_FLOW, the objtool pass on vmlinux.o is going
> to be generating a list of its exported noreturns which will then be
> read by the modules' objtool pass, so there will need to be a build
> dependency between them.
>
> In preparation for that, run objtool right before the module link so its
> no longer done on the descend in the deferred case.
>
> Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
> ---
> scripts/Makefile.build | 31 +++++++++++++++----------------
> scripts/Makefile.modfinal | 20 +++++++++++++++-----
> scripts/livepatch/klp-build | 12 ++++++------
> 3 files changed, 36 insertions(+), 27 deletions(-)
>
> diff --git a/scripts/Makefile.build b/scripts/Makefile.build
> index 87993362595ce..c1b22b4a4e217 100644
> --- a/scripts/Makefile.build
> +++ b/scripts/Makefile.build
> @@ -271,15 +271,21 @@ cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)),
> $(sub_cmd_record_mcount))
> endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
>
> -# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
> -# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
> -# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
> -
> +ifdef CONFIG_OBJTOOL
> +#
> +# NOTE: these variables are deprecated, and have no effect when
> +# CONFIG_OBJTOOL_DEFERRED is enabled. Objtool-allergic code can instead be
> +# marked with STACK_FRAME_NON_STANDARD() or ANNOTATE_*().
> +#
> +# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
> +# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
> +# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
> +#
> is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(target-stem).o)$(OBJECT_FILES_NON_STANDARD)n),$(is-kernel-object))
>
> -ifdef CONFIG_OBJTOOL
> -$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(CONFIG_OBJTOOL_DEFERRED),$(is-single-obj-m),y))
> -endif
> +# Enable per-TU objtool for !CONFIG_OBJTOOL_DEFERRED
> +$(obj)/%.o: private objtool-enabled = $(if $(CONFIG_OBJTOOL_DEFERRED),,$(if $(is-standard-object),y))
> +endif # CONFIG_OBJTOOL
>
> ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),)
> cmd_warn_shared_object = $(if $(word 2, $(modname-multi)),$(warning $(kbuild-file): $*.o is added to multiple modules: $(modname-multi)))
> @@ -497,17 +503,10 @@ $(obj)/lib.a: $(lib-y) FORCE
> $(call if_changed,ar)
>
> quiet_cmd_ld_multi_m = LD [M] $@
> - cmd_ld_multi_m = $(LD) $(ld_flags) -r -o $@ @$< $(cmd_objtool)
> + cmd_ld_multi_m = $(LD) $(ld_flags) -r -o $@ @$<
>
> -define rule_ld_multi_m
> - $(call cmd_and_savecmd,ld_multi_m)
> - $(call cmd,gen_objtooldep)
> -endef
> -
> -$(multi-obj-m): private objtool-enabled := $(CONFIG_OBJTOOL_DEFERRED)
> -$(multi-obj-m): private part-of-module := y
> $(multi-obj-m): %.o: %.mod FORCE
> - $(call if_changed_rule,ld_multi_m)
> + $(call if_changed,ld_multi_m)
> $(call multi_depend, $(multi-obj-m), .o, -objs -y -m)
>
> # Add intermediate targets:
> diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
> index 01a37ec872b90..56b4227cc6863 100644
> --- a/scripts/Makefile.modfinal
> +++ b/scripts/Makefile.modfinal
> @@ -32,11 +32,18 @@ ifneq ($(WARN_ON_UNUSED_TRACEPOINTS),)
> cmd_check_tracepoint = $(objtree)/scripts/tracepoint-update --module $<;
> endif
>
> +$(modules:%.o=%.ko): private objtool-enabled = $(CONFIG_OBJTOOL_DEFERRED)
Reviewed-by: Nicolas Schier <n.schier@xxxxxxxxx>
I understand that the variable name objtool-enabled is used across
Makefiles and that it makes sense to have it here, too, for consistency
and better spotting.
So, just for my understanding: in Makefile.modfinal it is not strictly
necessary but could be replaced by direct use of
$(CONFIG_OBJTOOL_DEFERRED); is that correct?
--
Nicolas