History

Merge 7.0 Kbuild changes into kbuild-fixes

kbuild-fixes needs to be based on 6.19 to apply some fixes for 62089b804895 ("kbuild: rpm-pkg: Generate debuginfo package manually") which landed in 6.19-rc1 but the new material of 7.0 needs fixes merged as well.

Nathan Chancellor committed 9 months ago

Commit df989b02 parents 05f7e89 d8ad80a63 files · +1515 −626Browse files

Showing the changes to scripts (41 of 63 files). Show all

Unified · Split

41 files
  1. scripts/Kconfig.include +0 −2
  2. scripts/Makefile.lib +1 −1
  3. scripts/Makefile.package +0 −1
  4. scripts/Makefile.warn +13 −14
  5. scripts/container +199 −0
  6. scripts/dummy-tools/python3 +4 −0
  7. scripts/kallsyms.c +17 −47
  8. scripts/kconfig/Makefile +2 −2
  9. scripts/kconfig/gconf.c +28 −7
  10. scripts/kconfig/icons/back.xpm +29 −0
  11. scripts/kconfig/icons/choice_no.xpm +18 −0
  12. scripts/kconfig/icons/choice_yes.xpm +18 −0
  13. scripts/kconfig/icons/load.xpm +31 −0
  14. scripts/kconfig/icons/menu.xpm +18 −0
  15. scripts/kconfig/icons/menuback.xpm +18 −0
  16. scripts/kconfig/icons/save.xpm +31 −0
  17. scripts/kconfig/icons/single_view.xpm +28 −0
  18. scripts/kconfig/icons/split_view.xpm +28 −0
  19. scripts/kconfig/icons/symbol_mod.xpm +18 −0
  20. scripts/kconfig/icons/symbol_no.xpm +18 −0
  21. scripts/kconfig/icons/symbol_yes.xpm +18 −0
  22. scripts/kconfig/icons/tree_view.xpm +28 −0
  23. scripts/kconfig/images.c +0 −328
  24. scripts/kconfig/images.h +0 −33
  25. scripts/kconfig/lkc.h +1 −1
  26. scripts/kconfig/menu.c +11 −1
  27. scripts/kconfig/merge_config.sh +225 −51
  28. scripts/kconfig/parser.y +3 −3
  29. scripts/kconfig/qconf.cc +14 −15
  30. scripts/kconfig/streamline_config.pl +1 −1
  31. scripts/kconfig/tests/conditional_dep/Kconfig +32 −0
  32. scripts/kconfig/tests/conditional_dep/__init__.py +14 −0
  33. scripts/kconfig/tests/conditional_dep/expected_config1 +11 −0
  34. scripts/kconfig/tests/conditional_dep/expected_config2 +9 −0
  35. scripts/kconfig/tests/conditional_dep/expected_config3 +11 −0
  36. scripts/kconfig/tests/conditional_dep/test_config1 +6 −0
  37. scripts/kconfig/tests/conditional_dep/test_config2 +7 −0
  38. scripts/kconfig/tests/conditional_dep/test_config3 +6 −0
  39. scripts/link-vmlinux.sh +4 −0
  40. scripts/make_fit.py +144 −35
  41. scripts/mod/modpost.c +5 −1
