android_kernel_samsung_sm8650/scripts/Makefile.modpost
Will McVicker d834db9f2c ANDROID: modules: re-introduce the MODULE_SCMVERSION config
Config MODULE_SCMVERSION introduces a new module attribute --
`scmversion` -- which can be used to identify a given module's SCM
version.  This is very useful for developers that update their kernel
independently from their kernel modules or vice-versa since the SCM
version provided by UTS_RELEASE (`uname -r`) will now differ from the
module's vermagic attribute.

For example, we have a CI setup that tests new kernel changes on the
hikey960 and db845c devices without updating their kernel modules. When
these tests fail, we need to be able to identify the exact device
configuration the test was using. By including MODULE_SCMVERSION, we can
identify the exact kernel and modules' SCM versions for debugging the
failures.

Additionally, by exposing the SCM version via the sysfs node
/sys/module/MODULENAME/scmversion, one can also verify the SCM versions
of the modules loaded from the initramfs. Currently, modinfo can only
retrieve module attributes from the module's ko on disk and not from the
actual module that is loaded in RAM.

You can retrieve the SCM version in two ways,

1) By using modinfo:
    > modinfo -F scmversion MODULENAME
2) By module sysfs node:
    > cat /sys/module/MODULENAME/scmversion

Bug: 180027765
Link: https://lore.kernel.org/all/20210121213641.3477522-1-willmcvicker@google.com/
Signed-off-by: Will McVicker <willmcvicker@google.com>
Change-Id: Ib7c72c72f95c4545adb7cd4e842729557039ce3a
2023-03-01 01:47:13 +00:00

197 lines
6.6 KiB
Makefile

