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

Pull Kbuild updates from Masahiro Yamada:

- Remove tristate choice support from Kconfig

- Stop using the PROVIDE() directive in the linker script

- Reduce the number of links for the combination of CONFIG_KALLSYMS and
CONFIG_DEBUG_INFO_BTF

- Enable the warning for symbol reference to .exit.* sections by
default

- Fix warnings in RPM package builds

- Improve scripts/make_fit.py to generate a FIT image with separate
base DTB and overlays

- Improve choice value calculation in Kconfig

- Fix conditional prompt behavior in choice in Kconfig

- Remove support for the uncommon EMAIL environment variable in Debian
package builds

- Remove support for the uncommon "name <email>" form for the DEBEMAIL
environment variable

- Raise the minimum supported GNU Make version to 4.0

- Remove stale code for the absolute kallsyms

- Move header files commonly used for host programs to scripts/include/

- Introduce the pacman-pkg target to generate a pacman package used in
Arch Linux

- Clean up Kconfig

* tag 'kbuild-v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (65 commits)
kbuild: doc: gcc to CC change
kallsyms: change sym_entry::percpu_absolute to bool type
kallsyms: unify seq and start_pos fields of struct sym_entry
kallsyms: add more original symbol type/name in comment lines
kallsyms: use \t instead of a tab in printf()
kallsyms: avoid repeated calculation of array size for markers
kbuild: add script and target to generate pacman package
modpost: use generic macros for hash table implementation
kbuild: move some helper headers from scripts/kconfig/ to scripts/include/
Makefile: add comment to discourage tools/* addition for kernel builds
kbuild: clean up scripts/remove-stale-files
kconfig: recursive checks drop file/lineno
kbuild: rpm-pkg: introduce a simple changelog section for kernel.spec
kallsyms: get rid of code for absolute kallsyms
kbuild: Create INSTALL_PATH directory if it does not exist
kbuild: Abort make on install failures
kconfig: remove 'e1' and 'e2' macros from expression deduplication
kconfig: remove SYMBOL_CHOICEVAL flag
kconfig: add const qualifiers to several function arguments
kconfig: call expr_eliminate_yn() at least once in expr_eliminate_dups()
...

+1017 -1468
+6
.gitignore
··· 93 /tar-install/ 94 95 # 96 # We don't want to ignore the following even if they are dot-files 97 # 98 !.clang-format
··· 93 /tar-install/ 94 95 # 96 + # pacman files (make pacman-pkg) 97 + # 98 + /PKGBUILD 99 + /pacman/ 100 + 101 + # 102 # We don't want to ignore the following even if they are dot-files 103 # 104 !.clang-format
+2 -9
Documentation/kbuild/kconfig-language.rst
··· 409 "endchoice" 410 411 This defines a choice group and accepts any of the above attributes as 412 - options. A choice can only be of type bool or tristate. If no type is 413 - specified for a choice, its type will be determined by the type of 414 - the first choice element in the group or remain unknown if none of the 415 - choice elements have a type specified, as well. 416 417 - While a boolean choice only allows a single config entry to be 418 - selected, a tristate choice also allows any number of config entries 419 - to be set to 'm'. This can be used if multiple drivers for a single 420 - hardware exists and only a single driver can be compiled/loaded into 421 - the kernel, but all drivers can be compiled as modules. 422 423 comment:: 424
··· 409 "endchoice" 410 411 This defines a choice group and accepts any of the above attributes as 412 + options. 413 414 + A choice only allows a single config entry to be selected. 415 416 comment:: 417
+3 -3
Documentation/kbuild/makefiles.rst
··· 578 Note: cc-option uses KBUILD_CFLAGS for $(CC) options 579 580 cc-option-yn 581 - cc-option-yn is used to check if gcc supports a given option 582 and return "y" if supported, otherwise "n". 583 584 Example:: ··· 596 Note: cc-option-yn uses KBUILD_CFLAGS for $(CC) options 597 598 cc-disable-warning 599 - cc-disable-warning checks if gcc supports a given warning and returns 600 the commandline switch to disable it. This special function is needed, 601 because gcc 4.4 and later accept any unknown -Wno-* option and only 602 warn about it if there is another warning in the source file. ··· 606 KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) 607 608 In the above example, -Wno-unused-but-set-variable will be added to 609 - KBUILD_CFLAGS only if gcc really accepts it. 610 611 gcc-min-version 612 gcc-min-version tests if the value of $(CONFIG_GCC_VERSION) is greater than
··· 578 Note: cc-option uses KBUILD_CFLAGS for $(CC) options 579 580 cc-option-yn 581 + cc-option-yn is used to check if $(CC) supports a given option 582 and return "y" if supported, otherwise "n". 583 584 Example:: ··· 596 Note: cc-option-yn uses KBUILD_CFLAGS for $(CC) options 597 598 cc-disable-warning 599 + cc-disable-warning checks if $(CC) supports a given warning and returns 600 the commandline switch to disable it. This special function is needed, 601 because gcc 4.4 and later accept any unknown -Wno-* option and only 602 warn about it if there is another warning in the source file. ··· 606 KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) 607 608 In the above example, -Wno-unused-but-set-variable will be added to 609 + KBUILD_CFLAGS only if $(CC) really accepts it. 610 611 gcc-min-version 612 gcc-min-version tests if the value of $(CONFIG_GCC_VERSION) is greater than
+2 -2
Documentation/process/changes.rst
··· 33 Clang/LLVM (optional) 13.0.1 clang --version 34 Rust (optional) 1.78.0 rustc --version 35 bindgen (optional) 0.65.1 bindgen --version 36 - GNU make 3.82 make --version 37 bash 4.2 bash --version 38 binutils 2.25 ld -v 39 flex 2.5.35 flex --version ··· 112 Make 113 ---- 114 115 - You will need GNU make 3.82 or later to build the kernel. 116 117 Bash 118 ----
··· 33 Clang/LLVM (optional) 13.0.1 clang --version 34 Rust (optional) 1.78.0 rustc --version 35 bindgen (optional) 0.65.1 bindgen --version 36 + GNU make 4.0 make --version 37 bash 4.2 bash --version 38 binutils 2.25 ld -v 39 flex 2.5.35 flex --version ··· 112 Make 113 ---- 114 115 + You will need GNU make 4.0 or later to build the kernel. 116 117 Bash 118 ----
+8
MAINTAINERS
··· 12117 F: scripts/basic/ 12118 F: scripts/clang-tools/ 12119 F: scripts/dummy-tools/ 12120 F: scripts/mk* 12121 F: scripts/mod/ 12122 F: scripts/package/ ··· 12172 F: include/uapi/linux/nfsd/ 12173 F: include/uapi/linux/sunrpc/ 12174 F: net/sunrpc/ 12175 12176 KERNEL REGRESSIONS 12177 M: Thorsten Leemhuis <linux@leemhuis.info>
··· 12117 F: scripts/basic/ 12118 F: scripts/clang-tools/ 12119 F: scripts/dummy-tools/ 12120 + F: scripts/include/ 12121 F: scripts/mk* 12122 F: scripts/mod/ 12123 F: scripts/package/ ··· 12171 F: include/uapi/linux/nfsd/ 12172 F: include/uapi/linux/sunrpc/ 12173 F: net/sunrpc/ 12174 + 12175 + KERNEL PACMAN PACKAGING (in addition to generic KERNEL BUILD) 12176 + M: Thomas Weißschuh <linux@weissschuh.net> 12177 + R: Christian Heusel <christian@heusel.eu> 12178 + R: Nathan Chancellor <nathan@kernel.org> 12179 + S: Maintained 12180 + F: scripts/package/PKGBUILD 12181 12182 KERNEL REGRESSIONS 12183 M: Thorsten Leemhuis <linux@leemhuis.info>
+14 -22
Makefile
··· 11 # Comments in this file are targeted only to the developer, do not 12 # expect to learn how to build the kernel reading this file. 13 14 - ifeq ($(filter undefine,$(.FEATURES)),) 15 - $(error GNU Make >= 3.82 is required. Your Make version is $(MAKE_VERSION)) 16 endif 17 18 $(if $(filter __%, $(MAKECMDGOALS)), \ ··· 93 94 # If the user is running make -s (silent mode), suppress echoing of 95 # commands 96 - # make-4.0 (and later) keep single letter options in the 1st word of MAKEFLAGS. 97 - 98 - ifeq ($(filter 3.%,$(MAKE_VERSION)),) 99 - short-opts := $(firstword -$(MAKEFLAGS)) 100 - else 101 - short-opts := $(filter-out --%,$(MAKEFLAGS)) 102 - endif 103 - 104 - ifneq ($(findstring s,$(short-opts)),) 105 quiet=silent_ 106 override KBUILD_VERBOSE := 107 endif ··· 191 192 ifneq ($(words $(subst :, ,$(abs_srctree))), 1) 193 $(error source directory cannot contain spaces or colons) 194 - endif 195 - 196 - ifneq ($(filter 3.%,$(MAKE_VERSION)),) 197 - # 'MAKEFLAGS += -rR' does not immediately become effective for GNU Make 3.x 198 - # We need to invoke sub-make to avoid implicit rules in the top Makefile. 199 - need-sub-make := 1 200 - # Cancel implicit rules for this Makefile. 201 - $(this-makefile): ; 202 endif 203 204 export sub_make_done := 1 ··· 458 -Dclippy::no_mangle_with_rust_abi \ 459 -Wclippy::dbg_macro 460 461 - KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) 462 - KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) 463 KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \ 464 -Zallow-features= $(HOSTRUSTFLAGS) 465 KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) ··· 1330 endif 1331 endif 1332 1333 PHONY += resolve_btfids_clean 1334 1335 resolve_btfids_O = $(abspath $(objtree))/tools/bpf/resolve_btfids ··· 1489 # Directories & files removed with 'make mrproper' 1490 MRPROPER_FILES += include/config include/generated \ 1491 arch/$(SRCARCH)/include/generated .objdiff \ 1492 - debian snap tar-install \ 1493 .config .config.old .version \ 1494 Module.symvers \ 1495 certs/signing_key.pem \
··· 11 # Comments in this file are targeted only to the developer, do not 12 # expect to learn how to build the kernel reading this file. 13 14 + ifeq ($(filter output-sync,$(.FEATURES)),) 15 + $(error GNU Make >= 4.0 is required. Your Make version is $(MAKE_VERSION)) 16 endif 17 18 $(if $(filter __%, $(MAKECMDGOALS)), \ ··· 93 94 # If the user is running make -s (silent mode), suppress echoing of 95 # commands 96 + ifneq ($(findstring s,$(firstword -$(MAKEFLAGS))),) 97 quiet=silent_ 98 override KBUILD_VERBOSE := 99 endif ··· 199 200 ifneq ($(words $(subst :, ,$(abs_srctree))), 1) 201 $(error source directory cannot contain spaces or colons) 202 endif 203 204 export sub_make_done := 1 ··· 474 -Dclippy::no_mangle_with_rust_abi \ 475 -Wclippy::dbg_macro 476 477 + KBUILD_HOSTCFLAGS := $(KBUILD_USERHOSTCFLAGS) $(HOST_LFS_CFLAGS) \ 478 + $(HOSTCFLAGS) -I $(srctree)/scripts/include 479 + KBUILD_HOSTCXXFLAGS := -Wall -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) \ 480 + -I $(srctree)/scripts/include 481 KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \ 482 -Zallow-features= $(HOSTRUSTFLAGS) 483 KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) ··· 1344 endif 1345 endif 1346 1347 + # The tools build system is not a part of Kbuild and tends to introduce 1348 + # its own unique issues. If you need to integrate a new tool into Kbuild, 1349 + # please consider locating that tool outside the tools/ tree and using the 1350 + # standard Kbuild "hostprogs" syntax instead of adding a new tools/* entry 1351 + # here. See Documentation/kbuild/makefiles.rst for details. 1352 + 1353 PHONY += resolve_btfids_clean 1354 1355 resolve_btfids_O = $(abspath $(objtree))/tools/bpf/resolve_btfids ··· 1497 # Directories & files removed with 'make mrproper' 1498 MRPROPER_FILES += include/config include/generated \ 1499 arch/$(SRCARCH)/include/generated .objdiff \ 1500 + debian snap tar-install PKGBUILD pacman \ 1501 .config .config.old .version \ 1502 Module.symvers \ 1503 certs/signing_key.pem \
+4 -2
arch/arm/Kconfig
··· 1483 from the ATAG list and store it at run time into the appended DTB. 1484 1485 choice 1486 - prompt "Kernel command line type" if ARM_ATAG_DTB_COMPAT 1487 default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER 1488 1489 config ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER ··· 1513 memory size and the root device (e.g., mem=64M root=/dev/nfs). 1514 1515 choice 1516 - prompt "Kernel command line type" if CMDLINE != "" 1517 default CMDLINE_FROM_BOOTLOADER 1518 1519 config CMDLINE_FROM_BOOTLOADER
··· 1483 from the ATAG list and store it at run time into the appended DTB. 1484 1485 choice 1486 + prompt "Kernel command line type" 1487 + depends on ARM_ATAG_DTB_COMPAT 1488 default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER 1489 1490 config ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER ··· 1512 memory size and the root device (e.g., mem=64M root=/dev/nfs). 1513 1514 choice 1515 + prompt "Kernel command line type" 1516 + depends on CMDLINE != "" 1517 default CMDLINE_FROM_BOOTLOADER 1518 1519 config CMDLINE_FROM_BOOTLOADER
+2
arch/arm/boot/install.sh
··· 17 # $3 - kernel map file 18 # $4 - default install path (blank if root directory) 19 20 if [ "$(basename $2)" = "zImage" ]; then 21 # Compressed install 22 echo "Installing compressed kernel"
··· 17 # $3 - kernel map file 18 # $4 - default install path (blank if root directory) 19 20 + set -e 21 + 22 if [ "$(basename $2)" = "zImage" ]; then 23 # Compressed install 24 echo "Installing compressed kernel"
+2 -1
arch/arm64/Kconfig
··· 2290 root device (e.g. root=/dev/nfs). 2291 2292 choice 2293 - prompt "Kernel command line type" if CMDLINE != "" 2294 default CMDLINE_FROM_BOOTLOADER 2295 help 2296 Choose how the kernel will handle the provided default kernel
··· 2290 root device (e.g. root=/dev/nfs). 2291 2292 choice 2293 + prompt "Kernel command line type" 2294 + depends on CMDLINE != "" 2295 default CMDLINE_FROM_BOOTLOADER 2296 help 2297 Choose how the kernel will handle the provided default kernel
+2
arch/arm64/boot/install.sh
··· 17 # $3 - kernel map file 18 # $4 - default install path (blank if root directory) 19 20 if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ] 21 then 22 # Compressed install
··· 17 # $3 - kernel map file 18 # $4 - default install path (blank if root directory) 19 20 + set -e 21 + 22 if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ] 23 then 24 # Compressed install
+2
arch/m68k/install.sh
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 if [ -f $4/vmlinuz ]; then 20 mv $4/vmlinuz $4/vmlinuz.old 21 fi
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 + set -e 20 + 21 if [ -f $4/vmlinuz ]; then 22 mv $4/vmlinuz $4/vmlinuz.old 23 fi
+4 -2
arch/mips/Kconfig
··· 2927 bool 2928 2929 choice 2930 - prompt "Kernel appended dtb support" if USE_OF 2931 default MIPS_NO_APPENDED_DTB 2932 2933 config MIPS_NO_APPENDED_DTB ··· 2969 endchoice 2970 2971 choice 2972 - prompt "Kernel command line type" if !CMDLINE_OVERRIDE 2973 default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \ 2974 !MACH_LOONGSON64 && !MIPS_MALTA && \ 2975 !CAVIUM_OCTEON_SOC
··· 2927 bool 2928 2929 choice 2930 + prompt "Kernel appended dtb support" 2931 + depends on USE_OF 2932 default MIPS_NO_APPENDED_DTB 2933 2934 config MIPS_NO_APPENDED_DTB ··· 2968 endchoice 2969 2970 choice 2971 + prompt "Kernel command line type" 2972 + depends on !CMDLINE_OVERRIDE 2973 default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \ 2974 !MACH_LOONGSON64 && !MIPS_MALTA && \ 2975 !CAVIUM_OCTEON_SOC
+2
arch/nios2/boot/install.sh
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 if [ -f $4/vmlinuz ]; then 20 mv $4/vmlinuz $4/vmlinuz.old 21 fi
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 + set -e 20 + 21 if [ -f $4/vmlinuz ]; then 22 mv $4/vmlinuz $4/vmlinuz.old 23 fi
+2
arch/parisc/install.sh
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 if [ "$(basename $2)" = "vmlinuz" ]; then 20 # Compressed install 21 echo "Installing compressed kernel"
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 + set -e 20 + 21 if [ "$(basename $2)" = "vmlinuz" ]; then 22 # Compressed install 23 echo "Installing compressed kernel"
+2 -1
arch/powerpc/Kconfig
··· 964 most cases you will need to specify the root device here. 965 966 choice 967 - prompt "Kernel command line type" if CMDLINE != "" 968 default CMDLINE_FROM_BOOTLOADER 969 970 config CMDLINE_FROM_BOOTLOADER
··· 964 most cases you will need to specify the root device here. 965 966 choice 967 + prompt "Kernel command line type" 968 + depends on CMDLINE != "" 969 default CMDLINE_FROM_BOOTLOADER 970 971 config CMDLINE_FROM_BOOTLOADER
+2 -1
arch/riscv/Kconfig
··· 960 line here and choose how the kernel should use it later on. 961 962 choice 963 - prompt "Built-in command line usage" if CMDLINE != "" 964 default CMDLINE_FALLBACK 965 help 966 Choose how the kernel will handle the provided built-in command
··· 960 line here and choose how the kernel should use it later on. 961 962 choice 963 + prompt "Built-in command line usage" 964 + depends on CMDLINE != "" 965 default CMDLINE_FALLBACK 966 help 967 Choose how the kernel will handle the provided built-in command
+2
arch/riscv/boot/install.sh
··· 17 # $3 - kernel map file 18 # $4 - default install path (blank if root directory) 19 20 case "${2##*/}" in 21 # Compressed install 22 Image.*|vmlinuz.efi)
··· 17 # $3 - kernel map file 18 # $4 - default install path (blank if root directory) 19 20 + set -e 21 + 22 case "${2##*/}" in 23 # Compressed install 24 Image.*|vmlinuz.efi)
+2
arch/s390/boot/install.sh
··· 15 # $3 - kernel map file 16 # $4 - default install path (blank if root directory) 17 18 echo "Warning: '${INSTALLKERNEL}' command not available - additional " \ 19 "bootloader config required" >&2 20 if [ -f "$4/vmlinuz-$1" ]; then mv -- "$4/vmlinuz-$1" "$4/vmlinuz-$1.old"; fi
··· 15 # $3 - kernel map file 16 # $4 - default install path (blank if root directory) 17 18 + set -e 19 + 20 echo "Warning: '${INSTALLKERNEL}' command not available - additional " \ 21 "bootloader config required" >&2 22 if [ -f "$4/vmlinuz-$1" ]; then mv -- "$4/vmlinuz-$1" "$4/vmlinuz-$1.old"; fi
+2
arch/sparc/boot/install.sh
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 if [ -f $4/vmlinuz ]; then 20 mv $4/vmlinuz $4/vmlinuz.old 21 fi
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 + set -e 20 + 21 if [ -f $4/vmlinuz ]; then 22 mv $4/vmlinuz $4/vmlinuz.old 23 fi
+2
arch/x86/boot/install.sh
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 if [ -f $4/vmlinuz ]; then 20 mv $4/vmlinuz $4/vmlinuz.old 21 fi
··· 16 # $3 - kernel map file 17 # $4 - default install path (blank if root directory) 18 19 + set -e 20 + 21 if [ -f $4/vmlinuz ]; then 22 mv $4/vmlinuz $4/vmlinuz.old 23 fi
+2 -1
fs/jffs2/Kconfig
··· 151 RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure. 152 153 choice 154 - prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS 155 default JFFS2_CMODE_PRIORITY 156 depends on JFFS2_FS 157 help 158 You can set here the default compression mode of JFFS2 from
··· 151 RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure. 152 153 choice 154 + prompt "JFFS2 default compression mode" 155 default JFFS2_CMODE_PRIORITY 156 + depends on JFFS2_COMPRESSION_OPTIONS 157 depends on JFFS2_FS 158 help 159 You can set here the default compression mode of JFFS2 from
-19
include/asm-generic/vmlinux.lds.h
··· 443 #endif 444 445 /* 446 - * Some symbol definitions will not exist yet during the first pass of the 447 - * link, but are guaranteed to exist in the final link. Provide preliminary 448 - * definitions that will be superseded in the final link to avoid having to 449 - * rely on weak external linkage, which requires a GOT when used in position 450 - * independent code. 451 - */ 452 - #define PRELIMINARY_SYMBOL_DEFINITIONS \ 453 - PROVIDE(kallsyms_addresses = .); \ 454 - PROVIDE(kallsyms_offsets = .); \ 455 - PROVIDE(kallsyms_names = .); \ 456 - PROVIDE(kallsyms_num_syms = .); \ 457 - PROVIDE(kallsyms_relative_base = .); \ 458 - PROVIDE(kallsyms_token_table = .); \ 459 - PROVIDE(kallsyms_token_index = .); \ 460 - PROVIDE(kallsyms_markers = .); \ 461 - PROVIDE(kallsyms_seqs_of_names = .); 462 - 463 - /* 464 * Read only Data 465 */ 466 #define RO_DATA(align) \ 467 . = ALIGN((align)); \ 468 - PRELIMINARY_SYMBOL_DEFINITIONS \ 469 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ 470 __start_rodata = .; \ 471 *(.rodata) *(.rodata.*) \
··· 443 #endif 444 445 /* 446 * Read only Data 447 */ 448 #define RO_DATA(align) \ 449 . = ALIGN((align)); \ 450 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ 451 __start_rodata = .; \ 452 *(.rodata) *(.rodata.*) \
-18
init/Kconfig
··· 1803 depends on KALLSYMS 1804 default X86_64 && SMP 1805 1806 - config KALLSYMS_BASE_RELATIVE 1807 - bool 1808 - depends on KALLSYMS 1809 - default y 1810 - help 1811 - Instead of emitting them as absolute values in the native word size, 1812 - emit the symbol references in the kallsyms table as 32-bit entries, 1813 - each containing a relative value in the range [base, base + U32_MAX] 1814 - or, when KALLSYMS_ABSOLUTE_PERCPU is in effect, each containing either 1815 - an absolute value in the range [0, S32_MAX] or a relative value in the 1816 - range [base, base + S32_MAX], where base is the lowest relative symbol 1817 - address encountered in the image. 1818 - 1819 - On 64-bit builds, this reduces the size of the address table by 50%, 1820 - but more importantly, it results in entries whose values are build 1821 - time constants, and no relocation pass is required at runtime to fix 1822 - up the entries based on the runtime load address of the kernel. 1823 - 1824 # end of the "standard kernel features (expert users)" menu 1825 1826 config ARCH_HAS_MEMBARRIER_CALLBACKS
··· 1803 depends on KALLSYMS 1804 default X86_64 && SMP 1805 1806 # end of the "standard kernel features (expert users)" menu 1807 1808 config ARCH_HAS_MEMBARRIER_CALLBACKS
+1 -1
init/Makefile
··· 52 # Build version-timestamp.c with final UTS_VERSION 53 # 54 55 - include/generated/utsversion.h: build-version-auto = $(shell $(src)/build-version) 56 include/generated/utsversion.h: build-timestamp-auto = $(shell LC_ALL=C date) 57 include/generated/utsversion.h: FORCE 58 $(call filechk,uts_version)
··· 52 # Build version-timestamp.c with final UTS_VERSION 53 # 54 55 + include/generated/utsversion.h: build-version-auto = $(shell $(srctree)/scripts/build-version) 56 include/generated/utsversion.h: build-timestamp-auto = $(shell LC_ALL=C date) 57 include/generated/utsversion.h: FORCE 58 $(call filechk,uts_version)
init/build-version scripts/build-version
+1 -4
kernel/kallsyms.c
··· 148 149 unsigned long kallsyms_sym_address(int idx) 150 { 151 - if (!IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE)) 152 - return kallsyms_addresses[idx]; 153 - 154 /* values are unsigned offsets if --absolute-percpu is not in effect */ 155 if (!IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU)) 156 return kallsyms_relative_base + (u32)kallsyms_offsets[idx]; ··· 322 unsigned long symbol_start = 0, symbol_end = 0; 323 unsigned long i, low, high, mid; 324 325 - /* Do a binary search on the sorted kallsyms_addresses array. */ 326 low = 0; 327 high = kallsyms_num_syms; 328
··· 148 149 unsigned long kallsyms_sym_address(int idx) 150 { 151 /* values are unsigned offsets if --absolute-percpu is not in effect */ 152 if (!IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU)) 153 return kallsyms_relative_base + (u32)kallsyms_offsets[idx]; ··· 325 unsigned long symbol_start = 0, symbol_end = 0; 326 unsigned long i, low, high, mid; 327 328 + /* Do a binary search on the sorted kallsyms_offsets array. */ 329 low = 0; 330 high = kallsyms_num_syms; 331
-6
kernel/kallsyms_internal.h
··· 4 5 #include <linux/types.h> 6 7 - /* 8 - * These will be re-linked against their real values during the second link 9 - * stage. Preliminary values must be provided in the linker script using the 10 - * PROVIDE() directive so that the first link stage can complete successfully. 11 - */ 12 - extern const unsigned long kallsyms_addresses[]; 13 extern const int kallsyms_offsets[]; 14 extern const u8 kallsyms_names[]; 15
··· 4 5 #include <linux/types.h> 6 7 extern const int kallsyms_offsets[]; 8 extern const u8 kallsyms_names[]; 9
-4
kernel/vmcore_info.c
··· 216 VMCOREINFO_SYMBOL(kallsyms_num_syms); 217 VMCOREINFO_SYMBOL(kallsyms_token_table); 218 VMCOREINFO_SYMBOL(kallsyms_token_index); 219 - #ifdef CONFIG_KALLSYMS_BASE_RELATIVE 220 VMCOREINFO_SYMBOL(kallsyms_offsets); 221 VMCOREINFO_SYMBOL(kallsyms_relative_base); 222 - #else 223 - VMCOREINFO_SYMBOL(kallsyms_addresses); 224 - #endif /* CONFIG_KALLSYMS_BASE_RELATIVE */ 225 #endif /* CONFIG_KALLSYMS */ 226 227 arch_crash_save_vmcoreinfo();
··· 216 VMCOREINFO_SYMBOL(kallsyms_num_syms); 217 VMCOREINFO_SYMBOL(kallsyms_token_table); 218 VMCOREINFO_SYMBOL(kallsyms_token_index); 219 VMCOREINFO_SYMBOL(kallsyms_offsets); 220 VMCOREINFO_SYMBOL(kallsyms_relative_base); 221 #endif /* CONFIG_KALLSYMS */ 222 223 arch_crash_save_vmcoreinfo();
+1 -1
scripts/Kbuild.include
··· 68 # Read a file, replacing newlines with spaces 69 # 70 # Make 4.2 or later can read a file by using its builtin function. 71 - ifneq ($(filter-out 3.% 4.0 4.1, $(MAKE_VERSION)),) 72 read-file = $(subst $(newline),$(space),$(file < $1)) 73 else 74 read-file = $(shell cat $1 2>/dev/null)
··· 68 # Read a file, replacing newlines with spaces 69 # 70 # Make 4.2 or later can read a file by using its builtin function. 71 + ifneq ($(filter-out 4.0 4.1, $(MAKE_VERSION)),) 72 read-file = $(subst $(newline),$(space),$(file < $1)) 73 else 74 read-file = $(shell cat $1 2>/dev/null)
+7 -2
scripts/Makefile.lib
··· 409 410 DT_CHECK_CMD = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) 411 412 ifneq ($(CHECK_DTBS),) 413 quiet_cmd_fdtoverlay = DTOVLCH $@ 414 - cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs) ; $(DT_CHECK_CMD) $@ || true 415 else 416 quiet_cmd_fdtoverlay = DTOVL $@ 417 - cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs) 418 endif 419 420 $(multi-dtb-y): FORCE ··· 533 cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ 534 --name '$(UIMAGE_NAME)' \ 535 $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ 536 --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) 537 538 # XZ
··· 409 410 DT_CHECK_CMD = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) 411 412 + # NOTE: 413 + # Do not replace $(filter %.dtb %.dtbo, $^) with $(real-prereqs). When a single 414 + # DTB is turned into a multi-blob DTB, $^ will contain header file dependencies 415 + # recorded in the .*.cmd file. 416 ifneq ($(CHECK_DTBS),) 417 quiet_cmd_fdtoverlay = DTOVLCH $@ 418 + cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(filter %.dtb %.dtbo, $^) ; $(DT_CHECK_CMD) $@ || true 419 else 420 quiet_cmd_fdtoverlay = DTOVL $@ 421 + cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(filter %.dtb %.dtbo, $^) 422 endif 423 424 $(multi-dtb-y): FORCE ··· 529 cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ 530 --name '$(UIMAGE_NAME)' \ 531 $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ 532 + $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ 533 --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) 534 535 # XZ
+14
scripts/Makefile.package
··· 141 cd $(objtree)/snap && \ 142 snapcraft --target-arch=$(UTS_MACHINE) 143 144 # dir-pkg tar*-pkg - tarball targets 145 # --------------------------------------------------------------------------- 146 ··· 234 @echo ' bindeb-pkg - Build only the binary kernel deb package' 235 @echo ' snap-pkg - Build only the binary kernel snap package' 236 @echo ' (will connect to external hosts)' 237 @echo ' dir-pkg - Build the kernel as a plain directory structure' 238 @echo ' tar-pkg - Build the kernel as an uncompressed tarball' 239 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball'
··· 141 cd $(objtree)/snap && \ 142 snapcraft --target-arch=$(UTS_MACHINE) 143 144 + # pacman-pkg 145 + # --------------------------------------------------------------------------- 146 + 147 + PHONY += pacman-pkg 148 + pacman-pkg: 149 + @ln -srf $(srctree)/scripts/package/PKGBUILD $(objtree)/PKGBUILD 150 + +objtree="$(realpath $(objtree))" \ 151 + BUILDDIR="$(realpath $(objtree))/pacman" \ 152 + CARCH="$(UTS_MACHINE)" \ 153 + KBUILD_MAKEFLAGS="$(MAKEFLAGS)" \ 154 + KBUILD_REVISION="$(shell $(srctree)/scripts/build-version)" \ 155 + makepkg $(MAKEPKGOPTS) 156 + 157 # dir-pkg tar*-pkg - tarball targets 158 # --------------------------------------------------------------------------- 159 ··· 221 @echo ' bindeb-pkg - Build only the binary kernel deb package' 222 @echo ' snap-pkg - Build only the binary kernel snap package' 223 @echo ' (will connect to external hosts)' 224 + @echo ' pacman-pkg - Build only the binary kernel pacman package' 225 @echo ' dir-pkg - Build the kernel as a plain directory structure' 226 @echo ' tar-pkg - Build the kernel as an uncompressed tarball' 227 @echo ' targz-pkg - Build the kernel as a gzip compressed tarball'
+4
scripts/install.sh
··· 20 fi 21 done 22 23 # User/arch may have a custom install script 24 for file in "${HOME}/bin/${INSTALLKERNEL}" \ 25 "/sbin/${INSTALLKERNEL}" \
··· 20 fi 21 done 22 23 + if [ -n "${INSTALL_PATH}" ] && ! [ -e "${INSTALL_PATH}" ]; then 24 + mkdir -p "${INSTALL_PATH}" 25 + fi 26 + 27 # User/arch may have a custom install script 28 for file in "${HOME}/bin/${INSTALLKERNEL}" \ 29 "/sbin/${INSTALLKERNEL}" \
+52 -73
scripts/kallsyms.c
··· 6 * of the GNU General Public License, incorporated herein by reference. 7 * 8 * Usage: kallsyms [--all-symbols] [--absolute-percpu] 9 - * [--base-relative] [--lto-clang] in.map > out.S 10 * 11 * Table compression uses all the unused char codes on the symbols and 12 * maps these to the most used substrings (tokens). For instance, it might ··· 36 unsigned long long addr; 37 unsigned int len; 38 unsigned int seq; 39 - unsigned int start_pos; 40 - unsigned int percpu_absolute; 41 unsigned char sym[]; 42 }; 43 ··· 62 static unsigned int table_size, table_cnt; 63 static int all_symbols; 64 static int absolute_percpu; 65 - static int base_relative; 66 static int lto_clang; 67 68 static int token_profit[0x10000]; ··· 74 static void usage(void) 75 { 76 fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] " 77 - "[--base-relative] [--lto-clang] in.map > out.S\n"); 78 exit(1); 79 } 80 ··· 181 sym->len = len; 182 sym->sym[0] = type; 183 strcpy(sym_name(sym), name); 184 - sym->percpu_absolute = 0; 185 186 return sym; 187 } ··· 257 } 258 } 259 table_cnt = pos; 260 - 261 - /* When valid symbol is not registered, exit to error */ 262 - if (!table_cnt) { 263 - fprintf(stderr, "No valid symbol.\n"); 264 - exit(1); 265 - } 266 } 267 268 static void read_map(const char *in) ··· 277 if (!sym) 278 continue; 279 280 - sym->start_pos = table_cnt; 281 282 if (table_cnt >= table_size) { 283 table_size += 10000; ··· 339 return total; 340 } 341 342 - static int symbol_absolute(const struct sym_entry *s) 343 { 344 return s->percpu_absolute; 345 } ··· 392 { 393 unsigned int i, k, off; 394 unsigned int best_idx[256]; 395 - unsigned int *markers; 396 char buf[KSYM_NAME_LEN]; 397 398 printf("#include <asm/bitsperlong.h>\n"); ··· 412 413 /* table of offset markers, that give the offset in the compressed stream 414 * every 256 symbols */ 415 - markers = malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256)); 416 if (!markers) { 417 fprintf(stderr, "kallsyms failure: " 418 "unable to allocate required memory\n"); ··· 455 } 456 for (k = 0; k < table[i]->len; k++) 457 printf(", 0x%02x", table[i]->sym[k]); 458 - printf("\n"); 459 } 460 printf("\n"); 461 462 - /* 463 - * Now that we wrote out the compressed symbol names, restore the 464 - * original names, which are needed in some of the later steps. 465 - */ 466 - for (i = 0; i < table_cnt; i++) { 467 - expand_symbol(table[i]->sym, table[i]->len, buf); 468 - strcpy((char *)table[i]->sym, buf); 469 - } 470 - 471 output_label("kallsyms_markers"); 472 - for (i = 0; i < ((table_cnt + 255) >> 8); i++) 473 printf("\t.long\t%u\n", markers[i]); 474 printf("\n"); 475 ··· 488 printf("\t.short\t%d\n", best_idx[i]); 489 printf("\n"); 490 491 - if (!base_relative) 492 - output_label("kallsyms_addresses"); 493 - else 494 - output_label("kallsyms_offsets"); 495 496 for (i = 0; i < table_cnt; i++) { 497 - if (base_relative) { 498 - /* 499 - * Use the offset relative to the lowest value 500 - * encountered of all relative symbols, and emit 501 - * non-relocatable fixed offsets that will be fixed 502 - * up at runtime. 503 - */ 504 505 - long long offset; 506 - int overflow; 507 508 - if (!absolute_percpu) { 509 - offset = table[i]->addr - relative_base; 510 - overflow = (offset < 0 || offset > UINT_MAX); 511 - } else if (symbol_absolute(table[i])) { 512 - offset = table[i]->addr; 513 - overflow = (offset < 0 || offset > INT_MAX); 514 - } else { 515 - offset = relative_base - table[i]->addr - 1; 516 - overflow = (offset < INT_MIN || offset >= 0); 517 - } 518 - if (overflow) { 519 - fprintf(stderr, "kallsyms failure: " 520 - "%s symbol value %#llx out of range in relative mode\n", 521 - symbol_absolute(table[i]) ? "absolute" : "relative", 522 - table[i]->addr); 523 - exit(EXIT_FAILURE); 524 - } 525 - printf("\t.long\t%#x /* %s */\n", (int)offset, table[i]->sym); 526 - } else if (!symbol_absolute(table[i])) { 527 - output_address(table[i]->addr); 528 } else { 529 - printf("\tPTR\t%#llx\n", table[i]->addr); 530 } 531 } 532 printf("\n"); 533 534 - if (base_relative) { 535 - output_label("kallsyms_relative_base"); 536 - output_address(relative_base); 537 - printf("\n"); 538 - } 539 540 if (lto_clang) 541 for (i = 0; i < table_cnt; i++) ··· 533 sort_symbols_by_name(); 534 output_label("kallsyms_seqs_of_names"); 535 for (i = 0; i < table_cnt; i++) 536 - printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n", 537 (unsigned char)(table[i]->seq >> 16), 538 (unsigned char)(table[i]->seq >> 8), 539 - (unsigned char)(table[i]->seq >> 0)); 540 printf("\n"); 541 } 542 ··· 761 return wa - wb; 762 763 /* sort by initial order, so that other symbols are left undisturbed */ 764 - return sa->start_pos - sb->start_pos; 765 } 766 767 static void sort_symbols(void) ··· 781 * versions of this tool. 782 */ 783 table[i]->sym[0] = 'A'; 784 - table[i]->percpu_absolute = 1; 785 } 786 } 787 ··· 807 static const struct option long_options[] = { 808 {"all-symbols", no_argument, &all_symbols, 1}, 809 {"absolute-percpu", no_argument, &absolute_percpu, 1}, 810 - {"base-relative", no_argument, &base_relative, 1}, 811 {"lto-clang", no_argument, &lto_clang, 1}, 812 {}, 813 }; ··· 827 if (absolute_percpu) 828 make_percpus_absolute(); 829 sort_symbols(); 830 - if (base_relative) 831 - record_relative_base(); 832 optimize_token_table(); 833 write_src(); 834
··· 6 * of the GNU General Public License, incorporated herein by reference. 7 * 8 * Usage: kallsyms [--all-symbols] [--absolute-percpu] 9 + * [--lto-clang] in.map > out.S 10 * 11 * Table compression uses all the unused char codes on the symbols and 12 * maps these to the most used substrings (tokens). For instance, it might ··· 36 unsigned long long addr; 37 unsigned int len; 38 unsigned int seq; 39 + bool percpu_absolute; 40 unsigned char sym[]; 41 }; 42 ··· 63 static unsigned int table_size, table_cnt; 64 static int all_symbols; 65 static int absolute_percpu; 66 static int lto_clang; 67 68 static int token_profit[0x10000]; ··· 76 static void usage(void) 77 { 78 fprintf(stderr, "Usage: kallsyms [--all-symbols] [--absolute-percpu] " 79 + "[--lto-clang] in.map > out.S\n"); 80 exit(1); 81 } 82 ··· 183 sym->len = len; 184 sym->sym[0] = type; 185 strcpy(sym_name(sym), name); 186 + sym->percpu_absolute = false; 187 188 return sym; 189 } ··· 259 } 260 } 261 table_cnt = pos; 262 } 263 264 static void read_map(const char *in) ··· 285 if (!sym) 286 continue; 287 288 + sym->seq = table_cnt; 289 290 if (table_cnt >= table_size) { 291 table_size += 10000; ··· 347 return total; 348 } 349 350 + static bool symbol_absolute(const struct sym_entry *s) 351 { 352 return s->percpu_absolute; 353 } ··· 400 { 401 unsigned int i, k, off; 402 unsigned int best_idx[256]; 403 + unsigned int *markers, markers_cnt; 404 char buf[KSYM_NAME_LEN]; 405 406 printf("#include <asm/bitsperlong.h>\n"); ··· 420 421 /* table of offset markers, that give the offset in the compressed stream 422 * every 256 symbols */ 423 + markers_cnt = (table_cnt + 255) / 256; 424 + markers = malloc(sizeof(*markers) * markers_cnt); 425 if (!markers) { 426 fprintf(stderr, "kallsyms failure: " 427 "unable to allocate required memory\n"); ··· 462 } 463 for (k = 0; k < table[i]->len; k++) 464 printf(", 0x%02x", table[i]->sym[k]); 465 + 466 + /* 467 + * Now that we wrote out the compressed symbol name, restore the 468 + * original name and print it in the comment. 469 + */ 470 + expand_symbol(table[i]->sym, table[i]->len, buf); 471 + strcpy((char *)table[i]->sym, buf); 472 + printf("\t/* %s */\n", table[i]->sym); 473 } 474 printf("\n"); 475 476 output_label("kallsyms_markers"); 477 + for (i = 0; i < markers_cnt; i++) 478 printf("\t.long\t%u\n", markers[i]); 479 printf("\n"); 480 ··· 497 printf("\t.short\t%d\n", best_idx[i]); 498 printf("\n"); 499 500 + output_label("kallsyms_offsets"); 501 502 for (i = 0; i < table_cnt; i++) { 503 + /* 504 + * Use the offset relative to the lowest value 505 + * encountered of all relative symbols, and emit 506 + * non-relocatable fixed offsets that will be fixed 507 + * up at runtime. 508 + */ 509 510 + long long offset; 511 + int overflow; 512 513 + if (!absolute_percpu) { 514 + offset = table[i]->addr - relative_base; 515 + overflow = (offset < 0 || offset > UINT_MAX); 516 + } else if (symbol_absolute(table[i])) { 517 + offset = table[i]->addr; 518 + overflow = (offset < 0 || offset > INT_MAX); 519 } else { 520 + offset = relative_base - table[i]->addr - 1; 521 + overflow = (offset < INT_MIN || offset >= 0); 522 } 523 + if (overflow) { 524 + fprintf(stderr, "kallsyms failure: " 525 + "%s symbol value %#llx out of range in relative mode\n", 526 + symbol_absolute(table[i]) ? "absolute" : "relative", 527 + table[i]->addr); 528 + exit(EXIT_FAILURE); 529 + } 530 + printf("\t.long\t%#x\t/* %s */\n", (int)offset, table[i]->sym); 531 } 532 printf("\n"); 533 534 + output_label("kallsyms_relative_base"); 535 + output_address(relative_base); 536 + printf("\n"); 537 538 if (lto_clang) 539 for (i = 0; i < table_cnt; i++) ··· 553 sort_symbols_by_name(); 554 output_label("kallsyms_seqs_of_names"); 555 for (i = 0; i < table_cnt; i++) 556 + printf("\t.byte 0x%02x, 0x%02x, 0x%02x\t/* %s */\n", 557 (unsigned char)(table[i]->seq >> 16), 558 (unsigned char)(table[i]->seq >> 8), 559 + (unsigned char)(table[i]->seq >> 0), 560 + table[i]->sym); 561 printf("\n"); 562 } 563 ··· 780 return wa - wb; 781 782 /* sort by initial order, so that other symbols are left undisturbed */ 783 + return sa->seq - sb->seq; 784 } 785 786 static void sort_symbols(void) ··· 800 * versions of this tool. 801 */ 802 table[i]->sym[0] = 'A'; 803 + table[i]->percpu_absolute = true; 804 } 805 } 806 ··· 826 static const struct option long_options[] = { 827 {"all-symbols", no_argument, &all_symbols, 1}, 828 {"absolute-percpu", no_argument, &absolute_percpu, 1}, 829 {"lto-clang", no_argument, &lto_clang, 1}, 830 {}, 831 }; ··· 847 if (absolute_percpu) 848 make_percpus_absolute(); 849 sort_symbols(); 850 + record_relative_base(); 851 optimize_token_table(); 852 write_src(); 853
scripts/kconfig/array_size.h scripts/include/array_size.h
+92 -146
scripts/kconfig/conf.c
··· 114 srand(seed); 115 } 116 117 - static bool randomize_choice_values(struct symbol *csym) 118 { 119 - struct property *prop; 120 - struct symbol *sym; 121 - struct expr *e; 122 - int cnt, def; 123 124 /* 125 - * If choice is mod then we may have more items selected 126 - * and if no then no-one. 127 - * In both cases stop. 128 */ 129 - if (csym->curr.tri != yes) 130 - return false; 131 132 - prop = sym_get_choice_prop(csym); 133 - 134 - /* count entries in choice block */ 135 - cnt = 0; 136 - expr_list_for_each_sym(prop->expr, e, sym) 137 - cnt++; 138 - 139 - /* 140 - * find a random value and set it to yes, 141 - * set the rest to no so we have only one set 142 - */ 143 - def = rand() % cnt; 144 - 145 - cnt = 0; 146 - expr_list_for_each_sym(prop->expr, e, sym) { 147 - if (def == cnt++) { 148 - sym->def[S_DEF_USER].tri = yes; 149 - csym->def[S_DEF_USER].val = sym; 150 - } else { 151 - sym->def[S_DEF_USER].tri = no; 152 - } 153 - sym->flags |= SYMBOL_DEF_USER; 154 - /* clear VALID to get value calculated */ 155 - sym->flags &= ~SYMBOL_VALID; 156 } 157 - csym->flags |= SYMBOL_DEF_USER; 158 - /* clear VALID to get value calculated */ 159 - csym->flags &= ~SYMBOL_VALID; 160 161 - return true; 162 } 163 164 enum conf_def_mode { ··· 172 def_random 173 }; 174 175 - static bool conf_set_all_new_symbols(enum conf_def_mode mode) 176 { 177 - struct symbol *sym, *csym; 178 int cnt; 179 /* 180 * can't go as the default in switch-case below, otherwise gcc whines ··· 183 int pby = 50; /* probability of bool = y */ 184 int pty = 33; /* probability of tristate = y */ 185 int ptm = 33; /* probability of tristate = m */ 186 - bool has_changed = false; 187 188 if (mode == def_random) { 189 int n, p[3]; ··· 229 } 230 } 231 232 - for_all_symbols(sym) { 233 - if (sym_has_value(sym) || sym->flags & SYMBOL_VALID) 234 continue; 235 - switch (sym_get_type(sym)) { 236 - case S_BOOLEAN: 237 - case S_TRISTATE: 238 - has_changed = true; 239 - switch (mode) { 240 - case def_yes: 241 - sym->def[S_DEF_USER].tri = yes; 242 - break; 243 - case def_mod: 244 - sym->def[S_DEF_USER].tri = mod; 245 - break; 246 - case def_no: 247 - sym->def[S_DEF_USER].tri = no; 248 - break; 249 - case def_random: 250 - sym->def[S_DEF_USER].tri = no; 251 - cnt = rand() % 100; 252 - if (sym->type == S_TRISTATE) { 253 - if (cnt < pty) 254 - sym->def[S_DEF_USER].tri = yes; 255 - else if (cnt < pty + ptm) 256 - sym->def[S_DEF_USER].tri = mod; 257 - } else if (cnt < pby) 258 - sym->def[S_DEF_USER].tri = yes; 259 - break; 260 - default: 261 - continue; 262 - } 263 - if (!(sym_is_choice(sym) && mode == def_random)) 264 - sym->flags |= SYMBOL_DEF_USER; 265 - break; 266 - default: 267 - break; 268 } 269 270 } 271 272 sym_clear_all_valid(); 273 - 274 - /* 275 - * We have different type of choice blocks. 276 - * If curr.tri equals to mod then we can select several 277 - * choice symbols in one block. 278 - * In this case we do nothing. 279 - * If curr.tri equals yes then only one symbol can be 280 - * selected in a choice block and we set it to yes, 281 - * and the rest to no. 282 - */ 283 - if (mode != def_random) { 284 - for_all_symbols(csym) { 285 - if ((sym_is_choice(csym) && !sym_has_value(csym)) || 286 - sym_is_choice_value(csym)) 287 - csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; 288 - } 289 - } 290 - 291 - for_all_symbols(csym) { 292 - if (sym_has_value(csym) || !sym_is_choice(csym)) 293 - continue; 294 - 295 - sym_calc_value(csym); 296 - if (mode == def_random) 297 - has_changed |= randomize_choice_values(csym); 298 - else { 299 - set_all_choice_values(csym); 300 - has_changed = true; 301 - } 302 - } 303 - 304 - return has_changed; 305 } 306 307 static void conf_rewrite_tristates(tristate old_val, tristate new_val) ··· 422 423 static void conf_choice(struct menu *menu) 424 { 425 - struct symbol *sym, *def_sym; 426 struct menu *child; 427 - bool is_new; 428 - 429 - sym = menu->sym; 430 - is_new = !sym_has_value(sym); 431 - if (sym_is_changeable(sym)) { 432 - conf_sym(menu); 433 - sym_calc_value(sym); 434 - switch (sym_get_tristate_value(sym)) { 435 - case no: 436 - case mod: 437 - return; 438 - case yes: 439 - break; 440 - } 441 - } else { 442 - switch (sym_get_tristate_value(sym)) { 443 - case no: 444 - return; 445 - case mod: 446 - printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 447 - return; 448 - case yes: 449 - break; 450 - } 451 - } 452 453 while (1) { 454 int cnt, def; 455 456 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 457 - def_sym = sym_get_choice_value(sym); 458 cnt = def = 0; 459 line[0] = 0; 460 for (child = menu->list; child; child = child->next) { ··· 448 printf("%*c", indent, ' '); 449 printf(" %d. %s (%s)", cnt, menu_get_prompt(child), 450 child->sym->name); 451 - if (!sym_has_value(child->sym)) 452 printf(" (NEW)"); 453 printf("\n"); 454 } 455 printf("%*schoice", indent - 1, ""); ··· 501 print_help(child); 502 continue; 503 } 504 - sym_set_tristate_value(child->sym, yes); 505 return; 506 } 507 } ··· 548 549 if (sym_is_choice(sym)) { 550 conf_choice(menu); 551 - if (sym->curr.tri != mod) 552 - return; 553 - goto conf_childs; 554 } 555 556 switch (sym->type) { ··· 580 return; 581 582 sym = menu->sym; 583 - if (sym && !sym_has_value(sym) && 584 - (sym_is_changeable(sym) || 585 - (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes))) { 586 - 587 switch (input_mode) { 588 case listnewconfig: 589 if (sym->name) ··· 796 conf_set_all_new_symbols(def_default); 797 break; 798 case randconfig: 799 - /* Really nothing to do in this loop */ 800 - while (conf_set_all_new_symbols(def_random)) ; 801 break; 802 case defconfig: 803 conf_set_all_new_symbols(def_default);
··· 114 srand(seed); 115 } 116 117 + /** 118 + * randomize_choice_values - randomize choice block 119 + * 120 + * @choice: menu entry for the choice 121 + */ 122 + static void randomize_choice_values(struct menu *choice) 123 { 124 + struct menu *menu; 125 + int x; 126 + int cnt = 0; 127 128 /* 129 + * First, count the number of symbols to randomize. If sym_has_value() 130 + * is true, it was specified by KCONFIG_ALLCONFIG. It needs to be 131 + * respected. 132 */ 133 + menu_for_each_sub_entry(menu, choice) { 134 + struct symbol *sym = menu->sym; 135 136 + if (sym && !sym_has_value(sym)) 137 + cnt++; 138 } 139 140 + while (cnt > 0) { 141 + x = rand() % cnt; 142 + 143 + menu_for_each_sub_entry(menu, choice) { 144 + struct symbol *sym = menu->sym; 145 + 146 + if (sym && !sym_has_value(sym)) 147 + x--; 148 + 149 + if (x < 0) { 150 + sym->def[S_DEF_USER].tri = yes; 151 + sym->flags |= SYMBOL_DEF_USER; 152 + /* 153 + * Move the selected item to the _tail_ because 154 + * this needs to have a lower priority than the 155 + * user input from KCONFIG_ALLCONFIG. 156 + */ 157 + list_move_tail(&sym->choice_link, 158 + &choice->choice_members); 159 + 160 + break; 161 + } 162 + } 163 + cnt--; 164 + } 165 } 166 167 enum conf_def_mode { ··· 169 def_random 170 }; 171 172 + static void conf_set_all_new_symbols(enum conf_def_mode mode) 173 { 174 + struct menu *menu; 175 int cnt; 176 /* 177 * can't go as the default in switch-case below, otherwise gcc whines ··· 180 int pby = 50; /* probability of bool = y */ 181 int pty = 33; /* probability of tristate = y */ 182 int ptm = 33; /* probability of tristate = m */ 183 184 if (mode == def_random) { 185 int n, p[3]; ··· 227 } 228 } 229 230 + menu_for_each_entry(menu) { 231 + struct symbol *sym = menu->sym; 232 + tristate val; 233 + 234 + if (!sym || !menu->prompt || sym_has_value(sym) || 235 + (sym->type != S_BOOLEAN && sym->type != S_TRISTATE) || 236 + sym_is_choice_value(sym)) 237 continue; 238 + 239 + if (sym_is_choice(sym)) { 240 + if (mode == def_random) 241 + randomize_choice_values(menu); 242 + continue; 243 } 244 245 + switch (mode) { 246 + case def_yes: 247 + val = yes; 248 + break; 249 + case def_mod: 250 + val = mod; 251 + break; 252 + case def_no: 253 + val = no; 254 + break; 255 + case def_random: 256 + val = no; 257 + cnt = rand() % 100; 258 + if (sym->type == S_TRISTATE) { 259 + if (cnt < pty) 260 + val = yes; 261 + else if (cnt < pty + ptm) 262 + val = mod; 263 + } else if (cnt < pby) { 264 + val = yes; 265 + } 266 + break; 267 + default: 268 + continue; 269 + } 270 + sym->def[S_DEF_USER].tri = val; 271 + sym->flags |= SYMBOL_DEF_USER; 272 } 273 274 sym_clear_all_valid(); 275 } 276 277 static void conf_rewrite_tristates(tristate old_val, tristate new_val) ··· 448 449 static void conf_choice(struct menu *menu) 450 { 451 + struct symbol *def_sym; 452 struct menu *child; 453 + bool is_new = false; 454 455 while (1) { 456 int cnt, def; 457 458 printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); 459 + def_sym = sym_calc_choice(menu); 460 cnt = def = 0; 461 line[0] = 0; 462 for (child = menu->list; child; child = child->next) { ··· 498 printf("%*c", indent, ' '); 499 printf(" %d. %s (%s)", cnt, menu_get_prompt(child), 500 child->sym->name); 501 + if (!sym_has_value(child->sym)) { 502 + is_new = true; 503 printf(" (NEW)"); 504 + } 505 printf("\n"); 506 } 507 printf("%*schoice", indent - 1, ""); ··· 549 print_help(child); 550 continue; 551 } 552 + choice_set_value(menu, child->sym); 553 return; 554 } 555 } ··· 596 597 if (sym_is_choice(sym)) { 598 conf_choice(menu); 599 + return; 600 } 601 602 switch (sym->type) { ··· 630 return; 631 632 sym = menu->sym; 633 + if (sym && !sym_has_value(sym) && sym_is_changeable(sym)) { 634 switch (input_mode) { 635 case listnewconfig: 636 if (sym->name) ··· 849 conf_set_all_new_symbols(def_default); 850 break; 851 case randconfig: 852 + conf_set_all_new_symbols(def_random); 853 break; 854 case defconfig: 855 conf_set_all_new_symbols(def_default);
+38 -89
scripts/kconfig/confdata.c
··· 382 383 def_flags = SYMBOL_DEF << def; 384 for_all_symbols(sym) { 385 - sym->flags |= SYMBOL_CHANGED; 386 sym->flags &= ~(def_flags|SYMBOL_VALID); 387 - if (sym_is_choice(sym)) 388 - sym->flags |= def_flags; 389 switch (sym->type) { 390 case S_INT: 391 case S_HEX: ··· 396 } 397 398 while (getline_stripped(&line, &line_asize, in) != -1) { 399 conf_lineno++; 400 401 if (!line[0]) /* blank line */ ··· 459 if (conf_set_sym_val(sym, def, def_flags, val)) 460 continue; 461 462 - if (sym && sym_is_choice_value(sym)) { 463 - struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 464 - switch (sym->def[def].tri) { 465 - case no: 466 - break; 467 - case mod: 468 - if (cs->def[def].tri == yes) { 469 - conf_warning("%s creates inconsistent choice state", sym->name); 470 - cs->flags &= ~def_flags; 471 - } 472 - break; 473 - case yes: 474 - if (cs->def[def].tri != no) 475 - conf_warning("override: %s changes choice state", sym->name); 476 - cs->def[def].val = sym; 477 - break; 478 - } 479 - cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri); 480 - } 481 } 482 free(line); 483 fclose(in); ··· 477 int conf_read(const char *name) 478 { 479 struct symbol *sym; 480 - int conf_unsaved = 0; 481 482 conf_set_changed(false); 483 ··· 507 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 508 /* no previous value and not saved */ 509 continue; 510 - conf_unsaved++; 511 /* maybe print value in verbose mode... */ 512 } 513 514 - for_all_symbols(sym) { 515 - if (sym_has_value(sym) && !sym_is_choice_value(sym)) { 516 - /* Reset values of generates values, so they'll appear 517 - * as new, if they should become visible, but that 518 - * doesn't quite work if the Kconfig and the saved 519 - * configuration disagree. 520 - */ 521 - if (sym->visible == no && !conf_unsaved) 522 - sym->flags &= ~SYMBOL_DEF_USER; 523 - } 524 - } 525 - 526 - if (conf_warnings || conf_unsaved) 527 conf_set_changed(true); 528 529 return 0; ··· 759 struct menu *choice; 760 761 sym = menu->sym; 762 - if (sym && !sym_is_choice(sym)) { 763 - sym_calc_value(sym); 764 - if (!(sym->flags & SYMBOL_WRITE)) 765 - continue; 766 - sym->flags &= ~SYMBOL_WRITE; 767 - /* If we cannot change the symbol - skip */ 768 - if (!sym_is_changeable(sym)) 769 - continue; 770 - /* If symbol equals to default value - skip */ 771 - if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0) 772 - continue; 773 774 - /* 775 - * If symbol is a choice value and equals to the 776 - * default for a choice - skip. 777 - */ 778 - choice = sym_get_choice_menu(sym); 779 - if (choice) { 780 - struct symbol *ds; 781 782 - ds = sym_choice_default(choice->sym); 783 - if (sym == ds) { 784 - if ((sym->type == S_BOOLEAN) && 785 - sym_get_tristate_value(sym) == yes) 786 - continue; 787 - } 788 - } 789 - print_symbol_for_dotconfig(out, sym); 790 } 791 } 792 fclose(out); 793 return 0; ··· 1112 } 1113 1114 static bool conf_changed; 1115 - static void (*conf_changed_callback)(void); 1116 1117 void conf_set_changed(bool val) 1118 { 1119 - bool changed = conf_changed != val; 1120 1121 conf_changed = val; 1122 - 1123 - if (conf_changed_callback && changed) 1124 - conf_changed_callback(); 1125 } 1126 1127 bool conf_get_changed(void) ··· 1127 return conf_changed; 1128 } 1129 1130 - void conf_set_changed_callback(void (*fn)(void)) 1131 { 1132 conf_changed_callback = fn; 1133 - } 1134 - 1135 - void set_all_choice_values(struct symbol *csym) 1136 - { 1137 - struct property *prop; 1138 - struct symbol *sym; 1139 - struct expr *e; 1140 - 1141 - prop = sym_get_choice_prop(csym); 1142 - 1143 - /* 1144 - * Set all non-assinged choice values to no 1145 - */ 1146 - expr_list_for_each_sym(prop->expr, e, sym) { 1147 - if (!sym_has_value(sym)) 1148 - sym->def[S_DEF_USER].tri = no; 1149 - } 1150 - csym->flags |= SYMBOL_DEF_USER; 1151 - /* clear VALID to get value calculated */ 1152 - csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES); 1153 }
··· 382 383 def_flags = SYMBOL_DEF << def; 384 for_all_symbols(sym) { 385 sym->flags &= ~(def_flags|SYMBOL_VALID); 386 switch (sym->type) { 387 case S_INT: 388 case S_HEX: ··· 399 } 400 401 while (getline_stripped(&line, &line_asize, in) != -1) { 402 + struct menu *choice; 403 + 404 conf_lineno++; 405 406 if (!line[0]) /* blank line */ ··· 460 if (conf_set_sym_val(sym, def, def_flags, val)) 461 continue; 462 463 + /* 464 + * If this is a choice member, give it the highest priority. 465 + * If conflicting CONFIG options are given from an input file, 466 + * the last one wins. 467 + */ 468 + choice = sym_get_choice_menu(sym); 469 + if (choice) 470 + list_move(&sym->choice_link, &choice->choice_members); 471 } 472 free(line); 473 fclose(in); ··· 489 int conf_read(const char *name) 490 { 491 struct symbol *sym; 492 493 conf_set_changed(false); 494 ··· 520 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 521 /* no previous value and not saved */ 522 continue; 523 + conf_set_changed(true); 524 /* maybe print value in verbose mode... */ 525 } 526 527 + if (conf_warnings) 528 conf_set_changed(true); 529 530 return 0; ··· 784 struct menu *choice; 785 786 sym = menu->sym; 787 788 + if (!sym || sym_is_choice(sym)) 789 + continue; 790 791 + sym_calc_value(sym); 792 + if (!(sym->flags & SYMBOL_WRITE)) 793 + continue; 794 + sym->flags &= ~SYMBOL_WRITE; 795 + /* Skip unchangeable symbols */ 796 + if (!sym_is_changeable(sym)) 797 + continue; 798 + /* Skip symbols that are equal to the default */ 799 + if (!strcmp(sym_get_string_value(sym), sym_get_string_default(sym))) 800 + continue; 801 + 802 + /* Skip choice values that are equal to the default */ 803 + choice = sym_get_choice_menu(sym); 804 + if (choice) { 805 + struct symbol *ds; 806 + 807 + ds = sym_choice_default(choice); 808 + if (sym == ds && sym_get_tristate_value(sym) == yes) 809 + continue; 810 } 811 + print_symbol_for_dotconfig(out, sym); 812 } 813 fclose(out); 814 return 0; ··· 1141 } 1142 1143 static bool conf_changed; 1144 + static void (*conf_changed_callback)(bool); 1145 1146 void conf_set_changed(bool val) 1147 { 1148 + if (conf_changed_callback && conf_changed != val) 1149 + conf_changed_callback(val); 1150 1151 conf_changed = val; 1152 } 1153 1154 bool conf_get_changed(void) ··· 1158 return conf_changed; 1159 } 1160 1161 + void conf_set_changed_callback(void (*fn)(bool)) 1162 { 1163 conf_changed_callback = fn; 1164 }
+51 -77
scripts/kconfig/expr.c
··· 90 break; 91 case E_AND: 92 case E_OR: 93 - case E_LIST: 94 e->left.expr = expr_copy(org->left.expr); 95 e->right.expr = expr_copy(org->right.expr); 96 break; ··· 135 136 static int trans_count; 137 138 - #define e1 (*ep1) 139 - #define e2 (*ep2) 140 - 141 /* 142 * expr_eliminate_eq() helper. 143 * ··· 147 { 148 /* Recurse down to leaves */ 149 150 - if (e1->type == type) { 151 - __expr_eliminate_eq(type, &e1->left.expr, &e2); 152 - __expr_eliminate_eq(type, &e1->right.expr, &e2); 153 return; 154 } 155 - if (e2->type == type) { 156 - __expr_eliminate_eq(type, &e1, &e2->left.expr); 157 - __expr_eliminate_eq(type, &e1, &e2->right.expr); 158 return; 159 } 160 161 - /* e1 and e2 are leaves. Compare them. */ 162 163 - if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 164 - e1->left.sym == e2->left.sym && 165 - (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) 166 return; 167 - if (!expr_eq(e1, e2)) 168 return; 169 170 - /* e1 and e2 are equal leaves. Prepare them for elimination. */ 171 172 trans_count++; 173 - expr_free(e1); expr_free(e2); 174 switch (type) { 175 case E_OR: 176 - e1 = expr_alloc_symbol(&symbol_no); 177 - e2 = expr_alloc_symbol(&symbol_no); 178 break; 179 case E_AND: 180 - e1 = expr_alloc_symbol(&symbol_yes); 181 - e2 = expr_alloc_symbol(&symbol_yes); 182 break; 183 default: 184 ; ··· 216 */ 217 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) 218 { 219 - if (!e1 || !e2) 220 return; 221 - switch (e1->type) { 222 case E_OR: 223 case E_AND: 224 - __expr_eliminate_eq(e1->type, ep1, ep2); 225 default: 226 ; 227 } 228 - if (e1->type != e2->type) switch (e2->type) { 229 case E_OR: 230 case E_AND: 231 - __expr_eliminate_eq(e2->type, ep1, ep2); 232 default: 233 ; 234 } 235 - e1 = expr_eliminate_yn(e1); 236 - e2 = expr_eliminate_yn(e2); 237 } 238 - 239 - #undef e1 240 - #undef e2 241 242 /* 243 * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two ··· 279 expr_free(e2); 280 trans_count = old_count; 281 return res; 282 - case E_LIST: 283 case E_RANGE: 284 case E_NONE: 285 /* panic */; ··· 558 */ 559 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) 560 { 561 - #define e1 (*ep1) 562 - #define e2 (*ep2) 563 struct expr *tmp; 564 565 /* Recurse down to leaves */ 566 567 - if (e1->type == type) { 568 - expr_eliminate_dups1(type, &e1->left.expr, &e2); 569 - expr_eliminate_dups1(type, &e1->right.expr, &e2); 570 return; 571 } 572 - if (e2->type == type) { 573 - expr_eliminate_dups1(type, &e1, &e2->left.expr); 574 - expr_eliminate_dups1(type, &e1, &e2->right.expr); 575 return; 576 } 577 578 - /* e1 and e2 are leaves. Compare and process them. */ 579 580 - if (e1 == e2) 581 return; 582 583 - switch (e1->type) { 584 case E_OR: case E_AND: 585 - expr_eliminate_dups1(e1->type, &e1, &e1); 586 default: 587 ; 588 } 589 590 switch (type) { 591 case E_OR: 592 - tmp = expr_join_or(e1, e2); 593 if (tmp) { 594 - expr_free(e1); expr_free(e2); 595 - e1 = expr_alloc_symbol(&symbol_no); 596 - e2 = tmp; 597 trans_count++; 598 } 599 break; 600 case E_AND: 601 - tmp = expr_join_and(e1, e2); 602 if (tmp) { 603 - expr_free(e1); expr_free(e2); 604 - e1 = expr_alloc_symbol(&symbol_yes); 605 - e2 = tmp; 606 trans_count++; 607 } 608 break; 609 default: 610 ; 611 } 612 - #undef e1 613 - #undef e2 614 } 615 616 /* ··· 627 return e; 628 629 oldcount = trans_count; 630 - while (1) { 631 trans_count = 0; 632 switch (e->type) { 633 case E_OR: case E_AND: ··· 635 default: 636 ; 637 } 638 - if (!trans_count) 639 - /* No simplifications done in this pass. We're done */ 640 - break; 641 e = expr_eliminate_yn(e); 642 - } 643 trans_count = oldcount; 644 return e; 645 } ··· 661 case E_LTH: 662 case E_UNEQUAL: 663 case E_SYMBOL: 664 - case E_LIST: 665 break; 666 default: 667 e->left.expr = expr_transform(e->left.expr); ··· 931 break; 932 case E_SYMBOL: 933 return expr_alloc_comp(type, e->left.sym, sym); 934 - case E_LIST: 935 case E_RANGE: 936 case E_NONE: 937 /* panic */; ··· 1066 case E_GTH: 1067 if (t2 == E_EQUAL || t2 == E_UNEQUAL) 1068 return 1; 1069 case E_EQUAL: 1070 case E_UNEQUAL: 1071 if (t2 == E_NOT) 1072 return 1; 1073 case E_NOT: 1074 if (t2 == E_AND) 1075 return 1; 1076 case E_AND: 1077 if (t2 == E_OR) 1078 return 1; 1079 - case E_OR: 1080 - if (t2 == E_LIST) 1081 - return 1; 1082 - case E_LIST: 1083 - if (t2 == 0) 1084 - return 1; 1085 default: 1086 - return -1; 1087 } 1088 return 0; 1089 } 1090 1091 - void expr_print(struct expr *e, 1092 void (*fn)(void *, struct symbol *, const char *), 1093 void *data, int prevtoken) 1094 { ··· 1152 fn(data, NULL, " && "); 1153 expr_print(e->right.expr, fn, data, E_AND); 1154 break; 1155 - case E_LIST: 1156 - fn(data, e->right.sym, e->right.sym->name); 1157 - if (e->left.expr) { 1158 - fn(data, NULL, " ^ "); 1159 - expr_print(e->left.expr, fn, data, E_LIST); 1160 - } 1161 - break; 1162 case E_RANGE: 1163 fn(data, NULL, "["); 1164 fn(data, e->left.sym, e->left.sym->name); ··· 1211 str_printf(gs, " [=%s]", sym_str); 1212 } 1213 1214 - void expr_gstr_print(struct expr *e, struct gstr *gs) 1215 { 1216 expr_print(e, expr_print_gstr_helper, gs, E_NONE); 1217 }
··· 90 break; 91 case E_AND: 92 case E_OR: 93 e->left.expr = expr_copy(org->left.expr); 94 e->right.expr = expr_copy(org->right.expr); 95 break; ··· 136 137 static int trans_count; 138 139 /* 140 * expr_eliminate_eq() helper. 141 * ··· 151 { 152 /* Recurse down to leaves */ 153 154 + if ((*ep1)->type == type) { 155 + __expr_eliminate_eq(type, &(*ep1)->left.expr, ep2); 156 + __expr_eliminate_eq(type, &(*ep1)->right.expr, ep2); 157 return; 158 } 159 + if ((*ep2)->type == type) { 160 + __expr_eliminate_eq(type, ep1, &(*ep2)->left.expr); 161 + __expr_eliminate_eq(type, ep1, &(*ep2)->right.expr); 162 return; 163 } 164 165 + /* *ep1 and *ep2 are leaves. Compare them. */ 166 167 + if ((*ep1)->type == E_SYMBOL && (*ep2)->type == E_SYMBOL && 168 + (*ep1)->left.sym == (*ep2)->left.sym && 169 + ((*ep1)->left.sym == &symbol_yes || (*ep1)->left.sym == &symbol_no)) 170 return; 171 + if (!expr_eq(*ep1, *ep2)) 172 return; 173 174 + /* *ep1 and *ep2 are equal leaves. Prepare them for elimination. */ 175 176 trans_count++; 177 + expr_free(*ep1); expr_free(*ep2); 178 switch (type) { 179 case E_OR: 180 + *ep1 = expr_alloc_symbol(&symbol_no); 181 + *ep2 = expr_alloc_symbol(&symbol_no); 182 break; 183 case E_AND: 184 + *ep1 = expr_alloc_symbol(&symbol_yes); 185 + *ep2 = expr_alloc_symbol(&symbol_yes); 186 break; 187 default: 188 ; ··· 220 */ 221 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) 222 { 223 + if (!*ep1 || !*ep2) 224 return; 225 + switch ((*ep1)->type) { 226 case E_OR: 227 case E_AND: 228 + __expr_eliminate_eq((*ep1)->type, ep1, ep2); 229 default: 230 ; 231 } 232 + if ((*ep1)->type != (*ep2)->type) switch ((*ep2)->type) { 233 case E_OR: 234 case E_AND: 235 + __expr_eliminate_eq((*ep2)->type, ep1, ep2); 236 default: 237 ; 238 } 239 + *ep1 = expr_eliminate_yn(*ep1); 240 + *ep2 = expr_eliminate_yn(*ep2); 241 } 242 243 /* 244 * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two ··· 286 expr_free(e2); 287 trans_count = old_count; 288 return res; 289 case E_RANGE: 290 case E_NONE: 291 /* panic */; ··· 566 */ 567 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) 568 { 569 struct expr *tmp; 570 571 /* Recurse down to leaves */ 572 573 + if ((*ep1)->type == type) { 574 + expr_eliminate_dups1(type, &(*ep1)->left.expr, ep2); 575 + expr_eliminate_dups1(type, &(*ep1)->right.expr, ep2); 576 return; 577 } 578 + if ((*ep2)->type == type) { 579 + expr_eliminate_dups1(type, ep1, &(*ep2)->left.expr); 580 + expr_eliminate_dups1(type, ep1, &(*ep2)->right.expr); 581 return; 582 } 583 584 + /* *ep1 and *ep2 are leaves. Compare and process them. */ 585 586 + if (*ep1 == *ep2) 587 return; 588 589 + switch ((*ep1)->type) { 590 case E_OR: case E_AND: 591 + expr_eliminate_dups1((*ep1)->type, ep1, ep1); 592 default: 593 ; 594 } 595 596 switch (type) { 597 case E_OR: 598 + tmp = expr_join_or(*ep1, *ep2); 599 if (tmp) { 600 + expr_free(*ep1); expr_free(*ep2); 601 + *ep1 = expr_alloc_symbol(&symbol_no); 602 + *ep2 = tmp; 603 trans_count++; 604 } 605 break; 606 case E_AND: 607 + tmp = expr_join_and(*ep1, *ep2); 608 if (tmp) { 609 + expr_free(*ep1); expr_free(*ep2); 610 + *ep1 = expr_alloc_symbol(&symbol_yes); 611 + *ep2 = tmp; 612 trans_count++; 613 } 614 break; 615 default: 616 ; 617 } 618 } 619 620 /* ··· 639 return e; 640 641 oldcount = trans_count; 642 + do { 643 trans_count = 0; 644 switch (e->type) { 645 case E_OR: case E_AND: ··· 647 default: 648 ; 649 } 650 e = expr_eliminate_yn(e); 651 + } while (trans_count); /* repeat until we get no more simplifications */ 652 trans_count = oldcount; 653 return e; 654 } ··· 676 case E_LTH: 677 case E_UNEQUAL: 678 case E_SYMBOL: 679 break; 680 default: 681 e->left.expr = expr_transform(e->left.expr); ··· 947 break; 948 case E_SYMBOL: 949 return expr_alloc_comp(type, e->left.sym, sym); 950 case E_RANGE: 951 case E_NONE: 952 /* panic */; ··· 1083 case E_GTH: 1084 if (t2 == E_EQUAL || t2 == E_UNEQUAL) 1085 return 1; 1086 + /* fallthrough */ 1087 case E_EQUAL: 1088 case E_UNEQUAL: 1089 if (t2 == E_NOT) 1090 return 1; 1091 + /* fallthrough */ 1092 case E_NOT: 1093 if (t2 == E_AND) 1094 return 1; 1095 + /* fallthrough */ 1096 case E_AND: 1097 if (t2 == E_OR) 1098 return 1; 1099 + /* fallthrough */ 1100 default: 1101 + break; 1102 } 1103 return 0; 1104 } 1105 1106 + void expr_print(const struct expr *e, 1107 void (*fn)(void *, struct symbol *, const char *), 1108 void *data, int prevtoken) 1109 { ··· 1171 fn(data, NULL, " && "); 1172 expr_print(e->right.expr, fn, data, E_AND); 1173 break; 1174 case E_RANGE: 1175 fn(data, NULL, "["); 1176 fn(data, e->left.sym, e->left.sym->name); ··· 1237 str_printf(gs, " [=%s]", sym_str); 1238 } 1239 1240 + void expr_gstr_print(const struct expr *e, struct gstr *gs) 1241 { 1242 expr_print(e, expr_print_gstr_helper, gs, E_NONE); 1243 }
+13 -16
scripts/kconfig/expr.h
··· 12 13 #include <assert.h> 14 #include <stdio.h> 15 - #include "list_types.h" 16 #ifndef __cplusplus 17 #include <stdbool.h> 18 #endif 19 20 - #include "list_types.h" 21 22 typedef enum tristate { 23 no, mod, yes ··· 25 enum expr_type { 26 E_NONE, E_OR, E_AND, E_NOT, 27 E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ, 28 - E_LIST, E_SYMBOL, E_RANGE 29 }; 30 31 union expr_data { ··· 41 #define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) 42 #define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) 43 #define EXPR_NOT(dep) (2-(dep)) 44 - 45 - #define expr_list_for_each_sym(l, e, s) \ 46 - for (e = (l); e && (s = e->right.sym); e = e->left.expr) 47 48 struct expr_value { 49 struct expr *expr; ··· 69 * Represents a configuration symbol. 70 * 71 * Choices are represented as a special kind of symbol with null name. 72 */ 73 struct symbol { 74 /* link node for the hash table */ ··· 108 /* config entries associated with this symbol */ 109 struct list_head menus; 110 111 /* SYMBOL_* flags */ 112 int flags; 113 ··· 130 131 #define SYMBOL_CONST 0x0001 /* symbol is const */ 132 #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ 133 - #define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */ 134 #define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ 135 #define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ 136 - #define SYMBOL_CHANGED 0x0400 /* ? */ 137 #define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */ 138 #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ 139 #define SYMBOL_WARNED 0x8000 /* warning has been issued */ ··· 142 #define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ 143 #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ 144 #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ 145 - 146 - /* choice values need to be set before calculating this symbol value */ 147 - #define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000 148 149 #define SYMBOL_MAXLENGTH 256 150 ··· 165 P_COMMENT, /* text associated with a comment */ 166 P_MENU, /* prompt associated with a menu or menuconfig symbol */ 167 P_DEFAULT, /* default y */ 168 - P_CHOICE, /* choice value */ 169 P_SELECT, /* select BAR */ 170 P_IMPLY, /* imply BAR */ 171 P_RANGE, /* range 7..100 (for a symbol) */ ··· 178 struct expr_value visible; 179 struct expr *expr; /* the optional conditional part of the property */ 180 struct menu *menu; /* the menu the property are associated with 181 - * valid for: P_SELECT, P_RANGE, P_CHOICE, 182 * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ 183 const char *filename; /* what file was this property defined */ 184 int lineno; /* what lineno was this property defined */ ··· 188 for (st = sym->prop; st; st = st->next) \ 189 if (st->type == (tok)) 190 #define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) 191 - #define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE) 192 #define for_all_prompts(sym, st) \ 193 for (st = sym->prop; st; st = st->next) \ 194 if (st->text) ··· 197 * for all front ends). Each symbol, menu, etc. defined in the Kconfig files 198 * gets a node. A symbol defined in multiple locations gets one node at each 199 * location. 200 */ 201 struct menu { 202 /* The next menu node at the same level */ ··· 217 struct symbol *sym; 218 219 struct list_head link; /* link to symbol::menus */ 220 221 /* 222 * The prompt associated with the node. This holds the prompt for a ··· 289 290 void expr_fprint(struct expr *e, FILE *out); 291 struct gstr; /* forward */ 292 - void expr_gstr_print(struct expr *e, struct gstr *gs); 293 void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, 294 tristate pr_type, const char *title); 295 296 - static inline int expr_is_yes(struct expr *e) 297 { 298 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); 299 }
··· 12 13 #include <assert.h> 14 #include <stdio.h> 15 #ifndef __cplusplus 16 #include <stdbool.h> 17 #endif 18 19 + #include <list_types.h> 20 21 typedef enum tristate { 22 no, mod, yes ··· 26 enum expr_type { 27 E_NONE, E_OR, E_AND, E_NOT, 28 E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ, 29 + E_SYMBOL, E_RANGE 30 }; 31 32 union expr_data { ··· 42 #define EXPR_OR(dep1, dep2) (((dep1)>(dep2))?(dep1):(dep2)) 43 #define EXPR_AND(dep1, dep2) (((dep1)<(dep2))?(dep1):(dep2)) 44 #define EXPR_NOT(dep) (2-(dep)) 45 46 struct expr_value { 47 struct expr *expr; ··· 73 * Represents a configuration symbol. 74 * 75 * Choices are represented as a special kind of symbol with null name. 76 + * 77 + * @choice_link: linked to menu::choice_members 78 */ 79 struct symbol { 80 /* link node for the hash table */ ··· 110 /* config entries associated with this symbol */ 111 struct list_head menus; 112 113 + struct list_head choice_link; 114 + 115 /* SYMBOL_* flags */ 116 int flags; 117 ··· 130 131 #define SYMBOL_CONST 0x0001 /* symbol is const */ 132 #define SYMBOL_CHECK 0x0008 /* used during dependency checking */ 133 #define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */ 134 #define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */ 135 #define SYMBOL_WRITTEN 0x0800 /* track info to avoid double-write to .config */ 136 #define SYMBOL_CHECKED 0x2000 /* used during dependency checking */ 137 #define SYMBOL_WARNED 0x8000 /* warning has been issued */ ··· 144 #define SYMBOL_DEF_AUTO 0x20000 /* symbol.def[S_DEF_AUTO] is valid */ 145 #define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */ 146 #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ 147 148 #define SYMBOL_MAXLENGTH 256 149 ··· 170 P_COMMENT, /* text associated with a comment */ 171 P_MENU, /* prompt associated with a menu or menuconfig symbol */ 172 P_DEFAULT, /* default y */ 173 P_SELECT, /* select BAR */ 174 P_IMPLY, /* imply BAR */ 175 P_RANGE, /* range 7..100 (for a symbol) */ ··· 184 struct expr_value visible; 185 struct expr *expr; /* the optional conditional part of the property */ 186 struct menu *menu; /* the menu the property are associated with 187 + * valid for: P_SELECT, P_RANGE, 188 * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ 189 const char *filename; /* what file was this property defined */ 190 int lineno; /* what lineno was this property defined */ ··· 194 for (st = sym->prop; st; st = st->next) \ 195 if (st->type == (tok)) 196 #define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT) 197 #define for_all_prompts(sym, st) \ 198 for (st = sym->prop; st; st = st->next) \ 199 if (st->text) ··· 204 * for all front ends). Each symbol, menu, etc. defined in the Kconfig files 205 * gets a node. A symbol defined in multiple locations gets one node at each 206 * location. 207 + * 208 + * @choice_members: list of choice members with priority. 209 */ 210 struct menu { 211 /* The next menu node at the same level */ ··· 222 struct symbol *sym; 223 224 struct list_head link; /* link to symbol::menus */ 225 + 226 + struct list_head choice_members; 227 228 /* 229 * The prompt associated with the node. This holds the prompt for a ··· 292 293 void expr_fprint(struct expr *e, FILE *out); 294 struct gstr; /* forward */ 295 + void expr_gstr_print(const struct expr *e, struct gstr *gs); 296 void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, 297 tristate pr_type, const char *title); 298 299 + static inline int expr_is_yes(const struct expr *e) 300 { 301 return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes); 302 }
+2
scripts/kconfig/gconf-cfg.sh
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 4 cflags=$1 5 libs=$2 6
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 4 + set -eu 5 + 6 cflags=$1 7 libs=$2 8
+10 -16
scripts/kconfig/gconf.c
··· 65 static void display_tree(struct menu *menu); 66 static void display_tree_part(void); 67 static void update_tree(struct menu *src, GtkTreeIter * dst); 68 - static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row); 69 - static gchar **fill_row(struct menu *menu); 70 - static void conf_changed(void); 71 72 static void replace_button_icon(GladeXML *xml, GdkDrawable *window, 73 GtkStyle *style, gchar *btn_name, gchar **xpm) ··· 82 image = gtk_image_new_from_pixmap(pixmap, mask); 83 gtk_widget_show(image); 84 gtk_tool_button_set_icon_widget(button, image); 85 } 86 87 /* Main Window Initialization */ ··· 1054 1055 if (sym_is_choice(sym)) { // parse childs for getting final value 1056 struct menu *child; 1057 - struct symbol *def_sym = sym_get_choice_value(sym); 1058 struct menu *def_menu = NULL; 1059 1060 for (child = menu->list; child; child = child->next) { ··· 1067 row[COL_VALUE] = 1068 g_strdup(menu_get_prompt(def_menu)); 1069 1070 - if (sym_get_type(sym) == S_BOOLEAN) { 1071 - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); 1072 - return row; 1073 - } 1074 } 1075 - if (sym->flags & SYMBOL_CHOICEVAL) 1076 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); 1077 1078 stype = sym_get_type(sym); ··· 1447 gtk_main(); 1448 1449 return 0; 1450 - } 1451 - 1452 - static void conf_changed(void) 1453 - { 1454 - bool changed = conf_get_changed(); 1455 - gtk_widget_set_sensitive(save_btn, changed); 1456 - gtk_widget_set_sensitive(save_menu_item, changed); 1457 }
··· 65 static void display_tree(struct menu *menu); 66 static void display_tree_part(void); 67 static void update_tree(struct menu *src, GtkTreeIter * dst); 68 69 static void replace_button_icon(GladeXML *xml, GdkDrawable *window, 70 GtkStyle *style, gchar *btn_name, gchar **xpm) ··· 85 image = gtk_image_new_from_pixmap(pixmap, mask); 86 gtk_widget_show(image); 87 gtk_tool_button_set_icon_widget(button, image); 88 + } 89 + 90 + static void conf_changed(bool dirty) 91 + { 92 + gtk_widget_set_sensitive(save_btn, dirty); 93 + gtk_widget_set_sensitive(save_menu_item, dirty); 94 } 95 96 /* Main Window Initialization */ ··· 1051 1052 if (sym_is_choice(sym)) { // parse childs for getting final value 1053 struct menu *child; 1054 + struct symbol *def_sym = sym_calc_choice(menu); 1055 struct menu *def_menu = NULL; 1056 1057 for (child = menu->list; child; child = child->next) { ··· 1064 row[COL_VALUE] = 1065 g_strdup(menu_get_prompt(def_menu)); 1066 1067 + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); 1068 + return row; 1069 } 1070 + if (sym_is_choice_value(sym)) 1071 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); 1072 1073 stype = sym_get_type(sym); ··· 1446 gtk_main(); 1447 1448 return 0; 1449 }
scripts/kconfig/hashtable.h scripts/include/hashtable.h
+1 -1
scripts/kconfig/internal.h
··· 2 #ifndef INTERNAL_H 3 #define INTERNAL_H 4 5 - #include "hashtable.h" 6 7 #define SYMBOL_HASHSIZE (1U << 14) 8
··· 2 #ifndef INTERNAL_H 3 #define INTERNAL_H 4 5 + #include <hashtable.h> 6 7 #define SYMBOL_HASHSIZE (1U << 14) 8
+53
scripts/kconfig/list.h scripts/include/list.h
··· 128 } 129 130 /** 131 * list_is_head - tests whether @list is the list @head 132 * @list: the entry to test 133 * @head: the head of the list ··· 190 list_entry((ptr)->next, type, member) 191 192 /** 193 * list_next_entry - get the next element in list 194 * @pos: the type * to cursor 195 * @member: the name of the list_head within the struct. 196 */ 197 #define list_next_entry(pos, member) \ 198 list_entry((pos)->member.next, typeof(*(pos)), member) 199 200 /** 201 * list_entry_is_head - test if the entry points to the head of the list ··· 235 for (pos = list_first_entry(head, typeof(*pos), member); \ 236 !list_entry_is_head(pos, head, member); \ 237 pos = list_next_entry(pos, member)) 238 239 /** 240 * list_for_each_entry_safe - iterate over list of given type. Safe against removal of list entry
··· 128 } 129 130 /** 131 + * list_move - delete from one list and add as another's head 132 + * @list: the entry to move 133 + * @head: the head that will precede our entry 134 + */ 135 + static inline void list_move(struct list_head *list, struct list_head *head) 136 + { 137 + __list_del_entry(list); 138 + list_add(list, head); 139 + } 140 + 141 + /** 142 + * list_move_tail - delete from one list and add as another's tail 143 + * @list: the entry to move 144 + * @head: the head that will follow our entry 145 + */ 146 + static inline void list_move_tail(struct list_head *list, 147 + struct list_head *head) 148 + { 149 + __list_del_entry(list); 150 + list_add_tail(list, head); 151 + } 152 + 153 + /** 154 * list_is_head - tests whether @list is the list @head 155 * @list: the entry to test 156 * @head: the head of the list ··· 167 list_entry((ptr)->next, type, member) 168 169 /** 170 + * list_last_entry - get the last element from a list 171 + * @ptr: the list head to take the element from. 172 + * @type: the type of the struct this is embedded in. 173 + * @member: the name of the list_head within the struct. 174 + * 175 + * Note, that list is expected to be not empty. 176 + */ 177 + #define list_last_entry(ptr, type, member) \ 178 + list_entry((ptr)->prev, type, member) 179 + 180 + /** 181 * list_next_entry - get the next element in list 182 * @pos: the type * to cursor 183 * @member: the name of the list_head within the struct. 184 */ 185 #define list_next_entry(pos, member) \ 186 list_entry((pos)->member.next, typeof(*(pos)), member) 187 + 188 + /** 189 + * list_prev_entry - get the prev element in list 190 + * @pos: the type * to cursor 191 + * @member: the name of the list_head within the struct. 192 + */ 193 + #define list_prev_entry(pos, member) \ 194 + list_entry((pos)->member.prev, typeof(*(pos)), member) 195 196 /** 197 * list_entry_is_head - test if the entry points to the head of the list ··· 193 for (pos = list_first_entry(head, typeof(*pos), member); \ 194 !list_entry_is_head(pos, head, member); \ 195 pos = list_next_entry(pos, member)) 196 + 197 + /** 198 + * list_for_each_entry_reverse - iterate backwards over list of given type. 199 + * @pos: the type * to use as a loop cursor. 200 + * @head: the head for your list. 201 + * @member: the name of the list_head within the struct. 202 + */ 203 + #define list_for_each_entry_reverse(pos, head, member) \ 204 + for (pos = list_last_entry(head, typeof(*pos), member); \ 205 + !list_entry_is_head(pos, head, member); \ 206 + pos = list_prev_entry(pos, member)) 207 208 /** 209 * list_for_each_entry_safe - iterate over list of given type. Safe against removal of list entry
scripts/kconfig/list_types.h scripts/include/list_types.h
+13 -21
scripts/kconfig/lkc.h
··· 40 /* confdata.c */ 41 extern struct gstr autoconf_cmd; 42 const char *conf_get_configname(void); 43 - void set_all_choice_values(struct symbol *csym); 44 45 /* confdata.c and expr.c */ 46 static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) ··· 75 void str_free(struct gstr *gs); 76 void str_append(struct gstr *gs, const char *s); 77 void str_printf(struct gstr *gs, const char *fmt, ...); 78 - char *str_get(struct gstr *gs); 79 80 /* menu.c */ 81 struct menu *menu_next(struct menu *menu, struct menu *root); ··· 84 #define menu_for_each_entry(menu) \ 85 menu_for_each_sub_entry(menu, &rootmenu) 86 void _menu_init(void); 87 - void menu_warn(struct menu *menu, const char *fmt, ...); 88 struct menu *menu_add_menu(void); 89 void menu_end_menu(void); 90 void menu_add_entry(struct symbol *sym); 91 void menu_add_dep(struct expr *dep); 92 void menu_add_visibility(struct expr *dep); 93 - struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); 94 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); 95 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); 96 void menu_finalize(void); ··· 101 102 bool menu_is_empty(struct menu *menu); 103 bool menu_is_visible(struct menu *menu); 104 - bool menu_has_prompt(struct menu *menu); 105 - const char *menu_get_prompt(struct menu *menu); 106 struct menu *menu_get_parent_menu(struct menu *menu); 107 int get_jump_key_char(void); 108 struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); ··· 110 111 /* symbol.c */ 112 void sym_clear_all_valid(void); 113 - struct symbol *sym_choice_default(struct symbol *sym); 114 struct property *sym_get_range_prop(struct symbol *sym); 115 const char *sym_get_string_default(struct symbol *sym); 116 struct symbol *sym_check_deps(struct symbol *sym); 117 - struct symbol *prop_get_symbol(struct property *prop); 118 119 - static inline tristate sym_get_tristate_value(struct symbol *sym) 120 { 121 return sym->curr.tri; 122 } 123 124 - 125 - static inline struct symbol *sym_get_choice_value(struct symbol *sym) 126 - { 127 - return (struct symbol *)sym->curr.val; 128 - } 129 - 130 - static inline bool sym_is_choice(struct symbol *sym) 131 { 132 /* A choice is a symbol with no name */ 133 return sym->name == NULL; 134 } 135 136 - static inline bool sym_is_choice_value(struct symbol *sym) 137 - { 138 - return sym->flags & SYMBOL_CHOICEVAL ? true : false; 139 - } 140 141 - static inline bool sym_has_value(struct symbol *sym) 142 { 143 return sym->flags & SYMBOL_DEF_USER ? true : false; 144 }
··· 40 /* confdata.c */ 41 extern struct gstr autoconf_cmd; 42 const char *conf_get_configname(void); 43 44 /* confdata.c and expr.c */ 45 static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) ··· 76 void str_free(struct gstr *gs); 77 void str_append(struct gstr *gs, const char *s); 78 void str_printf(struct gstr *gs, const char *fmt, ...); 79 + char *str_get(const struct gstr *gs); 80 81 /* menu.c */ 82 struct menu *menu_next(struct menu *menu, struct menu *root); ··· 85 #define menu_for_each_entry(menu) \ 86 menu_for_each_sub_entry(menu, &rootmenu) 87 void _menu_init(void); 88 + void menu_warn(const struct menu *menu, const char *fmt, ...); 89 struct menu *menu_add_menu(void); 90 void menu_end_menu(void); 91 void menu_add_entry(struct symbol *sym); 92 void menu_add_dep(struct expr *dep); 93 void menu_add_visibility(struct expr *dep); 94 + struct property *menu_add_prompt(enum prop_type type, const char *prompt, 95 + struct expr *dep); 96 void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); 97 void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); 98 void menu_finalize(void); ··· 101 102 bool menu_is_empty(struct menu *menu); 103 bool menu_is_visible(struct menu *menu); 104 + bool menu_has_prompt(const struct menu *menu); 105 + const char *menu_get_prompt(const struct menu *menu); 106 struct menu *menu_get_parent_menu(struct menu *menu); 107 int get_jump_key_char(void); 108 struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head); ··· 110 111 /* symbol.c */ 112 void sym_clear_all_valid(void); 113 + struct symbol *sym_choice_default(struct menu *choice); 114 + struct symbol *sym_calc_choice(struct menu *choice); 115 struct property *sym_get_range_prop(struct symbol *sym); 116 const char *sym_get_string_default(struct symbol *sym); 117 struct symbol *sym_check_deps(struct symbol *sym); 118 + struct symbol *prop_get_symbol(const struct property *prop); 119 120 + static inline tristate sym_get_tristate_value(const struct symbol *sym) 121 { 122 return sym->curr.tri; 123 } 124 125 + static inline bool sym_is_choice(const struct symbol *sym) 126 { 127 /* A choice is a symbol with no name */ 128 return sym->name == NULL; 129 } 130 131 + bool sym_is_choice_value(const struct symbol *sym); 132 133 + static inline bool sym_has_value(const struct symbol *sym) 134 { 135 return sym->flags & SYMBOL_DEF_USER ? true : false; 136 }
+9 -7
scripts/kconfig/lkc_proto.h
··· 13 int conf_write_autoconf(int overwrite); 14 void conf_set_changed(bool val); 15 bool conf_get_changed(void); 16 - void conf_set_changed_callback(void (*fn)(void)); 17 void conf_set_message_callback(void (*fn)(const char *s)); 18 bool conf_errors(void); 19 ··· 25 const char * sym_type_name(enum symbol_type type); 26 void sym_calc_value(struct symbol *sym); 27 bool sym_dep_errors(void); 28 - enum symbol_type sym_get_type(struct symbol *sym); 29 - bool sym_tristate_within_range(struct symbol *sym,tristate tri); 30 bool sym_set_tristate_value(struct symbol *sym,tristate tri); 31 tristate sym_toggle_tristate_value(struct symbol *sym); 32 bool sym_string_valid(struct symbol *sym, const char *newval); 33 bool sym_string_within_range(struct symbol *sym, const char *str); 34 bool sym_set_string_value(struct symbol *sym, const char *newval); 35 - bool sym_is_changeable(struct symbol *sym); 36 - struct property * sym_get_choice_prop(struct symbol *sym); 37 - struct menu *sym_get_choice_menu(struct symbol *sym); 38 const char * sym_get_string_value(struct symbol *sym); 39 40 const char * prop_get_type_name(enum prop_type type); 41 42 /* expr.c */ 43 - void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); 44 45 #endif /* LKC_PROTO_H */
··· 13 int conf_write_autoconf(int overwrite); 14 void conf_set_changed(bool val); 15 bool conf_get_changed(void); 16 + void conf_set_changed_callback(void (*fn)(bool)); 17 void conf_set_message_callback(void (*fn)(const char *s)); 18 bool conf_errors(void); 19 ··· 25 const char * sym_type_name(enum symbol_type type); 26 void sym_calc_value(struct symbol *sym); 27 bool sym_dep_errors(void); 28 + enum symbol_type sym_get_type(const struct symbol *sym); 29 + bool sym_tristate_within_range(const struct symbol *sym, tristate tri); 30 bool sym_set_tristate_value(struct symbol *sym,tristate tri); 31 + void choice_set_value(struct menu *choice, struct symbol *sym); 32 tristate sym_toggle_tristate_value(struct symbol *sym); 33 bool sym_string_valid(struct symbol *sym, const char *newval); 34 bool sym_string_within_range(struct symbol *sym, const char *str); 35 bool sym_set_string_value(struct symbol *sym, const char *newval); 36 + bool sym_is_changeable(const struct symbol *sym); 37 + struct menu *sym_get_choice_menu(const struct symbol *sym); 38 const char * sym_get_string_value(struct symbol *sym); 39 40 const char * prop_get_type_name(enum prop_type type); 41 42 /* expr.c */ 43 + void expr_print(const struct expr *e, 44 + void (*fn)(void *, struct symbol *, const char *), 45 + void *data, int prevtoken); 46 47 #endif /* LKC_PROTO_H */
+2
scripts/kconfig/mconf-cfg.sh
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 4 cflags=$1 5 libs=$2 6
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 4 + set -eu 5 + 6 cflags=$1 7 libs=$2 8
+12 -26
scripts/kconfig/mconf.c
··· 19 #include <signal.h> 20 #include <unistd.h> 21 22 - #include "list.h" 23 #include "lkc.h" 24 #include "lxdialog/dialog.h" 25 #include "mnconf-common.h" ··· 514 515 type = sym_get_type(sym); 516 if (sym_is_choice(sym)) { 517 - struct symbol *def_sym = sym_get_choice_value(sym); 518 struct menu *def_menu = NULL; 519 520 child_count++; ··· 523 def_menu = child; 524 } 525 526 - val = sym_get_tristate_value(sym); 527 - if (sym_is_changeable(sym)) { 528 - switch (val) { 529 - case yes: ch = '*'; break; 530 - case mod: ch = 'M'; break; 531 - default: ch = ' '; break; 532 - } 533 - item_make("<%c>", ch); 534 - item_set_tag('t'); 535 - item_set_data(menu); 536 - } else { 537 - item_make(" "); 538 - item_set_tag(def_menu ? 't' : ':'); 539 - item_set_data(menu); 540 - } 541 542 item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); 543 - if (val == yes) { 544 - if (def_menu) 545 - item_add_str(" (%s) --->", menu_get_prompt(def_menu)); 546 - return; 547 - } 548 } else { 549 if (menu == current_menu) { 550 item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); ··· 600 struct menu *child; 601 struct symbol *active; 602 603 - active = sym_get_choice_value(menu->sym); 604 while (1) { 605 int res; 606 int selected; ··· 619 item_set_data(child); 620 if (child->sym == active) 621 item_set_selected(1); 622 - if (child->sym == sym_get_choice_value(menu->sym)) 623 item_set_tag('X'); 624 } 625 dialog_clear(); ··· 636 if (!child->sym) 637 break; 638 639 - sym_set_tristate_value(child->sym, yes); 640 } 641 return; 642 case 1: ··· 800 conf(submenu, NULL); 801 break; 802 case 't': 803 - if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) 804 conf_choice(submenu); 805 else if (submenu->prompt->type == P_MENU) 806 conf(submenu, NULL);
··· 19 #include <signal.h> 20 #include <unistd.h> 21 22 + #include <list.h> 23 #include "lkc.h" 24 #include "lxdialog/dialog.h" 25 #include "mnconf-common.h" ··· 514 515 type = sym_get_type(sym); 516 if (sym_is_choice(sym)) { 517 + struct symbol *def_sym = sym_calc_choice(menu); 518 struct menu *def_menu = NULL; 519 520 child_count++; ··· 523 def_menu = child; 524 } 525 526 + item_make(" "); 527 + item_set_tag(def_menu ? 't' : ':'); 528 + item_set_data(menu); 529 530 item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); 531 + if (def_menu) 532 + item_add_str(" (%s) --->", menu_get_prompt(def_menu)); 533 + return; 534 } else { 535 if (menu == current_menu) { 536 item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); ··· 614 struct menu *child; 615 struct symbol *active; 616 617 + active = sym_calc_choice(menu); 618 while (1) { 619 int res; 620 int selected; ··· 633 item_set_data(child); 634 if (child->sym == active) 635 item_set_selected(1); 636 + if (child->sym == sym_calc_choice(menu)) 637 item_set_tag('X'); 638 } 639 dialog_clear(); ··· 650 if (!child->sym) 651 break; 652 653 + choice_set_value(menu, child->sym); 654 } 655 return; 656 case 1: ··· 814 conf(submenu, NULL); 815 break; 816 case 't': 817 + if (sym_is_choice(sym)) 818 conf_choice(submenu); 819 else if (submenu->prompt->type == P_MENU) 820 conf(submenu, NULL);
+13 -98
scripts/kconfig/menu.c
··· 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include "lkc.h" 12 #include "internal.h" 13 - #include "list.h" 14 15 static const char nohelp_text[] = "There is no help available for this option."; 16 ··· 38 return menu->next; 39 } 40 41 - void menu_warn(struct menu *menu, const char *fmt, ...) 42 { 43 va_list ap; 44 va_start(ap, fmt); ··· 48 va_end(ap); 49 } 50 51 - static void prop_warn(struct property *prop, const char *fmt, ...) 52 { 53 va_list ap; 54 va_start(ap, fmt); ··· 175 return prop; 176 } 177 178 - struct property *menu_add_prompt(enum prop_type type, char *prompt, 179 struct expr *dep) 180 { 181 struct property *prop = menu_add_prop(type, NULL, dep); ··· 306 struct menu *menu, *last_menu; 307 struct symbol *sym; 308 struct property *prop; 309 - struct expr *parentdep, *basedep, *dep, *dep2, **ep; 310 311 sym = parent->sym; 312 if (parent->list) { ··· 314 * This menu node has children. We (recursively) process them 315 * and propagate parent dependencies before moving on. 316 */ 317 - 318 - bool is_choice = false; 319 - 320 - if (sym && sym_is_choice(sym)) 321 - is_choice = true; 322 - 323 - if (is_choice) { 324 - if (sym->type == S_UNKNOWN) { 325 - /* find the first choice value to find out choice type */ 326 - current_entry = parent; 327 - for (menu = parent->list; menu; menu = menu->next) { 328 - if (menu->sym && menu->sym->type != S_UNKNOWN) { 329 - menu_set_type(menu->sym->type); 330 - break; 331 - } 332 - } 333 - } 334 - 335 - /* 336 - * Use the choice itself as the parent dependency of 337 - * the contained items. This turns the mode of the 338 - * choice into an upper bound on the visibility of the 339 - * choice value symbols. 340 - */ 341 - parentdep = expr_alloc_symbol(sym); 342 - } else { 343 - /* Menu node for 'menu', 'if' */ 344 - parentdep = parent->dep; 345 - } 346 347 /* For each child menu node... */ 348 for (menu = parent->list; menu; menu = menu->next) { ··· 323 */ 324 basedep = rewrite_m(menu->dep); 325 basedep = expr_transform(basedep); 326 - basedep = expr_alloc_and(expr_copy(parentdep), basedep); 327 basedep = expr_eliminate_dups(basedep); 328 menu->dep = basedep; 329 ··· 387 } 388 } 389 390 - if (is_choice) 391 - expr_free(parentdep); 392 - 393 /* 394 * Recursively process children in the same fashion before 395 * moving on 396 */ 397 for (menu = parent->list; menu; menu = menu->next) 398 - _menu_finalize(menu, is_choice); 399 } else if (!inside_choice && sym) { 400 /* 401 * Automatic submenu creation. If sym is a symbol and A, B, C, ··· 467 sym->dir_dep.expr = expr_alloc_or(sym->dir_dep.expr, parent->dep); 468 } 469 for (menu = parent->list; menu; menu = menu->next) { 470 - if (sym && sym_is_choice(sym) && 471 - menu->sym && !sym_is_choice_value(menu->sym)) { 472 - current_entry = menu; 473 - menu->sym->flags |= SYMBOL_CHOICEVAL; 474 - /* Non-tristate choice values of tristate choices must 475 - * depend on the choice being set to Y. The choice 476 - * values' dependencies were propagated to their 477 - * properties above, so the change here must be re- 478 - * propagated. 479 - */ 480 - if (sym->type == S_TRISTATE && menu->sym->type != S_TRISTATE) { 481 - basedep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes); 482 - menu->dep = expr_alloc_and(basedep, menu->dep); 483 - for (prop = menu->sym->prop; prop; prop = prop->next) { 484 - if (prop->menu != menu) 485 - continue; 486 - prop->visible.expr = expr_alloc_and(expr_copy(basedep), 487 - prop->visible.expr); 488 - } 489 - } 490 - menu_add_symbol(P_CHOICE, sym, NULL); 491 - prop = sym_get_choice_prop(sym); 492 - for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr) 493 - ; 494 - *ep = expr_alloc_one(E_LIST, NULL); 495 - (*ep)->right.sym = menu->sym; 496 - } 497 - 498 /* 499 * This code serves two purposes: 500 * ··· 515 sym_check_prop(sym); 516 sym->flags |= SYMBOL_WARNED; 517 } 518 - 519 - /* 520 - * For choices, add a reverse dependency (corresponding to a select) of 521 - * '<visibility> && m'. This prevents the user from setting the choice 522 - * mode to 'n' when the choice is visible. 523 - */ 524 - if (sym && sym_is_choice(sym) && parent->prompt) { 525 - sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr, 526 - expr_alloc_and(parent->prompt->visible.expr, 527 - expr_alloc_symbol(&symbol_mod))); 528 - } 529 } 530 531 void menu_finalize(void) ··· 522 _menu_finalize(&rootmenu, false); 523 } 524 525 - bool menu_has_prompt(struct menu *menu) 526 { 527 if (!menu->prompt) 528 return false; ··· 547 548 bool menu_is_visible(struct menu *menu) 549 { 550 - struct menu *child; 551 struct symbol *sym; 552 tristate visible; 553 ··· 565 } else 566 visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr); 567 568 - if (visible != no) 569 - return true; 570 - 571 - if (!sym || sym_get_tristate_value(menu->sym) == no) 572 - return false; 573 - 574 - for (child = menu->list; child; child = child->next) { 575 - if (menu_is_visible(child)) { 576 - if (sym) 577 - sym->flags |= SYMBOL_DEF_USER; 578 - return true; 579 - } 580 - } 581 - 582 - return false; 583 } 584 585 - const char *menu_get_prompt(struct menu *menu) 586 { 587 if (menu->prompt) 588 return menu->prompt->text; ··· 589 return menu; 590 } 591 592 - static void get_def_str(struct gstr *r, struct menu *menu) 593 { 594 str_printf(r, "Defined at %s:%d\n", 595 menu->filename, menu->lineno); 596 } 597 598 - static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix) 599 { 600 if (!expr_is_yes(expr)) { 601 str_append(r, prefix);
··· 8 #include <stdlib.h> 9 #include <string.h> 10 11 + #include <list.h> 12 #include "lkc.h" 13 #include "internal.h" 14 15 static const char nohelp_text[] = "There is no help available for this option."; 16 ··· 38 return menu->next; 39 } 40 41 + void menu_warn(const struct menu *menu, const char *fmt, ...) 42 { 43 va_list ap; 44 va_start(ap, fmt); ··· 48 va_end(ap); 49 } 50 51 + static void prop_warn(const struct property *prop, const char *fmt, ...) 52 { 53 va_list ap; 54 va_start(ap, fmt); ··· 175 return prop; 176 } 177 178 + struct property *menu_add_prompt(enum prop_type type, const char *prompt, 179 struct expr *dep) 180 { 181 struct property *prop = menu_add_prop(type, NULL, dep); ··· 306 struct menu *menu, *last_menu; 307 struct symbol *sym; 308 struct property *prop; 309 + struct expr *basedep, *dep, *dep2; 310 311 sym = parent->sym; 312 if (parent->list) { ··· 314 * This menu node has children. We (recursively) process them 315 * and propagate parent dependencies before moving on. 316 */ 317 318 /* For each child menu node... */ 319 for (menu = parent->list; menu; menu = menu->next) { ··· 352 */ 353 basedep = rewrite_m(menu->dep); 354 basedep = expr_transform(basedep); 355 + basedep = expr_alloc_and(expr_copy(parent->dep), basedep); 356 basedep = expr_eliminate_dups(basedep); 357 menu->dep = basedep; 358 ··· 416 } 417 } 418 419 /* 420 * Recursively process children in the same fashion before 421 * moving on 422 */ 423 for (menu = parent->list; menu; menu = menu->next) 424 + _menu_finalize(menu, sym && sym_is_choice(sym)); 425 } else if (!inside_choice && sym) { 426 /* 427 * Automatic submenu creation. If sym is a symbol and A, B, C, ··· 499 sym->dir_dep.expr = expr_alloc_or(sym->dir_dep.expr, parent->dep); 500 } 501 for (menu = parent->list; menu; menu = menu->next) { 502 /* 503 * This code serves two purposes: 504 * ··· 575 sym_check_prop(sym); 576 sym->flags |= SYMBOL_WARNED; 577 } 578 } 579 580 void menu_finalize(void) ··· 593 _menu_finalize(&rootmenu, false); 594 } 595 596 + bool menu_has_prompt(const struct menu *menu) 597 { 598 if (!menu->prompt) 599 return false; ··· 618 619 bool menu_is_visible(struct menu *menu) 620 { 621 struct symbol *sym; 622 tristate visible; 623 ··· 637 } else 638 visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr); 639 640 + return visible != no; 641 } 642 643 + const char *menu_get_prompt(const struct menu *menu) 644 { 645 if (menu->prompt) 646 return menu->prompt->text; ··· 675 return menu; 676 } 677 678 + static void get_def_str(struct gstr *r, const struct menu *menu) 679 { 680 str_printf(r, "Defined at %s:%d\n", 681 menu->filename, menu->lineno); 682 } 683 684 + static void get_dep_str(struct gstr *r, const struct expr *expr, 685 + const char *prefix) 686 { 687 if (!expr_is_yes(expr)) { 688 str_append(r, prefix);
+1 -1
scripts/kconfig/mnconf-common.c
··· 1 // SPDX-License-Identifier: GPL-2.0-only 2 #include "expr.h" 3 - #include "list.h" 4 #include "mnconf-common.h" 5 6 int jump_key_char;
··· 1 // SPDX-License-Identifier: GPL-2.0-only 2 + #include <list.h> 3 #include "expr.h" 4 #include "mnconf-common.h" 5 6 int jump_key_char;
+2
scripts/kconfig/mnconf-common.h
··· 4 5 #include <stddef.h> 6 7 struct search_data { 8 struct list_head *head; 9 struct menu *target;
··· 4 5 #include <stddef.h> 6 7 + #include <list_types.h> 8 + 9 struct search_data { 10 struct list_head *head; 11 struct menu *target;
+2
scripts/kconfig/nconf-cfg.sh
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 4 cflags=$1 5 libs=$2 6
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 4 + set -eu 5 + 6 cflags=$1 7 libs=$2 8
+10 -28
scripts/kconfig/nconf.c
··· 11 #include <strings.h> 12 #include <stdlib.h> 13 14 - #include "list.h" 15 #include "lkc.h" 16 #include "mnconf-common.h" 17 #include "nconf.h" ··· 815 816 type = sym_get_type(sym); 817 if (sym_is_choice(sym)) { 818 - struct symbol *def_sym = sym_get_choice_value(sym); 819 struct menu *def_menu = NULL; 820 821 child_count++; ··· 825 } 826 827 val = sym_get_tristate_value(sym); 828 - if (sym_is_changeable(sym)) { 829 - switch (val) { 830 - case yes: 831 - ch = '*'; 832 - break; 833 - case mod: 834 - ch = 'M'; 835 - break; 836 - default: 837 - ch = ' '; 838 - break; 839 - } 840 - item_make(menu, 't', "<%c>", ch); 841 - } else { 842 - item_make(menu, def_menu ? 't' : ':', " "); 843 - } 844 845 item_add_str("%*c%s", indent + 1, 846 ' ', menu_get_prompt(menu)); 847 - if (val == yes) { 848 - if (def_menu) 849 - item_add_str(" (%s) --->", menu_get_prompt(def_menu)); 850 - return; 851 - } 852 } else { 853 if (menu == current_menu) { 854 item_make(menu, ':', ··· 1174 conf(submenu); 1175 break; 1176 case 't': 1177 - if (sym_is_choice(sym) && 1178 - sym_get_tristate_value(sym) == yes) 1179 conf_choice(submenu); 1180 else if (submenu->prompt && 1181 submenu->prompt->type == P_MENU) ··· 1239 .pattern = "", 1240 }; 1241 1242 - active = sym_get_choice_value(menu->sym); 1243 /* this is mostly duplicated from the conf() function. */ 1244 while (!global_exit) { 1245 reset_menu(); ··· 1248 if (!show_all_items && !menu_is_visible(child)) 1249 continue; 1250 1251 - if (child->sym == sym_get_choice_value(menu->sym)) 1252 item_make(child, ':', "<X> %s", 1253 menu_get_prompt(child)); 1254 else if (child->sym) ··· 1331 case ' ': 1332 case 10: 1333 case KEY_RIGHT: 1334 - sym_set_tristate_value(child->sym, yes); 1335 return; 1336 case 'h': 1337 case '?':
··· 11 #include <strings.h> 12 #include <stdlib.h> 13 14 + #include <list.h> 15 #include "lkc.h" 16 #include "mnconf-common.h" 17 #include "nconf.h" ··· 815 816 type = sym_get_type(sym); 817 if (sym_is_choice(sym)) { 818 + struct symbol *def_sym = sym_calc_choice(menu); 819 struct menu *def_menu = NULL; 820 821 child_count++; ··· 825 } 826 827 val = sym_get_tristate_value(sym); 828 + item_make(menu, def_menu ? 't' : ':', " "); 829 830 item_add_str("%*c%s", indent + 1, 831 ' ', menu_get_prompt(menu)); 832 + if (def_menu) 833 + item_add_str(" (%s) --->", menu_get_prompt(def_menu)); 834 + return; 835 } else { 836 if (menu == current_menu) { 837 item_make(menu, ':', ··· 1191 conf(submenu); 1192 break; 1193 case 't': 1194 + if (sym_is_choice(sym)) 1195 conf_choice(submenu); 1196 else if (submenu->prompt && 1197 submenu->prompt->type == P_MENU) ··· 1257 .pattern = "", 1258 }; 1259 1260 + active = sym_calc_choice(menu); 1261 /* this is mostly duplicated from the conf() function. */ 1262 while (!global_exit) { 1263 reset_menu(); ··· 1266 if (!show_all_items && !menu_is_visible(child)) 1267 continue; 1268 1269 + if (child->sym == sym_calc_choice(menu)) 1270 item_make(child, ':', "<X> %s", 1271 menu_get_prompt(child)); 1272 else if (child->sym) ··· 1349 case ' ': 1350 case 10: 1351 case KEY_RIGHT: 1352 + choice_set_value(menu, child->sym); 1353 return; 1354 case 'h': 1355 case '?':
+24 -21
scripts/kconfig/parser.y
··· 28 static bool zconf_endtoken(const char *tokenname, 29 const char *expected_tokenname); 30 31 - struct menu *current_menu, *current_entry; 32 - 33 - static bool inside_choice = false; 34 35 %} 36 ··· 88 89 %type <symbol> nonconst_symbol 90 %type <symbol> symbol 91 - %type <type> type logic_type default 92 %type <expr> expr 93 %type <expr> if_expr 94 %type <string> end ··· 145 146 config_stmt: config_entry_start config_option_list 147 { 148 - if (inside_choice) { 149 if (!current_entry->prompt) { 150 fprintf(stderr, "%s:%d: error: choice member must have a prompt\n", 151 current_entry->filename, current_entry->lineno); 152 yynerrs++; 153 } 154 } 155 156 printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno); ··· 241 struct symbol *sym = sym_lookup(NULL, 0); 242 243 menu_add_entry(sym); 244 - menu_add_expr(P_CHOICE, NULL, NULL); 245 printd(DEBUG_PARSE, "%s:%d:choice\n", cur_filename, cur_lineno); 246 }; 247 ··· 257 258 $$ = menu_add_menu(); 259 260 - inside_choice = true; 261 }; 262 263 choice_end: end 264 { 265 - inside_choice = false; 266 267 if (zconf_endtoken($1, "choice")) { 268 menu_end_menu(); ··· 286 printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno); 287 }; 288 289 - choice_option: logic_type prompt_stmt_opt T_EOL 290 { 291 - menu_set_type($1); 292 - printd(DEBUG_PARSE, "%s:%d:type(%u)\n", cur_filename, cur_lineno, $1); 293 }; 294 295 choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL ··· 299 }; 300 301 type: 302 - logic_type 303 | T_INT { $$ = S_INT; } 304 | T_HEX { $$ = S_HEX; } 305 | T_STRING { $$ = S_STRING; } 306 - 307 - logic_type: 308 - T_BOOL { $$ = S_BOOLEAN; } 309 - | T_TRISTATE { $$ = S_TRISTATE; } 310 311 default: 312 T_DEFAULT { $$ = S_UNKNOWN; } ··· 489 * 490 * Return: -1 if an error is found, 0 otherwise. 491 */ 492 - static int choice_check_sanity(struct menu *menu) 493 { 494 struct property *prop; 495 int ret = 0; ··· 644 putc('"', out); 645 } 646 647 - static void print_symbol(FILE *out, struct menu *menu) 648 { 649 struct symbol *sym = menu->sym; 650 struct property *prop; ··· 694 expr_fprint(prop->visible.expr, out); 695 } 696 fputc('\n', out); 697 - break; 698 - case P_CHOICE: 699 - fputs(" #choice value\n", out); 700 break; 701 case P_SELECT: 702 fputs( " select ", out);
··· 28 static bool zconf_endtoken(const char *tokenname, 29 const char *expected_tokenname); 30 31 + struct menu *current_menu, *current_entry, *current_choice; 32 33 %} 34 ··· 90 91 %type <symbol> nonconst_symbol 92 %type <symbol> symbol 93 + %type <type> type default 94 %type <expr> expr 95 %type <expr> if_expr 96 %type <string> end ··· 147 148 config_stmt: config_entry_start config_option_list 149 { 150 + if (current_choice) { 151 if (!current_entry->prompt) { 152 fprintf(stderr, "%s:%d: error: choice member must have a prompt\n", 153 current_entry->filename, current_entry->lineno); 154 yynerrs++; 155 } 156 + 157 + if (current_entry->sym->type != S_BOOLEAN) { 158 + fprintf(stderr, "%s:%d: error: choice member must be bool\n", 159 + current_entry->filename, current_entry->lineno); 160 + yynerrs++; 161 + } 162 + 163 + list_add_tail(&current_entry->sym->choice_link, 164 + &current_choice->choice_members); 165 } 166 167 printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno); ··· 234 struct symbol *sym = sym_lookup(NULL, 0); 235 236 menu_add_entry(sym); 237 + menu_set_type(S_BOOLEAN); 238 + INIT_LIST_HEAD(&current_entry->choice_members); 239 + 240 printd(DEBUG_PARSE, "%s:%d:choice\n", cur_filename, cur_lineno); 241 }; 242 ··· 248 249 $$ = menu_add_menu(); 250 251 + current_choice = current_entry; 252 }; 253 254 choice_end: end 255 { 256 + current_choice = NULL; 257 258 if (zconf_endtoken($1, "choice")) { 259 menu_end_menu(); ··· 277 printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno); 278 }; 279 280 + choice_option: T_BOOL T_WORD_QUOTE if_expr T_EOL 281 { 282 + menu_add_prompt(P_PROMPT, $2, $3); 283 + printd(DEBUG_PARSE, "%s:%d:bool\n", cur_filename, cur_lineno); 284 }; 285 286 choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL ··· 290 }; 291 292 type: 293 + T_BOOL { $$ = S_BOOLEAN; } 294 + | T_TRISTATE { $$ = S_TRISTATE; } 295 | T_INT { $$ = S_INT; } 296 | T_HEX { $$ = S_HEX; } 297 | T_STRING { $$ = S_STRING; } 298 299 default: 300 T_DEFAULT { $$ = S_UNKNOWN; } ··· 483 * 484 * Return: -1 if an error is found, 0 otherwise. 485 */ 486 + static int choice_check_sanity(const struct menu *menu) 487 { 488 struct property *prop; 489 int ret = 0; ··· 638 putc('"', out); 639 } 640 641 + static void print_symbol(FILE *out, const struct menu *menu) 642 { 643 struct symbol *sym = menu->sym; 644 struct property *prop; ··· 688 expr_fprint(prop->visible.expr, out); 689 } 690 fputc('\n', out); 691 break; 692 case P_SELECT: 693 fputs( " select ", out);
+2 -2
scripts/kconfig/preprocess.c
··· 9 #include <stdlib.h> 10 #include <string.h> 11 12 - #include "array_size.h" 13 #include "internal.h" 14 - #include "list.h" 15 #include "lkc.h" 16 #include "preprocess.h" 17
··· 9 #include <stdlib.h> 10 #include <string.h> 11 12 + #include <array_size.h> 13 + #include <list.h> 14 #include "internal.h" 15 #include "lkc.h" 16 #include "preprocess.h" 17
+2
scripts/kconfig/qconf-cfg.sh
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 4 cflags=$1 5 libs=$2 6 bin=$3
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 4 + set -eu 5 + 6 cflags=$1 7 libs=$2 8 bin=$3
+6 -14
scripts/kconfig/qconf.cc
··· 147 expr = sym_get_tristate_value(sym); 148 switch (expr) { 149 case yes: 150 - if (sym_is_choice_value(sym) && type == S_BOOLEAN) 151 setIcon(promptColIdx, choiceYesIcon); 152 else 153 setIcon(promptColIdx, symbolYesIcon); ··· 1101 &stream, E_NONE); 1102 stream << "<br>"; 1103 break; 1104 - case P_CHOICE: 1105 - if (sym_is_choice(sym)) { 1106 - stream << "choice: "; 1107 - expr_print(prop->expr, expr_print_help, 1108 - &stream, E_NONE); 1109 - stream << "<br>"; 1110 - } 1111 - break; 1112 default: 1113 stream << "unknown property: "; 1114 stream << prop_get_type_name(prop->type); ··· 1389 1390 conf_set_changed_callback(conf_changed); 1391 1392 - // Set saveAction's initial state 1393 - conf_changed(); 1394 configname = xstrdup(conf_get_configname()); 1395 1396 QAction *saveAsAction = new QAction("Save &As...", this); ··· 1841 configSettings->writeSizes("/split2", split2->sizes()); 1842 } 1843 1844 - void ConfigMainWindow::conf_changed(void) 1845 { 1846 if (saveAction) 1847 - saveAction->setEnabled(conf_get_changed()); 1848 } 1849 1850 void fixup_rootmenu(struct menu *menu) ··· 1894 1895 conf_parse(name); 1896 fixup_rootmenu(&rootmenu); 1897 - conf_read(NULL); 1898 //zconfdump(stdout); 1899 1900 configApp = new QApplication(ac, av); ··· 1905 //zconfdump(stdout); 1906 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); 1907 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); 1908 v->show(); 1909 configApp->exec(); 1910
··· 147 expr = sym_get_tristate_value(sym); 148 switch (expr) { 149 case yes: 150 + if (sym_is_choice_value(sym)) 151 setIcon(promptColIdx, choiceYesIcon); 152 else 153 setIcon(promptColIdx, symbolYesIcon); ··· 1101 &stream, E_NONE); 1102 stream << "<br>"; 1103 break; 1104 default: 1105 stream << "unknown property: "; 1106 stream << prop_get_type_name(prop->type); ··· 1397 1398 conf_set_changed_callback(conf_changed); 1399 1400 configname = xstrdup(conf_get_configname()); 1401 1402 QAction *saveAsAction = new QAction("Save &As...", this); ··· 1851 configSettings->writeSizes("/split2", split2->sizes()); 1852 } 1853 1854 + void ConfigMainWindow::conf_changed(bool dirty) 1855 { 1856 if (saveAction) 1857 + saveAction->setEnabled(dirty); 1858 } 1859 1860 void fixup_rootmenu(struct menu *menu) ··· 1904 1905 conf_parse(name); 1906 fixup_rootmenu(&rootmenu); 1907 //zconfdump(stdout); 1908 1909 configApp = new QApplication(ac, av); ··· 1916 //zconfdump(stdout); 1917 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); 1918 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); 1919 + 1920 + conf_read(NULL); 1921 + 1922 v->show(); 1923 configApp->exec(); 1924
+1 -1
scripts/kconfig/qconf.h
··· 239 240 char *configname; 241 static QAction *saveAction; 242 - static void conf_changed(void); 243 public: 244 ConfigMainWindow(void); 245 public slots:
··· 239 240 char *configname; 241 static QAction *saveAction; 242 + static void conf_changed(bool); 243 public: 244 ConfigMainWindow(void); 245 public slots:
+193 -176
scripts/kconfig/symbol.c
··· 40 static tristate modules_val; 41 static int sym_warnings; 42 43 - enum symbol_type sym_get_type(struct symbol *sym) 44 { 45 enum symbol_type type = sym->type; 46 47 - if (type == S_TRISTATE) { 48 - if (sym_is_choice_value(sym) && sym->visible == yes) 49 - type = S_BOOLEAN; 50 - else if (modules_val == no) 51 - type = S_BOOLEAN; 52 - } 53 return type; 54 } 55 ··· 68 return "???"; 69 } 70 71 - struct property *sym_get_choice_prop(struct symbol *sym) 72 - { 73 - struct property *prop; 74 - 75 - for_all_choices(sym, prop) 76 - return prop; 77 - return NULL; 78 - } 79 - 80 /** 81 * sym_get_choice_menu - get the parent choice menu if present 82 * ··· 75 * 76 * Return: a choice menu if this function is called against a choice member. 77 */ 78 - struct menu *sym_get_choice_menu(struct symbol *sym) 79 { 80 struct menu *menu = NULL; 81 struct menu *m; ··· 179 { 180 struct menu *menu; 181 182 - sym->flags |= SYMBOL_CHANGED; 183 list_for_each_entry(menu, &sym->menus, link) 184 menu->flags |= MENU_CHANGED; 185 } ··· 194 static void sym_calc_visibility(struct symbol *sym) 195 { 196 struct property *prop; 197 - struct symbol *choice_sym = NULL; 198 tristate tri; 199 200 /* any prompt visible? */ 201 tri = no; 202 - 203 - if (sym_is_choice_value(sym)) 204 - choice_sym = prop_get_symbol(sym_get_choice_prop(sym)); 205 - 206 for_all_prompts(sym, prop) { 207 prop->visible.tri = expr_calc_value(prop->visible.expr); 208 - /* 209 - * Tristate choice_values with visibility 'mod' are 210 - * not visible if the corresponding choice's value is 211 - * 'yes'. 212 - */ 213 - if (choice_sym && sym->type == S_TRISTATE && 214 - prop->visible.tri == mod && choice_sym->curr.tri == yes) 215 - prop->visible.tri = no; 216 - 217 tri = EXPR_OR(tri, prop->visible.tri); 218 } 219 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) ··· 246 * Next locate the first visible choice value 247 * Return NULL if none was found 248 */ 249 - struct symbol *sym_choice_default(struct symbol *sym) 250 { 251 struct symbol *def_sym; 252 struct property *prop; 253 - struct expr *e; 254 255 /* any of the defaults visible? */ 256 - for_all_defaults(sym, prop) { 257 prop->visible.tri = expr_calc_value(prop->visible.expr); 258 if (prop->visible.tri == no) 259 continue; ··· 263 } 264 265 /* just get the first visible value */ 266 - prop = sym_get_choice_prop(sym); 267 - expr_list_for_each_sym(prop->expr, e, def_sym) 268 - if (def_sym->visible != no) 269 - return def_sym; 270 271 /* failed to locate any defaults */ 272 return NULL; 273 } 274 275 - static struct symbol *sym_calc_choice(struct symbol *sym) 276 { 277 - struct symbol *def_sym; 278 - struct property *prop; 279 - struct expr *e; 280 - int flags; 281 282 - /* first calculate all choice values' visibilities */ 283 - flags = sym->flags; 284 - prop = sym_get_choice_prop(sym); 285 - expr_list_for_each_sym(prop->expr, e, def_sym) { 286 - sym_calc_visibility(def_sym); 287 - if (def_sym->visible != no) 288 - flags &= def_sym->flags; 289 } 290 291 - sym->flags &= flags | ~SYMBOL_DEF_USER; 292 293 - /* is the user choice visible? */ 294 - def_sym = sym->def[S_DEF_USER].val; 295 - if (def_sym && def_sym->visible != no) 296 - return def_sym; 297 298 - def_sym = sym_choice_default(sym); 299 300 - if (def_sym == NULL) 301 - /* no choice? reset tristate value */ 302 - sym->curr.tri = no; 303 304 - return def_sym; 305 } 306 307 - static void sym_warn_unmet_dep(struct symbol *sym) 308 { 309 struct gstr gs = str_new(); 310 ··· 388 { 389 struct symbol_value newval, oldval; 390 struct property *prop; 391 - struct expr *e; 392 393 if (!sym) 394 return; 395 396 if (sym->flags & SYMBOL_VALID) 397 return; 398 - 399 - if (sym_is_choice_value(sym) && 400 - sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) { 401 - sym->flags &= ~SYMBOL_NEED_SET_CHOICE_VALUES; 402 - prop = sym_get_choice_prop(sym); 403 - sym_calc_value(prop_get_symbol(prop)); 404 - } 405 406 sym->flags |= SYMBOL_VALID; 407 ··· 434 switch (sym_get_type(sym)) { 435 case S_BOOLEAN: 436 case S_TRISTATE: 437 - if (sym_is_choice_value(sym) && sym->visible == yes) { 438 - prop = sym_get_choice_prop(sym); 439 - newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no; 440 } else { 441 if (sym->visible != no) { 442 /* if the symbol is visible use the user value ··· 497 } 498 499 sym->curr = newval; 500 - if (sym_is_choice(sym) && newval.tri == yes) 501 - sym->curr.val = sym_calc_choice(sym); 502 sym_validate_range(sym); 503 504 if (memcmp(&oldval, &sym->curr, sizeof(oldval))) { ··· 507 } 508 } 509 510 - if (sym_is_choice(sym)) { 511 - struct symbol *choice_sym; 512 - 513 - prop = sym_get_choice_prop(sym); 514 - expr_list_for_each_sym(prop->expr, e, choice_sym) { 515 - if ((sym->flags & SYMBOL_WRITE) && 516 - choice_sym->visible != no) 517 - choice_sym->flags |= SYMBOL_WRITE; 518 - if (sym->flags & SYMBOL_CHANGED) 519 - sym_set_changed(choice_sym); 520 - } 521 - 522 sym->flags &= ~SYMBOL_WRITE; 523 - } 524 - 525 - if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) 526 - set_all_choice_values(sym); 527 } 528 529 void sym_clear_all_valid(void) ··· 521 sym_calc_value(modules_sym); 522 } 523 524 - bool sym_tristate_within_range(struct symbol *sym, tristate val) 525 { 526 int type = sym_get_type(sym); 527 ··· 535 return false; 536 if (sym->visible <= sym->rev_dep.tri) 537 return false; 538 - if (sym_is_choice_value(sym) && sym->visible == yes) 539 - return val == yes; 540 return val >= sym->rev_dep.tri && val <= sym->visible; 541 } 542 ··· 542 { 543 tristate oldval = sym_get_tristate_value(sym); 544 545 - if (oldval != val && !sym_tristate_within_range(sym, val)) 546 return false; 547 548 - if (!(sym->flags & SYMBOL_DEF_USER)) { 549 sym->flags |= SYMBOL_DEF_USER; 550 sym_set_changed(sym); 551 } 552 - /* 553 - * setting a choice value also resets the new flag of the choice 554 - * symbol and all other choice values. 555 - */ 556 - if (sym_is_choice_value(sym) && val == yes) { 557 - struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); 558 - struct property *prop; 559 - struct expr *e; 560 561 - cs->def[S_DEF_USER].val = sym; 562 - cs->flags |= SYMBOL_DEF_USER; 563 - prop = sym_get_choice_prop(cs); 564 - for (e = prop->expr; e; e = e->left.expr) { 565 - if (e->right.sym->visible != no) 566 - e->right.sym->flags |= SYMBOL_DEF_USER; 567 - } 568 - } 569 - 570 - sym->def[S_DEF_USER].tri = val; 571 if (oldval != val) 572 sym_clear_all_valid(); 573 574 return true; 575 } 576 577 tristate sym_toggle_tristate_value(struct symbol *sym) 578 { 579 tristate oldval, newval; 580 581 oldval = newval = sym_get_tristate_value(sym); 582 do { ··· 866 return (const char *)sym->curr.val; 867 } 868 869 - bool sym_is_changeable(struct symbol *sym) 870 { 871 - return sym->visible > sym->rev_dep.tri; 872 } 873 874 HASHTABLE_DEFINE(sym_hashtable, SYMBOL_HASHSIZE); ··· 913 symbol->type = S_UNKNOWN; 914 symbol->flags = flags; 915 INIT_LIST_HEAD(&symbol->menus); 916 917 hash_add(sym_hashtable, &symbol->node, hash); 918 ··· 1074 { 1075 struct dep_stack *stack; 1076 struct symbol *sym, *next_sym; 1077 - struct menu *menu = NULL; 1078 - struct property *prop; 1079 struct dep_stack cv_stack; 1080 1081 - if (sym_is_choice_value(last_sym)) { 1082 dep_stack_insert(&cv_stack, last_sym); 1083 - last_sym = prop_get_symbol(sym_get_choice_prop(last_sym)); 1084 } 1085 1086 for (stack = check_top; stack != NULL; stack = stack->prev) ··· 1095 for (; stack; stack = stack->next) { 1096 sym = stack->sym; 1097 next_sym = stack->next ? stack->next->sym : last_sym; 1098 - prop = stack->prop; 1099 - if (prop == NULL) 1100 - prop = stack->sym->prop; 1101 1102 - /* for choice values find the menu entry (used below) */ 1103 - if (sym_is_choice(sym) || sym_is_choice_value(sym)) { 1104 - for (prop = sym->prop; prop; prop = prop->next) { 1105 - menu = prop->menu; 1106 - if (prop->menu) 1107 - break; 1108 - } 1109 - } 1110 if (stack->sym == last_sym) 1111 - fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", 1112 - prop->filename, prop->lineno); 1113 1114 - if (sym_is_choice(sym)) { 1115 - fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", 1116 - menu->filename, menu->lineno, 1117 sym->name ? sym->name : "<choice>", 1118 - next_sym->name ? next_sym->name : "<choice>"); 1119 - } else if (sym_is_choice_value(sym)) { 1120 - fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", 1121 - menu->filename, menu->lineno, 1122 - sym->name ? sym->name : "<choice>", 1123 - next_sym->name ? next_sym->name : "<choice>"); 1124 } else if (stack->expr == &sym->dir_dep.expr) { 1125 - fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", 1126 - prop->filename, prop->lineno, 1127 sym->name ? sym->name : "<choice>", 1128 - next_sym->name ? next_sym->name : "<choice>"); 1129 } else if (stack->expr == &sym->rev_dep.expr) { 1130 - fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", 1131 - prop->filename, prop->lineno, 1132 - sym->name ? sym->name : "<choice>", 1133 - next_sym->name ? next_sym->name : "<choice>"); 1134 } else if (stack->expr == &sym->implied.expr) { 1135 - fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n", 1136 - prop->filename, prop->lineno, 1137 - sym->name ? sym->name : "<choice>", 1138 - next_sym->name ? next_sym->name : "<choice>"); 1139 } else if (stack->expr) { 1140 - fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", 1141 - prop->filename, prop->lineno, 1142 sym->name ? sym->name : "<choice>", 1143 - prop_get_type_name(prop->type), 1144 - next_sym->name ? next_sym->name : "<choice>"); 1145 } else { 1146 - fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n", 1147 - prop->filename, prop->lineno, 1148 sym->name ? sym->name : "<choice>", 1149 - prop_get_type_name(prop->type), 1150 - next_sym->name ? next_sym->name : "<choice>"); 1151 } 1152 } 1153 ··· 1138 dep_stack_remove(); 1139 } 1140 1141 - static struct symbol *sym_check_expr_deps(struct expr *e) 1142 { 1143 struct symbol *sym; 1144 ··· 1199 stack.expr = NULL; 1200 1201 for (prop = sym->prop; prop; prop = prop->next) { 1202 - if (prop->type == P_CHOICE || prop->type == P_SELECT || 1203 - prop->type == P_IMPLY) 1204 continue; 1205 stack.prop = prop; 1206 sym2 = sym_check_expr_deps(prop->visible.expr); ··· 1253 if (menu->sym) 1254 menu->sym->flags &= ~SYMBOL_CHECK; 1255 1256 - if (sym2 && sym_is_choice_value(sym2) && 1257 - prop_get_symbol(sym_get_choice_prop(sym2)) == choice) 1258 - sym2 = choice; 1259 1260 dep_stack_remove(); 1261 ··· 1268 1269 struct symbol *sym_check_deps(struct symbol *sym) 1270 { 1271 struct symbol *sym2; 1272 - struct property *prop; 1273 1274 if (sym->flags & SYMBOL_CHECK) { 1275 sym_check_print_recursive(sym); ··· 1278 if (sym->flags & SYMBOL_CHECKED) 1279 return NULL; 1280 1281 - if (sym_is_choice_value(sym)) { 1282 struct dep_stack stack; 1283 1284 /* for choice groups start the check with main choice symbol */ 1285 dep_stack_insert(&stack, sym); 1286 - prop = sym_get_choice_prop(sym); 1287 - sym2 = sym_check_deps(prop_get_symbol(prop)); 1288 dep_stack_remove(); 1289 } else if (sym_is_choice(sym)) { 1290 sym2 = sym_check_choice_deps(sym); ··· 1297 return sym2; 1298 } 1299 1300 - struct symbol *prop_get_symbol(struct property *prop) 1301 { 1302 - if (prop->expr && (prop->expr->type == E_SYMBOL || 1303 - prop->expr->type == E_LIST)) 1304 return prop->expr->left.sym; 1305 return NULL; 1306 } ··· 1315 return "menu"; 1316 case P_DEFAULT: 1317 return "default"; 1318 - case P_CHOICE: 1319 - return "choice"; 1320 case P_SELECT: 1321 return "select"; 1322 case P_IMPLY:
··· 40 static tristate modules_val; 41 static int sym_warnings; 42 43 + enum symbol_type sym_get_type(const struct symbol *sym) 44 { 45 enum symbol_type type = sym->type; 46 47 + if (type == S_TRISTATE && modules_val == no) 48 + type = S_BOOLEAN; 49 return type; 50 } 51 ··· 72 return "???"; 73 } 74 75 /** 76 * sym_get_choice_menu - get the parent choice menu if present 77 * ··· 88 * 89 * Return: a choice menu if this function is called against a choice member. 90 */ 91 + struct menu *sym_get_choice_menu(const struct symbol *sym) 92 { 93 struct menu *menu = NULL; 94 struct menu *m; ··· 192 { 193 struct menu *menu; 194 195 list_for_each_entry(menu, &sym->menus, link) 196 menu->flags |= MENU_CHANGED; 197 } ··· 208 static void sym_calc_visibility(struct symbol *sym) 209 { 210 struct property *prop; 211 tristate tri; 212 213 /* any prompt visible? */ 214 tri = no; 215 for_all_prompts(sym, prop) { 216 prop->visible.tri = expr_calc_value(prop->visible.expr); 217 tri = EXPR_OR(tri, prop->visible.tri); 218 } 219 if (tri == mod && (sym->type != S_TRISTATE || modules_val == no)) ··· 274 * Next locate the first visible choice value 275 * Return NULL if none was found 276 */ 277 + struct symbol *sym_choice_default(struct menu *choice) 278 { 279 + struct menu *menu; 280 struct symbol *def_sym; 281 struct property *prop; 282 283 /* any of the defaults visible? */ 284 + for_all_defaults(choice->sym, prop) { 285 prop->visible.tri = expr_calc_value(prop->visible.expr); 286 if (prop->visible.tri == no) 287 continue; ··· 291 } 292 293 /* just get the first visible value */ 294 + menu_for_each_sub_entry(menu, choice) 295 + if (menu->sym && menu->sym->visible != no) 296 + return menu->sym; 297 298 /* failed to locate any defaults */ 299 return NULL; 300 } 301 302 + /* 303 + * sym_calc_choice - calculate symbol values in a choice 304 + * 305 + * @choice: a menu of the choice 306 + * 307 + * Return: a chosen symbol 308 + */ 309 + struct symbol *sym_calc_choice(struct menu *choice) 310 { 311 + struct symbol *res = NULL; 312 + struct symbol *sym; 313 + struct menu *menu; 314 315 + /* Traverse the list of choice members in the priority order. */ 316 + list_for_each_entry(sym, &choice->choice_members, choice_link) { 317 + sym_calc_visibility(sym); 318 + if (sym->visible == no) 319 + continue; 320 + 321 + /* The first visible symble with the user value 'y'. */ 322 + if (sym_has_value(sym) && sym->def[S_DEF_USER].tri == yes) { 323 + res = sym; 324 + break; 325 + } 326 } 327 328 + /* 329 + * If 'y' is not found in the user input, use the default, unless it is 330 + * explicitly set to 'n'. 331 + */ 332 + if (!res) { 333 + res = sym_choice_default(choice); 334 + if (res && sym_has_value(res) && res->def[S_DEF_USER].tri == no) 335 + res = NULL; 336 + } 337 338 + /* Still not found. Pick up the first visible, user-unspecified symbol. */ 339 + if (!res) { 340 + menu_for_each_sub_entry(menu, choice) { 341 + sym = menu->sym; 342 343 + if (!sym || sym->visible == no || sym_has_value(sym)) 344 + continue; 345 346 + res = sym; 347 + break; 348 + } 349 + } 350 351 + /* 352 + * Still not found. Traverse the linked list in the _reverse_ order to 353 + * pick up the least prioritized 'n'. 354 + */ 355 + if (!res) { 356 + list_for_each_entry_reverse(sym, &choice->choice_members, 357 + choice_link) { 358 + if (sym->visible == no) 359 + continue; 360 + 361 + res = sym; 362 + break; 363 + } 364 + } 365 + 366 + menu_for_each_sub_entry(menu, choice) { 367 + tristate val; 368 + 369 + sym = menu->sym; 370 + 371 + if (!sym || sym->visible == no) 372 + continue; 373 + 374 + val = sym == res ? yes : no; 375 + 376 + if (sym->curr.tri != val) 377 + sym_set_changed(sym); 378 + 379 + sym->curr.tri = val; 380 + sym->flags |= SYMBOL_VALID | SYMBOL_WRITE; 381 + } 382 + 383 + return res; 384 } 385 386 + static void sym_warn_unmet_dep(const struct symbol *sym) 387 { 388 struct gstr gs = str_new(); 389 ··· 365 { 366 struct symbol_value newval, oldval; 367 struct property *prop; 368 + struct menu *choice_menu; 369 370 if (!sym) 371 return; 372 373 if (sym->flags & SYMBOL_VALID) 374 return; 375 376 sym->flags |= SYMBOL_VALID; 377 ··· 418 switch (sym_get_type(sym)) { 419 case S_BOOLEAN: 420 case S_TRISTATE: 421 + choice_menu = sym_get_choice_menu(sym); 422 + 423 + if (choice_menu) { 424 + sym_calc_choice(choice_menu); 425 + newval.tri = sym->curr.tri; 426 } else { 427 if (sym->visible != no) { 428 /* if the symbol is visible use the user value ··· 479 } 480 481 sym->curr = newval; 482 sym_validate_range(sym); 483 484 if (memcmp(&oldval, &sym->curr, sizeof(oldval))) { ··· 491 } 492 } 493 494 + if (sym_is_choice(sym)) 495 sym->flags &= ~SYMBOL_WRITE; 496 } 497 498 void sym_clear_all_valid(void) ··· 520 sym_calc_value(modules_sym); 521 } 522 523 + bool sym_tristate_within_range(const struct symbol *sym, tristate val) 524 { 525 int type = sym_get_type(sym); 526 ··· 534 return false; 535 if (sym->visible <= sym->rev_dep.tri) 536 return false; 537 return val >= sym->rev_dep.tri && val <= sym->visible; 538 } 539 ··· 543 { 544 tristate oldval = sym_get_tristate_value(sym); 545 546 + if (!sym_tristate_within_range(sym, val)) 547 return false; 548 549 + if (!(sym->flags & SYMBOL_DEF_USER) || sym->def[S_DEF_USER].tri != val) { 550 + sym->def[S_DEF_USER].tri = val; 551 sym->flags |= SYMBOL_DEF_USER; 552 sym_set_changed(sym); 553 } 554 555 if (oldval != val) 556 sym_clear_all_valid(); 557 558 return true; 559 } 560 561 + /** 562 + * choice_set_value - set the user input to a choice 563 + * 564 + * @choice: menu entry for the choice 565 + * @sym: selected symbol 566 + */ 567 + void choice_set_value(struct menu *choice, struct symbol *sym) 568 + { 569 + struct menu *menu; 570 + bool changed = false; 571 + 572 + menu_for_each_sub_entry(menu, choice) { 573 + tristate val; 574 + 575 + if (!menu->sym) 576 + continue; 577 + 578 + if (menu->sym->visible == no) 579 + continue; 580 + 581 + val = menu->sym == sym ? yes : no; 582 + 583 + if (menu->sym->curr.tri != val) 584 + changed = true; 585 + 586 + menu->sym->def[S_DEF_USER].tri = val; 587 + menu->sym->flags |= SYMBOL_DEF_USER; 588 + 589 + /* 590 + * Now, the user has explicitly enabled or disabled this symbol, 591 + * it should be given the highest priority. We are possibly 592 + * setting multiple symbols to 'n', where the first symbol is 593 + * given the least prioritized 'n'. This works well when the 594 + * choice block ends up with selecting 'n' symbol. 595 + * (see sym_calc_choice()) 596 + */ 597 + list_move(&menu->sym->choice_link, &choice->choice_members); 598 + } 599 + 600 + if (changed) 601 + sym_clear_all_valid(); 602 + } 603 + 604 tristate sym_toggle_tristate_value(struct symbol *sym) 605 { 606 + struct menu *choice; 607 tristate oldval, newval; 608 + 609 + choice = sym_get_choice_menu(sym); 610 + if (choice) { 611 + choice_set_value(choice, sym); 612 + return yes; 613 + } 614 615 oldval = newval = sym_get_tristate_value(sym); 616 do { ··· 834 return (const char *)sym->curr.val; 835 } 836 837 + bool sym_is_changeable(const struct symbol *sym) 838 { 839 + return !sym_is_choice(sym) && sym->visible > sym->rev_dep.tri; 840 + } 841 + 842 + bool sym_is_choice_value(const struct symbol *sym) 843 + { 844 + return !list_empty(&sym->choice_link); 845 } 846 847 HASHTABLE_DEFINE(sym_hashtable, SYMBOL_HASHSIZE); ··· 876 symbol->type = S_UNKNOWN; 877 symbol->flags = flags; 878 INIT_LIST_HEAD(&symbol->menus); 879 + INIT_LIST_HEAD(&symbol->choice_link); 880 881 hash_add(sym_hashtable, &symbol->node, hash); 882 ··· 1036 { 1037 struct dep_stack *stack; 1038 struct symbol *sym, *next_sym; 1039 + struct menu *choice; 1040 struct dep_stack cv_stack; 1041 + enum prop_type type; 1042 1043 + choice = sym_get_choice_menu(last_sym); 1044 + if (choice) { 1045 dep_stack_insert(&cv_stack, last_sym); 1046 + last_sym = choice->sym; 1047 } 1048 1049 for (stack = check_top; stack != NULL; stack = stack->prev) ··· 1056 for (; stack; stack = stack->next) { 1057 sym = stack->sym; 1058 next_sym = stack->next ? stack->next->sym : last_sym; 1059 + type = stack->prop ? stack->prop->type : P_UNKNOWN; 1060 1061 if (stack->sym == last_sym) 1062 + fprintf(stderr, "error: recursive dependency detected!\n"); 1063 1064 + if (sym_is_choice(next_sym)) { 1065 + choice = list_first_entry(&next_sym->menus, struct menu, link); 1066 + 1067 + fprintf(stderr, "\tsymbol %s is part of choice block at %s:%d\n", 1068 sym->name ? sym->name : "<choice>", 1069 + choice->filename, choice->lineno); 1070 } else if (stack->expr == &sym->dir_dep.expr) { 1071 + fprintf(stderr, "\tsymbol %s depends on %s\n", 1072 sym->name ? sym->name : "<choice>", 1073 + next_sym->name); 1074 } else if (stack->expr == &sym->rev_dep.expr) { 1075 + fprintf(stderr, "\tsymbol %s is selected by %s\n", 1076 + sym->name, next_sym->name); 1077 } else if (stack->expr == &sym->implied.expr) { 1078 + fprintf(stderr, "\tsymbol %s is implied by %s\n", 1079 + sym->name, next_sym->name); 1080 } else if (stack->expr) { 1081 + fprintf(stderr, "\tsymbol %s %s value contains %s\n", 1082 sym->name ? sym->name : "<choice>", 1083 + prop_get_type_name(type), 1084 + next_sym->name); 1085 } else { 1086 + fprintf(stderr, "\tsymbol %s %s is visible depending on %s\n", 1087 sym->name ? sym->name : "<choice>", 1088 + prop_get_type_name(type), 1089 + next_sym->name); 1090 } 1091 } 1092 ··· 1121 dep_stack_remove(); 1122 } 1123 1124 + static struct symbol *sym_check_expr_deps(const struct expr *e) 1125 { 1126 struct symbol *sym; 1127 ··· 1182 stack.expr = NULL; 1183 1184 for (prop = sym->prop; prop; prop = prop->next) { 1185 + if (prop->type == P_SELECT || prop->type == P_IMPLY) 1186 continue; 1187 stack.prop = prop; 1188 sym2 = sym_check_expr_deps(prop->visible.expr); ··· 1237 if (menu->sym) 1238 menu->sym->flags &= ~SYMBOL_CHECK; 1239 1240 + if (sym2) { 1241 + struct menu *choice_menu2; 1242 + 1243 + choice_menu2 = sym_get_choice_menu(sym2); 1244 + if (choice_menu2 == choice_menu) 1245 + sym2 = choice; 1246 + } 1247 1248 dep_stack_remove(); 1249 ··· 1248 1249 struct symbol *sym_check_deps(struct symbol *sym) 1250 { 1251 + struct menu *choice; 1252 struct symbol *sym2; 1253 1254 if (sym->flags & SYMBOL_CHECK) { 1255 sym_check_print_recursive(sym); ··· 1258 if (sym->flags & SYMBOL_CHECKED) 1259 return NULL; 1260 1261 + choice = sym_get_choice_menu(sym); 1262 + if (choice) { 1263 struct dep_stack stack; 1264 1265 /* for choice groups start the check with main choice symbol */ 1266 dep_stack_insert(&stack, sym); 1267 + sym2 = sym_check_deps(choice->sym); 1268 dep_stack_remove(); 1269 } else if (sym_is_choice(sym)) { 1270 sym2 = sym_check_choice_deps(sym); ··· 1277 return sym2; 1278 } 1279 1280 + struct symbol *prop_get_symbol(const struct property *prop) 1281 { 1282 + if (prop->expr && prop->expr->type == E_SYMBOL) 1283 return prop->expr->left.sym; 1284 return NULL; 1285 } ··· 1296 return "menu"; 1297 case P_DEFAULT: 1298 return "default"; 1299 case P_SELECT: 1300 return "select"; 1301 case P_IMPLY:
-17
scripts/kconfig/tests/choice/Kconfig
··· 1 # SPDX-License-Identifier: GPL-2.0 2 3 - config MODULES 4 - bool "Enable loadable module support" 5 - modules 6 - default y 7 - 8 choice 9 prompt "boolean choice" 10 default BOOL_CHOICE1 ··· 9 10 config BOOL_CHOICE1 11 bool "choice 1" 12 - 13 - endchoice 14 - 15 - choice 16 - prompt "tristate choice" 17 - default TRI_CHOICE1 18 - 19 - config TRI_CHOICE0 20 - tristate "choice 0" 21 - 22 - config TRI_CHOICE1 23 - tristate "choice 1" 24 25 endchoice
··· 1 # SPDX-License-Identifier: GPL-2.0 2 3 choice 4 prompt "boolean choice" 5 default BOOL_CHOICE1 ··· 14 15 config BOOL_CHOICE1 16 bool "choice 1" 17 18 endchoice
-10
scripts/kconfig/tests/choice/__init__.py
··· 1 # SPDX-License-Identifier: GPL-2.0 2 """ 3 Basic choice tests. 4 - 5 - The handling of 'choice' is a bit complicated part in Kconfig. 6 - 7 - The behavior of 'y' choice is intuitive. If choice values are tristate, 8 - the choice can be 'm' where each value can be enabled independently. 9 """ 10 11 12 def test_oldask0(conf): 13 assert conf.oldaskconfig() == 0 14 assert conf.stdout_contains('oldask0_expected_stdout') 15 - 16 - 17 - def test_oldask1(conf): 18 - assert conf.oldaskconfig('oldask1_config') == 0 19 - assert conf.stdout_contains('oldask1_expected_stdout') 20 21 22 def test_allyes(conf):
··· 1 # SPDX-License-Identifier: GPL-2.0 2 """ 3 Basic choice tests. 4 """ 5 6 7 def test_oldask0(conf): 8 assert conf.oldaskconfig() == 0 9 assert conf.stdout_contains('oldask0_expected_stdout') 10 11 12 def test_allyes(conf):
-3
scripts/kconfig/tests/choice/alldef_expected_config
··· 1 - CONFIG_MODULES=y 2 # CONFIG_BOOL_CHOICE0 is not set 3 CONFIG_BOOL_CHOICE1=y 4 - # CONFIG_TRI_CHOICE0 is not set 5 - # CONFIG_TRI_CHOICE1 is not set
··· 1 # CONFIG_BOOL_CHOICE0 is not set 2 CONFIG_BOOL_CHOICE1=y
-3
scripts/kconfig/tests/choice/allmod_expected_config
··· 1 - CONFIG_MODULES=y 2 # CONFIG_BOOL_CHOICE0 is not set 3 CONFIG_BOOL_CHOICE1=y 4 - CONFIG_TRI_CHOICE0=m 5 - CONFIG_TRI_CHOICE1=m
··· 1 # CONFIG_BOOL_CHOICE0 is not set 2 CONFIG_BOOL_CHOICE1=y
-3
scripts/kconfig/tests/choice/allno_expected_config
··· 1 - # CONFIG_MODULES is not set 2 # CONFIG_BOOL_CHOICE0 is not set 3 CONFIG_BOOL_CHOICE1=y 4 - # CONFIG_TRI_CHOICE0 is not set 5 - CONFIG_TRI_CHOICE1=y
··· 1 # CONFIG_BOOL_CHOICE0 is not set 2 CONFIG_BOOL_CHOICE1=y
-3
scripts/kconfig/tests/choice/allyes_expected_config
··· 1 - CONFIG_MODULES=y 2 # CONFIG_BOOL_CHOICE0 is not set 3 CONFIG_BOOL_CHOICE1=y 4 - # CONFIG_TRI_CHOICE0 is not set 5 - CONFIG_TRI_CHOICE1=y
··· 1 # CONFIG_BOOL_CHOICE0 is not set 2 CONFIG_BOOL_CHOICE1=y
-4
scripts/kconfig/tests/choice/oldask0_expected_stdout
··· 1 - Enable loadable module support (MODULES) [Y/n/?] (NEW) 2 boolean choice 3 1. choice 0 (BOOL_CHOICE0) (NEW) 4 > 2. choice 1 (BOOL_CHOICE1) (NEW) 5 choice[1-2?]: 6 - tristate choice [M/y/?] (NEW) 7 - choice 0 (TRI_CHOICE0) [N/m/?] (NEW) 8 - choice 1 (TRI_CHOICE1) [N/m/?] (NEW)
··· 1 boolean choice 2 1. choice 0 (BOOL_CHOICE0) (NEW) 3 > 2. choice 1 (BOOL_CHOICE1) (NEW) 4 choice[1-2?]:
-1
scripts/kconfig/tests/choice/oldask1_config
··· 1 - # CONFIG_MODULES is not set
···
-9
scripts/kconfig/tests/choice/oldask1_expected_stdout
··· 1 - Enable loadable module support (MODULES) [N/y/?] 2 - boolean choice 3 - 1. choice 0 (BOOL_CHOICE0) (NEW) 4 - > 2. choice 1 (BOOL_CHOICE1) (NEW) 5 - choice[1-2?]: 6 - tristate choice 7 - 1. choice 0 (TRI_CHOICE0) (NEW) 8 - > 2. choice 1 (TRI_CHOICE1) (NEW) 9 - choice[1-2?]:
···
-21
scripts/kconfig/tests/choice_value_with_m_dep/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - 3 - config MODULES 4 - def_bool y 5 - modules 6 - 7 - config DEP 8 - tristate 9 - default m 10 - 11 - choice 12 - prompt "Tristate Choice" 13 - 14 - config CHOICE0 15 - tristate "Choice 0" 16 - 17 - config CHOICE1 18 - tristate "Choice 1" 19 - depends on DEP 20 - 21 - endchoice
···
-16
scripts/kconfig/tests/choice_value_with_m_dep/__init__.py
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - """ 3 - Hide tristate choice values with mod dependency in y choice. 4 - 5 - If tristate choice values depend on symbols set to 'm', they should be 6 - hidden when the choice containing them is changed from 'm' to 'y' 7 - (i.e. exclusive choice). 8 - 9 - Related Linux commit: fa64e5f6a35efd5e77d639125d973077ca506074 10 - """ 11 - 12 - 13 - def test(conf): 14 - assert conf.oldaskconfig('config', 'y') == 0 15 - assert conf.config_contains('expected_config') 16 - assert conf.stdout_contains('expected_stdout')
···
-2
scripts/kconfig/tests/choice_value_with_m_dep/config
··· 1 - CONFIG_CHOICE0=m 2 - CONFIG_CHOICE1=m
···
-3
scripts/kconfig/tests/choice_value_with_m_dep/expected_config
··· 1 - CONFIG_MODULES=y 2 - CONFIG_DEP=m 3 - CONFIG_CHOICE0=y
···
-4
scripts/kconfig/tests/choice_value_with_m_dep/expected_stdout
··· 1 - Tristate Choice [M/y/?] y 2 - Tristate Choice 3 - > 1. Choice 0 (CHOICE0) 4 - choice[1]: 1
···
+18 -18
scripts/kconfig/tests/err_recursive_dep/expected_stderr
··· 1 - Kconfig:5:error: recursive dependency detected! 2 - Kconfig:5: symbol A depends on A 3 For a resolution refer to Documentation/kbuild/kconfig-language.rst 4 subsection "Kconfig recursive dependency limitations" 5 6 - Kconfig:11:error: recursive dependency detected! 7 - Kconfig:11: symbol B is selected by B 8 For a resolution refer to Documentation/kbuild/kconfig-language.rst 9 subsection "Kconfig recursive dependency limitations" 10 11 - Kconfig:17:error: recursive dependency detected! 12 - Kconfig:17: symbol C1 depends on C2 13 - Kconfig:21: symbol C2 depends on C1 14 For a resolution refer to Documentation/kbuild/kconfig-language.rst 15 subsection "Kconfig recursive dependency limitations" 16 17 - Kconfig:27:error: recursive dependency detected! 18 - Kconfig:27: symbol D1 depends on D2 19 - Kconfig:32: symbol D2 is selected by D1 20 For a resolution refer to Documentation/kbuild/kconfig-language.rst 21 subsection "Kconfig recursive dependency limitations" 22 23 - Kconfig:37:error: recursive dependency detected! 24 - Kconfig:37: symbol E1 depends on E2 25 - Kconfig:42: symbol E2 is implied by E1 26 For a resolution refer to Documentation/kbuild/kconfig-language.rst 27 subsection "Kconfig recursive dependency limitations" 28 29 - Kconfig:49:error: recursive dependency detected! 30 - Kconfig:49: symbol F1 default value contains F2 31 - Kconfig:51: symbol F2 depends on F1 32 For a resolution refer to Documentation/kbuild/kconfig-language.rst 33 subsection "Kconfig recursive dependency limitations" 34 35 - Kconfig:60:error: recursive dependency detected! 36 - Kconfig:60: symbol G depends on G 37 For a resolution refer to Documentation/kbuild/kconfig-language.rst 38 subsection "Kconfig recursive dependency limitations"
··· 1 + error: recursive dependency detected! 2 + symbol A depends on A 3 For a resolution refer to Documentation/kbuild/kconfig-language.rst 4 subsection "Kconfig recursive dependency limitations" 5 6 + error: recursive dependency detected! 7 + symbol B is selected by B 8 For a resolution refer to Documentation/kbuild/kconfig-language.rst 9 subsection "Kconfig recursive dependency limitations" 10 11 + error: recursive dependency detected! 12 + symbol C1 depends on C2 13 + symbol C2 depends on C1 14 For a resolution refer to Documentation/kbuild/kconfig-language.rst 15 subsection "Kconfig recursive dependency limitations" 16 17 + error: recursive dependency detected! 18 + symbol D1 depends on D2 19 + symbol D2 is selected by D1 20 For a resolution refer to Documentation/kbuild/kconfig-language.rst 21 subsection "Kconfig recursive dependency limitations" 22 23 + error: recursive dependency detected! 24 + symbol E1 depends on E2 25 + symbol E2 is implied by E1 26 For a resolution refer to Documentation/kbuild/kconfig-language.rst 27 subsection "Kconfig recursive dependency limitations" 28 29 + error: recursive dependency detected! 30 + symbol F1 default value contains F2 31 + symbol F2 depends on F1 32 For a resolution refer to Documentation/kbuild/kconfig-language.rst 33 subsection "Kconfig recursive dependency limitations" 34 35 + error: recursive dependency detected! 36 + symbol G depends on G 37 For a resolution refer to Documentation/kbuild/kconfig-language.rst 38 subsection "Kconfig recursive dependency limitations"
-25
scripts/kconfig/tests/inter_choice/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - 3 - config MODULES 4 - def_bool y 5 - modules 6 - 7 - choice 8 - prompt "Choice" 9 - 10 - config CHOICE_VAL0 11 - tristate "Choice 0" 12 - 13 - config CHOIVE_VAL1 14 - tristate "Choice 1" 15 - 16 - endchoice 17 - 18 - choice 19 - prompt "Another choice" 20 - depends on CHOICE_VAL0 21 - 22 - config DUMMY 23 - bool "dummy" 24 - 25 - endchoice
···
-15
scripts/kconfig/tests/inter_choice/__init__.py
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - """ 3 - Do not affect user-assigned choice value by another choice. 4 - 5 - Handling of state flags for choices is complecated. In old days, 6 - the defconfig result of a choice could be affected by another choice 7 - if those choices interact by 'depends on', 'select', etc. 8 - 9 - Related Linux commit: fbe98bb9ed3dae23e320c6b113e35f129538d14a 10 - """ 11 - 12 - 13 - def test(conf): 14 - assert conf.defconfig('defconfig') == 0 15 - assert conf.config_contains('expected_config')
···
-1
scripts/kconfig/tests/inter_choice/defconfig
··· 1 - CONFIG_CHOICE_VAL0=y
···
-4
scripts/kconfig/tests/inter_choice/expected_config
··· 1 - CONFIG_MODULES=y 2 - CONFIG_CHOICE_VAL0=y 3 - # CONFIG_CHOIVE_VAL1 is not set 4 - CONFIG_DUMMY=y
···
+2 -2
scripts/kconfig/util.c
··· 8 #include <stdlib.h> 9 #include <string.h> 10 11 - #include "hashtable.h" 12 #include "lkc.h" 13 14 unsigned int strhash(const char *s) ··· 98 } 99 100 /* Retrieve value of growable string */ 101 - char *str_get(struct gstr *gs) 102 { 103 return gs->s; 104 }
··· 8 #include <stdlib.h> 9 #include <string.h> 10 11 + #include <hashtable.h> 12 #include "lkc.h" 13 14 unsigned int strhash(const char *s) ··· 98 } 99 100 /* Retrieve value of growable string */ 101 + char *str_get(const struct gstr *gs) 102 { 103 return gs->s; 104 }
+64 -22
scripts/make_fit.py
··· 22 Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and 23 zstd algorithms. 24 25 The resulting FIT can be booted by bootloaders which support FIT, such 26 as U-Boot, Linuxboot, Tianocore, etc. 27 ··· 69 help='Specifies the architecture') 70 parser.add_argument('-c', '--compress', type=str, default='none', 71 help='Specifies the compression') 72 parser.add_argument('-E', '--external', action='store_true', 73 help='Convert the FIT to use external data') 74 parser.add_argument('-n', '--name', type=str, required=True, ··· 147 fsw.end_node() 148 seq = 0 149 with fsw.add_node('configurations'): 150 - for model, compat in entries: 151 seq += 1 152 with fsw.add_node(f'conf-{seq}'): 153 fsw.property('compatible', bytes(compat)) 154 fsw.property_string('description', model) 155 - fsw.property_string('fdt', f'fdt-{seq}') 156 fsw.property_string('kernel', 'kernel') 157 fsw.end_node() 158 ··· 200 fname (str): Filename containing the DTB 201 arch: FIT architecture, e.g. 'arm64' 202 compress (str): Compressed algorithm, e.g. 'gzip' 203 - 204 - Returns: 205 - tuple: 206 - str: Model name 207 - bytes: Compatible stringlist 208 """ 209 with fsw.add_node(f'fdt-{seq}'): 210 - # Get the compatible / model information 211 - with open(fname, 'rb') as inf: 212 - data = inf.read() 213 - fdt = libfdt.FdtRo(data) 214 - model = fdt.getprop(0, 'model').as_str() 215 - compat = fdt.getprop(0, 'compatible') 216 - 217 - fsw.property_string('description', model) 218 fsw.property_string('type', 'flat_dt') 219 fsw.property_string('arch', arch) 220 fsw.property_string('compression', compress) ··· 210 with open(fname, 'rb') as inf: 211 compressed = compress_data(inf, compress) 212 fsw.property('data', compressed) 213 - return model, compat 214 215 216 def build_fit(args): 217 """Build the FIT from the provided files and arguments ··· 266 fsw = libfdt.FdtSw() 267 setup_fit(fsw, args.name) 268 entries = [] 269 270 # Handle the kernel 271 with open(args.kernel, 'rb') as inf: ··· 275 write_kernel(fsw, comp_data, args) 276 277 for fname in args.dtbs: 278 - # Ignore overlay (.dtbo) files 279 - if os.path.splitext(fname)[1] == '.dtb': 280 - seq += 1 281 - size += os.path.getsize(fname) 282 - model, compat = output_dtb(fsw, seq, fname, args.arch, args.compress) 283 - entries.append([model, compat]) 284 285 finish_fit(fsw, entries) 286
··· 22 Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and 23 zstd algorithms. 24 25 + Use -D to decompose "composite" DTBs into their base components and 26 + deduplicate the resulting base DTBs and DTB overlays. This requires the 27 + DTBs to be sourced from the kernel build directory, as the implementation 28 + looks at the .cmd files produced by the kernel build. 29 + 30 The resulting FIT can be booted by bootloaders which support FIT, such 31 as U-Boot, Linuxboot, Tianocore, etc. 32 ··· 64 help='Specifies the architecture') 65 parser.add_argument('-c', '--compress', type=str, default='none', 66 help='Specifies the compression') 67 + parser.add_argument('-D', '--decompose-dtbs', action='store_true', 68 + help='Decompose composite DTBs into base DTB and overlays') 69 parser.add_argument('-E', '--external', action='store_true', 70 help='Convert the FIT to use external data') 71 parser.add_argument('-n', '--name', type=str, required=True, ··· 140 fsw.end_node() 141 seq = 0 142 with fsw.add_node('configurations'): 143 + for model, compat, files in entries: 144 seq += 1 145 with fsw.add_node(f'conf-{seq}'): 146 fsw.property('compatible', bytes(compat)) 147 fsw.property_string('description', model) 148 + fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) 149 fsw.property_string('kernel', 'kernel') 150 fsw.end_node() 151 ··· 193 fname (str): Filename containing the DTB 194 arch: FIT architecture, e.g. 'arm64' 195 compress (str): Compressed algorithm, e.g. 'gzip' 196 """ 197 with fsw.add_node(f'fdt-{seq}'): 198 + fsw.property_string('description', os.path.basename(fname)) 199 fsw.property_string('type', 'flat_dt') 200 fsw.property_string('arch', arch) 201 fsw.property_string('compression', compress) ··· 215 with open(fname, 'rb') as inf: 216 compressed = compress_data(inf, compress) 217 fsw.property('data', compressed) 218 219 + 220 + def process_dtb(fname, args): 221 + """Process an input DTB, decomposing it if requested and is possible 222 + 223 + Args: 224 + fname (str): Filename containing the DTB 225 + args (Namespace): Program arguments 226 + Returns: 227 + tuple: 228 + str: Model name string 229 + str: Root compatible string 230 + files: list of filenames corresponding to the DTB 231 + """ 232 + # Get the compatible / model information 233 + with open(fname, 'rb') as inf: 234 + data = inf.read() 235 + fdt = libfdt.FdtRo(data) 236 + model = fdt.getprop(0, 'model').as_str() 237 + compat = fdt.getprop(0, 'compatible') 238 + 239 + if args.decompose_dtbs: 240 + # Check if the DTB needs to be decomposed 241 + path, basename = os.path.split(fname) 242 + cmd_fname = os.path.join(path, f'.{basename}.cmd') 243 + with open(cmd_fname, 'r', encoding='ascii') as inf: 244 + cmd = inf.read() 245 + 246 + if 'scripts/dtc/fdtoverlay' in cmd: 247 + # This depends on the structure of the composite DTB command 248 + files = cmd.split() 249 + files = files[files.index('-i') + 1:] 250 + else: 251 + files = [fname] 252 + else: 253 + files = [fname] 254 + 255 + return (model, compat, files) 256 257 def build_fit(args): 258 """Build the FIT from the provided files and arguments ··· 235 fsw = libfdt.FdtSw() 236 setup_fit(fsw, args.name) 237 entries = [] 238 + fdts = {} 239 240 # Handle the kernel 241 with open(args.kernel, 'rb') as inf: ··· 243 write_kernel(fsw, comp_data, args) 244 245 for fname in args.dtbs: 246 + # Ignore non-DTB (*.dtb) files 247 + if os.path.splitext(fname)[1] != '.dtb': 248 + continue 249 + 250 + (model, compat, files) = process_dtb(fname, args) 251 + 252 + for fn in files: 253 + if fn not in fdts: 254 + seq += 1 255 + size += os.path.getsize(fn) 256 + output_dtb(fsw, seq, fn, args.arch, args.compress) 257 + fdts[fn] = seq 258 + 259 + files_seq = [fdts[fn] for fn in files] 260 + 261 + entries.append([model, compat, files_seq]) 262 263 finish_fit(fsw, entries) 264
-213
scripts/mod/list.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef LIST_H 3 - #define LIST_H 4 - 5 - #include <stdbool.h> 6 - #include <stddef.h> 7 - 8 - /* Are two types/vars the same type (ignoring qualifiers)? */ 9 - #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) 10 - 11 - /** 12 - * container_of - cast a member of a structure out to the containing structure 13 - * @ptr: the pointer to the member. 14 - * @type: the type of the container struct this is embedded in. 15 - * @member: the name of the member within the struct. 16 - * 17 - */ 18 - #define container_of(ptr, type, member) ({ \ 19 - void *__mptr = (void *)(ptr); \ 20 - _Static_assert(__same_type(*(ptr), ((type *)0)->member) || \ 21 - __same_type(*(ptr), void), \ 22 - "pointer type mismatch in container_of()"); \ 23 - ((type *)(__mptr - offsetof(type, member))); }) 24 - 25 - #define LIST_POISON1 ((void *) 0x100) 26 - #define LIST_POISON2 ((void *) 0x122) 27 - 28 - /* 29 - * Circular doubly linked list implementation. 30 - * 31 - * Some of the internal functions ("__xxx") are useful when 32 - * manipulating whole lists rather than single entries, as 33 - * sometimes we already know the next/prev entries and we can 34 - * generate better code by using them directly rather than 35 - * using the generic single-entry routines. 36 - */ 37 - 38 - struct list_head { 39 - struct list_head *next, *prev; 40 - }; 41 - 42 - #define LIST_HEAD_INIT(name) { &(name), &(name) } 43 - 44 - #define LIST_HEAD(name) \ 45 - struct list_head name = LIST_HEAD_INIT(name) 46 - 47 - /** 48 - * INIT_LIST_HEAD - Initialize a list_head structure 49 - * @list: list_head structure to be initialized. 50 - * 51 - * Initializes the list_head to point to itself. If it is a list header, 52 - * the result is an empty list. 53 - */ 54 - static inline void INIT_LIST_HEAD(struct list_head *list) 55 - { 56 - list->next = list; 57 - list->prev = list; 58 - } 59 - 60 - /* 61 - * Insert a new entry between two known consecutive entries. 62 - * 63 - * This is only for internal list manipulation where we know 64 - * the prev/next entries already! 65 - */ 66 - static inline void __list_add(struct list_head *new, 67 - struct list_head *prev, 68 - struct list_head *next) 69 - { 70 - next->prev = new; 71 - new->next = next; 72 - new->prev = prev; 73 - prev->next = new; 74 - } 75 - 76 - /** 77 - * list_add - add a new entry 78 - * @new: new entry to be added 79 - * @head: list head to add it after 80 - * 81 - * Insert a new entry after the specified head. 82 - * This is good for implementing stacks. 83 - */ 84 - static inline void list_add(struct list_head *new, struct list_head *head) 85 - { 86 - __list_add(new, head, head->next); 87 - } 88 - 89 - /** 90 - * list_add_tail - add a new entry 91 - * @new: new entry to be added 92 - * @head: list head to add it before 93 - * 94 - * Insert a new entry before the specified head. 95 - * This is useful for implementing queues. 96 - */ 97 - static inline void list_add_tail(struct list_head *new, struct list_head *head) 98 - { 99 - __list_add(new, head->prev, head); 100 - } 101 - 102 - /* 103 - * Delete a list entry by making the prev/next entries 104 - * point to each other. 105 - * 106 - * This is only for internal list manipulation where we know 107 - * the prev/next entries already! 108 - */ 109 - static inline void __list_del(struct list_head *prev, struct list_head *next) 110 - { 111 - next->prev = prev; 112 - prev->next = next; 113 - } 114 - 115 - static inline void __list_del_entry(struct list_head *entry) 116 - { 117 - __list_del(entry->prev, entry->next); 118 - } 119 - 120 - /** 121 - * list_del - deletes entry from list. 122 - * @entry: the element to delete from the list. 123 - * Note: list_empty() on entry does not return true after this, the entry is 124 - * in an undefined state. 125 - */ 126 - static inline void list_del(struct list_head *entry) 127 - { 128 - __list_del_entry(entry); 129 - entry->next = LIST_POISON1; 130 - entry->prev = LIST_POISON2; 131 - } 132 - 133 - /** 134 - * list_is_head - tests whether @list is the list @head 135 - * @list: the entry to test 136 - * @head: the head of the list 137 - */ 138 - static inline int list_is_head(const struct list_head *list, const struct list_head *head) 139 - { 140 - return list == head; 141 - } 142 - 143 - /** 144 - * list_empty - tests whether a list is empty 145 - * @head: the list to test. 146 - */ 147 - static inline int list_empty(const struct list_head *head) 148 - { 149 - return head->next == head; 150 - } 151 - 152 - /** 153 - * list_entry - get the struct for this entry 154 - * @ptr: the &struct list_head pointer. 155 - * @type: the type of the struct this is embedded in. 156 - * @member: the name of the list_head within the struct. 157 - */ 158 - #define list_entry(ptr, type, member) \ 159 - container_of(ptr, type, member) 160 - 161 - /** 162 - * list_first_entry - get the first element from a list 163 - * @ptr: the list head to take the element from. 164 - * @type: the type of the struct this is embedded in. 165 - * @member: the name of the list_head within the struct. 166 - * 167 - * Note, that list is expected to be not empty. 168 - */ 169 - #define list_first_entry(ptr, type, member) \ 170 - list_entry((ptr)->next, type, member) 171 - 172 - /** 173 - * list_next_entry - get the next element in list 174 - * @pos: the type * to cursor 175 - * @member: the name of the list_head within the struct. 176 - */ 177 - #define list_next_entry(pos, member) \ 178 - list_entry((pos)->member.next, typeof(*(pos)), member) 179 - 180 - /** 181 - * list_entry_is_head - test if the entry points to the head of the list 182 - * @pos: the type * to cursor 183 - * @head: the head for your list. 184 - * @member: the name of the list_head within the struct. 185 - */ 186 - #define list_entry_is_head(pos, head, member) \ 187 - (&pos->member == (head)) 188 - 189 - /** 190 - * list_for_each_entry - iterate over list of given type 191 - * @pos: the type * to use as a loop cursor. 192 - * @head: the head for your list. 193 - * @member: the name of the list_head within the struct. 194 - */ 195 - #define list_for_each_entry(pos, head, member) \ 196 - for (pos = list_first_entry(head, typeof(*pos), member); \ 197 - !list_entry_is_head(pos, head, member); \ 198 - pos = list_next_entry(pos, member)) 199 - 200 - /** 201 - * list_for_each_entry_safe - iterate over list of given type. Safe against removal of list entry 202 - * @pos: the type * to use as a loop cursor. 203 - * @n: another type * to use as temporary storage 204 - * @head: the head for your list. 205 - * @member: the name of the list_head within the struct. 206 - */ 207 - #define list_for_each_entry_safe(pos, n, head, member) \ 208 - for (pos = list_first_entry(head, typeof(*pos), member), \ 209 - n = list_next_entry(pos, member); \ 210 - !list_entry_is_head(pos, head, member); \ 211 - pos = n, n = list_next_entry(n, member)) 212 - 213 - #endif /* LIST_H */
···
+8 -59
scripts/mod/modpost.c
··· 20 #include <limits.h> 21 #include <stdbool.h> 22 #include <errno.h> 23 #include "modpost.h" 24 #include "../../include/linux/license.h" 25 ··· 202 return mod; 203 } 204 205 - /* A hash of all exported symbols, 206 - * struct symbol is also used for lists of unresolved symbols */ 207 - 208 - #define SYMBOL_HASH_SIZE 1024 209 - 210 struct symbol { 211 - struct symbol *next; 212 struct list_head list; /* link to module::exported_symbols or module::unresolved_symbols */ 213 struct module *module; 214 char *namespace; ··· 216 char name[]; 217 }; 218 219 - static struct symbol *symbolhash[SYMBOL_HASH_SIZE]; 220 221 /* This is based on the hash algorithm from gdbm, via tdb */ 222 static inline unsigned int tdb_hash(const char *name) ··· 248 /* For the hash of exported symbols */ 249 static void hash_add_symbol(struct symbol *sym) 250 { 251 - unsigned int hash; 252 - 253 - hash = tdb_hash(sym->name) % SYMBOL_HASH_SIZE; 254 - sym->next = symbolhash[hash]; 255 - symbolhash[hash] = sym; 256 } 257 258 static void sym_add_unresolved(const char *name, struct module *mod, bool weak) ··· 269 if (name[0] == '.') 270 name++; 271 272 - for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) { 273 if (strcmp(s->name, name) == 0 && (!mod || s->module == mod)) 274 return s; 275 } ··· 948 match(fromsym, PATTERNS("*_ops", "*_probe", "*_console"))) 949 return 0; 950 951 - /* 952 - * symbols in data sections must not refer to .exit.*, but there are 953 - * quite a few offenders, so hide these unless for W=1 builds until 954 - * these are fixed. 955 - */ 956 - if (!extra_warn && 957 - match(fromsec, PATTERNS(DATA_SECTIONS)) && 958 - match(tosec, PATTERNS(ALL_EXIT_SECTIONS)) && 959 - match(fromsym, PATTERNS("*driver"))) 960 - return 0; 961 - 962 /* Check for pattern 3 */ 963 if (strstarts(fromsec, ".head.text") && 964 match(tosec, PATTERNS(ALL_INIT_SECTIONS))) ··· 1151 return (Elf_Addr)(-1); 1152 } 1153 1154 - #ifndef R_ARM_CALL 1155 - #define R_ARM_CALL 28 1156 - #endif 1157 - #ifndef R_ARM_JUMP24 1158 - #define R_ARM_JUMP24 29 1159 - #endif 1160 - 1161 - #ifndef R_ARM_THM_CALL 1162 - #define R_ARM_THM_CALL 10 1163 - #endif 1164 - #ifndef R_ARM_THM_JUMP24 1165 - #define R_ARM_THM_JUMP24 30 1166 - #endif 1167 - 1168 - #ifndef R_ARM_MOVW_ABS_NC 1169 - #define R_ARM_MOVW_ABS_NC 43 1170 - #endif 1171 - 1172 - #ifndef R_ARM_MOVT_ABS 1173 - #define R_ARM_MOVT_ABS 44 1174 - #endif 1175 - 1176 - #ifndef R_ARM_THM_MOVW_ABS_NC 1177 - #define R_ARM_THM_MOVW_ABS_NC 47 1178 - #endif 1179 - 1180 - #ifndef R_ARM_THM_MOVT_ABS 1181 - #define R_ARM_THM_MOVT_ABS 48 1182 - #endif 1183 - 1184 - #ifndef R_ARM_THM_JUMP19 1185 - #define R_ARM_THM_JUMP19 51 1186 - #endif 1187 - 1188 static int32_t sign_extend32(int32_t value, int index) 1189 { 1190 uint8_t shift = 31 - index; ··· 1211 ((lower & 0x07ff) << 1), 1212 20); 1213 return offset + sym->st_value + 4; 1214 - case R_ARM_THM_CALL: 1215 case R_ARM_THM_JUMP24: 1216 /* 1217 * Encoding T4:
··· 20 #include <limits.h> 21 #include <stdbool.h> 22 #include <errno.h> 23 + 24 + #include <hashtable.h> 25 + #include <list.h> 26 #include "modpost.h" 27 #include "../../include/linux/license.h" 28 ··· 199 return mod; 200 } 201 202 struct symbol { 203 + struct hlist_node hnode;/* link to hash table */ 204 struct list_head list; /* link to module::exported_symbols or module::unresolved_symbols */ 205 struct module *module; 206 char *namespace; ··· 218 char name[]; 219 }; 220 221 + static HASHTABLE_DEFINE(symbol_hashtable, 1U << 10); 222 223 /* This is based on the hash algorithm from gdbm, via tdb */ 224 static inline unsigned int tdb_hash(const char *name) ··· 250 /* For the hash of exported symbols */ 251 static void hash_add_symbol(struct symbol *sym) 252 { 253 + hash_add(symbol_hashtable, &sym->hnode, tdb_hash(sym->name)); 254 } 255 256 static void sym_add_unresolved(const char *name, struct module *mod, bool weak) ··· 275 if (name[0] == '.') 276 name++; 277 278 + hash_for_each_possible(symbol_hashtable, s, hnode, tdb_hash(name)) { 279 if (strcmp(s->name, name) == 0 && (!mod || s->module == mod)) 280 return s; 281 } ··· 954 match(fromsym, PATTERNS("*_ops", "*_probe", "*_console"))) 955 return 0; 956 957 /* Check for pattern 3 */ 958 if (strstarts(fromsec, ".head.text") && 959 match(tosec, PATTERNS(ALL_INIT_SECTIONS))) ··· 1168 return (Elf_Addr)(-1); 1169 } 1170 1171 static int32_t sign_extend32(int32_t value, int index) 1172 { 1173 uint8_t shift = 31 - index; ··· 1262 ((lower & 0x07ff) << 1), 1263 20); 1264 return offset + sym->st_value + 4; 1265 + case R_ARM_THM_PC22: 1266 case R_ARM_THM_JUMP24: 1267 /* 1268 * Encoding T4:
+1 -1
scripts/mod/modpost.h
··· 13 #include <elf.h> 14 #include "../../include/linux/module_symbol.h" 15 16 - #include "list.h" 17 #include "elfconfig.h" 18 19 /* On BSD-alike OSes elf.h defines these according to host's word size */
··· 13 #include <elf.h> 14 #include "../../include/linux/module_symbol.h" 15 16 + #include <list_types.h> 17 #include "elfconfig.h" 18 19 /* On BSD-alike OSes elf.h defines these according to host's word size */
+108
scripts/package/PKGBUILD
···
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # Maintainer: Thomas Weißschuh <linux@weissschuh.net> 3 + # Contributor: Jan Alexander Steffens (heftig) <heftig@archlinux.org> 4 + 5 + pkgbase=${PACMAN_PKGBASE:-linux-upstream} 6 + pkgname=("${pkgbase}" "${pkgbase}-api-headers") 7 + if grep -q CONFIG_MODULES=y include/config/auto.conf; then 8 + pkgname+=("${pkgbase}-headers") 9 + fi 10 + pkgver="${KERNELRELEASE//-/_}" 11 + # The PKGBUILD is evaluated multiple times. 12 + # Running scripts/build-version from here would introduce inconsistencies. 13 + pkgrel="${KBUILD_REVISION}" 14 + pkgdesc='Upstream Linux' 15 + url='https://www.kernel.org/' 16 + # Enable flexible cross-compilation 17 + arch=(${CARCH}) 18 + license=(GPL-2.0-only) 19 + makedepends=( 20 + bc 21 + bison 22 + cpio 23 + flex 24 + gettext 25 + kmod 26 + libelf 27 + openssl 28 + pahole 29 + perl 30 + python 31 + rsync 32 + tar 33 + ) 34 + options=(!debug !strip !buildflags !makeflags) 35 + 36 + build() { 37 + # MAKEFLAGS from makepkg.conf override the ones inherited from kbuild. 38 + # Bypass this override with a custom variable. 39 + export MAKEFLAGS="${KBUILD_MAKEFLAGS}" 40 + cd "${objtree}" 41 + 42 + ${MAKE} KERNELRELEASE="${KERNELRELEASE}" KBUILD_BUILD_VERSION="${pkgrel}" 43 + } 44 + 45 + _package() { 46 + pkgdesc="The ${pkgdesc} kernel and modules" 47 + 48 + export MAKEFLAGS="${KBUILD_MAKEFLAGS}" 49 + cd "${objtree}" 50 + local modulesdir="${pkgdir}/usr/${MODLIB}" 51 + 52 + echo "Installing boot image..." 53 + # systemd expects to find the kernel here to allow hibernation 54 + # https://github.com/systemd/systemd/commit/edda44605f06a41fb86b7ab8128dcf99161d2344 55 + install -Dm644 "$(${MAKE} -s image_name)" "${modulesdir}/vmlinuz" 56 + 57 + # Used by mkinitcpio to name the kernel 58 + echo "${pkgbase}" > "${modulesdir}/pkgbase" 59 + 60 + echo "Installing modules..." 61 + ${MAKE} INSTALL_MOD_PATH="${pkgdir}/usr" INSTALL_MOD_STRIP=1 \ 62 + DEPMOD=true modules_install 63 + 64 + if [ -d "${srctree}/arch/${SRCARCH}/boot/dts" ]; then 65 + echo "Installing dtbs..." 66 + ${MAKE} INSTALL_DTBS_PATH="${modulesdir}/dtb" dtbs_install 67 + fi 68 + 69 + # remove build link, will be part of -headers package 70 + rm -f "${modulesdir}/build" 71 + } 72 + 73 + _package-headers() { 74 + pkgdesc="Headers and scripts for building modules for the ${pkgdesc} kernel" 75 + 76 + export MAKEFLAGS="${KBUILD_MAKEFLAGS}" 77 + cd "${objtree}" 78 + local builddir="${pkgdir}/usr/${MODLIB}/build" 79 + 80 + echo "Installing build files..." 81 + "${srctree}/scripts/package/install-extmod-build" "${builddir}" 82 + 83 + echo "Installing System.map and config..." 84 + cp System.map "${builddir}/System.map" 85 + cp .config "${builddir}/.config" 86 + 87 + echo "Adding symlink..." 88 + mkdir -p "${pkgdir}/usr/src" 89 + ln -sr "${builddir}" "${pkgdir}/usr/src/${pkgbase}" 90 + } 91 + 92 + _package-api-headers() { 93 + pkgdesc="Kernel headers sanitized for use in userspace" 94 + provides=(linux-api-headers) 95 + conflicts=(linux-api-headers) 96 + 97 + export MAKEFLAGS="${KBUILD_MAKEFLAGS}" 98 + cd "${objtree}" 99 + 100 + ${MAKE} headers_install INSTALL_HDR_PATH="${pkgdir}/usr" 101 + } 102 + 103 + for _p in "${pkgname[@]}"; do 104 + eval "package_$_p() { 105 + $(declare -f "_package${_p#$pkgbase}") 106 + _package${_p#$pkgbase} 107 + }" 108 + done
+1 -1
scripts/package/builddeb
··· 10 # specified in KDEB_HOOKDIR) that will be called on package install and 11 # removal. 12 13 - set -e 14 15 is_enabled() { 16 grep -q "^$1=y" include/config/auto.conf
··· 10 # specified in KDEB_HOOKDIR) that will be called on package install and 11 # removal. 12 13 + set -eu 14 15 is_enabled() { 16 grep -q "^$1=y" include/config/auto.conf
+1 -1
scripts/package/buildtar
··· 11 # Wichert Akkerman <wichert@wiggy.net>. 12 # 13 14 - set -e 15 16 # 17 # Some variables and settings used throughout the script
··· 11 # Wichert Akkerman <wichert@wiggy.net>. 12 # 13 14 + set -eu 15 16 # 17 # Some variables and settings used throughout the script
+2
scripts/package/gen-diff-patch
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0-only 3 4 diff_patch=$1 5 6 mkdir -p "$(dirname "${diff_patch}")"
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0-only 3 4 + set -eu 5 + 6 diff_patch=$1 7 8 mkdir -p "$(dirname "${diff_patch}")"
+1 -4
scripts/package/install-extmod-build
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0-only 3 4 - set -e 5 6 destdir=${1} 7 - 8 - test -n "${srctree}" 9 - test -n "${SRCARCH}" 10 11 is_enabled() { 12 grep -q "^$1=y" include/config/auto.conf
··· 1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0-only 3 4 + set -eu 5 6 destdir=${1} 7 8 is_enabled() { 9 grep -q "^$1=y" include/config/auto.conf
+1 -1
scripts/package/kernel.spec
··· 27 %package headers 28 Summary: Header files for the Linux kernel for use by glibc 29 Group: Development/System 30 - Obsoletes: kernel-headers 31 Provides: kernel-headers = %{version} 32 %description headers 33 Kernel-headers includes the C header files that specify the interface
··· 27 %package headers 28 Summary: Header files for the Linux kernel for use by glibc 29 Group: Development/System 30 + Obsoletes: kernel-headers < %{version} 31 Provides: kernel-headers = %{version} 32 %description headers 33 Kernel-headers includes the C header files that specify the interface
+23 -21
scripts/package/mkdebian
··· 4 # 5 # Simple script to generate a debian/ directory for a Linux kernel. 6 7 - set -e 8 9 is_enabled() { 10 grep -q "^$1=y" include/config/auto.conf ··· 19 } 20 21 set_debarch() { 22 - if [ -n "$KBUILD_DEBARCH" ] ; then 23 debarch="$KBUILD_DEBARCH" 24 return 25 fi ··· 125 rm -rf debian 126 mkdir debian 127 128 - email=${DEBEMAIL-$EMAIL} 129 - 130 - # use email string directly if it contains <email> 131 - if echo "${email}" | grep -q '<.*>'; then 132 - maintainer=${email} 133 else 134 - # or construct the maintainer string 135 - user=${KBUILD_BUILD_USER-$(id -nu)} 136 - name=${DEBFULLNAME-${user}} 137 - if [ -z "${email}" ]; then 138 - buildhost=${KBUILD_BUILD_HOST-$(hostname -f 2>/dev/null || hostname)} 139 - email="${user}@${buildhost}" 140 - fi 141 - maintainer="${name} <${email}>" 142 fi 143 144 - if [ "$1" = --need-source ]; then 145 - gen_source 146 - fi 147 148 # Some variables and settings used throughout the script 149 version=$KERNELRELEASE 150 - if [ -n "$KDEB_PKGVERSION" ]; then 151 packageversion=$KDEB_PKGVERSION 152 else 153 - packageversion=$(${srctree}/scripts/setlocalversion --no-local ${srctree})-$($srctree/init/build-version) 154 fi 155 sourcename=${KDEB_SOURCENAME:-linux-upstream} 156 ··· 166 set_debarch 167 168 # Try to determine distribution 169 - if [ -n "$KDEB_CHANGELOG_DIST" ]; then 170 distribution=$KDEB_CHANGELOG_DIST 171 # In some cases lsb_release returns the codename as n/a, which breaks dpkg-parsechangelog 172 elif distribution=$(lsb_release -cs 2>/dev/null) && [ -n "$distribution" ] && [ "$distribution" != "n/a" ]; then
··· 4 # 5 # Simple script to generate a debian/ directory for a Linux kernel. 6 7 + set -eu 8 9 is_enabled() { 10 grep -q "^$1=y" include/config/auto.conf ··· 19 } 20 21 set_debarch() { 22 + if [ "${KBUILD_DEBARCH:+set}" ]; then 23 debarch="$KBUILD_DEBARCH" 24 return 25 fi ··· 125 rm -rf debian 126 mkdir debian 127 128 + user=${KBUILD_BUILD_USER:-$(id -nu)} 129 + name=${DEBFULLNAME:-${user}} 130 + if [ "${DEBEMAIL:+set}" ]; then 131 + email=${DEBEMAIL} 132 else 133 + buildhost=${KBUILD_BUILD_HOST:-$(hostname -f 2>/dev/null || hostname)} 134 + email="${user}@${buildhost}" 135 fi 136 + maintainer="${name} <${email}>" 137 138 + while [ $# -gt 0 ]; do 139 + case "$1" in 140 + --need-source) 141 + gen_source 142 + shift 143 + ;; 144 + *) 145 + break 146 + ;; 147 + esac 148 + done 149 150 # Some variables and settings used throughout the script 151 version=$KERNELRELEASE 152 + if [ "${KDEB_PKGVERSION:+set}" ]; then 153 packageversion=$KDEB_PKGVERSION 154 else 155 + packageversion=$(${srctree}/scripts/setlocalversion --no-local ${srctree})-$($srctree/scripts/build-version) 156 fi 157 sourcename=${KDEB_SOURCENAME:-linux-upstream} 158 ··· 164 set_debarch 165 166 # Try to determine distribution 167 + if [ "${KDEB_CHANGELOG_DIST:+set}" ]; then 168 distribution=$KDEB_CHANGELOG_DIST 169 # In some cases lsb_release returns the codename as n/a, which breaks dpkg-parsechangelog 170 elif distribution=$(lsb_release -cs 2>/dev/null) && [ -n "$distribution" ] && [ "$distribution" != "n/a" ]; then
+26 -1
scripts/package/mkspec
··· 9 # Patched for non-x86 by Opencon (L) 2002 <opencon@rio.skydome.net> 10 # 11 12 output=$1 13 14 mkdir -p "$(dirname "${output}")" ··· 26 cat<<EOF 27 %define ARCH ${ARCH} 28 %define KERNELRELEASE ${KERNELRELEASE} 29 - %define pkg_release $("${srctree}/init/build-version") 30 EOF 31 32 cat "${srctree}/scripts/package/kernel.spec"
··· 9 # Patched for non-x86 by Opencon (L) 2002 <opencon@rio.skydome.net> 10 # 11 12 + set -eu 13 + 14 output=$1 15 16 mkdir -p "$(dirname "${output}")" ··· 24 cat<<EOF 25 %define ARCH ${ARCH} 26 %define KERNELRELEASE ${KERNELRELEASE} 27 + %define pkg_release $("${srctree}/scripts/build-version") 28 EOF 29 30 cat "${srctree}/scripts/package/kernel.spec" 31 + 32 + # collect the user's name and email address for the changelog entry 33 + if [ "$(command -v git)" ]; then 34 + name=$(git config user.name) || true 35 + email=$(git config user.email) || true 36 + fi 37 + 38 + if [ ! "${name:+set}" ]; then 39 + name=${KBUILD_BUILD_USER:-$(id -nu)} 40 + fi 41 + 42 + if [ ! "${email:+set}" ]; then 43 + buildhost=${KBUILD_BUILD_HOST:-$(hostname -f 2>/dev/null || hostname)} 44 + builduser=${KBUILD_BUILD_USER:-$(id -nu)} 45 + email="${builduser}@${buildhost}" 46 + fi 47 + 48 + cat << EOF 49 + 50 + %changelog 51 + * $(LC_ALL=C; date +'%a %b %d %Y') ${name} <${email}> 52 + - Custom built Linux kernel. 53 + EOF
-18
scripts/remove-stale-files
··· 20 # yard. Stale files stay in this file for a while (for some release cycles?), 21 # then will be really dead and removed from the code base entirely. 22 23 - rm -f arch/powerpc/purgatory/kexec-purgatory.c 24 - rm -f arch/riscv/purgatory/kexec-purgatory.c 25 - rm -f arch/x86/purgatory/kexec-purgatory.c 26 - 27 - rm -f scripts/extract-cert 28 - 29 - rm -f scripts/kconfig/[gmnq]conf-cfg 30 - 31 - rm -f rust/target.json 32 - 33 - rm -f scripts/bin2c 34 - 35 - rm -f .scmversion 36 - 37 - rm -rf include/ksym 38 - 39 - find . -name '*.usyms' | xargs rm -f 40 - 41 rm -f *.spec
··· 20 # yard. Stale files stay in this file for a while (for some release cycles?), 21 # then will be really dead and removed from the code base entirely. 22 23 rm -f *.spec
-1
tools/perf/tests/vmlinux-kallsyms.c
··· 26 * when --all-symbols is specified so exclude them to get a 27 * stable symbol list. 28 */ 29 - "kallsyms_addresses", 30 "kallsyms_offsets", 31 "kallsyms_relative_base", 32 "kallsyms_num_syms",
··· 26 * when --all-symbols is specified so exclude them to get a 27 * stable symbol list. 28 */ 29 "kallsyms_offsets", 30 "kallsyms_relative_base", 31 "kallsyms_num_syms",
+2 -2
usr/Makefile
··· 62 quiet_cmd_initfs = GEN $@ 63 cmd_initfs = \ 64 $(CONFIG_SHELL) $< -o $@ -l $(obj)/.initramfs_data.cpio.d \ 65 - $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \ 66 - $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID)) \ 67 $(if $(KBUILD_BUILD_TIMESTAMP), -d "$(KBUILD_BUILD_TIMESTAMP)") \ 68 $(ramfs-input) 69
··· 62 quiet_cmd_initfs = GEN $@ 63 cmd_initfs = \ 64 $(CONFIG_SHELL) $< -o $@ -l $(obj)/.initramfs_data.cpio.d \ 65 + $(addprefix -u , $(CONFIG_INITRAMFS_ROOT_UID)) \ 66 + $(addprefix -g , $(CONFIG_INITRAMFS_ROOT_GID)) \ 67 $(if $(KBUILD_BUILD_TIMESTAMP), -d "$(KBUILD_BUILD_TIMESTAMP)") \ 68 $(ramfs-input) 69