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