# SPDX-License-Identifier: GPL-2.0
# ===========================================================================
# Module versions
# ===========================================================================
#
# Stage one of module building created the following:
# a) The individual .o files used for the module
# b) A <module>.o file which is the .o files above linked together
# c) A <module>.mod file, listing the name of the preliminary <module>.o file,
# plus all .o files
# d) modules.order, which lists all the modules
# Stage 2 is handled by this file and does the following
# 1) Find all modules listed in modules.order
# 2) modpost is then used to
# 3) create one <module>.mod.c file per module
# 4) create one Module.symvers file with CRC for all exported symbols
# Step 3 is used to place certain information in the module's ELF
# section, including information such as:
# Version magic (see include/linux/vermagic.h for full details)
# - Kernel release
# - SMP is CONFIG_SMP
# - PREEMPT is CONFIG_PREEMPT[_RT]
# - GCC Version
# Module info
# - Module version (MODULE_VERSION)
# - Module alias'es (MODULE_ALIAS)
# - Module license (MODULE_LICENSE)
# - See include/linux/module.h for more details
# Step 4 is solely used to allow module versioning in external modules,
# where the CRC of each module is retrieved from the Module.symvers file.
PHONY := __modpost
__modpost:
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
mixed-build-prefix = $(if $(KBUILD_MIXED_TREE),$(KBUILD_MIXED_TREE)/)
modpost-args = \
$(if $(CONFIG_MODVERSIONS),-m) \
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
$(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \
$(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \
-o $@
# 'make -i -k' ignores compile errors, and builds as many modules as possible.
ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),)
modpost-args += -n
endif
ifeq ($(CONFIG_MODULE_SCMVERSION),y)
ifeq ($(KBUILD_EXTMOD),)
module_srcpath := $(srctree)
else
# Get the external module's source path. KBUILD_EXTMOD could either be an
# absolute path or relative path from $(srctree). This makes sure that we
# aren't using a relative path from a separate working directory (O= or
# KBUILD_OUTPUT) since that may not be the actual module's SCM project path. So
# check the path relative to $(srctree) first.
ifneq ($(realpath $(srctree)/$(KBUILD_EXTMOD) 2>/dev/null),)
module_srcpath := $(srctree)/$(KBUILD_EXTMOD)
else
module_srcpath := $(KBUILD_EXTMOD)
endif
endif
# Get the SCM version of the module. Sed verifies setlocalversion returns
# a proper revision based on the SCM type, e.g. git, mercurial, or svn.
# Note: relative M= paths are not supported when building the kernel out of the
# srctree since setlocalversion won't be able to find the module srctree.
module_scmversion := $(shell $(srctree)/scripts/setlocalversion $(module_srcpath) | \
sed -n 's/.*-\(\(g\|hg\)[a-fA-F0-9]\+\(-dirty\)\?\|svn[0-9]\+\).*/\1/p')
ifneq ($(module_scmversion),)
modpost-args += -v $(module_scmversion)
endif
endif
ifeq ($(KBUILD_EXTMOD),)
# Generate the list of in-tree objects in vmlinux
# ---------------------------------------------------------------------------
# This is used to retrieve symbol versions generated by genksyms.
ifdef CONFIG_MODVERSIONS
ifndef KBUILD_MIXED_TREE
vmlinux.symvers Module.symvers: .vmlinux.objs
endif
endif
# Ignore libgcc.a
# Some architectures do '$(CC) --print-libgcc-file-name' to borrow libgcc.a
# from the toolchain, but there is no EXPORT_SYMBOL in it.
quiet_cmd_vmlinux_objs = GEN $@
cmd_vmlinux_objs = \
for f in $(real-prereqs); do \
case $${f} in \
*libgcc.a) ;; \
*) $(AR) t $${f} ;; \
esac \
done > $@
quiet_cmd_vmlinux_symvers = GEN $@
cmd_vmlinux_symvers = grep "\<vmlinux\s\+EXPORT" $< > $@
quiet_cmd_cat_symvers = GEN $@
cmd_cat_symvers = cat $(real-prereqs) > $@
ifndef KBUILD_MIXED_TREE
targets += .vmlinux.objs
.vmlinux.objs: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE
$(call if_changed,vmlinux_objs)
endif
vmlinux.o-if-present := $(wildcard vmlinux.o)
output-symdump := vmlinux.symvers
ifdef KBUILD_MODULES
output-symdump := $(if $(vmlinux.o-if-present), Module.symvers, modules-only.symvers)
missing-input := $(filter-out $(vmlinux.o-if-present),vmlinux.o)
targets += vmlinux.symvers
vmlinux.symvers: Module.symvers FORCE
$(call if_changed,vmlinux_symvers)
__modpost: $(if $(vmlinux.o-if-present),vmlinux.symvers,)
endif
# Overwrite values for mixed building (overwritting makes merges easier)
ifdef KBUILD_MIXED_TREE
targets += Module.symvers
Module.symvers: $(mixed-build-prefix)vmlinux.symvers modules-only.symvers FORCE
$(call if_changed,cat_symvers)
__modpost: Module.symvers
vmlinux.o-if-present :=
vmlinux.symvers-if-present := $(wildcard $(mixed-build-prefix)vmlinux.symvers)
modpost-args += $(addprefix -i ,$(vmlinux.symvers-if-present))
output-symdump := modules-only.symvers
missing-input := $(filter-out $(vmlinux.symvers-if-present),$(mixed-build-prefix)vmlinux.symvers)
endif
else
# set src + obj - they may be used in the modules's Makefile
obj := $(KBUILD_EXTMOD)
src := $(obj)
# Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS
include $(or $(wildcard $(src)/Kbuild), $(src)/Makefile)
module.symvers-if-present := $(wildcard Module.symvers)
output-symdump := $(KBUILD_EXTMOD)/Module.symvers
missing-input := $(filter-out $(module.symvers-if-present), Module.symvers)
modpost-args += -e $(addprefix -i ,$(module.symvers-if-present) $(KBUILD_EXTRA_SYMBOLS))
endif # ($(KBUILD_EXTMOD),)
ifneq ($(KBUILD_MODPOST_WARN)$(missing-input),)
modpost-args += -w
endif
modorder-if-needed := $(if $(KBUILD_MODULES), $(MODORDER))
MODPOST = scripts/mod/modpost
# Read out modules.order to pass in modpost.
# Otherwise, allmodconfig would fail with "Argument list too long".
quiet_cmd_modpost = MODPOST $@
cmd_modpost = \
$(if $(missing-input), \
echo >&2 "WARNING: $(missing-input) is missing."; \
echo >&2 " Modules may not have dependencies or modversions."; \
echo >&2 " You may get many unresolved symbol warnings.";) \
sed 's/ko$$/o/' $(or $(modorder-if-needed), /dev/null) | $(MODPOST) $(modpost-args) -T - $(vmlinux.o-if-present)
targets += $(output-symdump)
$(output-symdump): $(modorder-if-needed) $(vmlinux.o-if-present) $(module.symvers-if-present) $(MODPOST) FORCE
$(call if_changed,modpost)
__modpost: $(output-symdump)
PHONY += FORCE
FORCE:
existing-targets := $(wildcard $(sort $(targets)))
-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
.PHONY: $(PHONY)