diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/Makefile | 55 | ||||
-rw-r--r-- | scripts/Makefile.asm-generic | 58 | ||||
-rw-r--r-- | scripts/Makefile.build | 513 | ||||
-rw-r--r-- | scripts/Makefile.clang | 39 | ||||
-rw-r--r-- | scripts/Makefile.clean | 63 | ||||
-rw-r--r-- | scripts/Makefile.compiler | 74 | ||||
-rw-r--r-- | scripts/Makefile.debug | 44 | ||||
-rw-r--r-- | scripts/Makefile.defconf | 29 | ||||
-rw-r--r-- | scripts/Makefile.dtbinst | 39 | ||||
-rw-r--r-- | scripts/Makefile.extrawarn | 217 | ||||
-rw-r--r-- | scripts/Makefile.gcc-plugins | 63 | ||||
-rw-r--r-- | scripts/Makefile.headersinst | 84 | ||||
-rw-r--r-- | scripts/Makefile.host | 160 | ||||
-rw-r--r-- | scripts/Makefile.kasan | 78 | ||||
-rw-r--r-- | scripts/Makefile.kcov | 6 | ||||
-rw-r--r-- | scripts/Makefile.kcsan | 26 | ||||
-rw-r--r-- | scripts/Makefile.kmsan | 8 | ||||
-rw-r--r-- | scripts/Makefile.lib | 579 | ||||
-rw-r--r-- | scripts/Makefile.modfinal | 81 | ||||
-rw-r--r-- | scripts/Makefile.modinst | 163 | ||||
-rw-r--r-- | scripts/Makefile.modpost | 155 | ||||
-rw-r--r-- | scripts/Makefile.package | 274 | ||||
-rw-r--r-- | scripts/Makefile.randstruct | 17 | ||||
-rw-r--r-- | scripts/Makefile.ubsan | 15 | ||||
-rw-r--r-- | scripts/Makefile.userprogs | 45 | ||||
-rw-r--r-- | scripts/Makefile.vmlinux | 54 | ||||
-rw-r--r-- | scripts/Makefile.vmlinux_o | 105 |
27 files changed, 3044 insertions, 0 deletions
diff --git a/scripts/Makefile b/scripts/Makefile new file mode 100644 index 0000000000..576cf64be6 --- /dev/null +++ b/scripts/Makefile @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-2.0 +### +# scripts contains sources for various helper programs used throughout +# the kernel for the build process. + +hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms +hostprogs-always-$(BUILD_C_RECORDMCOUNT) += recordmcount +hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable +hostprogs-always-$(CONFIG_ASN1) += asn1_compiler +hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file +hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert +hostprogs-always-$(CONFIG_RUST_KERNEL_DOCTESTS) += rustdoc_test_builder +hostprogs-always-$(CONFIG_RUST_KERNEL_DOCTESTS) += rustdoc_test_gen +always-$(CONFIG_RUST) += target.json + +filechk_rust_target = $< < include/config/auto.conf + +$(obj)/target.json: scripts/generate_rust_target include/config/auto.conf FORCE + $(call filechk,rust_target) + +hostprogs += generate_rust_target +generate_rust_target-rust := y +rustdoc_test_builder-rust := y +rustdoc_test_gen-rust := y + +HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include +HOSTLDLIBS_sorttable = -lpthread +HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include +HOSTCFLAGS_sign-file.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null) +HOSTLDLIBS_sign-file = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) + +ifdef CONFIG_UNWINDER_ORC +ifeq ($(ARCH),x86_64) +ARCH := x86 +endif +HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include +HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED +endif + +ifdef CONFIG_BUILDTIME_MCOUNT_SORT +HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED +endif + +# The following programs are only built on demand +hostprogs += unifdef + +# The module linker script is preprocessed on demand +targets += module.lds + +subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins +subdir-$(CONFIG_MODVERSIONS) += genksyms +subdir-$(CONFIG_SECURITY_SELINUX) += selinux + +# Let clean descend into subdirs +subdir- += basic dtc gdb kconfig mod diff --git a/scripts/Makefile.asm-generic b/scripts/Makefile.asm-generic new file mode 100644 index 0000000000..8d01b37b76 --- /dev/null +++ b/scripts/Makefile.asm-generic @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0 +# include/asm-generic contains a lot of files that are used +# verbatim by several architectures. +# +# This Makefile reads the file arch/$(SRCARCH)/include/(uapi/)/asm/Kbuild +# and for each file listed in this file with generic-y creates +# a small wrapper file in arch/$(SRCARCH)/include/generated/(uapi/)/asm. + +PHONY := all +all: + +src := $(subst /generated,,$(obj)) + +include $(srctree)/scripts/Kbuild.include +-include $(kbuild-file) + +# $(generic)/Kbuild lists mandatory-y. Exclude um since it is a special case. +ifneq ($(SRCARCH),um) +include $(srctree)/$(generic)/Kbuild +endif + +redundant := $(filter $(mandatory-y) $(generated-y), $(generic-y)) +redundant += $(foreach f, $(generic-y), $(if $(wildcard $(srctree)/$(src)/$(f)),$(f))) +redundant := $(sort $(redundant)) +$(if $(redundant),\ + $(warning redundant generic-y found in $(src)/Kbuild: $(redundant))) + +# If arch does not implement mandatory headers, fallback to asm-generic ones. +mandatory-y := $(filter-out $(generated-y), $(mandatory-y)) +generic-y += $(foreach f, $(mandatory-y), $(if $(wildcard $(srctree)/$(src)/$(f)),,$(f))) + +generic-y := $(addprefix $(obj)/, $(generic-y)) +generated-y := $(addprefix $(obj)/, $(generated-y)) + +# Remove stale wrappers when the corresponding files are removed from generic-y +old-headers := $(wildcard $(obj)/*.h) +unwanted := $(filter-out $(generic-y) $(generated-y),$(old-headers)) + +quiet_cmd_wrap = WRAP $@ + cmd_wrap = echo "\#include <asm-generic/$*.h>" > $@ + +quiet_cmd_remove = REMOVE $(unwanted) + cmd_remove = rm -f $(unwanted) + +all: $(generic-y) + $(if $(unwanted),$(call cmd,remove)) + @: + +$(obj)/%.h: + $(call cmd,wrap) + +# Create output directory. Skip it if at least one old header exists +# since we know the output directory already exists. +ifeq ($(old-headers),) +$(shell mkdir -p $(obj)) +endif + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.build b/scripts/Makefile.build new file mode 100644 index 0000000000..82e3fb19fd --- /dev/null +++ b/scripts/Makefile.build @@ -0,0 +1,513 @@ +# SPDX-License-Identifier: GPL-2.0 +# ========================================================================== +# Building +# ========================================================================== + +src := $(obj) + +PHONY := $(obj)/ +$(obj)/: + +# Init all relevant variables used in kbuild files so +# 1) they have correct type +# 2) they do not inherit any value from the environment +obj-y := +obj-m := +lib-y := +lib-m := +always-y := +always-m := +targets := +subdir-y := +subdir-m := +EXTRA_AFLAGS := +EXTRA_CFLAGS := +EXTRA_CPPFLAGS := +EXTRA_LDFLAGS := +asflags-y := +ccflags-y := +rustflags-y := +cppflags-y := +ldflags-y := + +subdir-asflags-y := +subdir-ccflags-y := + +# Read auto.conf if it exists, otherwise ignore +-include include/config/auto.conf + +include $(srctree)/scripts/Kbuild.include +include $(srctree)/scripts/Makefile.compiler +include $(kbuild-file) +include $(srctree)/scripts/Makefile.lib + +# Do not include hostprogs rules unless needed. +# $(sort ...) is used here to remove duplicated words and excessive spaces. +hostprogs := $(sort $(hostprogs)) +ifneq ($(hostprogs),) +include $(srctree)/scripts/Makefile.host +endif + +# Do not include userprogs rules unless needed. +# $(sort ...) is used here to remove duplicated words and excessive spaces. +userprogs := $(sort $(userprogs)) +ifneq ($(userprogs),) +include $(srctree)/scripts/Makefile.userprogs +endif + +ifndef obj +$(warning kbuild: Makefile.build is included improperly) +endif + +ifeq ($(need-modorder),) +ifneq ($(obj-m),) +$(warning $(patsubst %.o,'%.ko',$(obj-m)) will not be built even though obj-m is specified.) +$(warning You cannot use subdir-y/m to visit a module Makefile. Use obj-y/m instead.) +endif +endif + +# =========================================================================== + +# subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...) +subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y))) +subdir-modorder := $(sort $(filter %/modules.order, $(obj-m))) + +targets-for-builtin := $(extra-y) + +ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) +targets-for-builtin += $(obj)/lib.a +endif + +ifdef need-builtin +targets-for-builtin += $(obj)/built-in.a +endif + +targets-for-modules := $(foreach x, o mod, \ + $(patsubst %.o, %.$x, $(filter %.o, $(obj-m)))) + +ifdef need-modorder +targets-for-modules += $(obj)/modules.order +endif + +targets += $(targets-for-builtin) $(targets-for-modules) + +# Linus' kernel sanity checking tool +ifeq ($(KBUILD_CHECKSRC),1) + quiet_cmd_checksrc = CHECK $< + cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< +else ifeq ($(KBUILD_CHECKSRC),2) + quiet_cmd_force_checksrc = CHECK $< + cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< +endif + +ifneq ($(KBUILD_EXTRA_WARN),) + cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $(KDOCFLAGS) \ + $(if $(findstring 2, $(KBUILD_EXTRA_WARN)), -Wall) \ + $< +endif + +# Compile C sources (.c) +# --------------------------------------------------------------------------- + +quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ + cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS) $(CC_FLAGS_LTO), $(c_flags)) -fverbose-asm -S -o $@ $< + +$(obj)/%.s: $(src)/%.c FORCE + $(call if_changed_dep,cc_s_c) + +quiet_cmd_cpp_i_c = CPP $(quiet_modtag) $@ +cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< + +$(obj)/%.i: $(src)/%.c FORCE + $(call if_changed_dep,cpp_i_c) + +genksyms = scripts/genksyms/genksyms \ + $(if $(1), -T $(2)) \ + $(if $(KBUILD_PRESERVE), -p) \ + -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) + +# These mirror gensymtypes_S and co below, keep them in synch. +cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) + +quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ + cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null + +$(obj)/%.symtypes : $(src)/%.c FORCE + $(call cmd,cc_symtypes_c) + +# LLVM assembly +# Generate .ll files from .c +quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@ + cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -fno-discard-value-names -o $@ $< + +$(obj)/%.ll: $(src)/%.c FORCE + $(call if_changed_dep,cc_ll_c) + +# C (.c) files +# The C file is compiled and updated dependency information is generated. +# (See cmd_cc_o_c + relevant part of rule_cc_o_c) + +is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y) + +# When a module consists of a single object, there is no reason to keep LLVM IR. +# Make $(LD) covert LLVM IR to ELF here. +ifdef CONFIG_LTO_CLANG +cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) +endif + +quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ + $(cmd_ld_single_m) \ + $(cmd_objtool) + +ifdef CONFIG_MODVERSIONS +# When module versioning is enabled the following steps are executed: +# o compile a <file>.o from <file>.c +# o if <file>.o doesn't contain a __export_symbol_*, i.e. does +# not export symbols, it's done. +# o otherwise, we calculate symbol versions using the good old +# genksyms on the preprocessed source and dump them into the .cmd file. +# o modpost will extract versions from that file and create *.c files that will +# be compiled and linked to the kernel and/or modules. + +gen_symversions = \ + if $(NM) $@ 2>/dev/null | grep -q ' __export_symbol_'; then \ + $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ + >> $(dot-target).cmd; \ + fi + +cmd_gen_symversions_c = $(call gen_symversions,c) + +endif + +ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT +# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl +ifdef BUILD_C_RECORDMCOUNT +ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") + RECORDMCOUNT_FLAGS = -w +endif +# Due to recursion, we must skip empty.o. +# The empty.o file is created in the make process in order to determine +# the target endianness and word size. It is made before all other C +# files, including recordmcount. +sub_cmd_record_mcount = \ + if [ $(@) != "scripts/mod/empty.o" ]; then \ + $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \ + fi; +recordmcount_source := $(srctree)/scripts/recordmcount.c \ + $(srctree)/scripts/recordmcount.h +else +sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ + "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ + "$(if $(CONFIG_64BIT),64,32)" \ + "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \ + "$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \ + "$(if $(part-of-module),1,0)" "$(@)"; +recordmcount_source := $(srctree)/scripts/recordmcount.pl +endif # BUILD_C_RECORDMCOUNT +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 + +is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y) + +$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y)) + +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))) +endif + +define rule_cc_o_c + $(call cmd_and_fixdep,cc_o_c) + $(call cmd,checksrc) + $(call cmd,checkdoc) + $(call cmd,gen_objtooldep) + $(call cmd,gen_symversions_c) + $(call cmd,record_mcount) + $(call cmd,warn_shared_object) +endef + +define rule_as_o_S + $(call cmd_and_fixdep,as_o_S) + $(call cmd,gen_objtooldep) + $(call cmd,gen_symversions_S) + $(call cmd,warn_shared_object) +endef + +# Built-in and composite module parts +$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE + $(call if_changed_rule,cc_o_c) + $(call cmd,force_checksrc) + +# To make this rule robust against "Argument list too long" error, +# ensure to add $(obj)/ prefix by a shell command. +cmd_mod = printf '%s\n' $(call real-search, $*.o, .o, -objs -y -m) | \ + $(AWK) '!x[$$0]++ { print("$(obj)/"$$0) }' > $@ + +$(obj)/%.mod: FORCE + $(call if_changed,mod) + +quiet_cmd_cc_lst_c = MKLST $@ + cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ + $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ + System.map $(OBJDUMP) > $@ + +$(obj)/%.lst: $(src)/%.c FORCE + $(call if_changed_dep,cc_lst_c) + +# Compile Rust sources (.rs) +# --------------------------------------------------------------------------- + +rust_allowed_features := new_uninit + +# `--out-dir` is required to avoid temporaries being created by `rustc` in the +# current working directory, which may be not accessible in the out-of-tree +# modules case. +rust_common_cmd = \ + RUST_MODFILE=$(modfile) $(RUSTC_OR_CLIPPY) $(rust_flags) \ + -Zallow-features=$(rust_allowed_features) \ + -Zcrate-attr=no_std \ + -Zcrate-attr='feature($(rust_allowed_features))' \ + --extern alloc --extern kernel \ + --crate-type rlib -L $(objtree)/rust/ \ + --crate-name $(basename $(notdir $@)) \ + --out-dir $(dir $@) --emit=dep-info=$(depfile) + +# `--emit=obj`, `--emit=asm` and `--emit=llvm-ir` imply a single codegen unit +# will be used. We explicitly request `-Ccodegen-units=1` in any case, and +# the compiler shows a warning if it is not 1. However, if we ever stop +# requesting it explicitly and we start using some other `--emit` that does not +# imply it (and for which codegen is performed), then we would be out of sync, +# i.e. the outputs we would get for the different single targets (e.g. `.ll`) +# would not match each other. + +quiet_cmd_rustc_o_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_o_rs = $(rust_common_cmd) --emit=obj=$@ $< + +$(obj)/%.o: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_o_rs) + +quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_rsi_rs = \ + $(rust_common_cmd) -Zunpretty=expanded $< >$@; \ + command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@ + +$(obj)/%.rsi: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_rsi_rs) + +quiet_cmd_rustc_s_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_s_rs = $(rust_common_cmd) --emit=asm=$@ $< + +$(obj)/%.s: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_s_rs) + +quiet_cmd_rustc_ll_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ + cmd_rustc_ll_rs = $(rust_common_cmd) --emit=llvm-ir=$@ $< + +$(obj)/%.ll: $(src)/%.rs FORCE + $(call if_changed_dep,rustc_ll_rs) + +# Compile assembler sources (.S) +# --------------------------------------------------------------------------- + +# .S file exports must have their C prototypes defined in asm/asm-prototypes.h +# or a file that it includes, in order to get versioned symbols. We build a +# dummy C file that includes asm-prototypes and the EXPORT_SYMBOL lines from +# the .S file (with trailing ';'), and run genksyms on that, to extract vers. +# +# This is convoluted. The .S file must first be preprocessed to run guards and +# expand names, then the resulting exports must be constructed into plain +# EXPORT_SYMBOL(symbol); to build our dummy C file, and that gets preprocessed +# to make the genksyms input. +# +# These mirror gensymtypes_c and co above, keep them in synch. +cmd_gensymtypes_S = \ + { echo "\#include <linux/kernel.h>" ; \ + echo "\#include <asm/asm-prototypes.h>" ; \ + $(NM) $@ | sed -n 's/.* __export_symbol_\(.*\)/EXPORT_SYMBOL(\1);/p' ; } | \ + $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) + +quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ + cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null + +$(obj)/%.symtypes : $(src)/%.S FORCE + $(call cmd,cc_symtypes_S) + + +quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@ +cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< + +$(obj)/%.s: $(src)/%.S FORCE + $(call if_changed_dep,cpp_s_S) + +quiet_cmd_as_o_S = AS $(quiet_modtag) $@ + cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) + +ifdef CONFIG_ASM_MODVERSIONS + +# versioning matches the C process described above, with difference that +# we parse asm-prototypes.h C header to get function definitions. + +cmd_gen_symversions_S = $(call gen_symversions,S) + +endif + +$(obj)/%.o: $(src)/%.S FORCE + $(call if_changed_rule,as_o_S) + +targets += $(filter-out $(subdir-builtin), $(real-obj-y)) +targets += $(filter-out $(subdir-modorder), $(real-obj-m)) +targets += $(real-dtb-y) $(lib-y) $(always-y) + +# Linker scripts preprocessor (.lds.S -> .lds) +# --------------------------------------------------------------------------- +quiet_cmd_cpp_lds_S = LDS $@ + cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \ + -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< + +$(obj)/%.lds: $(src)/%.lds.S FORCE + $(call if_changed_dep,cpp_lds_S) + +# ASN.1 grammar +# --------------------------------------------------------------------------- +quiet_cmd_asn1_compiler = ASN.1 $(basename $@).[ch] + cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \ + $(basename $@).c $(basename $@).h + +$(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler + $(call cmd,asn1_compiler) + +# Build the compiled-in targets +# --------------------------------------------------------------------------- + +# To build objects in subdirs, we need to descend into the directories +$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; +$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; + +# +# Rule to compile a set of .o files into one .a file (without symbol table) +# +# To make this rule robust against "Argument list too long" error, +# remove $(obj)/ prefix, and restore it by a shell command. + +quiet_cmd_ar_builtin = AR $@ + cmd_ar_builtin = rm -f $@; \ + $(if $(real-prereqs), printf "$(obj)/%s " $(patsubst $(obj)/%,%,$(real-prereqs)) | xargs) \ + $(AR) cDPrST $@ + +$(obj)/built-in.a: $(real-obj-y) FORCE + $(call if_changed,ar_builtin) + +# +# Rule to create modules.order file +# +# Create commands to either record .ko file or cat modules.order from +# a subdirectory +# Add $(obj-m) as the prerequisite to avoid updating the timestamp of +# modules.order unless contained modules are updated. + +cmd_modules_order = { $(foreach m, $(real-prereqs), \ + $(if $(filter %/modules.order, $m), cat $m, echo $m);) :; } \ + > $@ + +$(obj)/modules.order: $(obj-m) FORCE + $(call if_changed,modules_order) + +# +# Rule to compile a set of .o files into one .a file (with symbol table) +# + +$(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 $@ @$(patsubst %.o,%.mod,$@) $(cmd_objtool) + +define rule_ld_multi_m + $(call cmd_and_savecmd,ld_multi_m) + $(call cmd,gen_objtooldep) +endef + +$(multi-obj-m): objtool-enabled := $(delay-objtool) +$(multi-obj-m): part-of-module := y +$(multi-obj-m): %.o: %.mod FORCE + $(call if_changed_rule,ld_multi_m) +$(call multi_depend, $(multi-obj-m), .o, -objs -y -m) + +# Add intermediate targets: +# When building objects with specific suffix patterns, add intermediate +# targets that the final targets are derived from. +intermediate_targets = $(foreach sfx, $(2), \ + $(patsubst %$(strip $(1)),%$(sfx), \ + $(filter %$(strip $(1)), $(targets)))) +# %.asn1.o <- %.asn1.[ch] <- %.asn1 +# %.dtb.o <- %.dtb.S <- %.dtb <- %.dts +# %.dtbo.o <- %.dtbo.S <- %.dtbo <- %.dtso +# %.lex.o <- %.lex.c <- %.l +# %.tab.o <- %.tab.[ch] <- %.y +targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \ + $(call intermediate_targets, .dtb.o, .dtb.S .dtb) \ + $(call intermediate_targets, .dtbo.o, .dtbo.S .dtbo) \ + $(call intermediate_targets, .lex.o, .lex.c) \ + $(call intermediate_targets, .tab.o, .tab.c .tab.h) + +# Build +# --------------------------------------------------------------------------- + +$(obj)/: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \ + $(if $(KBUILD_MODULES), $(targets-for-modules)) \ + $(subdir-ym) $(always-y) + @: + +# Single targets +# --------------------------------------------------------------------------- + +single-subdirs := $(foreach d, $(subdir-ym), $(if $(filter $d/%, $(MAKECMDGOALS)), $d)) +single-subdir-goals := $(filter $(addsuffix /%, $(single-subdirs)), $(MAKECMDGOALS)) + +$(single-subdir-goals): $(single-subdirs) + @: + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-ym) +$(subdir-ym): + $(Q)$(MAKE) $(build)=$@ \ + need-builtin=$(if $(filter $@/built-in.a, $(subdir-builtin)),1) \ + need-modorder=$(if $(filter $@/modules.order, $(subdir-modorder)),1) \ + $(filter $@/%, $(single-subdir-goals)) + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE + +FORCE: + +targets += $(filter-out $(single-subdir-goals), $(MAKECMDGOALS)) +targets := $(filter-out $(PHONY), $(targets)) + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +# Create directories for object files if they do not exist +obj-dirs := $(sort $(patsubst %/,%, $(dir $(targets)))) +# If targets exist, their directories apparently exist. Skip mkdir. +existing-dirs := $(sort $(patsubst %/,%, $(dir $(existing-targets)))) +obj-dirs := $(strip $(filter-out $(existing-dirs), $(obj-dirs))) +ifneq ($(obj-dirs),) +$(shell mkdir -p $(obj-dirs)) +endif + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang new file mode 100644 index 0000000000..6c23c6af79 --- /dev/null +++ b/scripts/Makefile.clang @@ -0,0 +1,39 @@ +# Individual arch/{arch}/Makefiles should use -EL/-EB to set intended +# endianness and -m32/-m64 to set word size based on Kconfigs instead of +# relying on the target triple. +CLANG_TARGET_FLAGS_arm := arm-linux-gnueabi +CLANG_TARGET_FLAGS_arm64 := aarch64-linux-gnu +CLANG_TARGET_FLAGS_hexagon := hexagon-linux-musl +CLANG_TARGET_FLAGS_loongarch := loongarch64-linux-gnusf +CLANG_TARGET_FLAGS_m68k := m68k-linux-gnu +CLANG_TARGET_FLAGS_mips := mipsel-linux-gnu +CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu +CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu +CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu +CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu +CLANG_TARGET_FLAGS_um := $(CLANG_TARGET_FLAGS_$(SUBARCH)) +CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH)) + +ifeq ($(CLANG_TARGET_FLAGS),) +$(error add '--target=' option to scripts/Makefile.clang) +else +CLANG_FLAGS += --target=$(CLANG_TARGET_FLAGS) +endif + +ifeq ($(LLVM_IAS),0) +CLANG_FLAGS += -fno-integrated-as +GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) +CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE)) +else +CLANG_FLAGS += -fintegrated-as +endif +# By default, clang only warns when it encounters an unknown warning flag or +# certain optimization flags it knows it has not implemented. +# Make it behave more like gcc by erroring when these flags are encountered +# so they can be implemented or wrapped in cc-option. +CLANG_FLAGS += -Werror=unknown-warning-option +CLANG_FLAGS += -Werror=ignored-optimization-argument +CLANG_FLAGS += -Werror=option-ignored +CLANG_FLAGS += -Werror=unused-command-line-argument +KBUILD_CPPFLAGS += $(CLANG_FLAGS) +export CLANG_FLAGS diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean new file mode 100644 index 0000000000..f2cb4d7ffd --- /dev/null +++ b/scripts/Makefile.clean @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0 +# ========================================================================== +# Cleaning up +# ========================================================================== + +src := $(obj) + +PHONY := __clean +__clean: + +include $(srctree)/scripts/Kbuild.include +include $(kbuild-file) + +# Figure out what we need to build from the various variables +# ========================================================================== + +subdir-ymn := $(sort $(subdir-y) $(subdir-m) $(subdir-) \ + $(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m) $(obj-)))) + +# Add subdir path + +subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn)) + +# build a list of files to remove, usually relative to the current +# directory + +__clean-files := \ + $(clean-files) $(targets) $(hostprogs) $(userprogs) \ + $(extra-y) $(extra-m) $(extra-) \ + $(always-y) $(always-m) $(always-) \ + $(hostprogs-always-y) $(hostprogs-always-m) $(hostprogs-always-) \ + $(userprogs-always-y) $(userprogs-always-m) $(userprogs-always-) + +__clean-files := $(filter-out $(no-clean-files), $(__clean-files)) + +__clean-files := $(wildcard $(addprefix $(obj)/, $(__clean-files))) + +# ========================================================================== + +# To make this rule robust against "Argument list too long" error, +# remove $(obj)/ prefix, and restore it by a shell command. +quiet_cmd_clean = CLEAN $(obj) + cmd_clean = printf '$(obj)/%s ' $(patsubst $(obj)/%,%,$(__clean-files)) | xargs rm -rf + +__clean: $(subdir-ymn) +ifneq ($(strip $(__clean-files)),) + $(call cmd,clean) +endif + @: + + +# =========================================================================== +# Generic stuff +# =========================================================================== + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-ymn) +$(subdir-ymn): + $(Q)$(MAKE) $(clean)=$@ + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.compiler b/scripts/Makefile.compiler new file mode 100644 index 0000000000..8fcb427405 --- /dev/null +++ b/scripts/Makefile.compiler @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# cc-cross-prefix +# Usage: CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu- m68k-linux-) +# Return first <prefix> where a <prefix>gcc is found in PATH. +# If no gcc found in PATH with listed prefixes return nothing +# +# Note: '2>/dev/null' is here to force Make to invoke a shell. Otherwise, it +# would try to directly execute the shell builtin 'command'. This workaround +# should be kept for a long time since this issue was fixed only after the +# GNU Make 4.2.1 release. +cc-cross-prefix = $(firstword $(foreach c, $(1), \ + $(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c)))) + +# output directory for tests below +TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ + +# try-run +# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise) +# Exit code chooses option. "$$TMP" serves as a temporary file and is +# automatically cleaned up. +try-run = $(shell set -e; \ + TMP=$(TMPOUT)/tmp; \ + trap "rm -rf $(TMPOUT)" EXIT; \ + mkdir -p $(TMPOUT); \ + if ($(1)) >/dev/null 2>&1; \ + then echo "$(2)"; \ + else echo "$(3)"; \ + fi) + +# as-option +# Usage: aflags-y += $(call as-option,-Wa$(comma)-isa=foo,) + +as-option = $(call try-run,\ + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(1) -c -x assembler-with-cpp /dev/null -o "$$TMP",$(1),$(2)) + +# as-instr +# Usage: aflags-y += $(call as-instr,instr,option1,option2) + +as-instr = $(call try-run,\ + printf "%b\n" "$(1)" | $(CC) -Werror $(CLANG_FLAGS) $(KBUILD_AFLAGS) -c -x assembler-with-cpp -o "$$TMP" -,$(2),$(3)) + +# __cc-option +# Usage: MY_CFLAGS += $(call __cc-option,$(CC),$(MY_CFLAGS),-march=winchip-c6,-march=i586) +__cc-option = $(call try-run,\ + $(1) -Werror $(2) $(3) -c -x c /dev/null -o "$$TMP",$(3),$(4)) + +# cc-option +# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) + +cc-option = $(call __cc-option, $(CC),\ + $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS),$(1),$(2)) + +# cc-option-yn +# Usage: flag := $(call cc-option-yn,-march=winchip-c6) +cc-option-yn = $(call try-run,\ + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) + +# cc-disable-warning +# Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) +cc-disable-warning = $(call try-run,\ + $(CC) -Werror $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) + +# gcc-min-version +# Usage: cflags-$(call gcc-min-version, 70100) += -foo +gcc-min-version = $(call test-ge, $(CONFIG_GCC_VERSION), $1) + +# clang-min-version +# Usage: cflags-$(call clang-min-version, 110000) += -foo +clang-min-version = $(call test-ge, $(CONFIG_CLANG_VERSION), $1) + +# ld-option +# Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) +ld-option = $(call try-run, $(LD) $(KBUILD_LDFLAGS) $(1) -v,$(1),$(2),$(3)) diff --git a/scripts/Makefile.debug b/scripts/Makefile.debug new file mode 100644 index 0000000000..059ff38fe0 --- /dev/null +++ b/scripts/Makefile.debug @@ -0,0 +1,44 @@ +DEBUG_CFLAGS := +DEBUG_RUSTFLAGS := + +debug-flags-y := -g + +ifdef CONFIG_DEBUG_INFO_SPLIT +DEBUG_CFLAGS += -gsplit-dwarf +endif + +debug-flags-$(CONFIG_DEBUG_INFO_DWARF4) += -gdwarf-4 +debug-flags-$(CONFIG_DEBUG_INFO_DWARF5) += -gdwarf-5 +ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_AS_IS_GNU),yy) +# Clang does not pass -g or -gdwarf-* option down to GAS. +# Add -Wa, prefix to explicitly specify the flags. +KBUILD_AFLAGS += $(addprefix -Wa$(comma), $(debug-flags-y)) +endif +DEBUG_CFLAGS += $(debug-flags-y) +KBUILD_AFLAGS += $(debug-flags-y) + +ifdef CONFIG_DEBUG_INFO_REDUCED +DEBUG_CFLAGS += -fno-var-tracking +DEBUG_RUSTFLAGS += -Cdebuginfo=1 +ifdef CONFIG_CC_IS_GCC +DEBUG_CFLAGS += -femit-struct-debug-baseonly +endif +else +DEBUG_RUSTFLAGS += -Cdebuginfo=2 +endif + +ifdef CONFIG_DEBUG_INFO_COMPRESSED_ZLIB +DEBUG_CFLAGS += -gz=zlib +KBUILD_AFLAGS += -gz=zlib +KBUILD_LDFLAGS += --compress-debug-sections=zlib +else ifdef CONFIG_DEBUG_INFO_COMPRESSED_ZSTD +DEBUG_CFLAGS += -gz=zstd +KBUILD_AFLAGS += -gz=zstd +KBUILD_LDFLAGS += --compress-debug-sections=zstd +endif + +KBUILD_CFLAGS += $(DEBUG_CFLAGS) +export DEBUG_CFLAGS + +KBUILD_RUSTFLAGS += $(DEBUG_RUSTFLAGS) +export DEBUG_RUSTFLAGS diff --git a/scripts/Makefile.defconf b/scripts/Makefile.defconf new file mode 100644 index 0000000000..ab271b2051 --- /dev/null +++ b/scripts/Makefile.defconf @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0 +# Configuration heplers + +# Creates 'merged defconfigs' +# --------------------------------------------------------------------------- +# Usage: +# $(call merge_into_defconfig,base_config,config_fragment1 config_fragment2 ...) +# +# Input config fragments without '.config' suffix +define merge_into_defconfig + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \ + -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/$(1) \ + $(foreach config,$(2),$(srctree)/arch/$(ARCH)/configs/$(config).config) + +$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig +endef + + +# Creates 'merged defconfigs without warning about overrides' +# --------------------------------------------------------------------------- +# Usage: +# $(call merge_into_defconfig_override,base_config,config_fragment1 config_fragment2 ...) +# +# Input config fragments without '.config' suffix +define merge_into_defconfig_override + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \ + -Q -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/$(1) \ + $(foreach config,$(2),$(srctree)/arch/$(ARCH)/configs/$(config).config) + +$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig +endef diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst new file mode 100644 index 0000000000..4405d5b675 --- /dev/null +++ b/scripts/Makefile.dtbinst @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: GPL-2.0 +# ========================================================================== +# Installing dtb files +# +# Installs all dtb files listed in $(dtb-y) either in the +# INSTALL_DTBS_PATH directory or the default location: +# +# $INSTALL_PATH/dtbs/$KERNELRELEASE +# ========================================================================== + +src := $(obj) + +PHONY := __dtbs_install +__dtbs_install: + +include include/config/auto.conf +include $(srctree)/scripts/Kbuild.include +include $(kbuild-file) + +dtbs := $(addprefix $(dst)/, $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS),$(dtb-))) +subdirs := $(addprefix $(obj)/, $(subdir-y) $(subdir-m)) + +__dtbs_install: $(dtbs) $(subdirs) + @: + +quiet_cmd_dtb_install = INSTALL $@ + cmd_dtb_install = install -D $< $@ + +$(dst)/%.dtb: $(obj)/%.dtb + $(call cmd,dtb_install) + +$(dst)/%.dtbo: $(obj)/%.dtbo + $(call cmd,dtb_install) + +PHONY += $(subdirs) +$(subdirs): + $(Q)$(MAKE) $(dtbinst)=$@ dst=$(if $(CONFIG_ARCH_WANT_FLAT_DTB_INSTALL),$(dst),$(patsubst $(obj)/%,$(dst)/%,$@)) + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn new file mode 100644 index 0000000000..2fe6f2828d --- /dev/null +++ b/scripts/Makefile.extrawarn @@ -0,0 +1,217 @@ +# SPDX-License-Identifier: GPL-2.0 +# ========================================================================== +# make W=... settings +# +# There are four warning groups enabled by W=1, W=2, W=3, and W=e +# They are independent, and can be combined like W=12 or W=123e. +# ========================================================================== + +# Default set of warnings, always enabled +KBUILD_CFLAGS += -Wall +KBUILD_CFLAGS += -Wundef +KBUILD_CFLAGS += -Werror=implicit-function-declaration +KBUILD_CFLAGS += -Werror=implicit-int +KBUILD_CFLAGS += -Werror=return-type +KBUILD_CFLAGS += -Werror=strict-prototypes +KBUILD_CFLAGS += -Wno-format-security +KBUILD_CFLAGS += -Wno-trigraphs +KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,) +KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) + +ifneq ($(CONFIG_FRAME_WARN),0) +KBUILD_CFLAGS += -Wframe-larger-than=$(CONFIG_FRAME_WARN) +endif + +KBUILD_CPPFLAGS-$(CONFIG_WERROR) += -Werror +KBUILD_CPPFLAGS += $(KBUILD_CPPFLAGS-y) +KBUILD_CFLAGS-$(CONFIG_CC_NO_ARRAY_BOUNDS) += -Wno-array-bounds + +ifdef CONFIG_CC_IS_CLANG +# The kernel builds with '-std=gnu11' so use of GNU extensions is acceptable. +KBUILD_CFLAGS += -Wno-gnu +else + +# gcc inanely warns about local variables called 'main' +KBUILD_CFLAGS += -Wno-main +endif + +# These warnings generated too much noise in a regular build. +# Use make W=1 to enable them (see scripts/Makefile.extrawarn) +KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) +KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) + +# These result in bogus false positives +KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer) + +# Variable Length Arrays (VLAs) should not be used anywhere in the kernel +KBUILD_CFLAGS += -Wvla + +# disable pointer signed / unsigned warnings in gcc 4.0 +KBUILD_CFLAGS += -Wno-pointer-sign + +# In order to make sure new function cast mismatches are not introduced +# in the kernel (to avoid tripping CFI checking), the kernel should be +# globally built with -Wcast-function-type. +KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type) + +# The allocators already balk at large sizes, so silence the compiler +# warnings for bounds checks involving those possible values. While +# -Wno-alloc-size-larger-than would normally be used here, earlier versions +# of gcc (<9.1) weirdly don't handle the option correctly when _other_ +# warnings are produced (?!). Using -Walloc-size-larger-than=SIZE_MAX +# doesn't work (as it is documented to), silently resolving to "0" prior to +# version 9.1 (and producing an error more recently). Numeric values larger +# than PTRDIFF_MAX also don't work prior to version 9.1, which are silently +# ignored, continuing to default to PTRDIFF_MAX. So, left with no other +# choice, we must perform a versioned check to disable this warning. +# https://lore.kernel.org/lkml/20210824115859.187f272f@canb.auug.org.au +KBUILD_CFLAGS-$(call gcc-min-version, 90100) += -Wno-alloc-size-larger-than +KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) + +# Prohibit date/time macros, which would make the build non-deterministic +KBUILD_CFLAGS += -Werror=date-time + +# enforce correct pointer usage +KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) + +# Require designated initializers for all marked structures +KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) + +# Warn if there is an enum types mismatch +KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion) + +# backward compatibility +KBUILD_EXTRA_WARN ?= $(KBUILD_ENABLE_EXTRA_GCC_CHECKS) + +ifeq ("$(origin W)", "command line") + KBUILD_EXTRA_WARN := $(W) +endif + +export KBUILD_EXTRA_WARN + +# +# W=1 - warnings which may be relevant and do not occur too often +# +ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) + +KBUILD_CFLAGS += -Wextra -Wunused -Wno-unused-parameter +KBUILD_CFLAGS += -Wmissing-declarations +KBUILD_CFLAGS += $(call cc-option, -Wrestrict) +KBUILD_CFLAGS += -Wmissing-format-attribute +KBUILD_CFLAGS += -Wmissing-prototypes +KBUILD_CFLAGS += -Wold-style-definition +KBUILD_CFLAGS += -Wmissing-include-dirs +KBUILD_CFLAGS += $(call cc-option, -Wunused-but-set-variable) +KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable) +KBUILD_CFLAGS += $(call cc-option, -Wpacked-not-aligned) +KBUILD_CFLAGS += $(call cc-option, -Wformat-overflow) +KBUILD_CFLAGS += $(call cc-option, -Wformat-truncation) +KBUILD_CFLAGS += $(call cc-option, -Wstringop-overflow) +KBUILD_CFLAGS += $(call cc-option, -Wstringop-truncation) + +KBUILD_CPPFLAGS += -Wundef +KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 + +else + +# Some diagnostics enabled by default are noisy. +# Suppress them by using -Wno... except for W=1. +KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) +KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) +KBUILD_CFLAGS += $(call cc-disable-warning, restrict) +KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned) +KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow) +KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation) +KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow) +KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) + +ifdef CONFIG_CC_IS_CLANG +# Clang before clang-16 would warn on default argument promotions. +ifneq ($(call clang-min-version, 160000),y) +# Disable -Wformat +KBUILD_CFLAGS += -Wno-format +# Then re-enable flags that were part of the -Wformat group that aren't +# problematic. +KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier +KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull +# Requires clang-12+. +ifeq ($(call clang-min-version, 120000),y) +KBUILD_CFLAGS += -Wformat-insufficient-args +endif +endif +KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) +KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare +KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access) +KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict) +endif + +endif + +# +# W=2 - warnings which occur quite often but may still be relevant +# +ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) + +KBUILD_CFLAGS += -Wdisabled-optimization +KBUILD_CFLAGS += -Wshadow +KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) +KBUILD_CFLAGS += -Wmissing-field-initializers +KBUILD_CFLAGS += -Wtype-limits +KBUILD_CFLAGS += $(call cc-option, -Wmaybe-uninitialized) +KBUILD_CFLAGS += $(call cc-option, -Wunused-macros) + +ifdef CONFIG_CC_IS_CLANG +KBUILD_CFLAGS += -Winitializer-overrides +endif + +KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2 + +else + +# The following turn off the warnings enabled by -Wextra +KBUILD_CFLAGS += -Wno-missing-field-initializers +KBUILD_CFLAGS += -Wno-type-limits +KBUILD_CFLAGS += -Wno-shift-negative-value + +ifdef CONFIG_CC_IS_CLANG +KBUILD_CFLAGS += -Wno-initializer-overrides +else +KBUILD_CFLAGS += -Wno-maybe-uninitialized +endif + +endif + +# +# W=3 - more obscure warnings, can most likely be ignored +# +ifneq ($(findstring 3, $(KBUILD_EXTRA_WARN)),) + +KBUILD_CFLAGS += -Wbad-function-cast +KBUILD_CFLAGS += -Wcast-align +KBUILD_CFLAGS += -Wcast-qual +KBUILD_CFLAGS += -Wconversion +KBUILD_CFLAGS += -Wpacked +KBUILD_CFLAGS += -Wpadded +KBUILD_CFLAGS += -Wpointer-arith +KBUILD_CFLAGS += -Wredundant-decls +KBUILD_CFLAGS += -Wsign-compare +KBUILD_CFLAGS += -Wswitch-default +KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat) + +KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3 + +else + +# The following turn off the warnings enabled by -Wextra +KBUILD_CFLAGS += -Wno-sign-compare + +endif + +# +# W=e - error out on warnings +# +ifneq ($(findstring e, $(KBUILD_EXTRA_WARN)),) + +KBUILD_CFLAGS += -Werror + +endif diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins new file mode 100644 index 0000000000..e4deaf5fa5 --- /dev/null +++ b/scripts/Makefile.gcc-plugins @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0 + +gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \ + += -DLATENT_ENTROPY_PLUGIN +ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY + DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable -ULATENT_ENTROPY_PLUGIN +endif +export DISABLE_LATENT_ENTROPY_PLUGIN + +gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) \ + += -fplugin-arg-structleak_plugin-verbose +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF) \ + += -fplugin-arg-structleak_plugin-byref +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \ + += -fplugin-arg-structleak_plugin-byref-all +ifdef CONFIG_GCC_PLUGIN_STRUCTLEAK + DISABLE_STRUCTLEAK_PLUGIN += -fplugin-arg-structleak_plugin-disable +endif +export DISABLE_STRUCTLEAK_PLUGIN +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \ + += -DSTRUCTLEAK_PLUGIN + +gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += -DSTACKLEAK_PLUGIN +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += -fplugin-arg-stackleak_plugin-arch=$(SRCARCH) +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK_VERBOSE) \ + += -fplugin-arg-stackleak_plugin-verbose +ifdef CONFIG_GCC_PLUGIN_STACKLEAK + DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable +endif +export DISABLE_STACKLEAK_PLUGIN + +gcc-plugin-$(CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK) += arm_ssp_per_task_plugin.so +ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK + DISABLE_ARM_SSP_PER_TASK_PLUGIN += -fplugin-arg-arm_ssp_per_task_plugin-disable +endif +export DISABLE_ARM_SSP_PER_TASK_PLUGIN + +# All the plugin CFLAGS are collected here in case a build target needs to +# filter them out of the KBUILD_CFLAGS. +GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) +export GCC_PLUGINS_CFLAGS + +# Add the flags to the build! +KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) + +# Some plugins are enabled outside of this Makefile, but they still need to +# be included in GCC_PLUGIN so they can get built. +gcc-plugin-external-$(CONFIG_GCC_PLUGIN_SANCOV) \ + += sancov_plugin.so +gcc-plugin-external-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ + += randomize_layout_plugin.so + +# All enabled GCC plugins are collected here for building in +# scripts/gcc-scripts/Makefile. +GCC_PLUGIN := $(gcc-plugin-y) $(gcc-plugin-external-y) +export GCC_PLUGIN diff --git a/scripts/Makefile.headersinst b/scripts/Makefile.headersinst new file mode 100644 index 0000000000..029d85bb0b --- /dev/null +++ b/scripts/Makefile.headersinst @@ -0,0 +1,84 @@ +# SPDX-License-Identifier: GPL-2.0 +# ========================================================================== +# Installing headers +# +# All headers under include/uapi, include/generated/uapi, +# arch/<arch>/include/uapi and arch/<arch>/include/generated/uapi are +# exported. +# They are preprocessed to remove __KERNEL__ section of the file. +# +# ========================================================================== + +PHONY := __headers +__headers: + +include $(srctree)/scripts/Kbuild.include + +src := $(srctree)/$(obj) +gen := $(objtree)/$(subst include/,include/generated/,$(obj)) +dst := usr/include + +-include $(src)/Kbuild + +# $(filter %/, ...) is a workaround for GNU Make <= 4.2.1, where +# $(wildcard $(src)/*/) contains not only directories but also regular files. +src-subdirs := $(patsubst $(src)/%/,%,$(filter %/, $(wildcard $(src)/*/))) +gen-subdirs := $(patsubst $(gen)/%/,%,$(filter %/, $(wildcard $(gen)/*/))) +all-subdirs := $(sort $(src-subdirs) $(gen-subdirs)) + +src-headers := $(if $(src-subdirs), $(shell cd $(src) && find $(src-subdirs) -name '*.h')) +src-headers := $(filter-out $(no-export-headers), $(src-headers)) +gen-headers := $(if $(gen-subdirs), $(shell cd $(gen) && find $(gen-subdirs) -name '*.h')) +gen-headers := $(filter-out $(no-export-headers), $(gen-headers)) + +# If the same header is exported from source and generated directories, +# the former takes precedence, but this should be warned. +duplicated := $(filter $(gen-headers), $(src-headers)) +$(if $(duplicated), $(warning duplicated header export: $(duplicated))) + +gen-headers := $(filter-out $(duplicated), $(gen-headers)) + +# Add dst path prefix +all-subdirs := $(addprefix $(dst)/, $(all-subdirs)) +src-headers := $(addprefix $(dst)/, $(src-headers)) +gen-headers := $(addprefix $(dst)/, $(gen-headers)) +all-headers := $(src-headers) $(gen-headers) + +# Work out what needs to be removed +old-subdirs := $(wildcard $(all-subdirs)) +old-headers := $(if $(old-subdirs),$(shell find $(old-subdirs) -name '*.h')) +unwanted := $(filter-out $(all-headers), $(old-headers)) + +# Create directories +existing-dirs := $(sort $(dir $(old-headers))) +wanted-dirs := $(sort $(dir $(all-headers))) +new-dirs := $(filter-out $(existing-dirs), $(wanted-dirs)) +$(if $(new-dirs), $(shell mkdir -p $(new-dirs))) + +# Rules +quiet_cmd_install = HDRINST $@ + cmd_install = $(CONFIG_SHELL) $(srctree)/scripts/headers_install.sh $< $@ + +$(src-headers): $(dst)/%.h: $(src)/%.h $(srctree)/scripts/headers_install.sh FORCE + $(call if_changed,install) + +$(gen-headers): $(dst)/%.h: $(gen)/%.h $(srctree)/scripts/headers_install.sh FORCE + $(call if_changed,install) + +quiet_cmd_remove = REMOVE $(unwanted) + cmd_remove = rm -f $(unwanted) + +__headers: $(all-headers) +ifneq ($(unwanted),) + $(call cmd,remove) +endif + @: + +existing-headers := $(filter $(old-headers), $(all-headers)) + +-include $(foreach f,$(existing-headers),$(dir $(f)).$(notdir $(f)).cmd) + +PHONY += FORCE +FORCE: + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.host b/scripts/Makefile.host new file mode 100644 index 0000000000..8f7f842b54 --- /dev/null +++ b/scripts/Makefile.host @@ -0,0 +1,160 @@ +# SPDX-License-Identifier: GPL-2.0 + +# LEX +# --------------------------------------------------------------------------- +quiet_cmd_flex = LEX $@ + cmd_flex = $(LEX) -o$@ -L $< + +$(obj)/%.lex.c: $(src)/%.l FORCE + $(call if_changed,flex) + +# YACC +# --------------------------------------------------------------------------- +quiet_cmd_bison = YACC $(basename $@).[ch] + cmd_bison = $(YACC) -o $(basename $@).c --defines=$(basename $@).h -t -l $< + +$(obj)/%.tab.c $(obj)/%.tab.h: $(src)/%.y FORCE + $(call if_changed,bison) + +# ========================================================================== +# Building binaries on the host system +# Binaries are used during the compilation of the kernel, for example +# to preprocess a data file. +# +# Both C and C++ are supported, but preferred language is C for such utilities. +# Rust is also supported, but it may only be used in scenarios where a Rust +# toolchain is required to be available (e.g. when `CONFIG_RUST` is enabled). +# +# Sample syntax (see Documentation/kbuild/makefiles.rst for reference) +# hostprogs := bin2hex +# Will compile bin2hex.c and create an executable named bin2hex +# +# hostprogs := lxdialog +# lxdialog-objs := checklist.o lxdialog.o +# Will compile lxdialog.c and checklist.c, and then link the executable +# lxdialog, based on checklist.o and lxdialog.o +# +# hostprogs := qconf +# qconf-cxxobjs := qconf.o +# qconf-objs := menu.o +# Will compile qconf as a C++ program, and menu as a C program. +# They are linked as C++ code to the executable qconf +# +# hostprogs := target +# target-rust := y +# Will compile `target` as a Rust program, using `target.rs` as the crate root. +# The crate may consist of several source files. + +# C code +# Executables compiled from a single .c file +host-csingle := $(foreach m,$(hostprogs), \ + $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-rust),,$(m))) + +# C executables linked based on several .o files +host-cmulti := $(foreach m,$(hostprogs),\ + $(if $($(m)-cxxobjs)$($(m)-rust),,$(if $($(m)-objs),$(m)))) + +# Object (.o) files compiled from .c files +host-cobjs := $(sort $(foreach m,$(hostprogs),$($(m)-objs))) + +# C++ code +# C++ executables compiled from at least one .cc file +# and zero or more .c files +host-cxxmulti := $(foreach m,$(hostprogs),$(if $($(m)-cxxobjs),$(m))) + +# C++ Object (.o) files compiled from .cc files +host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) + +# Rust code +# Executables compiled from a single Rust crate (which may consist of +# one or more .rs files) +host-rust := $(foreach m,$(hostprogs),$(if $($(m)-rust),$(m))) + +host-csingle := $(addprefix $(obj)/,$(host-csingle)) +host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) +host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) +host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) +host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) +host-rust := $(addprefix $(obj)/,$(host-rust)) + +##### +# Handle options to gcc. Support building with separate output directory + +hostc_flags = -Wp,-MMD,$(depfile) \ + $(KBUILD_HOSTCFLAGS) $(HOST_EXTRACFLAGS) \ + $(HOSTCFLAGS_$(target-stem).o) +hostcxx_flags = -Wp,-MMD,$(depfile) \ + $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \ + $(HOSTCXXFLAGS_$(target-stem).o) + +# `--out-dir` is required to avoid temporaries being created by `rustc` in the +# current working directory, which may be not accessible in the out-of-tree +# modules case. +hostrust_flags = --out-dir $(dir $@) --emit=dep-info=$(depfile) \ + $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \ + $(HOSTRUSTFLAGS_$(target-stem)) + +# $(objtree)/$(obj) for including generated headers from checkin source files +ifeq ($(KBUILD_EXTMOD),) +ifdef building_out_of_srctree +hostc_flags += -I $(objtree)/$(obj) +hostcxx_flags += -I $(objtree)/$(obj) +endif +endif + +##### +# Compile programs on the host + +# Create executable from a single .c file +# host-csingle -> Executable +quiet_cmd_host-csingle = HOSTCC $@ + cmd_host-csingle = $(HOSTCC) $(hostc_flags) $(KBUILD_HOSTLDFLAGS) -o $@ $< \ + $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem)) +$(host-csingle): $(obj)/%: $(src)/%.c FORCE + $(call if_changed_dep,host-csingle) + +# Link an executable based on list of .o files, all plain c +# host-cmulti -> executable +quiet_cmd_host-cmulti = HOSTLD $@ + cmd_host-cmulti = $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ \ + $(addprefix $(obj)/, $($(target-stem)-objs)) \ + $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem)) +$(host-cmulti): FORCE + $(call if_changed,host-cmulti) +$(call multi_depend, $(host-cmulti), , -objs) + +# Create .o file from a single .c file +# host-cobjs -> .o +quiet_cmd_host-cobjs = HOSTCC $@ + cmd_host-cobjs = $(HOSTCC) $(hostc_flags) -c -o $@ $< +$(host-cobjs): $(obj)/%.o: $(src)/%.c FORCE + $(call if_changed_dep,host-cobjs) + +# Link an executable based on list of .o files, a mixture of .c and .cc +# host-cxxmulti -> executable +quiet_cmd_host-cxxmulti = HOSTLD $@ + cmd_host-cxxmulti = $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -o $@ \ + $(foreach o,objs cxxobjs,\ + $(addprefix $(obj)/, $($(target-stem)-$(o)))) \ + $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(target-stem)) +$(host-cxxmulti): FORCE + $(call if_changed,host-cxxmulti) +$(call multi_depend, $(host-cxxmulti), , -objs -cxxobjs) + +# Create .o file from a single .cc (C++) file +quiet_cmd_host-cxxobjs = HOSTCXX $@ + cmd_host-cxxobjs = $(HOSTCXX) $(hostcxx_flags) -c -o $@ $< +$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE + $(call if_changed_dep,host-cxxobjs) + +# Create executable from a single Rust crate (which may consist of +# one or more `.rs` files) +# host-rust -> Executable +quiet_cmd_host-rust = HOSTRUSTC $@ + cmd_host-rust = \ + $(HOSTRUSTC) $(hostrust_flags) --emit=link=$@ $< +$(host-rust): $(obj)/%: $(src)/%.rs FORCE + $(call if_changed_dep,host-rust) + +targets += $(host-csingle) $(host-cmulti) $(host-cobjs) \ + $(host-cxxmulti) $(host-cxxobjs) $(host-rust) diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan new file mode 100644 index 0000000000..390658a2d5 --- /dev/null +++ b/scripts/Makefile.kasan @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: GPL-2.0 + +ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX +# Safe for compiler to generate meminstrinsic calls in uninstrumented files. +CFLAGS_KASAN_NOSANITIZE := +else +# Don't let compiler generate memintrinsic calls in uninstrumented files +# because they are instrumented. +CFLAGS_KASAN_NOSANITIZE := -fno-builtin +endif + +KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET) + +cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1))) + +ifdef CONFIG_KASAN_STACK + stack_enable := 1 +else + stack_enable := 0 +endif + +ifdef CONFIG_KASAN_GENERIC + +ifdef CONFIG_KASAN_INLINE + call_threshold := 10000 +else + call_threshold := 0 +endif + +CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address + +# -fasan-shadow-offset fails without -fsanitize +CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \ + -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \ + $(call cc-option, -fsanitize=kernel-address \ + -mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET))) + +ifeq ($(strip $(CFLAGS_KASAN_SHADOW)),) + CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL) +else + # Now add all the compiler specific options that are valid standalone + CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \ + $(call cc-param,asan-globals=1) \ + $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \ + $(call cc-param,asan-instrument-allocas=1) +endif + +CFLAGS_KASAN += $(call cc-param,asan-stack=$(stack_enable)) + +# Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*() +# instead. With compilers that don't support this option, compiler-inserted +# memintrinsics won't be checked by KASAN on GENERIC_ENTRY architectures. +CFLAGS_KASAN += $(call cc-param,asan-kernel-mem-intrinsic-prefix=1) + +endif # CONFIG_KASAN_GENERIC + +ifdef CONFIG_KASAN_SW_TAGS + +ifdef CONFIG_KASAN_INLINE + instrumentation_flags := $(call cc-param,hwasan-mapping-offset=$(KASAN_SHADOW_OFFSET)) +else + instrumentation_flags := $(call cc-param,hwasan-instrument-with-calls=1) +endif + +CFLAGS_KASAN := -fsanitize=kernel-hwaddress \ + $(call cc-param,hwasan-instrument-stack=$(stack_enable)) \ + $(call cc-param,hwasan-use-short-granules=0) \ + $(call cc-param,hwasan-inline-all-checks=0) \ + $(instrumentation_flags) + +# Instrument memcpy/memset/memmove calls by using instrumented __hwasan_mem*(). +ifeq ($(call clang-min-version, 150000)$(call gcc-min-version, 130000),y) +CFLAGS_KASAN += $(call cc-param,hwasan-kernel-mem-intrinsic-prefix=1) +endif + +endif # CONFIG_KASAN_SW_TAGS + +export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov new file mode 100644 index 0000000000..67e8cfe347 --- /dev/null +++ b/scripts/Makefile.kcov @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc +kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS) += -fsanitize-coverage=trace-cmp +kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV) += -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so + +export CFLAGS_KCOV := $(kcov-flags-y) diff --git a/scripts/Makefile.kcsan b/scripts/Makefile.kcsan new file mode 100644 index 0000000000..19f693b68a --- /dev/null +++ b/scripts/Makefile.kcsan @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0 +# GCC and Clang accept backend options differently. Do not wrap in cc-option, +# because Clang accepts "--param" even if it is unused. +ifdef CONFIG_CC_IS_CLANG +cc-param = -mllvm -$(1) +else +cc-param = --param $(1) +endif + +# Keep most options here optional, to allow enabling more compilers if absence +# of some options does not break KCSAN nor causes false positive reports. +kcsan-cflags := -fsanitize=thread -fno-optimize-sibling-calls \ + $(call cc-option,$(call cc-param,tsan-compound-read-before-write=1),$(call cc-option,$(call cc-param,tsan-instrument-read-before-write=1))) \ + $(call cc-param,tsan-distinguish-volatile=1) + +ifdef CONFIG_CC_IS_GCC +# GCC started warning about operations unsupported by the TSan runtime. But +# KCSAN != TSan, so just ignore these warnings. +kcsan-cflags += -Wno-tsan +endif + +ifndef CONFIG_KCSAN_WEAK_MEMORY +kcsan-cflags += $(call cc-option,$(call cc-param,tsan-instrument-func-entry-exit=0)) +endif + +export CFLAGS_KCSAN := $(kcsan-cflags) diff --git a/scripts/Makefile.kmsan b/scripts/Makefile.kmsan new file mode 100644 index 0000000000..b5b0aa6132 --- /dev/null +++ b/scripts/Makefile.kmsan @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +kmsan-cflags := -fsanitize=kernel-memory + +ifdef CONFIG_KMSAN_CHECK_PARAM_RETVAL +kmsan-cflags += -fsanitize-memory-param-retval +endif + +export CFLAGS_KMSAN := $(kmsan-cflags) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib new file mode 100644 index 0000000000..68d0134bdb --- /dev/null +++ b/scripts/Makefile.lib @@ -0,0 +1,579 @@ +# SPDX-License-Identifier: GPL-2.0 +# Backward compatibility +asflags-y += $(EXTRA_AFLAGS) +ccflags-y += $(EXTRA_CFLAGS) +cppflags-y += $(EXTRA_CPPFLAGS) +ldflags-y += $(EXTRA_LDFLAGS) + +# flags that take effect in current and sub directories +KBUILD_AFLAGS += $(subdir-asflags-y) +KBUILD_CFLAGS += $(subdir-ccflags-y) +KBUILD_RUSTFLAGS += $(subdir-rustflags-y) + +# Figure out what we need to build from the various variables +# =========================================================================== + +# When an object is listed to be built compiled-in and modular, +# only build the compiled-in version +obj-m := $(filter-out $(obj-y),$(obj-m)) + +# Libraries are always collected in one lib file. +# Filter out objects already built-in +lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) + +# Subdirectories we need to descend into +subdir-ym := $(sort $(subdir-y) $(subdir-m) \ + $(patsubst %/,%, $(filter %/, $(obj-y) $(obj-m)))) + +# Handle objects in subdirs: +# - If we encounter foo/ in $(obj-y), replace it by foo/built-in.a and +# foo/modules.order +# - If we encounter foo/ in $(obj-m), replace it by foo/modules.order +# +# Generate modules.order to determine modorder. Unfortunately, we don't have +# information about ordering between -y and -m subdirs. Just put -y's first. + +ifdef need-modorder +obj-m := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m)) +else +obj-m := $(filter-out %/, $(obj-m)) +endif + +ifdef need-builtin +obj-y := $(patsubst %/, %/built-in.a, $(obj-y)) +else +obj-y := $(filter-out %/, $(obj-y)) +endif + +# Expand $(foo-objs) $(foo-y) etc. by replacing their individuals +suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s)))) +# List composite targets that are constructed by combining other targets +multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $m))) +# List primitive targets that are compiled from source files +real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $(call suffix-search, $m, $2, $3), $m)) + +# If $(foo-objs), $(foo-y), $(foo-m), or $(foo-) exists, foo.o is a composite object +multi-obj-y := $(call multi-search, $(obj-y), .o, -objs -y) +multi-obj-m := $(call multi-search, $(obj-m), .o, -objs -y -m) +multi-obj-ym := $(multi-obj-y) $(multi-obj-m) + +# Replace multi-part objects by their individual parts, +# including built-in.a from subdirectories +real-obj-y := $(call real-search, $(obj-y), .o, -objs -y) +real-obj-m := $(call real-search, $(obj-m), .o, -objs -y -m) + +always-y += $(always-m) + +# hostprogs-always-y += foo +# ... is a shorthand for +# hostprogs += foo +# always-y += foo +hostprogs += $(hostprogs-always-y) $(hostprogs-always-m) +always-y += $(hostprogs-always-y) $(hostprogs-always-m) + +# userprogs-always-y is likewise. +userprogs += $(userprogs-always-y) $(userprogs-always-m) +always-y += $(userprogs-always-y) $(userprogs-always-m) + +# DTB +# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built +dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-) + +# Composite DTB (i.e. DTB constructed by overlay) +multi-dtb-y := $(call multi-search, $(dtb-y), .dtb, -dtbs) +# Primitive DTB compiled from *.dts +real-dtb-y := $(call real-search, $(dtb-y), .dtb, -dtbs) +# Base DTB that overlay is applied onto (each first word of $(*-dtbs) expansion) +base-dtb-y := $(foreach m, $(multi-dtb-y), $(firstword $(call suffix-search, $m, .dtb, -dtbs))) + +always-y += $(dtb-y) + +# Add subdir path + +ifneq ($(obj),.) +extra-y := $(addprefix $(obj)/,$(extra-y)) +always-y := $(addprefix $(obj)/,$(always-y)) +targets := $(addprefix $(obj)/,$(targets)) +obj-m := $(addprefix $(obj)/,$(obj-m)) +lib-y := $(addprefix $(obj)/,$(lib-y)) +real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) +real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) +multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m)) +multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y)) +real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y)) +subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) +endif + +# Finds the multi-part object the current object will be linked into. +# If the object belongs to two or more multi-part objects, list them all. +modname-multi = $(sort $(foreach m,$(multi-obj-ym),\ + $(if $(filter $*.o, $(call suffix-search, $m, .o, -objs -y -m)),$(m:.o=)))) + +__modname = $(or $(modname-multi),$(basetarget)) + +modname = $(subst $(space),:,$(__modname)) +modfile = $(addprefix $(obj)/,$(__modname)) + +# target with $(obj)/ and its suffix stripped +target-stem = $(basename $(patsubst $(obj)/%,%,$@)) + +# These flags are needed for modversions and compiling, so we define them here +# $(modname_flags) defines KBUILD_MODNAME as the name of the module it will +# end up in (or would, if it gets compiled in) +name-fix-token = $(subst $(comma),_,$(subst -,_,$1)) +name-fix = $(call stringify,$(call name-fix-token,$1)) +basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) +modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \ + -D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname)) +modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile)) + +_c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(ccflags-remove-y), \ + $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ccflags-y)) \ + $(CFLAGS_$(target-stem).o)) +_rust_flags = $(filter-out $(RUSTFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(rustflags-remove-y), \ + $(KBUILD_RUSTFLAGS) $(rustflags-y)) \ + $(RUSTFLAGS_$(target-stem).o)) +_a_flags = $(filter-out $(AFLAGS_REMOVE_$(target-stem).o), \ + $(filter-out $(asflags-remove-y), \ + $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(asflags-y)) \ + $(AFLAGS_$(target-stem).o)) +_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds) + +# +# Enable gcov profiling flags for a file, directory or for all files depending +# on variables GCOV_PROFILE_obj.o, GCOV_PROFILE and CONFIG_GCOV_PROFILE_ALL +# (in this order) +# +ifeq ($(CONFIG_GCOV_KERNEL),y) +_c_flags += $(if $(patsubst n%,, \ + $(GCOV_PROFILE_$(basetarget).o)$(GCOV_PROFILE)$(CONFIG_GCOV_PROFILE_ALL)), \ + $(CFLAGS_GCOV)) +endif + +# +# Enable address sanitizer flags for kernel except some files or directories +# we don't want to check (depends on variables KASAN_SANITIZE_obj.o, KASAN_SANITIZE) +# +ifeq ($(CONFIG_KASAN),y) +ifneq ($(CONFIG_KASAN_HW_TAGS),y) +_c_flags += $(if $(patsubst n%,, \ + $(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \ + $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE)) +endif +endif + +ifeq ($(CONFIG_KMSAN),y) +_c_flags += $(if $(patsubst n%,, \ + $(KMSAN_SANITIZE_$(basetarget).o)$(KMSAN_SANITIZE)y), \ + $(CFLAGS_KMSAN)) +_c_flags += $(if $(patsubst n%,, \ + $(KMSAN_ENABLE_CHECKS_$(basetarget).o)$(KMSAN_ENABLE_CHECKS)y), \ + , -mllvm -msan-disable-checks=1) +endif + +ifeq ($(CONFIG_UBSAN),y) +_c_flags += $(if $(patsubst n%,, \ + $(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \ + $(CFLAGS_UBSAN)) +endif + +ifeq ($(CONFIG_KCOV),y) +_c_flags += $(if $(patsubst n%,, \ + $(KCOV_INSTRUMENT_$(basetarget).o)$(KCOV_INSTRUMENT)$(CONFIG_KCOV_INSTRUMENT_ALL)), \ + $(CFLAGS_KCOV)) +endif + +# +# Enable KCSAN flags except some files or directories we don't want to check +# (depends on variables KCSAN_SANITIZE_obj.o, KCSAN_SANITIZE) +# +ifeq ($(CONFIG_KCSAN),y) +_c_flags += $(if $(patsubst n%,, \ + $(KCSAN_SANITIZE_$(basetarget).o)$(KCSAN_SANITIZE)y), \ + $(CFLAGS_KCSAN)) +# Some uninstrumented files provide implied barriers required to avoid false +# positives: set KCSAN_INSTRUMENT_BARRIERS for barrier instrumentation only. +_c_flags += $(if $(patsubst n%,, \ + $(KCSAN_INSTRUMENT_BARRIERS_$(basetarget).o)$(KCSAN_INSTRUMENT_BARRIERS)n), \ + -D__KCSAN_INSTRUMENT_BARRIERS__) +endif + +# $(srctree)/$(src) for including checkin headers from generated source files +# $(objtree)/$(obj) for including generated headers from checkin source files +ifeq ($(KBUILD_EXTMOD),) +ifdef building_out_of_srctree +_c_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) +_a_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) +_cpp_flags += -I $(srctree)/$(src) -I $(objtree)/$(obj) +endif +endif + +part-of-module = $(if $(filter $(basename $@).o, $(real-obj-m)),y) +quiet_modtag = $(if $(part-of-module),[M], ) + +modkern_cflags = \ + $(if $(part-of-module), \ + $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ + $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL) $(modfile_flags)) + +modkern_rustflags = \ + $(if $(part-of-module), \ + $(KBUILD_RUSTFLAGS_MODULE) $(RUSTFLAGS_MODULE), \ + $(KBUILD_RUSTFLAGS_KERNEL) $(RUSTFLAGS_KERNEL)) + +modkern_aflags = $(if $(part-of-module), \ + $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE), \ + $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)) + +c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ + -include $(srctree)/include/linux/compiler_types.h \ + $(_c_flags) $(modkern_cflags) \ + $(basename_flags) $(modname_flags) + +rust_flags = $(_rust_flags) $(modkern_rustflags) @$(objtree)/include/generated/rustc_cfg + +a_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ + $(_a_flags) $(modkern_aflags) + +cpp_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ + $(_cpp_flags) + +ld_flags = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) + +DTC_INCLUDE := $(srctree)/scripts/dtc/include-prefixes + +dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ + $(addprefix -I,$(DTC_INCLUDE)) \ + -undef -D__DTS__ + +ifdef CONFIG_OBJTOOL + +objtool := $(objtree)/tools/objtool/objtool + +objtool-args-$(CONFIG_HAVE_JUMP_LABEL_HACK) += --hacks=jump_label +objtool-args-$(CONFIG_HAVE_NOINSTR_HACK) += --hacks=noinstr +objtool-args-$(CONFIG_CALL_DEPTH_TRACKING) += --hacks=skylake +objtool-args-$(CONFIG_X86_KERNEL_IBT) += --ibt +objtool-args-$(CONFIG_FINEIBT) += --cfi +objtool-args-$(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL) += --mcount +ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL +objtool-args-$(CONFIG_HAVE_OBJTOOL_NOP_MCOUNT) += --mnop +endif +objtool-args-$(CONFIG_UNWINDER_ORC) += --orc +objtool-args-$(CONFIG_RETPOLINE) += --retpoline +objtool-args-$(CONFIG_RETHUNK) += --rethunk +objtool-args-$(CONFIG_SLS) += --sls +objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval +objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call +objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess +objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable +objtool-args-$(CONFIG_PREFIX_SYMBOLS) += --prefix=$(CONFIG_FUNCTION_PADDING_BYTES) + +objtool-args = $(objtool-args-y) \ + $(if $(delay-objtool), --link) \ + $(if $(part-of-module), --module) + +delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT)) + +cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool-args) $@) +cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd) + +endif # CONFIG_OBJTOOL + +# Useful for describing the dependency of composite objects +# Usage: +# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) +define multi_depend +$(foreach m, $1, \ + $(eval $m: \ + $(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3)))) +endef + +# Copy a file +# =========================================================================== +# 'cp' preserves permissions. If you use it to copy a file in read-only srctree, +# the copy would be read-only as well, leading to an error when executing the +# rule next time. Use 'cat' instead in order to generate a writable file. +quiet_cmd_copy = COPY $@ + cmd_copy = cat $< > $@ + +$(obj)/%: $(src)/%_shipped + $(call cmd,copy) + +# Commands useful for building a boot image +# =========================================================================== +# +# Use as following: +# +# target: source(s) FORCE +# $(if_changed,ld/objcopy/gzip) +# +# and add target to 'targets' so that we know we have to +# read in the saved command line + +# Linking +# --------------------------------------------------------------------------- + +quiet_cmd_ld = LD $@ + cmd_ld = $(LD) $(ld_flags) $(real-prereqs) -o $@ + +# Archive +# --------------------------------------------------------------------------- + +quiet_cmd_ar = AR $@ + cmd_ar = rm -f $@; $(AR) cDPrsT $@ $(real-prereqs) + +# Objcopy +# --------------------------------------------------------------------------- + +quiet_cmd_objcopy = OBJCOPY $@ +cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ + +# Gzip +# --------------------------------------------------------------------------- + +quiet_cmd_gzip = GZIP $@ + cmd_gzip = cat $(real-prereqs) | $(KGZIP) -n -f -9 > $@ + +# DTC +# --------------------------------------------------------------------------- +DTC ?= $(objtree)/scripts/dtc/dtc +DTC_FLAGS += -Wno-interrupt_provider \ + -Wno-unique_unit_address + +# Disable noisy checks by default +ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),) +DTC_FLAGS += -Wno-unit_address_vs_reg \ + -Wno-avoid_unnecessary_addr_size \ + -Wno-alias_paths \ + -Wno-graph_child_address \ + -Wno-simple_bus_reg +else +DTC_FLAGS += \ + -Wunique_unit_address_if_enabled +endif + +ifneq ($(findstring 2,$(KBUILD_EXTRA_WARN)),) +DTC_FLAGS += -Wnode_name_chars_strict \ + -Wproperty_name_chars_strict \ + -Winterrupt_provider \ + -Wunique_unit_address +endif + +DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) + +# Set -@ if the target is a base DTB that overlay is applied onto +DTC_FLAGS += $(if $(filter $(patsubst $(obj)/%,%,$@), $(base-dtb-y)), -@) + +# Generate an assembly file to wrap the output of the device tree compiler +quiet_cmd_wrap_S_dtb = WRAP $@ + cmd_wrap_S_dtb = { \ + symbase=__$(patsubst .%,%,$(suffix $<))_$(subst -,_,$(notdir $*)); \ + echo '\#include <asm-generic/vmlinux.lds.h>'; \ + echo '.section .dtb.init.rodata,"a"'; \ + echo '.balign STRUCT_ALIGNMENT'; \ + echo ".global $${symbase}_begin"; \ + echo "$${symbase}_begin:"; \ + echo '.incbin "$<" '; \ + echo ".global $${symbase}_end"; \ + echo "$${symbase}_end:"; \ + echo '.balign STRUCT_ALIGNMENT'; \ + } > $@ + +$(obj)/%.dtb.S: $(obj)/%.dtb FORCE + $(call if_changed,wrap_S_dtb) + +$(obj)/%.dtbo.S: $(obj)/%.dtbo FORCE + $(call if_changed,wrap_S_dtb) + +quiet_cmd_dtc = DTC $@ +cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ + $(DTC) -o $@ -b 0 \ + $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ + -d $(depfile).dtc.tmp $(dtc-tmp) ; \ + cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) + +quiet_cmd_fdtoverlay = DTOVL $@ + cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs) + +$(multi-dtb-y): FORCE + $(call if_changed,fdtoverlay) +$(call multi_depend, $(multi-dtb-y), .dtb, -dtbs) + +ifneq ($(CHECK_DTBS)$(CHECK_DT_BINDING),) +DT_CHECKER ?= dt-validate +DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m) +DT_BINDING_DIR := Documentation/devicetree/bindings +DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.json + +quiet_cmd_dtb = DTC_CHK $@ + cmd_dtb = $(cmd_dtc) ; $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ || true +else +quiet_cmd_dtb = $(quiet_cmd_dtc) + cmd_dtb = $(cmd_dtc) +endif + +$(obj)/%.dtb: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE + $(call if_changed_dep,dtb) + +$(obj)/%.dtbo: $(src)/%.dtso $(DTC) FORCE + $(call if_changed_dep,dtc) + +dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) + +# Bzip2 +# --------------------------------------------------------------------------- + +# Bzip2 and LZMA do not include size in file... so we have to fake that; +# append the size as a 32-bit littleendian number as gzip does. +size_append = printf $(shell \ +dec_size=0; \ +for F in $(real-prereqs); do \ + fsize=$$($(CONFIG_SHELL) $(srctree)/scripts/file-size.sh $$F); \ + dec_size=$$(expr $$dec_size + $$fsize); \ +done; \ +printf "%08x\n" $$dec_size | \ + sed 's/\(..\)/\1 /g' | { \ + read ch0 ch1 ch2 ch3; \ + for ch in $$ch3 $$ch2 $$ch1 $$ch0; do \ + printf '%s%03o' '\\' $$((0x$$ch)); \ + done; \ + } \ +) + +quiet_cmd_file_size = GEN $@ + cmd_file_size = $(size_append) > $@ + +quiet_cmd_bzip2 = BZIP2 $@ + cmd_bzip2 = cat $(real-prereqs) | $(KBZIP2) -9 > $@ + +quiet_cmd_bzip2_with_size = BZIP2 $@ + cmd_bzip2_with_size = { cat $(real-prereqs) | $(KBZIP2) -9; $(size_append); } > $@ + +# Lzma +# --------------------------------------------------------------------------- + +quiet_cmd_lzma = LZMA $@ + cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@ + +quiet_cmd_lzma_with_size = LZMA $@ + cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ + +quiet_cmd_lzo = LZO $@ + cmd_lzo = cat $(real-prereqs) | $(KLZOP) -9 > $@ + +quiet_cmd_lzo_with_size = LZO $@ + cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@ + +quiet_cmd_lz4 = LZ4 $@ + cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout > $@ + +quiet_cmd_lz4_with_size = LZ4 $@ + cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \ + $(size_append); } > $@ + +# U-Boot mkimage +# --------------------------------------------------------------------------- + +MKIMAGE := $(srctree)/scripts/mkuboot.sh + +# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces +# the number of overrides in arch makefiles +UIMAGE_ARCH ?= $(SRCARCH) +UIMAGE_COMPRESSION ?= $(or $(2),none) +UIMAGE_OPTS-y ?= +UIMAGE_TYPE ?= kernel +UIMAGE_LOADADDR ?= arch_must_set_this +UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR) +UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)' + +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(BASH) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \ + -C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \ + -T $(UIMAGE_TYPE) \ + -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \ + -n $(UIMAGE_NAME) -d $< $@ + +# XZ +# --------------------------------------------------------------------------- +# Use xzkern to compress the kernel image and xzmisc to compress other things. +# +# xzkern uses a big LZMA2 dictionary since it doesn't increase memory usage +# of the kernel decompressor. A BCJ filter is used if it is available for +# the target architecture. xzkern also appends uncompressed size of the data +# using size_append. The .xz format has the size information available at +# the end of the file too, but it's in more complex format and it's good to +# avoid changing the part of the boot code that reads the uncompressed size. +# Note that the bytes added by size_append will make the xz tool think that +# the file is corrupt. This is expected. +# +# xzmisc doesn't use size_append, so it can be used to create normal .xz +# files. xzmisc uses smaller LZMA2 dictionary than xzkern, because a very +# big dictionary would increase the memory usage too much in the multi-call +# decompression mode. A BCJ filter isn't used either. +quiet_cmd_xzkern = XZKERN $@ + cmd_xzkern = cat $(real-prereqs) | sh $(srctree)/scripts/xz_wrap.sh > $@ + +quiet_cmd_xzkern_with_size = XZKERN $@ + cmd_xzkern_with_size = { cat $(real-prereqs) | sh $(srctree)/scripts/xz_wrap.sh; \ + $(size_append); } > $@ + +quiet_cmd_xzmisc = XZMISC $@ + cmd_xzmisc = cat $(real-prereqs) | $(XZ) --check=crc32 --lzma2=dict=1MiB > $@ + +# ZSTD +# --------------------------------------------------------------------------- +# Appends the uncompressed size of the data using size_append. The .zst +# format has the size information available at the beginning of the file too, +# but it's in a more complex format and it's good to avoid changing the part +# of the boot code that reads the uncompressed size. +# +# Note that the bytes added by size_append will make the zstd tool think that +# the file is corrupt. This is expected. +# +# zstd uses a maximum window size of 8 MB. zstd22 uses a maximum window size of +# 128 MB. zstd22 is used for kernel compression because it is decompressed in a +# single pass, so zstd doesn't need to allocate a window buffer. When streaming +# decompression is used, like initramfs decompression, zstd22 should likely not +# be used because it would require zstd to allocate a 128 MB buffer. + +quiet_cmd_zstd = ZSTD $@ + cmd_zstd = cat $(real-prereqs) | $(ZSTD) -19 > $@ + +quiet_cmd_zstd22 = ZSTD22 $@ + cmd_zstd22 = cat $(real-prereqs) | $(ZSTD) -22 --ultra > $@ + +quiet_cmd_zstd22_with_size = ZSTD22 $@ + cmd_zstd22_with_size = { cat $(real-prereqs) | $(ZSTD) -22 --ultra; $(size_append); } > $@ + +# ASM offsets +# --------------------------------------------------------------------------- + +# Default sed regexp - multiline due to syntax constraints +# +# Use [:space:] because LLVM's integrated assembler inserts <tab> around +# the .ascii directive whereas GCC keeps the <space> as-is. +define sed-offsets + 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:; \ + /^->/{s:->#\(.*\):/* \1 */:; \ + s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ + s:->::; p;}' +endef + +# Use filechk to avoid rebuilds when a header changes, but the resulting file +# does not +define filechk_offsets + echo "#ifndef $2"; \ + echo "#define $2"; \ + echo "/*"; \ + echo " * DO NOT MODIFY."; \ + echo " *"; \ + echo " * This file was generated by Kbuild"; \ + echo " */"; \ + echo ""; \ + sed -ne $(sed-offsets) < $<; \ + echo ""; \ + echo "#endif" +endef diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal new file mode 100644 index 0000000000..b3a6aa8fbe --- /dev/null +++ b/scripts/Makefile.modfinal @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: GPL-2.0-only +# =========================================================================== +# Module final link +# =========================================================================== + +PHONY := __modfinal +__modfinal: + +include include/config/auto.conf +include $(srctree)/scripts/Kbuild.include + +# for c_flags +include $(srctree)/scripts/Makefile.lib + +# find all modules listed in modules.order +modules := $(call read-file, $(MODORDER)) + +__modfinal: $(modules:%.o=%.ko) + @: + +# modname and part-of-module are set to make c_flags define proper module flags +modname = $(notdir $(@:.mod.o=)) +part-of-module = y + +quiet_cmd_cc_o_c = CC [M] $@ + cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI) $(CFLAGS_GCOV), $(c_flags)) -c -o $@ $< + +%.mod.o: %.mod.c FORCE + $(call if_changed_dep,cc_o_c) + +ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) + +quiet_cmd_ld_ko_o = LD [M] $@ + cmd_ld_ko_o += \ + $(LD) -r $(KBUILD_LDFLAGS) \ + $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ + -T scripts/module.lds -o $@ $(filter %.o, $^); \ + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) + +quiet_cmd_btf_ko = BTF [M] $@ + cmd_btf_ko = \ + if [ ! -f vmlinux ]; then \ + printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ + else \ + LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \ + $(RESOLVE_BTFIDS) -b vmlinux $@; \ + fi; + +# Same as newer-prereqs, but allows to exclude specified extra dependencies +newer_prereqs_except = $(filter-out $(PHONY) $(1),$?) + +# Same as if_changed, but allows to exclude specified extra dependencies +if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ + $(cmd); \ + printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) + +# Re-generate module BTFs if either module's .ko or vmlinux changed +%.ko: %.o %.mod.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE + +$(call if_changed_except,ld_ko_o,vmlinux) +ifdef CONFIG_DEBUG_INFO_BTF_MODULES + +$(if $(newer-prereqs),$(call cmd,btf_ko)) +endif + +targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst new file mode 100644 index 0000000000..0afd754726 --- /dev/null +++ b/scripts/Makefile.modinst @@ -0,0 +1,163 @@ +# SPDX-License-Identifier: GPL-2.0 +# ========================================================================== +# Installing modules +# ========================================================================== + +PHONY := __modinst +__modinst: + +include include/config/auto.conf +include $(srctree)/scripts/Kbuild.include + +install-y := + +ifeq ($(KBUILD_EXTMOD)$(sign-only),) + +# remove the old directory and symlink +$(shell rm -fr $(MODLIB)/kernel $(MODLIB)/build) + +install-$(CONFIG_MODULES) += $(addprefix $(MODLIB)/, build modules.order) + +$(MODLIB)/build: FORCE + $(call cmd,symlink) + +quiet_cmd_symlink = SYMLINK $@ + cmd_symlink = ln -s $(CURDIR) $@ + +$(MODLIB)/modules.order: modules.order FORCE + $(call cmd,install_modorder) + +quiet_cmd_install_modorder = INSTALL $@ + cmd_install_modorder = sed 's:^\(.*\)\.o$$:kernel/\1.ko:' $< > $@ + +# Install modules.builtin(.modinfo) even when CONFIG_MODULES is disabled. +install-y += $(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo) + +$(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo): $(MODLIB)/%: % FORCE + $(call cmd,install) + +endif + +modules := $(call read-file, $(MODORDER)) + +ifeq ($(KBUILD_EXTMOD),) +dst := $(MODLIB)/kernel +else +INSTALL_MOD_DIR ?= updates +dst := $(MODLIB)/$(INSTALL_MOD_DIR) +endif + +$(foreach x, % :, $(if $(findstring $x, $(dst)), \ + $(error module installation path cannot contain '$x'))) + +suffix-y := +suffix-$(CONFIG_MODULE_COMPRESS_GZIP) := .gz +suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz +suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst + +modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules)) +install-$(CONFIG_MODULES) += $(modules) + +__modinst: $(install-y) + @: + +# +# Installation +# +quiet_cmd_install = INSTALL $@ + cmd_install = cp $< $@ + +# Strip +# +# INSTALL_MOD_STRIP, if defined, will cause modules to be stripped after they +# are installed. If INSTALL_MOD_STRIP is '1', then the default option +# --strip-debug will be used. Otherwise, INSTALL_MOD_STRIP value will be used +# as the options to the strip command. +ifdef INSTALL_MOD_STRIP + +ifeq ($(INSTALL_MOD_STRIP),1) +strip-option := --strip-debug +else +strip-option := $(INSTALL_MOD_STRIP) +endif + +quiet_cmd_strip = STRIP $@ + cmd_strip = $(STRIP) $(strip-option) $@ + +else + +quiet_cmd_strip = + cmd_strip = : + +endif + +# +# Signing +# Don't stop modules_install even if we can't sign external modules. +# +ifeq ($(filter pkcs11:%, $(CONFIG_MODULE_SIG_KEY)),) +sig-key := $(if $(wildcard $(CONFIG_MODULE_SIG_KEY)),,$(srctree)/)$(CONFIG_MODULE_SIG_KEY) +else +sig-key := $(CONFIG_MODULE_SIG_KEY) +endif +quiet_cmd_sign = SIGN $@ + cmd_sign = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) "$(sig-key)" certs/signing_key.x509 $@ \ + $(if $(KBUILD_EXTMOD),|| true) + +ifeq ($(sign-only),) + +# During modules_install, modules are signed only when CONFIG_MODULE_SIG_ALL=y. +ifndef CONFIG_MODULE_SIG_ALL +quiet_cmd_sign := + cmd_sign := : +endif + +# Create necessary directories +$(foreach dir, $(sort $(dir $(install-y))), $(shell mkdir -p $(dir))) + +$(dst)/%.ko: $(extmod_prefix)%.ko FORCE + $(call cmd,install) + $(call cmd,strip) + $(call cmd,sign) + +ifdef CONFIG_MODULES +__modinst: depmod + +PHONY += depmod +depmod: $(install-y) + $(call cmd,depmod) + +quiet_cmd_depmod = DEPMOD $(MODLIB) + cmd_depmod = $(srctree)/scripts/depmod.sh $(KERNELRELEASE) +endif + +else + +$(dst)/%.ko: FORCE + $(call cmd,sign) + +endif + +# +# Compression +# +quiet_cmd_gzip = GZIP $@ + cmd_gzip = $(KGZIP) -n -f $< +quiet_cmd_xz = XZ $@ + cmd_xz = $(XZ) --check=crc32 --lzma2=dict=1MiB -f $< +quiet_cmd_zstd = ZSTD $@ + cmd_zstd = $(ZSTD) -T0 --rm -f -q $< + +$(dst)/%.ko.gz: $(dst)/%.ko FORCE + $(call cmd,gzip) + +$(dst)/%.ko.xz: $(dst)/%.ko FORCE + $(call cmd,xz) + +$(dst)/%.ko.zst: $(dst)/%.ko FORCE + $(call cmd,zstd) + +PHONY += FORCE +FORCE: + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost new file mode 100644 index 0000000000..739402f455 --- /dev/null +++ b/scripts/Makefile.modpost @@ -0,0 +1,155 @@ +# 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 + +MODPOST = scripts/mod/modpost + +modpost-args = \ + $(if $(CONFIG_MODULES),-M) \ + $(if $(CONFIG_MODVERSIONS),-m) \ + $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ + $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ + $(if $(KBUILD_MODPOST_WARN),-w) \ + $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ + $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \ + $(if $(findstring 1, $(KBUILD_EXTRA_WARN)),-W) \ + -o $@ + +modpost-deps := $(MODPOST) + +# 'make -i -k' ignores compile errors, and builds as many modules as possible. +ifneq ($(findstring i,$(filter-out --%,$(MAKEFLAGS))),) +modpost-args += -n +endif + +# Read out modules.order to pass in modpost. +# Otherwise, allmodconfig would fail with "Argument list too long". +ifdef KBUILD_MODULES +modpost-args += -T $(MODORDER) +modpost-deps += $(MODORDER) +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 +vmlinux.symvers Module.symvers: .vmlinux.objs +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 > $@ + +targets += .vmlinux.objs +.vmlinux.objs: vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE + $(call if_changed,vmlinux_objs) + +ifdef CONFIG_TRIM_UNUSED_KSYMS +ksym-wl := $(CONFIG_UNUSED_KSYMS_WHITELIST) +ksym-wl := $(if $(filter-out /%, $(ksym-wl)),$(srctree)/)$(ksym-wl) +modpost-args += -t $(addprefix -u , $(ksym-wl)) +modpost-deps += $(ksym-wl) +endif + +ifeq ($(wildcard vmlinux.o),) +missing-input := vmlinux.o +output-symdump := modules-only.symvers +else +modpost-args += vmlinux.o +modpost-deps += vmlinux.o +output-symdump := $(if $(KBUILD_MODULES), Module.symvers, 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 $(kbuild-file) + +output-symdump := $(KBUILD_EXTMOD)/Module.symvers + +ifeq ($(wildcard Module.symvers),) +missing-input := Module.symvers +else +modpost-args += -i Module.symvers +modpost-deps += Module.symvers +endif + +modpost-args += -e $(addprefix -i , $(KBUILD_EXTRA_SYMBOLS)) + +endif # ($(KBUILD_EXTMOD),) + +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 errors."; \ + echo >&2 " You can set KBUILD_MODPOST_WARN=1 to turn errors into warning"; \ + echo >&2 " if you want to proceed at your own risk.";) \ + $(MODPOST) $(modpost-args) + +targets += $(output-symdump) +$(output-symdump): $(modpost-deps) 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) diff --git a/scripts/Makefile.package b/scripts/Makefile.package new file mode 100644 index 0000000000..2bcab02da9 --- /dev/null +++ b/scripts/Makefile.package @@ -0,0 +1,274 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Makefile for the different targets used to generate full packages of a kernel + +include $(srctree)/scripts/Kbuild.include +include $(srctree)/scripts/Makefile.lib + +KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE)) +# Include only those top-level files that are needed by make, plus the GPL copy +TAR_CONTENT := Documentation LICENSES arch block certs crypto drivers fs \ + include init io_uring ipc kernel lib mm net rust \ + samples scripts security sound tools usr virt \ + .config Makefile \ + Kbuild Kconfig COPYING $(wildcard localversion*) + +quiet_cmd_src_tar = TAR $(2).tar.gz + cmd_src_tar = \ +if test "$(objtree)" != "$(srctree)"; then \ + echo >&2; \ + echo >&2 " ERROR:"; \ + echo >&2 " Building source tarball is not possible outside the"; \ + echo >&2 " kernel source tree. Don't set KBUILD_OUTPUT"; \ + echo >&2; \ + false; \ +fi ; \ +tar -I $(KGZIP) -c $(RCS_TAR_IGNORE) -f $(2).tar.gz \ + --transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3) + +# Git +# --------------------------------------------------------------------------- + +filechk_HEAD = git -C $(srctree) rev-parse --verify HEAD 2>/dev/null + +.tmp_HEAD: check-git FORCE + $(call filechk,HEAD) + +PHONY += check-git +check-git: + @if ! $(srctree)/scripts/check-git; then \ + echo >&2 "error: creating source package requires git repository"; \ + false; \ + fi + +git-config-tar.gz = -c tar.tar.gz.command="$(KGZIP)" +git-config-tar.bz2 = -c tar.tar.bz2.command="$(KBZIP2)" +git-config-tar.lzma = -c tar.tar.lzma.command="$(LZMA)" +git-config-tar.xz = -c tar.tar.xz.command="$(XZ)" +git-config-tar.zst = -c tar.tar.zst.command="$(ZSTD)" + +quiet_cmd_archive = ARCHIVE $@ + cmd_archive = git -C $(srctree) $(git-config-tar$(suffix $@)) archive \ + --output=$$(realpath $@) $(archive-args) + +suffix-gzip := .gz +suffix-bzip2 := .bz2 +suffix-lzma := .lzma +suffix-xz := .xz + +# Linux source tarball +# --------------------------------------------------------------------------- + +linux-tarballs := $(addprefix linux, .tar.gz .tar.bz2 .tar.lzma .tar.xz) + +targets += $(linux-tarballs) +$(linux-tarballs): archive-args = --prefix=linux/ $$(cat $<) +$(linux-tarballs): .tmp_HEAD FORCE + $(call if_changed,archive) + +# rpm-pkg srcrpm-pkg binrpm-pkg +# --------------------------------------------------------------------------- + +quiet_cmd_mkspec = GEN $@ + cmd_mkspec = $(srctree)/scripts/package/mkspec > $@ + +kernel.spec: FORCE + $(call cmd,mkspec) + +PHONY += rpm-sources +rpm-sources: linux.tar.gz + $(Q)mkdir -p rpmbuild/SOURCES + $(Q)ln -f linux.tar.gz rpmbuild/SOURCES/linux.tar.gz + $(Q)cp $(KCONFIG_CONFIG) rpmbuild/SOURCES/config + $(Q)$(srctree)/scripts/package/gen-diff-patch rpmbuild/SOURCES/diff.patch + +PHONY += rpm-pkg srcrpm-pkg binrpm-pkg + +rpm-pkg: private build-type := a +srcrpm-pkg: private build-type := s +binrpm-pkg: private build-type := b + +rpm-pkg srcrpm-pkg: rpm-sources +rpm-pkg srcrpm-pkg binrpm-pkg: kernel.spec + +$(strip rpmbuild -b$(build-type) kernel.spec \ + --define='_topdir $(abspath rpmbuild)' \ + $(if $(filter a b, $(build-type)), \ + --target $(UTS_MACHINE)-linux --build-in-place --noprep --define='_smp_mflags %{nil}' \ + $$(rpm -q rpm >/dev/null 2>&1 || echo --nodeps)) \ + $(if $(filter b, $(build-type)), \ + --without devel) \ + $(RPMOPTS)) + +# deb-pkg srcdeb-pkg bindeb-pkg +# --------------------------------------------------------------------------- + +KDEB_SOURCE_COMPRESS ?= gzip + +supported-deb-source-compress := gzip bzip2 lzma xz + +PHONY += linux.tar.unsupported-deb-src-compress +linux.tar.unsupported-deb-src-compress: + @echo "error: KDEB_SOURCE_COMPRESS=$(KDEB_SOURCE_COMPRESS) is not supported. The supported values are: $(supported-deb-source-compress)" >&2 + @false + +debian-orig-suffix := \ + $(strip $(if $(filter $(supported-deb-source-compress), $(KDEB_SOURCE_COMPRESS)), \ + $(suffix-$(KDEB_SOURCE_COMPRESS)),.unsupported-deb-src-compress)) + +quiet_cmd_debianize = GEN $@ + cmd_debianize = $(srctree)/scripts/package/mkdebian $(mkdebian-opts) + +debian: FORCE + $(call cmd,debianize) + +PHONY += debian-orig +debian-orig: private source = $(shell dpkg-parsechangelog -S Source) +debian-orig: private version = $(shell dpkg-parsechangelog -S Version | sed 's/-[^-]*$$//') +debian-orig: private orig-name = $(source)_$(version).orig.tar$(debian-orig-suffix) +debian-orig: mkdebian-opts = --need-source +debian-orig: linux.tar$(debian-orig-suffix) debian + $(Q)if [ "$(df --output=target .. 2>/dev/null)" = "$(df --output=target $< 2>/dev/null)" ]; then \ + ln -f $< ../$(orig-name); \ + else \ + cp $< ../$(orig-name); \ + fi + +KBUILD_PKG_ROOTCMD ?= 'fakeroot -u' + +PHONY += deb-pkg srcdeb-pkg bindeb-pkg + +deb-pkg: private build-type := source,binary +srcdeb-pkg: private build-type := source +bindeb-pkg: private build-type := binary + +deb-pkg srcdeb-pkg: debian-orig +bindeb-pkg: debian +deb-pkg srcdeb-pkg bindeb-pkg: + +$(strip dpkg-buildpackage \ + --build=$(build-type) --no-pre-clean --unsigned-changes \ + $(if $(findstring source, $(build-type)), \ + --unsigned-source --compression=$(KDEB_SOURCE_COMPRESS)) \ + $(if $(findstring binary, $(build-type)), \ + --rules-file='$(MAKE) -f debian/rules' --jobs=1 -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch), \ + --no-check-builddeps) \ + $(DPKG_FLAGS)) + +# snap-pkg +# --------------------------------------------------------------------------- +PHONY += snap-pkg +snap-pkg: + rm -rf $(objtree)/snap + mkdir $(objtree)/snap + $(MAKE) clean + $(call cmd,src_tar,$(KERNELPATH)) + sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \ + s@SRCTREE@$(shell realpath $(KERNELPATH).tar.gz)@" \ + $(srctree)/scripts/package/snapcraft.template > \ + $(objtree)/snap/snapcraft.yaml + cd $(objtree)/snap && \ + snapcraft --target-arch=$(UTS_MACHINE) + +# dir-pkg tar*-pkg - tarball targets +# --------------------------------------------------------------------------- + +tar-install: FORCE + $(Q)$(MAKE) -f $(srctree)/Makefile + +$(Q)$(srctree)/scripts/package/buildtar $@ + +compress-tar.gz = -I "$(KGZIP)" +compress-tar.bz2 = -I "$(KBZIP2)" +compress-tar.xz = -I "$(XZ)" +compress-tar.zst = -I "$(ZSTD)" + +quiet_cmd_tar = TAR $@ + cmd_tar = cd $<; tar cf ../$@ $(compress-tar$(suffix $@)) --owner=root --group=root --sort=name * + +dir-tarballs := $(addprefix linux-$(KERNELRELEASE)-$(ARCH), .tar .tar.gz .tar.bz2 .tar.xz .tar.zst) + +$(dir-tarballs): tar-install + $(call cmd,tar) + +PHONY += dir-pkg +dir-pkg: tar-install + @echo "Kernel tree successfully created in $<" + +PHONY += tar-pkg +tar-pkg: linux-$(KERNELRELEASE)-$(ARCH).tar + @: + +tar%-pkg: linux-$(KERNELRELEASE)-$(ARCH).tar.% FORCE + @: + +# perf-tar*-src-pkg - generate a source tarball with perf source +# --------------------------------------------------------------------------- + +.tmp_perf: + $(Q)mkdir .tmp_perf + +.tmp_perf/HEAD: .tmp_HEAD | .tmp_perf + $(call cmd,copy) + +quiet_cmd_perf_version_file = GEN $@ + cmd_perf_version_file = cd $(srctree)/tools/perf; util/PERF-VERSION-GEN $(dir $(abspath $@)) + +# PERF-VERSION-FILE and .tmp_HEAD are independent, but this avoids updating the +# timestamp of PERF-VERSION-FILE. +# The best is to fix tools/perf/util/PERF-VERSION-GEN. +.tmp_perf/PERF-VERSION-FILE: .tmp_HEAD $(srctree)/tools/perf/util/PERF-VERSION-GEN | .tmp_perf + $(call cmd,perf_version_file) + +perf-archive-args = --add-file=$$(realpath $(word 2, $^)) \ + --add-file=$$(realpath $(word 3, $^)) \ + $$(cat $(word 2, $^))^{tree} $$(cat $<) + + +perf-tarballs := $(addprefix perf-$(KERNELVERSION), .tar .tar.gz .tar.bz2 .tar.xz .tar.zst) + +targets += $(perf-tarballs) +$(perf-tarballs): archive-args = --prefix=perf-$(KERNELVERSION)/ $(perf-archive-args) +$(perf-tarballs): tools/perf/MANIFEST .tmp_perf/HEAD .tmp_perf/PERF-VERSION-FILE FORCE + $(call if_changed,archive) + +PHONY += perf-tar-src-pkg +perf-tar-src-pkg: perf-$(KERNELVERSION).tar + @: + +perf-tar%-src-pkg: perf-$(KERNELVERSION).tar.% FORCE + @: + +# Help text displayed when executing 'make help' +# --------------------------------------------------------------------------- +PHONY += help +help: + @echo ' rpm-pkg - Build both source and binary RPM kernel packages' + @echo ' srcrpm-pkg - Build only the source kernel RPM package' + @echo ' binrpm-pkg - Build only the binary kernel RPM package' + @echo ' deb-pkg - Build both source and binary deb kernel packages' + @echo ' srcdeb-pkg - Build only the source kernel deb package' + @echo ' bindeb-pkg - Build only the binary kernel deb package' + @echo ' snap-pkg - Build only the binary kernel snap package' + @echo ' (will connect to external hosts)' + @echo ' dir-pkg - Build the kernel as a plain directory structure' + @echo ' tar-pkg - Build the kernel as an uncompressed tarball' + @echo ' targz-pkg - Build the kernel as a gzip compressed tarball' + @echo ' tarbz2-pkg - Build the kernel as a bzip2 compressed tarball' + @echo ' tarxz-pkg - Build the kernel as a xz compressed tarball' + @echo ' tarzst-pkg - Build the kernel as a zstd compressed tarball' + @echo ' perf-tar-src-pkg - Build the perf source tarball with no compression' + @echo ' perf-targz-src-pkg - Build the perf source tarball with gzip compression' + @echo ' perf-tarbz2-src-pkg - Build the perf source tarball with bz2 compression' + @echo ' perf-tarxz-src-pkg - Build the perf source tarball with xz compression' + @echo ' perf-tarzst-src-pkg - Build the perf source tarball with zst compression' + +PHONY += FORCE +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.randstruct b/scripts/Makefile.randstruct new file mode 100644 index 0000000000..24e283e898 --- /dev/null +++ b/scripts/Makefile.randstruct @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 + +randstruct-cflags-y += -DRANDSTRUCT + +ifdef CONFIG_GCC_PLUGIN_RANDSTRUCT +randstruct-cflags-y \ + += -fplugin=$(objtree)/scripts/gcc-plugins/randomize_layout_plugin.so +randstruct-cflags-$(CONFIG_RANDSTRUCT_PERFORMANCE) \ + += -fplugin-arg-randomize_layout_plugin-performance-mode +else +randstruct-cflags-y \ + += -frandomize-layout-seed-file=$(objtree)/scripts/basic/randstruct.seed +endif + +export RANDSTRUCT_CFLAGS := $(randstruct-cflags-y) + +KBUILD_CFLAGS += $(RANDSTRUCT_CFLAGS) diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan new file mode 100644 index 0000000000..4749865c1b --- /dev/null +++ b/scripts/Makefile.ubsan @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Enable available and selected UBSAN features. +ubsan-cflags-$(CONFIG_UBSAN_ALIGNMENT) += -fsanitize=alignment +ubsan-cflags-$(CONFIG_UBSAN_BOUNDS_STRICT) += -fsanitize=bounds-strict +ubsan-cflags-$(CONFIG_UBSAN_ARRAY_BOUNDS) += -fsanitize=array-bounds +ubsan-cflags-$(CONFIG_UBSAN_LOCAL_BOUNDS) += -fsanitize=local-bounds +ubsan-cflags-$(CONFIG_UBSAN_SHIFT) += -fsanitize=shift +ubsan-cflags-$(CONFIG_UBSAN_DIV_ZERO) += -fsanitize=integer-divide-by-zero +ubsan-cflags-$(CONFIG_UBSAN_UNREACHABLE) += -fsanitize=unreachable +ubsan-cflags-$(CONFIG_UBSAN_BOOL) += -fsanitize=bool +ubsan-cflags-$(CONFIG_UBSAN_ENUM) += -fsanitize=enum +ubsan-cflags-$(CONFIG_UBSAN_TRAP) += -fsanitize-undefined-trap-on-error + +export CFLAGS_UBSAN := $(ubsan-cflags-y) diff --git a/scripts/Makefile.userprogs b/scripts/Makefile.userprogs new file mode 100644 index 0000000000..fb41529733 --- /dev/null +++ b/scripts/Makefile.userprogs @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Build userspace programs for the target system +# + +# Executables compiled from a single .c file +user-csingle := $(foreach m, $(userprogs), $(if $($(m)-objs),,$(m))) + +# Executables linked based on several .o files +user-cmulti := $(foreach m, $(userprogs), $(if $($(m)-objs),$(m))) + +# Objects compiled from .c files +user-cobjs := $(sort $(foreach m, $(userprogs), $($(m)-objs))) + +user-csingle := $(addprefix $(obj)/, $(user-csingle)) +user-cmulti := $(addprefix $(obj)/, $(user-cmulti)) +user-cobjs := $(addprefix $(obj)/, $(user-cobjs)) + +user_ccflags = -Wp,-MMD,$(depfile) $(KBUILD_USERCFLAGS) $(userccflags) \ + $($(target-stem)-userccflags) +user_ldflags = $(KBUILD_USERLDFLAGS) $(userldflags) $($(target-stem)-userldflags) + +# Create an executable from a single .c file +quiet_cmd_user_cc_c = CC [U] $@ + cmd_user_cc_c = $(CC) $(user_ccflags) $(user_ldflags) -o $@ $< \ + $($(target-stem)-userldlibs) +$(user-csingle): $(obj)/%: $(src)/%.c FORCE + $(call if_changed_dep,user_cc_c) + +# Link an executable based on list of .o files +quiet_cmd_user_ld = LD [U] $@ + cmd_user_ld = $(CC) $(user_ldflags) -o $@ \ + $(addprefix $(obj)/, $($(target-stem)-objs)) \ + $($(target-stem)-userldlibs) +$(user-cmulti): FORCE + $(call if_changed,user_ld) +$(call multi_depend, $(user-cmulti), , -objs) + +# Create .o file from a .c file +quiet_cmd_user_cc_o_c = CC [U] $@ + cmd_user_cc_o_c = $(CC) $(user_ccflags) -c -o $@ $< +$(user-cobjs): $(obj)/%.o: $(src)/%.c FORCE + $(call if_changed_dep,user_cc_o_c) + +targets += $(user-csingle) $(user-cmulti) $(user-cobjs) diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux new file mode 100644 index 0000000000..c9f3e03124 --- /dev/null +++ b/scripts/Makefile.vmlinux @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: GPL-2.0-only + +PHONY := __default +__default: vmlinux + +include include/config/auto.conf +include $(srctree)/scripts/Kbuild.include + +# for c_flags +include $(srctree)/scripts/Makefile.lib + +targets := + +quiet_cmd_cc_o_c = CC $@ + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + +%.o: %.c FORCE + $(call if_changed_dep,cc_o_c) + +ifdef CONFIG_MODULES +KASAN_SANITIZE_.vmlinux.export.o := n +KCSAN_SANITIZE_.vmlinux.export.o := n +GCOV_PROFILE_.vmlinux.export.o := n +targets += .vmlinux.export.o +vmlinux: .vmlinux.export.o +endif + +ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) + +# Final link of vmlinux with optional arch pass after final link +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 + +$(call if_changed_dep,link_vmlinux) + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o new file mode 100644 index 0000000000..25b3b587d3 --- /dev/null +++ b/scripts/Makefile.vmlinux_o @@ -0,0 +1,105 @@ +# SPDX-License-Identifier: GPL-2.0-only + +PHONY := __default +__default: vmlinux.o modules.builtin.modinfo modules.builtin + +include include/config/auto.conf +include $(srctree)/scripts/Kbuild.include + +# for objtool +include $(srctree)/scripts/Makefile.lib + +# Generate a linker script to ensure correct ordering of initcalls for Clang LTO +# --------------------------------------------------------------------------- + +quiet_cmd_gen_initcalls_lds = GEN $@ + cmd_gen_initcalls_lds = \ + $(PYTHON3) $(srctree)/scripts/jobserver-exec \ + $(PERL) $(real-prereqs) > $@ + +.tmp_initcalls.lds: $(srctree)/scripts/generate_initcall_order.pl \ + vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE + $(call if_changed,gen_initcalls_lds) + +targets := .tmp_initcalls.lds + +ifdef CONFIG_LTO_CLANG +initcalls-lds := .tmp_initcalls.lds +endif + +# objtool for vmlinux.o +# --------------------------------------------------------------------------- +# +# For LTO and IBT, objtool doesn't run on individual translation units. +# Run everything on vmlinux instead. + +objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION)) + +vmlinux-objtool-args-$(delay-objtool) += $(objtool-args-y) +vmlinux-objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable +vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION) += --noinstr \ + $(if $(or $(CONFIG_CPU_UNRET_ENTRY),$(CONFIG_CPU_SRSO)), --unret) + +objtool-args = $(vmlinux-objtool-args-y) --link + +# Link of vmlinux.o used for section mismatch analysis +# --------------------------------------------------------------------------- + +quiet_cmd_ld_vmlinux.o = LD $@ + cmd_ld_vmlinux.o = \ + $(LD) ${KBUILD_LDFLAGS} -r -o $@ \ + $(addprefix -T , $(initcalls-lds)) \ + --whole-archive vmlinux.a --no-whole-archive \ + --start-group $(KBUILD_VMLINUX_LIBS) --end-group \ + $(cmd_objtool) + +define rule_ld_vmlinux.o + $(call cmd_and_savecmd,ld_vmlinux.o) + $(call cmd,gen_objtooldep) +endef + +vmlinux.o: $(initcalls-lds) vmlinux.a $(KBUILD_VMLINUX_LIBS) FORCE + $(call if_changed_rule,ld_vmlinux.o) + +targets += vmlinux.o + +# module.builtin.modinfo +# --------------------------------------------------------------------------- + +OBJCOPYFLAGS_modules.builtin.modinfo := -j .modinfo -O binary + +targets += modules.builtin.modinfo +modules.builtin.modinfo: vmlinux.o FORCE + $(call if_changed,objcopy) + +# module.builtin +# --------------------------------------------------------------------------- + +# The second line aids cases where multiple modules share the same object. + +quiet_cmd_modules_builtin = GEN $@ + cmd_modules_builtin = \ + tr '\0' '\n' < $< | \ + sed -n 's/^[[:alnum:]:_]*\.file=//p' | \ + tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$$/.ko/' > $@ + +targets += modules.builtin +modules.builtin: modules.builtin.modinfo FORCE + $(call if_changed,modules_builtin) + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +existing-targets := $(wildcard $(sort $(targets))) + +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +.PHONY: $(PHONY) |