scripts/Kconfig.include+0−2
@@ -73,8 +73,6 @@ rustc-llvm-version := $(shell,$(srctree)/scripts/rustc-llvm-version.sh $(RUSTC)) · 72 unmodified lines
73 73
74# $(rustc-option,<flag>)74# $(rustc-option,<flag>)
75# Return y if the Rust compiler supports <flag>, n otherwise75# Return y if the Rust compiler supports <flag>, n otherwise
76# Calls to this should be guarded so that they are not evaluated if
77# CONFIG_RUST_IS_AVAILABLE is not set.
78# If you are testing for unstable features, consider testing RUSTC_VERSION76# If you are testing for unstable features, consider testing RUSTC_VERSION
79# instead, as features may have different completeness while available.77# instead, as features may have different completeness while available.
80rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib)78rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib)
scripts/Makefile.lib+1−1
@@ -400,7 +400,7 @@ FIT_COMPRESSION ?= gzip · 399 unmodified lines
400 400
401quiet_cmd_fit = FIT $@401quiet_cmd_fit = FIT $@
402 cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \402 cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \
403 --name '$(UIMAGE_NAME)' \403 --name '$(UIMAGE_NAME)' $(FIT_EXTRA_ARGS) \
404 $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \404 $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \
405 $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \405 $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \
406 --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)406 --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)
scripts/Makefile.package+0−1
@@ -201,7 +201,6 @@ quiet_cmd_cpio = CPIO $@ · 200 unmodified lines
201 cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $<201 cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $<
202 202
203modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio203modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio
204 $(Q)$(MAKE) $(build)=usr usr/gen_init_cpio
205 $(call cmd,cpio)204 $(call cmd,cpio)
206 205
207PHONY += modules-cpio-pkg206PHONY += modules-cpio-pkg
scripts/Makefile.warn+13−14
@@ -16,7 +16,7 @@ KBUILD_CFLAGS += -Werror=return-type · 15 unmodified lines
16KBUILD_CFLAGS += -Werror=strict-prototypes16KBUILD_CFLAGS += -Werror=strict-prototypes
17KBUILD_CFLAGS += -Wno-format-security17KBUILD_CFLAGS += -Wno-format-security
18KBUILD_CFLAGS += -Wno-trigraphs18KBUILD_CFLAGS += -Wno-trigraphs
19KBUILD_CFLAGS += $(call cc-option, -Wno-frame-address)19KBUILD_CFLAGS += -Wno-frame-address
20KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member)20KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member)
21KBUILD_CFLAGS += -Wmissing-declarations21KBUILD_CFLAGS += -Wmissing-declarations
22KBUILD_CFLAGS += -Wmissing-prototypes22KBUILD_CFLAGS += -Wmissing-prototypes
@@ -55,6 +55,9 @@ else · 32 unmodified lines
55KBUILD_CFLAGS += -Wno-main55KBUILD_CFLAGS += -Wno-main
56endif56endif
57 57
58# Too noisy on range checks and in macros handling both signed and unsigned.
59KBUILD_CFLAGS += -Wno-type-limits
60
58# These result in bogus false positives61# These result in bogus false positives
59KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer)62KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer)
60 63
@@ -72,7 +75,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign · 11 unmodified lines
72# In order to make sure new function cast mismatches are not introduced75# In order to make sure new function cast mismatches are not introduced
73# in the kernel (to avoid tripping CFI checking), the kernel should be76# in the kernel (to avoid tripping CFI checking), the kernel should be
74# globally built with -Wcast-function-type.77# globally built with -Wcast-function-type.
75KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type)78KBUILD_CFLAGS += -Wcast-function-type
76 79
77# Currently, disable -Wstringop-overflow for GCC 11, globally.80# Currently, disable -Wstringop-overflow for GCC 11, globally.
78KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow)81KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow)
@@ -99,7 +102,7 @@ KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) · 20 unmodified lines
99KBUILD_CFLAGS += -Werror=date-time102KBUILD_CFLAGS += -Werror=date-time
100 103
101# enforce correct pointer usage104# enforce correct pointer usage
102KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)105KBUILD_CFLAGS += -Werror=incompatible-pointer-types
103 106
104# Require designated initializers for all marked structures107# Require designated initializers for all marked structures
105KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)108KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
@@ -116,7 +119,7 @@ ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) · 10 unmodified lines
116 119
117KBUILD_CFLAGS += -Wmissing-format-attribute120KBUILD_CFLAGS += -Wmissing-format-attribute
118KBUILD_CFLAGS += -Wmissing-include-dirs121KBUILD_CFLAGS += -Wmissing-include-dirs
119KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable)122KBUILD_CFLAGS += -Wunused-const-variable
120 123
121KBUILD_CPPFLAGS += -Wundef124KBUILD_CPPFLAGS += -Wundef
122KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1125KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1
@@ -125,12 +128,12 @@ else · 2 unmodified lines
125 128
126# Some diagnostics enabled by default are noisy.129# Some diagnostics enabled by default are noisy.
127# Suppress them by using -Wno... except for W=1.130# Suppress them by using -Wno... except for W=1.
128KBUILD_CFLAGS += $(call cc-option, -Wno-unused-but-set-variable)131KBUILD_CFLAGS += -Wno-unused-but-set-variable
129KBUILD_CFLAGS += $(call cc-option, -Wno-unused-const-variable)132KBUILD_CFLAGS += -Wno-unused-const-variable
130KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned)133KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned)
131KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow)134KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow)
132ifdef CONFIG_CC_IS_GCC135ifdef CONFIG_CC_IS_GCC
133KBUILD_CFLAGS += $(call cc-option, -Wno-format-truncation)136KBUILD_CFLAGS += -Wno-format-truncation
134endif137endif
135KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation)138KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation)
136 139
@@ -145,14 +148,11 @@ KBUILD_CFLAGS += -Wno-format · 8 unmodified lines
145# problematic.148# problematic.
146KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier149KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier
147KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull150KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull
148# Requires clang-12+.
149ifeq ($(call clang-min-version, 120000),y)
150KBUILD_CFLAGS += -Wformat-insufficient-args151KBUILD_CFLAGS += -Wformat-insufficient-args
151endif152endif
152endif153KBUILD_CFLAGS += -Wno-pointer-to-enum-cast
153KBUILD_CFLAGS += $(call cc-option, -Wno-pointer-to-enum-cast)
154KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare154KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
155KBUILD_CFLAGS += $(call cc-option, -Wno-unaligned-access)155KBUILD_CFLAGS += -Wno-unaligned-access
156KBUILD_CFLAGS += -Wno-enum-compare-conditional156KBUILD_CFLAGS += -Wno-enum-compare-conditional
157endif157endif
158 158
@@ -166,7 +166,7 @@ ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) · 7 unmodified lines
166KBUILD_CFLAGS += -Wdisabled-optimization166KBUILD_CFLAGS += -Wdisabled-optimization
167KBUILD_CFLAGS += -Wshadow167KBUILD_CFLAGS += -Wshadow
168KBUILD_CFLAGS += $(call cc-option, -Wlogical-op)168KBUILD_CFLAGS += $(call cc-option, -Wlogical-op)
169KBUILD_CFLAGS += $(call cc-option, -Wunused-macros)169KBUILD_CFLAGS += -Wunused-macros
170 170
171KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2171KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2
172 172
@@ -174,7 +174,6 @@ else · 1 unmodified line
174 174
175# The following turn off the warnings enabled by -Wextra175# The following turn off the warnings enabled by -Wextra
176KBUILD_CFLAGS += -Wno-missing-field-initializers176KBUILD_CFLAGS += -Wno-missing-field-initializers
177KBUILD_CFLAGS += -Wno-type-limits
178KBUILD_CFLAGS += -Wno-shift-negative-value177KBUILD_CFLAGS += -Wno-shift-negative-value
179 178
180ifdef CONFIG_CC_IS_CLANG179ifdef CONFIG_CC_IS_CLANG
scripts/container+199−0
@@ -0,0 +1,199 @@
1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0-only
3# Copyright (C) 2025 Guillaume Tucker
4
5"""Containerized builds"""
6
7import abc
8import argparse
9import logging
10import os
11import pathlib
12import shutil
13import subprocess
14import sys
15import uuid
16
17
18class ContainerRuntime(abc.ABC):
19 """Base class for a container runtime implementation"""
20
21 name = None # Property defined in each implementation class
22
23 def __init__(self, args, logger):
24 self._uid = args.uid or os.getuid()
25 self._gid = args.gid or args.uid or os.getgid()
26 self._env_file = args.env_file
27 self._shell = args.shell
28 self._logger = logger
29
30 @classmethod
31 def is_present(cls):
32 """Determine whether the runtime is present on the system"""
33 return shutil.which(cls.name) is not None
34
35 @abc.abstractmethod
36 def _do_run(self, image, cmd, container_name):
37 """Runtime-specific handler to run a command in a container"""
38
39 @abc.abstractmethod
40 def _do_abort(self, container_name):
41 """Runtime-specific handler to abort a running container"""
42
43 def run(self, image, cmd):
44 """Run a command in a runtime container"""
45 container_name = str(uuid.uuid4())
46 self._logger.debug("container: %s", container_name)
47 try:
48 return self._do_run(image, cmd, container_name)
49 except KeyboardInterrupt:
50 self._logger.error("user aborted")
51 self._do_abort(container_name)
52 return 1
53
54
55class CommonRuntime(ContainerRuntime):
56 """Common logic for Docker and Podman"""
57
58 def _do_run(self, image, cmd, container_name):
59 cmdline = [self.name, 'run']
60 cmdline += self._get_opts(container_name)
61 cmdline.append(image)
62 cmdline += cmd
63 self._logger.debug('command: %s', ' '.join(cmdline))
64 return subprocess.call(cmdline)
65
66 def _get_opts(self, container_name):
67 opts = [
68 '--name', container_name,
69 '--rm',
70 '--volume', f'{pathlib.Path.cwd()}:/src',
71 '--workdir', '/src',
72 ]
73 if self._env_file:
74 opts += ['--env-file', self._env_file]
75 if self._shell:
76 opts += ['--interactive', '--tty']
77 return opts
78
79 def _do_abort(self, container_name):
80 subprocess.call([self.name, 'kill', container_name])
81
82
83class DockerRuntime(CommonRuntime):
84 """Run a command in a Docker container"""
85
86 name = 'docker'
87
88 def _get_opts(self, container_name):
89 return super()._get_opts(container_name) + [
90 '--user', f'{self._uid}:{self._gid}'
91 ]
92
93
94class PodmanRuntime(CommonRuntime):
95 """Run a command in a Podman container"""
96
97 name = 'podman'
98
99 def _get_opts(self, container_name):
100 return super()._get_opts(container_name) + [
101 '--userns', f'keep-id:uid={self._uid},gid={self._gid}',
102 ]
103
104
105class Runtimes:
106 """List of all supported runtimes"""
107
108 runtimes = [PodmanRuntime, DockerRuntime]
109
110 @classmethod
111 def get_names(cls):
112 """Get a list of all the runtime names"""
113 return list(runtime.name for runtime in cls.runtimes)
114
115 @classmethod
116 def get(cls, name):
117 """Get a single runtime class matching the given name"""
118 for runtime in cls.runtimes:
119 if runtime.name == name:
120 if not runtime.is_present():
121 raise ValueError(f"runtime not found: {name}")
122 return runtime
123 raise ValueError(f"unknown runtime: {name}")
124
125 @classmethod
126 def find(cls):
127 """Find the first runtime present on the system"""
128 for runtime in cls.runtimes:
129 if runtime.is_present():
130 return runtime
131 raise ValueError("no runtime found")
132
133
134def _get_logger(verbose):
135 """Set up a logger with the appropriate level"""
136 logger = logging.getLogger('container')
137 handler = logging.StreamHandler()
138 handler.setFormatter(logging.Formatter(
139 fmt='[container {levelname}] {message}', style='{'
140 ))
141 logger.addHandler(handler)
142 logger.setLevel(logging.DEBUG if verbose is True else logging.INFO)
143 return logger
144
145
146def main(args):
147 """Main entry point for the container tool"""
148 logger = _get_logger(args.verbose)
149 try:
150 cls = Runtimes.get(args.runtime) if args.runtime else Runtimes.find()
151 except ValueError as ex:
152 logger.error(ex)
153 return 1
154 logger.debug("runtime: %s", cls.name)
155 logger.debug("image: %s", args.image)
156 return cls(args, logger).run(args.image, args.cmd)
157
158
159if __name__ == '__main__':
160 parser = argparse.ArgumentParser(
161 'container',
162 description="See the documentation for more details: "
163 "https://docs.kernel.org/dev-tools/container.html"
164 )
165 parser.add_argument(
166 '-e', '--env-file',
167 help="Path to an environment file to load in the container."
168 )
169 parser.add_argument(
170 '-g', '--gid',
171 help="Group ID to use inside the container."
172 )
173 parser.add_argument(
174 '-i', '--image', required=True,
175 help="Container image name."
176 )
177 parser.add_argument(
178 '-r', '--runtime', choices=Runtimes.get_names(),
179 help="Container runtime name. If not specified, the first one found "
180 "on the system will be used i.e. Podman if present, otherwise Docker."
181 )
182 parser.add_argument(
183 '-s', '--shell', action='store_true',
184 help="Run the container in an interactive shell."
185 )
186 parser.add_argument(
187 '-u', '--uid',
188 help="User ID to use inside the container. If the -g option is not "
189 "specified, the user ID will also be set as the group ID."
190 )
191 parser.add_argument(
192 '-v', '--verbose', action='store_true',
193 help="Enable verbose output."
194 )
195 parser.add_argument(
196 'cmd', nargs='+',
197 help="Command to run in the container"
198 )
199 sys.exit(main(parser.parse_args(sys.argv[1:])))
scripts/dummy-tools/python3+4−0
@@ -0,0 +1,4 @@
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0-only
3
4true
scripts/kallsyms.c+17−47
@@ -46,7 +46,6 @@ struct addr_range { · 45 unmodified lines
46};46};
47 47
48static unsigned long long _text;48static unsigned long long _text;
49static unsigned long long relative_base;
50static struct addr_range text_ranges[] = {49static struct addr_range text_ranges[] = {
51 { "_stext", "_etext" },50 { "_stext", "_etext" },
52 { "_sinittext", "_einittext" },51 { "_sinittext", "_einittext" },
@@ -57,6 +56,7 @@ static struct addr_range text_ranges[] = { · 4 unmodified lines
57static struct sym_entry **table;56static struct sym_entry **table;
58static unsigned int table_size, table_cnt;57static unsigned int table_size, table_cnt;
59static int all_symbols;58static int all_symbols;
59static int pc_relative;
60 60
61static int token_profit[0x10000];61static int token_profit[0x10000];
62 62
@@ -280,7 +280,7 @@ static void read_map(const char *in) · 217 unmodified lines
280static void output_label(const char *label)280static void output_label(const char *label)
281{281{
282 printf(".globl %s\n", label);282 printf(".globl %s\n", label);
283 printf("\tALGN\n");283 printf("\t.balign 4\n");
284 printf("%s:\n", label);284 printf("%s:\n", label);
285}285}
286 286
@@ -343,15 +343,6 @@ static void write_src(void) · 56 unmodified lines
343 unsigned int *markers, markers_cnt;343 unsigned int *markers, markers_cnt;
344 char buf[KSYM_NAME_LEN];344 char buf[KSYM_NAME_LEN];
345 345
346 printf("#include <asm/bitsperlong.h>\n");
347 printf("#if BITS_PER_LONG == 64\n");
348 printf("#define PTR .quad\n");
349 printf("#define ALGN .balign 8\n");
350 printf("#else\n");
351 printf("#define PTR .long\n");
352 printf("#define ALGN .balign 4\n");
353 printf("#endif\n");
354
355 printf("\t.section .rodata, \"a\"\n");346 printf("\t.section .rodata, \"a\"\n");
356 347
357 output_label("kallsyms_num_syms");348 output_label("kallsyms_num_syms");
@@ -434,34 +425,24 @@ static void write_src(void) · 76 unmodified lines
434 output_label("kallsyms_offsets");425 output_label("kallsyms_offsets");
435 426
436 for (i = 0; i < table_cnt; i++) {427 for (i = 0; i < table_cnt; i++) {
437 /*428 if (pc_relative) {
438 * Use the offset relative to the lowest value429 long long offset = table[i]->addr - _text;
439 * encountered of all relative symbols, and emit430
440 * non-relocatable fixed offsets that will be fixed431 if (offset < INT_MIN || offset > INT_MAX) {
441 * up at runtime.432 fprintf(stderr, "kallsyms failure: "
442 */433 "relative symbol value %#llx out of range\n",
443 434 table[i]->addr);
444 long long offset;435 exit(EXIT_FAILURE);
445 436 }
446 offset = table[i]->addr - relative_base;437 printf("\t.long\t_text - . + (%d)\t/* %s */\n",
447 if (offset < 0 || offset > UINT_MAX) {438 (int)offset, table[i]->sym);
448 fprintf(stderr, "kallsyms failure: "439 } else {
449 "relative symbol value %#llx out of range\n",440 printf("\t.long\t%#x\t/* %s */\n",
450 table[i]->addr);441 (unsigned int)table[i]->addr, table[i]->sym);
451 exit(EXIT_FAILURE);
452 }442 }
453 printf("\t.long\t%#x\t/* %s */\n", (int)offset, table[i]->sym);
454 }443 }
455 printf("\n");444 printf("\n");
456 445
457 output_label("kallsyms_relative_base");
458 /* Provide proper symbols relocatability by their '_text' relativeness. */
459 if (_text <= relative_base)
460 printf("\tPTR\t_text + %#llx\n", relative_base - _text);
461 else
462 printf("\tPTR\t_text - %#llx\n", _text - relative_base);
463 printf("\n");
464
465 sort_symbols_by_name();446 sort_symbols_by_name();
466 output_label("kallsyms_seqs_of_names");447 output_label("kallsyms_seqs_of_names");
467 for (i = 0; i < table_cnt; i++)448 for (i = 0; i < table_cnt; i++)
@@ -701,22 +682,12 @@ static void sort_symbols(void) · 233 unmodified lines
701 qsort(table, table_cnt, sizeof(table[0]), compare_symbols);682 qsort(table, table_cnt, sizeof(table[0]), compare_symbols);
702}683}
703 684
704/* find the minimum non-absolute symbol address */
705static void record_relative_base(void)
706{
707 /*
708 * The table is sorted by address.
709 * Take the first symbol value.
710 */
711 if (table_cnt)
712 relative_base = table[0]->addr;
713}
714
715int main(int argc, char **argv)685int main(int argc, char **argv)
716{686{
717 while (1) {687 while (1) {
718 static const struct option long_options[] = {688 static const struct option long_options[] = {
719 {"all-symbols", no_argument, &all_symbols, 1},689 {"all-symbols", no_argument, &all_symbols, 1},
690 {"pc-relative", no_argument, &pc_relative, 1},
720 {},691 {},
721 };692 };
722 693
@@ -734,7 +705,6 @@ int main(int argc, char **argv) · 11 unmodified lines
734 read_map(argv[optind]);705 read_map(argv[optind]);
735 shrink_table();706 shrink_table();
736 sort_symbols();707 sort_symbols();
737 record_relative_base();
738 optimize_token_table();708 optimize_token_table();
739 write_src();709 write_src();
740 710
scripts/kconfig/Makefile+2−2
@@ -201,7 +201,7 @@ $(addprefix $(obj)/, mconf.o $(lxdialog)): | $(obj)/mconf-cflags · 200 unmodified lines
201# qconf: Used for the xconfig target based on Qt201# qconf: Used for the xconfig target based on Qt
202hostprogs += qconf202hostprogs += qconf
203qconf-cxxobjs := qconf.o qconf-moc.o203qconf-cxxobjs := qconf.o qconf-moc.o
204qconf-objs := images.o $(common-objs)204qconf-objs := $(common-objs)
205 205
206HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs)206HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs)
207HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags)207HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags)
@@ -219,7 +219,7 @@ targets += qconf-moc.cc · 11 unmodified lines
219 219
220# gconf: Used for the gconfig target based on GTK+220# gconf: Used for the gconfig target based on GTK+
221hostprogs += gconf221hostprogs += gconf
222gconf-objs := gconf.o images.o $(common-objs)222gconf-objs := gconf.o $(common-objs)
223 223
224HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs)224HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs)
225HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags)225HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags)
scripts/kconfig/gconf.c+28−7
@@ -5,7 +5,6 @@ · 4 unmodified lines
5 5
6#include <stdlib.h>6#include <stdlib.h>
7#include "lkc.h"7#include "lkc.h"
8#include "images.h"
9 8
10#include <gtk/gtk.h>9#include <gtk/gtk.h>
11 10
@@ -951,12 +950,24 @@ static void fixup_rootmenu(struct menu *menu) · 939 unmodified lines
951}950}
952 951
953/* Main Window Initialization */952/* Main Window Initialization */
954static void replace_button_icon(GtkWidget *widget, const char * const xpm[])953static void replace_button_icon(GtkWidget *widget, const char *filename)
955{954{
956 GdkPixbuf *pixbuf;955 GdkPixbuf *pixbuf;
957 GtkWidget *image;956 GtkWidget *image;
957 GError *err = NULL;
958
959 char *env = getenv(SRCTREE);
960 gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/", filename, NULL);
961
962 pixbuf = gdk_pixbuf_new_from_file(path, &err);
963 g_free(path);
964
965 if (err) {
966 g_warning("Failed to load icon %s: %s", filename, err->message);
967 g_error_free(err);
968 return;
969 }
958 970
959 pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm);
960 image = gtk_image_new_from_pixbuf(pixbuf);971 image = gtk_image_new_from_pixbuf(pixbuf);
961 g_object_unref(pixbuf);972 g_object_unref(pixbuf);
962 973
@@ -1078,17 +1089,17 @@ static void init_main_window(const gchar *glade_file) · 115 unmodified lines
1078 single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4"));1089 single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4"));
1079 g_signal_connect(single_btn, "clicked",1090 g_signal_connect(single_btn, "clicked",
1080 G_CALLBACK(on_single_clicked), NULL);1091 G_CALLBACK(on_single_clicked), NULL);
1081 replace_button_icon(single_btn, xpm_single_view);1092 replace_button_icon(single_btn, "single_view.xpm");
1082 1093
1083 split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5"));1094 split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5"));
1084 g_signal_connect(split_btn, "clicked",1095 g_signal_connect(split_btn, "clicked",
1085 G_CALLBACK(on_split_clicked), NULL);1096 G_CALLBACK(on_split_clicked), NULL);
1086 replace_button_icon(split_btn, xpm_split_view);1097 replace_button_icon(split_btn, "split_view.xpm");
1087 1098
1088 full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6"));1099 full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6"));
1089 g_signal_connect(full_btn, "clicked",1100 g_signal_connect(full_btn, "clicked",
1090 G_CALLBACK(on_full_clicked), NULL);1101 G_CALLBACK(on_full_clicked), NULL);
1091 replace_button_icon(full_btn, xpm_tree_view);1102 replace_button_icon(full_btn, "tree_view.xpm");
1092 1103
1093 widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7"));1104 widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7"));
1094 g_signal_connect(widget, "clicked",1105 g_signal_connect(widget, "clicked",
@@ -1269,7 +1280,17 @@ static void init_right_tree(void) · 174 unmodified lines
1269 g_signal_connect(G_OBJECT(renderer), "edited",1280 g_signal_connect(G_OBJECT(renderer), "edited",
1270 G_CALLBACK(renderer_edited), tree2_w);1281 G_CALLBACK(renderer_edited), tree2_w);
1271 1282
1272 pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu);1283 char *env = getenv(SRCTREE);
1284 gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/menu.xpm", NULL);
1285 GError *err = NULL;
1286
1287 pix_menu = gdk_pixbuf_new_from_file(path, &err);
1288 g_free(path);
1289
1290 if (err) {
1291 g_warning("Failed to load menu icon: %s", err->message);
1292 g_error_free(err);
1293 }
1273 1294
1274 for (i = 0; i < COL_VALUE; i++) {1295 for (i = 0; i < COL_VALUE; i++) {
1275 column = gtk_tree_view_get_column(view, i);1296 column = gtk_tree_view_get_column(view, i);
scripts/kconfig/icons/back.xpm+29−0
@@ -0,0 +1,29 @@
1/* XPM */
2static char * back_xpm[] = {
3"22 22 3 1",
4". c None",
5"# c #000083",
6"a c #838183",
7"......................",
8"......................",
9"......................",
10"......................",
11"......................",
12"...........######a....",
13"..#......##########...",
14"..##...####......##a..",
15"..###.###.........##..",
16"..######..........##..",
17"..#####...........##..",
18"..######..........##..",
19"..#######.........##..",
20"..########.......##a..",
21"...............a###...",
22"...............###....",
23"......................",
24"......................",
25"......................",
26"......................",
27"......................",
28"......................"
29};
scripts/kconfig/icons/choice_no.xpm+18−0
@@ -0,0 +1,18 @@
1/* XPM */
2static char * choice_no_xpm[] = {
3"12 12 2 1",
4" c white",
5". c black",
6" ",
7" .... ",
8" .. .. ",
9" . . ",
10" . . ",
11" . . ",
12" . . ",
13" . . ",
14" . . ",
15" .. .. ",
16" .... ",
17" "
18};
scripts/kconfig/icons/choice_yes.xpm+18−0
@@ -0,0 +1,18 @@
1/* XPM */
2static char * choice_yes_xpm[] = {
3"12 12 2 1",
4" c white",
5". c black",
6" ",
7" .... ",
8" .. .. ",
9" . . ",
10" . .. . ",
11" . .... . ",
12" . .... . ",
13" . .. . ",
14" . . ",
15" .. .. ",
16" .... ",
17" "
18};
scripts/kconfig/icons/load.xpm+31−0
@@ -0,0 +1,31 @@
1/* XPM */
2static char * load_xpm[] = {
3"22 22 5 1",
4". c None",
5"# c #000000",
6"c c #838100",
7"a c #ffff00",
8"b c #ffffff",
9"......................",
10"......................",
11"......................",
12"............####....#.",
13"...........#....##.##.",
14"..................###.",
15".................####.",
16".####...........#####.",
17"#abab##########.......",
18"#babababababab#.......",
19"#ababababababa#.......",
20"#babababababab#.......",
21"#ababab###############",
22"#babab##cccccccccccc##",
23"#abab##cccccccccccc##.",
24"#bab##cccccccccccc##..",
25"#ab##cccccccccccc##...",
26"#b##cccccccccccc##....",
27"###cccccccccccc##.....",
28"##cccccccccccc##......",
29"###############.......",
30"......................"
31};
scripts/kconfig/icons/menu.xpm+18−0
@@ -0,0 +1,18 @@
1/* XPM */
2static char * menu_xpm[] = {
3"12 12 2 1",
4" c white",
5". c black",
6" ",
7" .......... ",
8" . . ",
9" . .. . ",
10" . .... . ",
11" . ...... . ",
12" . ...... . ",
13" . .... . ",
14" . .. . ",
15" . . ",
16" .......... ",
17" "
18};
scripts/kconfig/icons/menuback.xpm+18−0
@@ -0,0 +1,18 @@
1/* XPM */
2static char * menuback_xpm[] = {
3"12 12 2 1",
4" c white",
5". c black",
6" ",
7" .......... ",
8" . . ",
9" . .. . ",
10" . .... . ",
11" . ...... . ",
12" . ...... . ",
13" . .... . ",
14" . .. . ",
15" . . ",
16" .......... ",
17" "
18};
scripts/kconfig/icons/save.xpm+31−0
@@ -0,0 +1,31 @@
1/* XPM */
2static char * save_xpm[] = {
3"22 22 5 1",
4". c None",
5"# c #000000",
6"a c #838100",
7"b c #c5c2c5",
8"c c #cdb6d5",
9"......................",
10".####################.",
11".#aa#bbbbbbbbbbbb#bb#.",
12".#aa#bbbbbbbbbbbb#bb#.",
13".#aa#bbbbbbbbbcbb####.",
14".#aa#bbbccbbbbbbb#aa#.",
15".#aa#bbbccbbbbbbb#aa#.",
16".#aa#bbbbbbbbbbbb#aa#.",
17".#aa#bbbbbbbbbbbb#aa#.",
18".#aa#bbbbbbbbbbbb#aa#.",
19".#aa#bbbbbbbbbbbb#aa#.",
20".#aaa############aaa#.",
21".#aaaaaaaaaaaaaaaaaa#.",
22".#aaaaaaaaaaaaaaaaaa#.",
23".#aaa#############aa#.",
24".#aaa#########bbb#aa#.",
25".#aaa#########bbb#aa#.",
26".#aaa#########bbb#aa#.",
27".#aaa#########bbb#aa#.",
28".#aaa#########bbb#aa#.",
29"..##################..",
30"......................"
31};
scripts/kconfig/icons/single_view.xpm+28−0
@@ -0,0 +1,28 @@
1/* XPM */
2static char * single_view_xpm[] = {
3"22 22 2 1",
4". c None",
5"# c #000000",
6"......................",
7"......................",
8"..........#...........",
9"..........#...........",
10"..........#...........",
11"..........#...........",
12"..........#...........",
13"..........#...........",
14"..........#...........",
15"..........#...........",
16"..........#...........",
17"..........#...........",
18"..........#...........",
19"..........#...........",
20"..........#...........",
21"..........#...........",
22"..........#...........",
23"..........#...........",
24"..........#...........",
25"..........#...........",
26"......................",
27"......................"
28};
scripts/kconfig/icons/split_view.xpm+28−0
@@ -0,0 +1,28 @@
1/* XPM */
2static char * split_view_xpm[] = {
3"22 22 2 1",
4". c None",
5"# c #000000",
6"......................",
7"......................",
8"......#......#........",
9"......#......#........",
10"......#......#........",
11"......#......#........",
12"......#......#........",
13"......#......#........",
14"......#......#........",
15"......#......#........",
16"......#......#........",
17"......#......#........",
18"......#......#........",
19"......#......#........",
20"......#......#........",
21"......#......#........",
22"......#......#........",
23"......#......#........",
24"......#......#........",
25"......#......#........",
26"......................",
27"......................"
28};
scripts/kconfig/icons/symbol_mod.xpm+18−0
@@ -0,0 +1,18 @@
1/* XPM */
2static char * symbol_mod_xpm[] = {
3"12 12 2 1",
4" c white",
5". c black",
6" ",
7" .......... ",
8" . . ",
9" . . ",
10" . .. . ",
11" . .... . ",
12" . .... . ",
13" . .. . ",
14" . . ",
15" . . ",
16" .......... ",
17" "
18};
scripts/kconfig/icons/symbol_no.xpm+18−0
@@ -0,0 +1,18 @@
1/* XPM */
2static char * symbol_no_xpm[] = {
3"12 12 2 1",
4" c white",
5". c black",
6" ",
7" .......... ",
8" . . ",
9" . . ",
10" . . ",
11" . . ",
12" . . ",
13" . . ",
14" . . ",
15" . . ",
16" .......... ",
17" "
18};
scripts/kconfig/icons/symbol_yes.xpm+18−0
@@ -0,0 +1,18 @@
1/* XPM */
2static char * symbol_yes_xpm[] = {
3"12 12 2 1",
4" c white",
5". c black",
6" ",
7" .......... ",
8" . . ",
9" . . ",
10" . . . ",
11" . .. . ",
12" . . .. . ",
13" . .... . ",
14" . .. . ",
15" . . ",
16" .......... ",
17" "
18};
scripts/kconfig/icons/tree_view.xpm+28−0
@@ -0,0 +1,28 @@
1/* XPM */
2static char * tree_view_xpm[] = {
3"22 22 2 1",
4". c None",
5"# c #000000",
6"......................",
7"......................",
8"......#...............",
9"......#...............",
10"......#...............",
11"......#...............",
12"......#...............",
13"......########........",
14"......#...............",
15"......#...............",
16"......#...............",
17"......#...............",
18"......#...............",
19"......########........",
20"......#...............",
21"......#...............",
22"......#...............",
23"......#...............",
24"......#...............",
25"......########........",
26"......................",
27"......................"
28};
scripts/kconfig/images.c+0−328
@@ -1,328 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 */
5
6#include "images.h"
7
8const char * const xpm_load[] = {
9"22 22 5 1",
10". c None",
11"# c #000000",
12"c c #838100",
13"a c #ffff00",
14"b c #ffffff",
15"......................",
16"......................",
17"......................",
18"............####....#.",
19"...........#....##.##.",
20"..................###.",
21".................####.",
22".####...........#####.",
23"#abab##########.......",
24"#babababababab#.......",
25"#ababababababa#.......",
26"#babababababab#.......",
27"#ababab###############",
28"#babab##cccccccccccc##",
29"#abab##cccccccccccc##.",
30"#bab##cccccccccccc##..",
31"#ab##cccccccccccc##...",
32"#b##cccccccccccc##....",
33"###cccccccccccc##.....",
34"##cccccccccccc##......",
35"###############.......",
36"......................"};
37
38const char * const xpm_save[] = {
39"22 22 5 1",
40". c None",
41"# c #000000",
42"a c #838100",
43"b c #c5c2c5",
44"c c #cdb6d5",
45"......................",
46".####################.",
47".#aa#bbbbbbbbbbbb#bb#.",
48".#aa#bbbbbbbbbbbb#bb#.",
49".#aa#bbbbbbbbbcbb####.",
50".#aa#bbbccbbbbbbb#aa#.",
51".#aa#bbbccbbbbbbb#aa#.",
52".#aa#bbbbbbbbbbbb#aa#.",
53".#aa#bbbbbbbbbbbb#aa#.",
54".#aa#bbbbbbbbbbbb#aa#.",
55".#aa#bbbbbbbbbbbb#aa#.",
56".#aaa############aaa#.",
57".#aaaaaaaaaaaaaaaaaa#.",
58".#aaaaaaaaaaaaaaaaaa#.",
59".#aaa#############aa#.",
60".#aaa#########bbb#aa#.",
61".#aaa#########bbb#aa#.",
62".#aaa#########bbb#aa#.",
63".#aaa#########bbb#aa#.",
64".#aaa#########bbb#aa#.",
65"..##################..",
66"......................"};
67
68const char * const xpm_back[] = {
69"22 22 3 1",
70". c None",
71"# c #000083",
72"a c #838183",
73"......................",
74"......................",
75"......................",
76"......................",
77"......................",
78"...........######a....",
79"..#......##########...",
80"..##...####......##a..",
81"..###.###.........##..",
82"..######..........##..",
83"..#####...........##..",
84"..######..........##..",
85"..#######.........##..",
86"..########.......##a..",
87"...............a###...",
88"...............###....",
89"......................",
90"......................",
91"......................",
92"......................",
93"......................",
94"......................"};
95
96const char * const xpm_tree_view[] = {
97"22 22 2 1",
98". c None",
99"# c #000000",
100"......................",
101"......................",
102"......#...............",
103"......#...............",
104"......#...............",
105"......#...............",
106"......#...............",
107"......########........",
108"......#...............",
109"......#...............",
110"......#...............",
111"......#...............",
112"......#...............",
113"......########........",
114"......#...............",
115"......#...............",
116"......#...............",
117"......#...............",
118"......#...............",
119"......########........",
120"......................",
121"......................"};
122
123const char * const xpm_single_view[] = {
124"22 22 2 1",
125". c None",
126"# c #000000",
127"......................",
128"......................",
129"..........#...........",
130"..........#...........",
131"..........#...........",
132"..........#...........",
133"..........#...........",
134"..........#...........",
135"..........#...........",
136"..........#...........",
137"..........#...........",
138"..........#...........",
139"..........#...........",
140"..........#...........",
141"..........#...........",
142"..........#...........",
143"..........#...........",
144"..........#...........",
145"..........#...........",
146"..........#...........",
147"......................",
148"......................"};
149
150const char * const xpm_split_view[] = {
151"22 22 2 1",
152". c None",
153"# c #000000",
154"......................",
155"......................",
156"......#......#........",
157"......#......#........",
158"......#......#........",
159"......#......#........",
160"......#......#........",
161"......#......#........",
162"......#......#........",
163"......#......#........",
164"......#......#........",
165"......#......#........",
166"......#......#........",
167"......#......#........",
168"......#......#........",
169"......#......#........",
170"......#......#........",
171"......#......#........",
172"......#......#........",
173"......#......#........",
174"......................",
175"......................"};
176
177const char * const xpm_symbol_no[] = {
178"12 12 2 1",
179" c white",
180". c black",
181" ",
182" .......... ",
183" . . ",
184" . . ",
185" . . ",
186" . . ",
187" . . ",
188" . . ",
189" . . ",
190" . . ",
191" .......... ",
192" "};
193
194const char * const xpm_symbol_mod[] = {
195"12 12 2 1",
196" c white",
197". c black",
198" ",
199" .......... ",
200" . . ",
201" . . ",
202" . .. . ",
203" . .... . ",
204" . .... . ",
205" . .. . ",
206" . . ",
207" . . ",
208" .......... ",
209" "};
210
211const char * const xpm_symbol_yes[] = {
212"12 12 2 1",
213" c white",
214". c black",
215" ",
216" .......... ",
217" . . ",
218" . . ",
219" . . . ",
220" . .. . ",
221" . . .. . ",
222" . .... . ",
223" . .. . ",
224" . . ",
225" .......... ",
226" "};
227
228const char * const xpm_choice_no[] = {
229"12 12 2 1",
230" c white",
231". c black",
232" ",
233" .... ",
234" .. .. ",
235" . . ",
236" . . ",
237" . . ",
238" . . ",
239" . . ",
240" . . ",
241" .. .. ",
242" .... ",
243" "};
244
245const char * const xpm_choice_yes[] = {
246"12 12 2 1",
247" c white",
248". c black",
249" ",
250" .... ",
251" .. .. ",
252" . . ",
253" . .. . ",
254" . .... . ",
255" . .... . ",
256" . .. . ",
257" . . ",
258" .. .. ",
259" .... ",
260" "};
261
262const char * const xpm_menu[] = {
263"12 12 2 1",
264" c white",
265". c black",
266" ",
267" .......... ",
268" . . ",
269" . .. . ",
270" . .... . ",
271" . ...... . ",
272" . ...... . ",
273" . .... . ",
274" . .. . ",
275" . . ",
276" .......... ",
277" "};
278
279const char * const xpm_menu_inv[] = {
280"12 12 2 1",
281" c white",
282". c black",
283" ",
284" .......... ",
285" .......... ",
286" .. ...... ",
287" .. .... ",
288" .. .. ",
289" .. .. ",
290" .. .... ",
291" .. ...... ",
292" .......... ",
293" .......... ",
294" "};
295
296const char * const xpm_menuback[] = {
297"12 12 2 1",
298" c white",
299". c black",
300" ",
301" .......... ",
302" . . ",
303" . .. . ",
304" . .... . ",
305" . ...... . ",
306" . ...... . ",
307" . .... . ",
308" . .. . ",
309" . . ",
310" .......... ",
311" "};
312
313const char * const xpm_void[] = {
314"12 12 2 1",
315" c white",
316". c black",
317" ",
318" ",
319" ",
320" ",
321" ",
322" ",
323" ",
324" ",
325" ",
326" ",
327" ",
328" "};
scripts/kconfig/images.h+0−33
@@ -1,33 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4 */
5
6#ifndef IMAGES_H
7#define IMAGES_H
8
9#ifdef __cplusplus
10extern "C" {
11#endif
12
13extern const char * const xpm_load[];
14extern const char * const xpm_save[];
15extern const char * const xpm_back[];
16extern const char * const xpm_tree_view[];
17extern const char * const xpm_single_view[];
18extern const char * const xpm_split_view[];
19extern const char * const xpm_symbol_no[];
20extern const char * const xpm_symbol_mod[];
21extern const char * const xpm_symbol_yes[];
22extern const char * const xpm_choice_no[];
23extern const char * const xpm_choice_yes[];
24extern const char * const xpm_menu[];
25extern const char * const xpm_menu_inv[];
26extern const char * const xpm_menuback[];
27extern const char * const xpm_void[];
28
29#ifdef __cplusplus
30}
31#endif
32
33#endif /* IMAGES_H */
scripts/kconfig/lkc.h+1−1
@@ -82,7 +82,7 @@ void menu_warn(const struct menu *menu, const char *fmt, ...); · 81 unmodified lines
82struct menu *menu_add_menu(void);82struct menu *menu_add_menu(void);
83void menu_end_menu(void);83void menu_end_menu(void);
84void menu_add_entry(struct symbol *sym, enum menu_type type);84void menu_add_entry(struct symbol *sym, enum menu_type type);
85void menu_add_dep(struct expr *dep);85void menu_add_dep(struct expr *dep, struct expr *cond);
86void menu_add_visibility(struct expr *dep);86void menu_add_visibility(struct expr *dep);
87struct property *menu_add_prompt(enum prop_type type, const char *prompt,87struct property *menu_add_prompt(enum prop_type type, const char *prompt,
88 struct expr *dep);88 struct expr *dep);
scripts/kconfig/menu.c+11−1
@@ -127,8 +127,18 @@ static struct expr *rewrite_m(struct expr *e) · 126 unmodified lines
127 return e;127 return e;
128}128}
129 129
130void menu_add_dep(struct expr *dep)130void menu_add_dep(struct expr *dep, struct expr *cond)
131{131{
132 if (cond) {
133 /*
134 * We have "depends on X if Y" and we want:
135 * Y != n --> X
136 * Y == n --> y
137 * That simplifies to: (X || (Y == n))
138 */
139 dep = expr_alloc_or(dep,
140 expr_trans_compare(cond, E_EQUAL, &symbol_no));
141 }
132 current_entry->dep = expr_alloc_and(current_entry->dep, dep);142 current_entry->dep = expr_alloc_and(current_entry->dep, dep);
133}143}
134 144
scripts/kconfig/merge_config.sh+225−51
@@ -16,8 +16,8 @@ · 15 unmodified lines
16set -e16set -e
17 17
18clean_up() {18clean_up() {
19 rm -f $TMP_FILE19 rm -f "$TMP_FILE"
20 rm -f $MERGE_FILE20 rm -f "$TMP_FILE.new"
21}21}
22 22
23usage() {23usage() {
@@ -43,6 +43,10 @@ STRICT=false · 19 unmodified lines
43CONFIG_PREFIX=${CONFIG_-CONFIG_}43CONFIG_PREFIX=${CONFIG_-CONFIG_}
44WARNOVERRIDE=echo44WARNOVERRIDE=echo
45 45
46if [ -z "$AWK" ]; then
47 AWK=awk
48fi
49
46while true; do50while true; do
47 case $1 in51 case $1 in
48 "-n")52 "-n")
@@ -117,11 +121,8 @@ if [ ! -r "$INITFILE" ]; then · 68 unmodified lines
117fi121fi
118 122
119MERGE_LIST=$*123MERGE_LIST=$*
120SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p"
121SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p"
122 124
123TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX)125TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX)
124MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX)
125 126
126echo "Using $INITFILE as base"127echo "Using $INITFILE as base"
127 128
@@ -129,6 +130,8 @@ trap clean_up EXIT · 1 unmodified line
129 130
130cat $INITFILE > $TMP_FILE131cat $INITFILE > $TMP_FILE
131 132
133PROCESSED_FILES=""
134
132# Merge files, printing warnings on overridden values135# Merge files, printing warnings on overridden values
133for ORIG_MERGE_FILE in $MERGE_LIST ; do136for ORIG_MERGE_FILE in $MERGE_LIST ; do
134 echo "Merging $ORIG_MERGE_FILE"137 echo "Merging $ORIG_MERGE_FILE"
@@ -136,42 +139,138 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do · 1 unmodified line
136 echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2139 echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2
137 exit 1140 exit 1
138 fi141 fi
139 cat $ORIG_MERGE_FILE > $MERGE_FILE
140 CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE)
141
142 for CFG in $CFG_LIST ; do
143 grep -q -w $CFG $TMP_FILE || continue
144 PREV_VAL=$(grep -w $CFG $TMP_FILE)
145 NEW_VAL=$(grep -w $CFG $MERGE_FILE)
146 BUILTIN_FLAG=false
147 if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then
148 ${WARNOVERRIDE} Previous value: $PREV_VAL
149 ${WARNOVERRIDE} New value: $NEW_VAL
150 ${WARNOVERRIDE} -y passed, will not demote y to m
151 ${WARNOVERRIDE}
152 BUILTIN_FLAG=true
153 elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then
154 ${WARNOVERRIDE} Value of $CFG is redefined by fragment $ORIG_MERGE_FILE:
155 ${WARNOVERRIDE} Previous value: $PREV_VAL
156 ${WARNOVERRIDE} New value: $NEW_VAL
157 ${WARNOVERRIDE}
158 if [ "$STRICT" = "true" ]; then
159 STRICT_MODE_VIOLATED=true
160 fi
161 elif [ "$WARNREDUN" = "true" ]; then
162 ${WARNOVERRIDE} Value of $CFG is redundant by fragment $ORIG_MERGE_FILE:
163 fi
164 if [ "$BUILTIN_FLAG" = "false" ]; then
165 sed -i "/$CFG[ =]/d" $TMP_FILE
166 else
167 sed -i "/$CFG[ =]/d" $MERGE_FILE
168 fi
169 done
170 # In case the previous file lacks a new line at the end
171 echo >> $TMP_FILE
172 cat $MERGE_FILE >> $TMP_FILE
173done
174 142
143 # Check for duplicate input files
144 case " $PROCESSED_FILES " in
145 *" $ORIG_MERGE_FILE "*)
146 ${WARNOVERRIDE} "WARNING: Input file provided multiple times: $ORIG_MERGE_FILE"
147 ;;
148 esac
149
150 # Use awk for single-pass processing instead of per-symbol grep/sed
151 if ! "$AWK" -v prefix="$CONFIG_PREFIX" \
152 -v warnoverride="$WARNOVERRIDE" \
153 -v strict="$STRICT" \
154 -v builtin="$BUILTIN" \
155 -v warnredun="$WARNREDUN" '
156 BEGIN {
157 strict_violated = 0
158 cfg_regex = "^" prefix "[a-zA-Z0-9_]+"
159 notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$"
160 }
161
162 # Extract config name from a line, returns "" if not a config line
163 function get_cfg(line) {
164 if (match(line, cfg_regex)) {
165 return substr(line, RSTART, RLENGTH)
166 } else if (match(line, notset_regex)) {
167 # Extract CONFIG_FOO from "# CONFIG_FOO is not set"
168 sub(/^# /, "", line)
169 sub(/ is not set$/, "", line)
170 return line
171 }
172 return ""
173 }
174
175 function warn_builtin(cfg, prev, new) {
176 if (warnoverride == "true") return
177 print cfg ": -y passed, will not demote y to m"
178 print "Previous value: " prev
179 print "New value: " new
180 print ""
181 }
182
183 function warn_redefined(cfg, prev, new) {
184 if (warnoverride == "true") return
185 print "Value of " cfg " is redefined by fragment " mergefile ":"
186 print "Previous value: " prev
187 print "New value: " new
188 print ""
189 }
190
191 function warn_redundant(cfg) {
192 if (warnredun != "true" || warnoverride == "true") return
193 print "Value of " cfg " is redundant by fragment " mergefile ":"
194 }
195
196 # First pass: read merge file, store all lines and index
197 FILENAME == ARGV[1] {
198 mergefile = FILENAME
199 merge_lines[FNR] = $0
200 merge_total = FNR
201 cfg = get_cfg($0)
202 if (cfg != "") {
203 merge_cfg[cfg] = $0
204 merge_cfg_line[cfg] = FNR
205 }
206 next
207 }
208
209 # Second pass: process base file (TMP_FILE)
210 FILENAME == ARGV[2] {
211 cfg = get_cfg($0)
212
213 # Not a config or not in merge file - keep it
214 if (cfg == "" || !(cfg in merge_cfg)) {
215 print $0 >> ARGV[3]
216 next
217 }
218
219 prev_val = $0
220 new_val = merge_cfg[cfg]
221
222 # BUILTIN: do not demote y to m
223 if (builtin == "true" && new_val ~ /=m$/ && prev_val ~ /=y$/) {
224 warn_builtin(cfg, prev_val, new_val)
225 print $0 >> ARGV[3]
226 skip_merge[merge_cfg_line[cfg]] = 1
227 next
228 }
229
230 # Values equal - redundant
231 if (prev_val == new_val) {
232 warn_redundant(cfg)
233 next
234 }
235
236 # "=n" is the same as "is not set"
237 if (prev_val ~ /=n$/ && new_val ~ / is not set$/) {
238 print $0 >> ARGV[3]
239 next
240 }
241
242 # Values differ - redefined
243 warn_redefined(cfg, prev_val, new_val)
244 if (strict == "true") {
245 strict_violated = 1
246 }
247 }
248
249 # output file, skip all lines
250 FILENAME == ARGV[3] {
251 nextfile
252 }
253
254 END {
255 # Newline in case base file lacks trailing newline
256 print "" >> ARGV[3]
257 # Append merge file, skipping lines marked for builtin preservation
258 for (i = 1; i <= merge_total; i++) {
259 if (!(i in skip_merge)) {
260 print merge_lines[i] >> ARGV[3]
261 }
262 }
263 if (strict_violated) {
264 exit 1
265 }
266 }' \
267 "$ORIG_MERGE_FILE" "$TMP_FILE" "$TMP_FILE.new"; then
268 # awk exited non-zero, strict mode was violated
269 STRICT_MODE_VIOLATED=true
270 fi
271 mv "$TMP_FILE.new" "$TMP_FILE"
272 PROCESSED_FILES="$PROCESSED_FILES $ORIG_MERGE_FILE"
273done
175if [ "$STRICT_MODE_VIOLATED" = "true" ]; then274if [ "$STRICT_MODE_VIOLATED" = "true" ]; then
176 echo "The fragment redefined a value and strict mode had been passed."275 echo "The fragment redefined a value and strict mode had been passed."
177 exit 1276 exit 1
@@ -198,16 +297,91 @@ fi · 20 unmodified lines
198# allnoconfig: Fills in any missing symbols with # CONFIG_* is not set297# allnoconfig: Fills in any missing symbols with # CONFIG_* is not set
199make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET298make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
200 299
300# Check all specified config values took effect (might have missed-dependency issues)
301if ! "$AWK" -v prefix="$CONFIG_PREFIX" \
302 -v warnoverride="$WARNOVERRIDE" \
303 -v strict="$STRICT" \
304 -v warnredun="$WARNREDUN" '
305BEGIN {
306 strict_violated = 0
307 cfg_regex = "^" prefix "[a-zA-Z0-9_]+"
308 notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$"
309}
201 310
202# Check all specified config values took (might have missed-dependency issues)311# Extract config name from a line, returns "" if not a config line
203for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do312function get_cfg(line) {
313 if (match(line, cfg_regex)) {
314 return substr(line, RSTART, RLENGTH)
315 } else if (match(line, notset_regex)) {
316 # Extract CONFIG_FOO from "# CONFIG_FOO is not set"
317 sub(/^# /, "", line)
318 sub(/ is not set$/, "", line)
319 return line
320 }
321 return ""
322}
204 323
205 REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)324function warn_mismatch(cfg, merged, final) {
206 ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true)325 if (warnredun == "true") return
207 if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then326 if (final == "" && !(merged ~ / is not set$/ || merged ~ /=n$/)) {
208 echo "Value requested for $CFG not in final .config"327 print "WARNING: Value requested for " cfg " not in final .config"
209 echo "Requested value: $REQUESTED_VAL"328 print "Requested value: " merged
210 echo "Actual value: $ACTUAL_VAL"329 print "Actual value: " final
211 echo ""330 } else if (final == "" && merged ~ / is not set$/) {
212 fi331 # not set, pass
213done332 } else if (merged == "" && final != "") {
333 print "WARNING: " cfg " not in merged config but added in final .config:"
334 print "Requested value: " merged
335 print "Actual value: " final
336 } else {
337 print "WARNING: " cfg " differs:"
338 print "Requested value: " merged
339 print "Actual value: " final
340 }
341}
342
343# First pass: read effective config file, store all lines
344FILENAME == ARGV[1] {
345 cfg = get_cfg($0)
346 if (cfg != "") {
347 config_cfg[cfg] = $0
348 }
349 next
350}
351
352# Second pass: process merged config and compare against effective config
353{
354 cfg = get_cfg($0)
355 if (cfg == "") next
356
357 # strip trailing comment
358 sub(/[[:space:]]+#.*/, "", $0)
359 merged_val = $0
360 final_val = config_cfg[cfg]
361
362 if (merged_val == final_val) next
363
364 if (merged_val ~ /=n$/ && final_val ~ / is not set$/) next
365 if (merged_val ~ /=n$/ && final_val == "") next
366
367 warn_mismatch(cfg, merged_val, final_val)
368
369 if (strict == "true") {
370 strict_violated = 1
371 }
372}
373
374END {
375 if (strict_violated) {
376 exit 1
377 }
378}' \
379"$KCONFIG_CONFIG" "$TMP_FILE"; then
380 # awk exited non-zero, strict mode was violated
381 STRICT_MODE_VIOLATED=true
382fi
383
384if [ "$STRICT" == "true" ] && [ "$STRICT_MODE_VIOLATED" == "true" ]; then
385 echo "Requested and effective config differ"
386 exit 1
387fi
scripts/kconfig/parser.y+3−3
@@ -323,7 +323,7 @@ if_entry: T_IF expr T_EOL · 322 unmodified lines
323{323{
324 printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno);324 printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno);
325 menu_add_entry(NULL, M_IF);325 menu_add_entry(NULL, M_IF);
326 menu_add_dep($2);326 menu_add_dep($2, NULL);
327 $$ = menu_add_menu();327 $$ = menu_add_menu();
328};328};
329 329
@@ -422,9 +422,9 @@ help: help_start T_HELPTEXT · 92 unmodified lines
422 422
423/* depends option */423/* depends option */
424 424
425depends: T_DEPENDS T_ON expr T_EOL425depends: T_DEPENDS T_ON expr if_expr T_EOL
426{426{
427 menu_add_dep($3);427 menu_add_dep($3, $4);
428 printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno);428 printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno);
429};429};
430 430
scripts/kconfig/qconf.cc+14−15
@@ -26,8 +26,6 @@ · 25 unmodified lines
26#include "lkc.h"26#include "lkc.h"
27#include "qconf.h"27#include "qconf.h"
28 28
29#include "images.h"
30
31 29
32static QApplication *configApp;30static QApplication *configApp;
33static ConfigSettings *configSettings;31static ConfigSettings *configSettings;
@@ -1283,13 +1281,14 @@ ConfigMainWindow::ConfigMainWindow(void) · 1249 unmodified lines
1283 move(x.toInt(), y.toInt());1281 move(x.toInt(), y.toInt());
1284 1282
1285 // set up icons1283 // set up icons
1286 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));1284 QString iconsDir = QString(getenv(SRCTREE) ? getenv(SRCTREE) : QDir::currentPath()) + "/scripts/kconfig/icons/";
1287 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));1285 ConfigItem::symbolYesIcon = QIcon(QPixmap(iconsDir + "symbol_yes.xpm"));
1288 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));1286 ConfigItem::symbolModIcon = QIcon(QPixmap(iconsDir + "symbol_mod.xpm"));
1289 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));1287 ConfigItem::symbolNoIcon = QIcon(QPixmap(iconsDir + "symbol_no.xpm"));
1290 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));1288 ConfigItem::choiceYesIcon = QIcon(QPixmap(iconsDir + "choice_yes.xpm"));
1291 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));1289 ConfigItem::choiceNoIcon = QIcon(QPixmap(iconsDir + "choice_no.xpm"));
1292 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));1290 ConfigItem::menuIcon = QIcon(QPixmap(iconsDir + "menu.xpm"));
1291 ConfigItem::menubackIcon = QIcon(QPixmap(iconsDir + "menuback.xpm"));
1293 1292
1294 QWidget *widget = new QWidget(this);1293 QWidget *widget = new QWidget(this);
1295 setCentralWidget(widget);1294 setCentralWidget(widget);
@@ -1312,7 +1311,7 @@ ConfigMainWindow::ConfigMainWindow(void) · 16 unmodified lines
1312 1311
1313 configList->setFocus();1312 configList->setFocus();
1314 1313
1315 backAction = new QAction(QPixmap(xpm_back), "Back", this);1314 backAction = new QAction(QPixmap(iconsDir + "back.xpm"), "Back", this);
1316 backAction->setShortcut(QKeySequence::Back);1315 backAction->setShortcut(QKeySequence::Back);
1317 connect(backAction, &QAction::triggered,1316 connect(backAction, &QAction::triggered,
1318 this, &ConfigMainWindow::goBack);1317 this, &ConfigMainWindow::goBack);
@@ -1322,12 +1321,12 @@ ConfigMainWindow::ConfigMainWindow(void) · 3 unmodified lines
1322 connect(quitAction, &QAction::triggered,1321 connect(quitAction, &QAction::triggered,
1323 this, &ConfigMainWindow::close);1322 this, &ConfigMainWindow::close);
1324 1323
1325 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this);1324 QAction *loadAction = new QAction(QPixmap(iconsDir + "load.xpm"), "&Open", this);
1326 loadAction->setShortcut(QKeySequence::Open);1325 loadAction->setShortcut(QKeySequence::Open);
1327 connect(loadAction, &QAction::triggered,1326 connect(loadAction, &QAction::triggered,
1328 this, &ConfigMainWindow::loadConfig);1327 this, &ConfigMainWindow::loadConfig);
1329 1328
1330 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);1329 saveAction = new QAction(QPixmap(iconsDir + "save.xpm"), "&Save", this);
1331 saveAction->setShortcut(QKeySequence::Save);1330 saveAction->setShortcut(QKeySequence::Save);
1332 connect(saveAction, &QAction::triggered,1331 connect(saveAction, &QAction::triggered,
1333 this, &ConfigMainWindow::saveConfig);1332 this, &ConfigMainWindow::saveConfig);
@@ -1344,15 +1343,15 @@ ConfigMainWindow::ConfigMainWindow(void) · 10 unmodified lines
1344 searchAction->setShortcut(QKeySequence::Find);1343 searchAction->setShortcut(QKeySequence::Find);
1345 connect(searchAction, &QAction::triggered,1344 connect(searchAction, &QAction::triggered,
1346 this, &ConfigMainWindow::searchConfig);1345 this, &ConfigMainWindow::searchConfig);
1347 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);1346 singleViewAction = new QAction(QPixmap(iconsDir + "single_view.xpm"), "Single View", this);
1348 singleViewAction->setCheckable(true);1347 singleViewAction->setCheckable(true);
1349 connect(singleViewAction, &QAction::triggered,1348 connect(singleViewAction, &QAction::triggered,
1350 this, &ConfigMainWindow::showSingleView);1349 this, &ConfigMainWindow::showSingleView);
1351 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);1350 splitViewAction = new QAction(QPixmap(iconsDir + "split_view.xpm"), "Split View", this);
1352 splitViewAction->setCheckable(true);1351 splitViewAction->setCheckable(true);
1353 connect(splitViewAction, &QAction::triggered,1352 connect(splitViewAction, &QAction::triggered,
1354 this, &ConfigMainWindow::showSplitView);1353 this, &ConfigMainWindow::showSplitView);
1355 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);1354 fullViewAction = new QAction(QPixmap(iconsDir + "tree_view.xpm"), "Full View", this);
1356 fullViewAction->setCheckable(true);1355 fullViewAction->setCheckable(true);
1357 connect(fullViewAction, &QAction::triggered,1356 connect(fullViewAction, &QAction::triggered,
1358 this, &ConfigMainWindow::showFullView);1357 this, &ConfigMainWindow::showFullView);
scripts/kconfig/streamline_config.pl+1−1
@@ -415,7 +415,7 @@ foreach my $module (keys(%modules)) { · 414 unmodified lines
415 }415 }
416 } else {416 } else {
417 # Most likely, someone has a custom (binary?) module loaded.417 # Most likely, someone has a custom (binary?) module loaded.
418 print STDERR "$module config not found!!\n";418 print STDERR "$module config not found!\n";
419 }419 }
420}420}
421 421
scripts/kconfig/tests/conditional_dep/Kconfig+32−0
@@ -0,0 +1,32 @@
1# SPDX-License-Identifier: GPL-2.0
2# Test Kconfig file for conditional dependencies.
3
4# Enable module support for tristate testing
5config MODULES
6 bool "Enable loadable module support"
7 modules
8 default y
9
10config FOO
11 bool "FOO symbol"
12
13config BAR
14 bool "BAR symbol"
15
16config TEST_BASIC
17 bool "Test basic conditional dependency"
18 depends on FOO if BAR
19 default y
20
21config TEST_COMPLEX
22 bool "Test complex conditional dependency"
23 depends on (FOO && BAR) if (FOO || BAR)
24 default y
25
26config BAZ
27 tristate "BAZ symbol"
28
29config TEST_OPTIONAL
30 tristate "Test simple optional dependency"
31 depends on BAZ if BAZ
32 default y
scripts/kconfig/tests/conditional_dep/__init__.py+14−0
@@ -0,0 +1,14 @@
1# SPDX-License-Identifier: GPL-2.0
2"""
3Correctly handle conditional dependencies.
4"""
5
6def test(conf):
7 assert conf.oldconfig('test_config1') == 0
8 assert conf.config_matches('expected_config1')
9
10 assert conf.oldconfig('test_config2') == 0
11 assert conf.config_matches('expected_config2')
12
13 assert conf.oldconfig('test_config3') == 0
14 assert conf.config_matches('expected_config3')
scripts/kconfig/tests/conditional_dep/expected_config1+11−0
@@ -0,0 +1,11 @@
1#
2# Automatically generated file; DO NOT EDIT.
3# Main menu
4#
5CONFIG_MODULES=y
6CONFIG_FOO=y
7CONFIG_BAR=y
8CONFIG_TEST_BASIC=y
9CONFIG_TEST_COMPLEX=y
10CONFIG_BAZ=m
11CONFIG_TEST_OPTIONAL=m
scripts/kconfig/tests/conditional_dep/expected_config2+9−0
@@ -0,0 +1,9 @@
1#
2# Automatically generated file; DO NOT EDIT.
3# Main menu
4#
5CONFIG_MODULES=y
6# CONFIG_FOO is not set
7CONFIG_BAR=y
8CONFIG_BAZ=y
9CONFIG_TEST_OPTIONAL=y
scripts/kconfig/tests/conditional_dep/expected_config3+11−0
@@ -0,0 +1,11 @@
1#
2# Automatically generated file; DO NOT EDIT.
3# Main menu
4#
5CONFIG_MODULES=y
6# CONFIG_FOO is not set
7# CONFIG_BAR is not set
8CONFIG_TEST_BASIC=y
9CONFIG_TEST_COMPLEX=y
10# CONFIG_BAZ is not set
11CONFIG_TEST_OPTIONAL=y
scripts/kconfig/tests/conditional_dep/test_config1+6−0
@@ -0,0 +1,6 @@
1# Basic check that everything can be configured if selected.
2CONFIG_FOO=y
3CONFIG_BAR=y
4CONFIG_BAZ=m
5# Ensure that TEST_OPTIONAL=y with BAZ=m is converted to TEST_OPTIONAL=m
6CONFIG_TEST_OPTIONAL=y
scripts/kconfig/tests/conditional_dep/test_config2+7−0
@@ -0,0 +1,7 @@
1# If FOO is not selected, then TEST_BASIC should fail the conditional
2# dependency since BAR is set.
3# TEST_COMPLEX will fail dependency as it depends on both FOO and BAR
4# if either of those is selected.
5CONFIG_FOO=n
6CONFIG_BAR=y
7CONFIG_BAZ=y
scripts/kconfig/tests/conditional_dep/test_config3+6−0
@@ -0,0 +1,6 @@
1# If FOO is not selected, but BAR is also not selected, then TEST_BASIC
2# should pass since the dependency on FOO is conditional on BAR.
3# TEST_COMPLEX should be also set since neither FOO nor BAR are selected
4# so it has no dependencies.
5CONFIG_FOO=n
6CONFIG_BAR=n
scripts/link-vmlinux.sh+4−0
@@ -143,6 +143,10 @@ kallsyms() · 142 unmodified lines
143 kallsymopt="${kallsymopt} --all-symbols"143 kallsymopt="${kallsymopt} --all-symbols"
144 fi144 fi
145 145
146 if is_enabled CONFIG_64BIT || is_enabled CONFIG_RELOCATABLE; then
147 kallsymopt="${kallsymopt} --pc-relative"
148 fi
149
146 info KSYMS "${2}.S"150 info KSYMS "${2}.S"
147 scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S"151 scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S"
148 152
scripts/make_fit.py+144−35
@@ -10,10 +10,14 @@ · 9 unmodified lines
10Usage:10Usage:
11 make_fit.py -A arm64 -n 'Linux-6.6' -O linux11 make_fit.py -A arm64 -n 'Linux-6.6' -O linux
12 -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk12 -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk
13 @arch/arm64/boot/dts/dtbs-list -E -c gzip13 -r /boot/initrd.img-6.14.0-27-generic @arch/arm64/boot/dts/dtbs-list
14 -E -c gzip
14 15
15Creates a FIT containing the supplied kernel and a set of devicetree files,16Creates a FIT containing the supplied kernel, an optional ramdisk, and a set of
16either specified individually or listed in a file (with an '@' prefix).17devicetree files, either specified individually or listed in a file (with an
18'@' prefix).
19
20Use -r to specify an existing ramdisk/initrd file.
17 21
18Use -E to generate an external FIT (where the data is placed after the22Use -E to generate an external FIT (where the data is placed after the
19FIT data structure). This allows parsing of the data without loading23FIT data structure). This allows parsing of the data without loading
@@ -29,12 +33,11 @@ looks at the .cmd files produced by the kernel build. · 9 unmodified lines
29 33
30The resulting FIT can be booted by bootloaders which support FIT, such34The resulting FIT can be booted by bootloaders which support FIT, such
31as U-Boot, Linuxboot, Tianocore, etc.35as U-Boot, Linuxboot, Tianocore, etc.
32
33Note that this tool does not yet support adding a ramdisk / initrd.
34"""36"""
35 37
36import argparse38import argparse
37import collections39import collections
40import multiprocessing
38import os41import os
39import subprocess42import subprocess
40import sys43import sys
@@ -48,11 +51,12 @@ import libfdt · 7 unmodified lines
48CompTool = collections.namedtuple('CompTool', 'ext,tools')51CompTool = collections.namedtuple('CompTool', 'ext,tools')
49 52
50COMP_TOOLS = {53COMP_TOOLS = {
51 'bzip2': CompTool('.bz2', 'bzip2'),54 'bzip2': CompTool('.bz2', 'pbzip2,bzip2'),
52 'gzip': CompTool('.gz', 'pigz,gzip'),55 'gzip': CompTool('.gz', 'pigz,gzip'),
53 'lz4': CompTool('.lz4', 'lz4'),56 'lz4': CompTool('.lz4', 'lz4'),
54 'lzma': CompTool('.lzma', 'lzma'),57 'lzma': CompTool('.lzma', 'plzip,lzma'),
55 'lzo': CompTool('.lzo', 'lzop'),58 'lzo': CompTool('.lzo', 'lzop'),
59 'xz': CompTool('.xz', 'xz'),
56 'zstd': CompTool('.zstd', 'zstd'),60 'zstd': CompTool('.zstd', 'zstd'),
57}61}
58 62
@@ -81,6 +85,8 @@ def parse_args(): · 22 unmodified lines
81 help='Specifies the operating system')85 help='Specifies the operating system')
82 parser.add_argument('-k', '--kernel', type=str, required=True,86 parser.add_argument('-k', '--kernel', type=str, required=True,
83 help='Specifies the (uncompressed) kernel input file (.itk)')87 help='Specifies the (uncompressed) kernel input file (.itk)')
88 parser.add_argument('-r', '--ramdisk', type=str,
89 help='Specifies the ramdisk/initrd input file')
84 parser.add_argument('-v', '--verbose', action='store_true',90 parser.add_argument('-v', '--verbose', action='store_true',
85 help='Enable verbose output')91 help='Enable verbose output')
86 parser.add_argument('dtbs', type=str, nargs='*',92 parser.add_argument('dtbs', type=str, nargs='*',
@@ -98,7 +104,7 @@ def setup_fit(fsw, name): · 11 unmodified lines
98 fsw (libfdt.FdtSw): Object to use for writing104 fsw (libfdt.FdtSw): Object to use for writing
99 name (str): Name of kernel image105 name (str): Name of kernel image
100 """106 """
101 fsw.INC_SIZE = 65536107 fsw.INC_SIZE = 16 << 20
102 fsw.finish_reservemap()108 fsw.finish_reservemap()
103 fsw.begin_node('')109 fsw.begin_node('')
104 fsw.property_string('description', f'{name} with devicetree set')110 fsw.property_string('description', f'{name} with devicetree set')
@@ -133,7 +139,28 @@ def write_kernel(fsw, data, args): · 28 unmodified lines
133 fsw.property_u32('entry', 0)139 fsw.property_u32('entry', 0)
134 140
135 141
136def finish_fit(fsw, entries):142def write_ramdisk(fsw, data, args):
143 """Write out the ramdisk image
144
145 Writes a ramdisk node along with the required properties
146
147 Args:
148 fsw (libfdt.FdtSw): Object to use for writing
149 data (bytes): Data to write (possibly compressed)
150 args (Namespace): Contains necessary strings:
151 arch: FIT architecture, e.g. 'arm64'
152 fit_os: Operating Systems, e.g. 'linux'
153 """
154 with fsw.add_node('ramdisk'):
155 fsw.property_string('description', 'Ramdisk')
156 fsw.property_string('type', 'ramdisk')
157 fsw.property_string('arch', args.arch)
158 fsw.property_string('compression', 'none')
159 fsw.property_string('os', args.os)
160 fsw.property('data', data)
161
162
163def finish_fit(fsw, entries, has_ramdisk=False):
137 """Finish the FIT ready for use164 """Finish the FIT ready for use
138 165
139 Writes the /configurations node and subnodes166 Writes the /configurations node and subnodes
@@ -143,6 +170,7 @@ def finish_fit(fsw, entries): · 3 unmodified lines
143 entries (list of tuple): List of configurations:170 entries (list of tuple): List of configurations:
144 str: Description of model171 str: Description of model
145 str: Compatible stringlist172 str: Compatible stringlist
173 has_ramdisk (bool): True if a ramdisk is included in the FIT
146 """174 """
147 fsw.end_node()175 fsw.end_node()
148 seq = 0176 seq = 0
@@ -154,6 +182,8 @@ def finish_fit(fsw, entries): · 5 unmodified lines
154 fsw.property_string('description', model)182 fsw.property_string('description', model)
155 fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii"))183 fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii"))
156 fsw.property_string('kernel', 'kernel')184 fsw.property_string('kernel', 'kernel')
185 if has_ramdisk:
186 fsw.property_string('ramdisk', 'ramdisk')
157 fsw.end_node()187 fsw.end_node()
158 188
159 189
@@ -179,7 +209,12 @@ def compress_data(inf, compress): · 19 unmodified lines
179 done = False209 done = False
180 for tool in comp.tools.split(','):210 for tool in comp.tools.split(','):
181 try:211 try:
182 subprocess.call([tool, '-c'], stdin=inf, stdout=outf)212 # Add parallel flags for tools that support them
213 cmd = [tool]
214 if tool in ('zstd', 'xz'):
215 cmd.extend(['-T0']) # Use all available cores
216 cmd.append('-c')
217 subprocess.call(cmd, stdin=inf, stdout=outf)
183 done = True218 done = True
184 break219 break
185 except FileNotFoundError:220 except FileNotFoundError:
@@ -191,15 +226,31 @@ def compress_data(inf, compress): · 5 unmodified lines
191 return comp_data226 return comp_data
192 227
193 228
194def output_dtb(fsw, seq, fname, arch, compress):229def compress_dtb(fname, compress):
230 """Compress a single DTB file
231
232 Args:
233 fname (str): Filename containing the DTB
234 compress (str): Compression algorithm, e.g. 'gzip'
235
236 Returns:
237 tuple: (str: fname, bytes: compressed_data)
238 """
239 with open(fname, 'rb') as inf:
240 compressed = compress_data(inf, compress)
241 return fname, compressed
242
243
244def output_dtb(fsw, seq, fname, arch, compress, data=None):
195 """Write out a single devicetree to the FIT245 """Write out a single devicetree to the FIT
196 246
197 Args:247 Args:
198 fsw (libfdt.FdtSw): Object to use for writing248 fsw (libfdt.FdtSw): Object to use for writing
199 seq (int): Sequence number (1 for first)249 seq (int): Sequence number (1 for first)
200 fname (str): Filename containing the DTB250 fname (str): Filename containing the DTB
201 arch: FIT architecture, e.g. 'arm64'251 arch (str): FIT architecture, e.g. 'arm64'
202 compress (str): Compressed algorithm, e.g. 'gzip'252 compress (str): Compressed algorithm, e.g. 'gzip'
253 data (bytes): Pre-compressed data (optional)
203 """254 """
204 with fsw.add_node(f'fdt-{seq}'):255 with fsw.add_node(f'fdt-{seq}'):
205 fsw.property_string('description', os.path.basename(fname))256 fsw.property_string('description', os.path.basename(fname))
@@ -207,9 +258,10 @@ def output_dtb(fsw, seq, fname, arch, compress): · 1 unmodified line
207 fsw.property_string('arch', arch)258 fsw.property_string('arch', arch)
208 fsw.property_string('compression', compress)259 fsw.property_string('compression', compress)
209 260
210 with open(fname, 'rb') as inf:261 if data is None:
211 compressed = compress_data(inf, compress)262 with open(fname, 'rb') as inf:
212 fsw.property('data', compressed)263 data = compress_data(inf, compress)
264 fsw.property('data', data)
213 265
214 266
215def process_dtb(fname, args):267def process_dtb(fname, args):
@@ -249,30 +301,27 @@ def process_dtb(fname, args): · 33 unmodified lines
249 301
250 return (model, compat, files)302 return (model, compat, files)
251 303
252def build_fit(args):304
253 """Build the FIT from the provided files and arguments305def _process_dtbs(args, fsw, entries, fdts):
306 """Process all DTB files and add them to the FIT
254 307
255 Args:308 Args:
256 args (Namespace): Program arguments309 args: Program arguments
310 fsw: FIT writer object
311 entries: List to append entries to
312 fdts: Dictionary of processed DTBs
257 313
258 Returns:314 Returns:
259 tuple:315 tuple:
260 bytes: FIT data316 Number of files processed
261 int: Number of configurations generated317 Total size of files processed
262 size: Total uncompressed size of data
263 """318 """
264 seq = 0319 seq = 0
265 size = 0320 size = 0
266 fsw = libfdt.FdtSw()
267 setup_fit(fsw, args.name)
268 entries = []
269 fdts = {}
270 321
271 # Handle the kernel322 # First figure out the unique DTB files that need compression
272 with open(args.kernel, 'rb') as inf:323 todo = []
273 comp_data = compress_data(inf, args.compress)324 file_info = [] # List of (fname, model, compat, files) tuples
274 size += os.path.getsize(args.kernel)
275 write_kernel(fsw, comp_data, args)
276 325
277 for fname in args.dtbs:326 for fname in args.dtbs:
278 # Ignore non-DTB (*.dtb) files327 # Ignore non-DTB (*.dtb) files
@@ -282,24 +331,84 @@ def build_fit(args): · 3 unmodified lines
282 try:331 try:
283 (model, compat, files) = process_dtb(fname, args)332 (model, compat, files) = process_dtb(fname, args)
284 except Exception as e:333 except Exception as e:
285 sys.stderr.write(f"Error processing {fname}:\n")334 sys.stderr.write(f'Error processing {fname}:\n')
286 raise e335 raise e
287 336
337 file_info.append((fname, model, compat, files))
338 for fn in files:
339 if fn not in fdts and fn not in todo:
340 todo.append(fn)
341
342 # Compress all DTBs in parallel
343 cache = {}
344 if todo and args.compress != 'none':
345 if args.verbose:
346 print(f'Compressing {len(todo)} DTBs...')
347
348 with multiprocessing.Pool() as pool:
349 compress_args = [(fn, args.compress) for fn in todo]
350 # unpacks each tuple, calls compress_dtb(fn, compress) in parallel
351 results = pool.starmap(compress_dtb, compress_args)
352
353 cache = dict(results)
354
355 # Now write all DTBs to the FIT using pre-compressed data
356 for fname, model, compat, files in file_info:
288 for fn in files:357 for fn in files:
289 if fn not in fdts:358 if fn not in fdts:
290 seq += 1359 seq += 1
291 size += os.path.getsize(fn)360 size += os.path.getsize(fn)
292 output_dtb(fsw, seq, fn, args.arch, args.compress)361 output_dtb(fsw, seq, fn, args.arch, args.compress,
362 cache.get(fn))
293 fdts[fn] = seq363 fdts[fn] = seq
294 364
295 files_seq = [fdts[fn] for fn in files]365 files_seq = [fdts[fn] for fn in files]
296
297 entries.append([model, compat, files_seq])366 entries.append([model, compat, files_seq])
298 367
299 finish_fit(fsw, entries)368 return seq, size
369
370
371def build_fit(args):
372 """Build the FIT from the provided files and arguments
373
374 Args:
375 args (Namespace): Program arguments
376
377 Returns:
378 tuple:
379 bytes: FIT data
380 int: Number of configurations generated
381 size: Total uncompressed size of data
382 """
383 size = 0
384 fsw = libfdt.FdtSw()
385 setup_fit(fsw, args.name)
386 entries = []
387 fdts = {}
388
389 # Handle the kernel
390 with open(args.kernel, 'rb') as inf:
391 comp_data = compress_data(inf, args.compress)
392 size += os.path.getsize(args.kernel)
393 write_kernel(fsw, comp_data, args)
394
395 # Handle the ramdisk if provided. Compression is not supported as it is
396 # already compressed.
397 if args.ramdisk:
398 with open(args.ramdisk, 'rb') as inf:
399 data = inf.read()
400 size += len(data)
401 write_ramdisk(fsw, data, args)
402
403 count, fdt_size = _process_dtbs(args, fsw, entries, fdts)
404 size += fdt_size
405
406 finish_fit(fsw, entries, bool(args.ramdisk))
300 407
301 # Include the kernel itself in the returned file count408 # Include the kernel itself in the returned file count
302 return fsw.as_fdt().as_bytearray(), seq + 1, size409 fdt = fsw.as_fdt()
410 fdt.pack()
411 return fdt.as_bytearray(), count + 1 + bool(args.ramdisk), size
303 412
304 413
305def run_make_fit():414def run_make_fit():
scripts/mod/modpost.c+5−1
@@ -602,6 +602,10 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) · 601 unmodified lines
602 /* Special register function linked on all modules during final link of .ko */602 /* Special register function linked on all modules during final link of .ko */
603 if (strstarts(symname, "_restgpr0_") ||603 if (strstarts(symname, "_restgpr0_") ||
604 strstarts(symname, "_savegpr0_") ||604 strstarts(symname, "_savegpr0_") ||
605 strstarts(symname, "_restgpr1_") ||
606 strstarts(symname, "_savegpr1_") ||
607 strstarts(symname, "_restfpr_") ||
608 strstarts(symname, "_savefpr_") ||
605 strstarts(symname, "_restvr_") ||609 strstarts(symname, "_restvr_") ||
606 strstarts(symname, "_savevr_") ||610 strstarts(symname, "_savevr_") ||
607 strcmp(symname, ".TOC.") == 0)611 strcmp(symname, ".TOC.") == 0)
@@ -958,7 +962,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, · 350 unmodified lines
958 /* symbols in data sections that may refer to any init/exit sections */962 /* symbols in data sections that may refer to any init/exit sections */
959 if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&963 if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
960 match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) &&964 match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) &&
961 match(fromsym, PATTERNS("*_ops", "*_probe", "*_console")))965 match(fromsym, PATTERNS("*_ops", "*_console")))
962 return 0;966 return 0;
963 967
964 /* Check for pattern 3 */968 /* Check for pattern 3 */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t