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 | gpio-sloppy-logic-analyzer | 38 | gpio-sloppy-logic-analyzer |
| 39 | autofdo | 39 | autofdo |
| 40 | propeller | 40 | propeller |
| 41 | container | ||
| 41 | 42 | ||
| 42 | 43 | ||
| 43 | .. only:: subproject and html | 44 | .. only:: subproject and html |
| @@ -14,23 +14,46 @@ selected, **gendwarfksyms** is used instead to calculate symbol versions · 13 unmodified lines | |||
| 14 | from the DWARF debugging information, which contains the necessary | 14 | from the DWARF debugging information, which contains the necessary |
| 15 | details about the final module ABI. | 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 | Usage | 40 | Usage |
| 18 | ----- | 41 | ----- |
| 19 | 42 | ||
| 20 | gendwarfksyms accepts a list of object files on the command line, and a | 43 | gendwarfksyms accepts a list of object files on the command line, and a |
| 21 | list of symbol names (one per line) in standard input:: | 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: | 48 | Options: |
| 26 | -d, --debug Print debugging information | 49 | -d, --debug Print debugging information |
| 27 | --dump-dies Dump DWARF DIE contents | 50 | --dump-dies Dump DWARF DIE contents |
| 28 | --dump-die-map Print debugging information about die_map changes | 51 | --dump-die-map Print debugging information about die_map changes |
| 29 | --dump-types Dump type strings | 52 | --dump-types Dump type strings |
| 30 | --dump-versions Dump expanded type strings used for symbol versions | 53 | --dump-versions Dump expanded type strings used for symbol versions |
| 31 | -s, --stable Support kABI stability features | 54 | -s, --stable Support kABI stability features |
| 32 | -T, --symtypes file Write a symtypes file | 55 | -T, --symtypes file Write a symtypes file |
| 33 | -h, --help Print this message | 56 | -h, --help Print this message |
| 34 | 57 | ||
| 35 | 58 | ||
| 36 | Type information availability | 59 | Type information availability |
| @@ -46,9 +69,9 @@ TU where symbols are actually exported, gendwarfksyms adds a pointer · 9 unmodified lines | |||
| 46 | to exported symbols in the `EXPORT_SYMBOL()` macro using the following | 69 | to exported symbols in the `EXPORT_SYMBOL()` macro using the following |
| 47 | macro:: | 70 | macro:: |
| 48 | 71 | ||
| 49 | #define __GENDWARFKSYMS_EXPORT(sym) \ | 72 | #define __GENDWARFKSYMS_EXPORT(sym) \ |
| 50 | static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ | 73 | static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ |
| 51 | __section(".discard.gendwarfksyms") = &sym; | 74 | __section(".discard.gendwarfksyms") = &sym; |
| 52 | 75 | ||
| 53 | 76 | ||
| 54 | When a symbol pointer is found in DWARF, gendwarfksyms can use its | 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 | one-letter prefix followed by "#" and the name of the type. Four | 94 | one-letter prefix followed by "#" and the name of the type. Four |
| 72 | reference types are supported:: | 95 | reference types are supported:: |
| 73 | 96 | ||
| 74 | e#<type> = enum | 97 | e#<type> = enum |
| 75 | s#<type> = struct | 98 | s#<type> = struct |
| 76 | t#<type> = typedef | 99 | t#<type> = typedef |
| 77 | u#<type> = union | 100 | u#<type> = union |
| 78 | 101 | ||
| 79 | Type names with spaces in them are wrapped in single quotes, e.g.:: | 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 | The rest of the line contains a type string. Unlike with genksyms that | 106 | The rest of the line contains a type string. Unlike with genksyms that |
| 84 | produces C-style type strings, gendwarfksyms uses the same simple parsed | 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 | The following helper macros, for example, can be used to specify rules | 151 | The following helper macros, for example, can be used to specify rules |
| 129 | in the source code:: | 152 | in the source code:: |
| 130 | 153 | ||
| 131 | #define ___KABI_RULE(hint, target, value) \ | 154 | #define ___KABI_RULE(hint, target, value) \ |
| 132 | static const char __PASTE(__gendwarfksyms_rule_, \ | 155 | static const char __PASTE(__gendwarfksyms_rule_, \ |
| 133 | __COUNTER__)[] __used __aligned(1) \ | 156 | __COUNTER__)[] __used __aligned(1) \ |
| 134 | __section(".discard.gendwarfksyms.kabi_rules") = \ | 157 | __section(".discard.gendwarfksyms.kabi_rules") = \ |
| 135 | "1\0" #hint "\0" target "\0" value | 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 | Using the `__KABI_RULE` macro, this rule can be defined as:: | 274 | Using the `__KABI_RULE` macro, this rule can be defined as:: |
| 252 | 275 | ||
| 253 | #define KABI_BYTE_SIZE(fqn, value) \ | 276 | #define KABI_BYTE_SIZE(fqn, value) \ |
| 254 | __KABI_RULE(byte_size, fqn, value) | 277 | __KABI_RULE(byte_size, fqn, value) |
| 255 | 278 | ||
| 256 | Example usage:: | 279 | Example usage:: |
| 257 | 280 | ||
| 258 | struct s { | 281 | struct s { |
| 259 | /* Unchanged original members */ | 282 | /* Unchanged original members */ |
| 260 | unsigned long a; | 283 | unsigned long a; |
| 261 | void *p; | 284 | void *p; |
| 262 | 285 | ||
| 263 | /* Appended new members */ | 286 | /* Appended new members */ |
| 264 | KABI_IGNORE(0, unsigned long n); | 287 | KABI_IGNORE(0, unsigned long n); |
| 265 | }; | 288 | }; |
| 266 | 289 | ||
| 267 | KABI_BYTE_SIZE(s, 16); | 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 | not known at the time the space is reserved, for convenience, names that | 353 | not known at the time the space is reserved, for convenience, names that |
| 331 | start with `__kabi_` are left out when calculating symbol versions:: | 354 | start with `__kabi_` are left out when calculating symbol versions:: |
| 332 | 355 | ||
| 333 | struct s { | 356 | struct s { |
| 334 | long a; | 357 | long a; |
| 335 | long __kabi_reserved_0; /* reserved for future use */ | 358 | long __kabi_reserved_0; /* reserved for future use */ |
| 336 | }; | 359 | }; |
| 337 | 360 | ||
| 338 | The reserved space can be taken into use by wrapping the member in a | 361 | The reserved space can be taken into use by wrapping the member in a |
| 339 | union, which includes the original type and the replacement member:: | 362 | union, which includes the original type and the replacement member:: |
| 340 | 363 | ||
| 341 | struct s { | 364 | struct s { |
| 342 | long a; | 365 | long a; |
| 343 | union { | 366 | union { |
| 344 | long __kabi_reserved_0; /* original type */ | 367 | long __kabi_reserved_0; /* original type */ |
| 345 | struct b b; /* replaced field */ | 368 | struct b b; /* replaced field */ |
| 346 | }; | 369 | }; |
| 347 | }; | 370 | }; |
| 348 | 371 | ||
| 349 | If the `__kabi_` naming scheme was used when reserving space, the name | 372 | If the `__kabi_` naming scheme was used when reserving space, the name |
| 350 | of the first member of the union must start with `__kabi_reserved`. This | 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 | timeframe isn't always possible, in which case one might have to resort | 392 | timeframe isn't always possible, in which case one might have to resort |
| 370 | to placing new members into existing alignment holes:: | 393 | to placing new members into existing alignment holes:: |
| 371 | 394 | ||
| 372 | struct s { | 395 | struct s { |
| 373 | int a; | 396 | int a; |
| 374 | /* a 4-byte alignment hole */ | 397 | /* a 4-byte alignment hole */ |
| 375 | unsigned long b; | 398 | unsigned long b; |
| 376 | }; | 399 | }; |
| 377 | 400 | ||
| 378 | 401 | ||
| 379 | While this won't change the size of the data structure, one needs to | 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 | member to a union where one of the fields has a name starting with | 405 | member to a union where one of the fields has a name starting with |
| 383 | `__kabi_ignored`:: | 406 | `__kabi_ignored`:: |
| 384 | 407 | ||
| 385 | struct s { | 408 | struct s { |
| 386 | int a; | 409 | int a; |
| 387 | union { | 410 | union { |
| 388 | char __kabi_ignored_0; | 411 | char __kabi_ignored_0; |
| 389 | int n; | 412 | int n; |
| 390 | }; | 413 | }; |
| 391 | unsigned long b; | 414 | unsigned long b; |
| 392 | }; | 415 | }; |
| 393 | 416 | ||
| 394 | With **--stable**, both versions produce the same symbol version. The | 417 | With **--stable**, both versions produce the same symbol version. The |
| 395 | examples include a `KABI_IGNORE` macro to simplify the code. | 418 | examples include a `KABI_IGNORE` macro to simplify the code. |
| @@ -118,7 +118,7 @@ applicable everywhere (see syntax). · 117 unmodified lines | |||
| 118 | This is a shorthand notation for a type definition plus a value. | 118 | This is a shorthand notation for a type definition plus a value. |
| 119 | Optionally dependencies for this default value can be added with "if". | 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 | This defines a dependency for this menu entry. If multiple | 123 | This defines a dependency for this menu entry. If multiple |
| 124 | dependencies are defined, they are connected with '&&'. Dependencies | 124 | dependencies are defined, they are connected with '&&'. Dependencies |
| @@ -134,6 +134,16 @@ applicable everywhere (see syntax). · 9 unmodified lines | |||
| 134 | bool "foo" | 134 | bool "foo" |
| 135 | default y | 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 | - reverse dependencies: "select" <symbol> ["if" <expr>] | 147 | - reverse dependencies: "select" <symbol> ["if" <expr>] |
| 138 | 148 | ||
| 139 | While normal dependencies reduce the upper limit of a symbol (see | 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 | or build cleanly with that module disabled, but cause a link failure | 612 | or build cleanly with that module disabled, but cause a link failure |
| 603 | when trying to use that loadable module from a built-in driver. | 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 | 615 | The recommended way to express this optional dependency in Kconfig logic |
| 606 | uses the slightly counterintuitive:: | 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 | config FOO | 624 | config FOO |
| 609 | tristate "Support for foo hardware" | 625 | tristate "Support for foo hardware" |
| @@ -6386,6 +6386,12 @@ S: Supported · 6385 unmodified lines | |||
| 6386 | F: drivers/video/console/ | 6386 | F: drivers/video/console/ |
| 6387 | F: include/linux/console* | 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 | CONTEXT TRACKING | 6395 | CONTEXT TRACKING |
| 6390 | M: Frederic Weisbecker <frederic@kernel.org> | 6396 | M: Frederic Weisbecker <frederic@kernel.org> |
| 6391 | M: "Paul E. McKenney" <paulmck@kernel.org> | 6397 | M: "Paul E. McKenney" <paulmck@kernel.org> |
| @@ -13683,8 +13689,10 @@ F: scripts/Makefile* · 7291 unmodified lines | |||
| 13683 | F: scripts/bash-completion/ | 13689 | F: scripts/bash-completion/ |
| 13684 | F: scripts/basic/ | 13690 | F: scripts/basic/ |
| 13685 | F: scripts/clang-tools/ | 13691 | F: scripts/clang-tools/ |
| 13692 | F: scripts/container | ||
| 13686 | F: scripts/dummy-tools/ | 13693 | F: scripts/dummy-tools/ |
| 13687 | F: scripts/include/ | 13694 | F: scripts/include/ |
| 13695 | F: scripts/install.sh | ||
| 13688 | F: scripts/mk* | 13696 | F: scripts/mk* |
| 13689 | F: scripts/mod/ | 13697 | F: scripts/mod/ |
| 13690 | F: scripts/package/ | 13698 | F: scripts/package/ |
| @@ -295,7 +295,8 @@ no-dot-config-targets := $(clean-targets) \ · 294 unmodified lines | |||
| 295 | cscope gtags TAGS tags help% %docs check% coccicheck \ | 295 | cscope gtags TAGS tags help% %docs check% coccicheck \ |
| 296 | $(version_h) headers headers_% archheaders archscripts \ | 296 | $(version_h) headers headers_% archheaders archscripts \ |
| 297 | %asm-generic kernelversion %src-pkg dt_binding_check \ | 297 | %asm-generic kernelversion %src-pkg dt_binding_check \ |
| 298 | outputmakefile rustavailable rustfmt rustfmtcheck | 298 | outputmakefile rustavailable rustfmt rustfmtcheck \ |
| 299 | run-command | ||
| 299 | no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \ | 300 | no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \ |
| 300 | image_name | 301 | image_name |
| 301 | single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/ | 302 | single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/ |
| @@ -447,6 +448,8 @@ ifneq ($(filter %/,$(LLVM)),) · 145 unmodified lines | |||
| 447 | LLVM_PREFIX := $(LLVM) | 448 | LLVM_PREFIX := $(LLVM) |
| 448 | else ifneq ($(filter -%,$(LLVM)),) | 449 | else ifneq ($(filter -%,$(LLVM)),) |
| 449 | LLVM_SUFFIX := $(LLVM) | 450 | LLVM_SUFFIX := $(LLVM) |
| 451 | else ifneq ($(LLVM),1) | ||
| 452 | $(error Invalid value for LLVM, see Documentation/kbuild/llvm.rst) | ||
| 450 | endif | 453 | endif |
| 451 | 454 | ||
| 452 | HOSTCC = $(LLVM_PREFIX)clang$(LLVM_SUFFIX) | 455 | HOSTCC = $(LLVM_PREFIX)clang$(LLVM_SUFFIX) |
| @@ -1102,7 +1105,7 @@ KBUILD_CFLAGS += -fno-builtin-wcslen · 649 unmodified lines | |||
| 1102 | 1105 | ||
| 1103 | # change __FILE__ to the relative path to the source directory | 1106 | # change __FILE__ to the relative path to the source directory |
| 1104 | ifdef building_out_of_srctree | 1107 | ifdef building_out_of_srctree |
| 1105 | KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) | 1108 | KBUILD_CPPFLAGS += -fmacro-prefix-map=$(srcroot)/= |
| 1106 | endif | 1109 | endif |
| 1107 | 1110 | ||
| 1108 | # include additional Makefiles when needed | 1111 | # include additional Makefiles when needed |
| @@ -1417,6 +1420,10 @@ ifdef CONFIG_HEADERS_INSTALL · 308 unmodified lines | |||
| 1417 | prepare: headers | 1420 | prepare: headers |
| 1418 | endif | 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 | PHONY += scripts_unifdef | 1427 | PHONY += scripts_unifdef |
| 1421 | scripts_unifdef: scripts_basic | 1428 | scripts_unifdef: scripts_basic |
| 1422 | $(Q)$(MAKE) $(build)=scripts scripts/unifdef | 1429 | $(Q)$(MAKE) $(build)=scripts scripts/unifdef |
| @@ -1670,6 +1677,8 @@ distclean: mrproper · 247 unmodified lines | |||
| 1670 | # Packaging of the kernel to various formats | 1677 | # Packaging of the kernel to various formats |
| 1671 | # --------------------------------------------------------------------------- | 1678 | # --------------------------------------------------------------------------- |
| 1672 | 1679 | ||
| 1680 | modules-cpio-pkg: usr_gen_init_cpio | ||
| 1681 | |||
| 1673 | %src-pkg: FORCE | 1682 | %src-pkg: FORCE |
| 1674 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@ | 1683 | $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.package $@ |
| 1675 | %pkg: include/config/kernel.release FORCE | 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 | REL_TYPE(R_MIPS_HIGHEST), | 79 | REL_TYPE(R_MIPS_HIGHEST), |
| 80 | REL_TYPE(R_MIPS_PC21_S2), | 80 | REL_TYPE(R_MIPS_PC21_S2), |
| 81 | REL_TYPE(R_MIPS_PC26_S2), | 81 | REL_TYPE(R_MIPS_PC26_S2), |
| 82 | REL_TYPE(R_MIPS_PC32), | ||
| 82 | #undef REL_TYPE | 83 | #undef REL_TYPE |
| 83 | }; | 84 | }; |
| 84 | const char *name = "unknown type rel type name"; | 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 | case R_MIPS_PC16: | 523 | case R_MIPS_PC16: |
| 523 | case R_MIPS_PC21_S2: | 524 | case R_MIPS_PC21_S2: |
| 524 | case R_MIPS_PC26_S2: | 525 | case R_MIPS_PC26_S2: |
| 526 | case R_MIPS_PC32: | ||
| 525 | /* | 527 | /* |
| 526 | * NONE can be ignored and PC relative relocations don't | 528 | * NONE can be ignored and PC relative relocations don't |
| 527 | * need to be adjusted. | 529 | * need to be adjusted. |
| @@ -29,6 +29,13 @@ void die(char *fmt, ...); · 28 unmodified lines | |||
| 29 | #define R_MIPS_PC26_S2 61 | 29 | #define R_MIPS_PC26_S2 61 |
| 30 | #endif | 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 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | 39 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
| 33 | 40 | ||
| 34 | enum symtype { | 41 | enum symtype { |
| @@ -123,6 +123,8 @@ · 122 unmodified lines | |||
| 123 | #define R_MIPS_LOVENDOR 100 | 123 | #define R_MIPS_LOVENDOR 100 |
| 124 | #define R_MIPS_HIVENDOR 127 | 124 | #define R_MIPS_HIVENDOR 127 |
| 125 | 125 | ||
| 126 | #define R_MIPS_PC32 248 | ||
| 127 | |||
| 126 | #define SHN_MIPS_ACCOMON 0xff00 /* Allocated common symbols */ | 128 | #define SHN_MIPS_ACCOMON 0xff00 /* Allocated common symbols */ |
| 127 | #define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ | 129 | #define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ |
| 128 | #define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ | 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 | # The following turn off the warnings enabled by -Wextra | 22 | # The following turn off the warnings enabled by -Wextra |
| 23 | ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) | 23 | ifeq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) |
| 24 | subdir-ccflags-y += -Wno-missing-field-initializers | 24 | subdir-ccflags-y += -Wno-missing-field-initializers |
| 25 | subdir-ccflags-y += -Wno-type-limits | ||
| 26 | subdir-ccflags-y += -Wno-shift-negative-value | 25 | subdir-ccflags-y += -Wno-shift-negative-value |
| 27 | endif | 26 | endif |
| 28 | ifeq ($(findstring 3, $(KBUILD_EXTRA_WARN)),) | 27 | ifeq ($(findstring 3, $(KBUILD_EXTRA_WARN)),) |
| @@ -17,7 +17,6 @@ subdir-ccflags-y += $(condflags) · 16 unmodified lines | |||
| 17 | # The following turn off the warnings enabled by -Wextra | 17 | # The following turn off the warnings enabled by -Wextra |
| 18 | subdir-ccflags-y += -Wno-missing-field-initializers | 18 | subdir-ccflags-y += -Wno-missing-field-initializers |
| 19 | subdir-ccflags-y += -Wno-sign-compare | 19 | subdir-ccflags-y += -Wno-sign-compare |
| 20 | subdir-ccflags-y += -Wno-type-limits | ||
| 21 | subdir-ccflags-y += -Wno-shift-negative-value | 20 | subdir-ccflags-y += -Wno-shift-negative-value |
| 22 | 21 | ||
| 23 | obj-$(CONFIG_BTRFS_FS) := btrfs.o | 22 | obj-$(CONFIG_BTRFS_FS) := btrfs.o |
| @@ -36,12 +36,6 @@ · 35 unmodified lines | |||
| 36 | #define __type_min(T) ((T)((T)-type_max(T)-(T)1)) | 36 | #define __type_min(T) ((T)((T)-type_max(T)-(T)1)) |
| 37 | #define type_min(t) __type_min(typeof(t)) | 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 | * Allows for effectively applying __must_check to a macro so we can have | 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 | typeof(d) _d = d; \ | 195 | typeof(d) _d = d; \ |
| 202 | unsigned long long _a_full = _a; \ | 196 | unsigned long long _a_full = _a; \ |
| 203 | unsigned int _to_shift = \ | 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 | *_d = (_a_full << _to_shift); \ | 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 | (*_d >> _to_shift) != _a); \ | 201 | (*_d >> _to_shift) != _a); \ |
| 208 | })) | 202 | })) |
| 209 | 203 | ||
| @@ -362,7 +362,7 @@ struct hv_kvp_exchg_msg_value { · 361 unmodified lines | |||
| 362 | __u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; | 362 | __u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; |
| 363 | __u32 value_u32; | 363 | __u32 value_u32; |
| 364 | __u64 value_u64; | 364 | __u64 value_u64; |
| 365 | }; | 365 | } __attribute__((packed)); |
| 366 | } __attribute__((packed)); | 366 | } __attribute__((packed)); |
| 367 | 367 | ||
| 368 | struct hv_kvp_msg_enumerate { | 368 | struct hv_kvp_msg_enumerate { |
| @@ -236,7 +236,7 @@ struct vmmdev_hgcm_function_parameter32 { · 235 unmodified lines | |||
| 236 | /** Relative to the request header. */ | 236 | /** Relative to the request header. */ |
| 237 | __u32 offset; | 237 | __u32 offset; |
| 238 | } page_list; | 238 | } page_list; |
| 239 | } u; | 239 | } __packed u; |
| 240 | } __packed; | 240 | } __packed; |
| 241 | VMMDEV_ASSERT_SIZE(vmmdev_hgcm_function_parameter32, 4 + 8); | 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 | union { | 251 | union { |
| 252 | __u64 phys_addr; | 252 | __u64 phys_addr; |
| 253 | __u64 linear_addr; | 253 | __u64 linear_addr; |
| 254 | } u; | 254 | } __packed u; |
| 255 | } __packed pointer; | 255 | } __packed pointer; |
| 256 | struct { | 256 | struct { |
| 257 | /** Size of the buffer described by the page list. */ | 257 | /** Size of the buffer described by the page list. */ |
| @@ -247,7 +247,7 @@ config WERROR · 246 unmodified lines | |||
| 247 | 247 | ||
| 248 | config UAPI_HEADER_TEST | 248 | config UAPI_HEADER_TEST |
| 249 | bool "Compile test UAPI headers" | 249 | bool "Compile test UAPI headers" |
| 250 | depends on HEADERS_INSTALL && CC_CAN_LINK | 250 | depends on HEADERS_INSTALL |
| 251 | help | 251 | help |
| 252 | Compile test headers exported to user-space to ensure they are | 252 | Compile test headers exported to user-space to ensure they are |
| 253 | self-contained, i.e. compilable as standalone units. | 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 | unsigned long kallsyms_sym_address(int idx) | 152 | unsigned long kallsyms_sym_address(int idx) |
| 153 | { | 153 | { |
| 154 | /* values are unsigned offsets */ | 154 | /* non-relocatable 32-bit kernels just embed the value directly */ |
| 155 | return kallsyms_relative_base + (u32)kallsyms_offsets[idx]; | 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 | static unsigned int get_symbol_seq(int index) | 160 | static unsigned int get_symbol_seq(int index) |
| @@ -8,7 +8,6 @@ extern const int kallsyms_offsets[]; · 7 unmodified lines | |||
| 8 | extern const u8 kallsyms_names[]; | 8 | extern const u8 kallsyms_names[]; |
| 9 | 9 | ||
| 10 | extern const unsigned int kallsyms_num_syms; | 10 | extern const unsigned int kallsyms_num_syms; |
| 11 | extern const unsigned long kallsyms_relative_base; | ||
| 12 | 11 | ||
| 13 | extern const char kallsyms_token_table[]; | 12 | extern const char kallsyms_token_table[]; |
| 14 | extern const u16 kallsyms_token_index[]; | 13 | extern const u16 kallsyms_token_index[]; |
| @@ -242,7 +242,6 @@ static int __init crash_save_vmcoreinfo_init(void) · 241 unmodified lines | |||
| 242 | VMCOREINFO_SYMBOL(kallsyms_token_table); | 242 | VMCOREINFO_SYMBOL(kallsyms_token_table); |
| 243 | VMCOREINFO_SYMBOL(kallsyms_token_index); | 243 | VMCOREINFO_SYMBOL(kallsyms_token_index); |
| 244 | VMCOREINFO_SYMBOL(kallsyms_offsets); | 244 | VMCOREINFO_SYMBOL(kallsyms_offsets); |
| 245 | VMCOREINFO_SYMBOL(kallsyms_relative_base); | ||
| 246 | #endif /* CONFIG_KALLSYMS */ | 245 | #endif /* CONFIG_KALLSYMS */ |
| 247 | 246 | ||
| 248 | arch_crash_save_vmcoreinfo(); | 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 | # $(rustc-option,<flag>) | 74 | # $(rustc-option,<flag>) |
| 75 | # Return y if the Rust compiler supports <flag>, n otherwise | 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 | # If you are testing for unstable features, consider testing RUSTC_VERSION | 76 | # If you are testing for unstable features, consider testing RUSTC_VERSION |
| 79 | # instead, as features may have different completeness while available. | 77 | # instead, as features may have different completeness while available. |
| 80 | rustc-option = $(success,trap "rm -rf .tmp_$$" EXIT; mkdir .tmp_$$; $(RUSTC) $(1) --crate-type=rlib /dev/null --out-dir=.tmp_$$ -o .tmp_$$/tmp.rlib) | 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 | quiet_cmd_fit = FIT $@ | 401 | quiet_cmd_fit = FIT $@ |
| 402 | cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ | 402 | cmd_fit = $(MAKE_FIT) -o $@ --arch $(UIMAGE_ARCH) --os linux \ |
| 403 | --name '$(UIMAGE_NAME)' \ | 403 | --name '$(UIMAGE_NAME)' $(FIT_EXTRA_ARGS) \ |
| 404 | $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ | 404 | $(if $(findstring 1,$(KBUILD_VERBOSE)),-v) \ |
| 405 | $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ | 405 | $(if $(FIT_DECOMPOSE_DTBS),--decompose-dtbs) \ |
| 406 | --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) | 406 | --compress $(FIT_COMPRESSION) -k $< @$(word 2,$^) |
| @@ -201,7 +201,6 @@ quiet_cmd_cpio = CPIO $@ · 200 unmodified lines | |||
| 201 | cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $< | 201 | cmd_cpio = $(CONFIG_SHELL) $(srctree)/usr/gen_initramfs.sh -o $@ $< |
| 202 | 202 | ||
| 203 | modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio | 203 | modules-$(KERNELRELEASE)-$(ARCH).cpio: .tmp_modules_cpio |
| 204 | $(Q)$(MAKE) $(build)=usr usr/gen_init_cpio | ||
| 205 | $(call cmd,cpio) | 204 | $(call cmd,cpio) |
| 206 | 205 | ||
| 207 | PHONY += modules-cpio-pkg | 206 | PHONY += modules-cpio-pkg |
| @@ -16,7 +16,7 @@ KBUILD_CFLAGS += -Werror=return-type · 15 unmodified lines | |||
| 16 | KBUILD_CFLAGS += -Werror=strict-prototypes | 16 | KBUILD_CFLAGS += -Werror=strict-prototypes |
| 17 | KBUILD_CFLAGS += -Wno-format-security | 17 | KBUILD_CFLAGS += -Wno-format-security |
| 18 | KBUILD_CFLAGS += -Wno-trigraphs | 18 | KBUILD_CFLAGS += -Wno-trigraphs |
| 19 | KBUILD_CFLAGS += $(call cc-option, -Wno-frame-address) | 19 | KBUILD_CFLAGS += -Wno-frame-address |
| 20 | KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member) | 20 | KBUILD_CFLAGS += $(call cc-option, -Wno-address-of-packed-member) |
| 21 | KBUILD_CFLAGS += -Wmissing-declarations | 21 | KBUILD_CFLAGS += -Wmissing-declarations |
| 22 | KBUILD_CFLAGS += -Wmissing-prototypes | 22 | KBUILD_CFLAGS += -Wmissing-prototypes |
| @@ -55,6 +55,9 @@ else · 32 unmodified lines | |||
| 55 | KBUILD_CFLAGS += -Wno-main | 55 | KBUILD_CFLAGS += -Wno-main |
| 56 | endif | 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 | # These result in bogus false positives | 61 | # These result in bogus false positives |
| 59 | KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer) | 62 | KBUILD_CFLAGS += $(call cc-option, -Wno-dangling-pointer) |
| 60 | 63 | ||
| @@ -72,7 +75,7 @@ KBUILD_CFLAGS += -Wno-pointer-sign · 11 unmodified lines | |||
| 72 | # In order to make sure new function cast mismatches are not introduced | 75 | # In order to make sure new function cast mismatches are not introduced |
| 73 | # in the kernel (to avoid tripping CFI checking), the kernel should be | 76 | # in the kernel (to avoid tripping CFI checking), the kernel should be |
| 74 | # globally built with -Wcast-function-type. | 77 | # globally built with -Wcast-function-type. |
| 75 | KBUILD_CFLAGS += $(call cc-option, -Wcast-function-type) | 78 | KBUILD_CFLAGS += -Wcast-function-type |
| 76 | 79 | ||
| 77 | # Currently, disable -Wstringop-overflow for GCC 11, globally. | 80 | # Currently, disable -Wstringop-overflow for GCC 11, globally. |
| 78 | KBUILD_CFLAGS-$(CONFIG_CC_NO_STRINGOP_OVERFLOW) += $(call cc-option, -Wno-stringop-overflow) | 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 | KBUILD_CFLAGS += -Werror=date-time | 102 | KBUILD_CFLAGS += -Werror=date-time |
| 100 | 103 | ||
| 101 | # enforce correct pointer usage | 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 | # Require designated initializers for all marked structures | 107 | # Require designated initializers for all marked structures |
| 105 | KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init) | 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 | KBUILD_CFLAGS += -Wmissing-format-attribute | 120 | KBUILD_CFLAGS += -Wmissing-format-attribute |
| 118 | KBUILD_CFLAGS += -Wmissing-include-dirs | 121 | KBUILD_CFLAGS += -Wmissing-include-dirs |
| 119 | KBUILD_CFLAGS += $(call cc-option, -Wunused-const-variable) | 122 | KBUILD_CFLAGS += -Wunused-const-variable |
| 120 | 123 | ||
| 121 | KBUILD_CPPFLAGS += -Wundef | 124 | KBUILD_CPPFLAGS += -Wundef |
| 122 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 | 125 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN1 |
| @@ -125,12 +128,12 @@ else · 2 unmodified lines | |||
| 125 | 128 | ||
| 126 | # Some diagnostics enabled by default are noisy. | 129 | # Some diagnostics enabled by default are noisy. |
| 127 | # Suppress them by using -Wno... except for W=1. | 130 | # Suppress them by using -Wno... except for W=1. |
| 128 | KBUILD_CFLAGS += $(call cc-option, -Wno-unused-but-set-variable) | 131 | KBUILD_CFLAGS += -Wno-unused-but-set-variable |
| 129 | KBUILD_CFLAGS += $(call cc-option, -Wno-unused-const-variable) | 132 | KBUILD_CFLAGS += -Wno-unused-const-variable |
| 130 | KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned) | 133 | KBUILD_CFLAGS += $(call cc-option, -Wno-packed-not-aligned) |
| 131 | KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow) | 134 | KBUILD_CFLAGS += $(call cc-option, -Wno-format-overflow) |
| 132 | ifdef CONFIG_CC_IS_GCC | 135 | ifdef CONFIG_CC_IS_GCC |
| 133 | KBUILD_CFLAGS += $(call cc-option, -Wno-format-truncation) | 136 | KBUILD_CFLAGS += -Wno-format-truncation |
| 134 | endif | 137 | endif |
| 135 | KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation) | 138 | KBUILD_CFLAGS += $(call cc-option, -Wno-stringop-truncation) |
| 136 | 139 | ||
| @@ -145,14 +148,11 @@ KBUILD_CFLAGS += -Wno-format · 8 unmodified lines | |||
| 145 | # problematic. | 148 | # problematic. |
| 146 | KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier | 149 | KBUILD_CFLAGS += -Wformat-extra-args -Wformat-invalid-specifier |
| 147 | KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull | 150 | KBUILD_CFLAGS += -Wformat-zero-length -Wnonnull |
| 148 | # Requires clang-12+. | ||
| 149 | ifeq ($(call clang-min-version, 120000),y) | ||
| 150 | KBUILD_CFLAGS += -Wformat-insufficient-args | 151 | KBUILD_CFLAGS += -Wformat-insufficient-args |
| 151 | endif | 152 | endif |
| 152 | endif | 153 | KBUILD_CFLAGS += -Wno-pointer-to-enum-cast |
| 153 | KBUILD_CFLAGS += $(call cc-option, -Wno-pointer-to-enum-cast) | ||
| 154 | KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare | 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 | KBUILD_CFLAGS += -Wno-enum-compare-conditional | 156 | KBUILD_CFLAGS += -Wno-enum-compare-conditional |
| 157 | endif | 157 | endif |
| 158 | 158 | ||
| @@ -166,7 +166,7 @@ ifneq ($(findstring 2, $(KBUILD_EXTRA_WARN)),) · 7 unmodified lines | |||
| 166 | KBUILD_CFLAGS += -Wdisabled-optimization | 166 | KBUILD_CFLAGS += -Wdisabled-optimization |
| 167 | KBUILD_CFLAGS += -Wshadow | 167 | KBUILD_CFLAGS += -Wshadow |
| 168 | KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) | 168 | KBUILD_CFLAGS += $(call cc-option, -Wlogical-op) |
| 169 | KBUILD_CFLAGS += $(call cc-option, -Wunused-macros) | 169 | KBUILD_CFLAGS += -Wunused-macros |
| 170 | 170 | ||
| 171 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2 | 171 | KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN2 |
| 172 | 172 | ||
| @@ -174,7 +174,6 @@ else · 1 unmodified line | |||
| 174 | 174 | ||
| 175 | # The following turn off the warnings enabled by -Wextra | 175 | # The following turn off the warnings enabled by -Wextra |
| 176 | KBUILD_CFLAGS += -Wno-missing-field-initializers | 176 | KBUILD_CFLAGS += -Wno-missing-field-initializers |
| 177 | KBUILD_CFLAGS += -Wno-type-limits | ||
| 178 | KBUILD_CFLAGS += -Wno-shift-negative-value | 177 | KBUILD_CFLAGS += -Wno-shift-negative-value |
| 179 | 178 | ||
| 180 | ifdef CONFIG_CC_IS_CLANG | 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 | static unsigned long long _text; | 48 | static unsigned long long _text; |
| 49 | static unsigned long long relative_base; | ||
| 50 | static struct addr_range text_ranges[] = { | 49 | static struct addr_range text_ranges[] = { |
| 51 | { "_stext", "_etext" }, | 50 | { "_stext", "_etext" }, |
| 52 | { "_sinittext", "_einittext" }, | 51 | { "_sinittext", "_einittext" }, |
| @@ -57,6 +56,7 @@ static struct addr_range text_ranges[] = { · 4 unmodified lines | |||
| 57 | static struct sym_entry **table; | 56 | static struct sym_entry **table; |
| 58 | static unsigned int table_size, table_cnt; | 57 | static unsigned int table_size, table_cnt; |
| 59 | static int all_symbols; | 58 | static int all_symbols; |
| 59 | static int pc_relative; | ||
| 60 | 60 | ||
| 61 | static int token_profit[0x10000]; | 61 | static int token_profit[0x10000]; |
| 62 | 62 | ||
| @@ -280,7 +280,7 @@ static void read_map(const char *in) · 217 unmodified lines | |||
| 280 | static void output_label(const char *label) | 280 | static void output_label(const char *label) |
| 281 | { | 281 | { |
| 282 | printf(".globl %s\n", label); | 282 | printf(".globl %s\n", label); |
| 283 | printf("\tALGN\n"); | 283 | printf("\t.balign 4\n"); |
| 284 | printf("%s:\n", label); | 284 | printf("%s:\n", label); |
| 285 | } | 285 | } |
| 286 | 286 | ||
| @@ -343,15 +343,6 @@ static void write_src(void) · 56 unmodified lines | |||
| 343 | unsigned int *markers, markers_cnt; | 343 | unsigned int *markers, markers_cnt; |
| 344 | char buf[KSYM_NAME_LEN]; | 344 | char buf[KSYM_NAME_LEN]; |
| 345 | 345 | ||
| 346 | printf("#include <asm/bitsperlong.h>\n"); | ||
| 347 | printf("#if BITS_PER_LONG == 64\n"); | ||
| 348 | printf("#define PTR .quad\n"); | ||
| 349 | printf("#define ALGN .balign 8\n"); | ||
| 350 | printf("#else\n"); | ||
| 351 | printf("#define PTR .long\n"); | ||
| 352 | printf("#define ALGN .balign 4\n"); | ||
| 353 | printf("#endif\n"); | ||
| 354 | |||
| 355 | printf("\t.section .rodata, \"a\"\n"); | 346 | printf("\t.section .rodata, \"a\"\n"); |
| 356 | 347 | ||
| 357 | output_label("kallsyms_num_syms"); | 348 | output_label("kallsyms_num_syms"); |
| @@ -434,34 +425,24 @@ static void write_src(void) · 76 unmodified lines | |||
| 434 | output_label("kallsyms_offsets"); | 425 | output_label("kallsyms_offsets"); |
| 435 | 426 | ||
| 436 | for (i = 0; i < table_cnt; i++) { | 427 | for (i = 0; i < table_cnt; i++) { |
| 437 | /* | 428 | if (pc_relative) { |
| 438 | * Use the offset relative to the lowest value | 429 | long long offset = table[i]->addr - _text; |
| 439 | * encountered of all relative symbols, and emit | 430 | |
| 440 | * non-relocatable fixed offsets that will be fixed | 431 | if (offset < INT_MIN || offset > INT_MAX) { |
| 441 | * up at runtime. | 432 | fprintf(stderr, "kallsyms failure: " |
| 442 | */ | 433 | "relative symbol value %#llx out of range\n", |
| 443 | 434 | table[i]->addr); | |
| 444 | long long offset; | 435 | exit(EXIT_FAILURE); |
| 445 | 436 | } | |
| 446 | offset = table[i]->addr - relative_base; | 437 | printf("\t.long\t_text - . + (%d)\t/* %s */\n", |
| 447 | if (offset < 0 || offset > UINT_MAX) { | 438 | (int)offset, table[i]->sym); |
| 448 | fprintf(stderr, "kallsyms failure: " | 439 | } else { |
| 449 | "relative symbol value %#llx out of range\n", | 440 | printf("\t.long\t%#x\t/* %s */\n", |
| 450 | table[i]->addr); | 441 | (unsigned int)table[i]->addr, table[i]->sym); |
| 451 | exit(EXIT_FAILURE); | ||
| 452 | } | 442 | } |
| 453 | printf("\t.long\t%#x\t/* %s */\n", (int)offset, table[i]->sym); | ||
| 454 | } | 443 | } |
| 455 | printf("\n"); | 444 | printf("\n"); |
| 456 | 445 | ||
| 457 | output_label("kallsyms_relative_base"); | ||
| 458 | /* Provide proper symbols relocatability by their '_text' relativeness. */ | ||
| 459 | if (_text <= relative_base) | ||
| 460 | printf("\tPTR\t_text + %#llx\n", relative_base - _text); | ||
| 461 | else | ||
| 462 | printf("\tPTR\t_text - %#llx\n", _text - relative_base); | ||
| 463 | printf("\n"); | ||
| 464 | |||
| 465 | sort_symbols_by_name(); | 446 | sort_symbols_by_name(); |
| 466 | output_label("kallsyms_seqs_of_names"); | 447 | output_label("kallsyms_seqs_of_names"); |
| 467 | for (i = 0; i < table_cnt; i++) | 448 | for (i = 0; i < table_cnt; i++) |
| @@ -701,22 +682,12 @@ static void sort_symbols(void) · 233 unmodified lines | |||
| 701 | qsort(table, table_cnt, sizeof(table[0]), compare_symbols); | 682 | qsort(table, table_cnt, sizeof(table[0]), compare_symbols); |
| 702 | } | 683 | } |
| 703 | 684 | ||
| 704 | /* find the minimum non-absolute symbol address */ | ||
| 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 | int main(int argc, char **argv) | 685 | int main(int argc, char **argv) |
| 716 | { | 686 | { |
| 717 | while (1) { | 687 | while (1) { |
| 718 | static const struct option long_options[] = { | 688 | static const struct option long_options[] = { |
| 719 | {"all-symbols", no_argument, &all_symbols, 1}, | 689 | {"all-symbols", no_argument, &all_symbols, 1}, |
| 690 | {"pc-relative", no_argument, &pc_relative, 1}, | ||
| 720 | {}, | 691 | {}, |
| 721 | }; | 692 | }; |
| 722 | 693 | ||
| @@ -734,7 +705,6 @@ int main(int argc, char **argv) · 11 unmodified lines | |||
| 734 | read_map(argv[optind]); | 705 | read_map(argv[optind]); |
| 735 | shrink_table(); | 706 | shrink_table(); |
| 736 | sort_symbols(); | 707 | sort_symbols(); |
| 737 | record_relative_base(); | ||
| 738 | optimize_token_table(); | 708 | optimize_token_table(); |
| 739 | write_src(); | 709 | write_src(); |
| 740 | 710 | ||
| @@ -201,7 +201,7 @@ $(addprefix $(obj)/, mconf.o $(lxdialog)): | $(obj)/mconf-cflags · 200 unmodified lines | |||
| 201 | # qconf: Used for the xconfig target based on Qt | 201 | # qconf: Used for the xconfig target based on Qt |
| 202 | hostprogs += qconf | 202 | hostprogs += qconf |
| 203 | qconf-cxxobjs := qconf.o qconf-moc.o | 203 | qconf-cxxobjs := qconf.o qconf-moc.o |
| 204 | qconf-objs := images.o $(common-objs) | 204 | qconf-objs := $(common-objs) |
| 205 | 205 | ||
| 206 | HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs) | 206 | HOSTLDLIBS_qconf = $(call read-file, $(obj)/qconf-libs) |
| 207 | HOSTCXXFLAGS_qconf.o = -std=c++11 -fPIC $(call read-file, $(obj)/qconf-cflags) | 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 | # gconf: Used for the gconfig target based on GTK+ | 220 | # gconf: Used for the gconfig target based on GTK+ |
| 221 | hostprogs += gconf | 221 | hostprogs += gconf |
| 222 | gconf-objs := gconf.o images.o $(common-objs) | 222 | gconf-objs := gconf.o $(common-objs) |
| 223 | 223 | ||
| 224 | HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs) | 224 | HOSTLDLIBS_gconf = $(call read-file, $(obj)/gconf-libs) |
| 225 | HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags) | 225 | HOSTCFLAGS_gconf.o = $(call read-file, $(obj)/gconf-cflags) |
| @@ -5,7 +5,6 @@ · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| 7 | #include "lkc.h" | 7 | #include "lkc.h" |
| 8 | #include "images.h" | ||
| 9 | 8 | ||
| 10 | #include <gtk/gtk.h> | 9 | #include <gtk/gtk.h> |
| 11 | 10 | ||
| @@ -951,12 +950,24 @@ static void fixup_rootmenu(struct menu *menu) · 939 unmodified lines | |||
| 951 | } | 950 | } |
| 952 | 951 | ||
| 953 | /* Main Window Initialization */ | 952 | /* Main Window Initialization */ |
| 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 | GdkPixbuf *pixbuf; | 955 | GdkPixbuf *pixbuf; |
| 957 | GtkWidget *image; | 956 | GtkWidget *image; |
| 957 | GError *err = NULL; | ||
| 958 | |||
| 959 | char *env = getenv(SRCTREE); | ||
| 960 | gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/", filename, NULL); | ||
| 961 | |||
| 962 | pixbuf = gdk_pixbuf_new_from_file(path, &err); | ||
| 963 | g_free(path); | ||
| 964 | |||
| 965 | if (err) { | ||
| 966 | g_warning("Failed to load icon %s: %s", filename, err->message); | ||
| 967 | g_error_free(err); | ||
| 968 | return; | ||
| 969 | } | ||
| 958 | 970 | ||
| 959 | pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)xpm); | ||
| 960 | image = gtk_image_new_from_pixbuf(pixbuf); | 971 | image = gtk_image_new_from_pixbuf(pixbuf); |
| 961 | g_object_unref(pixbuf); | 972 | g_object_unref(pixbuf); |
| 962 | 973 | ||
| @@ -1078,17 +1089,17 @@ static void init_main_window(const gchar *glade_file) · 115 unmodified lines | |||
| 1078 | single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4")); | 1089 | single_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button4")); |
| 1079 | g_signal_connect(single_btn, "clicked", | 1090 | g_signal_connect(single_btn, "clicked", |
| 1080 | G_CALLBACK(on_single_clicked), NULL); | 1091 | G_CALLBACK(on_single_clicked), NULL); |
| 1081 | replace_button_icon(single_btn, xpm_single_view); | 1092 | replace_button_icon(single_btn, "single_view.xpm"); |
| 1082 | 1093 | ||
| 1083 | split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5")); | 1094 | split_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button5")); |
| 1084 | g_signal_connect(split_btn, "clicked", | 1095 | g_signal_connect(split_btn, "clicked", |
| 1085 | G_CALLBACK(on_split_clicked), NULL); | 1096 | G_CALLBACK(on_split_clicked), NULL); |
| 1086 | replace_button_icon(split_btn, xpm_split_view); | 1097 | replace_button_icon(split_btn, "split_view.xpm"); |
| 1087 | 1098 | ||
| 1088 | full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6")); | 1099 | full_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button6")); |
| 1089 | g_signal_connect(full_btn, "clicked", | 1100 | g_signal_connect(full_btn, "clicked", |
| 1090 | G_CALLBACK(on_full_clicked), NULL); | 1101 | G_CALLBACK(on_full_clicked), NULL); |
| 1091 | replace_button_icon(full_btn, xpm_tree_view); | 1102 | replace_button_icon(full_btn, "tree_view.xpm"); |
| 1092 | 1103 | ||
| 1093 | widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7")); | 1104 | widget = GTK_WIDGET(gtk_builder_get_object(builder, "button7")); |
| 1094 | g_signal_connect(widget, "clicked", | 1105 | g_signal_connect(widget, "clicked", |
| @@ -1269,7 +1280,17 @@ static void init_right_tree(void) · 174 unmodified lines | |||
| 1269 | g_signal_connect(G_OBJECT(renderer), "edited", | 1280 | g_signal_connect(G_OBJECT(renderer), "edited", |
| 1270 | G_CALLBACK(renderer_edited), tree2_w); | 1281 | G_CALLBACK(renderer_edited), tree2_w); |
| 1271 | 1282 | ||
| 1272 | pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu); | 1283 | char *env = getenv(SRCTREE); |
| 1284 | gchar *path = g_strconcat(env ? env : g_get_current_dir(), "/scripts/kconfig/icons/menu.xpm", NULL); | ||
| 1285 | GError *err = NULL; | ||
| 1286 | |||
| 1287 | pix_menu = gdk_pixbuf_new_from_file(path, &err); | ||
| 1288 | g_free(path); | ||
| 1289 | |||
| 1290 | if (err) { | ||
| 1291 | g_warning("Failed to load menu icon: %s", err->message); | ||
| 1292 | g_error_free(err); | ||
| 1293 | } | ||
| 1273 | 1294 | ||
| 1274 | for (i = 0; i < COL_VALUE; i++) { | 1295 | for (i = 0; i < COL_VALUE; i++) { |
| 1275 | column = gtk_tree_view_get_column(view, i); | 1296 | column = gtk_tree_view_get_column(view, i); |
| @@ -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 | struct menu *menu_add_menu(void); | 82 | struct menu *menu_add_menu(void); |
| 83 | void menu_end_menu(void); | 83 | void menu_end_menu(void); |
| 84 | void menu_add_entry(struct symbol *sym, enum menu_type type); | 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 | void menu_add_visibility(struct expr *dep); | 86 | void menu_add_visibility(struct expr *dep); |
| 87 | struct property *menu_add_prompt(enum prop_type type, const char *prompt, | 87 | struct property *menu_add_prompt(enum prop_type type, const char *prompt, |
| 88 | struct expr *dep); | 88 | struct expr *dep); |
| @@ -127,8 +127,18 @@ static struct expr *rewrite_m(struct expr *e) · 126 unmodified lines | |||
| 127 | return e; | 127 | return e; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 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 | current_entry->dep = expr_alloc_and(current_entry->dep, dep); | 142 | current_entry->dep = expr_alloc_and(current_entry->dep, dep); |
| 133 | } | 143 | } |
| 134 | 144 | ||
| @@ -16,8 +16,8 @@ · 15 unmodified lines | |||
| 16 | set -e | 16 | set -e |
| 17 | 17 | ||
| 18 | clean_up() { | 18 | clean_up() { |
| 19 | rm -f $TMP_FILE | 19 | rm -f "$TMP_FILE" |
| 20 | rm -f $MERGE_FILE | 20 | rm -f "$TMP_FILE.new" |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | usage() { | 23 | usage() { |
| @@ -43,6 +43,10 @@ STRICT=false · 19 unmodified lines | |||
| 43 | CONFIG_PREFIX=${CONFIG_-CONFIG_} | 43 | CONFIG_PREFIX=${CONFIG_-CONFIG_} |
| 44 | WARNOVERRIDE=echo | 44 | WARNOVERRIDE=echo |
| 45 | 45 | ||
| 46 | if [ -z "$AWK" ]; then | ||
| 47 | AWK=awk | ||
| 48 | fi | ||
| 49 | |||
| 46 | while true; do | 50 | while true; do |
| 47 | case $1 in | 51 | case $1 in |
| 48 | "-n") | 52 | "-n") |
| @@ -117,11 +121,8 @@ if [ ! -r "$INITFILE" ]; then · 68 unmodified lines | |||
| 117 | fi | 121 | fi |
| 118 | 122 | ||
| 119 | MERGE_LIST=$* | 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 | TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) | 125 | TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) |
| 124 | MERGE_FILE=$(mktemp ./.merge_tmp.config.XXXXXXXXXX) | ||
| 125 | 126 | ||
| 126 | echo "Using $INITFILE as base" | 127 | echo "Using $INITFILE as base" |
| 127 | 128 | ||
| @@ -129,6 +130,8 @@ trap clean_up EXIT · 1 unmodified line | |||
| 129 | 130 | ||
| 130 | cat $INITFILE > $TMP_FILE | 131 | cat $INITFILE > $TMP_FILE |
| 131 | 132 | ||
| 133 | PROCESSED_FILES="" | ||
| 134 | |||
| 132 | # Merge files, printing warnings on overridden values | 135 | # Merge files, printing warnings on overridden values |
| 133 | for ORIG_MERGE_FILE in $MERGE_LIST ; do | 136 | for ORIG_MERGE_FILE in $MERGE_LIST ; do |
| 134 | echo "Merging $ORIG_MERGE_FILE" | 137 | echo "Merging $ORIG_MERGE_FILE" |
| @@ -136,42 +139,138 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do · 1 unmodified line | |||
| 136 | echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2 | 139 | echo "The merge file '$ORIG_MERGE_FILE' does not exist. Exit." >&2 |
| 137 | exit 1 | 140 | exit 1 |
| 138 | fi | 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 | if [ "$STRICT_MODE_VIOLATED" = "true" ]; then | 274 | if [ "$STRICT_MODE_VIOLATED" = "true" ]; then |
| 176 | echo "The fragment redefined a value and strict mode had been passed." | 275 | echo "The fragment redefined a value and strict mode had been passed." |
| 177 | exit 1 | 276 | exit 1 |
| @@ -198,16 +297,91 @@ fi · 20 unmodified lines | |||
| 198 | # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set | 297 | # allnoconfig: Fills in any missing symbols with # CONFIG_* is not set |
| 199 | make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET | 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) | 311 | # Extract config name from a line, returns "" if not a config line |
| 203 | for CFG in $(sed -n -e "$SED_CONFIG_EXP1" -e "$SED_CONFIG_EXP2" $TMP_FILE); do | 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) | 324 | function warn_mismatch(cfg, merged, final) { |
| 206 | ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG" || true) | 325 | if (warnredun == "true") return |
| 207 | if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then | 326 | if (final == "" && !(merged ~ / is not set$/ || merged ~ /=n$/)) { |
| 208 | echo "Value requested for $CFG not in final .config" | 327 | print "WARNING: Value requested for " cfg " not in final .config" |
| 209 | echo "Requested value: $REQUESTED_VAL" | 328 | print "Requested value: " merged |
| 210 | echo "Actual value: $ACTUAL_VAL" | 329 | print "Actual value: " final |
| 211 | echo "" | 330 | } else if (final == "" && merged ~ / is not set$/) { |
| 212 | fi | 331 | # not set, pass |
| 213 | done | 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 | printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno); | 324 | printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno); |
| 325 | menu_add_entry(NULL, M_IF); | 325 | menu_add_entry(NULL, M_IF); |
| 326 | menu_add_dep($2); | 326 | menu_add_dep($2, NULL); |
| 327 | $$ = menu_add_menu(); | 327 | $$ = menu_add_menu(); |
| 328 | }; | 328 | }; |
| 329 | 329 | ||
| @@ -422,9 +422,9 @@ help: help_start T_HELPTEXT · 92 unmodified lines | |||
| 422 | 422 | ||
| 423 | /* depends option */ | 423 | /* depends option */ |
| 424 | 424 | ||
| 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 | printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno); | 428 | printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno); |
| 429 | }; | 429 | }; |
| 430 | 430 | ||
| @@ -26,8 +26,6 @@ · 25 unmodified lines | |||
| 26 | #include "lkc.h" | 26 | #include "lkc.h" |
| 27 | #include "qconf.h" | 27 | #include "qconf.h" |
| 28 | 28 | ||
| 29 | #include "images.h" | ||
| 30 | |||
| 31 | 29 | ||
| 32 | static QApplication *configApp; | 30 | static QApplication *configApp; |
| 33 | static ConfigSettings *configSettings; | 31 | static ConfigSettings *configSettings; |
| @@ -1283,13 +1281,14 @@ ConfigMainWindow::ConfigMainWindow(void) · 1249 unmodified lines | |||
| 1283 | move(x.toInt(), y.toInt()); | 1281 | move(x.toInt(), y.toInt()); |
| 1284 | 1282 | ||
| 1285 | // set up icons | 1283 | // set up icons |
| 1286 | ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes)); | 1284 | QString iconsDir = QString(getenv(SRCTREE) ? getenv(SRCTREE) : QDir::currentPath()) + "/scripts/kconfig/icons/"; |
| 1287 | ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod)); | 1285 | ConfigItem::symbolYesIcon = QIcon(QPixmap(iconsDir + "symbol_yes.xpm")); |
| 1288 | ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no)); | 1286 | ConfigItem::symbolModIcon = QIcon(QPixmap(iconsDir + "symbol_mod.xpm")); |
| 1289 | ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes)); | 1287 | ConfigItem::symbolNoIcon = QIcon(QPixmap(iconsDir + "symbol_no.xpm")); |
| 1290 | ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no)); | 1288 | ConfigItem::choiceYesIcon = QIcon(QPixmap(iconsDir + "choice_yes.xpm")); |
| 1291 | ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu)); | 1289 | ConfigItem::choiceNoIcon = QIcon(QPixmap(iconsDir + "choice_no.xpm")); |
| 1292 | ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); | 1290 | ConfigItem::menuIcon = QIcon(QPixmap(iconsDir + "menu.xpm")); |
| 1291 | ConfigItem::menubackIcon = QIcon(QPixmap(iconsDir + "menuback.xpm")); | ||
| 1293 | 1292 | ||
| 1294 | QWidget *widget = new QWidget(this); | 1293 | QWidget *widget = new QWidget(this); |
| 1295 | setCentralWidget(widget); | 1294 | setCentralWidget(widget); |
| @@ -1312,7 +1311,7 @@ ConfigMainWindow::ConfigMainWindow(void) · 16 unmodified lines | |||
| 1312 | 1311 | ||
| 1313 | configList->setFocus(); | 1312 | configList->setFocus(); |
| 1314 | 1313 | ||
| 1315 | backAction = new QAction(QPixmap(xpm_back), "Back", this); | 1314 | backAction = new QAction(QPixmap(iconsDir + "back.xpm"), "Back", this); |
| 1316 | backAction->setShortcut(QKeySequence::Back); | 1315 | backAction->setShortcut(QKeySequence::Back); |
| 1317 | connect(backAction, &QAction::triggered, | 1316 | connect(backAction, &QAction::triggered, |
| 1318 | this, &ConfigMainWindow::goBack); | 1317 | this, &ConfigMainWindow::goBack); |
| @@ -1322,12 +1321,12 @@ ConfigMainWindow::ConfigMainWindow(void) · 3 unmodified lines | |||
| 1322 | connect(quitAction, &QAction::triggered, | 1321 | connect(quitAction, &QAction::triggered, |
| 1323 | this, &ConfigMainWindow::close); | 1322 | this, &ConfigMainWindow::close); |
| 1324 | 1323 | ||
| 1325 | QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this); | 1324 | QAction *loadAction = new QAction(QPixmap(iconsDir + "load.xpm"), "&Open", this); |
| 1326 | loadAction->setShortcut(QKeySequence::Open); | 1325 | loadAction->setShortcut(QKeySequence::Open); |
| 1327 | connect(loadAction, &QAction::triggered, | 1326 | connect(loadAction, &QAction::triggered, |
| 1328 | this, &ConfigMainWindow::loadConfig); | 1327 | this, &ConfigMainWindow::loadConfig); |
| 1329 | 1328 | ||
| 1330 | saveAction = new QAction(QPixmap(xpm_save), "&Save", this); | 1329 | saveAction = new QAction(QPixmap(iconsDir + "save.xpm"), "&Save", this); |
| 1331 | saveAction->setShortcut(QKeySequence::Save); | 1330 | saveAction->setShortcut(QKeySequence::Save); |
| 1332 | connect(saveAction, &QAction::triggered, | 1331 | connect(saveAction, &QAction::triggered, |
| 1333 | this, &ConfigMainWindow::saveConfig); | 1332 | this, &ConfigMainWindow::saveConfig); |
| @@ -1344,15 +1343,15 @@ ConfigMainWindow::ConfigMainWindow(void) · 10 unmodified lines | |||
| 1344 | searchAction->setShortcut(QKeySequence::Find); | 1343 | searchAction->setShortcut(QKeySequence::Find); |
| 1345 | connect(searchAction, &QAction::triggered, | 1344 | connect(searchAction, &QAction::triggered, |
| 1346 | this, &ConfigMainWindow::searchConfig); | 1345 | this, &ConfigMainWindow::searchConfig); |
| 1347 | singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); | 1346 | singleViewAction = new QAction(QPixmap(iconsDir + "single_view.xpm"), "Single View", this); |
| 1348 | singleViewAction->setCheckable(true); | 1347 | singleViewAction->setCheckable(true); |
| 1349 | connect(singleViewAction, &QAction::triggered, | 1348 | connect(singleViewAction, &QAction::triggered, |
| 1350 | this, &ConfigMainWindow::showSingleView); | 1349 | this, &ConfigMainWindow::showSingleView); |
| 1351 | splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); | 1350 | splitViewAction = new QAction(QPixmap(iconsDir + "split_view.xpm"), "Split View", this); |
| 1352 | splitViewAction->setCheckable(true); | 1351 | splitViewAction->setCheckable(true); |
| 1353 | connect(splitViewAction, &QAction::triggered, | 1352 | connect(splitViewAction, &QAction::triggered, |
| 1354 | this, &ConfigMainWindow::showSplitView); | 1353 | this, &ConfigMainWindow::showSplitView); |
| 1355 | fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); | 1354 | fullViewAction = new QAction(QPixmap(iconsDir + "tree_view.xpm"), "Full View", this); |
| 1356 | fullViewAction->setCheckable(true); | 1355 | fullViewAction->setCheckable(true); |
| 1357 | connect(fullViewAction, &QAction::triggered, | 1356 | connect(fullViewAction, &QAction::triggered, |
| 1358 | this, &ConfigMainWindow::showFullView); | 1357 | this, &ConfigMainWindow::showFullView); |
| @@ -415,7 +415,7 @@ foreach my $module (keys(%modules)) { · 414 unmodified lines | |||
| 415 | } | 415 | } |
| 416 | } else { | 416 | } else { |
| 417 | # Most likely, someone has a custom (binary?) module loaded. | 417 | # Most likely, someone has a custom (binary?) module loaded. |
| 418 | print STDERR "$module config not found!!\n"; | 418 | print STDERR "$module config not found!\n"; |
| 419 | } | 419 | } |
| 420 | } | 420 | } |
| 421 | 421 | ||
| @@ -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 | kallsymopt="${kallsymopt} --all-symbols" | 143 | kallsymopt="${kallsymopt} --all-symbols" |
| 144 | fi | 144 | fi |
| 145 | 145 | ||
| 146 | if is_enabled CONFIG_64BIT || is_enabled CONFIG_RELOCATABLE; then | ||
| 147 | kallsymopt="${kallsymopt} --pc-relative" | ||
| 148 | fi | ||
| 149 | |||
| 146 | info KSYMS "${2}.S" | 150 | info KSYMS "${2}.S" |
| 147 | scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S" | 151 | scripts/kallsyms ${kallsymopt} "${1}" > "${2}.S" |
| 148 | 152 | ||
| @@ -10,10 +10,14 @@ · 9 unmodified lines | |||
| 10 | Usage: | 10 | Usage: |
| 11 | make_fit.py -A arm64 -n 'Linux-6.6' -O linux | 11 | make_fit.py -A arm64 -n 'Linux-6.6' -O linux |
| 12 | -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk | 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 | Creates a FIT containing the supplied kernel, an optional ramdisk, and a set of |
| 16 | either specified individually or listed in a file (with an '@' prefix). | 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 | Use -E to generate an external FIT (where the data is placed after the | 22 | Use -E to generate an external FIT (where the data is placed after the |
| 19 | FIT data structure). This allows parsing of the data without loading | 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 | The resulting FIT can be booted by bootloaders which support FIT, such | 34 | The resulting FIT can be booted by bootloaders which support FIT, such |
| 31 | as U-Boot, Linuxboot, Tianocore, etc. | 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 | import argparse | 38 | import argparse |
| 37 | import collections | 39 | import collections |
| 40 | import multiprocessing | ||
| 38 | import os | 41 | import os |
| 39 | import subprocess | 42 | import subprocess |
| 40 | import sys | 43 | import sys |
| @@ -48,11 +51,12 @@ import libfdt · 7 unmodified lines | |||
| 48 | CompTool = collections.namedtuple('CompTool', 'ext,tools') | 51 | CompTool = collections.namedtuple('CompTool', 'ext,tools') |
| 49 | 52 | ||
| 50 | COMP_TOOLS = { | 53 | COMP_TOOLS = { |
| 51 | 'bzip2': CompTool('.bz2', 'bzip2'), | 54 | 'bzip2': CompTool('.bz2', 'pbzip2,bzip2'), |
| 52 | 'gzip': CompTool('.gz', 'pigz,gzip'), | 55 | 'gzip': CompTool('.gz', 'pigz,gzip'), |
| 53 | 'lz4': CompTool('.lz4', 'lz4'), | 56 | 'lz4': CompTool('.lz4', 'lz4'), |
| 54 | 'lzma': CompTool('.lzma', 'lzma'), | 57 | 'lzma': CompTool('.lzma', 'plzip,lzma'), |
| 55 | 'lzo': CompTool('.lzo', 'lzop'), | 58 | 'lzo': CompTool('.lzo', 'lzop'), |
| 59 | 'xz': CompTool('.xz', 'xz'), | ||
| 56 | 'zstd': CompTool('.zstd', 'zstd'), | 60 | 'zstd': CompTool('.zstd', 'zstd'), |
| 57 | } | 61 | } |
| 58 | 62 | ||
| @@ -81,6 +85,8 @@ def parse_args(): · 22 unmodified lines | |||
| 81 | help='Specifies the operating system') | 85 | help='Specifies the operating system') |
| 82 | parser.add_argument('-k', '--kernel', type=str, required=True, | 86 | parser.add_argument('-k', '--kernel', type=str, required=True, |
| 83 | help='Specifies the (uncompressed) kernel input file (.itk)') | 87 | help='Specifies the (uncompressed) kernel input file (.itk)') |
| 88 | parser.add_argument('-r', '--ramdisk', type=str, | ||
| 89 | help='Specifies the ramdisk/initrd input file') | ||
| 84 | parser.add_argument('-v', '--verbose', action='store_true', | 90 | parser.add_argument('-v', '--verbose', action='store_true', |
| 85 | help='Enable verbose output') | 91 | help='Enable verbose output') |
| 86 | parser.add_argument('dtbs', type=str, nargs='*', | 92 | parser.add_argument('dtbs', type=str, nargs='*', |
| @@ -98,7 +104,7 @@ def setup_fit(fsw, name): · 11 unmodified lines | |||
| 98 | fsw (libfdt.FdtSw): Object to use for writing | 104 | fsw (libfdt.FdtSw): Object to use for writing |
| 99 | name (str): Name of kernel image | 105 | name (str): Name of kernel image |
| 100 | """ | 106 | """ |
| 101 | fsw.INC_SIZE = 65536 | 107 | fsw.INC_SIZE = 16 << 20 |
| 102 | fsw.finish_reservemap() | 108 | fsw.finish_reservemap() |
| 103 | fsw.begin_node('') | 109 | fsw.begin_node('') |
| 104 | fsw.property_string('description', f'{name} with devicetree set') | 110 | fsw.property_string('description', f'{name} with devicetree set') |
| @@ -133,7 +139,28 @@ def write_kernel(fsw, data, args): · 28 unmodified lines | |||
| 133 | fsw.property_u32('entry', 0) | 139 | fsw.property_u32('entry', 0) |
| 134 | 140 | ||
| 135 | 141 | ||
| 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 | """Finish the FIT ready for use | 164 | """Finish the FIT ready for use |
| 138 | 165 | ||
| 139 | Writes the /configurations node and subnodes | 166 | Writes the /configurations node and subnodes |
| @@ -143,6 +170,7 @@ def finish_fit(fsw, entries): · 3 unmodified lines | |||
| 143 | entries (list of tuple): List of configurations: | 170 | entries (list of tuple): List of configurations: |
| 144 | str: Description of model | 171 | str: Description of model |
| 145 | str: Compatible stringlist | 172 | str: Compatible stringlist |
| 173 | has_ramdisk (bool): True if a ramdisk is included in the FIT | ||
| 146 | """ | 174 | """ |
| 147 | fsw.end_node() | 175 | fsw.end_node() |
| 148 | seq = 0 | 176 | seq = 0 |
| @@ -154,6 +182,8 @@ def finish_fit(fsw, entries): · 5 unmodified lines | |||
| 154 | fsw.property_string('description', model) | 182 | fsw.property_string('description', model) |
| 155 | fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) | 183 | fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii")) |
| 156 | fsw.property_string('kernel', 'kernel') | 184 | fsw.property_string('kernel', 'kernel') |
| 185 | if has_ramdisk: | ||
| 186 | fsw.property_string('ramdisk', 'ramdisk') | ||
| 157 | fsw.end_node() | 187 | fsw.end_node() |
| 158 | 188 | ||
| 159 | 189 | ||
| @@ -179,7 +209,12 @@ def compress_data(inf, compress): · 19 unmodified lines | |||
| 179 | done = False | 209 | done = False |
| 180 | for tool in comp.tools.split(','): | 210 | for tool in comp.tools.split(','): |
| 181 | try: | 211 | try: |
| 182 | subprocess.call([tool, '-c'], stdin=inf, stdout=outf) | 212 | # Add parallel flags for tools that support them |
| 213 | cmd = [tool] | ||
| 214 | if tool in ('zstd', 'xz'): | ||
| 215 | cmd.extend(['-T0']) # Use all available cores | ||
| 216 | cmd.append('-c') | ||
| 217 | subprocess.call(cmd, stdin=inf, stdout=outf) | ||
| 183 | done = True | 218 | done = True |
| 184 | break | 219 | break |
| 185 | except FileNotFoundError: | 220 | except FileNotFoundError: |
| @@ -191,15 +226,31 @@ def compress_data(inf, compress): · 5 unmodified lines | |||
| 191 | return comp_data | 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 | """Write out a single devicetree to the FIT | 245 | """Write out a single devicetree to the FIT |
| 196 | 246 | ||
| 197 | Args: | 247 | Args: |
| 198 | fsw (libfdt.FdtSw): Object to use for writing | 248 | fsw (libfdt.FdtSw): Object to use for writing |
| 199 | seq (int): Sequence number (1 for first) | 249 | seq (int): Sequence number (1 for first) |
| 200 | fname (str): Filename containing the DTB | 250 | fname (str): Filename containing the DTB |
| 201 | arch: FIT architecture, e.g. 'arm64' | 251 | arch (str): FIT architecture, e.g. 'arm64' |
| 202 | compress (str): Compressed algorithm, e.g. 'gzip' | 252 | compress (str): Compressed algorithm, e.g. 'gzip' |
| 253 | data (bytes): Pre-compressed data (optional) | ||
| 203 | """ | 254 | """ |
| 204 | with fsw.add_node(f'fdt-{seq}'): | 255 | with fsw.add_node(f'fdt-{seq}'): |
| 205 | fsw.property_string('description', os.path.basename(fname)) | 256 | fsw.property_string('description', os.path.basename(fname)) |
| @@ -207,9 +258,10 @@ def output_dtb(fsw, seq, fname, arch, compress): · 1 unmodified line | |||
| 207 | fsw.property_string('arch', arch) | 258 | fsw.property_string('arch', arch) |
| 208 | fsw.property_string('compression', compress) | 259 | fsw.property_string('compression', compress) |
| 209 | 260 | ||
| 210 | with open(fname, 'rb') as inf: | 261 | if data is None: |
| 211 | compressed = compress_data(inf, compress) | 262 | with open(fname, 'rb') as inf: |
| 212 | fsw.property('data', compressed) | 263 | data = compress_data(inf, compress) |
| 264 | fsw.property('data', data) | ||
| 213 | 265 | ||
| 214 | 266 | ||
| 215 | def process_dtb(fname, args): | 267 | def process_dtb(fname, args): |
| @@ -249,30 +301,27 @@ def process_dtb(fname, args): · 33 unmodified lines | |||
| 249 | 301 | ||
| 250 | return (model, compat, files) | 302 | return (model, compat, files) |
| 251 | 303 | ||
| 252 | def build_fit(args): | 304 | |
| 253 | """Build the FIT from the provided files and arguments | 305 | def _process_dtbs(args, fsw, entries, fdts): |
| 306 | """Process all DTB files and add them to the FIT | ||
| 254 | 307 | ||
| 255 | Args: | 308 | Args: |
| 256 | args (Namespace): Program 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 | Returns: | 314 | Returns: |
| 259 | tuple: | 315 | tuple: |
| 260 | bytes: FIT data | 316 | Number of files processed |
| 261 | int: Number of configurations generated | 317 | Total size of files processed |
| 262 | size: Total uncompressed size of data | ||
| 263 | """ | 318 | """ |
| 264 | seq = 0 | 319 | seq = 0 |
| 265 | size = 0 | 320 | size = 0 |
| 266 | fsw = libfdt.FdtSw() | ||
| 267 | setup_fit(fsw, args.name) | ||
| 268 | entries = [] | ||
| 269 | fdts = {} | ||
| 270 | 321 | ||
| 271 | # Handle the kernel | 322 | # First figure out the unique DTB files that need compression |
| 272 | with open(args.kernel, 'rb') as inf: | 323 | todo = [] |
| 273 | comp_data = compress_data(inf, args.compress) | 324 | file_info = [] # List of (fname, model, compat, files) tuples |
| 274 | size += os.path.getsize(args.kernel) | ||
| 275 | write_kernel(fsw, comp_data, args) | ||
| 276 | 325 | ||
| 277 | for fname in args.dtbs: | 326 | for fname in args.dtbs: |
| 278 | # Ignore non-DTB (*.dtb) files | 327 | # Ignore non-DTB (*.dtb) files |
| @@ -282,24 +331,84 @@ def build_fit(args): · 3 unmodified lines | |||
| 282 | try: | 331 | try: |
| 283 | (model, compat, files) = process_dtb(fname, args) | 332 | (model, compat, files) = process_dtb(fname, args) |
| 284 | except Exception as e: | 333 | except Exception as e: |
| 285 | sys.stderr.write(f"Error processing {fname}:\n") | 334 | sys.stderr.write(f'Error processing {fname}:\n') |
| 286 | raise e | 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 | for fn in files: | 357 | for fn in files: |
| 289 | if fn not in fdts: | 358 | if fn not in fdts: |
| 290 | seq += 1 | 359 | seq += 1 |
| 291 | size += os.path.getsize(fn) | 360 | size += os.path.getsize(fn) |
| 292 | output_dtb(fsw, seq, fn, args.arch, args.compress) | 361 | output_dtb(fsw, seq, fn, args.arch, args.compress, |
| 362 | cache.get(fn)) | ||
| 293 | fdts[fn] = seq | 363 | fdts[fn] = seq |
| 294 | 364 | ||
| 295 | files_seq = [fdts[fn] for fn in files] | 365 | files_seq = [fdts[fn] for fn in files] |
| 296 | |||
| 297 | entries.append([model, compat, files_seq]) | 366 | entries.append([model, compat, files_seq]) |
| 298 | 367 | ||
| 299 | finish_fit(fsw, entries) | 368 | return seq, size |
| 369 | |||
| 370 | |||
| 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 | # Include the kernel itself in the returned file count | 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 | def run_make_fit(): | 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 | /* Special register function linked on all modules during final link of .ko */ | 602 | /* Special register function linked on all modules during final link of .ko */ |
| 603 | if (strstarts(symname, "_restgpr0_") || | 603 | if (strstarts(symname, "_restgpr0_") || |
| 604 | strstarts(symname, "_savegpr0_") || | 604 | strstarts(symname, "_savegpr0_") || |
| 605 | strstarts(symname, "_restgpr1_") || | ||
| 606 | strstarts(symname, "_savegpr1_") || | ||
| 607 | strstarts(symname, "_restfpr_") || | ||
| 608 | strstarts(symname, "_savefpr_") || | ||
| 605 | strstarts(symname, "_restvr_") || | 609 | strstarts(symname, "_restvr_") || |
| 606 | strstarts(symname, "_savevr_") || | 610 | strstarts(symname, "_savevr_") || |
| 607 | strcmp(symname, ".TOC.") == 0) | 611 | strcmp(symname, ".TOC.") == 0) |
| @@ -958,7 +962,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, · 350 unmodified lines | |||
| 958 | /* symbols in data sections that may refer to any init/exit sections */ | 962 | /* symbols in data sections that may refer to any init/exit sections */ |
| 959 | if (match(fromsec, PATTERNS(DATA_SECTIONS)) && | 963 | if (match(fromsec, PATTERNS(DATA_SECTIONS)) && |
| 960 | match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && | 964 | match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && |
| 961 | match(fromsym, PATTERNS("*_ops", "*_probe", "*_console"))) | 965 | match(fromsym, PATTERNS("*_ops", "*_console"))) |
| 962 | return 0; | 966 | return 0; |
| 963 | 967 | ||
| 964 | /* Check for pattern 3 */ | 968 | /* Check for pattern 3 */ |
| @@ -27,7 +27,6 @@ static bool is_ignored_symbol(const char *name, char type) · 26 unmodified lines | |||
| 27 | * stable symbol list. | 27 | * stable symbol list. |
| 28 | */ | 28 | */ |
| 29 | "kallsyms_offsets", | 29 | "kallsyms_offsets", |
| 30 | "kallsyms_relative_base", | ||
| 31 | "kallsyms_num_syms", | 30 | "kallsyms_num_syms", |
| 32 | "kallsyms_names", | 31 | "kallsyms_names", |
| 33 | "kallsyms_markers", | 32 | "kallsyms_markers", |
| @@ -65,16 +65,101 @@ no-header-test += asm/uctx.h · 64 unmodified lines | |||
| 65 | no-header-test += asm/fbio.h | 65 | no-header-test += asm/fbio.h |
| 66 | endif | 66 | endif |
| 67 | 67 | ||
| 68 | ifeq ($(SRCARCH),xtensa) | ||
| 69 | no-header-test += linux/bpf_perf_event.h | ||
| 70 | endif | ||
| 71 | |||
| 68 | # asm-generic/*.h is used by asm/*.h, and should not be included directly | 72 | # asm-generic/*.h is used by asm/*.h, and should not be included directly |
| 69 | no-header-test += asm-generic/% | 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 | always-y := $(patsubst $(obj)/%.h,%.hdrtest, $(shell find $(obj) -name '*.h' 2>/dev/null)) | 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 | # Include the header twice to detect missing include guard. | 157 | # Include the header twice to detect missing include guard. |
| 74 | quiet_cmd_hdrtest = HDRTEST $< | 158 | quiet_cmd_hdrtest = HDRTEST $< |
| 75 | cmd_hdrtest = \ | 159 | cmd_hdrtest = \ |
| 76 | $(CC) $(c_flags) -fsyntax-only -Werror -x c /dev/null \ | 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 | $(PERL) $(src)/headers_check.pl $(obj) $<; \ | 163 | $(PERL) $(src)/headers_check.pl $(obj) $<; \ |
| 79 | touch $@ | 164 | touch $@ |
| 80 | 165 | ||
| @@ -40,7 +40,6 @@ foreach my $file (@files) { · 39 unmodified lines | |||
| 40 | &check_include(); | 40 | &check_include(); |
| 41 | &check_asm_types(); | 41 | &check_asm_types(); |
| 42 | &check_declarations(); | 42 | &check_declarations(); |
| 43 | # Dropped for now. Too much noise &check_config(); | ||
| 44 | } | 43 | } |
| 45 | close $fh; | 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 | my $linux_asm_types; | 79 | my $linux_asm_types; |
| 88 | sub check_asm_types | 80 | sub check_asm_types |
| 89 | { | 81 | { |