kbuild-fixes needs to be based on 6.19 to apply some fixes for 62089b804895 ("kbuild: rpm-pkg: Generate debuginfo package manually") which landed in 6.19-rc1 but the new material of 7.0 needs fixes merged as well.
Unified · Split
| @@ -0,0 +1,227 @@ | ||
| 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 | |
| @@ -38,6 +38,7 @@ Documentation/process/debugging/index.rst · 37 unmodified lines | ||
| 38 | 38 | gpio-sloppy-logic-analyzer |
| 39 | 39 | autofdo |
| 40 | 40 | propeller |
| 41 | + container | |
| 41 | 42 | |
| 42 | 43 | |
| 43 | 44 | .. only:: subproject and html |
| @@ -14,23 +14,46 @@ selected, **gendwarfksyms** is used instead to calculate symbol versions · 13 unmodified lines | ||
| 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 |
| @@ -46,9 +69,9 @@ TU where symbols are actually exported, gendwarfksyms adds a pointer · 9 unmodified lines | ||
| 46 | 69 | to exported symbols in the `EXPORT_SYMBOL()` macro using the following |
| 47 | 70 | macro:: |
| 48 | 71 | |
| 49 | − #define __GENDWARFKSYMS_EXPORT(sym) \ | |
| 50 | − static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ | |
| 51 | − __section(".discard.gendwarfksyms") = &sym; | |
| 72 | + #define __GENDWARFKSYMS_EXPORT(sym) \ | |
| 73 | + static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ | |
| 74 | + __section(".discard.gendwarfksyms") = &sym; | |
| 52 | 75 | |
| 53 | 76 | |
| 54 | 77 | When a symbol pointer is found in DWARF, gendwarfksyms can use its |
| @@ -71,14 +94,14 @@ either a type reference or a symbol name. Type references have a · 16 unmodified lines | ||
| 71 | 94 | one-letter prefix followed by "#" and the name of the type. Four |
| 72 | 95 | reference types are supported:: |
| 73 | 96 | |
| 74 | − e#<type> = enum | |
| 75 | − s#<type> = struct | |
| 76 | − t#<type> = typedef | |
| 77 | − u#<type> = union | |
| 97 | + e#<type> = enum | |
| 98 | + s#<type> = struct | |
| 99 | + t#<type> = typedef | |
| 100 | + u#<type> = union | |
| 78 | 101 | |
| 79 | 102 | Type names with spaces in them are wrapped in single quotes, e.g.:: |
| 80 | 103 | |
| 81 | − s#'core::result::Result<u8, core::num::error::ParseIntError>' | |
| 104 | + s#'core::result::Result<u8, core::num::error::ParseIntError>' | |
| 82 | 105 | |
| 83 | 106 | The rest of the line contains a type string. Unlike with genksyms that |
| 84 | 107 | produces C-style type strings, gendwarfksyms uses the same simple parsed |
| @@ -128,8 +151,8 @@ the rules. The fields are as follows: · 43 unmodified lines | ||
| 128 | 151 | The following helper macros, for example, can be used to specify rules |
| 129 | 152 | in the source code:: |
| 130 | 153 | |
| 131 | − #define ___KABI_RULE(hint, target, value) \ | |
| 132 | − static const char __PASTE(__gendwarfksyms_rule_, \ | |
| 154 | + #define ___KABI_RULE(hint, target, value) \ | |
| 155 | + static const char __PASTE(__gendwarfksyms_rule_, \ | |
| 133 | 156 | __COUNTER__)[] __used __aligned(1) \ |
| 134 | 157 | __section(".discard.gendwarfksyms.kabi_rules") = \ |
| 135 | 158 | "1\0" #hint "\0" target "\0" value |
| @@ -250,18 +273,18 @@ The rule fields are expected to be as follows: · 114 unmodified lines | ||
| 250 | 273 | |
| 251 | 274 | Using the `__KABI_RULE` macro, this rule can be defined as:: |
| 252 | 275 | |
| 253 | − #define KABI_BYTE_SIZE(fqn, value) \ | |
| 254 | − __KABI_RULE(byte_size, fqn, value) | |
| 276 | + #define KABI_BYTE_SIZE(fqn, value) \ | |
| 277 | + __KABI_RULE(byte_size, fqn, value) | |
| 255 | 278 | |
| 256 | 279 | Example usage:: |
| 257 | 280 | |
| 258 | 281 | struct s { |
| 259 | − /* Unchanged original members */ | |
| 282 | + /* Unchanged original members */ | |
| 260 | 283 | unsigned long a; |
| 261 | − void *p; | |
| 284 | + void *p; | |
| 262 | 285 | |
| 263 | − /* Appended new members */ | |
| 264 | − KABI_IGNORE(0, unsigned long n); | |
| 286 | + /* Appended new members */ | |
| 287 | + KABI_IGNORE(0, unsigned long n); | |
| 265 | 288 | }; |
| 266 | 289 | |
| 267 | 290 | KABI_BYTE_SIZE(s, 16); |
| @@ -330,21 +353,21 @@ reserved member needs a unique name, but as the actual purpose is usually · 62 unmodified lines | ||
| 330 | 353 | not known at the time the space is reserved, for convenience, names that |
| 331 | 354 | start with `__kabi_` are left out when calculating symbol versions:: |
| 332 | 355 | |
| 333 | − struct s { | |
| 334 | − long a; | |
| 335 | − long __kabi_reserved_0; /* reserved for future use */ | |
| 336 | − }; | |
| 356 | + struct s { | |
| 357 | + long a; | |
| 358 | + long __kabi_reserved_0; /* reserved for future use */ | |
| 359 | + }; | |
| 337 | 360 | |
| 338 | 361 | The reserved space can be taken into use by wrapping the member in a |
| 339 | 362 | union, which includes the original type and the replacement member:: |
| 340 | 363 | |
| 341 | − struct s { | |
| 342 | − long a; | |
| 343 | − union { | |
| 344 | − long __kabi_reserved_0; /* original type */ | |
| 345 | − struct b b; /* replaced field */ | |
| 346 | − }; | |
| 347 | − }; | |
| 364 | + struct s { | |
| 365 | + long a; | |
| 366 | + union { | |
| 367 | + long __kabi_reserved_0; /* original type */ | |
| 368 | + struct b b; /* replaced field */ | |
| 369 | + }; | |
| 370 | + }; | |
| 348 | 371 | |
| 349 | 372 | If the `__kabi_` naming scheme was used when reserving space, the name |
| 350 | 373 | of the first member of the union must start with `__kabi_reserved`. This |
| @@ -369,11 +392,11 @@ Predicting which structures will require changes during the support · 18 unmodified lines | ||
| 369 | 392 | timeframe isn't always possible, in which case one might have to resort |
| 370 | 393 | to placing new members into existing alignment holes:: |
| 371 | 394 | |
| 372 | − struct s { | |
| 373 | − int a; | |
| 374 | − /* a 4-byte alignment hole */ | |
| 375 | − unsigned long b; | |
| 376 | − }; | |
| 395 | + struct s { | |
| 396 | + int a; | |
| 397 | + /* a 4-byte alignment hole */ | |
| 398 | + unsigned long b; | |
| 399 | + }; | |
| 377 | 400 | |
| 378 | 401 | |
| 379 | 402 | While this won't change the size of the data structure, one needs to |
| @@ -382,14 +405,14 @@ to reserved fields, this can be accomplished by wrapping the added · 2 unmodified lines | ||
| 382 | 405 | member to a union where one of the fields has a name starting with |
| 383 | 406 | `__kabi_ignored`:: |
| 384 | 407 | |
| 385 | − struct s { | |
| 386 | − int a; | |
| 387 | − union { | |
| 388 | − char __kabi_ignored_0; | |
| 389 | − int n; | |
| 390 | − }; | |
| 391 | − unsigned long b; | |
| 392 | − }; | |
| 408 | + struct s { | |
| 409 | + int a; | |
| 410 | + union { | |
| 411 | + char __kabi_ignored_0; | |
| 412 | + int n; | |
| 413 | + }; | |
| 414 | + unsigned long b; | |
| 415 | + }; | |
| 393 | 416 | |
| 394 | 417 | With **--stable**, both versions produce the same symbol version. The |
| 395 | 418 | examples include a `KABI_IGNORE` macro to simplify the code. |
| @@ -118,7 +118,7 @@ applicable everywhere (see syntax). · 117 unmodified lines | ||
| 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 |
| @@ -134,6 +134,16 @@ applicable everywhere (see syntax). · 9 unmodified lines | ||
| 134 | 134 | bool "foo" |
| 135 | 135 | default y |
| 136 | 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. | |
| 146 | + | |
| 137 | 147 | - reverse dependencies: "select" <symbol> ["if" <expr>] |
| 138 | 148 | |
| 139 | 149 | While normal dependencies reduce the upper limit of a symbol (see |
| @@ -602,8 +612,14 @@ Some drivers are able to optionally use a feature from another module · 462 unmodified lines | ||
| 602 | 612 | or build cleanly with that module disabled, but cause a link failure |
| 603 | 613 | when trying to use that loadable module from a built-in driver. |
| 604 | 614 | |
| 605 | −The most common way to express this optional dependency in Kconfig logic | |
| 606 | −uses the slightly counterintuitive:: | |
| 615 | +The recommended way to express this optional dependency in Kconfig logic | |
| 616 | +uses the conditional form:: | |
| 617 | + | |
| 618 | + config FOO | |
| 619 | + tristate "Support for foo hardware" | |
| 620 | + depends on BAR if BAR | |
| 621 | + | |
| 622 | +This slightly counterintuitive style is also widely used:: | |
| 607 | 623 | |
| 608 | 624 | config FOO |
| 609 | 625 | tristate "Support for foo hardware" |
| @@ -6386,6 +6386,12 @@ S: Supported · 6385 unmodified lines | ||
| 6386 | 6386 | F: drivers/video/console/ |
| 6387 | 6387 | F: include/linux/console* |
| 6388 | 6388 | |
| 6389 | +CONTAINER BUILD SCRIPT | |
| 6390 | +M: Guillaume Tucker <gtucker@gtucker.io> | |
| 6391 | +S: Maintained | |
| 6392 | +F: Documentation/dev-tools/container.rst | |
| 6393 | +F: scripts/container | |
| 6394 | + | |
| 6389 | 6395 | CONTEXT TRACKING |
| 6390 | 6396 | M: Frederic Weisbecker <frederic@kernel.org> |
| 6391 | 6397 | M: "Paul E. McKenney" <paulmck@kernel.org> |
| @@ -13683,8 +13689,10 @@ F: scripts/Makefile* · 7291 unmodified lines | ||
| 13683 | 13689 | F: scripts/bash-completion/ |
| 13684 | 13690 | F: scripts/basic/ |
| 13685 | 13691 | F: scripts/clang-tools/ |
| 13692 | +F: scripts/container | |
| 13686 | 13693 | F: scripts/dummy-tools/ |
| 13687 | 13694 | F: scripts/include/ |
| 13695 | +F: scripts/install.sh | |
| 13688 | 13696 | F: scripts/mk* |
| 13689 | 13697 | F: scripts/mod/ |
| 13690 | 13698 | F: scripts/package/ |
| @@ -295,7 +295,8 @@ no-dot-config-targets := $(clean-targets) \ · 294 unmodified lines | ||
| 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 %/ |
| @@ -447,6 +448,8 @@ ifneq ($(filter %/,$(LLVM)),) · 145 unmodified lines | ||
| 447 | 448 | LLVM_PREFIX := $(LLVM) |
| 448 | 449 | else ifneq ($(filter -%,$(LLVM)),) |
| 449 | 450 | LLVM_SUFFIX := $(LLVM) |
| 451 | +else ifneq ($(LLVM),1) | |
| 452 | +$(error Invalid value for LLVM, see Documentation/kbuild/llvm.rst) | |
| 450 | 453 | endif |
| 451 | 454 | |
| 452 | 455 | HOSTCC = $(LLVM_PREFIX)clang$(LLVM_SUFFIX) |
| @@ -1102,7 +1105,7 @@ KBUILD_CFLAGS += -fno-builtin-wcslen · 649 unmodified lines | ||
| 1102 | 1105 | |
| 1103 | 1106 | # change __FILE__ to the relative path to the source directory |
| 1104 | 1107 | ifdef building_out_of_srctree |
| 1105 | −KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) | |
| 1108 | +KBUILD_CPPFLAGS += -fmacro-prefix-map=$(srcroot)/= | |
| 1106 | 1109 | endif |
| 1107 | 1110 | |
| 1108 | 1111 | # include additional Makefiles when needed |
| @@ -1417,6 +1420,10 @@ ifdef CONFIG_HEADERS_INSTALL · 308 unmodified lines | ||
| 1417 | 1420 | prepare: headers |
| 1418 | 1421 | endif |
| 1419 | 1422 | |
| 1423 | +PHONY += usr_gen_init_cpio | |
| 1424 | +usr_gen_init_cpio: scripts_basic | |
| 1425 | + $(Q)$(MAKE) $(build)=usr usr/gen_init_cpio | |
| 1426 | + | |
| 1420 | 1427 | PHONY += scripts_unifdef |
| 1421 | 1428 | scripts_unifdef: scripts_basic |
| 1422 | 1429 | $(Q)$(MAKE) $(build)=scripts scripts/unifdef |
| @@ -1670,6 +1677,8 @@ distclean: mrproper · 247 unmodified lines | ||
| 1670 | 1677 | # Packaging of the kernel to various formats |
| 1671 | 1678 | # --------------------------------------------------------------------------- |
| 1672 | 1679 | |
| 1680 | +modules-cpio-pkg: usr_gen_init_cpio | |
| 1681 | + | |
| 1673 | 1682 | %src-pkg: FORCE |
| 1674 | 1683 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@ |
| 1675 | 1684 | %pkg: include/config/kernel.release FORCE |
File renamed without changes.
| @@ -79,6 +79,7 @@ static const char *rel_type(unsigned type) · 78 unmodified lines | ||
| 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"; |
| @@ -522,6 +523,7 @@ static int do_reloc(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, · 437 unmodified lines | ||
| 522 | 523 | case R_MIPS_PC16: |
| 523 | 524 | case R_MIPS_PC21_S2: |
| 524 | 525 | case R_MIPS_PC26_S2: |
| 526 | + case R_MIPS_PC32: | |
| 525 | 527 | /* |
| 526 | 528 | * NONE can be ignored and PC relative relocations don't |
| 527 | 529 | * need to be adjusted. |
| @@ -29,6 +29,13 @@ void die(char *fmt, ...); · 28 unmodified lines | ||
| 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 { |
| @@ -123,6 +123,8 @@ · 122 unmodified lines | ||
| 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. */ |
| @@ -22,7 +22,6 @@ subdir-ccflags-y += $(call cc-option, -Wstringop-truncation) · 21 unmodified lines | ||
| 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)),) |
| @@ -17,7 +17,6 @@ subdir-ccflags-y += $(condflags) · 16 unmodified lines | ||
| 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 |
| @@ -36,12 +36,6 @@ · 35 unmodified lines | ||
| 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 |
| @@ -201,9 +195,9 @@ static inline bool __must_check __must_check_overflow(bool overflow) · 153 unmodified lines | ||
| 201 | 195 | typeof(d) _d = d; \ |
| 202 | 196 | unsigned long long _a_full = _a; \ |
| 203 | 197 | unsigned int _to_shift = \ |
| 204 | − is_non_negative(_s) && _s < 8 * sizeof(*d) ? _s : 0; \ | |
| 198 | + _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \ | |
| 205 | 199 | *_d = (_a_full << _to_shift); \ |
| 206 | − (_to_shift != _s || is_negative(*_d) || is_negative(_a) || \ | |
| 200 | + (_to_shift != _s || *_d < 0 || _a < 0 || \ | |
| 207 | 201 | (*_d >> _to_shift) != _a); \ |
| 208 | 202 | })) |
| 209 | 203 | |
| @@ -362,7 +362,7 @@ struct hv_kvp_exchg_msg_value { · 361 unmodified lines | ||
| 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 { |
| @@ -236,7 +236,7 @@ struct vmmdev_hgcm_function_parameter32 { · 235 unmodified lines | ||
| 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,7 +251,7 @@ struct vmmdev_hgcm_function_parameter64 { · 8 unmodified lines | ||
| 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. */ |
| @@ -247,7 +247,7 @@ config WERROR · 246 unmodified lines | ||
| 247 | 247 | |
| 248 | 248 | config UAPI_HEADER_TEST |
| 249 | 249 | bool "Compile test UAPI headers" |
| 250 | − depends on HEADERS_INSTALL && CC_CAN_LINK | |
| 250 | + depends on HEADERS_INSTALL | |
| 251 | 251 | help |
| 252 | 252 | Compile test headers exported to user-space to ensure they are |
| 253 | 253 | self-contained, i.e. compilable as standalone units. |
| @@ -151,8 +151,10 @@ static unsigned int get_symbol_offset(unsigned long pos) · 150 unmodified lines | ||
| 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) |
| @@ -8,7 +8,6 @@ extern const int kallsyms_offsets[]; · 7 unmodified lines | ||
| 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[]; |
| @@ -242,7 +242,6 @@ static int __init crash_save_vmcoreinfo_init(void) · 241 unmodified lines | ||
| 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(); |
| @@ -73,8 +73,6 @@ rustc-llvm-version := $(shell,$(srctree)/scripts/rustc-llvm-version.sh $(RUSTC)) · 72 unmodified lines | ||
| 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) |
| @@ -400,7 +400,7 @@ FIT_COMPRESSION ?= gzip · 399 unmodified lines | ||
| 400 | 400 | |
| 401 | 401 | quiet_cmd_fit = FIT $@ |
| 402 | 402 | cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ |
| 403 | − --name '$(UIMAGE_NAME)' \ | |
| 403 | + --name '$(UIMAGE_NAME)' $(FIT_EXTRA_ARGS) \ | |
| 404 | 404 | $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ |
| 405 | 405 | $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ |
| 406 | 406 | --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) |
| @@ -201,7 +201,6 @@ quiet_cmd_cpio = CPIO $@ · 200 unmodified lines | ||
| 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 |
| @@ -16,7 +16,7 @@ KBUILD_CFLAGS += -Werror=return-type · 15 unmodified lines | ||
| 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,6 +55,9 @@ else · 32 unmodified lines | ||
| 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 | |
| @@ -72,7 +75,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign · 11 unmodified lines | ||
| 72 | 75 | # In order to make sure new function cast mismatches are not introduced |
| 73 | 76 | # in the kernel (to avoid tripping CFI checking), the kernel should be |
| 74 | 77 | # globally built with -Wcast-function-type. |
| 75 | −KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type) | |
| 78 | +KBUILD_CFLAGS += -Wcast-function-type | |
| 76 | 79 | |
| 77 | 80 | # Currently, disable -Wstringop-overflow for GCC 11, globally. |
| 78 | 81 | KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) |
| @@ -99,7 +102,7 @@ KBUILD_CFLAGS += $(KBUILD_CFLAGS-y) $(CONFIG_CC_IMPLICIT_FALLTHROUGH) · 20 unmodified lines | ||
| 99 | 102 | KBUILD_CFLAGS += -Werror=date-time |
| 100 | 103 | |
| 101 | 104 | # enforce correct pointer usage |
| 102 | −KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) | |
| 105 | +KBUILD_CFLAGS += -Werror=incompatible-pointer-types | |
| 103 | 106 | |
| 104 | 107 | # Require designated initializers for all marked structures |
| 105 | 108 | KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) |
| @@ -116,7 +119,7 @@ ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) · 10 unmodified lines | ||
| 116 | 119 | |
| 117 | 120 | KBUILD_CFLAGS += -Wmissing-format-attribute |
| 118 | 121 | KBUILD_CFLAGS += -Wmissing-include-dirs |
| 119 | −KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable) | |
| 122 | +KBUILD_CFLAGS += -Wunused-const-variable | |
| 120 | 123 | |
| 121 | 124 | KBUILD_CPPFLAGS += -Wundef |
| 122 | 125 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 |
| @@ -125,12 +128,12 @@ else · 2 unmodified lines | ||
| 125 | 128 | |
| 126 | 129 | # Some diagnostics enabled by default are noisy. |
| 127 | 130 | # Suppress them by using -Wno... except for W=1. |
| 128 | −KBUILD_CFLAGS += $(call cc-option, -Wno-unused-but-set-variable) | |
| 129 | −KBUILD_CFLAGS += $(call cc-option, -Wno-unused-const-variable) | |
| 131 | +KBUILD_CFLAGS += -Wno-unused-but-set-variable | |
| 132 | +KBUILD_CFLAGS += -Wno-unused-const-variable | |
| 130 | 133 | KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned) |
| 131 | 134 | KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow) |
| 132 | 135 | ifdef CONFIG_CC_IS_GCC |
| 133 | −KBUILD_CFLAGS += $(call cc-option, -Wno-format-truncation) | |
| 136 | +KBUILD_CFLAGS += -Wno-format-truncation | |
| 134 | 137 | endif |
| 135 | 138 | KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation) |
| 136 | 139 | |
| @@ -145,14 +148,11 @@ KBUILD_CFLAGS += -Wno-format · 8 unmodified lines | ||
| 145 | 148 | # problematic. |
| 146 | 149 | KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier |
| 147 | 150 | KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull |
| 148 | −# Requires clang-12+. | |
| 149 | −ifeq ($(call clang-min-version, 120000),y) | |
| 150 | 151 | KBUILD_CFLAGS += -Wformat-insufficient-args |
| 151 | 152 | endif |
| 152 | −endif | |
| 153 | −KBUILD_CFLAGS += $(call cc-option, -Wno-pointer-to-enum-cast) | |
| 153 | +KBUILD_CFLAGS += -Wno-pointer-to-enum-cast | |
| 154 | 154 | KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare |
| 155 | −KBUILD_CFLAGS += $(call cc-option, -Wno-unaligned-access) | |
| 155 | +KBUILD_CFLAGS += -Wno-unaligned-access | |
| 156 | 156 | KBUILD_CFLAGS += -Wno-enum-compare-conditional |
| 157 | 157 | endif |
| 158 | 158 | |
| @@ -166,7 +166,7 @@ ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) · 7 unmodified lines | ||
| 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,7 +174,6 @@ else · 1 unmodified line | ||
| 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 |
| @@ -0,0 +1,199 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +# SPDX-License-Identifier: GPL-2.0-only | |
| 3 | +# Copyright (C) 2025 Guillaume Tucker | |
| 4 | + | |
| 5 | +"""Containerized builds""" | |
| 6 | + | |
| 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:]))) | |
| @@ -0,0 +1,4 @@ | ||
| 1 | +#!/bin/sh | |
| 2 | +# SPDX-License-Identifier: GPL-2.0-only | |
| 3 | + | |
| 4 | +true | |
| @@ -46,7 +46,6 @@ struct addr_range { · 45 unmodified lines | ||
| 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" }, |
| @@ -57,6 +56,7 @@ static struct addr_range text_ranges[] = { · 4 unmodified lines | ||
| 57 | 56 | static struct sym_entry **table; |
| 58 | 57 | static unsigned int table_size, table_cnt; |
| 59 | 58 | static int all_symbols; |
| 59 | +static int pc_relative; | |
| 60 | 60 | |
| 61 | 61 | static int token_profit[0x10000]; |
| 62 | 62 | |
| @@ -280,7 +280,7 @@ static void read_map(const char *in) · 217 unmodified lines | ||
| 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 | |
| @@ -343,15 +343,6 @@ static void write_src(void) · 56 unmodified lines | ||
| 343 | 343 | unsigned int *markers, markers_cnt; |
| 344 | 344 | char buf[KSYM_NAME_LEN]; |
| 345 | 345 | |
| 346 | − printf("#include <asm/bitsperlong.h>\n"); | |
| 347 | − printf("#if BITS_PER_LONG == 64\n"); | |
| 348 | − printf("#define PTR .quad\n"); | |
| 349 | − printf("#define ALGN .balign 8\n"); | |
| 350 | − printf("#else\n"); | |
| 351 | − printf("#define PTR .long\n"); | |
| 352 | − printf("#define ALGN .balign 4\n"); | |
| 353 | − printf("#endif\n"); | |
| 354 | − | |
| 355 | 346 | printf("\t.section .rodata, \"a\"\n"); |
| 356 | 347 | |
| 357 | 348 | output_label("kallsyms_num_syms"); |
| @@ -434,34 +425,24 @@ static void write_src(void) · 76 unmodified lines | ||
| 434 | 425 | output_label("kallsyms_offsets"); |
| 435 | 426 | |
| 436 | 427 | for (i = 0; i < table_cnt; i++) { |
| 437 | − /* | |
| 438 | − * Use the offset relative to the lowest value | |
| 439 | − * encountered of all relative symbols, and emit | |
| 440 | − * non-relocatable fixed offsets that will be fixed | |
| 441 | − * up at runtime. | |
| 442 | − */ | |
| 443 | − | |
| 444 | − long long offset; | |
| 445 | − | |
| 446 | − offset = table[i]->addr - relative_base; | |
| 447 | − if (offset < 0 || offset > UINT_MAX) { | |
| 448 | − fprintf(stderr, "kallsyms failure: " | |
| 449 | − "relative symbol value %#llx out of range\n", | |
| 450 | − table[i]->addr); | |
| 451 | − exit(EXIT_FAILURE); | |
| 428 | + if (pc_relative) { | |
| 429 | + long long offset = table[i]->addr - _text; | |
| 430 | + | |
| 431 | + if (offset < INT_MIN || offset > INT_MAX) { | |
| 432 | + fprintf(stderr, "kallsyms failure: " | |
| 433 | + "relative symbol value %#llx out of range\n", | |
| 434 | + table[i]->addr); | |
| 435 | + exit(EXIT_FAILURE); | |
| 436 | + } | |
| 437 | + printf("\t.long\t_text - . + (%d)\t/* %s */\n", | |
| 438 | + (int)offset, table[i]->sym); | |
| 439 | + } else { | |
| 440 | + printf("\t.long\t%#x\t/* %s */\n", | |
| 441 | + (unsigned int)table[i]->addr, table[i]->sym); | |
| 452 | 442 | } |
| 453 | − printf("\t.long\t%#x\t/* %s */\n", (int)offset, table[i]->sym); | |
| 454 | 443 | } |
| 455 | 444 | printf("\n"); |
| 456 | 445 | |
| 457 | − output_label("kallsyms_relative_base"); | |
| 458 | − /* Provide proper symbols relocatability by their '_text' relativeness. */ | |
| 459 | − if (_text <= relative_base) | |
| 460 | − printf("\tPTR\t_text + %#llx\n", relative_base - _text); | |
| 461 | − else | |
| 462 | − printf("\tPTR\t_text - %#llx\n", _text - relative_base); | |
| 463 | − printf("\n"); | |
| 464 | − | |
| 465 | 446 | sort_symbols_by_name(); |
| 466 | 447 | output_label("kallsyms_seqs_of_names"); |
| 467 | 448 | for (i = 0; i < table_cnt; i++) |
| @@ -701,22 +682,12 @@ static void sort_symbols(void) · 233 unmodified lines | ||
| 701 | 682 | qsort(table, table_cnt, sizeof(table[0]), compare_symbols); |
| 702 | 683 | } |
| 703 | 684 | |
| 704 | −/* find the minimum non-absolute symbol address */ | |
| 705 | −static void record_relative_base(void) | |
| 706 | −{ | |
| 707 | − /* | |
| 708 | − * The table is sorted by address. | |
| 709 | − * Take the first symbol value. | |
| 710 | − */ | |
| 711 | − if (table_cnt) | |
| 712 | − relative_base = table[0]->addr; | |
| 713 | −} | |
| 714 | − | |
| 715 | 685 | int main(int argc, char **argv) |
| 716 | 686 | { |
| 717 | 687 | while (1) { |
| 718 | 688 | static const struct option long_options[] = { |
| 719 | 689 | {"all-symbols", no_argument, &all_symbols, 1}, |
| 690 | + {"pc-relative", no_argument, &pc_relative, 1}, | |
| 720 | 691 | {}, |
| 721 | 692 | }; |
| 722 | 693 | |
| @@ -734,7 +705,6 @@ int main(int argc, char **argv) · 11 unmodified lines | ||
| 734 | 705 | read_map(argv[optind]); |
| 735 | 706 | shrink_table(); |
| 736 | 707 | sort_symbols(); |
| 737 | − record_relative_base(); | |
| 738 | 708 | optimize_token_table(); |
| 739 | 709 | write_src(); |
| 740 | 710 | |
| @@ -201,7 +201,7 @@ $(addprefix $(obj)/, mconf.o $(lxdialog)): | $(obj)/mconf-cflags · 200 unmodified lines | ||
| 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,7 +219,7 @@ targets += qconf-moc.cc · 11 unmodified lines | ||
| 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) |
| @@ -5,7 +5,6 @@ · 4 unmodified lines | ||
| 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 | |
| @@ -951,12 +950,24 @@ static void fixup_rootmenu(struct menu *menu) · 939 unmodified lines | ||
| 951 | 950 | } |
| 952 | 951 | |
| 953 | 952 | /* Main Window Initialization */ |
| 954 | −static void replace_button_icon(GtkWidget *widget, const char * const xpm[]) | |
| 953 | +static void replace_button_icon(GtkWidget *widget, const char *filename) | |
| 955 | 954 | { |
| 956 | 955 | GdkPixbuf *pixbuf; |
| 957 | 956 | GtkWidget *image; |
| 957 | + GError *err = NULL; | |
| 958 | + | |
| 959 | + char *env = getenv(SRCTREE); | |
| 960 | + gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/", filename, NULL); | |
| 961 | + | |
| 962 | + pixbuf = gdk_pixbuf_new_from_file(path, &err); | |
| 963 | + g_free(path); | |
| 964 | + | |
| 965 | + if (err) { | |
| 966 | + g_warning("Failed to load icon %s: %s", filename, err->message); | |
| 967 | + g_error_free(err); | |
| 968 | + return; | |
| 969 | + } | |
| 958 | 970 | |
| 959 | − pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm); | |
| 960 | 971 | image = gtk_image_new_from_pixbuf(pixbuf); |
| 961 | 972 | g_object_unref(pixbuf); |
| 962 | 973 | |
| @@ -1078,17 +1089,17 @@ static void init_main_window(const gchar *glade_file) · 115 unmodified lines | ||
| 1078 | 1089 | single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4")); |
| 1079 | 1090 | g_signal_connect(single_btn, "clicked", |
| 1080 | 1091 | G_CALLBACK(on_single_clicked), NULL); |
| 1081 | − replace_button_icon(single_btn, xpm_single_view); | |
| 1092 | + replace_button_icon(single_btn, "single_view.xpm"); | |
| 1082 | 1093 | |
| 1083 | 1094 | split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5")); |
| 1084 | 1095 | g_signal_connect(split_btn, "clicked", |
| 1085 | 1096 | G_CALLBACK(on_split_clicked), NULL); |
| 1086 | − replace_button_icon(split_btn, xpm_split_view); | |
| 1097 | + replace_button_icon(split_btn, "split_view.xpm"); | |
| 1087 | 1098 | |
| 1088 | 1099 | full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6")); |
| 1089 | 1100 | g_signal_connect(full_btn, "clicked", |
| 1090 | 1101 | G_CALLBACK(on_full_clicked), NULL); |
| 1091 | − replace_button_icon(full_btn, xpm_tree_view); | |
| 1102 | + replace_button_icon(full_btn, "tree_view.xpm"); | |
| 1092 | 1103 | |
| 1093 | 1104 | widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7")); |
| 1094 | 1105 | g_signal_connect(widget, "clicked", |
| @@ -1269,7 +1280,17 @@ static void init_right_tree(void) · 174 unmodified lines | ||
| 1269 | 1280 | g_signal_connect(G_OBJECT(renderer), "edited", |
| 1270 | 1281 | G_CALLBACK(renderer_edited), tree2_w); |
| 1271 | 1282 | |
| 1272 | − pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu); | |
| 1283 | + char *env = getenv(SRCTREE); | |
| 1284 | + gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/menu.xpm", NULL); | |
| 1285 | + GError *err = NULL; | |
| 1286 | + | |
| 1287 | + pix_menu = gdk_pixbuf_new_from_file(path, &err); | |
| 1288 | + g_free(path); | |
| 1289 | + | |
| 1290 | + if (err) { | |
| 1291 | + g_warning("Failed to load menu icon: %s", err->message); | |
| 1292 | + g_error_free(err); | |
| 1293 | + } | |
| 1273 | 1294 | |
| 1274 | 1295 | for (i = 0; i < COL_VALUE; i++) { |
| 1275 | 1296 | column = gtk_tree_view_get_column(view, i); |
| @@ -0,0 +1,29 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,18 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,18 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,31 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,18 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,18 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,31 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,28 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,28 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,18 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,18 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,18 @@ | ||
| 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 | +}; | |
| @@ -0,0 +1,28 @@ | ||
| 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 | +}; | |
| @@ -1,328 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 2 | −/* | |
| 3 | − * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | |
| 4 | − */ | |
| 5 | − | |
| 6 | −#include "images.h" | |
| 7 | − | |
| 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 | −" "}; | |
| @@ -1,33 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | −/* | |
| 3 | − * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> | |
| 4 | − */ | |
| 5 | − | |
| 6 | −#ifndef IMAGES_H | |
| 7 | −#define IMAGES_H | |
| 8 | − | |
| 9 | −#ifdef __cplusplus | |
| 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 */ | |
| @@ -82,7 +82,7 @@ void menu_warn(const struct menu *menu, const char *fmt, ...); · 81 unmodified lines | ||
| 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); |
| @@ -127,8 +127,18 @@ static struct expr *rewrite_m(struct expr *e) · 126 unmodified lines | ||
| 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 | |
| @@ -16,8 +16,8 @@ · 15 unmodified lines | ||
| 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() { |
| @@ -43,6 +43,10 @@ STRICT=false · 19 unmodified lines | ||
| 43 | 43 | CONFIG_PREFIX=${CONFIG_-CONFIG_} |
| 44 | 44 | WARNOVERRIDE=echo |
| 45 | 45 | |
| 46 | +if [ -z "$AWK" ]; then | |
| 47 | + AWK=awk | |
| 48 | +fi | |
| 49 | + | |
| 46 | 50 | while true; do |
| 47 | 51 | case $1 in |
| 48 | 52 | "-n") |
| @@ -117,11 +121,8 @@ if [ ! -r "$INITFILE" ]; then · 68 unmodified lines | ||
| 117 | 121 | fi |
| 118 | 122 | |
| 119 | 123 | MERGE_LIST=$* |
| 120 | −SED_CONFIG_EXP1="s/^\(${CONFIG_PREFIX}[a-zA-Z0-9_]*\)=.*/\1/p" | |
| 121 | −SED_CONFIG_EXP2="s/^# \(${CONFIG_PREFIX}[a-zA-Z0-9_]*\) is not set$/\1/p" | |
| 122 | 124 | |
| 123 | 125 | TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) |
| 124 | −MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX) | |
| 125 | 126 | |
| 126 | 127 | echo "Using $INITFILE as base" |
| 127 | 128 | |
| @@ -129,6 +130,8 @@ trap clean_up EXIT · 1 unmodified line | ||
| 129 | 130 | |
| 130 | 131 | cat $INITFILE > $TMP_FILE |
| 131 | 132 | |
| 133 | +PROCESSED_FILES="" | |
| 134 | + | |
| 132 | 135 | # Merge files, printing warnings on overridden values |
| 133 | 136 | for ORIG_MERGE_FILE in $MERGE_LIST ; do |
| 134 | 137 | echo "Merging $ORIG_MERGE_FILE" |
| @@ -136,42 +139,138 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do · 1 unmodified line | ||
| 136 | 139 | echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2 |
| 137 | 140 | exit 1 |
| 138 | 141 | fi |
| 139 | − cat $ORIG_MERGE_FILE > $MERGE_FILE | |
| 140 | − CFG_LIST=$(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $MERGE_FILE) | |
| 141 | − | |
| 142 | − for CFG in $CFG_LIST ; do | |
| 143 | − grep -q -w $CFG $TMP_FILE || continue | |
| 144 | − PREV_VAL=$(grep -w $CFG $TMP_FILE) | |
| 145 | − NEW_VAL=$(grep -w $CFG $MERGE_FILE) | |
| 146 | − BUILTIN_FLAG=false | |
| 147 | − if [ "$BUILTIN" = "true" ] && [ "${NEW_VAL#CONFIG_*=}" = "m" ] && [ "${PREV_VAL#CONFIG_*=}" = "y" ]; then | |
| 148 | − ${WARNOVERRIDE} Previous value: $PREV_VAL | |
| 149 | − ${WARNOVERRIDE} New value: $NEW_VAL | |
| 150 | − ${WARNOVERRIDE} -y passed, will not demote y to m | |
| 151 | − ${WARNOVERRIDE} | |
| 152 | − BUILTIN_FLAG=true | |
| 153 | − elif [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then | |
| 154 | − ${WARNOVERRIDE} Value of $CFG is redefined by fragment $ORIG_MERGE_FILE: | |
| 155 | − ${WARNOVERRIDE} Previous value: $PREV_VAL | |
| 156 | − ${WARNOVERRIDE} New value: $NEW_VAL | |
| 157 | − ${WARNOVERRIDE} | |
| 158 | − if [ "$STRICT" = "true" ]; then | |
| 159 | − STRICT_MODE_VIOLATED=true | |
| 160 | − fi | |
| 161 | − elif [ "$WARNREDUN" = "true" ]; then | |
| 162 | − ${WARNOVERRIDE} Value of $CFG is redundant by fragment $ORIG_MERGE_FILE: | |
| 163 | − fi | |
| 164 | − if [ "$BUILTIN_FLAG" = "false" ]; then | |
| 165 | − sed -i "/$CFG[ =]/d" $TMP_FILE | |
| 166 | − else | |
| 167 | − sed -i "/$CFG[ =]/d" $MERGE_FILE | |
| 168 | − fi | |
| 169 | − done | |
| 170 | − # In case the previous file lacks a new line at the end | |
| 171 | − echo >> $TMP_FILE | |
| 172 | − cat $MERGE_FILE >> $TMP_FILE | |
| 173 | −done | |
| 174 | 142 | |
| 143 | + # Check for duplicate input files | |
| 144 | + case " $PROCESSED_FILES " in | |
| 145 | + *" $ORIG_MERGE_FILE "*) | |
| 146 | + ${WARNOVERRIDE} "WARNING: Input file provided multiple times: $ORIG_MERGE_FILE" | |
| 147 | + ;; | |
| 148 | + esac | |
| 149 | + | |
| 150 | + # Use awk for single-pass processing instead of per-symbol grep/sed | |
| 151 | + if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ | |
| 152 | + -v warnoverride="$WARNOVERRIDE" \ | |
| 153 | + -v strict="$STRICT" \ | |
| 154 | + -v builtin="$BUILTIN" \ | |
| 155 | + -v warnredun="$WARNREDUN" ' | |
| 156 | + BEGIN { | |
| 157 | + strict_violated = 0 | |
| 158 | + cfg_regex = "^" prefix "[a-zA-Z0-9_]+" | |
| 159 | + notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$" | |
| 160 | + } | |
| 161 | + | |
| 162 | + # Extract config name from a line, returns "" if not a config line | |
| 163 | + function get_cfg(line) { | |
| 164 | + if (match(line, cfg_regex)) { | |
| 165 | + return substr(line, RSTART, RLENGTH) | |
| 166 | + } else if (match(line, notset_regex)) { | |
| 167 | + # Extract CONFIG_FOO from "# CONFIG_FOO is not set" | |
| 168 | + sub(/^# /, "", line) | |
| 169 | + sub(/ is not set$/, "", line) | |
| 170 | + return line | |
| 171 | + } | |
| 172 | + return "" | |
| 173 | + } | |
| 174 | + | |
| 175 | + function warn_builtin(cfg, prev, new) { | |
| 176 | + if (warnoverride == "true") return | |
| 177 | + print cfg ": -y passed, will not demote y to m" | |
| 178 | + print "Previous value: " prev | |
| 179 | + print "New value: " new | |
| 180 | + print "" | |
| 181 | + } | |
| 182 | + | |
| 183 | + function warn_redefined(cfg, prev, new) { | |
| 184 | + if (warnoverride == "true") return | |
| 185 | + print "Value of " cfg " is redefined by fragment " mergefile ":" | |
| 186 | + print "Previous value: " prev | |
| 187 | + print "New value: " new | |
| 188 | + print "" | |
| 189 | + } | |
| 190 | + | |
| 191 | + function warn_redundant(cfg) { | |
| 192 | + if (warnredun != "true" || warnoverride == "true") return | |
| 193 | + print "Value of " cfg " is redundant by fragment " mergefile ":" | |
| 194 | + } | |
| 195 | + | |
| 196 | + # First pass: read merge file, store all lines and index | |
| 197 | + FILENAME == ARGV[1] { | |
| 198 | + mergefile = FILENAME | |
| 199 | + merge_lines[FNR] = $0 | |
| 200 | + merge_total = FNR | |
| 201 | + cfg = get_cfg($0) | |
| 202 | + if (cfg != "") { | |
| 203 | + merge_cfg[cfg] = $0 | |
| 204 | + merge_cfg_line[cfg] = FNR | |
| 205 | + } | |
| 206 | + next | |
| 207 | + } | |
| 208 | + | |
| 209 | + # Second pass: process base file (TMP_FILE) | |
| 210 | + FILENAME == ARGV[2] { | |
| 211 | + cfg = get_cfg($0) | |
| 212 | + | |
| 213 | + # Not a config or not in merge file - keep it | |
| 214 | + if (cfg == "" || !(cfg in merge_cfg)) { | |
| 215 | + print $0 >> ARGV[3] | |
| 216 | + next | |
| 217 | + } | |
| 218 | + | |
| 219 | + prev_val = $0 | |
| 220 | + new_val = merge_cfg[cfg] | |
| 221 | + | |
| 222 | + # BUILTIN: do not demote y to m | |
| 223 | + if (builtin == "true" && new_val ~ /=m$/ && prev_val ~ /=y$/) { | |
| 224 | + warn_builtin(cfg, prev_val, new_val) | |
| 225 | + print $0 >> ARGV[3] | |
| 226 | + skip_merge[merge_cfg_line[cfg]] = 1 | |
| 227 | + next | |
| 228 | + } | |
| 229 | + | |
| 230 | + # Values equal - redundant | |
| 231 | + if (prev_val == new_val) { | |
| 232 | + warn_redundant(cfg) | |
| 233 | + next | |
| 234 | + } | |
| 235 | + | |
| 236 | + # "=n" is the same as "is not set" | |
| 237 | + if (prev_val ~ /=n$/ && new_val ~ / is not set$/) { | |
| 238 | + print $0 >> ARGV[3] | |
| 239 | + next | |
| 240 | + } | |
| 241 | + | |
| 242 | + # Values differ - redefined | |
| 243 | + warn_redefined(cfg, prev_val, new_val) | |
| 244 | + if (strict == "true") { | |
| 245 | + strict_violated = 1 | |
| 246 | + } | |
| 247 | + } | |
| 248 | + | |
| 249 | + # output file, skip all lines | |
| 250 | + FILENAME == ARGV[3] { | |
| 251 | + nextfile | |
| 252 | + } | |
| 253 | + | |
| 254 | + END { | |
| 255 | + # Newline in case base file lacks trailing newline | |
| 256 | + print "" >> ARGV[3] | |
| 257 | + # Append merge file, skipping lines marked for builtin preservation | |
| 258 | + for (i = 1; i <= merge_total; i++) { | |
| 259 | + if (!(i in skip_merge)) { | |
| 260 | + print merge_lines[i] >> ARGV[3] | |
| 261 | + } | |
| 262 | + } | |
| 263 | + if (strict_violated) { | |
| 264 | + exit 1 | |
| 265 | + } | |
| 266 | + }' \ | |
| 267 | + "$ORIG_MERGE_FILE" "$TMP_FILE" "$TMP_FILE.new"; then | |
| 268 | + # awk exited non-zero, strict mode was violated | |
| 269 | + STRICT_MODE_VIOLATED=true | |
| 270 | + fi | |
| 271 | + mv "$TMP_FILE.new" "$TMP_FILE" | |
| 272 | + PROCESSED_FILES="$PROCESSED_FILES $ORIG_MERGE_FILE" | |
| 273 | +done | |
| 175 | 274 | if [ "$STRICT_MODE_VIOLATED" = "true" ]; then |
| 176 | 275 | echo "The fragment redefined a value and strict mode had been passed." |
| 177 | 276 | exit 1 |
| @@ -198,16 +297,91 @@ fi · 20 unmodified lines | ||
| 198 | 297 | # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set |
| 199 | 298 | make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET |
| 200 | 299 | |
| 300 | +# Check all specified config values took effect (might have missed-dependency issues) | |
| 301 | +if ! "$AWK" -v prefix="$CONFIG_PREFIX" \ | |
| 302 | + -v warnoverride="$WARNOVERRIDE" \ | |
| 303 | + -v strict="$STRICT" \ | |
| 304 | + -v warnredun="$WARNREDUN" ' | |
| 305 | +BEGIN { | |
| 306 | + strict_violated = 0 | |
| 307 | + cfg_regex = "^" prefix "[a-zA-Z0-9_]+" | |
| 308 | + notset_regex = "^# " prefix "[a-zA-Z0-9_]+ is not set$" | |
| 309 | +} | |
| 201 | 310 | |
| 202 | −# Check all specified config values took (might have missed-dependency issues) | |
| 203 | −for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do | |
| 311 | +# Extract config name from a line, returns "" if not a config line | |
| 312 | +function get_cfg(line) { | |
| 313 | + if (match(line, cfg_regex)) { | |
| 314 | + return substr(line, RSTART, RLENGTH) | |
| 315 | + } else if (match(line, notset_regex)) { | |
| 316 | + # Extract CONFIG_FOO from "# CONFIG_FOO is not set" | |
| 317 | + sub(/^# /, "", line) | |
| 318 | + sub(/ is not set$/, "", line) | |
| 319 | + return line | |
| 320 | + } | |
| 321 | + return "" | |
| 322 | +} | |
| 204 | 323 | |
| 205 | − REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) | |
| 206 | − ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true) | |
| 207 | − if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then | |
| 208 | − echo "Value requested for $CFG not in final .config" | |
| 209 | − echo "Requested value: $REQUESTED_VAL" | |
| 210 | − echo "Actual value: $ACTUAL_VAL" | |
| 211 | − echo "" | |
| 212 | − fi | |
| 213 | −done | |
| 324 | +function warn_mismatch(cfg, merged, final) { | |
| 325 | + if (warnredun == "true") return | |
| 326 | + if (final == "" && !(merged ~ / is not set$/ || merged ~ /=n$/)) { | |
| 327 | + print "WARNING: Value requested for " cfg " not in final .config" | |
| 328 | + print "Requested value: " merged | |
| 329 | + print "Actual value: " final | |
| 330 | + } else if (final == "" && merged ~ / is not set$/) { | |
| 331 | + # not set, pass | |
| 332 | + } else if (merged == "" && final != "") { | |
| 333 | + print "WARNING: " cfg " not in merged config but added in final .config:" | |
| 334 | + print "Requested value: " merged | |
| 335 | + print "Actual value: " final | |
| 336 | + } else { | |
| 337 | + print "WARNING: " cfg " differs:" | |
| 338 | + print "Requested value: " merged | |
| 339 | + print "Actual value: " final | |
| 340 | + } | |
| 341 | +} | |
| 342 | + | |
| 343 | +# First pass: read effective config file, store all lines | |
| 344 | +FILENAME == ARGV[1] { | |
| 345 | + cfg = get_cfg($0) | |
| 346 | + if (cfg != "") { | |
| 347 | + config_cfg[cfg] = $0 | |
| 348 | + } | |
| 349 | + next | |
| 350 | +} | |
| 351 | + | |
| 352 | +# Second pass: process merged config and compare against effective config | |
| 353 | +{ | |
| 354 | + cfg = get_cfg($0) | |
| 355 | + if (cfg == "") next | |
| 356 | + | |
| 357 | + # strip trailing comment | |
| 358 | + sub(/[[:space:]]+#.*/, "", $0) | |
| 359 | + merged_val = $0 | |
| 360 | + final_val = config_cfg[cfg] | |
| 361 | + | |
| 362 | + if (merged_val == final_val) next | |
| 363 | + | |
| 364 | + if (merged_val ~ /=n$/ && final_val ~ / is not set$/) next | |
| 365 | + if (merged_val ~ /=n$/ && final_val == "") next | |
| 366 | + | |
| 367 | + warn_mismatch(cfg, merged_val, final_val) | |
| 368 | + | |
| 369 | + if (strict == "true") { | |
| 370 | + strict_violated = 1 | |
| 371 | + } | |
| 372 | +} | |
| 373 | + | |
| 374 | +END { | |
| 375 | + if (strict_violated) { | |
| 376 | + exit 1 | |
| 377 | + } | |
| 378 | +}' \ | |
| 379 | +"$KCONFIG_CONFIG" "$TMP_FILE"; then | |
| 380 | + # awk exited non-zero, strict mode was violated | |
| 381 | + STRICT_MODE_VIOLATED=true | |
| 382 | +fi | |
| 383 | + | |
| 384 | +if [ "$STRICT" == "true" ] && [ "$STRICT_MODE_VIOLATED" == "true" ]; then | |
| 385 | + echo "Requested and effective config differ" | |
| 386 | + exit 1 | |
| 387 | +fi | |
| @@ -323,7 +323,7 @@ if_entry: T_IF expr T_EOL · 322 unmodified lines | ||
| 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,9 +422,9 @@ help: help_start T_HELPTEXT · 92 unmodified lines | ||
| 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 | |
| @@ -26,8 +26,6 @@ · 25 unmodified lines | ||
| 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; |
| @@ -1283,13 +1281,14 @@ ConfigMainWindow::ConfigMainWindow(void) · 1249 unmodified lines | ||
| 1283 | 1281 | move(x.toInt(), y.toInt()); |
| 1284 | 1282 | |
| 1285 | 1283 | // set up icons |
| 1286 | − ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes)); | |
| 1287 | − ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod)); | |
| 1288 | − ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no)); | |
| 1289 | − ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes)); | |
| 1290 | − ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no)); | |
| 1291 | − ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu)); | |
| 1292 | − ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); | |
| 1284 | + QString iconsDir = QString(getenv(SRCTREE) ? getenv(SRCTREE) : QDir::currentPath()) + "/scripts/kconfig/icons/"; | |
| 1285 | + ConfigItem::symbolYesIcon = QIcon(QPixmap(iconsDir + "symbol_yes.xpm")); | |
| 1286 | + ConfigItem::symbolModIcon = QIcon(QPixmap(iconsDir + "symbol_mod.xpm")); | |
| 1287 | + ConfigItem::symbolNoIcon = QIcon(QPixmap(iconsDir + "symbol_no.xpm")); | |
| 1288 | + ConfigItem::choiceYesIcon = QIcon(QPixmap(iconsDir + "choice_yes.xpm")); | |
| 1289 | + ConfigItem::choiceNoIcon = QIcon(QPixmap(iconsDir + "choice_no.xpm")); | |
| 1290 | + ConfigItem::menuIcon = QIcon(QPixmap(iconsDir + "menu.xpm")); | |
| 1291 | + ConfigItem::menubackIcon = QIcon(QPixmap(iconsDir + "menuback.xpm")); | |
| 1293 | 1292 | |
| 1294 | 1293 | QWidget *widget = new QWidget(this); |
| 1295 | 1294 | setCentralWidget(widget); |
| @@ -1312,7 +1311,7 @@ ConfigMainWindow::ConfigMainWindow(void) · 16 unmodified lines | ||
| 1312 | 1311 | |
| 1313 | 1312 | configList->setFocus(); |
| 1314 | 1313 | |
| 1315 | − backAction = new QAction(QPixmap(xpm_back), "Back", this); | |
| 1314 | + backAction = new QAction(QPixmap(iconsDir + "back.xpm"), "Back", this); | |
| 1316 | 1315 | backAction->setShortcut(QKeySequence::Back); |
| 1317 | 1316 | connect(backAction, &QAction::triggered, |
| 1318 | 1317 | this, &ConfigMainWindow::goBack); |
| @@ -1322,12 +1321,12 @@ ConfigMainWindow::ConfigMainWindow(void) · 3 unmodified lines | ||
| 1322 | 1321 | connect(quitAction, &QAction::triggered, |
| 1323 | 1322 | this, &ConfigMainWindow::close); |
| 1324 | 1323 | |
| 1325 | − QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this); | |
| 1324 | + QAction *loadAction = new QAction(QPixmap(iconsDir + "load.xpm"), "&Open", this); | |
| 1326 | 1325 | loadAction->setShortcut(QKeySequence::Open); |
| 1327 | 1326 | connect(loadAction, &QAction::triggered, |
| 1328 | 1327 | this, &ConfigMainWindow::loadConfig); |
| 1329 | 1328 | |
| 1330 | − saveAction = new QAction(QPixmap(xpm_save), "&Save", this); | |
| 1329 | + saveAction = new QAction(QPixmap(iconsDir + "save.xpm"), "&Save", this); | |
| 1331 | 1330 | saveAction->setShortcut(QKeySequence::Save); |
| 1332 | 1331 | connect(saveAction, &QAction::triggered, |
| 1333 | 1332 | this, &ConfigMainWindow::saveConfig); |
| @@ -1344,15 +1343,15 @@ ConfigMainWindow::ConfigMainWindow(void) · 10 unmodified lines | ||
| 1344 | 1343 | searchAction->setShortcut(QKeySequence::Find); |
| 1345 | 1344 | connect(searchAction, &QAction::triggered, |
| 1346 | 1345 | this, &ConfigMainWindow::searchConfig); |
| 1347 | − singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); | |
| 1346 | + singleViewAction = new QAction(QPixmap(iconsDir + "single_view.xpm"), "Single View", this); | |
| 1348 | 1347 | singleViewAction->setCheckable(true); |
| 1349 | 1348 | connect(singleViewAction, &QAction::triggered, |
| 1350 | 1349 | this, &ConfigMainWindow::showSingleView); |
| 1351 | − splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); | |
| 1350 | + splitViewAction = new QAction(QPixmap(iconsDir + "split_view.xpm"), "Split View", this); | |
| 1352 | 1351 | splitViewAction->setCheckable(true); |
| 1353 | 1352 | connect(splitViewAction, &QAction::triggered, |
| 1354 | 1353 | this, &ConfigMainWindow::showSplitView); |
| 1355 | − fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); | |
| 1354 | + fullViewAction = new QAction(QPixmap(iconsDir + "tree_view.xpm"), "Full View", this); | |
| 1356 | 1355 | fullViewAction->setCheckable(true); |
| 1357 | 1356 | connect(fullViewAction, &QAction::triggered, |
| 1358 | 1357 | this, &ConfigMainWindow::showFullView); |
| @@ -415,7 +415,7 @@ foreach my $module (keys(%modules)) { · 414 unmodified lines | ||
| 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 | |
| @@ -0,0 +1,32 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +# Test Kconfig file for conditional dependencies. | |
| 3 | + | |
| 4 | +# Enable module support for tristate testing | |
| 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 | |
| @@ -0,0 +1,14 @@ | ||
| 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') | |
| @@ -0,0 +1,11 @@ | ||
| 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 | |
| @@ -0,0 +1,9 @@ | ||
| 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 | |
| @@ -0,0 +1,11 @@ | ||
| 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 | |
| @@ -0,0 +1,6 @@ | ||
| 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 | |
| @@ -0,0 +1,7 @@ | ||
| 1 | +# If FOO is not selected, then TEST_BASIC should fail the conditional | |
| 2 | +# dependency since BAR is set. | |
| 3 | +# TEST_COMPLEX will fail dependency as it depends on both FOO and BAR | |
| 4 | +# if either of those is selected. | |
| 5 | +CONFIG_FOO=n | |
| 6 | +CONFIG_BAR=y | |
| 7 | +CONFIG_BAZ=y | |
| @@ -0,0 +1,6 @@ | ||
| 1 | +# If FOO is not selected, but BAR is also not selected, then TEST_BASIC | |
| 2 | +# should pass since the dependency on FOO is conditional on BAR. | |
| 3 | +# TEST_COMPLEX should be also set since neither FOO nor BAR are selected | |
| 4 | +# so it has no dependencies. | |
| 5 | +CONFIG_FOO=n | |
| 6 | +CONFIG_BAR=n | |
| @@ -143,6 +143,10 @@ kallsyms() · 142 unmodified lines | ||
| 143 | 143 | kallsymopt="${kallsymopt} --all-symbols" |
| 144 | 144 | fi |
| 145 | 145 | |
| 146 | + if is_enabled CONFIG_64BIT || is_enabled CONFIG_RELOCATABLE; then | |
| 147 | + kallsymopt="${kallsymopt} --pc-relative" | |
| 148 | + fi | |
| 149 | + | |
| 146 | 150 | info KSYMS "${2}.S" |
| 147 | 151 | scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S" |
| 148 | 152 | |
| @@ -10,10 +10,14 @@ · 9 unmodified lines | ||
| 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 |
| @@ -29,12 +33,11 @@ looks at the .cmd files produced by the kernel build. · 9 unmodified lines | ||
| 29 | 33 | |
| 30 | 34 | The resulting FIT can be booted by bootloaders which support FIT, such |
| 31 | 35 | as U-Boot, Linuxboot, Tianocore, etc. |
| 32 | − | |
| 33 | −Note that this tool does not yet support adding a ramdisk / initrd. | |
| 34 | 36 | """ |
| 35 | 37 | |
| 36 | 38 | import argparse |
| 37 | 39 | import collections |
| 40 | +import multiprocessing | |
| 38 | 41 | import os |
| 39 | 42 | import subprocess |
| 40 | 43 | import sys |
| @@ -48,11 +51,12 @@ import libfdt · 7 unmodified lines | ||
| 48 | 51 | CompTool = collections.namedtuple('CompTool', 'ext,tools') |
| 49 | 52 | |
| 50 | 53 | COMP_TOOLS = { |
| 51 | − 'bzip2': CompTool('.bz2', 'bzip2'), | |
| 54 | + 'bzip2': CompTool('.bz2', 'pbzip2,bzip2'), | |
| 52 | 55 | 'gzip': CompTool('.gz', 'pigz,gzip'), |
| 53 | 56 | 'lz4': CompTool('.lz4', 'lz4'), |
| 54 | − 'lzma': CompTool('.lzma', 'lzma'), | |
| 57 | + 'lzma': CompTool('.lzma', 'plzip,lzma'), | |
| 55 | 58 | 'lzo': CompTool('.lzo', 'lzop'), |
| 59 | + 'xz': CompTool('.xz', 'xz'), | |
| 56 | 60 | 'zstd': CompTool('.zstd', 'zstd'), |
| 57 | 61 | } |
| 58 | 62 | |
| @@ -81,6 +85,8 @@ def parse_args(): · 22 unmodified lines | ||
| 81 | 85 | help='Specifies the operating system') |
| 82 | 86 | parser.add_argument('-k', '--kernel', type=str, required=True, |
| 83 | 87 | help='Specifies the (uncompressed) kernel input file (.itk)') |
| 88 | + parser.add_argument('-r', '--ramdisk', type=str, | |
| 89 | + help='Specifies the ramdisk/initrd input file') | |
| 84 | 90 | parser.add_argument('-v', '--verbose', action='store_true', |
| 85 | 91 | help='Enable verbose output') |
| 86 | 92 | parser.add_argument('dtbs', type=str, nargs='*', |
| @@ -98,7 +104,7 @@ def setup_fit(fsw, name): · 11 unmodified lines | ||
| 98 | 104 | fsw (libfdt.FdtSw): Object to use for writing |
| 99 | 105 | name (str): Name of kernel image |
| 100 | 106 | """ |
| 101 | − fsw.INC_SIZE = 65536 | |
| 107 | + fsw.INC_SIZE = 16 << 20 | |
| 102 | 108 | fsw.finish_reservemap() |
| 103 | 109 | fsw.begin_node('') |
| 104 | 110 | fsw.property_string('description', f'{name} with devicetree set') |
| @@ -133,7 +139,28 @@ def write_kernel(fsw, data, args): · 28 unmodified lines | ||
| 133 | 139 | fsw.property_u32('entry', 0) |
| 134 | 140 | |
| 135 | 141 | |
| 136 | −def finish_fit(fsw, entries): | |
| 142 | +def write_ramdisk(fsw, data, args): | |
| 143 | + """Write out the ramdisk image | |
| 144 | + | |
| 145 | + Writes a ramdisk node along with the required properties | |
| 146 | + | |
| 147 | + Args: | |
| 148 | + fsw (libfdt.FdtSw): Object to use for writing | |
| 149 | + data (bytes): Data to write (possibly compressed) | |
| 150 | + args (Namespace): Contains necessary strings: | |
| 151 | + arch: FIT architecture, e.g. 'arm64' | |
| 152 | + fit_os: Operating Systems, e.g. 'linux' | |
| 153 | + """ | |
| 154 | + with fsw.add_node('ramdisk'): | |
| 155 | + fsw.property_string('description', 'Ramdisk') | |
| 156 | + fsw.property_string('type', 'ramdisk') | |
| 157 | + fsw.property_string('arch', args.arch) | |
| 158 | + fsw.property_string('compression', 'none') | |
| 159 | + fsw.property_string('os', args.os) | |
| 160 | + fsw.property('data', data) | |
| 161 | + | |
| 162 | + | |
| 163 | +def finish_fit(fsw, entries, has_ramdisk=False): | |
| 137 | 164 | """Finish the FIT ready for use |
| 138 | 165 | |
| 139 | 166 | Writes the /configurations node and subnodes |
| @@ -143,6 +170,7 @@ def finish_fit(fsw, entries): · 3 unmodified lines | ||
| 143 | 170 | entries (list of tuple): List of configurations: |
| 144 | 171 | str: Description of model |
| 145 | 172 | str: Compatible stringlist |
| 173 | + has_ramdisk (bool): True if a ramdisk is included in the FIT | |
| 146 | 174 | """ |
| 147 | 175 | fsw.end_node() |
| 148 | 176 | seq = 0 |
| @@ -154,6 +182,8 @@ def finish_fit(fsw, entries): · 5 unmodified lines | ||
| 154 | 182 | fsw.property_string('description', model) |
| 155 | 183 | fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) |
| 156 | 184 | fsw.property_string('kernel', 'kernel') |
| 185 | + if has_ramdisk: | |
| 186 | + fsw.property_string('ramdisk', 'ramdisk') | |
| 157 | 187 | fsw.end_node() |
| 158 | 188 | |
| 159 | 189 | |
| @@ -179,7 +209,12 @@ def compress_data(inf, compress): · 19 unmodified lines | ||
| 179 | 209 | done = False |
| 180 | 210 | for tool in comp.tools.split(','): |
| 181 | 211 | try: |
| 182 | − subprocess.call([tool, '-c'], stdin=inf, stdout=outf) | |
| 212 | + # Add parallel flags for tools that support them | |
| 213 | + cmd = [tool] | |
| 214 | + if tool in ('zstd', 'xz'): | |
| 215 | + cmd.extend(['-T0']) # Use all available cores | |
| 216 | + cmd.append('-c') | |
| 217 | + subprocess.call(cmd, stdin=inf, stdout=outf) | |
| 183 | 218 | done = True |
| 184 | 219 | break |
| 185 | 220 | except FileNotFoundError: |
| @@ -191,15 +226,31 @@ def compress_data(inf, compress): · 5 unmodified lines | ||
| 191 | 226 | return comp_data |
| 192 | 227 | |
| 193 | 228 | |
| 194 | −def output_dtb(fsw, seq, fname, arch, compress): | |
| 229 | +def compress_dtb(fname, compress): | |
| 230 | + """Compress a single DTB file | |
| 231 | + | |
| 232 | + Args: | |
| 233 | + fname (str): Filename containing the DTB | |
| 234 | + compress (str): Compression algorithm, e.g. 'gzip' | |
| 235 | + | |
| 236 | + Returns: | |
| 237 | + tuple: (str: fname, bytes: compressed_data) | |
| 238 | + """ | |
| 239 | + with open(fname, 'rb') as inf: | |
| 240 | + compressed = compress_data(inf, compress) | |
| 241 | + return fname, compressed | |
| 242 | + | |
| 243 | + | |
| 244 | +def output_dtb(fsw, seq, fname, arch, compress, data=None): | |
| 195 | 245 | """Write out a single devicetree to the FIT |
| 196 | 246 | |
| 197 | 247 | Args: |
| 198 | 248 | fsw (libfdt.FdtSw): Object to use for writing |
| 199 | 249 | seq (int): Sequence number (1 for first) |
| 200 | 250 | fname (str): Filename containing the DTB |
| 201 | − arch: FIT architecture, e.g. 'arm64' | |
| 251 | + arch (str): FIT architecture, e.g. 'arm64' | |
| 202 | 252 | compress (str): Compressed algorithm, e.g. 'gzip' |
| 253 | + data (bytes): Pre-compressed data (optional) | |
| 203 | 254 | """ |
| 204 | 255 | with fsw.add_node(f'fdt-{seq}'): |
| 205 | 256 | fsw.property_string('description', os.path.basename(fname)) |
| @@ -207,9 +258,10 @@ def output_dtb(fsw, seq, fname, arch, compress): · 1 unmodified line | ||
| 207 | 258 | fsw.property_string('arch', arch) |
| 208 | 259 | fsw.property_string('compression', compress) |
| 209 | 260 | |
| 210 | − with open(fname, 'rb') as inf: | |
| 211 | − compressed = compress_data(inf, compress) | |
| 212 | − fsw.property('data', compressed) | |
| 261 | + if data is None: | |
| 262 | + with open(fname, 'rb') as inf: | |
| 263 | + data = compress_data(inf, compress) | |
| 264 | + fsw.property('data', data) | |
| 213 | 265 | |
| 214 | 266 | |
| 215 | 267 | def process_dtb(fname, args): |
| @@ -249,30 +301,27 @@ def process_dtb(fname, args): · 33 unmodified lines | ||
| 249 | 301 | |
| 250 | 302 | return (model, compat, files) |
| 251 | 303 | |
| 252 | −def build_fit(args): | |
| 253 | − """Build the FIT from the provided files and arguments | |
| 304 | + | |
| 305 | +def _process_dtbs(args, fsw, entries, fdts): | |
| 306 | + """Process all DTB files and add them to the FIT | |
| 254 | 307 | |
| 255 | 308 | Args: |
| 256 | − args (Namespace): Program arguments | |
| 309 | + args: Program arguments | |
| 310 | + fsw: FIT writer object | |
| 311 | + entries: List to append entries to | |
| 312 | + fdts: Dictionary of processed DTBs | |
| 257 | 313 | |
| 258 | 314 | Returns: |
| 259 | 315 | tuple: |
| 260 | − bytes: FIT data | |
| 261 | − int: Number of configurations generated | |
| 262 | − size: Total uncompressed size of data | |
| 316 | + Number of files processed | |
| 317 | + Total size of files processed | |
| 263 | 318 | """ |
| 264 | 319 | seq = 0 |
| 265 | 320 | size = 0 |
| 266 | − fsw = libfdt.FdtSw() | |
| 267 | − setup_fit(fsw, args.name) | |
| 268 | − entries = [] | |
| 269 | − fdts = {} | |
| 270 | 321 | |
| 271 | − # Handle the kernel | |
| 272 | − with open(args.kernel, 'rb') as inf: | |
| 273 | − comp_data = compress_data(inf, args.compress) | |
| 274 | − size += os.path.getsize(args.kernel) | |
| 275 | − write_kernel(fsw, comp_data, args) | |
| 322 | + # First figure out the unique DTB files that need compression | |
| 323 | + todo = [] | |
| 324 | + file_info = [] # List of (fname, model, compat, files) tuples | |
| 276 | 325 | |
| 277 | 326 | for fname in args.dtbs: |
| 278 | 327 | # Ignore non-DTB (*.dtb) files |
| @@ -282,24 +331,84 @@ def build_fit(args): · 3 unmodified lines | ||
| 282 | 331 | try: |
| 283 | 332 | (model, compat, files) = process_dtb(fname, args) |
| 284 | 333 | except Exception as e: |
| 285 | − sys.stderr.write(f"Error processing {fname}:\n") | |
| 334 | + sys.stderr.write(f'Error processing {fname}:\n') | |
| 286 | 335 | raise e |
| 287 | 336 | |
| 337 | + file_info.append((fname, model, compat, files)) | |
| 338 | + for fn in files: | |
| 339 | + if fn not in fdts and fn not in todo: | |
| 340 | + todo.append(fn) | |
| 341 | + | |
| 342 | + # Compress all DTBs in parallel | |
| 343 | + cache = {} | |
| 344 | + if todo and args.compress != 'none': | |
| 345 | + if args.verbose: | |
| 346 | + print(f'Compressing {len(todo)} DTBs...') | |
| 347 | + | |
| 348 | + with multiprocessing.Pool() as pool: | |
| 349 | + compress_args = [(fn, args.compress) for fn in todo] | |
| 350 | + # unpacks each tuple, calls compress_dtb(fn, compress) in parallel | |
| 351 | + results = pool.starmap(compress_dtb, compress_args) | |
| 352 | + | |
| 353 | + cache = dict(results) | |
| 354 | + | |
| 355 | + # Now write all DTBs to the FIT using pre-compressed data | |
| 356 | + for fname, model, compat, files in file_info: | |
| 288 | 357 | for fn in files: |
| 289 | 358 | if fn not in fdts: |
| 290 | 359 | seq += 1 |
| 291 | 360 | size += os.path.getsize(fn) |
| 292 | − output_dtb(fsw, seq, fn, args.arch, args.compress) | |
| 361 | + output_dtb(fsw, seq, fn, args.arch, args.compress, | |
| 362 | + cache.get(fn)) | |
| 293 | 363 | fdts[fn] = seq |
| 294 | 364 | |
| 295 | 365 | files_seq = [fdts[fn] for fn in files] |
| 296 | − | |
| 297 | 366 | entries.append([model, compat, files_seq]) |
| 298 | 367 | |
| 299 | − finish_fit(fsw, entries) | |
| 368 | + return seq, size | |
| 369 | + | |
| 370 | + | |
| 371 | +def build_fit(args): | |
| 372 | + """Build the FIT from the provided files and arguments | |
| 373 | + | |
| 374 | + Args: | |
| 375 | + args (Namespace): Program arguments | |
| 376 | + | |
| 377 | + Returns: | |
| 378 | + tuple: | |
| 379 | + bytes: FIT data | |
| 380 | + int: Number of configurations generated | |
| 381 | + size: Total uncompressed size of data | |
| 382 | + """ | |
| 383 | + size = 0 | |
| 384 | + fsw = libfdt.FdtSw() | |
| 385 | + setup_fit(fsw, args.name) | |
| 386 | + entries = [] | |
| 387 | + fdts = {} | |
| 388 | + | |
| 389 | + # Handle the kernel | |
| 390 | + with open(args.kernel, 'rb') as inf: | |
| 391 | + comp_data = compress_data(inf, args.compress) | |
| 392 | + size += os.path.getsize(args.kernel) | |
| 393 | + write_kernel(fsw, comp_data, args) | |
| 394 | + | |
| 395 | + # Handle the ramdisk if provided. Compression is not supported as it is | |
| 396 | + # already compressed. | |
| 397 | + if args.ramdisk: | |
| 398 | + with open(args.ramdisk, 'rb') as inf: | |
| 399 | + data = inf.read() | |
| 400 | + size += len(data) | |
| 401 | + write_ramdisk(fsw, data, args) | |
| 402 | + | |
| 403 | + count, fdt_size = _process_dtbs(args, fsw, entries, fdts) | |
| 404 | + size += fdt_size | |
| 405 | + | |
| 406 | + finish_fit(fsw, entries, bool(args.ramdisk)) | |
| 300 | 407 | |
| 301 | 408 | # Include the kernel itself in the returned file count |
| 302 | − return fsw.as_fdt().as_bytearray(), seq + 1, size | |
| 409 | + fdt = fsw.as_fdt() | |
| 410 | + fdt.pack() | |
| 411 | + return fdt.as_bytearray(), count + 1 + bool(args.ramdisk), size | |
| 303 | 412 | |
| 304 | 413 | |
| 305 | 414 | def run_make_fit(): |
| @@ -602,6 +602,10 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) · 601 unmodified lines | ||
| 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) |
| @@ -958,7 +962,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, · 350 unmodified lines | ||
| 958 | 962 | /* symbols in data sections that may refer to any init/exit sections */ |
| 959 | 963 | if (match(fromsec, PATTERNS(DATA_SECTIONS)) && |
| 960 | 964 | match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && |
| 961 | − match(fromsym, PATTERNS("*_ops", "*_probe", "*_console"))) | |
| 965 | + match(fromsym, PATTERNS("*_ops", "*_console"))) | |
| 962 | 966 | return 0; |
| 963 | 967 | |
| 964 | 968 | /* Check for pattern 3 */ |
| @@ -27,7 +27,6 @@ static bool is_ignored_symbol(const char *name, char type) · 26 unmodified lines | ||
| 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", |
| @@ -65,16 +65,101 @@ no-header-test += asm/uctx.h · 64 unmodified lines | ||
| 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)) |
| 72 | 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))) | |
| 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 | |
| @@ -40,7 +40,6 @@ foreach my $file (@files) { · 39 unmodified lines | ||
| 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 | } |
| @@ -77,13 +76,6 @@ sub check_declarations · 30 unmodified lines | ||
| 77 | 76 | } |
| 78 | 77 | } |
| 79 | 78 | |
| 80 | −sub check_config | |
| 81 | −{ | |
| 82 | − if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9_]+)[^a-zA-Z0-9_]/) { | |
| 83 | − printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n"; | |
| 84 | − } | |
| 85 | −} | |
| 86 | − | |
| 87 | 79 | my $linux_asm_types; |
| 88 | 80 | sub check_asm_types |
| 89 | 81 | { |