mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 14:14:24 +08:00
Merge branch 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
Pull kbuild updates from Michal Marek: - new option CONFIG_TRIM_UNUSED_KSYMS which does a two-pass build and unexports symbols which are not used in the current config [Nicolas Pitre] - several kbuild rule cleanups [Masahiro Yamada] - warning option adjustments for gcov etc [Arnd Bergmann] - a few more small fixes * 'kbuild' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild: (31 commits) kbuild: move -Wunused-const-variable to W=1 warning level kbuild: fix if_change and friends to consider argument order kbuild: fix adjust_autoksyms.sh for modules that need only one symbol kbuild: fix ksym_dep_filter when multiple EXPORT_SYMBOL() on the same line gcov: disable -Wmaybe-uninitialized warning gcov: disable tree-loop-im to reduce stack usage gcov: disable for COMPILE_TEST Kbuild: disable 'maybe-uninitialized' warning for CONFIG_PROFILE_ALL_BRANCHES Kbuild: change CC_OPTIMIZE_FOR_SIZE definition kbuild: forbid kernel directory to contain spaces and colons kbuild: adjust ksym_dep_filter for some cmd_* renames kbuild: Fix dependencies for final vmlinux link kbuild: better abstract vmlinux sequential prerequisites kbuild: fix call to adjust_autoksyms.sh when output directory specified kbuild: Get rid of KBUILD_STR kbuild: rename cmd_as_s_S to cmd_cpp_s_S kbuild: rename cmd_cc_i_c to cmd_cpp_i_c kbuild: drop redundant "PHONY += FORCE" kbuild: delete unnecessary "@:" kbuild: mark help target as PHONY ...
This commit is contained in:
commit
5b26fc8824
66
Makefile
66
Makefile
@ -128,6 +128,10 @@ _all:
|
||||
# Cancel implicit rules on top Makefile
|
||||
$(CURDIR)/Makefile Makefile: ;
|
||||
|
||||
ifneq ($(words $(subst :, ,$(CURDIR))), 1)
|
||||
$(error main directory cannot contain spaces nor colons)
|
||||
endif
|
||||
|
||||
ifneq ($(KBUILD_OUTPUT),)
|
||||
# Invoke a second make in the output directory, passing relevant variables
|
||||
# check that the output directory actually exists
|
||||
@ -142,7 +146,7 @@ PHONY += $(MAKECMDGOALS) sub-make
|
||||
$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
|
||||
@:
|
||||
|
||||
sub-make: FORCE
|
||||
sub-make:
|
||||
$(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \
|
||||
-f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))
|
||||
|
||||
@ -364,7 +368,7 @@ AFLAGS_MODULE =
|
||||
LDFLAGS_MODULE =
|
||||
CFLAGS_KERNEL =
|
||||
AFLAGS_KERNEL =
|
||||
CFLAGS_GCOV = -fprofile-arcs -ftest-coverage
|
||||
CFLAGS_GCOV = -fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized
|
||||
CFLAGS_KCOV = -fsanitize-coverage=trace-pc
|
||||
|
||||
|
||||
@ -617,7 +621,11 @@ KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)
|
||||
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
|
||||
KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,)
|
||||
else
|
||||
KBUILD_CFLAGS += -O2
|
||||
ifdef CONFIG_PROFILE_ALL_BRANCHES
|
||||
KBUILD_CFLAGS += -O2 $(call cc-disable-warning,maybe-uninitialized,)
|
||||
else
|
||||
KBUILD_CFLAGS += -O2
|
||||
endif
|
||||
endif
|
||||
|
||||
# Tell gcc to never replace conditional load with a non-conditional one
|
||||
@ -697,9 +705,10 @@ KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
|
||||
KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
|
||||
else
|
||||
|
||||
# This warning generated too much noise in a regular build.
|
||||
# Use make W=1 to enable this warning (see scripts/Makefile.build)
|
||||
# These warnings generated too much noise in a regular build.
|
||||
# Use make W=1 to enable them (see scripts/Makefile.build)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
|
||||
KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
|
||||
endif
|
||||
|
||||
ifdef CONFIG_FRAME_POINTER
|
||||
@ -926,27 +935,41 @@ export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Doc
|
||||
|
||||
vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)
|
||||
|
||||
# Final link of vmlinux
|
||||
cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux)
|
||||
quiet_cmd_link-vmlinux = LINK $@
|
||||
|
||||
# Include targets which we want to
|
||||
# execute if the rest of the kernel build went well.
|
||||
vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE
|
||||
# Include targets which we want to execute sequentially if the rest of the
|
||||
# kernel build went well. If CONFIG_TRIM_UNUSED_KSYMS is set, this might be
|
||||
# evaluated more than once.
|
||||
PHONY += vmlinux_prereq
|
||||
vmlinux_prereq: $(vmlinux-deps) FORCE
|
||||
ifdef CONFIG_HEADERS_CHECK
|
||||
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
|
||||
endif
|
||||
ifdef CONFIG_SAMPLES
|
||||
$(Q)$(MAKE) $(build)=samples
|
||||
endif
|
||||
ifdef CONFIG_BUILD_DOCSRC
|
||||
$(Q)$(MAKE) $(build)=Documentation
|
||||
endif
|
||||
ifdef CONFIG_GDB_SCRIPTS
|
||||
$(Q)ln -fsn `cd $(srctree) && /bin/pwd`/scripts/gdb/vmlinux-gdb.py
|
||||
endif
|
||||
ifdef CONFIG_TRIM_UNUSED_KSYMS
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \
|
||||
"$(MAKE) KBUILD_MODULES=1 -f $(srctree)/Makefile vmlinux_prereq"
|
||||
endif
|
||||
|
||||
# standalone target for easier testing
|
||||
include/generated/autoksyms.h: FORCE
|
||||
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh true
|
||||
|
||||
# Final link of vmlinux
|
||||
cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux)
|
||||
quiet_cmd_link-vmlinux = LINK $@
|
||||
|
||||
vmlinux: scripts/link-vmlinux.sh vmlinux_prereq $(vmlinux-deps) FORCE
|
||||
+$(call if_changed,link-vmlinux)
|
||||
|
||||
# Build samples along the rest of the kernel
|
||||
ifdef CONFIG_SAMPLES
|
||||
vmlinux-dirs += samples
|
||||
endif
|
||||
|
||||
# The actual objects are generated when descending,
|
||||
# make sure no implicit rule kicks in
|
||||
$(sort $(vmlinux-deps)): $(vmlinux-dirs) ;
|
||||
@ -998,10 +1021,12 @@ prepare2: prepare3 outputmakefile asm-generic
|
||||
prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
|
||||
include/config/auto.conf
|
||||
$(cmd_crmodverdir)
|
||||
$(Q)test -e include/generated/autoksyms.h || \
|
||||
touch include/generated/autoksyms.h
|
||||
|
||||
archprepare: archheaders archscripts prepare1 scripts_basic
|
||||
|
||||
prepare0: archprepare FORCE
|
||||
prepare0: archprepare
|
||||
$(Q)$(MAKE) $(build)=.
|
||||
|
||||
# All the preparing..
|
||||
@ -1061,7 +1086,7 @@ INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware
|
||||
export INSTALL_FW_PATH
|
||||
|
||||
PHONY += firmware_install
|
||||
firmware_install: FORCE
|
||||
firmware_install:
|
||||
@mkdir -p $(objtree)/firmware
|
||||
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install
|
||||
|
||||
@ -1081,7 +1106,7 @@ PHONY += archscripts
|
||||
archscripts:
|
||||
|
||||
PHONY += __headers
|
||||
__headers: $(version_h) scripts_basic asm-generic archheaders archscripts FORCE
|
||||
__headers: $(version_h) scripts_basic asm-generic archheaders archscripts
|
||||
$(Q)$(MAKE) $(build)=scripts build_unifdef
|
||||
|
||||
PHONY += headers_install_all
|
||||
@ -1192,7 +1217,8 @@ else # CONFIG_MODULES
|
||||
# Modules not configured
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
modules modules_install: FORCE
|
||||
PHONY += modules modules_install
|
||||
modules modules_install:
|
||||
@echo >&2
|
||||
@echo >&2 "The present kernel configuration has modules disabled."
|
||||
@echo >&2 "Type 'make config' and enable loadable module support."
|
||||
@ -1283,6 +1309,7 @@ boards := $(sort $(notdir $(boards)))
|
||||
board-dirs := $(dir $(wildcard $(srctree)/arch/$(SRCARCH)/configs/*/*_defconfig))
|
||||
board-dirs := $(sort $(notdir $(board-dirs:/=)))
|
||||
|
||||
PHONY += help
|
||||
help:
|
||||
@echo 'Cleaning targets:'
|
||||
@echo ' clean - Remove most generated files but keep the config and'
|
||||
@ -1453,6 +1480,7 @@ $(clean-dirs):
|
||||
clean: rm-dirs := $(MODVERDIR)
|
||||
clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers
|
||||
|
||||
PHONY += help
|
||||
help:
|
||||
@echo ' Building external modules.'
|
||||
@echo ' Syntax: make -C path/to/kernel/src M=$$PWD target'
|
||||
|
@ -82,7 +82,6 @@ $(obj)/uImage: $(obj)/zImage FORCE
|
||||
|
||||
$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
|
||||
$(Q)$(MAKE) $(build)=$(obj)/bootp $@
|
||||
@:
|
||||
|
||||
$(obj)/bootpImage: $(obj)/bootp/bootp FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
@ -17,7 +17,6 @@ targets := bootp init.o kernel.o initrd.o
|
||||
# Note that bootp.lds picks up kernel.o and initrd.o
|
||||
$(obj)/bootp: $(src)/bootp.lds $(addprefix $(obj)/,init.o kernel.o initrd.o) FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
# kernel.o and initrd.o includes a binary image using
|
||||
# .incbin, a dependency which is not tracked automatically
|
||||
@ -26,4 +25,4 @@ $(obj)/kernel.o: arch/arm/boot/zImage FORCE
|
||||
|
||||
$(obj)/initrd.o: $(INITRD) FORCE
|
||||
|
||||
PHONY += $(INITRD) FORCE
|
||||
PHONY += $(INITRD)
|
||||
|
@ -74,5 +74,5 @@ $(MODLIB)/vdso: FORCE
|
||||
@mkdir -p $(MODLIB)/vdso
|
||||
|
||||
PHONY += vdso_install
|
||||
vdso_install: $(obj)/vdso.so.dbg $(MODLIB)/vdso FORCE
|
||||
vdso_install: $(obj)/vdso.so.dbg $(MODLIB)/vdso
|
||||
$(call cmd,vdso_install)
|
||||
|
@ -23,7 +23,6 @@ LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -estartup -T $(obj)/vmlinux.lds \
|
||||
|
||||
$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
@ -95,8 +95,8 @@ define archhelp
|
||||
echo '* unwcheck - Check vmlinux for invalid unwind info'
|
||||
endef
|
||||
|
||||
archprepare: make_nr_irqs_h FORCE
|
||||
PHONY += make_nr_irqs_h FORCE
|
||||
archprepare: make_nr_irqs_h
|
||||
PHONY += make_nr_irqs_h
|
||||
|
||||
make_nr_irqs_h: FORCE
|
||||
make_nr_irqs_h:
|
||||
$(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h
|
||||
|
@ -19,7 +19,6 @@ LDFLAGS_vmlinux := -T
|
||||
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
@ -8,7 +8,6 @@ LDFLAGS_vmlinux := -Ttext $(CONFIG_KERNEL_ZIMAGE_BASE_ADDRESS) -e startup_32
|
||||
|
||||
$(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
@ -11,7 +11,6 @@ LDFLAGS_vmlinux := -T
|
||||
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
LDFLAGS_piggy.o := -r --format binary --oformat elf32-littlenios2 -T
|
||||
|
||||
|
@ -22,7 +22,6 @@ OBJECTS += $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o
|
||||
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS)
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\)$$/\#define SZ\2 0x\1/p'
|
||||
|
||||
|
@ -55,7 +55,6 @@ $(addprefix $(obj)/,$(lib1funcs-y)): $(obj)/%: $(lib1funcs-dir)/% FORCE
|
||||
|
||||
$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(lib1funcs-obj) FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
@ -17,7 +17,6 @@ LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(load-y) -e romstart \
|
||||
|
||||
$(obj)/vmlinux: $(obj)/head.o $(obj-y) $(obj)/piggy.o FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
OBJCOPYFLAGS += -j .empty_zero_page
|
||||
|
||||
|
@ -31,7 +31,7 @@ $(obj)/uImage: $(obj)/zImage FORCE
|
||||
$(call if_changed,uimage)
|
||||
@echo ' Image $@ is ready'
|
||||
|
||||
PHONY += initrd FORCE
|
||||
PHONY += initrd
|
||||
initrd:
|
||||
@test "$(INITRD)" != "" || \
|
||||
(echo You must specify INITRD; exit -1)
|
||||
|
@ -54,7 +54,6 @@ LDFLAGS_vmlinux += -T
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/head.o $(obj)/piggy.o \
|
||||
$(obj)/misc.o FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
# We now have a PIC decompressor implementation. Decompressors running
|
||||
# from RAM should not define ZTEXTADDR. Decompressors running directly
|
||||
|
@ -87,7 +87,6 @@ vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o
|
||||
|
||||
$(obj)/vmlinux: $(vmlinux-objs-y) FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
OBJCOPYFLAGS_vmlinux.bin := -R .comment -S
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
|
@ -193,10 +193,10 @@ vdso_img_insttargets := $(vdso_img_sodbg:%.dbg=install_%)
|
||||
$(MODLIB)/vdso: FORCE
|
||||
@mkdir -p $(MODLIB)/vdso
|
||||
|
||||
$(vdso_img_insttargets): install_%: $(obj)/%.dbg $(MODLIB)/vdso FORCE
|
||||
$(vdso_img_insttargets): install_%: $(obj)/%.dbg $(MODLIB)/vdso
|
||||
$(call cmd,vdso_install)
|
||||
|
||||
PHONY += vdso_install $(vdso_img_insttargets)
|
||||
vdso_install: $(vdso_img_insttargets) FORCE
|
||||
vdso_install: $(vdso_img_insttargets)
|
||||
|
||||
clean-files := vdso32.so vdso32.so.dbg vdso64* vdso-image-*.c vdsox32.so*
|
||||
|
@ -26,7 +26,5 @@ quiet_cmd_bin2c = BIN2C $@
|
||||
|
||||
$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
|
||||
$(call if_changed,bin2c)
|
||||
@:
|
||||
|
||||
|
||||
obj-$(CONFIG_KEXEC_FILE) += kexec-purgatory.o
|
||||
|
@ -59,7 +59,6 @@ OBJCOPYFLAGS_realmode.bin := -O binary
|
||||
targets += realmode.bin
|
||||
$(obj)/realmode.bin: $(obj)/realmode.elf $(obj)/realmode.relocs FORCE
|
||||
$(call if_changed,objcopy)
|
||||
@:
|
||||
|
||||
quiet_cmd_relocs = RELOCS $@
|
||||
cmd_relocs = arch/x86/tools/relocs --realmode $< > $@
|
||||
|
@ -38,7 +38,7 @@ extern struct module __this_module;
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
|
||||
#ifndef __GENKSYMS__
|
||||
#if defined(__KERNEL__) && !defined(__GENKSYMS__)
|
||||
#ifdef CONFIG_MODVERSIONS
|
||||
/* Mark the CRC weak since genksyms apparently decides not to
|
||||
* generate a checksums for some symbols */
|
||||
@ -53,7 +53,7 @@ extern struct module __this_module;
|
||||
#endif
|
||||
|
||||
/* For every exported symbol, place a struct in the __ksymtab section */
|
||||
#define __EXPORT_SYMBOL(sym, sec) \
|
||||
#define ___EXPORT_SYMBOL(sym, sec) \
|
||||
extern typeof(sym) sym; \
|
||||
__CRC_SYMBOL(sym, sec) \
|
||||
static const char __kstrtab_##sym[] \
|
||||
@ -65,6 +65,35 @@ extern struct module __this_module;
|
||||
__attribute__((section("___ksymtab" sec "+" #sym), unused)) \
|
||||
= { (unsigned long)&sym, __kstrtab_##sym }
|
||||
|
||||
#if defined(__KSYM_DEPS__)
|
||||
|
||||
/*
|
||||
* For fine grained build dependencies, we want to tell the build system
|
||||
* about each possible exported symbol even if they're not actually exported.
|
||||
* We use a string pattern that is unlikely to be valid code that the build
|
||||
* system filters out from the preprocessor output (see ksym_dep_filter
|
||||
* in scripts/Kbuild.include).
|
||||
*/
|
||||
#define __EXPORT_SYMBOL(sym, sec) === __KSYM_##sym ===
|
||||
|
||||
#elif defined(CONFIG_TRIM_UNUSED_KSYMS)
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <generated/autoksyms.h>
|
||||
|
||||
#define __EXPORT_SYMBOL(sym, sec) \
|
||||
__cond_export_sym(sym, sec, config_enabled(__KSYM_##sym))
|
||||
#define __cond_export_sym(sym, sec, conf) \
|
||||
___cond_export_sym(sym, sec, conf)
|
||||
#define ___cond_export_sym(sym, sec, enabled) \
|
||||
__cond_export_sym_##enabled(sym, sec)
|
||||
#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
|
||||
#define __cond_export_sym_0(sym, sec) /* nothing */
|
||||
|
||||
#else
|
||||
#define __EXPORT_SYMBOL ___EXPORT_SYMBOL
|
||||
#endif
|
||||
|
||||
#define EXPORT_SYMBOL(sym) \
|
||||
__EXPORT_SYMBOL(sym, "")
|
||||
|
||||
|
29
init/Kconfig
29
init/Kconfig
@ -1306,6 +1306,17 @@ source "usr/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
choice
|
||||
prompt "Compiler optimization level"
|
||||
default CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
|
||||
|
||||
config CC_OPTIMIZE_FOR_PERFORMANCE
|
||||
bool "Optimize for performance"
|
||||
help
|
||||
This is the default optimization level for the kernel, building
|
||||
with the "-O2" compiler flag for best performance and most
|
||||
helpful compile-time warnings.
|
||||
|
||||
config CC_OPTIMIZE_FOR_SIZE
|
||||
bool "Optimize for size"
|
||||
help
|
||||
@ -1314,6 +1325,8 @@ config CC_OPTIMIZE_FOR_SIZE
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
endchoice
|
||||
|
||||
config SYSCTL
|
||||
bool
|
||||
|
||||
@ -2049,6 +2062,22 @@ config MODULE_COMPRESS_XZ
|
||||
|
||||
endchoice
|
||||
|
||||
config TRIM_UNUSED_KSYMS
|
||||
bool "Trim unused exported kernel symbols"
|
||||
depends on MODULES && !UNUSED_SYMBOLS
|
||||
help
|
||||
The kernel and some modules make many symbols available for
|
||||
other modules to use via EXPORT_SYMBOL() and variants. Depending
|
||||
on the set of modules being selected in your kernel configuration,
|
||||
many of those exported symbols might never be used.
|
||||
|
||||
This option allows for unused exported symbols to be dropped from
|
||||
the build. In turn, this provides the compiler more opportunities
|
||||
(especially when using LTO) for optimizing the code and reducing
|
||||
binary size. This might have some security advantages as well.
|
||||
|
||||
If unsure say N.
|
||||
|
||||
endif # MODULES
|
||||
|
||||
config MODULES_TREE_LOOKUP
|
||||
|
@ -37,6 +37,7 @@ config ARCH_HAS_GCOV_PROFILE_ALL
|
||||
|
||||
config GCOV_PROFILE_ALL
|
||||
bool "Profile entire Kernel"
|
||||
depends on !COMPILE_TEST
|
||||
depends on GCOV_KERNEL
|
||||
depends on ARCH_HAS_GCOV_PROFILE_ALL
|
||||
default n
|
||||
|
@ -7,6 +7,7 @@ quote := "
|
||||
squote := '
|
||||
empty :=
|
||||
space := $(empty) $(empty)
|
||||
space_escape := _-_SPACE_-_
|
||||
|
||||
###
|
||||
# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
|
||||
@ -226,10 +227,10 @@ objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o)))
|
||||
# See Documentation/kbuild/makefiles.txt for more info
|
||||
|
||||
ifneq ($(KBUILD_NOCMDDEP),1)
|
||||
# Check if both arguments has same arguments. Result is empty string if equal.
|
||||
# User may override this check using make KBUILD_NOCMDDEP=1
|
||||
arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
|
||||
$(filter-out $(cmd_$@), $(cmd_$(1))) )
|
||||
# Check if both arguments are the same including their order. Result is empty
|
||||
# string if equal. User may override this check using make KBUILD_NOCMDDEP=1
|
||||
arg-check = $(filter-out $(subst $(space),$(space_escape),$(strip $(cmd_$@))), \
|
||||
$(subst $(space),$(space_escape),$(strip $(cmd_$1))))
|
||||
else
|
||||
arg-check = $(if $(strip $(cmd_$@)),,1)
|
||||
endif
|
||||
@ -256,10 +257,42 @@ if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
|
||||
# Execute the command and also postprocess generated .d dependencies file.
|
||||
if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \
|
||||
@set -e; \
|
||||
$(cmd_and_fixdep), @:)
|
||||
|
||||
ifndef CONFIG_TRIM_UNUSED_KSYMS
|
||||
|
||||
cmd_and_fixdep = \
|
||||
$(echo-cmd) $(cmd_$(1)); \
|
||||
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
|
||||
rm -f $(depfile); \
|
||||
mv -f $(dot-target).tmp $(dot-target).cmd, @:)
|
||||
mv -f $(dot-target).tmp $(dot-target).cmd;
|
||||
|
||||
else
|
||||
|
||||
# Filter out exported kernel symbol names from the preprocessor output.
|
||||
# See also __KSYM_DEPS__ in include/linux/export.h.
|
||||
# We disable the depfile generation here, so as not to overwrite the existing
|
||||
# depfile while fixdep is parsing it.
|
||||
flags_nodeps = $(filter-out -Wp$(comma)-M%, $($(1)))
|
||||
ksym_dep_filter = \
|
||||
case "$(1)" in \
|
||||
cc_*_c|cpp_i_c) \
|
||||
$(CPP) $(call flags_nodeps,c_flags) -D__KSYM_DEPS__ $< ;; \
|
||||
as_*_S|cpp_s_S) \
|
||||
$(CPP) $(call flags_nodeps,a_flags) -D__KSYM_DEPS__ $< ;; \
|
||||
boot*|build*|*cpp_lds_S|dtc|host*|vdso*) : ;; \
|
||||
*) echo "Don't know how to preprocess $(1)" >&2; false ;; \
|
||||
esac | tr ";" "\n" | sed -rn 's/^.*=== __KSYM_(.*) ===.*$$/KSYM_\1/p'
|
||||
|
||||
cmd_and_fixdep = \
|
||||
$(echo-cmd) $(cmd_$(1)); \
|
||||
$(ksym_dep_filter) | \
|
||||
scripts/basic/fixdep -e $(depfile) $@ '$(make-cmd)' \
|
||||
> $(dot-target).tmp; \
|
||||
rm -f $(depfile); \
|
||||
mv -f $(dot-target).tmp $(dot-target).cmd;
|
||||
|
||||
endif
|
||||
|
||||
# Usage: $(call if_changed_rule,foo)
|
||||
# Will check if $(cmd_foo) or any of the prerequisites changed,
|
||||
@ -341,8 +374,6 @@ endif
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
space_escape := %%%SPACE%%%
|
||||
#
|
||||
define config_filename
|
||||
ifneq ($$(CONFIG_$(1)),"")
|
||||
$(1)_FILENAME := $$(subst \\,\,$$(subst \$$(quote),$$(quote),$$(subst $$(space_escape),\$$(space),$$(patsubst "%",%,$$(subst $$(space),$$(space_escape),$$(CONFIG_$(1)))))))
|
||||
|
@ -152,11 +152,11 @@ cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $<
|
||||
$(obj)/%.s: $(src)/%.c FORCE
|
||||
$(call if_changed_dep,cc_s_c)
|
||||
|
||||
quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
|
||||
cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
|
||||
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,cc_i_c)
|
||||
$(call if_changed_dep,cpp_i_c)
|
||||
|
||||
cmd_gensymtypes = \
|
||||
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
|
||||
@ -266,26 +266,24 @@ endif # CONFIG_STACK_VALIDATION
|
||||
|
||||
define rule_cc_o_c
|
||||
$(call echo-cmd,checksrc) $(cmd_checksrc) \
|
||||
$(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
|
||||
$(call cmd_and_fixdep,cc_o_c) \
|
||||
$(cmd_modversions) \
|
||||
$(cmd_objtool) \
|
||||
$(call echo-cmd,record_mcount) \
|
||||
$(cmd_record_mcount) \
|
||||
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
|
||||
$(dot-target).tmp; \
|
||||
rm -f $(depfile); \
|
||||
mv -f $(dot-target).tmp $(dot-target).cmd
|
||||
$(cmd_objtool) \
|
||||
$(call echo-cmd,record_mcount) $(cmd_record_mcount)
|
||||
endef
|
||||
|
||||
define rule_as_o_S
|
||||
$(call echo-cmd,as_o_S) $(cmd_as_o_S); \
|
||||
$(cmd_objtool) \
|
||||
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,as_o_S)' > \
|
||||
$(dot-target).tmp; \
|
||||
rm -f $(depfile); \
|
||||
mv -f $(dot-target).tmp $(dot-target).cmd
|
||||
$(call cmd_and_fixdep,as_o_S) \
|
||||
$(cmd_objtool)
|
||||
endef
|
||||
|
||||
# List module undefined symbols (or empty line if not enabled)
|
||||
ifdef CONFIG_TRIM_UNUSED_KSYMS
|
||||
cmd_undef_syms = $(NM) $@ | sed -n 's/^ \+U //p' | xargs echo
|
||||
else
|
||||
cmd_undef_syms = echo
|
||||
endif
|
||||
|
||||
# Built-in and composite module parts
|
||||
$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE
|
||||
$(call cmd,force_checksrc)
|
||||
@ -296,7 +294,8 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE
|
||||
$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE
|
||||
$(call cmd,force_checksrc)
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
@{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
|
||||
@{ echo $(@:.o=.ko); echo $@; \
|
||||
$(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
|
||||
|
||||
quiet_cmd_cc_lst_c = MKLST $@
|
||||
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
|
||||
@ -314,11 +313,11 @@ modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
|
||||
$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
|
||||
$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
|
||||
|
||||
quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
|
||||
cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
|
||||
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,as_s_S)
|
||||
$(call if_changed_dep,cpp_s_S)
|
||||
|
||||
quiet_cmd_as_o_S = AS $(quiet_modtag) $@
|
||||
cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
|
||||
@ -426,7 +425,8 @@ $(call multi_depend, $(multi-used-y), .o, -objs -y)
|
||||
|
||||
$(multi-used-m): FORCE
|
||||
$(call if_changed,link_multi-m)
|
||||
@{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
|
||||
@{ echo $(@:.o=.ko); echo $(link_multi_deps); \
|
||||
$(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod)
|
||||
$(call multi_depend, $(multi-used-m), .o, -objs -y -m)
|
||||
|
||||
targets += $(multi-used-y) $(multi-used-m)
|
||||
|
@ -24,6 +24,7 @@ warning-1 += $(call cc-option, -Wmissing-prototypes)
|
||||
warning-1 += -Wold-style-definition
|
||||
warning-1 += $(call cc-option, -Wmissing-include-dirs)
|
||||
warning-1 += $(call cc-option, -Wunused-but-set-variable)
|
||||
warning-1 += $(call cc-option, -Wunused-const-variable)
|
||||
warning-1 += $(call cc-disable-warning, missing-field-initializers)
|
||||
warning-1 += $(call cc-disable-warning, sign-compare)
|
||||
|
||||
|
@ -96,10 +96,10 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
|
||||
# Note: Files that end up in two or more modules are compiled without the
|
||||
# KBUILD_MODNAME definition. The reason is that any made-up name would
|
||||
# differ in different configs.
|
||||
name-fix = $(subst $(comma),_,$(subst -,_,$1))
|
||||
basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
|
||||
name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote)
|
||||
basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
|
||||
modname_flags = $(if $(filter 1,$(words $(modname))),\
|
||||
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
|
||||
-DKBUILD_MODNAME=$(call name-fix,$(modname)))
|
||||
|
||||
orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
|
||||
$(ccflags-y) $(CFLAGS_$(basetarget).o)
|
||||
@ -162,7 +162,7 @@ endif
|
||||
|
||||
c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
|
||||
$(__c_flags) $(modkern_cflags) \
|
||||
-D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
|
||||
$(basename_flags) $(modname_flags)
|
||||
|
||||
a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
|
||||
$(__a_flags) $(modkern_aflags)
|
||||
|
101
scripts/adjust_autoksyms.sh
Executable file
101
scripts/adjust_autoksyms.sh
Executable file
@ -0,0 +1,101 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script to create/update include/generated/autoksyms.h and dependency files
|
||||
#
|
||||
# Copyright: (C) 2016 Linaro Limited
|
||||
# Created by: Nicolas Pitre, January 2016
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2 as
|
||||
# published by the Free Software Foundation.
|
||||
|
||||
# Create/update the include/generated/autoksyms.h file from the list
|
||||
# of all module's needed symbols as recorded on the third line of
|
||||
# .tmp_versions/*.mod files.
|
||||
#
|
||||
# For each symbol being added or removed, the corresponding dependency
|
||||
# file's timestamp is updated to force a rebuild of the affected source
|
||||
# file. All arguments passed to this script are assumed to be a command
|
||||
# to be exec'd to trigger a rebuild of those files.
|
||||
|
||||
set -e
|
||||
|
||||
cur_ksyms_file="include/generated/autoksyms.h"
|
||||
new_ksyms_file="include/generated/autoksyms.h.tmpnew"
|
||||
|
||||
info() {
|
||||
if [ "$quiet" != "silent_" ]; then
|
||||
printf " %-7s %s\n" "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
info "CHK" "$cur_ksyms_file"
|
||||
|
||||
# Use "make V=1" to debug this script.
|
||||
case "$KBUILD_VERBOSE" in
|
||||
*1*)
|
||||
set -x
|
||||
;;
|
||||
esac
|
||||
|
||||
# We need access to CONFIG_ symbols
|
||||
case "${KCONFIG_CONFIG}" in
|
||||
*/*)
|
||||
. "${KCONFIG_CONFIG}"
|
||||
;;
|
||||
*)
|
||||
# Force using a file from the current directory
|
||||
. "./${KCONFIG_CONFIG}"
|
||||
esac
|
||||
|
||||
# In case it doesn't exist yet...
|
||||
if [ -e "$cur_ksyms_file" ]; then touch "$cur_ksyms_file"; fi
|
||||
|
||||
# Generate a new ksym list file with symbols needed by the current
|
||||
# set of modules.
|
||||
cat > "$new_ksyms_file" << EOT
|
||||
/*
|
||||
* Automatically generated file; DO NOT EDIT.
|
||||
*/
|
||||
|
||||
EOT
|
||||
sed -ns -e '3{s/ /\n/g;/^$/!p;}' "$MODVERDIR"/*.mod | sort -u |
|
||||
while read sym; do
|
||||
if [ -n "$CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX" ]; then
|
||||
sym="${sym#_}"
|
||||
fi
|
||||
echo "#define __KSYM_${sym} 1"
|
||||
done >> "$new_ksyms_file"
|
||||
|
||||
# Special case for modversions (see modpost.c)
|
||||
if [ -n "$CONFIG_MODVERSIONS" ]; then
|
||||
echo "#define __KSYM_module_layout 1" >> "$new_ksyms_file"
|
||||
fi
|
||||
|
||||
# Extract changes between old and new list and touch corresponding
|
||||
# dependency files.
|
||||
changed=$(
|
||||
count=0
|
||||
sort "$cur_ksyms_file" "$new_ksyms_file" | uniq -u |
|
||||
sed -n 's/^#define __KSYM_\(.*\) 1/\1/p' | tr "A-Z_" "a-z/" |
|
||||
while read sympath; do
|
||||
if [ -z "$sympath" ]; then continue; fi
|
||||
depfile="include/config/ksym/${sympath}.h"
|
||||
mkdir -p "$(dirname "$depfile")"
|
||||
touch "$depfile"
|
||||
echo $((count += 1))
|
||||
done | tail -1 )
|
||||
changed=${changed:-0}
|
||||
|
||||
if [ $changed -gt 0 ]; then
|
||||
# Replace the old list with tne new one
|
||||
old=$(grep -c "^#define __KSYM_" "$cur_ksyms_file" || true)
|
||||
new=$(grep -c "^#define __KSYM_" "$new_ksyms_file" || true)
|
||||
info "KSYMS" "symbols: before=$old, after=$new, changed=$changed"
|
||||
info "UPD" "$cur_ksyms_file"
|
||||
mv -f "$new_ksyms_file" "$cur_ksyms_file"
|
||||
# Then trigger a rebuild of affected source files
|
||||
exec $@
|
||||
else
|
||||
rm -f "$new_ksyms_file"
|
||||
fi
|
@ -120,13 +120,15 @@
|
||||
#define INT_NFIG ntohl(0x4e464947)
|
||||
#define INT_FIG_ ntohl(0x4649475f)
|
||||
|
||||
int insert_extra_deps;
|
||||
char *target;
|
||||
char *depfile;
|
||||
char *cmdline;
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
|
||||
fprintf(stderr, "Usage: fixdep [-e] <depfile> <target> <cmdline>\n");
|
||||
fprintf(stderr, " -e insert extra dependencies given on stdin\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -138,6 +140,40 @@ static void print_cmdline(void)
|
||||
printf("cmd_%s := %s\n\n", target, cmdline);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out a dependency path from a symbol name
|
||||
*/
|
||||
static void print_config(const char *m, int slen)
|
||||
{
|
||||
int c, i;
|
||||
|
||||
printf(" $(wildcard include/config/");
|
||||
for (i = 0; i < slen; i++) {
|
||||
c = m[i];
|
||||
if (c == '_')
|
||||
c = '/';
|
||||
else
|
||||
c = tolower(c);
|
||||
putchar(c);
|
||||
}
|
||||
printf(".h) \\\n");
|
||||
}
|
||||
|
||||
static void do_extra_deps(void)
|
||||
{
|
||||
if (insert_extra_deps) {
|
||||
char buf[80];
|
||||
while(fgets(buf, sizeof(buf), stdin)) {
|
||||
int len = strlen(buf);
|
||||
if (len < 2 || buf[len-1] != '\n') {
|
||||
fprintf(stderr, "fixdep: bad data on stdin\n");
|
||||
exit(1);
|
||||
}
|
||||
print_config(buf, len-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct item {
|
||||
struct item *next;
|
||||
unsigned int len;
|
||||
@ -197,23 +233,12 @@ static void define_config(const char *name, int len, unsigned int hash)
|
||||
static void use_config(const char *m, int slen)
|
||||
{
|
||||
unsigned int hash = strhash(m, slen);
|
||||
int c, i;
|
||||
|
||||
if (is_defined_config(m, slen, hash))
|
||||
return;
|
||||
|
||||
define_config(m, slen, hash);
|
||||
|
||||
printf(" $(wildcard include/config/");
|
||||
for (i = 0; i < slen; i++) {
|
||||
c = m[i];
|
||||
if (c == '_')
|
||||
c = '/';
|
||||
else
|
||||
c = tolower(c);
|
||||
putchar(c);
|
||||
}
|
||||
printf(".h) \\\n");
|
||||
print_config(m, slen);
|
||||
}
|
||||
|
||||
static void parse_config_file(const char *map, size_t len)
|
||||
@ -250,7 +275,7 @@ static void parse_config_file(const char *map, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
/* test is s ends in sub */
|
||||
/* test if s ends in sub */
|
||||
static int strrcmp(const char *s, const char *sub)
|
||||
{
|
||||
int slen = strlen(s);
|
||||
@ -333,6 +358,7 @@ static void parse_dep_file(void *map, size_t len)
|
||||
|
||||
/* Ignore certain dependencies */
|
||||
if (strrcmp(s, "include/generated/autoconf.h") &&
|
||||
strrcmp(s, "include/generated/autoksyms.h") &&
|
||||
strrcmp(s, "arch/um/include/uml-config.h") &&
|
||||
strrcmp(s, "include/linux/kconfig.h") &&
|
||||
strrcmp(s, ".ver")) {
|
||||
@ -378,6 +404,8 @@ static void parse_dep_file(void *map, size_t len)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
do_extra_deps();
|
||||
|
||||
printf("\n%s: $(deps_%s)\n\n", target, target);
|
||||
printf("$(deps_%s):\n", target);
|
||||
}
|
||||
@ -434,7 +462,10 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
traps();
|
||||
|
||||
if (argc != 4)
|
||||
if (argc == 5 && !strcmp(argv[1], "-e")) {
|
||||
insert_extra_deps = 1;
|
||||
argv++;
|
||||
} else if (argc != 4)
|
||||
usage();
|
||||
|
||||
depfile = argv[1];
|
||||
|
@ -873,5 +873,8 @@ int main(int argc, char **argv)
|
||||
(double)nsyms / (double)HASH_BUCKETS);
|
||||
}
|
||||
|
||||
if (dumpfile)
|
||||
fclose(dumpfile);
|
||||
|
||||
return errors != 0;
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ quiet_cmd_mkdir = MKDIR $(dir $@)
|
||||
quiet_cmd_cc_o_c = CC $@
|
||||
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
|
||||
|
||||
quiet_cmd_cc_i_c = CPP $@
|
||||
cmd_cc_i_c = $(CC) $(c_flags) -E -o $@ $<
|
||||
quiet_cmd_cpp_i_c = CPP $@
|
||||
cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $<
|
||||
|
||||
quiet_cmd_cc_s_c = AS $@
|
||||
cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<
|
||||
@ -83,11 +83,11 @@ $(OUTPUT)%.o: %.S FORCE
|
||||
|
||||
$(OUTPUT)%.i: %.c FORCE
|
||||
$(call rule_mkdir)
|
||||
$(call if_changed_dep,cc_i_c)
|
||||
$(call if_changed_dep,cpp_i_c)
|
||||
|
||||
$(OUTPUT)%.s: %.S FORCE
|
||||
$(call rule_mkdir)
|
||||
$(call if_changed_dep,cc_i_c)
|
||||
$(call if_changed_dep,cpp_i_c)
|
||||
|
||||
$(OUTPUT)%.s: %.c FORCE
|
||||
$(call rule_mkdir)
|
||||
|
Loading…
Reference in New Issue
Block a user