Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'kbuild-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux

Pull Kbuild/Kconfig updates from Nathan Chancellor:
"Kbuild:

- Drop '*_probe' pattern from modpost section check allowlist, which
hid legitimate warnings (Johan Hovold)

- Disable -Wtype-limits altogether, instead of enabling at W=2
(Vincent Mailhol)

- Improve UAPI testing to skip testing headers that require a libc
when CONFIG_CC_CAN_LINK is not set, opening up testing of headers
with no libc dependencies to more environments (Thomas Weißschuh)

- Update gendwarfksyms documentation with required dependencies
(Jihan LIN)

- Reject invalid LLVM= values to avoid unintentionally falling back
to system toolchain (Thomas Weißschuh)

- Add a script to help run the kernel build process in a container
for consistent environments and testing (Guillaume Tucker)

- Simplify kallsyms by getting rid of the relative base (Ard
Biesheuvel)

- Performance and usability improvements to scripts/make_fit.py
(Simon Glass)

- Minor various clean ups and fixes

Kconfig:

- Move XPM icons to individual files, clearing up GTK deprecation
warnings (Rostislav Krasny)

- Support

depends on FOO if BAR

as syntactic sugar for

depends on FOO || !BAR

(Nicolas Pitre, Graham Roff)

- Refactor merge_config.sh to use awk over shell/sed/grep,
dramatically speeding up processing large number of config
fragments (Anders Roxell, Mikko Rapeli)"

* tag 'kbuild-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux: (39 commits)
kbuild: remove dependency of run-command on config
scripts/make_fit: Compress dtbs in parallel
scripts/make_fit: Support a few more parallel compressors
kbuild: Support a FIT_EXTRA_ARGS environment variable
scripts/make_fit: Move dtb processing into a function
scripts/make_fit: Support an initial ramdisk
scripts/make_fit: Speed up operation
rust: kconfig: Don't require RUST_IS_AVAILABLE for rustc-option
MAINTAINERS: Add scripts/install.sh into Kbuild entry
modpost: Amend ppc64 save/restfpr symnames for -Os build
MIPS: tools: relocs: Ship a definition of R_MIPS_PC32
streamline_config.pl: remove superfluous exclamation mark
kbuild: dummy-tools: Add python3
scripts: kconfig: merge_config.sh: warn on duplicate input files
scripts: kconfig: merge_config.sh: use awk in checks too
scripts: kconfig: merge_config.sh: refactor from shell/sed/grep to awk
kallsyms: Get rid of kallsyms relative base
mips: Add support for PC32 relocations in vmlinux
Documentation: dev-tools: add container.rst page
scripts: add tool to run containerized builds
...

+1516 -627
+227
Documentation/dev-tools/container.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-only 2 + .. Copyright (C) 2025 Guillaume Tucker 3 + 4 + ==================== 5 + Containerized Builds 6 + ==================== 7 + 8 + The ``container`` tool can be used to run any command in the kernel source tree 9 + from within a container. Doing so facilitates reproducing builds across 10 + various platforms, for example when a test bot has reported an issue which 11 + requires a specific version of a compiler or an external test suite. While 12 + this can already be done by users who are familiar with containers, having a 13 + dedicated tool in the kernel tree lowers the barrier to entry by solving common 14 + problems once and for all (e.g. user id management). It also makes it easier 15 + to share an exact command line leading to a particular result. The main use 16 + case is likely to be kernel builds but virtually anything can be run: KUnit, 17 + checkpatch etc. provided a suitable image is available. 18 + 19 + 20 + Options 21 + ======= 22 + 23 + Command line syntax:: 24 + 25 + scripts/container -i IMAGE [OPTION]... CMD... 26 + 27 + Available options: 28 + 29 + ``-e, --env-file ENV_FILE`` 30 + 31 + Path to an environment file to load in the container. 32 + 33 + ``-g, --gid GID`` 34 + 35 + Group id to use inside the container. 36 + 37 + ``-i, --image IMAGE`` 38 + 39 + Container image name (required). 40 + 41 + ``-r, --runtime RUNTIME`` 42 + 43 + Container runtime name. Supported runtimes: ``docker``, ``podman``. 44 + 45 + If not specified, the first one found on the system will be used 46 + i.e. Podman if present, otherwise Docker. 47 + 48 + ``-s, --shell`` 49 + 50 + Run the container in an interactive shell. 51 + 52 + ``-u, --uid UID`` 53 + 54 + User id to use inside the container. 55 + 56 + If the ``-g`` option is not specified, the user id will also be used for 57 + the group id. 58 + 59 + ``-v, --verbose`` 60 + 61 + Enable verbose output. 62 + 63 + ``-h, --help`` 64 + 65 + Show the help message and exit. 66 + 67 + 68 + Usage 69 + ===== 70 + 71 + It's entirely up to the user to choose which image to use and the ``CMD`` 72 + arguments are passed directly as an arbitrary command line to run in the 73 + container. The tool will take care of mounting the source tree as the current 74 + working directory and adjust the user and group id as needed. 75 + 76 + The container image which would typically include a compiler toolchain is 77 + provided by the user and selected via the ``-i`` option. The container runtime 78 + can be selected with the ``-r`` option, which can be either ``docker`` or 79 + ``podman``. If none is specified, the first one found on the system will be 80 + used while giving priority to Podman. Support for other runtimes may be added 81 + later depending on their popularity among users. 82 + 83 + By default, commands are run non-interactively. The user can abort a running 84 + container with SIGINT (Ctrl-C). To run commands interactively with a TTY, the 85 + ``--shell`` or ``-s`` option can be used. Signals will then be received by the 86 + shell directly rather than the parent ``container`` process. To exit an 87 + interactive shell, use Ctrl-D or ``exit``. 88 + 89 + .. note:: 90 + 91 + The only host requirement aside from a container runtime is Python 3.10 or 92 + later. 93 + 94 + .. note:: 95 + 96 + Out-of-tree builds are not fully supported yet. The ``O=`` option can 97 + however already be used with a relative path inside the source tree to keep 98 + separate build outputs. A workaround to build outside the tree is to use 99 + ``mount --bind``, see the examples section further down. 100 + 101 + 102 + Environment Variables 103 + ===================== 104 + 105 + Environment variables are not propagated to the container so they have to be 106 + either defined in the image itself or via the ``-e`` option using an 107 + environment file. In some cases it makes more sense to have them defined in 108 + the Containerfile used to create the image. For example, a Clang-only compiler 109 + toolchain image may have ``LLVM=1`` defined. 110 + 111 + The local environment file is more useful for user-specific variables added 112 + during development. It is passed as-is to the container runtime so its format 113 + may vary. Typically, it will look like the output of ``env``. For example:: 114 + 115 + INSTALL_MOD_STRIP=1 116 + SOME_RANDOM_TEXT=One upon a time 117 + 118 + Please also note that ``make`` options can still be passed on the command line, 119 + so while this can't be done since the first argument needs to be the 120 + executable:: 121 + 122 + scripts/container -i docker.io/tuxmake/korg-clang LLVM=1 make # won't work 123 + 124 + this will work:: 125 + 126 + scripts/container -i docker.io/tuxmake/korg-clang make LLVM=1 127 + 128 + 129 + User IDs 130 + ======== 131 + 132 + This is an area where the behaviour will vary slightly depending on the 133 + container runtime. The goal is to run commands as the user invoking the tool. 134 + With Podman, a namespace is created to map the current user id to a different 135 + one in the container (1000 by default). With Docker, while this is also 136 + possible with recent versions it requires a special feature to be enabled in 137 + the daemon so it's not used here for simplicity. Instead, the container is run 138 + with the current user id directly. In both cases, this will provide the same 139 + file permissions for the kernel source tree mounted as a volume. The only 140 + difference is that when using Docker without a namespace, the user id may not 141 + be the same as the default one set in the image. 142 + 143 + Say, we're using an image which sets up a default user with id 1000 and the 144 + current user calling the ``container`` tool has id 1234. The kernel source 145 + tree was checked out by this same user so the files belong to user 1234. With 146 + Podman, the container will be running as user id 1000 with a mapping to id 1234 147 + so that the files from the mounted volume appear to belong to id 1000 inside 148 + the container. With Docker and no namespace, the container will be running 149 + with user id 1234 which can access the files in the volume but not in the user 150 + 1000 home directory. This shouldn't be an issue when running commands only in 151 + the kernel tree but it is worth highlighting here as it might matter for 152 + special corner cases. 153 + 154 + .. note:: 155 + 156 + Podman's `Docker compatibility 157 + <https://podman-desktop.io/docs/migrating-from-docker/managing-docker-compatibility>`__ 158 + mode to run ``docker`` commands on top of a Podman backend is more complex 159 + and not fully supported yet. As such, Podman will take priority if both 160 + runtimes are available on the system. 161 + 162 + 163 + Examples 164 + ======== 165 + 166 + The TuxMake project provides a variety of prebuilt container images available 167 + on `Docker Hub <https://hub.docker.com/u/tuxmake>`__. Here's the shortest 168 + example to build a kernel using a TuxMake Clang image:: 169 + 170 + scripts/container -i docker.io/tuxmake/korg-clang -- make LLVM=1 defconfig 171 + scripts/container -i docker.io/tuxmake/korg-clang -- make LLVM=1 -j$(nproc) 172 + 173 + .. note:: 174 + 175 + When running a command with options within the container, it should be 176 + separated with a double dash ``--`` to not confuse them with the 177 + ``container`` tool options. Plain commands with no options don't strictly 178 + require the double dashes e.g.:: 179 + 180 + scripts/container -i docker.io/tuxmake/korg-clang make mrproper 181 + 182 + To run ``checkpatch.pl`` in a ``patches`` directory with a generic Perl image:: 183 + 184 + scripts/container -i perl:slim-trixie scripts/checkpatch.pl patches/* 185 + 186 + As an alternative to the TuxMake images, the examples below refer to 187 + ``kernel.org`` images which are based on the `kernel.org compiler toolchains 188 + <https://mirrors.edge.kernel.org/pub/tools/>`__. These aren't (yet) officially 189 + available in any public registry but users can build their own locally instead 190 + using this `experimental repository 191 + <https://gitlab.com/gtucker/korg-containers>`__ by running ``make 192 + PREFIX=kernel.org/``. 193 + 194 + To build just ``bzImage`` using Clang:: 195 + 196 + scripts/container -i kernel.org/clang -- make bzImage -j$(nproc) 197 + 198 + Same with GCC 15 as a particular version tag:: 199 + 200 + scripts/container -i kernel.org/gcc:15 -- make bzImage -j$(nproc) 201 + 202 + For an out-of-tree build, a trick is to bind-mount the destination directory to 203 + a relative path inside the source tree:: 204 + 205 + mkdir -p $HOME/tmp/my-kernel-build 206 + mkdir -p build 207 + sudo mount --bind $HOME/tmp/my-kernel-build build 208 + scripts/container -i kernel.org/gcc -- make mrproper 209 + scripts/container -i kernel.org/gcc -- make O=build defconfig 210 + scripts/container -i kernel.org/gcc -- make O=build -j$(nproc) 211 + 212 + To run KUnit in an interactive shell and get the full output:: 213 + 214 + scripts/container -s -i kernel.org/gcc:kunit -- \ 215 + tools/testing/kunit/kunit.py \ 216 + run \ 217 + --arch=x86_64 \ 218 + --cross_compile=x86_64-linux- 219 + 220 + To just start an interactive shell:: 221 + 222 + scripts/container -si kernel.org/gcc bash 223 + 224 + To build the HTML documentation, which requires the ``kdocs`` image built with 225 + ``make PREFIX=kernel.org/ extra`` as it's not a compiler toolchain:: 226 + 227 + scripts/container -i kernel.org/kdocs make htmldocs
+1
Documentation/dev-tools/index.rst
··· 39 39 gpio-sloppy-logic-analyzer 40 40 autofdo 41 41 propeller 42 + container
+73 -50
Documentation/kbuild/gendwarfksyms.rst
··· 14 14 from the DWARF debugging information, which contains the necessary 15 15 details about the final module ABI. 16 16 17 + Dependencies 18 + ------------ 19 + 20 + gendwarfksyms depends on the libelf, libdw, and zlib libraries. 21 + 22 + Here are a few examples of how to install these dependencies: 23 + 24 + * Arch Linux and derivatives:: 25 + 26 + sudo pacman --needed -S libelf zlib 27 + 28 + * Debian, Ubuntu, and derivatives:: 29 + 30 + sudo apt install libelf-dev libdw-dev zlib1g-dev 31 + 32 + * Fedora and derivatives:: 33 + 34 + sudo dnf install elfutils-libelf-devel elfutils-devel zlib-devel 35 + 36 + * openSUSE and derivatives:: 37 + 38 + sudo zypper install libelf-devel libdw-devel zlib-devel 39 + 17 40 Usage 18 41 ----- 19 42 20 43 gendwarfksyms accepts a list of object files on the command line, and a 21 44 list of symbol names (one per line) in standard input:: 22 45 23 - Usage: gendwarfksyms [options] elf-object-file ... < symbol-list 46 + Usage: gendwarfksyms [options] elf-object-file ... < symbol-list 24 47 25 - Options: 26 - -d, --debug Print debugging information 27 - --dump-dies Dump DWARF DIE contents 28 - --dump-die-map Print debugging information about die_map changes 29 - --dump-types Dump type strings 30 - --dump-versions Dump expanded type strings used for symbol versions 31 - -s, --stable Support kABI stability features 32 - -T, --symtypes file Write a symtypes file 33 - -h, --help Print this message 48 + Options: 49 + -d, --debug Print debugging information 50 + --dump-dies Dump DWARF DIE contents 51 + --dump-die-map Print debugging information about die_map changes 52 + --dump-types Dump type strings 53 + --dump-versions Dump expanded type strings used for symbol versions 54 + -s, --stable Support kABI stability features 55 + -T, --symtypes file Write a symtypes file 56 + -h, --help Print this message 34 57 35 58 36 59 Type information availability ··· 69 46 to exported symbols in the `EXPORT_SYMBOL()` macro using the following 70 47 macro:: 71 48 72 - #define __GENDWARFKSYMS_EXPORT(sym) \ 73 - static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ 74 - __section(".discard.gendwarfksyms") = &sym; 49 + #define __GENDWARFKSYMS_EXPORT(sym) \ 50 + static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ 51 + __section(".discard.gendwarfksyms") = &sym; 75 52 76 53 77 54 When a symbol pointer is found in DWARF, gendwarfksyms can use its ··· 94 71 one-letter prefix followed by "#" and the name of the type. Four 95 72 reference types are supported:: 96 73 97 - e#<type> = enum 98 - s#<type> = struct 99 - t#<type> = typedef 100 - u#<type> = union 74 + e#<type> = enum 75 + s#<type> = struct 76 + t#<type> = typedef 77 + u#<type> = union 101 78 102 79 Type names with spaces in them are wrapped in single quotes, e.g.:: 103 80 104 - s#'core::result::Result<u8, core::num::error::ParseIntError>' 81 + s#'core::result::Result<u8, core::num::error::ParseIntError>' 105 82 106 83 The rest of the line contains a type string. Unlike with genksyms that 107 84 produces C-style type strings, gendwarfksyms uses the same simple parsed ··· 151 128 The following helper macros, for example, can be used to specify rules 152 129 in the source code:: 153 130 154 - #define ___KABI_RULE(hint, target, value) \ 155 - static const char __PASTE(__gendwarfksyms_rule_, \ 131 + #define ___KABI_RULE(hint, target, value) \ 132 + static const char __PASTE(__gendwarfksyms_rule_, \ 156 133 __COUNTER__)[] __used __aligned(1) \ 157 134 __section(".discard.gendwarfksyms.kabi_rules") = \ 158 135 "1\0" #hint "\0" target "\0" value ··· 273 250 274 251 Using the `__KABI_RULE` macro, this rule can be defined as:: 275 252 276 - #define KABI_BYTE_SIZE(fqn, value) \ 277 - __KABI_RULE(byte_size, fqn, value) 253 + #define KABI_BYTE_SIZE(fqn, value) \ 254 + __KABI_RULE(byte_size, fqn, value) 278 255 279 256 Example usage:: 280 257 281 258 struct s { 282 - /* Unchanged original members */ 259 + /* Unchanged original members */ 283 260 unsigned long a; 284 - void *p; 261 + void *p; 285 262 286 - /* Appended new members */ 287 - KABI_IGNORE(0, unsigned long n); 263 + /* Appended new members */ 264 + KABI_IGNORE(0, unsigned long n); 288 265 }; 289 266 290 267 KABI_BYTE_SIZE(s, 16); ··· 353 330 not known at the time the space is reserved, for convenience, names that 354 331 start with `__kabi_` are left out when calculating symbol versions:: 355 332 356 - struct s { 357 - long a; 358 - long __kabi_reserved_0; /* reserved for future use */ 359 - }; 333 + struct s { 334 + long a; 335 + long __kabi_reserved_0; /* reserved for future use */ 336 + }; 360 337 361 338 The reserved space can be taken into use by wrapping the member in a 362 339 union, which includes the original type and the replacement member:: 363 340 364 - struct s { 365 - long a; 366 - union { 367 - long __kabi_reserved_0; /* original type */ 368 - struct b b; /* replaced field */ 369 - }; 370 - }; 341 + struct s { 342 + long a; 343 + union { 344 + long __kabi_reserved_0; /* original type */ 345 + struct b b; /* replaced field */ 346 + }; 347 + }; 371 348 372 349 If the `__kabi_` naming scheme was used when reserving space, the name 373 350 of the first member of the union must start with `__kabi_reserved`. This ··· 392 369 timeframe isn't always possible, in which case one might have to resort 393 370 to placing new members into existing alignment holes:: 394 371 395 - struct s { 396 - int a; 397 - /* a 4-byte alignment hole */ 398 - unsigned long b; 399 - }; 372 + struct s { 373 + int a; 374 + /* a 4-byte alignment hole */ 375 + unsigned long b; 376 + }; 400 377 401 378 402 379 While this won't change the size of the data structure, one needs to ··· 405 382 member to a union where one of the fields has a name starting with 406 383 `__kabi_ignored`:: 407 384 408 - struct s { 409 - int a; 410 - union { 411 - char __kabi_ignored_0; 412 - int n; 413 - }; 414 - unsigned long b; 415 - }; 385 + struct s { 386 + int a; 387 + union { 388 + char __kabi_ignored_0; 389 + int n; 390 + }; 391 + unsigned long b; 392 + }; 416 393 417 394 With **--stable**, both versions produce the same symbol version. The 418 395 examples include a `KABI_IGNORE` macro to simplify the code.
+19 -3
Documentation/kbuild/kconfig-language.rst
··· 118 118 This is a shorthand notation for a type definition plus a value. 119 119 Optionally dependencies for this default value can be added with "if". 120 120 121 - - dependencies: "depends on" <expr> 121 + - dependencies: "depends on" <expr> ["if" <expr>] 122 122 123 123 This defines a dependency for this menu entry. If multiple 124 124 dependencies are defined, they are connected with '&&'. Dependencies ··· 133 133 depends on BAR 134 134 bool "foo" 135 135 default y 136 + 137 + The dependency definition itself may be conditional by appending "if" 138 + followed by an expression. For example:: 139 + 140 + config FOO 141 + tristate 142 + depends on BAR if BAZ 143 + 144 + meaning that FOO is constrained by the value of BAR only if BAZ is 145 + also set. 136 146 137 147 - reverse dependencies: "select" <symbol> ["if" <expr>] 138 148 ··· 612 602 or build cleanly with that module disabled, but cause a link failure 613 603 when trying to use that loadable module from a built-in driver. 614 604 615 - The most common way to express this optional dependency in Kconfig logic 616 - uses the slightly counterintuitive:: 605 + The recommended way to express this optional dependency in Kconfig logic 606 + uses the conditional form:: 607 + 608 + config FOO 609 + tristate "Support for foo hardware" 610 + depends on BAR if BAR 611 + 612 + This slightly counterintuitive style is also widely used:: 617 613 618 614 config FOO 619 615 tristate "Support for foo hardware"
+8
MAINTAINERS
··· 6437 6437 F: drivers/video/console/ 6438 6438 F: include/linux/console* 6439 6439 6440 + CONTAINER BUILD SCRIPT 6441 + M: Guillaume Tucker <gtucker@gtucker.io> 6442 + S: Maintained 6443 + F: Documentation/dev-tools/container.rst 6444 + F: scripts/container 6445 + 6440 6446 CONTEXT TRACKING 6441 6447 M: Frederic Weisbecker <frederic@kernel.org> 6442 6448 M: "Paul E. McKenney" <paulmck@kernel.org> ··· 13773 13767 F: scripts/bash-completion/ 13774 13768 F: scripts/basic/ 13775 13769 F: scripts/clang-tools/ 13770 + F: scripts/container 13776 13771 F: scripts/dummy-tools/ 13777 13772 F: scripts/include/ 13773 + F: scripts/install.sh 13778 13774 F: scripts/mk* 13779 13775 F: scripts/mod/ 13780 13776 F: scripts/package/
+11 -2
Makefile
··· 295 295 cscope gtags TAGS tags help% %docs check% coccicheck \ 296 296 $(version_h) headers headers_% archheaders archscripts \ 297 297 %asm-generic kernelversion %src-pkg dt_binding_check \ 298 - outputmakefile rustavailable rustfmt rustfmtcheck 298 + outputmakefile rustavailable rustfmt rustfmtcheck \ 299 + run-command 299 300 no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \ 300 301 image_name 301 302 single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/ ··· 448 447 LLVM_PREFIX := $(LLVM) 449 448 else ifneq ($(filter -%,$(LLVM)),) 450 449 LLVM_SUFFIX := $(LLVM) 450 + else ifneq ($(LLVM),1) 451 + $(error Invalid value for LLVM, see Documentation/kbuild/llvm.rst) 451 452 endif 452 453 453 454 HOSTCC = $(LLVM_PREFIX)clang$(LLVM_SUFFIX) ··· 1112 1109 1113 1110 # change __FILE__ to the relative path to the source directory 1114 1111 ifdef building_out_of_srctree 1115 - KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) 1112 + KBUILD_CPPFLAGS += -fmacro-prefix-map=$(srcroot)/= 1116 1113 endif 1117 1114 1118 1115 # include additional Makefiles when needed ··· 1436 1433 prepare: headers 1437 1434 endif 1438 1435 1436 + PHONY += usr_gen_init_cpio 1437 + usr_gen_init_cpio: scripts_basic 1438 + $(Q)$(MAKE) $(build)=usr usr/gen_init_cpio 1439 + 1439 1440 PHONY += scripts_unifdef 1440 1441 scripts_unifdef: scripts_basic 1441 1442 $(Q)$(MAKE) $(build)=scripts scripts/unifdef ··· 1692 1685 1693 1686 # Packaging of the kernel to various formats 1694 1687 # --------------------------------------------------------------------------- 1688 + 1689 + modules-cpio-pkg: usr_gen_init_cpio 1695 1690 1696 1691 %src-pkg: FORCE 1697 1692 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@
arch/hexagon/include/uapi/asm/signal.h arch/hexagon/include/asm/signal.h
+2
arch/mips/boot/tools/relocs.c
··· 79 79 REL_TYPE(R_MIPS_HIGHEST), 80 80 REL_TYPE(R_MIPS_PC21_S2), 81 81 REL_TYPE(R_MIPS_PC26_S2), 82 + REL_TYPE(R_MIPS_PC32), 82 83 #undef REL_TYPE 83 84 }; 84 85 const char *name = "unknown type rel type name"; ··· 523 522 case R_MIPS_PC16: 524 523 case R_MIPS_PC21_S2: 525 524 case R_MIPS_PC26_S2: 525 + case R_MIPS_PC32: 526 526 /* 527 527 * NONE can be ignored and PC relative relocations don't 528 528 * need to be adjusted.
+7
arch/mips/boot/tools/relocs.h
··· 29 29 #define R_MIPS_PC26_S2 61 30 30 #endif 31 31 32 + /* 33 + * GNU extension that available in glibc only since 2023, not available on musl. 34 + */ 35 + #ifndef R_MIPS_PC32 36 + #define R_MIPS_PC32 248 37 + #endif 38 + 32 39 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 33 40 34 41 enum symtype {
+2
arch/mips/include/asm/elf.h
··· 123 123 #define R_MIPS_LOVENDOR 100 124 124 #define R_MIPS_HIVENDOR 127 125 125 126 + #define R_MIPS_PC32 248 127 + 126 128 #define SHN_MIPS_ACCOMON 0xff00 /* Allocated common symbols */ 127 129 #define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ 128 130 #define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
-1
drivers/gpu/drm/Makefile
··· 22 22 # The following turn off the warnings enabled by -Wextra 23 23 ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) 24 24 subdir-ccflags-y += -Wno-missing-field-initializers 25 - subdir-ccflags-y += -Wno-type-limits 26 25 subdir-ccflags-y += -Wno-shift-negative-value 27 26 endif 28 27 ifeq ($(findstring 3, $(KBUILD_EXTRA_WARN)),)
-1
fs/btrfs/Makefile
··· 17 17 # The following turn off the warnings enabled by -Wextra 18 18 subdir-ccflags-y += -Wno-missing-field-initializers 19 19 subdir-ccflags-y += -Wno-sign-compare 20 - subdir-ccflags-y += -Wno-type-limits 21 20 subdir-ccflags-y += -Wno-shift-negative-value 22 21 23 22 obj-$(CONFIG_BTRFS_FS) := btrfs.o
+2 -8
include/linux/overflow.h
··· 36 36 #define __type_min(T) ((T)((T)-type_max(T)-(T)1)) 37 37 #define type_min(t) __type_min(typeof(t)) 38 38 39 - /* 40 - * Avoids triggering -Wtype-limits compilation warning, 41 - * while using unsigned data types to check a < 0. 42 - */ 43 - #define is_non_negative(a) ((a) > 0 || (a) == 0) 44 - #define is_negative(a) (!(is_non_negative(a))) 45 39 46 40 /* 47 41 * Allows for effectively applying __must_check to a macro so we can have ··· 195 201 typeof(d) _d = d; \ 196 202 unsigned long long _a_full = _a; \ 197 203 unsigned int _to_shift = \ 198 - is_non_negative(_s) && _s < 8 * sizeof(*d) ? _s : 0; \ 204 + _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \ 199 205 *_d = (_a_full << _to_shift); \ 200 - (_to_shift != _s || is_negative(*_d) || is_negative(_a) || \ 206 + (_to_shift != _s || *_d < 0 || _a < 0 || \ 201 207 (*_d >> _to_shift) != _a); \ 202 208 })) 203 209
+1 -1
include/uapi/linux/hyperv.h
··· 362 362 __u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; 363 363 __u32 value_u32; 364 364 __u64 value_u64; 365 - }; 365 + } __attribute__((packed)); 366 366 } __attribute__((packed)); 367 367 368 368 struct hv_kvp_msg_enumerate {
+2 -2
include/uapi/linux/vbox_vmmdev_types.h
··· 236 236 /** Relative to the request header. */ 237 237 __u32 offset; 238 238 } page_list; 239 - } u; 239 + } __packed u; 240 240 } __packed; 241 241 VMMDEV_ASSERT_SIZE(vmmdev_hgcm_function_parameter32, 4 + 8); 242 242 ··· 251 251 union { 252 252 __u64 phys_addr; 253 253 __u64 linear_addr; 254 - } u; 254 + } __packed u; 255 255 } __packed pointer; 256 256 struct { 257 257 /** Size of the buffer described by the page list. */
+1 -1
init/Kconfig
··· 254 254 255 255 config UAPI_HEADER_TEST 256 256 bool "Compile test UAPI headers" 257 - depends on HEADERS_INSTALL && CC_CAN_LINK 257 + depends on HEADERS_INSTALL 258 258 help 259 259 Compile test headers exported to user-space to ensure they are 260 260 self-contained, i.e. compilable as standalone units.
+4 -2
kernel/kallsyms.c
··· 151 151 152 152 unsigned long kallsyms_sym_address(int idx) 153 153 { 154 - /* values are unsigned offsets */ 155 - return kallsyms_relative_base + (u32)kallsyms_offsets[idx]; 154 + /* non-relocatable 32-bit kernels just embed the value directly */ 155 + if (!IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_RELOCATABLE)) 156 + return (u32)kallsyms_offsets[idx]; 157 + return (unsigned long)offset_to_ptr(kallsyms_offsets + idx); 156 158 } 157 159 158 160 static unsigned int get_symbol_seq(int index)
-1
kernel/kallsyms_internal.h
··· 8 8 extern const u8 kallsyms_names[]; 9 9 10 10 extern const unsigned int kallsyms_num_syms; 11 - extern const unsigned long kallsyms_relative_base; 12 11 13 12 extern const char kallsyms_token_table[]; 14 13 extern const u16 kallsyms_token_index[];
-1
kernel/vmcore_info.c
··· 242 242 VMCOREINFO_SYMBOL(kallsyms_token_table); 243 243 VMCOREINFO_SYMBOL(kallsyms_token_index); 244 244 VMCOREINFO_SYMBOL(kallsyms_offsets); 245 - VMCOREINFO_SYMBOL(kallsyms_relative_base); 246 245 #endif /* CONFIG_KALLSYMS */ 247 246 248 247 arch_crash_save_vmcoreinfo();
-2
scripts/Kconfig.include
··· 73 73 74 74 # $(rustc-option,<flag>) 75 75 # 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 76 # If you are testing for unstable features, consider testing RUSTC_VERSION 79 77 # instead, as features may have different completeness while available. 80 78 rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib)
+1 -1
scripts/Makefile.lib
··· 410 410 411 411 quiet_cmd_fit = FIT $@ 412 412 cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ 413 - --name '$(UIMAGE_NAME)' \ 413 + --name '$(UIMAGE_NAME)' $(FIT_EXTRA_ARGS) \ 414 414 $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ 415 415 $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ 416 416 --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^)
-1
scripts/Makefile.package
··· 201 201 cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $< 202 202 203 203 modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio 204 - $(Q)$(MAKE) $(build)=usr usr/gen_init_cpio 205 204 $(call cmd,cpio) 206 205 207 206 PHONY += modules-cpio-pkg
+13 -14
scripts/Makefile.warn
··· 16 16 KBUILD_CFLAGS += -Werror=strict-prototypes 17 17 KBUILD_CFLAGS += -Wno-format-security 18 18 KBUILD_CFLAGS += -Wno-trigraphs 19 - KBUILD_CFLAGS += $(call cc-option, -Wno-frame-address) 19 + KBUILD_CFLAGS += -Wno-frame-address 20 20 KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member) 21 21 KBUILD_CFLAGS += -Wmissing-declarations 22 22 KBUILD_CFLAGS += -Wmissing-prototypes ··· 55 55 KBUILD_CFLAGS += -Wno-main 56 56 endif 57 57 58 + # Too noisy on range checks and in macros handling both signed and unsigned. 59 + KBUILD_CFLAGS += -Wno-type-limits 60 + 58 61 # These result in bogus false positives 59 62 KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer) 60 63 ··· 75 72 # In order to make sure new function cast mismatches are not introduced 76 73 # in the kernel (to avoid tripping CFI checking), the kernel should be 77 74 # globally built with -Wcast-function-type. 78 - KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type) 75 + KBUILD_CFLAGS += -Wcast-function-type 79 76 80 77 # Currently, disable -Wstringop-overflow for GCC 11, globally. 81 78 KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) ··· 102 99 KBUILD_CFLAGS += -Werror=date-time 103 100 104 101 # enforce correct pointer usage 105 - KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) 102 + KBUILD_CFLAGS += -Werror=incompatible-pointer-types 106 103 107 104 # Require designated initializers for all marked structures 108 105 KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) ··· 119 116 120 117 KBUILD_CFLAGS += -Wmissing-format-attribute 121 118 KBUILD_CFLAGS += -Wmissing-include-dirs 122 - KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable) 119 + KBUILD_CFLAGS += -Wunused-const-variable 123 120 124 121 KBUILD_CPPFLAGS += -Wundef 125 122 KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 ··· 128 125 129 126 # Some diagnostics enabled by default are noisy. 130 127 # Suppress them by using -Wno... except for W=1. 131 - KBUILD_CFLAGS += $(call cc-option, -Wno-unused-but-set-variable) 132 - KBUILD_CFLAGS += $(call cc-option, -Wno-unused-const-variable) 128 + KBUILD_CFLAGS += -Wno-unused-but-set-variable 129 + KBUILD_CFLAGS += -Wno-unused-const-variable 133 130 KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned) 134 131 KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow) 135 132 ifdef CONFIG_CC_IS_GCC 136 - KBUILD_CFLAGS += $(call cc-option, -Wno-format-truncation) 133 + KBUILD_CFLAGS += -Wno-format-truncation 137 134 endif 138 135 KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation) 139 136 ··· 148 145 # problematic. 149 146 KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier 150 147 KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull 151 - # Requires clang-12+. 152 - ifeq ($(call clang-min-version, 120000),y) 153 148 KBUILD_CFLAGS += -Wformat-insufficient-args 154 149 endif 155 - endif 156 - KBUILD_CFLAGS += $(call cc-option, -Wno-pointer-to-enum-cast) 150 + KBUILD_CFLAGS += -Wno-pointer-to-enum-cast 157 151 KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare 158 - KBUILD_CFLAGS += $(call cc-option, -Wno-unaligned-access) 152 + KBUILD_CFLAGS += -Wno-unaligned-access 159 153 KBUILD_CFLAGS += -Wno-enum-compare-conditional 160 154 endif 161 155 ··· 166 166 KBUILD_CFLAGS += -Wdisabled-optimization 167 167 KBUILD_CFLAGS += -Wshadow 168 168 KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) 169 - KBUILD_CFLAGS += $(call cc-option, -Wunused-macros) 169 + KBUILD_CFLAGS += -Wunused-macros 170 170 171 171 KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2 172 172 ··· 174 174 175 175 # The following turn off the warnings enabled by -Wextra 176 176 KBUILD_CFLAGS += -Wno-missing-field-initializers 177 - KBUILD_CFLAGS += -Wno-type-limits 178 177 KBUILD_CFLAGS += -Wno-shift-negative-value 179 178 180 179 ifdef CONFIG_CC_IS_CLANG
+199
scripts/container
··· 1 + #!/usr/bin/env python3 2 + # SPDX-License-Identifier: GPL-2.0-only 3 + # Copyright (C) 2025 Guillaume Tucker 4 + 5 + """Containerized builds""" 6 + 7 + import abc 8 + import argparse 9 + import logging 10 + import os 11 + import pathlib 12 + import shutil 13 + import subprocess 14 + import sys 15 + import uuid 16 + 17 + 18 + class 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 + 55 + class 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 + 83 + class 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 + 94 + class 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 + 105 + class 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 + 134 + def _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 + 146 + def 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 + 159 + if __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:])))
+4
scripts/dummy-tools/python3
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0-only 3 + 4 + true
+16 -46
scripts/kallsyms.c
··· 46 46 }; 47 47 48 48 static unsigned long long _text; 49 - static unsigned long long relative_base; 50 49 static struct addr_range text_ranges[] = { 51 50 { "_stext", "_etext" }, 52 51 { "_sinittext", "_einittext" }, ··· 56 57 static struct sym_entry **table; 57 58 static unsigned int table_size, table_cnt; 58 59 static int all_symbols; 60 + static int pc_relative; 59 61 60 62 static int token_profit[0x10000]; 61 63 ··· 280 280 static void output_label(const char *label) 281 281 { 282 282 printf(".globl %s\n", label); 283 - printf("\tALGN\n"); 283 + printf("\t.balign 4\n"); 284 284 printf("%s:\n", label); 285 285 } 286 286 ··· 342 342 unsigned int best_idx[256]; 343 343 unsigned int *markers, markers_cnt; 344 344 char buf[KSYM_NAME_LEN]; 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 345 355 346 printf("\t.section .rodata, \"a\"\n"); 356 347 ··· 425 434 output_label("kallsyms_offsets"); 426 435 427 436 for (i = 0; i < table_cnt; i++) { 428 - /* 429 - * Use the offset relative to the lowest value 430 - * encountered of all relative symbols, and emit 431 - * non-relocatable fixed offsets that will be fixed 432 - * up at runtime. 433 - */ 437 + if (pc_relative) { 438 + long long offset = table[i]->addr - _text; 434 439 435 - long long offset; 436 - 437 - offset = table[i]->addr - relative_base; 438 - if (offset < 0 || offset > UINT_MAX) { 439 - fprintf(stderr, "kallsyms failure: " 440 - "relative symbol value %#llx out of range\n", 441 - table[i]->addr); 442 - exit(EXIT_FAILURE); 440 + if (offset < INT_MIN || offset > INT_MAX) { 441 + fprintf(stderr, "kallsyms failure: " 442 + "relative symbol value %#llx out of range\n", 443 + table[i]->addr); 444 + exit(EXIT_FAILURE); 445 + } 446 + printf("\t.long\t_text - . + (%d)\t/* %s */\n", 447 + (int)offset, table[i]->sym); 448 + } else { 449 + printf("\t.long\t%#x\t/* %s */\n", 450 + (unsigned int)table[i]->addr, table[i]->sym); 443 451 } 444 - printf("\t.long\t%#x\t/* %s */\n", (int)offset, table[i]->sym); 445 452 } 446 - printf("\n"); 447 - 448 - output_label("kallsyms_relative_base"); 449 - /* Provide proper symbols relocatability by their '_text' relativeness. */ 450 - if (_text <= relative_base) 451 - printf("\tPTR\t_text + %#llx\n", relative_base - _text); 452 - else 453 - printf("\tPTR\t_text - %#llx\n", _text - relative_base); 454 453 printf("\n"); 455 454 456 455 sort_symbols_by_name(); ··· 682 701 qsort(table, table_cnt, sizeof(table[0]), compare_symbols); 683 702 } 684 703 685 - /* find the minimum non-absolute symbol address */ 686 - static void record_relative_base(void) 687 - { 688 - /* 689 - * The table is sorted by address. 690 - * Take the first symbol value. 691 - */ 692 - if (table_cnt) 693 - relative_base = table[0]->addr; 694 - } 695 - 696 704 int main(int argc, char **argv) 697 705 { 698 706 while (1) { 699 707 static const struct option long_options[] = { 700 708 {"all-symbols", no_argument, &all_symbols, 1}, 709 + {"pc-relative", no_argument, &pc_relative, 1}, 701 710 {}, 702 711 }; 703 712 ··· 705 734 read_map(argv[optind]); 706 735 shrink_table(); 707 736 sort_symbols(); 708 - record_relative_base(); 709 737 optimize_token_table(); 710 738 write_src(); 711 739
+2 -2
scripts/kconfig/Makefile
··· 201 201 # qconf: Used for the xconfig target based on Qt 202 202 hostprogs += qconf 203 203 qconf-cxxobjs := qconf.o qconf-moc.o 204 - qconf-objs := images.o $(common-objs) 204 + qconf-objs := $(common-objs) 205 205 206 206 HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs) 207 207 HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags) ··· 219 219 220 220 # gconf: Used for the gconfig target based on GTK+ 221 221 hostprogs += gconf 222 - gconf-objs := gconf.o images.o $(common-objs) 222 + gconf-objs := gconf.o $(common-objs) 223 223 224 224 HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs) 225 225 HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags)
+28 -7
scripts/kconfig/gconf.c
··· 5 5 6 6 #include <stdlib.h> 7 7 #include "lkc.h" 8 - #include "images.h" 9 8 10 9 #include <gtk/gtk.h> 11 10 ··· 950 951 } 951 952 952 953 /* Main Window Initialization */ 953 - static void replace_button_icon(GtkWidget *widget, const char * const xpm[]) 954 + static void replace_button_icon(GtkWidget *widget, const char *filename) 954 955 { 955 956 GdkPixbuf *pixbuf; 956 957 GtkWidget *image; 958 + GError *err = NULL; 957 959 958 - pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm); 960 + char *env = getenv(SRCTREE); 961 + gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/", filename, NULL); 962 + 963 + pixbuf = gdk_pixbuf_new_from_file(path, &err); 964 + g_free(path); 965 + 966 + if (err) { 967 + g_warning("Failed to load icon %s: %s", filename, err->message); 968 + g_error_free(err); 969 + return; 970 + } 971 + 959 972 image = gtk_image_new_from_pixbuf(pixbuf); 960 973 g_object_unref(pixbuf); 961 974 ··· 1089 1078 single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4")); 1090 1079 g_signal_connect(single_btn, "clicked", 1091 1080 G_CALLBACK(on_single_clicked), NULL); 1092 - replace_button_icon(single_btn, xpm_single_view); 1081 + replace_button_icon(single_btn, "single_view.xpm"); 1093 1082 1094 1083 split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5")); 1095 1084 g_signal_connect(split_btn, "clicked", 1096 1085 G_CALLBACK(on_split_clicked), NULL); 1097 - replace_button_icon(split_btn, xpm_split_view); 1086 + replace_button_icon(split_btn, "split_view.xpm"); 1098 1087 1099 1088 full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6")); 1100 1089 g_signal_connect(full_btn, "clicked", 1101 1090 G_CALLBACK(on_full_clicked), NULL); 1102 - replace_button_icon(full_btn, xpm_tree_view); 1091 + replace_button_icon(full_btn, "tree_view.xpm"); 1103 1092 1104 1093 widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7")); 1105 1094 g_signal_connect(widget, "clicked", ··· 1280 1269 g_signal_connect(G_OBJECT(renderer), "edited", 1281 1270 G_CALLBACK(renderer_edited), tree2_w); 1282 1271 1283 - pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu); 1272 + char *env = getenv(SRCTREE); 1273 + gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/menu.xpm", NULL); 1274 + GError *err = NULL; 1275 + 1276 + pix_menu = gdk_pixbuf_new_from_file(path, &err); 1277 + g_free(path); 1278 + 1279 + if (err) { 1280 + g_warning("Failed to load menu icon: %s", err->message); 1281 + g_error_free(err); 1282 + } 1284 1283 1285 1284 for (i = 0; i < COL_VALUE; i++) { 1286 1285 column = gtk_tree_view_get_column(view, i);
+29
scripts/kconfig/icons/back.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+18
scripts/kconfig/icons/choice_no.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+18
scripts/kconfig/icons/choice_yes.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+31
scripts/kconfig/icons/load.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+18
scripts/kconfig/icons/menu.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+18
scripts/kconfig/icons/menuback.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+31
scripts/kconfig/icons/save.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+28
scripts/kconfig/icons/single_view.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+28
scripts/kconfig/icons/split_view.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+18
scripts/kconfig/icons/symbol_mod.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+18
scripts/kconfig/icons/symbol_no.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+18
scripts/kconfig/icons/symbol_yes.xpm
··· 1 + /* XPM */ 2 + static 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 + };
+28
scripts/kconfig/icons/tree_view.xpm
··· 1 + /* XPM */ 2 + static 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 + };
-328
scripts/kconfig/images.c
··· 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 - 8 - const 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 - 38 - const 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 - 68 - const 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 - 96 - const 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 - 123 - const 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 - 150 - const 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 - 177 - const 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 - 194 - const 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 - 211 - const 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 - 228 - const 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 - 245 - const 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 - 262 - const 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 - 279 - const 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 - 296 - const 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 - 313 - const 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 - " "};
-33
scripts/kconfig/images.h
··· 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 10 - extern "C" { 11 - #endif 12 - 13 - extern const char * const xpm_load[]; 14 - extern const char * const xpm_save[]; 15 - extern const char * const xpm_back[]; 16 - extern const char * const xpm_tree_view[]; 17 - extern const char * const xpm_single_view[]; 18 - extern const char * const xpm_split_view[]; 19 - extern const char * const xpm_symbol_no[]; 20 - extern const char * const xpm_symbol_mod[]; 21 - extern const char * const xpm_symbol_yes[]; 22 - extern const char * const xpm_choice_no[]; 23 - extern const char * const xpm_choice_yes[]; 24 - extern const char * const xpm_menu[]; 25 - extern const char * const xpm_menu_inv[]; 26 - extern const char * const xpm_menuback[]; 27 - extern const char * const xpm_void[]; 28 - 29 - #ifdef __cplusplus 30 - } 31 - #endif 32 - 33 - #endif /* IMAGES_H */
+1 -1
scripts/kconfig/lkc.h
··· 82 82 struct menu *menu_add_menu(void); 83 83 void menu_end_menu(void); 84 84 void menu_add_entry(struct symbol *sym, enum menu_type type); 85 - void menu_add_dep(struct expr *dep); 85 + void menu_add_dep(struct expr *dep, struct expr *cond); 86 86 void menu_add_visibility(struct expr *dep); 87 87 struct property *menu_add_prompt(enum prop_type type, const char *prompt, 88 88 struct expr *dep);
+11 -1
scripts/kconfig/menu.c
··· 127 127 return e; 128 128 } 129 129 130 - void menu_add_dep(struct expr *dep) 130 + void 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 142 current_entry->dep = expr_alloc_and(current_entry->dep, dep); 133 143 } 134 144
+224 -50
scripts/kconfig/merge_config.sh
··· 16 16 set -e 17 17 18 18 clean_up() { 19 - rm -f $TMP_FILE 20 - rm -f $MERGE_FILE 19 + rm -f "$TMP_FILE" 20 + rm -f "$TMP_FILE.new" 21 21 } 22 22 23 23 usage() { ··· 42 42 STRICT=false 43 43 CONFIG_PREFIX=${CONFIG_-CONFIG_} 44 44 WARNOVERRIDE=echo 45 + 46 + if [ -z "$AWK" ]; then 47 + AWK=awk 48 + fi 45 49 46 50 while true; do 47 51 case $1 in ··· 121 117 fi 122 118 123 119 MERGE_LIST=$* 124 - SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p" 125 - SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p" 126 120 127 121 TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) 128 - MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX) 129 122 130 123 echo "Using $INITFILE as base" 131 124 132 125 trap clean_up EXIT 133 126 134 127 cat $INITFILE > $TMP_FILE 128 + 129 + PROCESSED_FILES="" 135 130 136 131 # Merge files, printing warnings on overridden values 137 132 for ORIG_MERGE_FILE in $MERGE_LIST ; do ··· 139 136 echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2 140 137 exit 1 141 138 fi 142 - cat $ORIG_MERGE_FILE > $MERGE_FILE 143 - CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE) 144 139 145 - for CFG in $CFG_LIST ; do 146 - grep -q -w $CFG $TMP_FILE || continue 147 - PREV_VAL=$(grep -w $CFG $TMP_FILE) 148 - NEW_VAL=$(grep -w $CFG $MERGE_FILE) 149 - BUILTIN_FLAG=false 150 - if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then 151 - ${WARNOVERRIDE} Previous value: $PREV_VAL 152 - ${WARNOVERRIDE} New value: $NEW_VAL 153 - ${WARNOVERRIDE} -y passed, will not demote y to m 154 - ${WARNOVERRIDE} 155 - BUILTIN_FLAG=true 156 - elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then 157 - ${WARNOVERRIDE} Value of $CFG is redefined by fragment $ORIG_MERGE_FILE: 158 - ${WARNOVERRIDE} Previous value: $PREV_VAL 159 - ${WARNOVERRIDE} New value: $NEW_VAL 160 - ${WARNOVERRIDE} 161 - if [ "$STRICT" = "true" ]; then 162 - STRICT_MODE_VIOLATED=true 163 - fi 164 - elif [ "$WARNREDUN" = "true" ]; then 165 - ${WARNOVERRIDE} Value of $CFG is redundant by fragment $ORIG_MERGE_FILE: 166 - fi 167 - if [ "$BUILTIN_FLAG" = "false" ]; then 168 - sed -i "/$CFG[ =]/d" $TMP_FILE 169 - else 170 - sed -i "/$CFG[ =]/d" $MERGE_FILE 171 - fi 172 - done 173 - # In case the previous file lacks a new line at the end 174 - echo >> $TMP_FILE 175 - cat $MERGE_FILE >> $TMP_FILE 140 + # Check for duplicate input files 141 + case " $PROCESSED_FILES " in 142 + *" $ORIG_MERGE_FILE "*) 143 + ${WARNOVERRIDE} "WARNING: Input file provided multiple times: $ORIG_MERGE_FILE" 144 + ;; 145 + esac 146 + 147 + # Use awk for single-pass processing instead of per-symbol grep/sed 148 + if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ 149 + -v warnoverride="$WARNOVERRIDE" \ 150 + -v strict="$STRICT" \ 151 + -v builtin="$BUILTIN" \ 152 + -v warnredun="$WARNREDUN" ' 153 + BEGIN { 154 + strict_violated = 0 155 + cfg_regex = "^" prefix "[a-zA-Z0-9_]+" 156 + notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$" 157 + } 158 + 159 + # Extract config name from a line, returns "" if not a config line 160 + function get_cfg(line) { 161 + if (match(line, cfg_regex)) { 162 + return substr(line, RSTART, RLENGTH) 163 + } else if (match(line, notset_regex)) { 164 + # Extract CONFIG_FOO from "# CONFIG_FOO is not set" 165 + sub(/^# /, "", line) 166 + sub(/ is not set$/, "", line) 167 + return line 168 + } 169 + return "" 170 + } 171 + 172 + function warn_builtin(cfg, prev, new) { 173 + if (warnoverride == "true") return 174 + print cfg ": -y passed, will not demote y to m" 175 + print "Previous value: " prev 176 + print "New value: " new 177 + print "" 178 + } 179 + 180 + function warn_redefined(cfg, prev, new) { 181 + if (warnoverride == "true") return 182 + print "Value of " cfg " is redefined by fragment " mergefile ":" 183 + print "Previous value: " prev 184 + print "New value: " new 185 + print "" 186 + } 187 + 188 + function warn_redundant(cfg) { 189 + if (warnredun != "true" || warnoverride == "true") return 190 + print "Value of " cfg " is redundant by fragment " mergefile ":" 191 + } 192 + 193 + # First pass: read merge file, store all lines and index 194 + FILENAME == ARGV[1] { 195 + mergefile = FILENAME 196 + merge_lines[FNR] = $0 197 + merge_total = FNR 198 + cfg = get_cfg($0) 199 + if (cfg != "") { 200 + merge_cfg[cfg] = $0 201 + merge_cfg_line[cfg] = FNR 202 + } 203 + next 204 + } 205 + 206 + # Second pass: process base file (TMP_FILE) 207 + FILENAME == ARGV[2] { 208 + cfg = get_cfg($0) 209 + 210 + # Not a config or not in merge file - keep it 211 + if (cfg == "" || !(cfg in merge_cfg)) { 212 + print $0 >> ARGV[3] 213 + next 214 + } 215 + 216 + prev_val = $0 217 + new_val = merge_cfg[cfg] 218 + 219 + # BUILTIN: do not demote y to m 220 + if (builtin == "true" && new_val ~ /=m$/ && prev_val ~ /=y$/) { 221 + warn_builtin(cfg, prev_val, new_val) 222 + print $0 >> ARGV[3] 223 + skip_merge[merge_cfg_line[cfg]] = 1 224 + next 225 + } 226 + 227 + # Values equal - redundant 228 + if (prev_val == new_val) { 229 + warn_redundant(cfg) 230 + next 231 + } 232 + 233 + # "=n" is the same as "is not set" 234 + if (prev_val ~ /=n$/ && new_val ~ / is not set$/) { 235 + print $0 >> ARGV[3] 236 + next 237 + } 238 + 239 + # Values differ - redefined 240 + warn_redefined(cfg, prev_val, new_val) 241 + if (strict == "true") { 242 + strict_violated = 1 243 + } 244 + } 245 + 246 + # output file, skip all lines 247 + FILENAME == ARGV[3] { 248 + nextfile 249 + } 250 + 251 + END { 252 + # Newline in case base file lacks trailing newline 253 + print "" >> ARGV[3] 254 + # Append merge file, skipping lines marked for builtin preservation 255 + for (i = 1; i <= merge_total; i++) { 256 + if (!(i in skip_merge)) { 257 + print merge_lines[i] >> ARGV[3] 258 + } 259 + } 260 + if (strict_violated) { 261 + exit 1 262 + } 263 + }' \ 264 + "$ORIG_MERGE_FILE" "$TMP_FILE" "$TMP_FILE.new"; then 265 + # awk exited non-zero, strict mode was violated 266 + STRICT_MODE_VIOLATED=true 267 + fi 268 + mv "$TMP_FILE.new" "$TMP_FILE" 269 + PROCESSED_FILES="$PROCESSED_FILES $ORIG_MERGE_FILE" 176 270 done 177 - 178 271 if [ "$STRICT_MODE_VIOLATED" = "true" ]; then 179 272 echo "The fragment redefined a value and strict mode had been passed." 180 273 exit 1 ··· 297 198 # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set 298 199 make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET 299 200 201 + # Check all specified config values took effect (might have missed-dependency issues) 202 + if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ 203 + -v warnoverride="$WARNOVERRIDE" \ 204 + -v strict="$STRICT" \ 205 + -v warnredun="$WARNREDUN" ' 206 + BEGIN { 207 + strict_violated = 0 208 + cfg_regex = "^" prefix "[a-zA-Z0-9_]+" 209 + notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$" 210 + } 300 211 301 - # Check all specified config values took (might have missed-dependency issues) 302 - for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do 212 + # Extract config name from a line, returns "" if not a config line 213 + function get_cfg(line) { 214 + if (match(line, cfg_regex)) { 215 + return substr(line, RSTART, RLENGTH) 216 + } else if (match(line, notset_regex)) { 217 + # Extract CONFIG_FOO from "# CONFIG_FOO is not set" 218 + sub(/^# /, "", line) 219 + sub(/ is not set$/, "", line) 220 + return line 221 + } 222 + return "" 223 + } 303 224 304 - REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) 305 - ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true) 306 - if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then 307 - echo "Value requested for $CFG not in final .config" 308 - echo "Requested value: $REQUESTED_VAL" 309 - echo "Actual value: $ACTUAL_VAL" 310 - echo "" 311 - fi 312 - done 225 + function warn_mismatch(cfg, merged, final) { 226 + if (warnredun == "true") return 227 + if (final == "" && !(merged ~ / is not set$/ || merged ~ /=n$/)) { 228 + print "WARNING: Value requested for " cfg " not in final .config" 229 + print "Requested value: " merged 230 + print "Actual value: " final 231 + } else if (final == "" && merged ~ / is not set$/) { 232 + # not set, pass 233 + } else if (merged == "" && final != "") { 234 + print "WARNING: " cfg " not in merged config but added in final .config:" 235 + print "Requested value: " merged 236 + print "Actual value: " final 237 + } else { 238 + print "WARNING: " cfg " differs:" 239 + print "Requested value: " merged 240 + print "Actual value: " final 241 + } 242 + } 243 + 244 + # First pass: read effective config file, store all lines 245 + FILENAME == ARGV[1] { 246 + cfg = get_cfg($0) 247 + if (cfg != "") { 248 + config_cfg[cfg] = $0 249 + } 250 + next 251 + } 252 + 253 + # Second pass: process merged config and compare against effective config 254 + { 255 + cfg = get_cfg($0) 256 + if (cfg == "") next 257 + 258 + # strip trailing comment 259 + sub(/[[:space:]]+#.*/, "", $0) 260 + merged_val = $0 261 + final_val = config_cfg[cfg] 262 + 263 + if (merged_val == final_val) next 264 + 265 + if (merged_val ~ /=n$/ && final_val ~ / is not set$/) next 266 + if (merged_val ~ /=n$/ && final_val == "") next 267 + 268 + warn_mismatch(cfg, merged_val, final_val) 269 + 270 + if (strict == "true") { 271 + strict_violated = 1 272 + } 273 + } 274 + 275 + END { 276 + if (strict_violated) { 277 + exit 1 278 + } 279 + }' \ 280 + "$KCONFIG_CONFIG" "$TMP_FILE"; then 281 + # awk exited non-zero, strict mode was violated 282 + STRICT_MODE_VIOLATED=true 283 + fi 284 + 285 + if [ "$STRICT" == "true" ] && [ "$STRICT_MODE_VIOLATED" == "true" ]; then 286 + echo "Requested and effective config differ" 287 + exit 1 288 + fi
+3 -3
scripts/kconfig/parser.y
··· 323 323 { 324 324 printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno); 325 325 menu_add_entry(NULL, M_IF); 326 - menu_add_dep($2); 326 + menu_add_dep($2, NULL); 327 327 $$ = menu_add_menu(); 328 328 }; 329 329 ··· 422 422 423 423 /* depends option */ 424 424 425 - depends: T_DEPENDS T_ON expr T_EOL 425 + depends: T_DEPENDS T_ON expr if_expr T_EOL 426 426 { 427 - menu_add_dep($3); 427 + menu_add_dep($3, $4); 428 428 printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno); 429 429 }; 430 430
+14 -15
scripts/kconfig/qconf.cc
··· 26 26 #include "lkc.h" 27 27 #include "qconf.h" 28 28 29 - #include "images.h" 30 - 31 29 32 30 static QApplication *configApp; 33 31 static ConfigSettings *configSettings; ··· 1281 1283 move(x.toInt(), y.toInt()); 1282 1284 1283 1285 // set up icons 1284 - ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes)); 1285 - ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod)); 1286 - ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no)); 1287 - ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes)); 1288 - ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no)); 1289 - ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu)); 1290 - ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); 1286 + QString iconsDir = QString(getenv(SRCTREE) ? getenv(SRCTREE) : QDir::currentPath()) + "/scripts/kconfig/icons/"; 1287 + ConfigItem::symbolYesIcon = QIcon(QPixmap(iconsDir + "symbol_yes.xpm")); 1288 + ConfigItem::symbolModIcon = QIcon(QPixmap(iconsDir + "symbol_mod.xpm")); 1289 + ConfigItem::symbolNoIcon = QIcon(QPixmap(iconsDir + "symbol_no.xpm")); 1290 + ConfigItem::choiceYesIcon = QIcon(QPixmap(iconsDir + "choice_yes.xpm")); 1291 + ConfigItem::choiceNoIcon = QIcon(QPixmap(iconsDir + "choice_no.xpm")); 1292 + ConfigItem::menuIcon = QIcon(QPixmap(iconsDir + "menu.xpm")); 1293 + ConfigItem::menubackIcon = QIcon(QPixmap(iconsDir + "menuback.xpm")); 1291 1294 1292 1295 QWidget *widget = new QWidget(this); 1293 1296 setCentralWidget(widget); ··· 1311 1312 1312 1313 configList->setFocus(); 1313 1314 1314 - backAction = new QAction(QPixmap(xpm_back), "Back", this); 1315 + backAction = new QAction(QPixmap(iconsDir + "back.xpm"), "Back", this); 1315 1316 backAction->setShortcut(QKeySequence::Back); 1316 1317 connect(backAction, &QAction::triggered, 1317 1318 this, &ConfigMainWindow::goBack); ··· 1321 1322 connect(quitAction, &QAction::triggered, 1322 1323 this, &ConfigMainWindow::close); 1323 1324 1324 - QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this); 1325 + QAction *loadAction = new QAction(QPixmap(iconsDir + "load.xpm"), "&Open", this); 1325 1326 loadAction->setShortcut(QKeySequence::Open); 1326 1327 connect(loadAction, &QAction::triggered, 1327 1328 this, &ConfigMainWindow::loadConfig); 1328 1329 1329 - saveAction = new QAction(QPixmap(xpm_save), "&Save", this); 1330 + saveAction = new QAction(QPixmap(iconsDir + "save.xpm"), "&Save", this); 1330 1331 saveAction->setShortcut(QKeySequence::Save); 1331 1332 connect(saveAction, &QAction::triggered, 1332 1333 this, &ConfigMainWindow::saveConfig); ··· 1343 1344 searchAction->setShortcut(QKeySequence::Find); 1344 1345 connect(searchAction, &QAction::triggered, 1345 1346 this, &ConfigMainWindow::searchConfig); 1346 - singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); 1347 + singleViewAction = new QAction(QPixmap(iconsDir + "single_view.xpm"), "Single View", this); 1347 1348 singleViewAction->setCheckable(true); 1348 1349 connect(singleViewAction, &QAction::triggered, 1349 1350 this, &ConfigMainWindow::showSingleView); 1350 - splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); 1351 + splitViewAction = new QAction(QPixmap(iconsDir + "split_view.xpm"), "Split View", this); 1351 1352 splitViewAction->setCheckable(true); 1352 1353 connect(splitViewAction, &QAction::triggered, 1353 1354 this, &ConfigMainWindow::showSplitView); 1354 - fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); 1355 + fullViewAction = new QAction(QPixmap(iconsDir + "tree_view.xpm"), "Full View", this); 1355 1356 fullViewAction->setCheckable(true); 1356 1357 connect(fullViewAction, &QAction::triggered, 1357 1358 this, &ConfigMainWindow::showFullView);
+1 -1
scripts/kconfig/streamline_config.pl
··· 415 415 } 416 416 } else { 417 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
+32
scripts/kconfig/tests/conditional_dep/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # Test Kconfig file for conditional dependencies. 3 + 4 + # Enable module support for tristate testing 5 + config MODULES 6 + bool "Enable loadable module support" 7 + modules 8 + default y 9 + 10 + config FOO 11 + bool "FOO symbol" 12 + 13 + config BAR 14 + bool "BAR symbol" 15 + 16 + config TEST_BASIC 17 + bool "Test basic conditional dependency" 18 + depends on FOO if BAR 19 + default y 20 + 21 + config TEST_COMPLEX 22 + bool "Test complex conditional dependency" 23 + depends on (FOO && BAR) if (FOO || BAR) 24 + default y 25 + 26 + config BAZ 27 + tristate "BAZ symbol" 28 + 29 + config TEST_OPTIONAL 30 + tristate "Test simple optional dependency" 31 + depends on BAZ if BAZ 32 + default y
+14
scripts/kconfig/tests/conditional_dep/__init__.py
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + """ 3 + Correctly handle conditional dependencies. 4 + """ 5 + 6 + def 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')
+11
scripts/kconfig/tests/conditional_dep/expected_config1
··· 1 + # 2 + # Automatically generated file; DO NOT EDIT. 3 + # Main menu 4 + # 5 + CONFIG_MODULES=y 6 + CONFIG_FOO=y 7 + CONFIG_BAR=y 8 + CONFIG_TEST_BASIC=y 9 + CONFIG_TEST_COMPLEX=y 10 + CONFIG_BAZ=m 11 + CONFIG_TEST_OPTIONAL=m
+9
scripts/kconfig/tests/conditional_dep/expected_config2
··· 1 + # 2 + # Automatically generated file; DO NOT EDIT. 3 + # Main menu 4 + # 5 + CONFIG_MODULES=y 6 + # CONFIG_FOO is not set 7 + CONFIG_BAR=y 8 + CONFIG_BAZ=y 9 + CONFIG_TEST_OPTIONAL=y
+11
scripts/kconfig/tests/conditional_dep/expected_config3
··· 1 + # 2 + # Automatically generated file; DO NOT EDIT. 3 + # Main menu 4 + # 5 + CONFIG_MODULES=y 6 + # CONFIG_FOO is not set 7 + # CONFIG_BAR is not set 8 + CONFIG_TEST_BASIC=y 9 + CONFIG_TEST_COMPLEX=y 10 + # CONFIG_BAZ is not set 11 + CONFIG_TEST_OPTIONAL=y
+6
scripts/kconfig/tests/conditional_dep/test_config1
··· 1 + # Basic check that everything can be configured if selected. 2 + CONFIG_FOO=y 3 + CONFIG_BAR=y 4 + CONFIG_BAZ=m 5 + # Ensure that TEST_OPTIONAL=y with BAZ=m is converted to TEST_OPTIONAL=m 6 + CONFIG_TEST_OPTIONAL=y
+7
scripts/kconfig/tests/conditional_dep/test_config2
··· 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. 5 + CONFIG_FOO=n 6 + CONFIG_BAR=y 7 + CONFIG_BAZ=y
+6
scripts/kconfig/tests/conditional_dep/test_config3
··· 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. 5 + CONFIG_FOO=n 6 + CONFIG_BAR=n
+147 -38
scripts/make_fit.py
··· 10 10 Usage: 11 11 make_fit.py -A arm64 -n 'Linux-6.6' -O linux 12 12 -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk 13 - @arch/arm64/boot/dts/dtbs-list -E -c gzip 13 + -r /boot/initrd.img-6.14.0-27-generic @arch/arm64/boot/dts/dtbs-list 14 + -E -c gzip 14 15 15 - Creates a FIT containing the supplied kernel and a set of devicetree files, 16 - either specified individually or listed in a file (with an '@' prefix). 16 + Creates a FIT containing the supplied kernel, an optional ramdisk, and a set of 17 + devicetree files, either specified individually or listed in a file (with an 18 + '@' prefix). 19 + 20 + Use -r to specify an existing ramdisk/initrd file. 17 21 18 22 Use -E to generate an external FIT (where the data is placed after the 19 23 FIT data structure). This allows parsing of the data without loading ··· 33 29 34 30 The resulting FIT can be booted by bootloaders which support FIT, such 35 31 as U-Boot, Linuxboot, Tianocore, etc. 36 - 37 - Note that this tool does not yet support adding a ramdisk / initrd. 38 32 """ 39 33 40 34 import argparse 41 35 import collections 36 + import multiprocessing 42 37 import os 43 38 import subprocess 44 39 import sys ··· 51 48 CompTool = collections.namedtuple('CompTool', 'ext,tools') 52 49 53 50 COMP_TOOLS = { 54 - 'bzip2': CompTool('.bz2', 'bzip2'), 51 + 'bzip2': CompTool('.bz2', 'pbzip2,bzip2'), 55 52 'gzip': CompTool('.gz', 'pigz,gzip'), 56 53 'lz4': CompTool('.lz4', 'lz4'), 57 - 'lzma': CompTool('.lzma', 'lzma'), 54 + 'lzma': CompTool('.lzma', 'plzip,lzma'), 58 55 'lzo': CompTool('.lzo', 'lzop'), 56 + 'xz': CompTool('.xz', 'xz'), 59 57 'zstd': CompTool('.zstd', 'zstd'), 60 58 } 61 59 ··· 85 81 help='Specifies the operating system') 86 82 parser.add_argument('-k', '--kernel', type=str, required=True, 87 83 help='Specifies the (uncompressed) kernel input file (.itk)') 84 + parser.add_argument('-r', '--ramdisk', type=str, 85 + help='Specifies the ramdisk/initrd input file') 88 86 parser.add_argument('-v', '--verbose', action='store_true', 89 87 help='Enable verbose output') 90 88 parser.add_argument('dtbs', type=str, nargs='*', ··· 104 98 fsw (libfdt.FdtSw): Object to use for writing 105 99 name (str): Name of kernel image 106 100 """ 107 - fsw.INC_SIZE = 65536 101 + fsw.INC_SIZE = 16 << 20 108 102 fsw.finish_reservemap() 109 103 fsw.begin_node('') 110 104 fsw.property_string('description', f'{name} with devicetree set') ··· 139 133 fsw.property_u32('entry', 0) 140 134 141 135 142 - def finish_fit(fsw, entries): 136 + def write_ramdisk(fsw, data, args): 137 + """Write out the ramdisk image 138 + 139 + Writes a ramdisk node along with the required properties 140 + 141 + Args: 142 + fsw (libfdt.FdtSw): Object to use for writing 143 + data (bytes): Data to write (possibly compressed) 144 + args (Namespace): Contains necessary strings: 145 + arch: FIT architecture, e.g. 'arm64' 146 + fit_os: Operating Systems, e.g. 'linux' 147 + """ 148 + with fsw.add_node('ramdisk'): 149 + fsw.property_string('description', 'Ramdisk') 150 + fsw.property_string('type', 'ramdisk') 151 + fsw.property_string('arch', args.arch) 152 + fsw.property_string('compression', 'none') 153 + fsw.property_string('os', args.os) 154 + fsw.property('data', data) 155 + 156 + 157 + def finish_fit(fsw, entries, has_ramdisk=False): 143 158 """Finish the FIT ready for use 144 159 145 160 Writes the /configurations node and subnodes ··· 170 143 entries (list of tuple): List of configurations: 171 144 str: Description of model 172 145 str: Compatible stringlist 146 + has_ramdisk (bool): True if a ramdisk is included in the FIT 173 147 """ 174 148 fsw.end_node() 175 149 seq = 0 ··· 182 154 fsw.property_string('description', model) 183 155 fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) 184 156 fsw.property_string('kernel', 'kernel') 157 + if has_ramdisk: 158 + fsw.property_string('ramdisk', 'ramdisk') 185 159 fsw.end_node() 186 160 187 161 ··· 209 179 done = False 210 180 for tool in comp.tools.split(','): 211 181 try: 212 - subprocess.call([tool, '-c'], stdin=inf, stdout=outf) 182 + # Add parallel flags for tools that support them 183 + cmd = [tool] 184 + if tool in ('zstd', 'xz'): 185 + cmd.extend(['-T0']) # Use all available cores 186 + cmd.append('-c') 187 + subprocess.call(cmd, stdin=inf, stdout=outf) 213 188 done = True 214 189 break 215 190 except FileNotFoundError: ··· 226 191 return comp_data 227 192 228 193 229 - def output_dtb(fsw, seq, fname, arch, compress): 194 + def compress_dtb(fname, compress): 195 + """Compress a single DTB file 196 + 197 + Args: 198 + fname (str): Filename containing the DTB 199 + compress (str): Compression algorithm, e.g. 'gzip' 200 + 201 + Returns: 202 + tuple: (str: fname, bytes: compressed_data) 203 + """ 204 + with open(fname, 'rb') as inf: 205 + compressed = compress_data(inf, compress) 206 + return fname, compressed 207 + 208 + 209 + def output_dtb(fsw, seq, fname, arch, compress, data=None): 230 210 """Write out a single devicetree to the FIT 231 211 232 212 Args: 233 213 fsw (libfdt.FdtSw): Object to use for writing 234 214 seq (int): Sequence number (1 for first) 235 215 fname (str): Filename containing the DTB 236 - arch: FIT architecture, e.g. 'arm64' 216 + arch (str): FIT architecture, e.g. 'arm64' 237 217 compress (str): Compressed algorithm, e.g. 'gzip' 218 + data (bytes): Pre-compressed data (optional) 238 219 """ 239 220 with fsw.add_node(f'fdt-{seq}'): 240 221 fsw.property_string('description', os.path.basename(fname)) ··· 258 207 fsw.property_string('arch', arch) 259 208 fsw.property_string('compression', compress) 260 209 261 - with open(fname, 'rb') as inf: 262 - compressed = compress_data(inf, compress) 263 - fsw.property('data', compressed) 210 + if data is None: 211 + with open(fname, 'rb') as inf: 212 + data = compress_data(inf, compress) 213 + fsw.property('data', data) 264 214 265 215 266 216 def process_dtb(fname, args): ··· 301 249 302 250 return (model, compat, files) 303 251 252 + 253 + def _process_dtbs(args, fsw, entries, fdts): 254 + """Process all DTB files and add them to the FIT 255 + 256 + Args: 257 + args: Program arguments 258 + fsw: FIT writer object 259 + entries: List to append entries to 260 + fdts: Dictionary of processed DTBs 261 + 262 + Returns: 263 + tuple: 264 + Number of files processed 265 + Total size of files processed 266 + """ 267 + seq = 0 268 + size = 0 269 + 270 + # First figure out the unique DTB files that need compression 271 + todo = [] 272 + file_info = [] # List of (fname, model, compat, files) tuples 273 + 274 + for fname in args.dtbs: 275 + # Ignore non-DTB (*.dtb) files 276 + if os.path.splitext(fname)[1] != '.dtb': 277 + continue 278 + 279 + try: 280 + (model, compat, files) = process_dtb(fname, args) 281 + except Exception as e: 282 + sys.stderr.write(f'Error processing {fname}:\n') 283 + raise e 284 + 285 + file_info.append((fname, model, compat, files)) 286 + for fn in files: 287 + if fn not in fdts and fn not in todo: 288 + todo.append(fn) 289 + 290 + # Compress all DTBs in parallel 291 + cache = {} 292 + if todo and args.compress != 'none': 293 + if args.verbose: 294 + print(f'Compressing {len(todo)} DTBs...') 295 + 296 + with multiprocessing.Pool() as pool: 297 + compress_args = [(fn, args.compress) for fn in todo] 298 + # unpacks each tuple, calls compress_dtb(fn, compress) in parallel 299 + results = pool.starmap(compress_dtb, compress_args) 300 + 301 + cache = dict(results) 302 + 303 + # Now write all DTBs to the FIT using pre-compressed data 304 + for fname, model, compat, files in file_info: 305 + for fn in files: 306 + if fn not in fdts: 307 + seq += 1 308 + size += os.path.getsize(fn) 309 + output_dtb(fsw, seq, fn, args.arch, args.compress, 310 + cache.get(fn)) 311 + fdts[fn] = seq 312 + 313 + files_seq = [fdts[fn] for fn in files] 314 + entries.append([model, compat, files_seq]) 315 + 316 + return seq, size 317 + 318 + 304 319 def build_fit(args): 305 320 """Build the FIT from the provided files and arguments 306 321 ··· 380 261 int: Number of configurations generated 381 262 size: Total uncompressed size of data 382 263 """ 383 - seq = 0 384 264 size = 0 385 265 fsw = libfdt.FdtSw() 386 266 setup_fit(fsw, args.name) ··· 392 274 size += os.path.getsize(args.kernel) 393 275 write_kernel(fsw, comp_data, args) 394 276 395 - for fname in args.dtbs: 396 - # Ignore non-DTB (*.dtb) files 397 - if os.path.splitext(fname)[1] != '.dtb': 398 - continue 277 + # Handle the ramdisk if provided. Compression is not supported as it is 278 + # already compressed. 279 + if args.ramdisk: 280 + with open(args.ramdisk, 'rb') as inf: 281 + data = inf.read() 282 + size += len(data) 283 + write_ramdisk(fsw, data, args) 399 284 400 - try: 401 - (model, compat, files) = process_dtb(fname, args) 402 - except Exception as e: 403 - sys.stderr.write(f"Error processing {fname}:\n") 404 - raise e 285 + count, fdt_size = _process_dtbs(args, fsw, entries, fdts) 286 + size += fdt_size 405 287 406 - for fn in files: 407 - if fn not in fdts: 408 - seq += 1 409 - size += os.path.getsize(fn) 410 - output_dtb(fsw, seq, fn, args.arch, args.compress) 411 - fdts[fn] = seq 412 - 413 - files_seq = [fdts[fn] for fn in files] 414 - 415 - entries.append([model, compat, files_seq]) 416 - 417 - finish_fit(fsw, entries) 288 + finish_fit(fsw, entries, bool(args.ramdisk)) 418 289 419 290 # Include the kernel itself in the returned file count 420 - return fsw.as_fdt().as_bytearray(), seq + 1, size 291 + fdt = fsw.as_fdt() 292 + fdt.pack() 293 + return fdt.as_bytearray(), count + 1 + bool(args.ramdisk), size 421 294 422 295 423 296 def run_make_fit():
+5 -1
scripts/mod/modpost.c
··· 602 602 /* Special register function linked on all modules during final link of .ko */ 603 603 if (strstarts(symname, "_restgpr0_") || 604 604 strstarts(symname, "_savegpr0_") || 605 + strstarts(symname, "_restgpr1_") || 606 + strstarts(symname, "_savegpr1_") || 607 + strstarts(symname, "_restfpr_") || 608 + strstarts(symname, "_savefpr_") || 605 609 strstarts(symname, "_restvr_") || 606 610 strstarts(symname, "_savevr_") || 607 611 strcmp(symname, ".TOC.") == 0) ··· 962 958 /* symbols in data sections that may refer to any init/exit sections */ 963 959 if (match(fromsec, PATTERNS(DATA_SECTIONS)) && 964 960 match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && 965 - match(fromsym, PATTERNS("*_ops", "*_probe", "*_console"))) 961 + match(fromsym, PATTERNS("*_ops", "*_console"))) 966 962 return 0; 967 963 968 964 /* Check for pattern 3 */
-1
tools/perf/tests/vmlinux-kallsyms.c
··· 27 27 * stable symbol list. 28 28 */ 29 29 "kallsyms_offsets", 30 - "kallsyms_relative_base", 31 30 "kallsyms_num_syms", 32 31 "kallsyms_names", 33 32 "kallsyms_markers",
+86 -1
usr/include/Makefile
··· 65 65 no-header-test += asm/fbio.h 66 66 endif 67 67 68 + ifeq ($(SRCARCH),xtensa) 69 + no-header-test += linux/bpf_perf_event.h 70 + endif 71 + 68 72 # asm-generic/*.h is used by asm/*.h, and should not be included directly 69 73 no-header-test += asm-generic/% 70 74 75 + # The following are using libc header and types. 76 + # 77 + # Do not add a new header to the list without legitimate reason. 78 + # Please consider to fix the header first. 79 + # 80 + # Sorted alphabetically. 81 + uses-libc += linux/a.out.h 82 + uses-libc += linux/atmbr2684.h 83 + uses-libc += linux/auto_dev-ioctl.h 84 + uses-libc += linux/auto_fs.h 85 + uses-libc += linux/auto_fs4.h 86 + uses-libc += linux/btrfs_tree.h 87 + uses-libc += linux/cec-funcs.h 88 + uses-libc += linux/cec.h 89 + uses-libc += linux/dvb/dmx.h 90 + uses-libc += linux/dvb/video.h 91 + uses-libc += linux/ethtool.h 92 + uses-libc += linux/ethtool_netlink.h 93 + uses-libc += linux/fuse.h 94 + uses-libc += linux/gsmmux.h 95 + uses-libc += linux/icmp.h 96 + uses-libc += linux/idxd.h 97 + uses-libc += linux/if.h 98 + uses-libc += linux/if_arp.h 99 + uses-libc += linux/if_bonding.h 100 + uses-libc += linux/if_pppox.h 101 + uses-libc += linux/if_tunnel.h 102 + uses-libc += linux/input.h 103 + uses-libc += linux/ip6_tunnel.h 104 + uses-libc += linux/joystick.h 105 + uses-libc += linux/llc.h 106 + uses-libc += linux/mctp.h 107 + uses-libc += linux/mdio.h 108 + uses-libc += linux/mii.h 109 + uses-libc += linux/mptcp.h 110 + uses-libc += linux/netdevice.h 111 + uses-libc += linux/netfilter/xt_RATEEST.h 112 + uses-libc += linux/netfilter/xt_hashlimit.h 113 + uses-libc += linux/netfilter/xt_physdev.h 114 + uses-libc += linux/netfilter/xt_rateest.h 115 + uses-libc += linux/netfilter_arp/arp_tables.h 116 + uses-libc += linux/netfilter_arp/arpt_mangle.h 117 + uses-libc += linux/netfilter_bridge.h 118 + uses-libc += linux/netfilter_bridge/ebtables.h 119 + uses-libc += linux/netfilter_ipv4.h 120 + uses-libc += linux/netfilter_ipv4/ip_tables.h 121 + uses-libc += linux/netfilter_ipv6.h 122 + uses-libc += linux/netfilter_ipv6/ip6_tables.h 123 + uses-libc += linux/route.h 124 + uses-libc += linux/shm.h 125 + uses-libc += linux/soundcard.h 126 + uses-libc += linux/string.h 127 + uses-libc += linux/tipc_config.h 128 + uses-libc += linux/uhid.h 129 + uses-libc += linux/uinput.h 130 + uses-libc += linux/vhost.h 131 + uses-libc += linux/vhost_types.h 132 + uses-libc += linux/virtio_ring.h 133 + uses-libc += linux/wireless.h 134 + uses-libc += regulator/regulator.h 135 + uses-libc += scsi/fc/fc_els.h 136 + 137 + ifeq ($(SRCARCH),hexagon) 138 + uses-libc += asm/sigcontext.h 139 + endif 140 + 141 + ifeq ($(SRCARCH),nios2) 142 + uses-libc += asm/ptrace.h 143 + uses-libc += linux/bpf_perf_event.h 144 + endif 145 + 146 + ifeq ($(SRCARCH),s390) 147 + uses-libc += asm/chpid.h 148 + uses-libc += asm/chsc.h 149 + endif 150 + 71 151 always-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h' 2>/dev/null)) 152 + 153 + target-no-libc = $(filter-out $(uses-libc), $*.h) 154 + target-can-compile = $(and $(filter-out $(no-header-test), $*.h), \ 155 + $(or $(CONFIG_CC_CAN_LINK), $(target-no-libc))) 72 156 73 157 # Include the header twice to detect missing include guard. 74 158 quiet_cmd_hdrtest = HDRTEST $< 75 159 cmd_hdrtest = \ 76 160 $(CC) $(c_flags) -fsyntax-only -Werror -x c /dev/null \ 77 - $(if $(filter-out $(no-header-test), $*.h), -include $< -include $<); \ 161 + $(if $(target-no-libc), -nostdinc) \ 162 + $(if $(target-can-compile), -include $< -include $<); \ 78 163 $(PERL) $(src)/headers_check.pl $(obj) $<; \ 79 164 touch $@ 80 165
-8
usr/include/headers_check.pl
··· 40 40 &check_include(); 41 41 &check_asm_types(); 42 42 &check_declarations(); 43 - # Dropped for now. Too much noise &check_config(); 44 43 } 45 44 close $fh; 46 45 } ··· 73 74 "userspace cannot reference function or " . 74 75 "variable defined in the kernel\n"; 75 76 $ret = 1; 76 - } 77 - } 78 - 79 - sub check_config 80 - { 81 - if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9_]+)[^a-zA-Z0-9_]/) { 82 - printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n"; 83 77 } 84 78 } 85 79