Commit df202b45 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'kbuild-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kbuild updates from Masahiro Yamada:

 - Add HOSTPKG_CONFIG env variable to allow users to override pkg-config

 - Support W=e as a shorthand for KCFLAGS=-Werror

 - Fix CONFIG_IKHEADERS build to support toybox cpio

 - Add scripts/dummy-tools/pahole to ease distro packagers' life

 - Suppress false-positive warnings from checksyscalls.sh for W=2 build

 - Factor out the common code of arch/*/boot/install.sh into
   scripts/install.sh

 - Support 'kernel-install' tool in scripts/prune-kernel

 - Refactor module-versioning to link the symbol versions at the final
   link of vmlinux and modules

 - Remove CONFIG_MODULE_REL_CRCS because module-versioning now works in
   an arch-agnostic way

 - Refactor modpost, Makefiles

* tag 'kbuild-v5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (56 commits)
  genksyms: adjust the output format to modpost
  kbuild: stop merging *.symversions
  kbuild: link symbol CRCs at final link, removing CONFIG_MODULE_REL_CRCS
  modpost: extract symbol versions from *.cmd files
  modpost: add sym_find_with_module() helper
  modpost: change the license of EXPORT_SYMBOL to bool type
  modpost: remove left-over cross_compile declaration
  kbuild: record symbol versions in *.cmd files
  kbuild: generate a list of objects in vmlinux
  modpost: move *.mod.c generation to write_mod_c_files()
  modpost: merge add_{intree_flag,retpoline,staging_flag} to add_header
  scripts/prune-kernel: Use kernel-install if available
  kbuild: factor out the common installation code into scripts/install.sh
  modpost: split new_symbol() to symbol allocation and hash table addition
  modpost: make sym_add_exported() always allocate a new symbol
  modpost: make multiple export error
  modpost: dump Module.symvers in the same order of modules.order
  modpost: traverse the namespace_list in order
  modpost: use doubly linked list for dump_lists
  modpost: traverse unresolved symbols in order
  ...
parents 16477cdf 5ce2176b
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
*.symversions *.symversions
*.tab.[ch] *.tab.[ch]
*.tar *.tar
*.usyms
*.xz *.xz
*.zst *.zst
Module.symvers Module.symvers
......
...@@ -693,6 +693,8 @@ in documenting basic Kconfig syntax a more precise definition of Kconfig ...@@ -693,6 +693,8 @@ in documenting basic Kconfig syntax a more precise definition of Kconfig
semantics is welcomed. One project deduced Kconfig semantics through semantics is welcomed. One project deduced Kconfig semantics through
the use of the xconfig configurator [1]_. Work should be done to confirm if the use of the xconfig configurator [1]_. Work should be done to confirm if
the deduced semantics matches our intended Kconfig design goals. the deduced semantics matches our intended Kconfig design goals.
Another project formalized a denotational semantics of a core subset of
the Kconfig language [10]_.
Having well defined semantics can be useful for tools for practical Having well defined semantics can be useful for tools for practical
evaluation of dependencies, for instance one such case was work to evaluation of dependencies, for instance one such case was work to
...@@ -700,6 +702,8 @@ express in boolean abstraction of the inferred semantics of Kconfig to ...@@ -700,6 +702,8 @@ express in boolean abstraction of the inferred semantics of Kconfig to
translate Kconfig logic into boolean formulas and run a SAT solver on this to translate Kconfig logic into boolean formulas and run a SAT solver on this to
find dead code / features (always inactive), 114 dead features were found in find dead code / features (always inactive), 114 dead features were found in
Linux using this methodology [1]_ (Section 8: Threats to validity). Linux using this methodology [1]_ (Section 8: Threats to validity).
The kismet tool, based on the semantics in [10]_, finds abuses of reverse
dependencies and has led to dozens of committed fixes to Linux Kconfig files [11]_.
Confirming this could prove useful as Kconfig stands as one of the leading Confirming this could prove useful as Kconfig stands as one of the leading
industrial variability modeling languages [1]_ [2]_. Its study would help industrial variability modeling languages [1]_ [2]_. Its study would help
...@@ -738,3 +742,5 @@ https://kernelnewbies.org/KernelProjects/kconfig-sat ...@@ -738,3 +742,5 @@ https://kernelnewbies.org/KernelProjects/kconfig-sat
.. [7] https://vamos.cs.fau.de .. [7] https://vamos.cs.fau.de
.. [8] https://undertaker.cs.fau.de .. [8] https://undertaker.cs.fau.de
.. [9] https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf .. [9] https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf
.. [10] https://paulgazzillo.com/papers/esecfse21.pdf
.. [11] https://github.com/paulgazz/kmax
...@@ -436,6 +436,7 @@ else ...@@ -436,6 +436,7 @@ else
HOSTCC = gcc HOSTCC = gcc
HOSTCXX = g++ HOSTCXX = g++
endif endif
HOSTPKG_CONFIG = pkg-config
KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ KBUILD_USERHOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
-O2 -fomit-frame-pointer -std=gnu11 \ -O2 -fomit-frame-pointer -std=gnu11 \
...@@ -533,7 +534,7 @@ KBUILD_LDFLAGS_MODULE := ...@@ -533,7 +534,7 @@ KBUILD_LDFLAGS_MODULE :=
KBUILD_LDFLAGS := KBUILD_LDFLAGS :=
CLANG_FLAGS := CLANG_FLAGS :=
export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG
export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
...@@ -1294,11 +1295,12 @@ scripts_unifdef: scripts_basic ...@@ -1294,11 +1295,12 @@ scripts_unifdef: scripts_basic
# Install # Install
# Many distributions have the custom install script, /sbin/installkernel. # Many distributions have the custom install script, /sbin/installkernel.
# If DKMS is installed, 'make install' will eventually recuses back # If DKMS is installed, 'make install' will eventually recurse back
# to the this Makefile to build and install external modules. # to this Makefile to build and install external modules.
# Cancel sub_make_done so that options such as M=, V=, etc. are parsed. # Cancel sub_make_done so that options such as M=, V=, etc. are parsed.
install: sub_make_done := quiet_cmd_install = INSTALL $(INSTALL_PATH)
cmd_install = unset sub_make_done; $(srctree)/scripts/install.sh
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Tools # Tools
...@@ -1650,6 +1652,7 @@ help: ...@@ -1650,6 +1652,7 @@ help:
@echo ' 1: warnings which may be relevant and do not occur too often' @echo ' 1: warnings which may be relevant and do not occur too often'
@echo ' 2: warnings which occur quite often but may still be relevant' @echo ' 2: warnings which occur quite often but may still be relevant'
@echo ' 3: more obscure warnings, can most likely be ignored' @echo ' 3: more obscure warnings, can most likely be ignored'
@echo ' e: warnings are being treated as errors'
@echo ' Multiple levels can be combined with W=12 or W=123' @echo ' Multiple levels can be combined with W=12 or W=123'
@echo '' @echo ''
@echo 'Execute "make" or "make all" to build all targets marked with [*] ' @echo 'Execute "make" or "make all" to build all targets marked with [*] '
...@@ -1792,7 +1795,8 @@ ifdef single-build ...@@ -1792,7 +1795,8 @@ ifdef single-build
# .ko is special because modpost is needed # .ko is special because modpost is needed
single-ko := $(sort $(filter %.ko, $(MAKECMDGOALS))) single-ko := $(sort $(filter %.ko, $(MAKECMDGOALS)))
single-no-ko := $(sort $(patsubst %.ko,%.mod, $(MAKECMDGOALS))) single-no-ko := $(filter-out $(single-ko), $(MAKECMDGOALS)) \
$(foreach x, o mod, $(patsubst %.ko, %.$x, $(single-ko)))
$(single-ko): single_modpost $(single-ko): single_modpost
@: @:
...@@ -1848,7 +1852,7 @@ clean: $(clean-dirs) ...@@ -1848,7 +1852,7 @@ clean: $(clean-dirs)
-o -name '*.ko.*' \ -o -name '*.ko.*' \
-o -name '*.dtb' -o -name '*.dtbo' -o -name '*.dtb.S' -o -name '*.dt.yaml' \ -o -name '*.dtb' -o -name '*.dtbo' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
-o -name '*.dwo' -o -name '*.lst' \ -o -name '*.dwo' -o -name '*.lst' \
-o -name '*.su' -o -name '*.mod' \ -o -name '*.su' -o -name '*.mod' -o -name '*.usyms' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.lex.c' -o -name '*.tab.[ch]' \ -o -name '*.lex.c' -o -name '*.tab.[ch]' \
-o -name '*.asn1.[ch]' \ -o -name '*.asn1.[ch]' \
......
...@@ -312,9 +312,9 @@ $(BOOT_TARGETS): vmlinux ...@@ -312,9 +312,9 @@ $(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
@$(kecho) ' Kernel: $(boot)/$@ is ready' @$(kecho) ' Kernel: $(boot)/$@ is ready'
$(INSTALL_TARGETS): KBUILD_IMAGE = $(boot)/$(patsubst %install,%Image,$@)
$(INSTALL_TARGETS): $(INSTALL_TARGETS):
$(CONFIG_SHELL) $(srctree)/$(boot)/install.sh "$(KERNELRELEASE)" \ $(call cmd,install)
$(boot)/$(patsubst %install,%Image,$@) System.map "$(INSTALL_PATH)"
PHONY += vdso_install PHONY += vdso_install
vdso_install: vdso_install:
......
#!/bin/sh #!/bin/sh
# #
# arch/arm/boot/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -18,25 +16,6 @@ ...@@ -18,25 +16,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
if [ "$(basename $2)" = "zImage" ]; then if [ "$(basename $2)" = "zImage" ]; then
# Compressed install # Compressed install
......
...@@ -162,11 +162,9 @@ Image: vmlinux ...@@ -162,11 +162,9 @@ Image: vmlinux
Image.%: Image Image.%: Image
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
install: install-image := Image install: KBUILD_IMAGE := $(boot)/Image
zinstall: install-image := Image.gz
install zinstall: install zinstall:
$(CONFIG_SHELL) $(srctree)/$(boot)/install.sh $(KERNELRELEASE) \ $(call cmd,install)
$(boot)/$(install-image) System.map "$(INSTALL_PATH)"
PHONY += vdso_install PHONY += vdso_install
vdso_install: vdso_install:
......
#!/bin/sh #!/bin/sh
# #
# arch/arm64/boot/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -18,25 +16,6 @@ ...@@ -18,25 +16,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
if [ "$(basename $2)" = "Image.gz" ]; then if [ "$(basename $2)" = "Image.gz" ]; then
# Compressed install # Compressed install
......
...@@ -72,8 +72,9 @@ archheaders: ...@@ -72,8 +72,9 @@ archheaders:
CLEAN_FILES += vmlinux.gz CLEAN_FILES += vmlinux.gz
install: vmlinux.gz install: KBUILD_IMAGE := vmlinux.gz
sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)" install:
$(call cmd,install)
define archhelp define archhelp
echo '* compressed - Build compressed kernel image' echo '* compressed - Build compressed kernel image'
......
#!/bin/sh #!/bin/sh
# #
# arch/ia64/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -17,14 +15,6 @@ ...@@ -17,14 +15,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
# Default install - same as make zlilo
if [ -f $4/vmlinuz ]; then if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old mv $4/vmlinuz $4/vmlinuz.old
......
...@@ -138,5 +138,6 @@ CLEAN_FILES += vmlinux.gz vmlinux.bz2 ...@@ -138,5 +138,6 @@ CLEAN_FILES += vmlinux.gz vmlinux.bz2
archheaders: archheaders:
$(Q)$(MAKE) $(build)=arch/m68k/kernel/syscalls all $(Q)$(MAKE) $(build)=arch/m68k/kernel/syscalls all
install: KBUILD_IMAGE := vmlinux.gz
install: install:
sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)" $(call cmd,install)
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
generated-y += syscall_table.h generated-y += syscall_table.h
generic-y += export.h
generic-y += extable.h generic-y += extable.h
generic-y += kvm_para.h generic-y += kvm_para.h
generic-y += mcs_spinlock.h generic-y += mcs_spinlock.h
......
#define KCRC_ALIGN 2
#include <asm-generic/export.h>
...@@ -15,28 +15,6 @@ ...@@ -15,28 +15,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
# Default install - same as make zlilo
if [ -f $4/vmlinuz ]; then if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old mv $4/vmlinuz $4/vmlinuz.old
......
...@@ -56,8 +56,7 @@ $(BOOT_TARGETS): vmlinux ...@@ -56,8 +56,7 @@ $(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(nios2-boot) $(nios2-boot)/$@ $(Q)$(MAKE) $(build)=$(nios2-boot) $(nios2-boot)/$@
install: install:
sh $(srctree)/$(nios2-boot)/install.sh $(KERNELRELEASE) \ $(call cmd,install)
$(KBUILD_IMAGE) System.map "$(INSTALL_PATH)"
define archhelp define archhelp
echo '* vmImage - Kernel-only image for U-Boot ($(KBUILD_IMAGE))' echo '* vmImage - Kernel-only image for U-Boot ($(KBUILD_IMAGE))'
......
...@@ -15,28 +15,6 @@ ...@@ -15,28 +15,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
# Default install - same as make zlilo
if [ -f $4/vmlinuz ]; then if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old mv $4/vmlinuz $4/vmlinuz.old
......
...@@ -184,12 +184,11 @@ vdso_install: ...@@ -184,12 +184,11 @@ vdso_install:
$(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso $@ $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso $@
$(if $(CONFIG_COMPAT_VDSO), \ $(if $(CONFIG_COMPAT_VDSO), \
$(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 $@) $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 $@)
install:
$(CONFIG_SHELL) $(srctree)/arch/parisc/install.sh \ install: KBUILD_IMAGE := vmlinux
$(KERNELRELEASE) vmlinux System.map "$(INSTALL_PATH)" zinstall: KBUILD_IMAGE := vmlinuz
zinstall: install zinstall:
$(CONFIG_SHELL) $(srctree)/arch/parisc/install.sh \ $(call cmd,install)
$(KERNELRELEASE) vmlinuz System.map "$(INSTALL_PATH)"
CLEAN_FILES += lifimage CLEAN_FILES += lifimage
MRPROPER_FILES += palo.conf MRPROPER_FILES += palo.conf
......
#!/bin/sh #!/bin/sh
# #
# arch/parisc/install.sh, derived from arch/i386/boot/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -17,32 +15,6 @@ ...@@ -17,32 +15,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -n "${INSTALLKERNEL}" ]; then
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi
fi
# Default install
if [ "$(basename $2)" = "vmlinuz" ]; then if [ "$(basename $2)" = "vmlinuz" ]; then
# Compressed install # Compressed install
......
...@@ -566,7 +566,6 @@ config RELOCATABLE ...@@ -566,7 +566,6 @@ config RELOCATABLE
bool "Build a relocatable kernel" bool "Build a relocatable kernel"
depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE))
select NONSTATIC_KERNEL select NONSTATIC_KERNEL
select MODULE_REL_CRCS if MODVERSIONS
help help
This builds a kernel image that is capable of running at the This builds a kernel image that is capable of running at the
location the kernel is loaded at. For ppc32, there is no any location the kernel is loaded at. For ppc32, there is no any
......
...@@ -408,8 +408,7 @@ endef ...@@ -408,8 +408,7 @@ endef
PHONY += install PHONY += install
install: install:
sh -x $(srctree)/$(boot)/install.sh "$(KERNELRELEASE)" vmlinux \ $(call cmd,install)
System.map "$(INSTALL_PATH)"
ifeq ($(KBUILD_EXTMOD),) ifeq ($(KBUILD_EXTMOD),)
# We need to generate vdso-offsets.h before compiling certain files in kernel/. # We need to generate vdso-offsets.h before compiling certain files in kernel/.
......
...@@ -453,8 +453,8 @@ clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ ...@@ -453,8 +453,8 @@ clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \
clean-kernel-base := vmlinux.strip vmlinux.bin clean-kernel-base := vmlinux.strip vmlinux.bin
clean-kernel := $(addsuffix .gz,$(clean-kernel-base)) clean-kernel := $(addsuffix .gz,$(clean-kernel-base))
clean-kernel += $(addsuffix .xz,$(clean-kernel-base)) clean-kernel += $(addsuffix .xz,$(clean-kernel-base))
# If not absolute clean-files are relative to $(obj). # clean-files are relative to $(obj).
clean-files += $(addprefix $(objtree)/, $(clean-kernel)) clean-files += $(addprefix ../../../, $(clean-kernel))
WRAPPER_OBJDIR := /usr/lib/kernel-wrapper WRAPPER_OBJDIR := /usr/lib/kernel-wrapper
WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts
......
...@@ -15,32 +15,9 @@ ...@@ -15,32 +15,9 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
# Bail with error code if anything goes wrong
set -e set -e
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
# Default install
# this should work for both the pSeries zImage and the iSeries vmlinux.sm # this should work for both the pSeries zImage and the iSeries vmlinux.sm
image_name=`basename $2` image_name=`basename $2`
......
...@@ -139,11 +139,10 @@ $(BOOT_TARGETS): vmlinux ...@@ -139,11 +139,10 @@ $(BOOT_TARGETS): vmlinux
Image.%: Image Image.%: Image
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
install: install-image = Image install: KBUILD_IMAGE := $(boot)/Image
zinstall: install-image = Image.gz zinstall: KBUILD_IMAGE := $(boot)/Image.gz
install zinstall: install zinstall:
$(CONFIG_SHELL) $(srctree)/$(boot)/install.sh $(KERNELRELEASE) \ $(call cmd,install)
$(boot)/$(install-image) System.map "$(INSTALL_PATH)"
PHONY += rv32_randconfig PHONY += rv32_randconfig
rv32_randconfig: rv32_randconfig:
......
#!/bin/sh #!/bin/sh
# #
# arch/riscv/boot/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public # This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive # License. See the file "COPYING" in the main directory of this archive
# for more details. # for more details.
...@@ -18,25 +16,6 @@ ...@@ -18,25 +16,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
if [ "$(basename $2)" = "Image.gz" ]; then if [ "$(basename $2)" = "Image.gz" ]; then
# Compressed install # Compressed install
......
...@@ -586,7 +586,6 @@ endchoice ...@@ -586,7 +586,6 @@ endchoice
config RELOCATABLE config RELOCATABLE
bool "Build a relocatable kernel" bool "Build a relocatable kernel"
select MODULE_REL_CRCS if MODVERSIONS
default y default y
help help
This builds a kernel image that retains relocation information This builds a kernel image that retains relocation information
......
...@@ -142,8 +142,7 @@ all: bzImage ...@@ -142,8 +142,7 @@ all: bzImage
KBUILD_IMAGE := $(boot)/bzImage KBUILD_IMAGE := $(boot)/bzImage
install: install:
sh -x $(srctree)/$(boot)/install.sh $(KERNELRELEASE) $(KBUILD_IMAGE) \ $(call cmd,install)
System.map "$(INSTALL_PATH)"
bzImage: vmlinux bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
......
...@@ -14,12 +14,6 @@ ...@@ -14,12 +14,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
echo "Warning: '${INSTALLKERNEL}' command not available - additional " \ echo "Warning: '${INSTALLKERNEL}' command not available - additional " \
"bootloader config required" >&2 "bootloader config required" >&2
......
...@@ -72,8 +72,7 @@ image zImage uImage tftpboot.img vmlinux.aout: vmlinux ...@@ -72,8 +72,7 @@ image zImage uImage tftpboot.img vmlinux.aout: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
install: install:
sh $(srctree)/$(boot)/install.sh $(KERNELRELEASE) $(KBUILD_IMAGE) \ $(call cmd,install)
System.map "$(INSTALL_PATH)"
archheaders: archheaders:
$(Q)$(MAKE) $(build)=arch/sparc/kernel/syscalls all $(Q)$(MAKE) $(build)=arch/sparc/kernel/syscalls all
......
...@@ -15,28 +15,6 @@ ...@@ -15,28 +15,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
# Default install - same as make zlilo
if [ -f $4/vmlinuz ]; then if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old mv $4/vmlinuz $4/vmlinuz.old
......
...@@ -106,7 +106,6 @@ config LD_SCRIPT_DYN ...@@ -106,7 +106,6 @@ config LD_SCRIPT_DYN
bool bool
default y default y
depends on !LD_SCRIPT_STATIC depends on !LD_SCRIPT_STATIC
select MODULE_REL_CRCS if MODVERSIONS
config LD_SCRIPT_DYN_RPATH config LD_SCRIPT_DYN_RPATH
bool "set rpath in the binary" if EXPERT bool "set rpath in the binary" if EXPERT
......
...@@ -271,8 +271,7 @@ $(BOOT_TARGETS): vmlinux ...@@ -271,8 +271,7 @@ $(BOOT_TARGETS): vmlinux
PHONY += install PHONY += install
install: install:
$(CONFIG_SHELL) $(srctree)/$(boot)/install.sh $(KERNELRELEASE) \ $(call cmd,install)
$(KBUILD_IMAGE) System.map "$(INSTALL_PATH)"
PHONY += vdso_install PHONY += vdso_install
vdso_install: vdso_install:
......
...@@ -15,28 +15,6 @@ ...@@ -15,28 +15,6 @@
# $2 - kernel image file # $2 - kernel image file
# $3 - kernel map file # $3 - kernel map file
# $4 - default install path (blank if root directory) # $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
# Default install - same as make zlilo
if [ -f $4/vmlinuz ]; then if [ -f $4/vmlinuz ]; then
mv $4/vmlinuz $4/vmlinuz.old mv $4/vmlinuz $4/vmlinuz.old
......
...@@ -86,5 +86,5 @@ targets += x509_revocation_list ...@@ -86,5 +86,5 @@ targets += x509_revocation_list
hostprogs := extract-cert hostprogs := extract-cert
HOSTCFLAGS_extract-cert.o = $(shell pkg-config --cflags libcrypto 2> /dev/null) HOSTCFLAGS_extract-cert.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null)
HOSTLDLIBS_extract-cert = $(shell pkg-config --libs libcrypto 2> /dev/null || echo -lcrypto) HOSTLDLIBS_extract-cert = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto)
...@@ -2,6 +2,14 @@ ...@@ -2,6 +2,14 @@
#ifndef __ASM_GENERIC_EXPORT_H #ifndef __ASM_GENERIC_EXPORT_H
#define __ASM_GENERIC_EXPORT_H #define __ASM_GENERIC_EXPORT_H
/*
* This comment block is used by fixdep. Please do not remove.
*
* When CONFIG_MODVERSIONS is changed from n to y, all source files having
* EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a
* side effect of the *.o build rule.
*/
#ifndef KSYM_FUNC #ifndef KSYM_FUNC
#define KSYM_FUNC(x) x #define KSYM_FUNC(x) x
#endif #endif
...@@ -12,9 +20,6 @@ ...@@ -12,9 +20,6 @@
#else #else
#define KSYM_ALIGN 4 #define KSYM_ALIGN 4
#endif #endif
#ifndef KCRC_ALIGN
#define KCRC_ALIGN 4
#endif
.macro __put, val, name .macro __put, val, name
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
...@@ -43,17 +48,6 @@ __ksymtab_\name: ...@@ -43,17 +48,6 @@ __ksymtab_\name:
__kstrtab_\name: __kstrtab_\name:
.asciz "\name" .asciz "\name"
.previous .previous
#ifdef CONFIG_MODVERSIONS
.section ___kcrctab\sec+\name,"a"
.balign KCRC_ALIGN
#if defined(CONFIG_MODULE_REL_CRCS)
.long __crc_\name - .
#else
.long __crc_\name
#endif
.weak __crc_\name
.previous
#endif
#endif #endif
.endm .endm
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Please do not include this explicitly.
* This is used by C files generated by modpost.
*/
#ifndef __LINUX_EXPORT_INTERNAL_H__
#define __LINUX_EXPORT_INTERNAL_H__
#include <linux/compiler.h>
#include <linux/types.h>
/* __used is needed to keep __crc_* for LTO */
#define SYMBOL_CRC(sym, crc, sec) \
u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc
#endif /* __LINUX_EXPORT_INTERNAL_H__ */
...@@ -11,6 +11,14 @@ ...@@ -11,6 +11,14 @@
* hackers place grumpy comments in header files. * hackers place grumpy comments in header files.
*/ */
/*
* This comment block is used by fixdep. Please do not remove.
*
* When CONFIG_MODVERSIONS is changed from n to y, all source files having
* EXPORT_SYMBOL variants must be re-compiled because genksyms is run as a
* side effect of the *.o build rule.
*/
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#ifdef MODULE #ifdef MODULE
extern struct module __this_module; extern struct module __this_module;
...@@ -19,26 +27,6 @@ extern struct module __this_module; ...@@ -19,26 +27,6 @@ extern struct module __this_module;
#define THIS_MODULE ((struct module *)0) #define THIS_MODULE ((struct module *)0)
#endif #endif
#ifdef CONFIG_MODVERSIONS
/* Mark the CRC weak since genksyms apparently decides not to
* generate a checksums for some symbols */
#if defined(CONFIG_MODULE_REL_CRCS)
#define __CRC_SYMBOL(sym, sec) \
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
" .weak __crc_" #sym " \n" \
" .long __crc_" #sym " - . \n" \
" .previous \n")
#else
#define __CRC_SYMBOL(sym, sec) \
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
" .weak __crc_" #sym " \n" \
" .long __crc_" #sym " \n" \
" .previous \n")
#endif
#else
#define __CRC_SYMBOL(sym, sec)
#endif
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
#include <linux/compiler.h> #include <linux/compiler.h>
/* /*
...@@ -85,7 +73,6 @@ struct kernel_symbol { ...@@ -85,7 +73,6 @@ struct kernel_symbol {
/* /*
* For every exported symbol, do the following: * For every exported symbol, do the following:
* *
* - If applicable, place a CRC entry in the __kcrctab section.
* - Put the name of the symbol and namespace (empty string "" for none) in * - Put the name of the symbol and namespace (empty string "" for none) in
* __ksymtab_strings. * __ksymtab_strings.
* - Place a struct kernel_symbol entry in the __ksymtab section. * - Place a struct kernel_symbol entry in the __ksymtab section.
...@@ -98,7 +85,6 @@ struct kernel_symbol { ...@@ -98,7 +85,6 @@ struct kernel_symbol {
extern typeof(sym) sym; \ extern typeof(sym) sym; \
extern const char __kstrtab_##sym[]; \ extern const char __kstrtab_##sym[]; \
extern const char __kstrtabns_##sym[]; \ extern const char __kstrtabns_##sym[]; \
__CRC_SYMBOL(sym, sec); \
asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \ asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \
"__kstrtab_" #sym ": \n" \ "__kstrtab_" #sym ": \n" \
" .asciz \"" #sym "\" \n" \ " .asciz \"" #sym "\" \n" \
......
...@@ -2136,10 +2136,6 @@ config ASM_MODVERSIONS ...@@ -2136,10 +2136,6 @@ config ASM_MODVERSIONS
assembly. This can be enabled only when the target architecture assembly. This can be enabled only when the target architecture
supports it. supports it.
config MODULE_REL_CRCS
bool
depends on MODVERSIONS
config MODULE_SRCVERSION_ALL config MODULE_SRCVERSION_ALL
bool "Source checksum for all modules" bool "Source checksum for all modules"
help help
......
...@@ -74,7 +74,7 @@ fi ...@@ -74,7 +74,7 @@ fi
# of tree builds having stale headers in srctree. Just silence CPIO for now. # of tree builds having stale headers in srctree. Just silence CPIO for now.
for f in $dir_list; for f in $dir_list;
do find "$f" -name "*.h"; do find "$f" -name "*.h";
done | cpio --quiet -pd $cpio_dir >/dev/null 2>&1 done | cpio --quiet -pdu $cpio_dir >/dev/null 2>&1
# Remove comments except SDPX lines # Remove comments except SDPX lines
find $cpio_dir -type f -print0 | find $cpio_dir -type f -print0 |
......
...@@ -1231,11 +1231,6 @@ static int try_to_force_load(struct module *mod, const char *reason) ...@@ -1231,11 +1231,6 @@ static int try_to_force_load(struct module *mod, const char *reason)
#ifdef CONFIG_MODVERSIONS #ifdef CONFIG_MODVERSIONS
static u32 resolve_rel_crc(const s32 *crc)
{
return *(u32 *)((void *)crc + *crc);
}
static int check_version(const struct load_info *info, static int check_version(const struct load_info *info,
const char *symname, const char *symname,
struct module *mod, struct module *mod,
...@@ -1264,9 +1259,6 @@ static int check_version(const struct load_info *info, ...@@ -1264,9 +1259,6 @@ static int check_version(const struct load_info *info,
if (strcmp(versions[i].name, symname) != 0) if (strcmp(versions[i].name, symname) != 0)
continue; continue;
if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
crcval = resolve_rel_crc(crc);
else
crcval = *crc; crcval = *crc;
if (versions[i].crc == crcval) if (versions[i].crc == crcval)
return 1; return 1;
......
...@@ -14,8 +14,8 @@ hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert ...@@ -14,8 +14,8 @@ hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
HOSTLDLIBS_sorttable = -lpthread HOSTLDLIBS_sorttable = -lpthread
HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
HOSTCFLAGS_sign-file.o = $(shell pkg-config --cflags libcrypto 2> /dev/null) HOSTCFLAGS_sign-file.o = $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /dev/null)
HOSTLDLIBS_sign-file = $(shell pkg-config --libs libcrypto 2> /dev/null || echo -lcrypto) HOSTLDLIBS_sign-file = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto)
ifdef CONFIG_UNWINDER_ORC ifdef CONFIG_UNWINDER_ORC
ifeq ($(ARCH),x86_64) ifeq ($(ARCH),x86_64)
......
...@@ -85,7 +85,8 @@ ifdef need-builtin ...@@ -85,7 +85,8 @@ ifdef need-builtin
targets-for-builtin += $(obj)/built-in.a targets-for-builtin += $(obj)/built-in.a
endif endif
targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m))) targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \
$(patsubst %.o, %.$x, $(filter %.o, $(obj-m))))
ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m))) targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m)))
...@@ -125,18 +126,16 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< ...@@ -125,18 +126,16 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $<
$(obj)/%.i: $(src)/%.c FORCE $(obj)/%.i: $(src)/%.c FORCE
$(call if_changed_dep,cpp_i_c) $(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. # These mirror gensymtypes_S and co below, keep them in synch.
cmd_gensymtypes_c = \ cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms)
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
scripts/genksyms/genksyms $(if $(1), -T $(2)) \
$(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
$(if $(KBUILD_PRESERVE),-p) \
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
cmd_cc_symtypes_c = \ cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null
$(call cmd_gensymtypes_c,true,$@) >/dev/null; \
test -s $@ || rm -f $@
$(obj)/%.symtypes : $(src)/%.c FORCE $(obj)/%.symtypes : $(src)/%.c FORCE
$(call cmd,cc_symtypes_c) $(call cmd,cc_symtypes_c)
...@@ -162,35 +161,18 @@ ifdef CONFIG_MODVERSIONS ...@@ -162,35 +161,18 @@ ifdef CONFIG_MODVERSIONS
# o if <file>.o doesn't contain a __ksymtab version, i.e. does # o if <file>.o doesn't contain a __ksymtab version, i.e. does
# not export symbols, it's done. # not export symbols, it's done.
# o otherwise, we calculate symbol versions using the good old # o otherwise, we calculate symbol versions using the good old
# genksyms on the preprocessed source and postprocess them in a way # genksyms on the preprocessed source and dump them into the .cmd file.
# that they are usable as a linker script # o modpost will extract versions from that file and create *.c files that will
# o generate .tmp_<file>.o from <file>.o using the linker to # be compiled and linked to the kernel and/or modules.
# replace the unresolved symbols __crc_exported_symbol with
# the actual value of the checksum generated by genksyms gen_symversions = \
# o remove .tmp_<file>.o to <file>.o
ifdef CONFIG_LTO_CLANG
# Generate .o.symversions files for each .o with exported symbols, and link these
# to the kernel and/or modules at the end.
cmd_modversions_c = \
if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \ if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
> $@.symversions; \ >> $(dot-target).cmd; \
else \
rm -f $@.symversions; \
fi;
else
cmd_modversions_c = \
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
> $(@D)/.tmp_$(@F:.o=.ver); \
\
$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
-T $(@D)/.tmp_$(@F:.o=.ver); \
mv -f $(@D)/.tmp_$(@F) $@; \
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
fi fi
endif
cmd_gen_symversions_c = $(call gen_symversions,c)
endif endif
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
...@@ -265,9 +247,6 @@ endif ...@@ -265,9 +247,6 @@ endif
ifdef CONFIG_TRIM_UNUSED_KSYMS ifdef CONFIG_TRIM_UNUSED_KSYMS
cmd_gen_ksymdeps = \ cmd_gen_ksymdeps = \
$(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
# List module undefined symbols
undefined_syms = $(NM) $< | $(AWK) '$$1 == "U" { printf("%s%s", x++ ? " " : "", $$2) }';
endif endif
define rule_cc_o_c define rule_cc_o_c
...@@ -276,7 +255,7 @@ define rule_cc_o_c ...@@ -276,7 +255,7 @@ define rule_cc_o_c
$(call cmd,checksrc) $(call cmd,checksrc)
$(call cmd,checkdoc) $(call cmd,checkdoc)
$(call cmd,gen_objtooldep) $(call cmd,gen_objtooldep)
$(call cmd,modversions_c) $(call cmd,gen_symversions_c)
$(call cmd,record_mcount) $(call cmd,record_mcount)
endef endef
...@@ -284,7 +263,7 @@ define rule_as_o_S ...@@ -284,7 +263,7 @@ define rule_as_o_S
$(call cmd_and_fixdep,as_o_S) $(call cmd_and_fixdep,as_o_S)
$(call cmd,gen_ksymdeps) $(call cmd,gen_ksymdeps)
$(call cmd,gen_objtooldep) $(call cmd,gen_objtooldep)
$(call cmd,modversions_S) $(call cmd,gen_symversions_S)
endef endef
# Built-in and composite module parts # Built-in and composite module parts
...@@ -298,8 +277,6 @@ ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) ...@@ -298,8 +277,6 @@ ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
quiet_cmd_cc_prelink_modules = LD [M] $@ quiet_cmd_cc_prelink_modules = LD [M] $@
cmd_cc_prelink_modules = \ cmd_cc_prelink_modules = \
$(LD) $(ld_flags) -r -o $@ \ $(LD) $(ld_flags) -r -o $@ \
$(shell [ -s $(@:.prelink.o=.o.symversions) ] && \
echo -T $(@:.prelink.o=.o.symversions)) \
--whole-archive $(filter-out FORCE,$^) \ --whole-archive $(filter-out FORCE,$^) \
$(cmd_objtool) $(cmd_objtool)
...@@ -313,14 +290,18 @@ $(obj)/%.prelink.o: $(obj)/%.o FORCE ...@@ -313,14 +290,18 @@ $(obj)/%.prelink.o: $(obj)/%.o FORCE
$(call if_changed,cc_prelink_modules) $(call if_changed,cc_prelink_modules)
endif endif
cmd_mod = { \ cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \
echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \ $(AWK) -v RS='( |\n)' '!x[$$0]++' > $@
$(undefined_syms) echo; \
} > $@
$(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE $(obj)/%.mod: FORCE
$(call if_changed,mod) $(call if_changed,mod)
# List module undefined symbols
cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@
$(obj)/%.usyms: $(obj)/%$(mod-prelink-ext).o FORCE
$(call if_changed,undefined_syms)
quiet_cmd_cc_lst_c = MKLST $@ quiet_cmd_cc_lst_c = MKLST $@
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
$(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
...@@ -349,16 +330,10 @@ cmd_gensymtypes_S = \ ...@@ -349,16 +330,10 @@ cmd_gensymtypes_S = \
$(CPP) $(a_flags) $< | \ $(CPP) $(a_flags) $< | \
grep "\<___EXPORT_SYMBOL\>" | \ grep "\<___EXPORT_SYMBOL\>" | \
sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ; } | \ sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ; } | \
$(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \ $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms)
scripts/genksyms/genksyms $(if $(1), -T $(2)) \
$(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
$(if $(KBUILD_PRESERVE),-p) \
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@
cmd_cc_symtypes_S = \ cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null
$(call cmd_gensymtypes_S,true,$@) >/dev/null; \
test -s $@ || rm -f $@
$(obj)/%.symtypes : $(src)/%.S FORCE $(obj)/%.symtypes : $(src)/%.S FORCE
$(call cmd,cc_symtypes_S) $(call cmd,cc_symtypes_S)
...@@ -378,16 +353,8 @@ ifdef CONFIG_ASM_MODVERSIONS ...@@ -378,16 +353,8 @@ ifdef CONFIG_ASM_MODVERSIONS
# versioning matches the C process described above, with difference that # versioning matches the C process described above, with difference that
# we parse asm-prototypes.h C header to get function definitions. # we parse asm-prototypes.h C header to get function definitions.
cmd_modversions_S = \ cmd_gen_symversions_S = $(call gen_symversions,S)
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
$(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
> $(@D)/.tmp_$(@F:.o=.ver); \
\
$(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
-T $(@D)/.tmp_$(@F:.o=.ver); \
mv -f $(@D)/.tmp_$(@F) $@; \
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
fi
endif endif
$(obj)/%.o: $(src)/%.S FORCE $(obj)/%.o: $(src)/%.S FORCE
...@@ -422,17 +389,6 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler ...@@ -422,17 +389,6 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
# combine symversions for later processing
ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y)
cmd_update_lto_symversions = \
rm -f $@.symversions \
$(foreach n, $(filter-out FORCE,$^), \
$(if $(shell test -s $(n).symversions && echo y), \
; cat $(n).symversions >> $@.symversions))
else
cmd_update_lto_symversions = echo >/dev/null
endif
# #
# Rule to compile a set of .o files into one .a file (without symbol table) # Rule to compile a set of .o files into one .a file (without symbol table)
# #
...@@ -440,11 +396,8 @@ endif ...@@ -440,11 +396,8 @@ endif
quiet_cmd_ar_builtin = AR $@ quiet_cmd_ar_builtin = AR $@
cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs) cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
quiet_cmd_ar_and_symver = AR $@
cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin)
$(obj)/built-in.a: $(real-obj-y) FORCE $(obj)/built-in.a: $(real-obj-y) FORCE
$(call if_changed,ar_and_symver) $(call if_changed,ar_builtin)
# #
# Rule to create modules.order file # Rule to create modules.order file
...@@ -464,32 +417,24 @@ $(obj)/modules.order: $(obj-m) FORCE ...@@ -464,32 +417,24 @@ $(obj)/modules.order: $(obj-m) FORCE
# #
# Rule to compile a set of .o files into one .a file (with symbol table) # Rule to compile a set of .o files into one .a file (with symbol table)
# #
quiet_cmd_ar_lib = AR $@
cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar)
$(obj)/lib.a: $(lib-y) FORCE $(obj)/lib.a: $(lib-y) FORCE
$(call if_changed,ar_lib) $(call if_changed,ar)
# NOTE:
# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
# module is turned into a multi object module, $^ will contain header file
# dependencies recorded in the .*.cmd file.
ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
quiet_cmd_link_multi-m = AR [M] $@ quiet_cmd_link_multi-m = AR [M] $@
cmd_link_multi-m = \ cmd_link_multi-m = \
$(cmd_update_lto_symversions); \
rm -f $@; \ rm -f $@; \
$(AR) cDPrsT $@ $(filter %.o,$^) $(AR) cDPrsT $@ @$(patsubst %.o,%.mod,$@)
else else
quiet_cmd_link_multi-m = LD [M] $@ quiet_cmd_link_multi-m = LD [M] $@
cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@)
endif endif
$(multi-obj-m): FORCE $(multi-obj-m): %.o: %.mod FORCE
$(call if_changed,link_multi-m) $(call if_changed,link_multi-m)
$(call multi_depend, $(multi-obj-m), .o, -objs -y -m) $(call multi_depend, $(multi-obj-m), .o, -objs -y -m)
targets += $(multi-obj-m)
targets := $(filter-out $(PHONY), $(targets)) targets := $(filter-out $(PHONY), $(targets))
# Add intermediate targets: # Add intermediate targets:
......
...@@ -36,13 +36,7 @@ __clean-files := \ ...@@ -36,13 +36,7 @@ __clean-files := \
__clean-files := $(filter-out $(no-clean-files), $(__clean-files)) __clean-files := $(filter-out $(no-clean-files), $(__clean-files))
# clean-files is given relative to the current directory, unless it __clean-files := $(wildcard $(addprefix $(obj)/, $(__clean-files)))
# starts with $(objtree)/ (which means "./", so do not add "./" unless
# you want to delete a file from the toplevel object directory).
__clean-files := $(wildcard \
$(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \
$(filter $(objtree)/%, $(__clean-files)))
# ========================================================================== # ==========================================================================
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
# ========================================================================== # ==========================================================================
# make W=... settings # make W=... settings
# #
# There are three warning groups enabled by W=1, W=2, W=3. # 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=123. # They are independent, and can be combined like W=12 or W=123e.
# ========================================================================== # ==========================================================================
KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned) KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned)
...@@ -94,3 +94,12 @@ KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat) ...@@ -94,3 +94,12 @@ KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat)
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3 KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3
endif endif
#
# W=e - error out on warnings
#
ifneq ($(findstring e, $(KBUILD_EXTRA_WARN)),)
KBUILD_CFLAGS += -Werror
endif
...@@ -236,9 +236,9 @@ endif ...@@ -236,9 +236,9 @@ endif
# Usage: # Usage:
# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) # $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)
define multi_depend define multi_depend
$(foreach m, $(notdir $1), \ $(foreach m, $1, \
$(eval $(obj)/$m: \ $(eval $m: \
$(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) $(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3))))
endef endef
# Copy a file # Copy a file
......
# SPDX-License-Identifier: GPL-2.0-only
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
# for c_flags
include $(srctree)/scripts/Makefile.lib
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)
targets := $(MAKECMDGOALS)
# 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)
...@@ -35,7 +35,7 @@ case "$KBUILD_VERBOSE" in ...@@ -35,7 +35,7 @@ case "$KBUILD_VERBOSE" in
esac esac
# Generate a new symbol list file # Generate a new symbol list file
$CONFIG_SHELL $srctree/scripts/gen_autoksyms.sh "$new_ksyms_file" $CONFIG_SHELL $srctree/scripts/gen_autoksyms.sh --modorder "$new_ksyms_file"
# Extract changes between old and new list and touch corresponding # Extract changes between old and new list and touch corresponding
# dependency files. # dependency files.
......
...@@ -268,4 +268,4 @@ syscall_list() { ...@@ -268,4 +268,4 @@ syscall_list() {
} }
(ignore_list && syscall_list $(dirname $0)/../arch/x86/entry/syscalls/syscall_32.tbl) | \ (ignore_list && syscall_list $(dirname $0)/../arch/x86/entry/syscalls/syscall_32.tbl) | \
$* -Wno-error -E -x c - > /dev/null $* -Wno-error -Wno-unused-macros -E -x c - > /dev/null
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
echo v99.99
...@@ -2,13 +2,10 @@ ...@@ -2,13 +2,10 @@
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
# Create an autoksyms.h header file from the list of all module's needed symbols # Create an autoksyms.h header file from the list of all module's needed symbols
# as recorded on the second line of *.mod files and the user-provided symbol # as recorded in *.usyms files and the user-provided symbol whitelist.
# whitelist.
set -e set -e
output_file="$1"
# Use "make V=1" to debug this script. # Use "make V=1" to debug this script.
case "$KBUILD_VERBOSE" in case "$KBUILD_VERBOSE" in
*1*) *1*)
...@@ -16,6 +13,15 @@ case "$KBUILD_VERBOSE" in ...@@ -16,6 +13,15 @@ case "$KBUILD_VERBOSE" in
;; ;;
esac esac
read_modorder=
if [ "$1" = --modorder ]; then
shift
read_modorder=1
fi
output_file="$1"
needed_symbols= needed_symbols=
# Special case for modversions (see modpost.c) # Special case for modversions (see modpost.c)
...@@ -41,10 +47,8 @@ cat > "$output_file" << EOT ...@@ -41,10 +47,8 @@ cat > "$output_file" << EOT
EOT EOT
[ -f modules.order ] && modlist=modules.order || modlist=/dev/null
{ {
sed 's/ko$/mod/' $modlist | xargs -n1 sed -n -e '2p' [ -n "${read_modorder}" ] && sed 's/ko$/usyms/' modules.order | xargs cat
echo "$needed_symbols" echo "$needed_symbols"
[ -n "$ksym_wl" ] && cat "$ksym_wl" [ -n "$ksym_wl" ] && cat "$ksym_wl"
} | sed -e 's/ /\n/g' | sed -n -e '/^$/!p' | } | sed -e 's/ /\n/g' | sed -n -e '/^$/!p' |
......
...@@ -33,7 +33,7 @@ char *cur_filename; ...@@ -33,7 +33,7 @@ char *cur_filename;
int in_source_file; int in_source_file;
static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
flag_preserve, flag_warnings, flag_rel_crcs; flag_preserve, flag_warnings;
static int errors; static int errors;
static int nsyms; static int nsyms;
...@@ -680,11 +680,7 @@ void export_symbol(const char *name) ...@@ -680,11 +680,7 @@ void export_symbol(const char *name)
if (flag_dump_defs) if (flag_dump_defs)
fputs(">\n", debugfile); fputs(">\n", debugfile);
/* Used as a linker script. */ printf("#SYMVER %s 0x%08lx\n", name, crc);
printf(!flag_rel_crcs ? "__crc_%s = 0x%08lx;\n" :
"SECTIONS { .rodata : ALIGN(4) { "
"__crc_%s = .; LONG(0x%08lx); } }\n",
name, crc);
} }
} }
...@@ -733,7 +729,6 @@ static void genksyms_usage(void) ...@@ -733,7 +729,6 @@ static void genksyms_usage(void)
" -q, --quiet Disable warnings (default)\n" " -q, --quiet Disable warnings (default)\n"
" -h, --help Print this message\n" " -h, --help Print this message\n"
" -V, --version Print the release version\n" " -V, --version Print the release version\n"
" -R, --relative-crc Emit section relative symbol CRCs\n"
#else /* __GNU_LIBRARY__ */ #else /* __GNU_LIBRARY__ */
" -s Select symbol prefix\n" " -s Select symbol prefix\n"
" -d Increment the debug level (repeatable)\n" " -d Increment the debug level (repeatable)\n"
...@@ -745,7 +740,6 @@ static void genksyms_usage(void) ...@@ -745,7 +740,6 @@ static void genksyms_usage(void)
" -q Disable warnings (default)\n" " -q Disable warnings (default)\n"
" -h Print this message\n" " -h Print this message\n"
" -V Print the release version\n" " -V Print the release version\n"
" -R Emit section relative symbol CRCs\n"
#endif /* __GNU_LIBRARY__ */ #endif /* __GNU_LIBRARY__ */
, stderr); , stderr);
} }
...@@ -766,14 +760,13 @@ int main(int argc, char **argv) ...@@ -766,14 +760,13 @@ int main(int argc, char **argv)
{"preserve", 0, 0, 'p'}, {"preserve", 0, 0, 'p'},
{"version", 0, 0, 'V'}, {"version", 0, 0, 'V'},
{"help", 0, 0, 'h'}, {"help", 0, 0, 'h'},
{"relative-crc", 0, 0, 'R'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
while ((o = getopt_long(argc, argv, "s:dwqVDr:T:phR", while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph",
&long_opts[0], NULL)) != EOF) &long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */ #else /* __GNU_LIBRARY__ */
while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF) while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF)
#endif /* __GNU_LIBRARY__ */ #endif /* __GNU_LIBRARY__ */
switch (o) { switch (o) {
case 'd': case 'd':
...@@ -813,9 +806,6 @@ int main(int argc, char **argv) ...@@ -813,9 +806,6 @@ int main(int argc, char **argv)
case 'h': case 'h':
genksyms_usage(); genksyms_usage();
return 0; return 0;
case 'R':
flag_rel_crcs = 1;
break;
default: default:
genksyms_usage(); genksyms_usage();
return 1; return 1;
......
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 1995 by Linus Torvalds
#
# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
# Common code factored out by Masahiro Yamada
set -e
# Make sure the files actually exist
for file in "${KBUILD_IMAGE}" System.map
do
if [ ! -f "${file}" ]; then
echo >&2
echo >&2 " *** Missing file: ${file}"
echo >&2 ' *** You need to run "make" before "make install".'
echo >&2
exit 1
fi
done
# User/arch may have a custom install script
for file in "${HOME}/bin/${INSTALLKERNEL}" \
"/sbin/${INSTALLKERNEL}" \
"${srctree}/arch/${SRCARCH}/install.sh" \
"${srctree}/arch/${SRCARCH}/boot/install.sh"
do
if [ ! -x "${file}" ]; then
continue
fi
# installkernel(8) says the parameters are like follows:
#
# installkernel version zImage System.map [directory]
exec "${file}" "${KERNELRELEASE}" "${KBUILD_IMAGE}" System.map "${INSTALL_PATH}"
done
echo "No install script found" >&2
exit 1
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
PKG="gtk+-2.0 gmodule-2.0 libglade-2.0" PKG="gtk+-2.0 gmodule-2.0 libglade-2.0"
if [ -z "$(command -v pkg-config)" ]; then if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then
echo >&2 "*" echo >&2 "*"
echo >&2 "* 'make gconfig' requires 'pkg-config'. Please install it." echo >&2 "* 'make gconfig' requires '${HOSTPKG_CONFIG}'. Please install it."
echo >&2 "*" echo >&2 "*"
exit 1 exit 1
fi fi
if ! pkg-config --exists $PKG; then if ! ${HOSTPKG_CONFIG} --exists $PKG; then
echo >&2 "*" echo >&2 "*"
echo >&2 "* Unable to find the GTK+ installation. Please make sure that" echo >&2 "* Unable to find the GTK+ installation. Please make sure that"
echo >&2 "* the GTK+ 2.0 development package is correctly installed." echo >&2 "* the GTK+ 2.0 development package is correctly installed."
...@@ -19,12 +19,12 @@ if ! pkg-config --exists $PKG; then ...@@ -19,12 +19,12 @@ if ! pkg-config --exists $PKG; then
exit 1 exit 1
fi fi
if ! pkg-config --atleast-version=2.0.0 gtk+-2.0; then if ! ${HOSTPKG_CONFIG} --atleast-version=2.0.0 gtk+-2.0; then
echo >&2 "*" echo >&2 "*"
echo >&2 "* GTK+ is present but version >= 2.0.0 is required." echo >&2 "* GTK+ is present but version >= 2.0.0 is required."
echo >&2 "*" echo >&2 "*"
exit 1 exit 1
fi fi
echo cflags=\"$(pkg-config --cflags $PKG)\" echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG)\"
echo libs=\"$(pkg-config --libs $PKG)\" echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG)\"
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
PKG="ncursesw" PKG="ncursesw"
PKG2="ncurses" PKG2="ncurses"
if [ -n "$(command -v pkg-config)" ]; then if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then
if pkg-config --exists $PKG; then if ${HOSTPKG_CONFIG} --exists $PKG; then
echo cflags=\"$(pkg-config --cflags $PKG)\" echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG)\"
echo libs=\"$(pkg-config --libs $PKG)\" echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG)\"
exit 0 exit 0
fi fi
if pkg-config --exists $PKG2; then if ${HOSTPKG_CONFIG} --exists $PKG2; then
echo cflags=\"$(pkg-config --cflags $PKG2)\" echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG2)\"
echo libs=\"$(pkg-config --libs $PKG2)\" echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG2)\"
exit 0 exit 0
fi fi
fi fi
...@@ -46,7 +46,7 @@ echo >&2 "* Unable to find the ncurses package." ...@@ -46,7 +46,7 @@ echo >&2 "* Unable to find the ncurses package."
echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev"
echo >&2 "* depending on your distribution)." echo >&2 "* depending on your distribution)."
echo >&2 "*" echo >&2 "*"
echo >&2 "* You may also need to install pkg-config to find the" echo >&2 "* You may also need to install ${HOSTPKG_CONFIG} to find the"
echo >&2 "* ncurses installed in a non-default location." echo >&2 "* ncurses installed in a non-default location."
echo >&2 "*" echo >&2 "*"
exit 1 exit 1
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
PKG="ncursesw menuw panelw" PKG="ncursesw menuw panelw"
PKG2="ncurses menu panel" PKG2="ncurses menu panel"
if [ -n "$(command -v pkg-config)" ]; then if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then
if pkg-config --exists $PKG; then if ${HOSTPKG_CONFIG} --exists $PKG; then
echo cflags=\"$(pkg-config --cflags $PKG)\" echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG)\"
echo libs=\"$(pkg-config --libs $PKG)\" echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG)\"
exit 0 exit 0
fi fi
if pkg-config --exists $PKG2; then if ${HOSTPKG_CONFIG} --exists $PKG2; then
echo cflags=\"$(pkg-config --cflags $PKG2)\" echo cflags=\"$(${HOSTPKG_CONFIG} --cflags $PKG2)\"
echo libs=\"$(pkg-config --libs $PKG2)\" echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG2)\"
exit 0 exit 0
fi fi
fi fi
...@@ -44,7 +44,7 @@ echo >&2 "* Unable to find the ncurses package." ...@@ -44,7 +44,7 @@ echo >&2 "* Unable to find the ncurses package."
echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev" echo >&2 "* Install ncurses (ncurses-devel or libncurses-dev"
echo >&2 "* depending on your distribution)." echo >&2 "* depending on your distribution)."
echo >&2 "*" echo >&2 "*"
echo >&2 "* You may also need to install pkg-config to find the" echo >&2 "* You may also need to install ${HOSTPKG_CONFIG} to find the"
echo >&2 "* ncurses installed in a non-default location." echo >&2 "* ncurses installed in a non-default location."
echo >&2 "*" echo >&2 "*"
exit 1 exit 1
...@@ -3,22 +3,22 @@ ...@@ -3,22 +3,22 @@
PKG="Qt5Core Qt5Gui Qt5Widgets" PKG="Qt5Core Qt5Gui Qt5Widgets"
if [ -z "$(command -v pkg-config)" ]; then if [ -z "$(command -v ${HOSTPKG_CONFIG})" ]; then
echo >&2 "*" echo >&2 "*"
echo >&2 "* 'make xconfig' requires 'pkg-config'. Please install it." echo >&2 "* 'make xconfig' requires '${HOSTPKG_CONFIG}'. Please install it."
echo >&2 "*" echo >&2 "*"
exit 1 exit 1
fi fi
if pkg-config --exists $PKG; then if ${HOSTPKG_CONFIG} --exists $PKG; then
echo cflags=\"-std=c++11 -fPIC $(pkg-config --cflags $PKG)\" echo cflags=\"-std=c++11 -fPIC $(${HOSTPKG_CONFIG} --cflags $PKG)\"
echo libs=\"$(pkg-config --libs $PKG)\" echo libs=\"$(${HOSTPKG_CONFIG} --libs $PKG)\"
echo moc=\"$(pkg-config --variable=host_bins Qt5Core)/moc\" echo moc=\"$(${HOSTPKG_CONFIG} --variable=host_bins Qt5Core)/moc\"
exit 0 exit 0
fi fi
echo >&2 "*" echo >&2 "*"
echo >&2 "* Could not find Qt5 via pkg-config." echo >&2 "* Could not find Qt5 via ${HOSTPKG_CONFIG}."
echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH" echo >&2 "* Please install Qt5 and make sure it's in PKG_CONFIG_PATH"
echo >&2 "*" echo >&2 "*"
exit 1 exit 1
...@@ -56,20 +56,6 @@ gen_initcalls() ...@@ -56,20 +56,6 @@ gen_initcalls()
> .tmp_initcalls.lds > .tmp_initcalls.lds
} }
# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
# .tmp_symversions.lds
gen_symversions()
{
info GEN .tmp_symversions.lds
rm -f .tmp_symversions.lds
for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
if [ -f ${o}.symversions ]; then
cat ${o}.symversions >> .tmp_symversions.lds
fi
done
}
# Link of vmlinux.o used for section mismatch analysis # Link of vmlinux.o used for section mismatch analysis
# ${1} output file # ${1} output file
modpost_link() modpost_link()
...@@ -88,11 +74,6 @@ modpost_link() ...@@ -88,11 +74,6 @@ modpost_link()
gen_initcalls gen_initcalls
lds="-T .tmp_initcalls.lds" lds="-T .tmp_initcalls.lds"
if is_enabled CONFIG_MODVERSIONS; then
gen_symversions
lds="${lds} -T .tmp_symversions.lds"
fi
# This might take a while, so indicate that we're doing # This might take a while, so indicate that we're doing
# an LTO link # an LTO link
info LTO ${1} info LTO ${1}
...@@ -199,6 +180,10 @@ vmlinux_link() ...@@ -199,6 +180,10 @@ vmlinux_link()
libs="${KBUILD_VMLINUX_LIBS}" libs="${KBUILD_VMLINUX_LIBS}"
fi fi
if is_enabled CONFIG_MODULES; then
objs="${objs} .vmlinux.export.o"
fi
if [ "${SRCARCH}" = "um" ]; then if [ "${SRCARCH}" = "um" ]; then
wl=-Wl, wl=-Wl,
ld="${CC}" ld="${CC}"
...@@ -320,13 +305,14 @@ cleanup() ...@@ -320,13 +305,14 @@ cleanup()
rm -f .btf.* rm -f .btf.*
rm -f .tmp_System.map rm -f .tmp_System.map
rm -f .tmp_initcalls.lds rm -f .tmp_initcalls.lds
rm -f .tmp_symversions.lds
rm -f .tmp_vmlinux* rm -f .tmp_vmlinux*
rm -f System.map rm -f System.map
rm -f vmlinux rm -f vmlinux
rm -f vmlinux.map rm -f vmlinux.map
rm -f vmlinux.o rm -f vmlinux.o
rm -f .vmlinux.d rm -f .vmlinux.d
rm -f .vmlinux.objs
rm -f .vmlinux.export.c
} }
# Use "make V=1" to debug this script # Use "make V=1" to debug this script
...@@ -358,6 +344,16 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 ...@@ -358,6 +344,16 @@ ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
modpost_link vmlinux.o modpost_link vmlinux.o
objtool_link vmlinux.o objtool_link vmlinux.o
# Generate the list of objects in vmlinux
for f in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
case ${f} in
*.a)
${AR} t ${f} ;;
*)
echo ${f} ;;
esac
done > .vmlinux.objs
# modpost vmlinux.o to check for section mismatches # modpost vmlinux.o to check for section mismatches
${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1 ${MAKE} -f "${srctree}/scripts/Makefile.modpost" MODPOST_VMLINUX=1
...@@ -368,6 +364,10 @@ info GEN modules.builtin ...@@ -368,6 +364,10 @@ info GEN modules.builtin
tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' | tr '\0' '\n' < modules.builtin.modinfo | sed -n 's/^[[:alnum:]:_]*\.file=//p' |
tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin tr ' ' '\n' | uniq | sed -e 's:^:kernel/:' -e 's/$/.ko/' > modules.builtin
if is_enabled CONFIG_MODULES; then
${MAKE} -f "${srctree}/scripts/Makefile.vmlinux" .vmlinux.export.o
fi
btf_vmlinux_bin_o="" btf_vmlinux_bin_o=""
if is_enabled CONFIG_DEBUG_INFO_BTF; then if is_enabled CONFIG_DEBUG_INFO_BTF; then
btf_vmlinux_bin_o=.btf.vmlinux.bin.o btf_vmlinux_bin_o=.btf.vmlinux.bin.o
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LIST_H
#define LIST_H
#include <stdbool.h>
#include <stddef.h>
/* Are two types/vars the same type (ignoring qualifiers)? */
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
void *__mptr = (void *)(ptr); \
_Static_assert(__same_type(*(ptr), ((type *)0)->member) || \
__same_type(*(ptr), void), \
"pointer type mismatch in container_of()"); \
((type *)(__mptr - offsetof(type, member))); })
#define LIST_POISON1 ((void *) 0x100)
#define LIST_POISON2 ((void *) 0x122)
/*
* Circular doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/**
* INIT_LIST_HEAD - Initialize a list_head structure
* @list: list_head structure to be initialized.
*
* Initializes the list_head to point to itself. If it is a list header,
* the result is an empty list.
*/
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del_entry(entry);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/**
* list_is_head - tests whether @list is the list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_head(const struct list_head *list, const struct list_head *head)
{
return list == head;
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_next_entry - get the next element in list
* @pos: the type * to cursor
* @member: the name of the list_head within the struct.
*/
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(pos)), member)
/**
* list_entry_is_head - test if the entry points to the head of the list
* @pos: the type * to cursor
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_entry_is_head(pos, head, member) \
(&pos->member == (head))
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \
!list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))
/**
* list_for_each_entry_safe - iterate over list of given type. Safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member), \
n = list_next_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))
#endif /* LIST_H */
...@@ -23,20 +23,20 @@ ...@@ -23,20 +23,20 @@
#include "../../include/linux/license.h" #include "../../include/linux/license.h"
/* Are we using CONFIG_MODVERSIONS? */ /* Are we using CONFIG_MODVERSIONS? */
static int modversions = 0; static bool modversions;
/* Is CONFIG_MODULE_SRCVERSION_ALL set? */ /* Is CONFIG_MODULE_SRCVERSION_ALL set? */
static int all_versions = 0; static bool all_versions;
/* If we are modposting external module set to 1 */ /* If we are modposting external module set to 1 */
static int external_module = 0; static bool external_module;
/* Only warn about unresolved symbols */ /* Only warn about unresolved symbols */
static int warn_unresolved = 0; static bool warn_unresolved;
/* How a symbol is exported */
static int sec_mismatch_count = 0; static int sec_mismatch_count;
static int sec_mismatch_warn_only = true; static bool sec_mismatch_warn_only = true;
/* ignore missing files */ /* ignore missing files */
static int ignore_missing_files; static bool ignore_missing_files;
/* If set to 1, only warn (instead of error) about missing ns imports */ /* If set to 1, only warn (instead of error) about missing ns imports */
static int allow_missing_ns_imports; static bool allow_missing_ns_imports;
static bool error_occurred; static bool error_occurred;
...@@ -47,12 +47,6 @@ static bool error_occurred; ...@@ -47,12 +47,6 @@ static bool error_occurred;
#define MAX_UNRESOLVED_REPORTS 10 #define MAX_UNRESOLVED_REPORTS 10
static unsigned int nr_unresolved; static unsigned int nr_unresolved;
enum export {
export_plain,
export_gpl,
export_unknown
};
/* In kernel, this size is defined in linux/module.h; /* In kernel, this size is defined in linux/module.h;
* here we use Elf_Addr instead of long for covering cross-compile * here we use Elf_Addr instead of long for covering cross-compile
*/ */
...@@ -165,16 +159,17 @@ char *get_line(char **stringp) ...@@ -165,16 +159,17 @@ char *get_line(char **stringp)
} }
/* A list of all modules we processed */ /* A list of all modules we processed */
static struct module *modules; LIST_HEAD(modules);
static struct module *find_module(const char *modname) static struct module *find_module(const char *modname)
{ {
struct module *mod; struct module *mod;
for (mod = modules; mod; mod = mod->next) list_for_each_entry(mod, &modules, list) {
if (strcmp(mod->name, modname) == 0) if (strcmp(mod->name, modname) == 0)
break;
return mod; return mod;
}
return NULL;
} }
static struct module *new_module(const char *modname) static struct module *new_module(const char *modname)
...@@ -184,12 +179,22 @@ static struct module *new_module(const char *modname) ...@@ -184,12 +179,22 @@ static struct module *new_module(const char *modname)
mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1)); mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1));
memset(mod, 0, sizeof(*mod)); memset(mod, 0, sizeof(*mod));
/* add to list */ INIT_LIST_HEAD(&mod->exported_symbols);
INIT_LIST_HEAD(&mod->unresolved_symbols);
INIT_LIST_HEAD(&mod->missing_namespaces);
INIT_LIST_HEAD(&mod->imported_namespaces);
strcpy(mod->name, modname); strcpy(mod->name, modname);
mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0); mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0);
mod->gpl_compatible = -1;
mod->next = modules; /*
modules = mod; * Set mod->is_gpl_compatible to true by default. If MODULE_LICENSE()
* is missing, do not check the use for EXPORT_SYMBOL_GPL() becasue
* modpost will exit wiht error anyway.
*/
mod->is_gpl_compatible = true;
list_add_tail(&mod->list, &modules);
return mod; return mod;
} }
...@@ -201,13 +206,14 @@ static struct module *new_module(const char *modname) ...@@ -201,13 +206,14 @@ static struct module *new_module(const char *modname)
struct symbol { struct symbol {
struct symbol *next; struct symbol *next;
struct list_head list; /* link to module::exported_symbols or module::unresolved_symbols */
struct module *module; struct module *module;
unsigned int crc;
int crc_valid;
char *namespace; char *namespace;
unsigned int weak:1; unsigned int crc;
unsigned int is_static:1; /* 1 if symbol is not global */ bool crc_valid;
enum export export; /* Type of export */ bool weak;
bool is_static; /* true if symbol is not global */
bool is_gpl_only; /* exported by EXPORT_SYMBOL_GPL */
char name[]; char name[];
}; };
...@@ -230,32 +236,37 @@ static inline unsigned int tdb_hash(const char *name) ...@@ -230,32 +236,37 @@ static inline unsigned int tdb_hash(const char *name)
* Allocate a new symbols for use in the hash of exported symbols or * Allocate a new symbols for use in the hash of exported symbols or
* the list of unresolved symbols per module * the list of unresolved symbols per module
**/ **/
static struct symbol *alloc_symbol(const char *name, unsigned int weak, static struct symbol *alloc_symbol(const char *name)
struct symbol *next)
{ {
struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
strcpy(s->name, name); strcpy(s->name, name);
s->weak = weak; s->is_static = true;
s->next = next;
s->is_static = 1;
return s; return s;
} }
/* For the hash of exported symbols */ /* For the hash of exported symbols */
static struct symbol *new_symbol(const char *name, struct module *module, static void hash_add_symbol(struct symbol *sym)
enum export export)
{ {
unsigned int hash; unsigned int hash;
hash = tdb_hash(name) % SYMBOL_HASH_SIZE; hash = tdb_hash(sym->name) % SYMBOL_HASH_SIZE;
symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); sym->next = symbolhash[hash];
symbolhash[hash] = sym;
}
static void sym_add_unresolved(const char *name, struct module *mod, bool weak)
{
struct symbol *sym;
sym = alloc_symbol(name);
sym->weak = weak;
return symbolhash[hash]; list_add_tail(&sym->list, &mod->unresolved_symbols);
} }
static struct symbol *find_symbol(const char *name) static struct symbol *sym_find_with_module(const char *name, struct module *mod)
{ {
struct symbol *s; struct symbol *s;
...@@ -264,69 +275,46 @@ static struct symbol *find_symbol(const char *name) ...@@ -264,69 +275,46 @@ static struct symbol *find_symbol(const char *name)
name++; name++;
for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) { for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
if (strcmp(s->name, name) == 0) if (strcmp(s->name, name) == 0 && (!mod || s->module == mod))
return s; return s;
} }
return NULL; return NULL;
} }
static bool contains_namespace(struct namespace_list *list, static struct symbol *find_symbol(const char *name)
const char *namespace)
{ {
for (; list; list = list->next) return sym_find_with_module(name, NULL);
}
struct namespace_list {
struct list_head list;
char namespace[];
};
static bool contains_namespace(struct list_head *head, const char *namespace)
{
struct namespace_list *list;
list_for_each_entry(list, head, list) {
if (!strcmp(list->namespace, namespace)) if (!strcmp(list->namespace, namespace))
return true; return true;
}
return false; return false;
} }
static void add_namespace(struct namespace_list **list, const char *namespace) static void add_namespace(struct list_head *head, const char *namespace)
{ {
struct namespace_list *ns_entry; struct namespace_list *ns_entry;
if (!contains_namespace(*list, namespace)) { if (!contains_namespace(head, namespace)) {
ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) + ns_entry = NOFAIL(malloc(sizeof(*ns_entry) +
strlen(namespace) + 1)); strlen(namespace) + 1));
strcpy(ns_entry->namespace, namespace); strcpy(ns_entry->namespace, namespace);
ns_entry->next = *list; list_add_tail(&ns_entry->list, head);
*list = ns_entry;
} }
} }
static bool module_imports_namespace(struct module *module,
const char *namespace)
{
return contains_namespace(module->imported_namespaces, namespace);
}
static const struct {
const char *str;
enum export export;
} export_list[] = {
{ .str = "EXPORT_SYMBOL", .export = export_plain },
{ .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
{ .str = "(unknown)", .export = export_unknown },
};
static const char *export_str(enum export ex)
{
return export_list[ex].str;
}
static enum export export_no(const char *s)
{
int i;
if (!s)
return export_unknown;
for (i = 0; export_list[i].export != export_unknown; i++) {
if (strcmp(export_list[i].str, s) == 0)
return export_list[i].export;
}
return export_unknown;
}
static void *sym_get_data_by_offset(const struct elf_info *info, static void *sym_get_data_by_offset(const struct elf_info *info,
unsigned int secindex, unsigned long offset) unsigned int secindex, unsigned long offset)
{ {
...@@ -357,35 +345,6 @@ static const char *sec_name(const struct elf_info *info, int secindex) ...@@ -357,35 +345,6 @@ static const char *sec_name(const struct elf_info *info, int secindex)
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
{
const char *secname = sec_name(elf, sec);
if (strstarts(secname, "___ksymtab+"))
return export_plain;
else if (strstarts(secname, "___ksymtab_gpl+"))
return export_gpl;
else
return export_unknown;
}
static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
{
if (sec == elf->export_sec)
return export_plain;
else if (sec == elf->export_gpl_sec)
return export_gpl;
else
return export_unknown;
}
static const char *namespace_from_kstrtabns(const struct elf_info *info,
const Elf_Sym *sym)
{
const char *value = sym_get_data(info, sym);
return value[0] ? value : NULL;
}
static void sym_update_namespace(const char *symname, const char *namespace) static void sym_update_namespace(const char *symname, const char *namespace)
{ {
struct symbol *s = find_symbol(symname); struct symbol *s = find_symbol(symname);
...@@ -401,47 +360,33 @@ static void sym_update_namespace(const char *symname, const char *namespace) ...@@ -401,47 +360,33 @@ static void sym_update_namespace(const char *symname, const char *namespace)
} }
free(s->namespace); free(s->namespace);
s->namespace = s->namespace = namespace[0] ? NOFAIL(strdup(namespace)) : NULL;
namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL;
} }
/**
* Add an exported symbol - it may have already been added without a
* CRC, in this case just update the CRC
**/
static struct symbol *sym_add_exported(const char *name, struct module *mod, static struct symbol *sym_add_exported(const char *name, struct module *mod,
enum export export) bool gpl_only)
{ {
struct symbol *s = find_symbol(name); struct symbol *s = find_symbol(name);
if (!s) { if (s && (!external_module || s->module->is_vmlinux || s->module == mod)) {
s = new_symbol(name, mod, export); error("%s: '%s' exported twice. Previous export was in %s%s\n",
} else if (!external_module || s->module->is_vmlinux ||
s->module == mod) {
warn("%s: '%s' exported twice. Previous export was in %s%s\n",
mod->name, name, s->module->name, mod->name, name, s->module->name,
s->module->is_vmlinux ? "" : ".ko"); s->module->is_vmlinux ? "" : ".ko");
return s;
} }
s = alloc_symbol(name);
s->module = mod; s->module = mod;
s->export = export; s->is_gpl_only = gpl_only;
list_add_tail(&s->list, &mod->exported_symbols);
hash_add_symbol(s);
return s; return s;
} }
static void sym_set_crc(const char *name, unsigned int crc) static void sym_set_crc(struct symbol *sym, unsigned int crc)
{ {
struct symbol *s = find_symbol(name); sym->crc = crc;
sym->crc_valid = true;
/*
* Ignore stand-alone __crc_*, which might be auto-generated symbols
* such as __*_veneer in ARM ELF.
*/
if (!s)
return;
s->crc = crc;
s->crc_valid = 1;
} }
static void *grab_file(const char *filename, size_t *size) static void *grab_file(const char *filename, size_t *size)
...@@ -576,10 +521,7 @@ static int parse_elf(struct elf_info *info, const char *filename) ...@@ -576,10 +521,7 @@ static int parse_elf(struct elf_info *info, const char *filename)
fatal("%s has NOBITS .modinfo\n", filename); fatal("%s has NOBITS .modinfo\n", filename);
info->modinfo = (void *)hdr + sechdrs[i].sh_offset; info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
info->modinfo_len = sechdrs[i].sh_size; info->modinfo_len = sechdrs[i].sh_size;
} else if (strcmp(secname, "__ksymtab") == 0) }
info->export_sec = i;
else if (strcmp(secname, "__ksymtab_gpl") == 0)
info->export_gpl_sec = i;
if (sechdrs[i].sh_type == SHT_SYMTAB) { if (sechdrs[i].sh_type == SHT_SYMTAB) {
unsigned int sh_link_idx; unsigned int sh_link_idx;
...@@ -667,44 +609,9 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) ...@@ -667,44 +609,9 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname)
return 0; return 0;
} }
static void handle_modversion(const struct module *mod,
const struct elf_info *info,
const Elf_Sym *sym, const char *symname)
{
unsigned int crc;
if (sym->st_shndx == SHN_UNDEF) {
warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n"
"Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
symname, mod->name, mod->is_vmlinux ? "" : ".ko",
symname);
return;
}
if (sym->st_shndx == SHN_ABS) {
crc = sym->st_value;
} else {
unsigned int *crcp;
/* symbol points to the CRC in the ELF object */
crcp = sym_get_data(info, sym);
crc = TO_NATIVE(*crcp);
}
sym_set_crc(symname, crc);
}
static void handle_symbol(struct module *mod, struct elf_info *info, static void handle_symbol(struct module *mod, struct elf_info *info,
const Elf_Sym *sym, const char *symname) const Elf_Sym *sym, const char *symname)
{ {
enum export export;
const char *name;
if (strstarts(symname, "__ksymtab"))
export = export_from_secname(info, get_secindex(info, sym));
else
export = export_from_sec(info, get_secindex(info, sym));
switch (sym->st_shndx) { switch (sym->st_shndx) {
case SHN_COMMON: case SHN_COMMON:
if (strstarts(symname, "__gnu_lto_")) { if (strstarts(symname, "__gnu_lto_")) {
...@@ -732,20 +639,26 @@ static void handle_symbol(struct module *mod, struct elf_info *info, ...@@ -732,20 +639,26 @@ static void handle_symbol(struct module *mod, struct elf_info *info,
} }
} }
mod->unres = alloc_symbol(symname, sym_add_unresolved(symname, mod,
ELF_ST_BIND(sym->st_info) == STB_WEAK, ELF_ST_BIND(sym->st_info) == STB_WEAK);
mod->unres);
break; break;
default: default:
/* All exported symbols */ /* All exported symbols */
if (strstarts(symname, "__ksymtab_")) { if (strstarts(symname, "__ksymtab_")) {
const char *name, *secname;
name = symname + strlen("__ksymtab_"); name = symname + strlen("__ksymtab_");
sym_add_exported(name, mod, export); secname = sec_name(info, get_secindex(info, sym));
if (strstarts(secname, "___ksymtab_gpl+"))
sym_add_exported(name, mod, true);
else if (strstarts(secname, "___ksymtab+"))
sym_add_exported(name, mod, false);
} }
if (strcmp(symname, "init_module") == 0) if (strcmp(symname, "init_module") == 0)
mod->has_init = 1; mod->has_init = true;
if (strcmp(symname, "cleanup_module") == 0) if (strcmp(symname, "cleanup_module") == 0)
mod->has_cleanup = 1; mod->has_cleanup = true;
break; break;
} }
} }
...@@ -2003,6 +1916,104 @@ static char *remove_dot(char *s) ...@@ -2003,6 +1916,104 @@ static char *remove_dot(char *s)
return s; return s;
} }
/*
* The CRCs are recorded in .*.cmd files in the form of:
* #SYMVER <name> <crc>
*/
static void extract_crcs_for_object(const char *object, struct module *mod)
{
char cmd_file[PATH_MAX];
char *buf, *p;
const char *base;
int dirlen, ret;
base = strrchr(object, '/');
if (base) {
base++;
dirlen = base - object;
} else {
dirlen = 0;
base = object;
}
ret = snprintf(cmd_file, sizeof(cmd_file), "%.*s.%s.cmd",
dirlen, object, base);
if (ret >= sizeof(cmd_file)) {
error("%s: too long path was truncated\n", cmd_file);
return;
}
buf = read_text_file(cmd_file);
p = buf;
while ((p = strstr(p, "\n#SYMVER "))) {
char *name;
size_t namelen;
unsigned int crc;
struct symbol *sym;
name = p + strlen("\n#SYMVER ");
p = strchr(name, ' ');
if (!p)
break;
namelen = p - name;
p++;
if (!isdigit(*p))
continue; /* skip this line */
crc = strtol(p, &p, 0);
if (*p != '\n')
continue; /* skip this line */
name[namelen] = '\0';
/*
* sym_find_with_module() may return NULL here.
* It typically occurs when CONFIG_TRIM_UNUSED_KSYMS=y.
* Since commit e1327a127703, genksyms calculates CRCs of all
* symbols, including trimmed ones. Ignore orphan CRCs.
*/
sym = sym_find_with_module(name, mod);
if (sym)
sym_set_crc(sym, crc);
}
free(buf);
}
/*
* The symbol versions (CRC) are recorded in the .*.cmd files.
* Parse them to retrieve CRCs for the current module.
*/
static void mod_set_crcs(struct module *mod)
{
char objlist[PATH_MAX];
char *buf, *p, *obj;
int ret;
if (mod->is_vmlinux) {
strcpy(objlist, ".vmlinux.objs");
} else {
/* objects for a module are listed in the *.mod file. */
ret = snprintf(objlist, sizeof(objlist), "%s.mod", mod->name);
if (ret >= sizeof(objlist)) {
error("%s: too long path was truncated\n", objlist);
return;
}
}
buf = read_text_file(objlist);
p = buf;
while ((obj = strsep(&p, "\n")) && obj[0])
extract_crcs_for_object(obj, mod);
free(buf);
}
static void read_symbols(const char *modname) static void read_symbols(const char *modname)
{ {
const char *symname; const char *symname;
...@@ -2034,10 +2045,8 @@ static void read_symbols(const char *modname) ...@@ -2034,10 +2045,8 @@ static void read_symbols(const char *modname)
if (!license) if (!license)
error("missing MODULE_LICENSE() in %s\n", modname); error("missing MODULE_LICENSE() in %s\n", modname);
while (license) { while (license) {
if (license_is_gpl_compatible(license)) if (!license_is_gpl_compatible(license)) {
mod->gpl_compatible = 1; mod->is_gpl_compatible = false;
else {
mod->gpl_compatible = 0;
break; break;
} }
license = get_next_modinfo(&info, "license", license); license = get_next_modinfo(&info, "license", license);
...@@ -2064,12 +2073,7 @@ static void read_symbols(const char *modname) ...@@ -2064,12 +2073,7 @@ static void read_symbols(const char *modname)
/* Apply symbol namespaces from __kstrtabns_<symbol> entries. */ /* Apply symbol namespaces from __kstrtabns_<symbol> entries. */
if (strstarts(symname, "__kstrtabns_")) if (strstarts(symname, "__kstrtabns_"))
sym_update_namespace(symname + strlen("__kstrtabns_"), sym_update_namespace(symname + strlen("__kstrtabns_"),
namespace_from_kstrtabns(&info, sym_get_data(&info, sym));
sym));
if (strstarts(symname, "__crc_"))
handle_modversion(mod, &info, sym,
symname + strlen("__crc_"));
} }
// check for static EXPORT_SYMBOL_* functions && global vars // check for static EXPORT_SYMBOL_* functions && global vars
...@@ -2082,7 +2086,7 @@ static void read_symbols(const char *modname) ...@@ -2082,7 +2086,7 @@ static void read_symbols(const char *modname)
sym->st_name)); sym->st_name));
if (s) if (s)
s->is_static = 0; s->is_static = false;
} }
} }
...@@ -2097,12 +2101,17 @@ static void read_symbols(const char *modname) ...@@ -2097,12 +2101,17 @@ static void read_symbols(const char *modname)
parse_elf_finish(&info); parse_elf_finish(&info);
/* Our trick to get versioning for module struct etc. - it's if (modversions) {
/*
* Our trick to get versioning for module struct etc. - it's
* never passed as an argument to an exported function, so * never passed as an argument to an exported function, so
* the automatic versioning doesn't pick it up, but it's really * the automatic versioning doesn't pick it up, but it's really
* important anyhow */ * important anyhow.
if (modversions) */
mod->unres = alloc_symbol("module_layout", 0, mod->unres); sym_add_unresolved("module_layout", mod, false);
mod_set_crcs(mod);
}
} }
static void read_symbols_from_files(const char *filename) static void read_symbols_from_files(const char *filename)
...@@ -2155,34 +2164,30 @@ void buf_write(struct buffer *buf, const char *s, int len) ...@@ -2155,34 +2164,30 @@ void buf_write(struct buffer *buf, const char *s, int len)
buf->pos += len; buf->pos += len;
} }
static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
{
switch (exp) {
case export_gpl:
error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
m, s);
break;
case export_plain:
case export_unknown:
/* ignore */
break;
}
}
static void check_exports(struct module *mod) static void check_exports(struct module *mod)
{ {
struct symbol *s, *exp; struct symbol *s, *exp;
for (s = mod->unres; s; s = s->next) { list_for_each_entry(s, &mod->unresolved_symbols, list) {
const char *basename; const char *basename;
exp = find_symbol(s->name); exp = find_symbol(s->name);
if (!exp || exp->module == mod) { if (!exp) {
if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS) if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR, modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
"\"%s\" [%s.ko] undefined!\n", "\"%s\" [%s.ko] undefined!\n",
s->name, mod->name); s->name, mod->name);
continue; continue;
} }
if (exp->module == mod) {
error("\"%s\" [%s.ko] was exported without definition\n",
s->name, mod->name);
continue;
}
s->module = exp->module;
s->crc_valid = exp->crc_valid;
s->crc = exp->crc;
basename = strrchr(mod->name, '/'); basename = strrchr(mod->name, '/');
if (basename) if (basename)
basename++; basename++;
...@@ -2190,15 +2195,16 @@ static void check_exports(struct module *mod) ...@@ -2190,15 +2195,16 @@ static void check_exports(struct module *mod)
basename = mod->name; basename = mod->name;
if (exp->namespace && if (exp->namespace &&
!module_imports_namespace(mod, exp->namespace)) { !contains_namespace(&mod->imported_namespaces, exp->namespace)) {
modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR, modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR,
"module %s uses symbol %s from namespace %s, but does not import it.\n", "module %s uses symbol %s from namespace %s, but does not import it.\n",
basename, exp->name, exp->namespace); basename, exp->name, exp->namespace);
add_namespace(&mod->missing_namespaces, exp->namespace); add_namespace(&mod->missing_namespaces, exp->namespace);
} }
if (!mod->gpl_compatible) if (!mod->is_gpl_compatible && exp->is_gpl_only)
check_for_gpl_usage(exp->export, basename, exp->name); error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
basename, exp->name);
} }
} }
...@@ -2228,6 +2234,7 @@ static void add_header(struct buffer *b, struct module *mod) ...@@ -2228,6 +2234,7 @@ static void add_header(struct buffer *b, struct module *mod)
buf_printf(b, "#define INCLUDE_VERMAGIC\n"); buf_printf(b, "#define INCLUDE_VERMAGIC\n");
buf_printf(b, "#include <linux/build-salt.h>\n"); buf_printf(b, "#include <linux/build-salt.h>\n");
buf_printf(b, "#include <linux/elfnote-lto.h>\n"); buf_printf(b, "#include <linux/elfnote-lto.h>\n");
buf_printf(b, "#include <linux/export-internal.h>\n");
buf_printf(b, "#include <linux/vermagic.h>\n"); buf_printf(b, "#include <linux/vermagic.h>\n");
buf_printf(b, "#include <linux/compiler.h>\n"); buf_printf(b, "#include <linux/compiler.h>\n");
buf_printf(b, "\n"); buf_printf(b, "\n");
...@@ -2248,26 +2255,41 @@ static void add_header(struct buffer *b, struct module *mod) ...@@ -2248,26 +2255,41 @@ static void add_header(struct buffer *b, struct module *mod)
"#endif\n"); "#endif\n");
buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n"); buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
buf_printf(b, "};\n"); buf_printf(b, "};\n");
}
static void add_intree_flag(struct buffer *b, int is_intree) if (!external_module)
{
if (is_intree)
buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
}
/* Cannot check for assembler */ buf_printf(b,
static void add_retpoline(struct buffer *b) "\n"
{ "#ifdef CONFIG_RETPOLINE\n"
buf_printf(b, "\n#ifdef CONFIG_RETPOLINE\n"); "MODULE_INFO(retpoline, \"Y\");\n"
buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n"); "#endif\n");
buf_printf(b, "#endif\n");
if (strstarts(mod->name, "drivers/staging"))
buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
} }
static void add_staging_flag(struct buffer *b, const char *name) static void add_exported_symbols(struct buffer *buf, struct module *mod)
{ {
if (strstarts(name, "drivers/staging")) struct symbol *sym;
buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
if (!modversions)
return;
/* record CRCs for exported symbols */
buf_printf(buf, "\n");
list_for_each_entry(sym, &mod->exported_symbols, list) {
if (!sym->crc_valid) {
warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n"
"Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
sym->name, mod->name, mod->is_vmlinux ? "" : ".ko",
sym->name);
continue;
}
buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n",
sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : "");
}
} }
/** /**
...@@ -2275,16 +2297,7 @@ static void add_staging_flag(struct buffer *b, const char *name) ...@@ -2275,16 +2297,7 @@ static void add_staging_flag(struct buffer *b, const char *name)
**/ **/
static void add_versions(struct buffer *b, struct module *mod) static void add_versions(struct buffer *b, struct module *mod)
{ {
struct symbol *s, *exp; struct symbol *s;
for (s = mod->unres; s; s = s->next) {
exp = find_symbol(s->name);
if (!exp || exp->module == mod)
continue;
s->module = exp->module;
s->crc_valid = exp->crc_valid;
s->crc = exp->crc;
}
if (!modversions) if (!modversions)
return; return;
...@@ -2293,7 +2306,7 @@ static void add_versions(struct buffer *b, struct module *mod) ...@@ -2293,7 +2306,7 @@ static void add_versions(struct buffer *b, struct module *mod)
buf_printf(b, "static const struct modversion_info ____versions[]\n"); buf_printf(b, "static const struct modversion_info ____versions[]\n");
buf_printf(b, "__used __section(\"__versions\") = {\n"); buf_printf(b, "__used __section(\"__versions\") = {\n");
for (s = mod->unres; s; s = s->next) { list_for_each_entry(s, &mod->unresolved_symbols, list) {
if (!s->module) if (!s->module)
continue; continue;
if (!s->crc_valid) { if (!s->crc_valid) {
...@@ -2319,13 +2332,14 @@ static void add_depends(struct buffer *b, struct module *mod) ...@@ -2319,13 +2332,14 @@ static void add_depends(struct buffer *b, struct module *mod)
int first = 1; int first = 1;
/* Clear ->seen flag of modules that own symbols needed by this. */ /* Clear ->seen flag of modules that own symbols needed by this. */
for (s = mod->unres; s; s = s->next) list_for_each_entry(s, &mod->unresolved_symbols, list) {
if (s->module) if (s->module)
s->module->seen = s->module->is_vmlinux; s->module->seen = s->module->is_vmlinux;
}
buf_printf(b, "\n"); buf_printf(b, "\n");
buf_printf(b, "MODULE_INFO(depends, \""); buf_printf(b, "MODULE_INFO(depends, \"");
for (s = mod->unres; s; s = s->next) { list_for_each_entry(s, &mod->unresolved_symbols, list) {
const char *p; const char *p;
if (!s->module) if (!s->module)
continue; continue;
...@@ -2333,7 +2347,7 @@ static void add_depends(struct buffer *b, struct module *mod) ...@@ -2333,7 +2347,7 @@ static void add_depends(struct buffer *b, struct module *mod)
if (s->module->seen) if (s->module->seen)
continue; continue;
s->module->seen = 1; s->module->seen = true;
p = strrchr(s->module->name, '/'); p = strrchr(s->module->name, '/');
if (p) if (p)
p++; p++;
...@@ -2358,6 +2372,9 @@ static void write_buf(struct buffer *b, const char *fname) ...@@ -2358,6 +2372,9 @@ static void write_buf(struct buffer *b, const char *fname)
{ {
FILE *file; FILE *file;
if (error_occurred)
return;
file = fopen(fname, "w"); file = fopen(fname, "w");
if (!file) { if (!file) {
perror(fname); perror(fname);
...@@ -2408,6 +2425,47 @@ static void write_if_changed(struct buffer *b, const char *fname) ...@@ -2408,6 +2425,47 @@ static void write_if_changed(struct buffer *b, const char *fname)
write_buf(b, fname); write_buf(b, fname);
} }
static void write_vmlinux_export_c_file(struct module *mod)
{
struct buffer buf = { };
buf_printf(&buf,
"#include <linux/export-internal.h>\n");
add_exported_symbols(&buf, mod);
write_if_changed(&buf, ".vmlinux.export.c");
free(buf.p);
}
/* do sanity checks, and generate *.mod.c file */
static void write_mod_c_file(struct module *mod)
{
struct buffer buf = { };
char fname[PATH_MAX];
int ret;
check_modname_len(mod);
check_exports(mod);
add_header(&buf, mod);
add_exported_symbols(&buf, mod);
add_versions(&buf, mod);
add_depends(&buf, mod);
add_moddevtable(&buf, mod);
add_srcversion(&buf, mod);
ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);
if (ret >= sizeof(fname)) {
error("%s: too long path was truncated\n", fname);
goto free;
}
write_if_changed(&buf, fname);
free:
free(buf.p);
}
/* parse Module.symvers file. line format: /* parse Module.symvers file. line format:
* 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace * 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace
**/ **/
...@@ -2427,6 +2485,7 @@ static void read_dump(const char *fname) ...@@ -2427,6 +2485,7 @@ static void read_dump(const char *fname)
unsigned int crc; unsigned int crc;
struct module *mod; struct module *mod;
struct symbol *s; struct symbol *s;
bool gpl_only;
if (!(symname = strchr(line, '\t'))) if (!(symname = strchr(line, '\t')))
goto fail; goto fail;
...@@ -2444,14 +2503,24 @@ static void read_dump(const char *fname) ...@@ -2444,14 +2503,24 @@ static void read_dump(const char *fname)
crc = strtoul(line, &d, 16); crc = strtoul(line, &d, 16);
if (*symname == '\0' || *modname == '\0' || *d != '\0') if (*symname == '\0' || *modname == '\0' || *d != '\0')
goto fail; goto fail;
if (!strcmp(export, "EXPORT_SYMBOL_GPL")) {
gpl_only = true;
} else if (!strcmp(export, "EXPORT_SYMBOL")) {
gpl_only = false;
} else {
error("%s: unknown license %s. skip", symname, export);
continue;
}
mod = find_module(modname); mod = find_module(modname);
if (!mod) { if (!mod) {
mod = new_module(modname); mod = new_module(modname);
mod->from_dump = 1; mod->from_dump = true;
} }
s = sym_add_exported(symname, mod, export_no(export)); s = sym_add_exported(symname, mod, gpl_only);
s->is_static = 0; s->is_static = false;
sym_set_crc(symname, crc); sym_set_crc(s, crc);
sym_update_namespace(symname, namespace); sym_update_namespace(symname, namespace);
} }
free(buf); free(buf);
...@@ -2464,22 +2533,17 @@ static void read_dump(const char *fname) ...@@ -2464,22 +2533,17 @@ static void read_dump(const char *fname)
static void write_dump(const char *fname) static void write_dump(const char *fname)
{ {
struct buffer buf = { }; struct buffer buf = { };
struct symbol *symbol; struct module *mod;
const char *namespace; struct symbol *sym;
int n;
for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { list_for_each_entry(mod, &modules, list) {
symbol = symbolhash[n]; if (mod->from_dump)
while (symbol) { continue;
if (!symbol->module->from_dump) { list_for_each_entry(sym, &mod->exported_symbols, list) {
namespace = symbol->namespace; buf_printf(&buf, "0x%08x\t%s\t%s\tEXPORT_SYMBOL%s\t%s\n",
buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n", sym->crc, sym->name, mod->name,
symbol->crc, symbol->name, sym->is_gpl_only ? "_GPL" : "",
symbol->module->name, sym->namespace ?: "");
export_str(symbol->export),
namespace ? namespace : "");
}
symbol = symbol->next;
} }
} }
write_buf(&buf, fname); write_buf(&buf, fname);
...@@ -2492,14 +2556,14 @@ static void write_namespace_deps_files(const char *fname) ...@@ -2492,14 +2556,14 @@ static void write_namespace_deps_files(const char *fname)
struct namespace_list *ns; struct namespace_list *ns;
struct buffer ns_deps_buf = {}; struct buffer ns_deps_buf = {};
for (mod = modules; mod; mod = mod->next) { list_for_each_entry(mod, &modules, list) {
if (mod->from_dump || !mod->missing_namespaces) if (mod->from_dump || list_empty(&mod->missing_namespaces))
continue; continue;
buf_printf(&ns_deps_buf, "%s.ko:", mod->name); buf_printf(&ns_deps_buf, "%s.ko:", mod->name);
for (ns = mod->missing_namespaces; ns; ns = ns->next) list_for_each_entry(ns, &mod->missing_namespaces, list)
buf_printf(&ns_deps_buf, " %s", ns->namespace); buf_printf(&ns_deps_buf, " %s", ns->namespace);
buf_printf(&ns_deps_buf, "\n"); buf_printf(&ns_deps_buf, "\n");
...@@ -2510,55 +2574,53 @@ static void write_namespace_deps_files(const char *fname) ...@@ -2510,55 +2574,53 @@ static void write_namespace_deps_files(const char *fname)
} }
struct dump_list { struct dump_list {
struct dump_list *next; struct list_head list;
const char *file; const char *file;
}; };
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct module *mod; struct module *mod;
struct buffer buf = { };
char *missing_namespace_deps = NULL; char *missing_namespace_deps = NULL;
char *dump_write = NULL, *files_source = NULL; char *dump_write = NULL, *files_source = NULL;
int opt; int opt;
int n; int n;
struct dump_list *dump_read_start = NULL; LIST_HEAD(dump_lists);
struct dump_list **dump_read_iter = &dump_read_start; struct dump_list *dl, *dl2;
while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) { while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) {
switch (opt) { switch (opt) {
case 'e': case 'e':
external_module = 1; external_module = true;
break; break;
case 'i': case 'i':
*dump_read_iter = dl = NOFAIL(malloc(sizeof(*dl)));
NOFAIL(calloc(1, sizeof(**dump_read_iter))); dl->file = optarg;
(*dump_read_iter)->file = optarg; list_add_tail(&dl->list, &dump_lists);
dump_read_iter = &(*dump_read_iter)->next;
break; break;
case 'm': case 'm':
modversions = 1; modversions = true;
break; break;
case 'n': case 'n':
ignore_missing_files = 1; ignore_missing_files = true;
break; break;
case 'o': case 'o':
dump_write = optarg; dump_write = optarg;
break; break;
case 'a': case 'a':
all_versions = 1; all_versions = true;
break; break;
case 'T': case 'T':
files_source = optarg; files_source = optarg;
break; break;
case 'w': case 'w':
warn_unresolved = 1; warn_unresolved = true;
break; break;
case 'E': case 'E':
sec_mismatch_warn_only = false; sec_mismatch_warn_only = false;
break; break;
case 'N': case 'N':
allow_missing_ns_imports = 1; allow_missing_ns_imports = true;
break; break;
case 'd': case 'd':
missing_namespace_deps = optarg; missing_namespace_deps = optarg;
...@@ -2568,13 +2630,10 @@ int main(int argc, char **argv) ...@@ -2568,13 +2630,10 @@ int main(int argc, char **argv)
} }
} }
while (dump_read_start) { list_for_each_entry_safe(dl, dl2, &dump_lists, list) {
struct dump_list *tmp; read_dump(dl->file);
list_del(&dl->list);
read_dump(dump_read_start->file); free(dl);
tmp = dump_read_start->next;
free(dump_read_start);
dump_read_start = tmp;
} }
while (optind < argc) while (optind < argc)
...@@ -2583,28 +2642,14 @@ int main(int argc, char **argv) ...@@ -2583,28 +2642,14 @@ int main(int argc, char **argv)
if (files_source) if (files_source)
read_symbols_from_files(files_source); read_symbols_from_files(files_source);
for (mod = modules; mod; mod = mod->next) { list_for_each_entry(mod, &modules, list) {
char fname[PATH_MAX]; if (mod->from_dump)
if (mod->is_vmlinux || mod->from_dump)
continue; continue;
buf.pos = 0; if (mod->is_vmlinux)
write_vmlinux_export_c_file(mod);
check_modname_len(mod); else
check_exports(mod); write_mod_c_file(mod);
add_header(&buf, mod);
add_intree_flag(&buf, !external_module);
add_retpoline(&buf);
add_staging_flag(&buf, mod->name);
add_versions(&buf, mod);
add_depends(&buf, mod);
add_moddevtable(&buf, mod);
add_srcversion(&buf, mod);
sprintf(fname, "%s.mod.c", mod->name);
write_if_changed(&buf, fname);
} }
if (missing_namespace_deps) if (missing_namespace_deps)
...@@ -2620,9 +2665,8 @@ int main(int argc, char **argv) ...@@ -2620,9 +2665,8 @@ int main(int argc, char **argv)
for (s = symbolhash[n]; s; s = s->next) { for (s = symbolhash[n]; s; s = s->next) {
if (s->is_static) if (s->is_static)
error("\"%s\" [%s] is a static %s\n", error("\"%s\" [%s] is a static EXPORT_SYMBOL\n",
s->name, s->module->name, s->name, s->module->name);
export_str(s->export));
} }
} }
...@@ -2630,7 +2674,5 @@ int main(int argc, char **argv) ...@@ -2630,7 +2674,5 @@ int main(int argc, char **argv)
warn("suppressed %u unresolved symbol warnings because there were too many)\n", warn("suppressed %u unresolved symbol warnings because there were too many)\n",
nr_unresolved - MAX_UNRESOLVED_REPORTS); nr_unresolved - MAX_UNRESOLVED_REPORTS);
free(buf.p);
return error_occurred ? 1 : 0; return error_occurred ? 1 : 0;
} }
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
...@@ -10,6 +11,7 @@ ...@@ -10,6 +11,7 @@
#include <unistd.h> #include <unistd.h>
#include <elf.h> #include <elf.h>
#include "list.h"
#include "elfconfig.h" #include "elfconfig.h"
/* On BSD-alike OSes elf.h defines these according to host's word size */ /* On BSD-alike OSes elf.h defines these according to host's word size */
...@@ -109,26 +111,22 @@ buf_printf(struct buffer *buf, const char *fmt, ...); ...@@ -109,26 +111,22 @@ buf_printf(struct buffer *buf, const char *fmt, ...);
void void
buf_write(struct buffer *buf, const char *s, int len); buf_write(struct buffer *buf, const char *s, int len);
struct namespace_list {
struct namespace_list *next;
char namespace[];
};
struct module { struct module {
struct module *next; struct list_head list;
int gpl_compatible; struct list_head exported_symbols;
struct symbol *unres; struct list_head unresolved_symbols;
int from_dump; /* 1 if module was loaded from *.symvers */ bool is_gpl_compatible;
int is_vmlinux; bool from_dump; /* true if module was loaded from *.symvers */
int seen; bool is_vmlinux;
int has_init; bool seen;
int has_cleanup; bool has_init;
bool has_cleanup;
struct buffer dev_table_buf; struct buffer dev_table_buf;
char srcversion[25]; char srcversion[25];
// Missing namespace dependencies // Missing namespace dependencies
struct namespace_list *missing_namespaces; struct list_head missing_namespaces;
// Actual imported namespaces // Actual imported namespaces
struct namespace_list *imported_namespaces; struct list_head imported_namespaces;
char name[]; char name[];
}; };
...@@ -138,8 +136,6 @@ struct elf_info { ...@@ -138,8 +136,6 @@ struct elf_info {
Elf_Shdr *sechdrs; Elf_Shdr *sechdrs;
Elf_Sym *symtab_start; Elf_Sym *symtab_start;
Elf_Sym *symtab_stop; Elf_Sym *symtab_stop;
Elf_Section export_sec;
Elf_Section export_gpl_sec;
char *strtab; char *strtab;
char *modinfo; char *modinfo;
unsigned int modinfo_len; unsigned int modinfo_len;
...@@ -178,7 +174,6 @@ static inline unsigned int get_secindex(const struct elf_info *info, ...@@ -178,7 +174,6 @@ static inline unsigned int get_secindex(const struct elf_info *info,
} }
/* file2alias.c */ /* file2alias.c */
extern unsigned int cross_build;
void handle_moddevtable(struct module *mod, struct elf_info *info, void handle_moddevtable(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname); Elf_Sym *sym, const char *symname);
void add_moddevtable(struct buffer *buf, struct module *mod); void add_moddevtable(struct buffer *buf, struct module *mod);
......
...@@ -290,13 +290,11 @@ static int parse_file(const char *fname, struct md4_ctx *md) ...@@ -290,13 +290,11 @@ static int parse_file(const char *fname, struct md4_ctx *md)
return 1; return 1;
} }
/* Check whether the file is a static library or not */ /* Check whether the file is a static library or not */
static int is_static_library(const char *objfile) static bool is_static_library(const char *objfile)
{ {
int len = strlen(objfile); int len = strlen(objfile);
if (objfile[len - 2] == '.' && objfile[len - 1] == 'a')
return 1; return objfile[len - 2] == '.' && objfile[len - 1] == 'a';
else
return 0;
} }
/* We have dir/file.o. Open dir/.file.o.cmd, look for source_ and deps_ line /* We have dir/file.o. Open dir/.file.o.cmd, look for source_ and deps_ line
...@@ -387,7 +385,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) ...@@ -387,7 +385,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
/* Calc and record src checksum. */ /* Calc and record src checksum. */
void get_src_version(const char *modname, char sum[], unsigned sumlen) void get_src_version(const char *modname, char sum[], unsigned sumlen)
{ {
char *buf, *pos, *firstline; char *buf;
struct md4_ctx md; struct md4_ctx md;
char *fname; char *fname;
char filelist[PATH_MAX + 1]; char filelist[PATH_MAX + 1];
...@@ -397,15 +395,8 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) ...@@ -397,15 +395,8 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen)
buf = read_text_file(filelist); buf = read_text_file(filelist);
pos = buf;
firstline = get_line(&pos);
if (!firstline) {
warn("bad ending versions file for %s\n", modname);
goto free;
}
md4_init(&md); md4_init(&md);
while ((fname = strsep(&firstline, " "))) { while ((fname = strsep(&buf, "\n"))) {
if (!*fname) if (!*fname)
continue; continue;
if (!(is_static_library(fname)) && if (!(is_static_library(fname)) &&
......
...@@ -16,6 +16,10 @@ do ...@@ -16,6 +16,10 @@ do
rm -f "/boot/initramfs-$f.img" "/boot/System.map-$f" rm -f "/boot/initramfs-$f.img" "/boot/System.map-$f"
rm -f "/boot/vmlinuz-$f" "/boot/config-$f" rm -f "/boot/vmlinuz-$f" "/boot/config-$f"
rm -rf "/lib/modules/$f" rm -rf "/lib/modules/$f"
if [ -x "$(command -v new-kernel-pkg)" ]; then
new-kernel-pkg --remove $f new-kernel-pkg --remove $f
elif [ -x "$(command -v kernel-install)" ]; then
kernel-install remove $f
fi
fi fi
done done
...@@ -19,8 +19,8 @@ LIBSUBCMD = $(LIBSUBCMD_OUTPUT)libsubcmd.a ...@@ -19,8 +19,8 @@ LIBSUBCMD = $(LIBSUBCMD_OUTPUT)libsubcmd.a
OBJTOOL := $(OUTPUT)objtool OBJTOOL := $(OUTPUT)objtool
OBJTOOL_IN := $(OBJTOOL)-in.o OBJTOOL_IN := $(OBJTOOL)-in.o
LIBELF_FLAGS := $(shell pkg-config libelf --cflags 2>/dev/null) LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null)
LIBELF_LIBS := $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf) LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf)
all: $(OBJTOOL) all: $(OBJTOOL)
......
...@@ -82,7 +82,7 @@ always-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h' 2>/ ...@@ -82,7 +82,7 @@ always-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h' 2>/
# Include the header twice to detect missing include guard. # Include the header twice to detect missing include guard.
quiet_cmd_hdrtest = HDRTEST $< quiet_cmd_hdrtest = HDRTEST $<
cmd_hdrtest = \ cmd_hdrtest = \
$(CC) $(c_flags) -S -o /dev/null -x c /dev/null \ $(CC) $(c_flags) -fsyntax-only -x c /dev/null \
$(if $(filter-out $(no-header-test), $*.h), -include $< -include $<); \ $(if $(filter-out $(no-header-test), $*.h), -include $< -include $<); \
$(PERL) $(srctree)/$(src)/headers_check.pl $(obj) $(SRCARCH) $<; \ $(PERL) $(srctree)/$(src)/headers_check.pl $(obj) $(SRCARCH) $<; \
touch $@ touch $@
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment