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

Merge tag 'kbuild-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kbuild updates from Masahiro Yamada:

- Add generic support for built-in boot DTB files

- Enable TAB cycling for dialog buttons in nconfig

- Fix issues in streamline_config.pl

- Refactor Kconfig

- Add support for Clang's AutoFDO (Automatic Feedback-Directed
Optimization)

- Add support for Clang's Propeller, a profile-guided optimization.

- Change the working directory to the external module directory for M=
builds

- Support building external modules in a separate output directory

- Enable objtool for *.mod.o and additional kernel objects

- Use lz4 instead of deprecated lz4c

- Work around a performance issue with "git describe"

- Refactor modpost

* tag 'kbuild-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (85 commits)
kbuild: rename .tmp_vmlinux.kallsyms0.syms to .tmp_vmlinux0.syms
gitignore: Don't ignore 'tags' directory
kbuild: add dependency from vmlinux to resolve_btfids
modpost: replace tdb_hash() with hash_str()
kbuild: deb-pkg: add python3:native to build dependency
genksyms: reduce indentation in export_symbol()
modpost: improve error messages in device_id_check()
modpost: rename alias symbol for MODULE_DEVICE_TABLE()
modpost: rename variables in handle_moddevtable()
modpost: move strstarts() to modpost.h
modpost: convert do_usb_table() to a generic handler
modpost: convert do_of_table() to a generic handler
modpost: convert do_pnp_device_entry() to a generic handler
modpost: convert do_pnp_card_entries() to a generic handler
modpost: call module_alias_printf() from all do_*_entry() functions
modpost: pass (struct module *) to do_*_entry() functions
modpost: remove DEF_FIELD_ADDR_VAR() macro
modpost: deduplicate MODULE_ALIAS() for all drivers
modpost: introduce module_alias_printf() helper
modpost: remove unnecessary check in do_acpi_entry()
...

+1478 -1017
+1
.gitignore
··· 129 129 130 130 # ctags files 131 131 tags 132 + !tags/ 132 133 TAGS 133 134 134 135 # cscope files
+168
Documentation/dev-tools/autofdo.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + =================================== 4 + Using AutoFDO with the Linux kernel 5 + =================================== 6 + 7 + This enables AutoFDO build support for the kernel when using 8 + the Clang compiler. AutoFDO (Auto-Feedback-Directed Optimization) 9 + is a type of profile-guided optimization (PGO) used to enhance the 10 + performance of binary executables. It gathers information about the 11 + frequency of execution of various code paths within a binary using 12 + hardware sampling. This data is then used to guide the compiler's 13 + optimization decisions, resulting in a more efficient binary. AutoFDO 14 + is a powerful optimization technique, and data indicates that it can 15 + significantly improve kernel performance. It's especially beneficial 16 + for workloads affected by front-end stalls. 17 + 18 + For AutoFDO builds, unlike non-FDO builds, the user must supply a 19 + profile. Acquiring an AutoFDO profile can be done in several ways. 20 + AutoFDO profiles are created by converting hardware sampling using 21 + the "perf" tool. It is crucial that the workload used to create these 22 + perf files is representative; they must exhibit runtime 23 + characteristics similar to the workloads that are intended to be 24 + optimized. Failure to do so will result in the compiler optimizing 25 + for the wrong objective. 26 + 27 + The AutoFDO profile often encapsulates the program's behavior. If the 28 + performance-critical codes are architecture-independent, the profile 29 + can be applied across platforms to achieve performance gains. For 30 + instance, using the profile generated on Intel architecture to build 31 + a kernel for AMD architecture can also yield performance improvements. 32 + 33 + There are two methods for acquiring a representative profile: 34 + (1) Sample real workloads using a production environment. 35 + (2) Generate the profile using a representative load test. 36 + When enabling the AutoFDO build configuration without providing an 37 + AutoFDO profile, the compiler only modifies the dwarf information in 38 + the kernel without impacting runtime performance. It's advisable to 39 + use a kernel binary built with the same AutoFDO configuration to 40 + collect the perf profile. While it's possible to use a kernel built 41 + with different options, it may result in inferior performance. 42 + 43 + One can collect profiles using AutoFDO build for the previous kernel. 44 + AutoFDO employs relative line numbers to match the profiles, offering 45 + some tolerance for source changes. This mode is commonly used in a 46 + production environment for profile collection. 47 + 48 + In a profile collection based on a load test, the AutoFDO collection 49 + process consists of the following steps: 50 + 51 + #. Initial build: The kernel is built with AutoFDO options 52 + without a profile. 53 + 54 + #. Profiling: The above kernel is then run with a representative 55 + workload to gather execution frequency data. This data is 56 + collected using hardware sampling, via perf. AutoFDO is most 57 + effective on platforms supporting advanced PMU features like 58 + LBR on Intel machines. 59 + 60 + #. AutoFDO profile generation: Perf output file is converted to 61 + the AutoFDO profile via offline tools. 62 + 63 + The support requires a Clang compiler LLVM 17 or later. 64 + 65 + Preparation 66 + =========== 67 + 68 + Configure the kernel with:: 69 + 70 + CONFIG_AUTOFDO_CLANG=y 71 + 72 + Customization 73 + ============= 74 + 75 + The default CONFIG_AUTOFDO_CLANG setting covers kernel space objects for 76 + AutoFDO builds. One can, however, enable or disable AutoFDO build for 77 + individual files and directories by adding a line similar to the following 78 + to the respective kernel Makefile: 79 + 80 + - For enabling a single file (e.g. foo.o) :: 81 + 82 + AUTOFDO_PROFILE_foo.o := y 83 + 84 + - For enabling all files in one directory :: 85 + 86 + AUTOFDO_PROFILE := y 87 + 88 + - For disabling one file :: 89 + 90 + AUTOFDO_PROFILE_foo.o := n 91 + 92 + - For disabling all files in one directory :: 93 + 94 + AUTOFDO_PROFILE := n 95 + 96 + Workflow 97 + ======== 98 + 99 + Here is an example workflow for AutoFDO kernel: 100 + 101 + 1) Build the kernel on the host machine with LLVM enabled, 102 + for example, :: 103 + 104 + $ make menuconfig LLVM=1 105 + 106 + Turn on AutoFDO build config:: 107 + 108 + CONFIG_AUTOFDO_CLANG=y 109 + 110 + With a configuration that with LLVM enabled, use the following command:: 111 + 112 + $ scripts/config -e AUTOFDO_CLANG 113 + 114 + After getting the config, build with :: 115 + 116 + $ make LLVM=1 117 + 118 + 2) Install the kernel on the test machine. 119 + 120 + 3) Run the load tests. The '-c' option in perf specifies the sample 121 + event period. We suggest using a suitable prime number, like 500009, 122 + for this purpose. 123 + 124 + - For Intel platforms:: 125 + 126 + $ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c <count> -o <perf_file> -- <loadtest> 127 + 128 + - For AMD platforms: 129 + 130 + The supported systems are: Zen3 with BRS, or Zen4 with amd_lbr_v2. To check, 131 + 132 + For Zen3:: 133 + 134 + $ cat proc/cpuinfo | grep " brs" 135 + 136 + For Zen4:: 137 + 138 + $ cat proc/cpuinfo | grep amd_lbr_v2 139 + 140 + The following command generated the perf data file:: 141 + 142 + $ perf record --pfm-events RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c <count> -o <perf_file> -- <loadtest> 143 + 144 + 4) (Optional) Download the raw perf file to the host machine. 145 + 146 + 5) To generate an AutoFDO profile, two offline tools are available: 147 + create_llvm_prof and llvm_profgen. The create_llvm_prof tool is part 148 + of the AutoFDO project and can be found on GitHub 149 + (https://github.com/google/autofdo), version v0.30.1 or later. 150 + The llvm_profgen tool is included in the LLVM compiler itself. It's 151 + important to note that the version of llvm_profgen doesn't need to match 152 + the version of Clang. It needs to be the LLVM 19 release of Clang 153 + or later, or just from the LLVM trunk. :: 154 + 155 + $ llvm-profgen --kernel --binary=<vmlinux> --perfdata=<perf_file> -o <profile_file> 156 + 157 + or :: 158 + 159 + $ create_llvm_prof --binary=<vmlinux> --profile=<perf_file> --format=extbinary --out=<profile_file> 160 + 161 + Note that multiple AutoFDO profile files can be merged into one via:: 162 + 163 + $ llvm-profdata merge -o <profile_file> <profile_1> <profile_2> ... <profile_n> 164 + 165 + 6) Rebuild the kernel using the AutoFDO profile file with the same config as step 1, 166 + (Note CONFIG_AUTOFDO_CLANG needs to be enabled):: 167 + 168 + $ make LLVM=1 CLANG_AUTOFDO_PROFILE=<profile_file>
+6 -14
Documentation/dev-tools/coccinelle.rst
··· 250 250 - Your directory from which spatch is called is processed next 251 251 - The directory provided with the ``--dir`` option is processed last, if used 252 252 253 - Since coccicheck runs through make, it naturally runs from the kernel 254 - proper dir; as such the second rule above would be implied for picking up a 255 - .cocciconfig when using ``make coccicheck``. 256 - 257 253 ``make coccicheck`` also supports using M= targets. If you do not supply 258 254 any M= target, it is assumed you want to target the entire kernel. 259 255 The kernel coccicheck script has:: 260 256 261 - if [ "$KBUILD_EXTMOD" = "" ] ; then 262 - OPTIONS="--dir $srctree $COCCIINCLUDE" 263 - else 264 - OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" 265 - fi 257 + OPTIONS="--dir $srcroot $COCCIINCLUDE" 266 258 267 - KBUILD_EXTMOD is set when an explicit target with M= is used. For both cases 268 - the spatch ``--dir`` argument is used, as such third rule applies when whether 269 - M= is used or not, and when M= is used the target directory can have its own 270 - .cocciconfig file. When M= is not passed as an argument to coccicheck the 271 - target directory is the same as the directory from where spatch was called. 259 + Here, $srcroot refers to the source directory of the target: it points to the 260 + external module's source directory when M= used, and otherwise, to the kernel 261 + source directory. The third rule ensures the spatch reads the .cocciconfig from 262 + the target directory, allowing external modules to have their own .cocciconfig 263 + file. 272 264 273 265 If not using the kernel's coccicheck target, keep the above precedence 274 266 order logic of .cocciconfig reading. If using the kernel's coccicheck target,
+2
Documentation/dev-tools/index.rst
··· 34 34 ktap 35 35 checkuapi 36 36 gpio-sloppy-logic-analyzer 37 + autofdo 38 + propeller 37 39 38 40 39 41 .. only:: subproject and html
+162
Documentation/dev-tools/propeller.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ===================================== 4 + Using Propeller with the Linux kernel 5 + ===================================== 6 + 7 + This enables Propeller build support for the kernel when using Clang 8 + compiler. Propeller is a profile-guided optimization (PGO) method used 9 + to optimize binary executables. Like AutoFDO, it utilizes hardware 10 + sampling to gather information about the frequency of execution of 11 + different code paths within a binary. Unlike AutoFDO, this information 12 + is then used right before linking phase to optimize (among others) 13 + block layout within and across functions. 14 + 15 + A few important notes about adopting Propeller optimization: 16 + 17 + #. Although it can be used as a standalone optimization step, it is 18 + strongly recommended to apply Propeller on top of AutoFDO, 19 + AutoFDO+ThinLTO or Instrument FDO. The rest of this document 20 + assumes this paradigm. 21 + 22 + #. Propeller uses another round of profiling on top of 23 + AutoFDO/AutoFDO+ThinLTO/iFDO. The whole build process involves 24 + "build-afdo - train-afdo - build-propeller - train-propeller - 25 + build-optimized". 26 + 27 + #. Propeller requires LLVM 19 release or later for Clang/Clang++ 28 + and the linker(ld.lld). 29 + 30 + #. In addition to LLVM toolchain, Propeller requires a profiling 31 + conversion tool: https://github.com/google/autofdo with a release 32 + after v0.30.1: https://github.com/google/autofdo/releases/tag/v0.30.1. 33 + 34 + The Propeller optimization process involves the following steps: 35 + 36 + #. Initial building: Build the AutoFDO or AutoFDO+ThinLTO binary as 37 + you would normally do, but with a set of compile-time / link-time 38 + flags, so that a special metadata section is created within the 39 + kernel binary. The special section is only intend to be used by the 40 + profiling tool, it is not part of the runtime image, nor does it 41 + change kernel run time text sections. 42 + 43 + #. Profiling: The above kernel is then run with a representative 44 + workload to gather execution frequency data. This data is collected 45 + using hardware sampling, via perf. Propeller is most effective on 46 + platforms supporting advanced PMU features like LBR on Intel 47 + machines. This step is the same as profiling the kernel for AutoFDO 48 + (the exact perf parameters can be different). 49 + 50 + #. Propeller profile generation: Perf output file is converted to a 51 + pair of Propeller profiles via an offline tool. 52 + 53 + #. Optimized build: Build the AutoFDO or AutoFDO+ThinLTO optimized 54 + binary as you would normally do, but with a compile-time / 55 + link-time flag to pick up the Propeller compile time and link time 56 + profiles. This build step uses 3 profiles - the AutoFDO profile, 57 + the Propeller compile-time profile and the Propeller link-time 58 + profile. 59 + 60 + #. Deployment: The optimized kernel binary is deployed and used 61 + in production environments, providing improved performance 62 + and reduced latency. 63 + 64 + Preparation 65 + =========== 66 + 67 + Configure the kernel with:: 68 + 69 + CONFIG_AUTOFDO_CLANG=y 70 + CONFIG_PROPELLER_CLANG=y 71 + 72 + Customization 73 + ============= 74 + 75 + The default CONFIG_PROPELLER_CLANG setting covers kernel space objects 76 + for Propeller builds. One can, however, enable or disable Propeller build 77 + for individual files and directories by adding a line similar to the 78 + following to the respective kernel Makefile: 79 + 80 + - For enabling a single file (e.g. foo.o):: 81 + 82 + PROPELLER_PROFILE_foo.o := y 83 + 84 + - For enabling all files in one directory:: 85 + 86 + PROPELLER_PROFILE := y 87 + 88 + - For disabling one file:: 89 + 90 + PROPELLER_PROFILE_foo.o := n 91 + 92 + - For disabling all files in one directory:: 93 + 94 + PROPELLER__PROFILE := n 95 + 96 + 97 + Workflow 98 + ======== 99 + 100 + Here is an example workflow for building an AutoFDO+Propeller kernel: 101 + 102 + 1) Assuming an AutoFDO profile is already collected following 103 + instructions in the AutoFDO document, build the kernel on the host 104 + machine, with AutoFDO and Propeller build configs :: 105 + 106 + CONFIG_AUTOFDO_CLANG=y 107 + CONFIG_PROPELLER_CLANG=y 108 + 109 + and :: 110 + 111 + $ make LLVM=1 CLANG_AUTOFDO_PROFILE=<autofdo-profile-name> 112 + 113 + 2) Install the kernel on the test machine. 114 + 115 + 3) Run the load tests. The '-c' option in perf specifies the sample 116 + event period. We suggest using a suitable prime number, like 500009, 117 + for this purpose. 118 + 119 + - For Intel platforms:: 120 + 121 + $ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c <count> -o <perf_file> -- <loadtest> 122 + 123 + - For AMD platforms:: 124 + 125 + $ perf record --pfm-event RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c <count> -o <perf_file> -- <loadtest> 126 + 127 + Note you can repeat the above steps to collect multiple <perf_file>s. 128 + 129 + 4) (Optional) Download the raw perf file(s) to the host machine. 130 + 131 + 5) Use the create_llvm_prof tool (https://github.com/google/autofdo) to 132 + generate Propeller profile. :: 133 + 134 + $ create_llvm_prof --binary=<vmlinux> --profile=<perf_file> 135 + --format=propeller --propeller_output_module_name 136 + --out=<propeller_profile_prefix>_cc_profile.txt 137 + --propeller_symorder=<propeller_profile_prefix>_ld_profile.txt 138 + 139 + "<propeller_profile_prefix>" can be something like "/home/user/dir/any_string". 140 + 141 + This command generates a pair of Propeller profiles: 142 + "<propeller_profile_prefix>_cc_profile.txt" and 143 + "<propeller_profile_prefix>_ld_profile.txt". 144 + 145 + If there are more than 1 perf_file collected in the previous step, 146 + you can create a temp list file "<perf_file_list>" with each line 147 + containing one perf file name and run:: 148 + 149 + $ create_llvm_prof --binary=<vmlinux> --profile=@<perf_file_list> 150 + --format=propeller --propeller_output_module_name 151 + --out=<propeller_profile_prefix>_cc_profile.txt 152 + --propeller_symorder=<propeller_profile_prefix>_ld_profile.txt 153 + 154 + 6) Rebuild the kernel using the AutoFDO and Propeller 155 + profiles. :: 156 + 157 + CONFIG_AUTOFDO_CLANG=y 158 + CONFIG_PROPELLER_CLANG=y 159 + 160 + and :: 161 + 162 + $ make LLVM=1 CLANG_AUTOFDO_PROFILE=<profile_file> CLANG_PROPELLER_PROFILE_PREFIX=<propeller_profile_prefix>
+7 -1
Documentation/kbuild/kbuild.rst
··· 137 137 This variable can also be used to point to the kernel output directory when 138 138 building external modules against a pre-built kernel in a separate build 139 139 directory. Please note that this does NOT specify the output directory for the 140 - external modules themselves. 140 + external modules themselves. (Use KBUILD_EXTMOD_OUTPUT for that purpose.) 141 141 142 142 The output directory can also be specified using "O=...". 143 143 144 144 Setting "O=..." takes precedence over KBUILD_OUTPUT. 145 + 146 + KBUILD_EXTMOD_OUTPUT 147 + -------------------- 148 + Specify the output directory for external modules. 149 + 150 + Setting "MO=..." takes precedence over KBUILD_EXTMOD_OUTPUT. 145 151 146 152 KBUILD_EXTRA_WARN 147 153 -----------------
+2 -2
Documentation/kbuild/kconfig-language.rst
··· 412 412 <choice block> 413 413 "endchoice" 414 414 415 - This defines a choice group and accepts any of the above attributes as 416 - options. 415 + This defines a choice group and accepts "prompt", "default", "depends on", and 416 + "help" attributes as options. 417 417 418 418 A choice only allows a single config entry to be selected. 419 419
+14
Documentation/kbuild/makefiles.rst
··· 449 449 to prerequisites are referenced with $(src) (because they are not 450 450 generated files). 451 451 452 + $(srcroot) 453 + $(srcroot) refers to the root of the source you are building, which can be 454 + either the kernel source or the external modules source, depending on whether 455 + KBUILD_EXTMOD is set. This can be either a relative or an absolute path, but 456 + if KBUILD_ABS_SRCTREE=1 is set, it is always an absolute path. 457 + 458 + $(srctree) 459 + $(srctree) refers to the root of the kernel source tree. When building the 460 + kernel, this is the same as $(srcroot). 461 + 462 + $(objtree) 463 + $(objtree) refers to the root of the kernel object tree. It is ``.`` when 464 + building the kernel, but it is different when building external modules. 465 + 452 466 $(kecho) 453 467 echoing information to user in a rule is often a good practice 454 468 but when execution ``make -s`` one does not expect to see any output
+28 -1
Documentation/kbuild/modules.rst
··· 59 59 60 60 $ make -C /lib/modules/`uname -r`/build M=$PWD modules_install 61 61 62 + Starting from Linux 6.13, you can use the -f option instead of -C. This 63 + will avoid unnecessary change of the working directory. The external 64 + module will be output to the directory where you invoke make. 65 + 66 + $ make -f /lib/modules/`uname -r`/build/Makefile M=$PWD 67 + 62 68 Options 63 69 ------- 64 70 ··· 72 66 of the kernel output directory if the kernel was built in a separate 73 67 build directory.) 74 68 75 - make -C $KDIR M=$PWD 69 + You can optionally pass MO= option if you want to build the modules in 70 + a separate directory. 71 + 72 + make -C $KDIR M=$PWD [MO=$BUILD_DIR] 76 73 77 74 -C $KDIR 78 75 The directory that contains the kernel and relevant build ··· 88 79 The value given to "M" is the absolute path of the 89 80 directory where the external module (kbuild file) is 90 81 located. 82 + 83 + MO=$BUILD_DIR 84 + Specifies a separate output directory for the external module. 91 85 92 86 Targets 93 87 ------- ··· 226 214 each file; however, some external modules use makefiles 227 215 consisting of several hundred lines, and here it really pays 228 216 off to separate the kbuild part from the rest. 217 + 218 + Linux 6.13 and later support another way. The external module Makefile 219 + can include the kernel Makefile directly, rather than invoking sub Make. 220 + 221 + Example 3:: 222 + 223 + --> filename: Kbuild 224 + obj-m := 8123.o 225 + 8123-y := 8123_if.o 8123_pci.o 226 + 227 + --> filename: Makefile 228 + KDIR ?= /lib/modules/$(shell uname -r)/build 229 + export KBUILD_EXTMOD := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) 230 + include $(KDIR)/Makefile 231 + 229 232 230 233 Building Multiple Modules 231 234 -------------------------
+14
MAINTAINERS
··· 3715 3715 F: lib/*audit.c 3716 3716 K: \baudit_[a-z_0-9]\+\b 3717 3717 3718 + AUTOFDO BUILD 3719 + M: Rong Xu <xur@google.com> 3720 + M: Han Shen <shenhan@google.com> 3721 + S: Supported 3722 + F: Documentation/dev-tools/autofdo.rst 3723 + F: scripts/Makefile.autofdo 3724 + 3718 3725 AUXILIARY BUS DRIVER 3719 3726 M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> 3720 3727 R: Dave Ertman <david.m.ertman@intel.com> ··· 18714 18707 S: Maintained 18715 18708 F: include/linux/psi* 18716 18709 F: kernel/sched/psi.c 18710 + 18711 + PROPELLER BUILD 18712 + M: Rong Xu <xur@google.com> 18713 + M: Han Shen <shenhan@google.com> 18714 + S: Supported 18715 + F: Documentation/dev-tools/propeller.rst 18716 + F: scripts/Makefile.propeller 18717 18717 18718 18718 PRINTK 18719 18719 M: Petr Mladek <pmladek@suse.com>
+136 -85
Makefile
··· 40 40 41 41 this-makefile := $(lastword $(MAKEFILE_LIST)) 42 42 abs_srctree := $(realpath $(dir $(this-makefile))) 43 - abs_objtree := $(CURDIR) 43 + abs_output := $(CURDIR) 44 44 45 45 ifneq ($(sub_make_done),1) 46 46 ··· 134 134 KBUILD_EXTMOD := $(M) 135 135 endif 136 136 137 + ifeq ("$(origin MO)", "command line") 138 + KBUILD_EXTMOD_OUTPUT := $(MO) 139 + endif 140 + 137 141 $(if $(word 2, $(KBUILD_EXTMOD)), \ 138 142 $(error building multiple external modules is not supported)) 139 143 ··· 180 176 # The O= assignment takes precedence over the KBUILD_OUTPUT environment 181 177 # variable. 182 178 183 - # Do we want to change the working directory? 184 179 ifeq ("$(origin O)", "command line") 185 180 KBUILD_OUTPUT := $(O) 186 181 endif 187 182 188 - ifneq ($(KBUILD_OUTPUT),) 183 + ifdef KBUILD_EXTMOD 184 + ifdef KBUILD_OUTPUT 185 + objtree := $(realpath $(KBUILD_OUTPUT)) 186 + $(if $(objtree),,$(error specified kernel directory "$(KBUILD_OUTPUT)" does not exist)) 187 + else 188 + objtree := $(abs_srctree) 189 + endif 190 + # If Make is invoked from the kernel directory (either kernel 191 + # source directory or kernel build directory), external modules 192 + # are built in $(KBUILD_EXTMOD) for backward compatibility, 193 + # otherwise, built in the current directory. 194 + output := $(or $(KBUILD_EXTMOD_OUTPUT),$(if $(filter $(CURDIR),$(objtree) $(abs_srctree)),$(KBUILD_EXTMOD))) 195 + # KBUILD_EXTMOD might be a relative path. Remember its absolute path before 196 + # Make changes the working directory. 197 + srcroot := $(realpath $(KBUILD_EXTMOD)) 198 + $(if $(srcroot),,$(error specified external module directory "$(KBUILD_EXTMOD)" does not exist)) 199 + else 200 + objtree := . 201 + output := $(KBUILD_OUTPUT) 202 + endif 203 + 204 + export objtree srcroot 205 + 206 + # Do we want to change the working directory? 207 + ifneq ($(output),) 189 208 # $(realpath ...) gets empty if the path does not exist. Run 'mkdir -p' first. 190 - $(shell mkdir -p "$(KBUILD_OUTPUT)") 209 + $(shell mkdir -p "$(output)") 191 210 # $(realpath ...) resolves symlinks 192 - abs_objtree := $(realpath $(KBUILD_OUTPUT)) 193 - $(if $(abs_objtree),,$(error failed to create output directory "$(KBUILD_OUTPUT)")) 194 - endif # ifneq ($(KBUILD_OUTPUT),) 211 + abs_output := $(realpath $(output)) 212 + $(if $(abs_output),,$(error failed to create output directory "$(output)")) 213 + endif 195 214 196 215 ifneq ($(words $(subst :, ,$(abs_srctree))), 1) 197 216 $(error source directory cannot contain spaces or colons) ··· 224 197 225 198 endif # sub_make_done 226 199 227 - ifeq ($(abs_objtree),$(CURDIR)) 200 + ifeq ($(abs_output),$(CURDIR)) 228 201 # Suppress "Entering directory ..." if we are at the final work directory. 229 202 no-print-directory := --no-print-directory 230 203 else ··· 248 221 249 222 # Invoke a second make in the output directory, passing relevant variables 250 223 __sub-make: 251 - $(Q)$(MAKE) $(no-print-directory) -C $(abs_objtree) \ 224 + $(Q)$(MAKE) $(no-print-directory) -C $(abs_output) \ 252 225 -f $(abs_srctree)/Makefile $(MAKECMDGOALS) 253 226 254 227 else # need-sub-make 255 228 256 229 # We process the rest of the Makefile if this is the final invocation of make 257 230 258 - ifeq ($(abs_srctree),$(abs_objtree)) 259 - # building in the source tree 260 - srctree := . 261 - building_out_of_srctree := 231 + ifndef KBUILD_EXTMOD 232 + srcroot := $(abs_srctree) 233 + endif 234 + 235 + ifeq ($(srcroot),$(CURDIR)) 236 + building_out_of_srctree := 262 237 else 263 - ifeq ($(abs_srctree)/,$(dir $(abs_objtree))) 264 - # building in a subdirectory of the source tree 265 - srctree := .. 266 - else 267 - srctree := $(abs_srctree) 268 - endif 269 - building_out_of_srctree := 1 238 + export building_out_of_srctree := 1 270 239 endif 271 240 272 - ifneq ($(KBUILD_ABS_SRCTREE),) 273 - srctree := $(abs_srctree) 241 + ifdef KBUILD_ABS_SRCTREE 242 + # Do nothing. Use the absolute path. 243 + else ifeq ($(srcroot),$(CURDIR)) 244 + # Building in the source. 245 + srcroot := . 246 + else ifeq ($(srcroot)/,$(dir $(CURDIR))) 247 + # Building in a subdirectory of the source. 248 + srcroot := .. 274 249 endif 275 250 276 - objtree := . 251 + export srctree := $(if $(KBUILD_EXTMOD),$(abs_srctree),$(srcroot)) 277 252 278 - VPATH := 279 - 280 - ifeq ($(KBUILD_EXTMOD),) 281 253 ifdef building_out_of_srctree 282 - VPATH := $(srctree) 254 + export VPATH := $(srcroot) 255 + else 256 + VPATH := 283 257 endif 284 - endif 285 - 286 - export building_out_of_srctree srctree objtree VPATH 287 258 288 259 # To make sure we do not include .config for any of the *config targets 289 260 # catch them early, and hand them over to scripts/kconfig/Makefile ··· 301 276 outputmakefile rustavailable rustfmt rustfmtcheck 302 277 no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \ 303 278 image_name 304 - single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %.symtypes %/ 279 + single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/ 305 280 306 281 config-build := 307 282 mixed-build := ··· 379 354 include $(srctree)/scripts/Kbuild.include 380 355 381 356 # Read KERNELRELEASE from include/config/kernel.release (if it exists) 382 - KERNELRELEASE = $(call read-file, include/config/kernel.release) 357 + KERNELRELEASE = $(call read-file, $(objtree)/include/config/kernel.release) 383 358 KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) 384 359 export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION 385 360 ··· 538 513 KBZIP2 = bzip2 539 514 KLZOP = lzop 540 515 LZMA = lzma 541 - LZ4 = lz4c 516 + LZ4 = lz4 542 517 XZ = xz 543 518 ZSTD = zstd 544 519 ··· 568 543 LINUXINCLUDE := \ 569 544 -I$(srctree)/arch/$(SRCARCH)/include \ 570 545 -I$(objtree)/arch/$(SRCARCH)/include/generated \ 571 - $(if $(building_out_of_srctree),-I$(srctree)/include) \ 546 + -I$(srctree)/include \ 572 547 -I$(objtree)/include \ 573 548 $(USERINCLUDE) 574 549 ··· 654 629 # At the same time when output Makefile generated, generate .gitignore to 655 630 # ignore whole output directory 656 631 632 + ifdef KBUILD_EXTMOD 633 + print_env_for_makefile = \ 634 + echo "export KBUILD_OUTPUT = $(objtree)"; \ 635 + echo "export KBUILD_EXTMOD = $(realpath $(srcroot))" ; \ 636 + echo "export KBUILD_EXTMOD_OUTPUT = $(CURDIR)" 637 + else 638 + print_env_for_makefile = \ 639 + echo "export KBUILD_OUTPUT = $(CURDIR)" 640 + endif 641 + 657 642 quiet_cmd_makefile = GEN Makefile 658 643 cmd_makefile = { \ 659 - echo "\# Automatically generated by $(srctree)/Makefile: don't edit"; \ 660 - echo "include $(srctree)/Makefile"; \ 644 + echo "\# Automatically generated by $(abs_srctree)/Makefile: don't edit"; \ 645 + $(print_env_for_makefile); \ 646 + echo "include $(abs_srctree)/Makefile"; \ 661 647 } > Makefile 662 648 663 649 outputmakefile: 650 + ifeq ($(KBUILD_EXTMOD),) 664 651 @if [ -f $(srctree)/.config -o \ 665 652 -d $(srctree)/include/config -o \ 666 653 -d $(srctree)/arch/$(SRCARCH)/include/generated ]; then \ ··· 682 645 echo >&2 "***"; \ 683 646 false; \ 684 647 fi 685 - $(Q)ln -fsn $(srctree) source 648 + else 649 + @if [ -f $(srcroot)/modules.order ]; then \ 650 + echo >&2 "***"; \ 651 + echo >&2 "*** The external module source tree is not clean."; \ 652 + echo >&2 "*** Please run 'make -C $(abs_srctree) M=$(realpath $(srcroot)) clean'"; \ 653 + echo >&2 "***"; \ 654 + false; \ 655 + fi 656 + endif 657 + $(Q)ln -fsn $(srcroot) source 686 658 $(call cmd,makefile) 687 659 $(Q)test -e .gitignore || \ 688 660 { echo "# this is build directory, ignore it"; echo "*"; } > .gitignore ··· 763 717 # in addition to whatever we do anyway. 764 718 # Just "make" or "make all" shall build modules as well 765 719 766 - ifneq ($(filter all modules nsdeps %compile_commands.json clang-%,$(MAKECMDGOALS)),) 720 + ifneq ($(filter all modules nsdeps compile_commands.json clang-%,$(MAKECMDGOALS)),) 767 721 KBUILD_MODULES := 1 768 722 endif 769 723 ··· 774 728 export KBUILD_MODULES KBUILD_BUILTIN 775 729 776 730 ifdef need-config 777 - include include/config/auto.conf 731 + include $(objtree)/include/config/auto.conf 778 732 endif 779 733 780 734 ifeq ($(KBUILD_EXTMOD),) ··· 835 789 else # !may-sync-config 836 790 # External modules and some install targets need include/generated/autoconf.h 837 791 # and include/config/auto.conf but do not care if they are up-to-date. 838 - # Use auto.conf to trigger the test 839 - PHONY += include/config/auto.conf 792 + # Use auto.conf to show the error message 840 793 841 - include/config/auto.conf: 842 - @test -e include/generated/autoconf.h -a -e $@ || ( \ 843 - echo >&2; \ 844 - echo >&2 " ERROR: Kernel configuration is invalid."; \ 845 - echo >&2 " include/generated/autoconf.h or $@ are missing.";\ 846 - echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ 847 - echo >&2 ; \ 848 - /bin/false) 794 + checked-configs := $(addprefix $(objtree)/, include/generated/autoconf.h include/generated/rustc_cfg include/config/auto.conf) 795 + missing-configs := $(filter-out $(wildcard $(checked-configs)), $(checked-configs)) 796 + 797 + ifdef missing-configs 798 + PHONY += $(objtree)/include/config/auto.conf 799 + 800 + $(objtree)/include/config/auto.conf: 801 + @echo >&2 '***' 802 + @echo >&2 '*** ERROR: Kernel configuration is invalid. The following files are missing:' 803 + @printf >&2 '*** - %s\n' $(missing-configs) 804 + @echo >&2 '*** Run "make oldconfig && make prepare" on kernel source to fix it.' 805 + @echo >&2 '***' 806 + @/bin/false 807 + endif 849 808 850 809 endif # may-sync-config 851 810 endif # need-config ··· 1064 1013 KBUILD_CFLAGS += -fconserve-stack 1065 1014 endif 1066 1015 1067 - # change __FILE__ to the relative path from the srctree 1068 - KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) 1016 + # change __FILE__ to the relative path to the source directory 1017 + ifdef building_out_of_srctree 1018 + KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) 1019 + endif 1069 1020 1070 1021 # include additional Makefiles when needed 1071 1022 include-y := scripts/Makefile.extrawarn ··· 1079 1026 include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan 1080 1027 include-$(CONFIG_KCOV) += scripts/Makefile.kcov 1081 1028 include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct 1029 + include-$(CONFIG_AUTOFDO_CLANG) += scripts/Makefile.autofdo 1030 + include-$(CONFIG_PROPELLER_CLANG) += scripts/Makefile.propeller 1082 1031 include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins 1083 1032 1084 1033 include $(addprefix $(srctree)/, $(include-y)) ··· 1160 1105 export MODLIB 1161 1106 1162 1107 PHONY += prepare0 1163 - 1164 - export extmod_prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/) 1165 - export MODORDER := $(extmod_prefix)modules.order 1166 - export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps 1167 1108 1168 1109 ifeq ($(KBUILD_EXTMOD),) 1169 1110 ··· 1255 1204 1256 1205 archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \ 1257 1206 asm-generic $(version_h) include/generated/utsrelease.h \ 1258 - include/generated/compile.h include/generated/autoconf.h remove-stale-files 1207 + include/generated/compile.h include/generated/autoconf.h \ 1208 + include/generated/rustc_cfg remove-stale-files 1259 1209 1260 1210 prepare0: archprepare 1261 1211 $(Q)$(MAKE) $(build)=scripts/mod ··· 1487 1435 all: dtbs 1488 1436 endif 1489 1437 1438 + ifdef CONFIG_GENERIC_BUILTIN_DTB 1439 + vmlinux: dtbs 1440 + endif 1441 + 1490 1442 endif 1491 1443 1492 1444 PHONY += scripts_dtc ··· 1558 1502 modules.builtin modules.builtin.modinfo modules.nsdeps \ 1559 1503 modules.builtin.ranges vmlinux.o.map \ 1560 1504 compile_commands.json rust/test \ 1561 - rust-project.json .vmlinux.objs .vmlinux.export.c 1505 + rust-project.json .vmlinux.objs .vmlinux.export.c \ 1506 + .builtin-dtbs-list .builtin-dtb.S 1562 1507 1563 1508 # Directories & files removed with 'make mrproper' 1564 1509 MRPROPER_FILES += include/config include/generated \ ··· 1807 1750 # Formatting targets 1808 1751 PHONY += rustfmt rustfmtcheck 1809 1752 1810 - # We skip `rust/alloc` since we want to minimize the diff w.r.t. upstream. 1811 - # 1812 - # We match using absolute paths since `find` does not resolve them 1813 - # when matching, which is a problem when e.g. `srctree` is `..`. 1814 - # We `grep` afterwards in order to remove the directory entry itself. 1815 1753 rustfmt: 1816 - $(Q)find $(abs_srctree) -type f -name '*.rs' \ 1817 - -o -path $(abs_srctree)/rust/alloc -prune \ 1818 - -o -path $(abs_objtree)/rust/test -prune \ 1819 - | grep -Fv $(abs_srctree)/rust/alloc \ 1820 - | grep -Fv $(abs_objtree)/rust/test \ 1821 - | grep -Fv generated \ 1754 + $(Q)find $(srctree) $(RCS_FIND_IGNORE) \ 1755 + -type f -a -name '*.rs' -a ! -name '*generated*' -print \ 1822 1756 | xargs $(RUSTFMT) $(rustfmt_flags) 1823 1757 1824 1758 rustfmtcheck: rustfmt_flags = --check ··· 1848 1800 KBUILD_BUILTIN := 1849 1801 KBUILD_MODULES := 1 1850 1802 1851 - build-dir := $(KBUILD_EXTMOD) 1803 + build-dir := . 1852 1804 1853 - compile_commands.json: $(extmod_prefix)compile_commands.json 1854 - PHONY += compile_commands.json 1855 - 1856 - clean-dirs := $(KBUILD_EXTMOD) 1857 - clean: private rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \ 1858 - $(KBUILD_EXTMOD)/compile_commands.json 1805 + clean-dirs := . 1806 + clean: private rm-files := Module.symvers modules.nsdeps compile_commands.json 1859 1807 1860 1808 PHONY += prepare 1861 1809 # now expand this into a simple variable to reduce the cost of shell evaluations ··· 1910 1866 1911 1867 ifdef CONFIG_MODULES 1912 1868 1913 - $(MODORDER): $(build-dir) 1869 + modules.order: $(build-dir) 1914 1870 @: 1915 1871 1916 1872 # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. ··· 1921 1877 endif 1922 1878 1923 1879 PHONY += modules_check 1924 - modules_check: $(MODORDER) 1880 + modules_check: modules.order 1925 1881 $(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh $< 1926 1882 1927 1883 else # CONFIG_MODULES ··· 1962 1918 $(single-no-ko): $(build-dir) 1963 1919 @: 1964 1920 1965 - # Remove MODORDER when done because it is not the real one. 1921 + # Remove modules.order when done because it is not the real one. 1966 1922 PHONY += single_modules 1967 1923 single_modules: $(single-no-ko) modules_prepare 1968 - $(Q){ $(foreach m, $(single-ko), echo $(extmod_prefix)$(m:%.ko=%.o);) } > $(MODORDER) 1924 + $(Q){ $(foreach m, $(single-ko), echo $(m:%.ko=%.o);) } > modules.order 1969 1925 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost 1970 1926 ifneq ($(KBUILD_MODPOST_NOFINAL),1) 1971 1927 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal 1972 1928 endif 1973 - $(Q)rm -f $(MODORDER) 1929 + $(Q)rm -f modules.order 1974 1930 1975 1931 single-goals := $(addprefix $(build-dir)/, $(single-no-ko)) 1976 1932 1977 1933 KBUILD_MODULES := 1 1978 1934 1979 1935 endif 1936 + 1937 + prepare: outputmakefile 1980 1938 1981 1939 # Preset locale variables to speed up the build process. Limit locale 1982 1940 # tweaks to this spot to avoid wrong language settings when running ··· 1995 1949 1996 1950 clean: $(clean-dirs) 1997 1951 $(call cmd,rmfiles) 1998 - @find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ 1952 + @find . $(RCS_FIND_IGNORE) \ 1999 1953 \( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \ 2000 1954 -o -name '*.ko.*' \ 2001 1955 -o -name '*.dtb' -o -name '*.dtbo' \ ··· 2028 1982 PHONY += rust-analyzer 2029 1983 rust-analyzer: 2030 1984 +$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh 1985 + ifdef KBUILD_EXTMOD 1986 + # FIXME: external modules must not descend into a sub-directory of the kernel 1987 + $(Q)$(MAKE) $(build)=$(objtree)/rust src=$(srctree)/rust $@ 1988 + else 2031 1989 $(Q)$(MAKE) $(build)=rust $@ 1990 + endif 2032 1991 2033 1992 # Script to generate missing namespace dependencies 2034 1993 # --------------------------------------------------------------------------- ··· 2049 1998 quiet_cmd_gen_compile_commands = GEN $@ 2050 1999 cmd_gen_compile_commands = $(PYTHON3) $< -a $(AR) -o $@ $(filter-out $<, $(real-prereqs)) 2051 2000 2052 - $(extmod_prefix)compile_commands.json: $(srctree)/scripts/clang-tools/gen_compile_commands.py \ 2001 + compile_commands.json: $(srctree)/scripts/clang-tools/gen_compile_commands.py \ 2053 2002 $(if $(KBUILD_EXTMOD),, vmlinux.a $(KBUILD_VMLINUX_LIBS)) \ 2054 - $(if $(CONFIG_MODULES), $(MODORDER)) FORCE 2003 + $(if $(CONFIG_MODULES), modules.order) FORCE 2055 2004 $(call if_changed,gen_compile_commands) 2056 2005 2057 - targets += $(extmod_prefix)compile_commands.json 2006 + targets += compile_commands.json 2058 2007 2059 2008 PHONY += clang-tidy clang-analyzer 2060 2009 ··· 2062 2011 quiet_cmd_clang_tools = CHECK $< 2063 2012 cmd_clang_tools = $(PYTHON3) $(srctree)/scripts/clang-tools/run-clang-tools.py $@ $< 2064 2013 2065 - clang-tidy clang-analyzer: $(extmod_prefix)compile_commands.json 2014 + clang-tidy clang-analyzer: compile_commands.json 2066 2015 $(call cmd,clang_tools) 2067 2016 else 2068 2017 clang-tidy clang-analyzer:
+39
arch/Kconfig
··· 812 812 If unsure, say Y. 813 813 endchoice 814 814 815 + config ARCH_SUPPORTS_AUTOFDO_CLANG 816 + bool 817 + 818 + config AUTOFDO_CLANG 819 + bool "Enable Clang's AutoFDO build (EXPERIMENTAL)" 820 + depends on ARCH_SUPPORTS_AUTOFDO_CLANG 821 + depends on CC_IS_CLANG && CLANG_VERSION >= 170000 822 + help 823 + This option enables Clang’s AutoFDO build. When 824 + an AutoFDO profile is specified in variable 825 + CLANG_AUTOFDO_PROFILE during the build process, 826 + Clang uses the profile to optimize the kernel. 827 + 828 + If no profile is specified, AutoFDO options are 829 + still passed to Clang to facilitate the collection 830 + of perf data for creating an AutoFDO profile in 831 + subsequent builds. 832 + 833 + If unsure, say N. 834 + 835 + config ARCH_SUPPORTS_PROPELLER_CLANG 836 + bool 837 + 838 + config PROPELLER_CLANG 839 + bool "Enable Clang's Propeller build" 840 + depends on ARCH_SUPPORTS_PROPELLER_CLANG 841 + depends on CC_IS_CLANG && CLANG_VERSION >= 190000 842 + help 843 + This option enables Clang’s Propeller build. When the Propeller 844 + profiles is specified in variable CLANG_PROPELLER_PROFILE_PREFIX 845 + during the build process, Clang uses the profiles to optimize 846 + the kernel. 847 + 848 + If no profile is specified, Propeller options are still passed 849 + to Clang to facilitate the collection of perf data for creating 850 + the Propeller profiles in subsequent builds. 851 + 852 + If unsure, say N. 853 + 815 854 config ARCH_SUPPORTS_CFI_CLANG 816 855 bool 817 856 help
+2 -2
arch/arm/Makefile
··· 264 264 -mstack-protector-guard=tls \ 265 265 -mstack-protector-guard-offset=$(shell \ 266 266 awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\ 267 - include/generated/asm-offsets.h)) 267 + $(objtree)/include/generated/asm-offsets.h)) 268 268 else 269 269 stack_protector_prepare: prepare0 270 270 $(eval SSP_PLUGIN_CFLAGS := \ 271 271 -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ 272 272 awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\ 273 - include/generated/asm-offsets.h)) 273 + $(objtree)/include/generated/asm-offsets.h)) 274 274 $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) 275 275 $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) 276 276 endif
+1 -1
arch/arm64/Makefile
··· 71 71 -mstack-protector-guard-reg=sp_el0 \ 72 72 -mstack-protector-guard-offset=$(shell \ 73 73 awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ 74 - include/generated/asm-offsets.h)) 74 + $(objtree)/include/generated/asm-offsets.h)) 75 75 endif 76 76 77 77 ifeq ($(CONFIG_ARM64_BTI_KERNEL),y)
+1
arch/mips/kernel/head.S
··· 59 59 #endif 60 60 .endm 61 61 62 + __HEAD 62 63 #ifndef CONFIG_NO_EXCEPT_FILL 63 64 /* 64 65 * Reserved space for exception handlers.
+1
arch/mips/kernel/vmlinux.lds.S
··· 61 61 /* read-only */ 62 62 _text = .; /* Text and read-only data */ 63 63 .text : { 64 + HEAD_TEXT 64 65 TEXT_TEXT 65 66 SCHED_TEXT 66 67 LOCK_TEXT
+4 -2
arch/powerpc/Makefile
··· 403 403 stack_protector_prepare: prepare0 404 404 ifdef CONFIG_PPC64 405 405 $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 \ 406 - -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h)) 406 + -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' \ 407 + $(objtree)/include/generated/asm-offsets.h)) 407 408 else 408 409 $(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \ 409 - -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h)) 410 + -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' \ 411 + $(objtree)/include/generated/asm-offsets.h)) 410 412 endif 411 413 endif 412 414
+1 -1
arch/riscv/Makefile
··· 135 135 -mstack-protector-guard-reg=tp \ 136 136 -mstack-protector-guard-offset=$(shell \ 137 137 awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \ 138 - include/generated/asm-offsets.h)) 138 + $(objtree)/include/generated/asm-offsets.h)) 139 139 endif 140 140 141 141 # arch specific predefines for sparse
+5
arch/sparc/kernel/vmlinux.lds.S
··· 48 48 { 49 49 _text = .; 50 50 HEAD_TEXT 51 + ALIGN_FUNCTION(); 52 + #ifdef CONFIG_SPARC64 53 + /* Match text section symbols in head_64.S first */ 54 + *head_64.o(.text) 55 + #endif 51 56 TEXT_TEXT 52 57 SCHED_TEXT 53 58 LOCK_TEXT
+2
arch/x86/Kconfig
··· 128 128 select ARCH_SUPPORTS_LTO_CLANG 129 129 select ARCH_SUPPORTS_LTO_CLANG_THIN 130 130 select ARCH_SUPPORTS_RT 131 + select ARCH_SUPPORTS_AUTOFDO_CLANG 132 + select ARCH_SUPPORTS_PROPELLER_CLANG if X86_64 131 133 select ARCH_USE_BUILTIN_BSWAP 132 134 select ARCH_USE_CMPXCHG_LOCKREF if X86_CMPXCHG64 133 135 select ARCH_USE_MEMTEST
+4
arch/x86/kernel/vmlinux.lds.S
··· 420 420 421 421 STABS_DEBUG 422 422 DWARF_DEBUG 423 + #ifdef CONFIG_PROPELLER_CLANG 424 + .llvm_bb_addr_map : { *(.llvm_bb_addr_map) } 425 + #endif 426 + 423 427 ELF_DETAILS 424 428 425 429 DISCARDS
+1 -3
drivers/accessibility/speakup/Makefile
··· 40 40 makemapdata-objs := makemapdata.o 41 41 42 42 quiet_cmd_mkmap = MKMAP $@ 43 - cmd_mkmap = TOPDIR=$(srctree) \ 44 - SPKDIR=$(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD),$(srctree)/drivers/accessibility/speakup) \ 45 - $(obj)/makemapdata > $@ 43 + cmd_mkmap = TOPDIR=$(srctree) SPKDIR=$(src) $(obj)/makemapdata > $@ 46 44 47 45 $(obj)/mapdata.h: $(obj)/makemapdata 48 46 $(call cmd,mkmap)
+6
drivers/of/Kconfig
··· 2 2 config DTC 3 3 bool 4 4 5 + config GENERIC_BUILTIN_DTB 6 + bool 7 + 8 + config BUILTIN_DTB_ALL 9 + bool 10 + 5 11 menuconfig OF 6 12 bool "Device Tree and Open Firmware support" 7 13 help
+1 -1
drivers/usb/dwc2/Kconfig
··· 21 21 if USB_DWC2 22 22 23 23 choice 24 - bool "DWC2 Mode Selection" 24 + prompt "DWC2 Mode Selection" 25 25 default USB_DWC2_DUAL_ROLE if (USB && USB_GADGET) 26 26 default USB_DWC2_HOST if (USB && !USB_GADGET) 27 27 default USB_DWC2_PERIPHERAL if (!USB && USB_GADGET)
+1 -1
drivers/usb/dwc3/Kconfig
··· 23 23 controller. 24 24 25 25 choice 26 - bool "DWC3 Mode Selection" 26 + prompt "DWC3 Mode Selection" 27 27 default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET) 28 28 default USB_DWC3_HOST if (USB && !USB_GADGET) 29 29 default USB_DWC3_GADGET if (!USB && USB_GADGET)
+1 -1
drivers/usb/isp1760/Kconfig
··· 26 26 if USB_ISP1760 27 27 28 28 choice 29 - bool "ISP1760 Mode Selection" 29 + prompt "ISP1760 Mode Selection" 30 30 default USB_ISP1760_DUAL_ROLE if (USB && USB_GADGET) 31 31 default USB_ISP1760_HOST_ROLE if (USB && !USB_GADGET) 32 32 default USB_ISP1760_GADGET_ROLE if (!USB && USB_GADGET)
+1 -1
drivers/usb/mtu3/Kconfig
··· 21 21 22 22 if USB_MTU3 23 23 choice 24 - bool "MTU3 Mode Selection" 24 + prompt "MTU3 Mode Selection" 25 25 default USB_MTU3_DUAL_ROLE if (USB && USB_GADGET) 26 26 default USB_MTU3_HOST if (USB && !USB_GADGET) 27 27 default USB_MTU3_GADGET if (!USB && USB_GADGET)
+1 -1
drivers/usb/musb/Kconfig
··· 29 29 if USB_MUSB_HDRC 30 30 31 31 choice 32 - bool "MUSB Mode Selection" 32 + prompt "MUSB Mode Selection" 33 33 default USB_MUSB_DUAL_ROLE if (USB && USB_GADGET) 34 34 default USB_MUSB_HOST if (USB && !USB_GADGET) 35 35 default USB_MUSB_GADGET if (!USB && USB_GADGET)
+40 -13
include/asm-generic/vmlinux.lds.h
··· 95 95 * With LTO_CLANG, the linker also splits sections by default, so we need 96 96 * these macros to combine the sections during the final link. 97 97 * 98 + * With AUTOFDO_CLANG and PROPELLER_CLANG, by default, the linker splits 99 + * text sections and regroups functions into subsections. 100 + * 98 101 * RODATA_MAIN is not used because existing code already defines .rodata.x 99 102 * sections to be brought in with rodata. 100 103 */ 101 - #if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) 104 + #if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) || \ 105 + defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) 102 106 #define TEXT_MAIN .text .text.[0-9a-zA-Z_]* 107 + #else 108 + #define TEXT_MAIN .text 109 + #endif 110 + #if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) 103 111 #define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* .data.$__unnamed_* .data.$L* 104 112 #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* 105 113 #define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L* 106 114 #define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..L* .bss..compoundliteral* 107 115 #define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]* 108 116 #else 109 - #define TEXT_MAIN .text 110 117 #define DATA_MAIN .data 111 118 #define SDATA_MAIN .sdata 112 119 #define RODATA_MAIN .rodata ··· 357 350 *(.data..decrypted) \ 358 351 *(.ref.data) \ 359 352 *(.data..shared_aligned) /* percpu related */ \ 360 - *(.data.unlikely) \ 353 + *(.data..unlikely) \ 361 354 __start_once = .; \ 362 - *(.data.once) \ 355 + *(.data..once) \ 363 356 __end_once = .; \ 364 357 STRUCT_ALIGN(); \ 365 358 *(__tracepoints) \ ··· 556 549 __cpuidle_text_end = .; \ 557 550 __noinstr_text_end = .; 558 551 552 + #define TEXT_SPLIT \ 553 + __split_text_start = .; \ 554 + *(.text.split .text.split.[0-9a-zA-Z_]*) \ 555 + __split_text_end = .; 556 + 557 + #define TEXT_UNLIKELY \ 558 + __unlikely_text_start = .; \ 559 + *(.text.unlikely .text.unlikely.*) \ 560 + __unlikely_text_end = .; 561 + 562 + #define TEXT_HOT \ 563 + __hot_text_start = .; \ 564 + *(.text.hot .text.hot.*) \ 565 + __hot_text_end = .; 566 + 559 567 /* 560 568 * .text section. Map to function alignment to avoid address changes 561 569 * during second ld run in second ld pass when generating System.map 562 570 * 563 - * TEXT_MAIN here will match .text.fixup and .text.unlikely if dead 564 - * code elimination is enabled, so these sections should be converted 565 - * to use ".." first. 571 + * TEXT_MAIN here will match symbols with a fixed pattern (for example, 572 + * .text.hot or .text.unlikely) if dead code elimination or 573 + * function-section is enabled. Match these symbols first before 574 + * TEXT_MAIN to ensure they are grouped together. 575 + * 576 + * Also placing .text.hot section at the beginning of a page, this 577 + * would help the TLB performance. 566 578 */ 567 579 #define TEXT_TEXT \ 568 580 ALIGN_FUNCTION(); \ 569 - *(.text.hot .text.hot.*) \ 570 - *(TEXT_MAIN .text.fixup) \ 571 - *(.text.unlikely .text.unlikely.*) \ 581 + *(.text.asan.* .text.tsan.*) \ 572 582 *(.text.unknown .text.unknown.*) \ 583 + TEXT_SPLIT \ 584 + TEXT_UNLIKELY \ 585 + . = ALIGN(PAGE_SIZE); \ 586 + TEXT_HOT \ 587 + *(TEXT_MAIN .text.fixup) \ 573 588 NOINSTR_TEXT \ 574 - *(.ref.text) \ 575 - *(.text.asan.* .text.tsan.*) 576 - 589 + *(.ref.text) 577 590 578 591 /* sched.text is aling to function alignment to secure we have same 579 592 * address even at second ld pass when generating System.map */
+3 -3
include/linux/mmdebug.h
··· 46 46 } \ 47 47 } while (0) 48 48 #define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \ 49 - static bool __section(".data.once") __warned; \ 49 + static bool __section(".data..once") __warned; \ 50 50 int __ret_warn_once = !!(cond); \ 51 51 \ 52 52 if (unlikely(__ret_warn_once && !__warned)) { \ ··· 66 66 unlikely(__ret_warn); \ 67 67 }) 68 68 #define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \ 69 - static bool __section(".data.once") __warned; \ 69 + static bool __section(".data..once") __warned; \ 70 70 int __ret_warn_once = !!(cond); \ 71 71 \ 72 72 if (unlikely(__ret_warn_once && !__warned)) { \ ··· 77 77 unlikely(__ret_warn_once); \ 78 78 }) 79 79 #define VM_WARN_ON_ONCE_MM(cond, mm) ({ \ 80 - static bool __section(".data.once") __warned; \ 80 + static bool __section(".data..once") __warned; \ 81 81 int __ret_warn_once = !!(cond); \ 82 82 \ 83 83 if (unlikely(__ret_warn_once && !__warned)) { \
+1 -1
include/linux/module.h
··· 247 247 #ifdef MODULE 248 248 /* Creates an alias so file2alias.c can find device table. */ 249 249 #define MODULE_DEVICE_TABLE(type, name) \ 250 - extern typeof(name) __mod_##type##__##name##_device_table \ 250 + extern typeof(name) __mod_device_table__##type##__##name \ 251 251 __attribute__ ((unused, alias(__stringify(name)))) 252 252 #else /* !MODULE */ 253 253 #define MODULE_DEVICE_TABLE(type, name)
+2 -2
include/linux/once.h
··· 46 46 #define DO_ONCE(func, ...) \ 47 47 ({ \ 48 48 bool ___ret = false; \ 49 - static bool __section(".data.once") ___done = false; \ 49 + static bool __section(".data..once") ___done = false; \ 50 50 static DEFINE_STATIC_KEY_TRUE(___once_key); \ 51 51 if (static_branch_unlikely(&___once_key)) { \ 52 52 unsigned long ___flags; \ ··· 64 64 #define DO_ONCE_SLEEPABLE(func, ...) \ 65 65 ({ \ 66 66 bool ___ret = false; \ 67 - static bool __section(".data.once") ___done = false; \ 67 + static bool __section(".data..once") ___done = false; \ 68 68 static DEFINE_STATIC_KEY_TRUE(___once_key); \ 69 69 if (static_branch_unlikely(&___once_key)) { \ 70 70 ___ret = __do_once_sleepable_start(&___done); \
+1 -1
include/linux/once_lite.h
··· 12 12 13 13 #define __ONCE_LITE_IF(condition) \ 14 14 ({ \ 15 - static bool __section(".data.once") __already_done; \ 15 + static bool __section(".data..once") __already_done; \ 16 16 bool __ret_cond = !!(condition); \ 17 17 bool __ret_once = false; \ 18 18 \
+1 -1
include/linux/rcupdate.h
··· 401 401 */ 402 402 #define RCU_LOCKDEP_WARN(c, s) \ 403 403 do { \ 404 - static bool __section(".data.unlikely") __warned; \ 404 + static bool __section(".data..unlikely") __warned; \ 405 405 if (debug_lockdep_rcu_enabled() && (c) && \ 406 406 debug_lockdep_rcu_enabled() && !__warned) { \ 407 407 __warned = true; \
+1 -1
include/net/net_debug.h
··· 27 27 28 28 #define netdev_level_once(level, dev, fmt, ...) \ 29 29 do { \ 30 - static bool __section(".data.once") __print_once; \ 30 + static bool __section(".data..once") __print_once; \ 31 31 \ 32 32 if (!__print_once) { \ 33 33 __print_once = true; \
+1 -1
mm/internal.h
··· 49 49 * when we specify __GFP_NOWARN. 50 50 */ 51 51 #define WARN_ON_ONCE_GFP(cond, gfp) ({ \ 52 - static bool __section(".data.once") __warned; \ 52 + static bool __section(".data..once") __warned; \ 53 53 int __ret_warn_once = !!(cond); \ 54 54 \ 55 55 if (unlikely(!(gfp & __GFP_NOWARN) && __ret_warn_once && !__warned)) { \
+2 -2
rust/Makefile
··· 372 372 $(Q)$(srctree)/scripts/generate_rust_analyzer.py \ 373 373 --cfgs='core=$(core-cfgs)' \ 374 374 $(realpath $(srctree)) $(realpath $(objtree)) \ 375 - $(rustc_sysroot) $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \ 376 - $(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json 375 + $(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \ 376 + > rust-project.json 377 377 378 378 redirect-intrinsics = \ 379 379 __addsf3 __eqsf2 __extendsfdf2 __gesf2 __lesf2 __ltsf2 __mulsf3 __nesf2 __truncdfsf2 __unordsf2 \
+1 -1
scripts/Kbuild.include
··· 205 205 206 206 cmd_and_fixdep = \ 207 207 $(cmd); \ 208 - scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\ 208 + $(objtree)/scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\ 209 209 rm -f $(depfile) 210 210 211 211 # Usage: $(call if_changed_rule,foo)
+24
scripts/Makefile.autofdo
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + # Enable available and selected Clang AutoFDO features. 4 + 5 + CFLAGS_AUTOFDO_CLANG := -fdebug-info-for-profiling -mllvm -enable-fs-discriminator=true -mllvm -improved-fs-discriminator=true 6 + 7 + ifndef CONFIG_DEBUG_INFO 8 + CFLAGS_AUTOFDO_CLANG += -gmlt 9 + endif 10 + 11 + ifdef CLANG_AUTOFDO_PROFILE 12 + CFLAGS_AUTOFDO_CLANG += -fprofile-sample-use=$(CLANG_AUTOFDO_PROFILE) -ffunction-sections 13 + CFLAGS_AUTOFDO_CLANG += -fsplit-machine-functions 14 + endif 15 + 16 + ifdef CONFIG_LTO_CLANG_THIN 17 + ifdef CLANG_AUTOFDO_PROFILE 18 + KBUILD_LDFLAGS += --lto-sample-profile=$(CLANG_AUTOFDO_PROFILE) 19 + endif 20 + KBUILD_LDFLAGS += --mllvm=-enable-fs-discriminator=true --mllvm=-improved-fs-discriminator=true -plugin-opt=thinlto 21 + KBUILD_LDFLAGS += -plugin-opt=-split-machine-functions 22 + endif 23 + 24 + export CFLAGS_AUTOFDO_CLANG
+7 -52
scripts/Makefile.build
··· 3 3 # Building 4 4 # ========================================================================== 5 5 6 - src := $(if $(VPATH),$(VPATH)/)$(obj) 6 + src := $(srcroot)/$(obj) 7 7 8 8 PHONY := $(obj)/ 9 9 $(obj)/: ··· 34 34 subdir-ccflags-y := 35 35 36 36 # Read auto.conf if it exists, otherwise ignore 37 - -include include/config/auto.conf 37 + -include $(objtree)/include/config/auto.conf 38 38 39 39 include $(srctree)/scripts/Kbuild.include 40 40 include $(srctree)/scripts/Makefile.compiler ··· 107 107 $(obj)/%.i: $(obj)/%.c FORCE 108 108 $(call if_changed_dep,cpp_i_c) 109 109 110 - genksyms = scripts/genksyms/genksyms \ 111 - $(if $(1), -T $(2)) \ 112 - $(if $(KBUILD_PRESERVE), -p) \ 113 - -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) 110 + genksyms = $(objtree)/scripts/genksyms/genksyms \ 111 + $(if $(KBUILD_SYMTYPES), -T $(@:.o=.symtypes)) \ 112 + $(if $(KBUILD_PRESERVE), -p) \ 113 + $(addprefix -r , $(wildcard $(@:.o=.symref))) 114 114 115 115 # These mirror gensymtypes_S and co below, keep them in synch. 116 116 cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) 117 - 118 - quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ 119 - cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null 120 - 121 - $(obj)/%.symtypes : $(obj)/%.c FORCE 122 - $(call cmd,cc_symtypes_c) 123 117 124 118 # LLVM assembly 125 119 # Generate .ll files from .c ··· 129 135 130 136 is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y) 131 137 132 - # When a module consists of a single object, there is no reason to keep LLVM IR. 133 - # Make $(LD) covert LLVM IR to ELF here. 134 - ifdef CONFIG_LTO_CLANG 135 - cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) 136 - endif 137 - 138 - quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ 139 - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ 140 - $(cmd_ld_single_m) \ 141 - $(cmd_objtool) 142 - 143 138 ifdef CONFIG_MODVERSIONS 144 139 # When module versioning is enabled the following steps are executed: 145 140 # o compile a <file>.o from <file>.c ··· 141 158 142 159 gen_symversions = \ 143 160 if $(NM) $@ 2>/dev/null | grep -q ' __export_symbol_'; then \ 144 - $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ 145 - >> $(dot-target).cmd; \ 161 + $(cmd_gensymtypes_$1) >> $(dot-target).cmd; \ 146 162 fi 147 163 148 164 cmd_gen_symversions_c = $(call gen_symversions,c) ··· 188 206 ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),) 189 207 cmd_warn_shared_object = $(if $(word 2, $(modname-multi)),$(warning $(kbuild-file): $*.o is added to multiple modules: $(modname-multi))) 190 208 endif 191 - 192 - define rule_cc_o_c 193 - $(call cmd_and_fixdep,cc_o_c) 194 - $(call cmd,checksrc) 195 - $(call cmd,checkdoc) 196 - $(call cmd,gen_objtooldep) 197 - $(call cmd,gen_symversions_c) 198 - $(call cmd,record_mcount) 199 - $(call cmd,warn_shared_object) 200 - endef 201 - 202 - define rule_as_o_S 203 - $(call cmd_and_fixdep,as_o_S) 204 - $(call cmd,gen_objtooldep) 205 - $(call cmd,gen_symversions_S) 206 - $(call cmd,warn_shared_object) 207 - endef 208 209 209 210 # Built-in and composite module parts 210 211 $(obj)/%.o: $(obj)/%.c $(recordmcount_source) FORCE ··· 295 330 $(NM) $@ | sed -n 's/.* __export_symbol_\(.*\)/EXPORT_SYMBOL(\1);/p' ; } | \ 296 331 $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) 297 332 298 - quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ 299 - cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null 300 - 301 - $(obj)/%.symtypes : $(obj)/%.S FORCE 302 - $(call cmd,cc_symtypes_S) 303 - 304 - 305 333 quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@ 306 334 cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< 307 335 308 336 $(obj)/%.s: $(obj)/%.S FORCE 309 337 $(call if_changed_dep,cpp_s_S) 310 - 311 - quiet_cmd_as_o_S = AS $(quiet_modtag) $@ 312 - cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) 313 338 314 339 ifdef CONFIG_ASM_MODVERSIONS 315 340
+1 -1
scripts/Makefile.clean
··· 3 3 # Cleaning up 4 4 # ========================================================================== 5 5 6 - src := $(if $(VPATH),$(VPATH)/)$(obj) 6 + src := $(srcroot)/$(obj) 7 7 8 8 PHONY := __clean 9 9 __clean:
+1 -1
scripts/Makefile.compiler
··· 13 13 $(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c)))) 14 14 15 15 # output directory for tests below 16 - TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$ 16 + TMPOUT = .tmp_$$$$ 17 17 18 18 # try-run 19 19 # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
+3 -5
scripts/Makefile.host
··· 96 96 $(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \ 97 97 $(HOSTRUSTFLAGS_$(target-stem)) 98 98 99 - # $(objtree)/$(obj) for including generated headers from checkin source files 100 - ifeq ($(KBUILD_EXTMOD),) 99 + # $(obj) for including generated headers from checkin source files 101 100 ifdef building_out_of_srctree 102 - hostc_flags += -I $(objtree)/$(obj) 103 - hostcxx_flags += -I $(objtree)/$(obj) 104 - endif 101 + hostc_flags += -I $(obj) 102 + hostcxx_flags += -I $(obj) 105 103 endif 106 104 107 105 #####
+58 -4
scripts/Makefile.lib
··· 191 191 -D__KCSAN_INSTRUMENT_BARRIERS__) 192 192 endif 193 193 194 + # 195 + # Enable AutoFDO build flags except some files or directories we don't want to 196 + # enable (depends on variables AUTOFDO_PROFILE_obj.o and AUTOFDO_PROFILE). 197 + # 198 + ifeq ($(CONFIG_AUTOFDO_CLANG),y) 199 + _c_flags += $(if $(patsubst n%,, \ 200 + $(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(is-kernel-object)), \ 201 + $(CFLAGS_AUTOFDO_CLANG)) 202 + endif 203 + 204 + # 205 + # Enable Propeller build flags except some files or directories we don't want to 206 + # enable (depends on variables AUTOFDO_PROPELLER_obj.o and PROPELLER_PROFILE). 207 + # 208 + ifdef CONFIG_PROPELLER_CLANG 209 + _c_flags += $(if $(patsubst n%,, \ 210 + $(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(PROPELLER_PROFILE))$(is-kernel-object), \ 211 + $(CFLAGS_PROPELLER_CLANG)) 212 + endif 213 + 194 214 # $(src) for including checkin headers from generated source files 195 215 # $(obj) for including generated headers from checkin source files 196 - ifeq ($(KBUILD_EXTMOD),) 197 216 ifdef building_out_of_srctree 198 217 _c_flags += $(addprefix -I, $(src) $(obj)) 199 218 _a_flags += $(addprefix -I, $(src) $(obj)) 200 219 _cpp_flags += $(addprefix -I, $(src) $(obj)) 201 - endif 202 220 endif 203 221 204 222 # If $(is-kernel-object) is 'y', this object will be linked to vmlinux or modules ··· 296 278 $(foreach m, $1, \ 297 279 $(eval $m: \ 298 280 $(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3)))) 281 + endef 282 + 283 + # Build commands 284 + # =========================================================================== 285 + # These are shared by some Makefile.* files. 286 + 287 + objtool-enabled := y 288 + 289 + ifdef CONFIG_LTO_CLANG 290 + # objtool cannot process LLVM IR. Make $(LD) covert LLVM IR to ELF here. 291 + cmd_ld_single = $(if $(objtool-enabled), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) 292 + endif 293 + 294 + quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ 295 + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \ 296 + $(cmd_ld_single) \ 297 + $(cmd_objtool) 298 + 299 + define rule_cc_o_c 300 + $(call cmd_and_fixdep,cc_o_c) 301 + $(call cmd,checksrc) 302 + $(call cmd,checkdoc) 303 + $(call cmd,gen_objtooldep) 304 + $(call cmd,gen_symversions_c) 305 + $(call cmd,record_mcount) 306 + $(call cmd,warn_shared_object) 307 + endef 308 + 309 + quiet_cmd_as_o_S = AS $(quiet_modtag) $@ 310 + cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool) 311 + 312 + define rule_as_o_S 313 + $(call cmd_and_fixdep,as_o_S) 314 + $(call cmd,gen_objtooldep) 315 + $(call cmd,gen_symversions_S) 316 + $(call cmd,warn_shared_object) 299 317 endef 300 318 301 319 # Copy a file ··· 425 371 cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@ 426 372 427 373 quiet_cmd_lz4 = LZ4 $@ 428 - cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout > $@ 374 + cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -9 - - > $@ 429 375 430 376 quiet_cmd_lz4_with_size = LZ4 $@ 431 - cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \ 377 + cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -9 - -; \ 432 378 $(size_append); } > $@ 433 379 434 380 # U-Boot mkimage
+13 -18
scripts/Makefile.modfinal
··· 6 6 PHONY := __modfinal 7 7 __modfinal: 8 8 9 - include include/config/auto.conf 9 + include $(objtree)/include/config/auto.conf 10 10 include $(srctree)/scripts/Kbuild.include 11 - 12 - # for c_flags 13 11 include $(srctree)/scripts/Makefile.lib 14 12 15 13 # find all modules listed in modules.order 16 - modules := $(call read-file, $(MODORDER)) 14 + modules := $(call read-file, modules.order) 17 15 18 16 __modfinal: $(modules:%.o=%.ko) 19 17 @: ··· 20 22 modname = $(notdir $(@:.mod.o=)) 21 23 part-of-module = y 22 24 GCOV_PROFILE := n 23 - KCSAN_SANITIZE := n 24 - 25 - quiet_cmd_cc_o_c = CC [M] $@ 26 - cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $< 25 + ccflags-remove-y := $(CC_FLAGS_CFI) 27 26 28 27 %.mod.o: %.mod.c FORCE 29 - $(call if_changed_dep,cc_o_c) 28 + $(call if_changed_rule,cc_o_c) 30 29 31 - $(extmod_prefix).module-common.o: $(srctree)/scripts/module-common.c FORCE 32 - $(call if_changed_dep,cc_o_c) 30 + .module-common.o: $(srctree)/scripts/module-common.c FORCE 31 + $(call if_changed_rule,cc_o_c) 33 32 34 33 quiet_cmd_ld_ko_o = LD [M] $@ 35 34 cmd_ld_ko_o = \ 36 35 $(LD) -r $(KBUILD_LDFLAGS) \ 37 36 $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ 38 - -T scripts/module.lds -o $@ $(filter %.o, $^) 37 + -T $(objtree)/scripts/module.lds -o $@ $(filter %.o, $^) 39 38 40 39 quiet_cmd_btf_ko = BTF [M] $@ 41 40 cmd_btf_ko = \ 42 - if [ ! -f vmlinux ]; then \ 41 + if [ ! -f $(objtree)/vmlinux ]; then \ 43 42 printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \ 44 43 else \ 45 - LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base vmlinux $@; \ 46 - $(RESOLVE_BTFIDS) -b vmlinux $@; \ 44 + LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base $(objtree)/vmlinux $@; \ 45 + $(RESOLVE_BTFIDS) -b $(objtree)/vmlinux $@; \ 47 46 fi; 48 47 49 48 # Same as newer-prereqs, but allows to exclude specified extra dependencies ··· 52 57 printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) 53 58 54 59 # Re-generate module BTFs if either module's .ko or vmlinux changed 55 - %.ko: %.o %.mod.o $(extmod_prefix).module-common.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE 56 - +$(call if_changed_except,ld_ko_o,vmlinux) 60 + %.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE 61 + +$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux) 57 62 ifdef CONFIG_DEBUG_INFO_BTF_MODULES 58 63 +$(if $(newer-prereqs),$(call cmd,btf_ko)) 59 64 endif 60 65 61 - targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) $(extmod_prefix).module-common.o 66 + targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) .module-common.o 62 67 63 68 # Add FORCE to the prerequisites of a target to force it to be always rebuilt. 64 69 # ---------------------------------------------------------------------------
+4 -4
scripts/Makefile.modinst
··· 6 6 PHONY := __modinst 7 7 __modinst: 8 8 9 - include include/config/auto.conf 9 + include $(objtree)/include/config/auto.conf 10 10 include $(srctree)/scripts/Kbuild.include 11 11 12 12 install-y := ··· 40 40 41 41 endif 42 42 43 - modules := $(call read-file, $(MODORDER)) 43 + modules := $(call read-file, modules.order) 44 44 45 45 ifeq ($(KBUILD_EXTMOD),) 46 46 dst := $(MODLIB)/kernel ··· 59 59 suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst 60 60 endif 61 61 62 - modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules)) 62 + modules := $(patsubst %.o, $(dst)/%.ko$(suffix-y), $(modules)) 63 63 install-$(CONFIG_MODULES) += $(modules) 64 64 65 65 __modinst: $(install-y) ··· 119 119 # Create necessary directories 120 120 $(foreach dir, $(sort $(dir $(install-y))), $(shell mkdir -p $(dir))) 121 121 122 - $(dst)/%.ko: $(extmod_prefix)%.ko FORCE 122 + $(dst)/%.ko: %.ko FORCE 123 123 $(call cmd,install) 124 124 $(call cmd,strip) 125 125 $(call cmd,sign)
+12 -12
scripts/Makefile.modpost
··· 35 35 PHONY := __modpost 36 36 __modpost: 37 37 38 - include include/config/auto.conf 38 + include $(objtree)/include/config/auto.conf 39 39 include $(srctree)/scripts/Kbuild.include 40 40 41 - MODPOST = scripts/mod/modpost 41 + MODPOST = $(objtree)/scripts/mod/modpost 42 42 43 43 modpost-args = \ 44 44 $(if $(CONFIG_MODULES),-M) \ ··· 46 46 $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \ 47 47 $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \ 48 48 $(if $(KBUILD_MODPOST_WARN),-w) \ 49 - $(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \ 49 + $(if $(KBUILD_NSDEPS),-d modules.nsdeps) \ 50 50 $(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \ 51 51 $(if $(findstring 1, $(KBUILD_EXTRA_WARN)),-W) \ 52 52 -o $@ ··· 61 61 # Read out modules.order to pass in modpost. 62 62 # Otherwise, allmodconfig would fail with "Argument list too long". 63 63 ifdef KBUILD_MODULES 64 - modpost-args += -T $(MODORDER) 65 - modpost-deps += $(MODORDER) 64 + modpost-args += -T modules.order 65 + modpost-deps += modules.order 66 66 endif 67 67 68 68 ifeq ($(KBUILD_EXTMOD),) ··· 111 111 else 112 112 113 113 # set src + obj - they may be used in the modules's Makefile 114 - obj := $(KBUILD_EXTMOD) 115 - src := $(if $(VPATH),$(VPATH)/)$(obj) 114 + obj := . 115 + src := $(srcroot) 116 116 117 117 # Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS 118 118 include $(kbuild-file) 119 119 120 - output-symdump := $(KBUILD_EXTMOD)/Module.symvers 120 + output-symdump := Module.symvers 121 121 122 - ifeq ($(wildcard Module.symvers),) 123 - missing-input := Module.symvers 122 + ifeq ($(wildcard $(objtree)/Module.symvers),) 123 + missing-input := $(objtree)/Module.symvers 124 124 else 125 - modpost-args += -i Module.symvers 126 - modpost-deps += Module.symvers 125 + modpost-args += -i $(objtree)/Module.symvers 126 + modpost-deps += $(objtree)/Module.symvers 127 127 endif 128 128 129 129 modpost-args += -e $(addprefix -i , $(KBUILD_EXTRA_SYMBOLS))
+39
scripts/Makefile.propeller
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + # Enable available and selected Clang Propeller features. 4 + ifdef CLANG_PROPELLER_PROFILE_PREFIX 5 + CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=list=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt -ffunction-sections 6 + KBUILD_LDFLAGS += --symbol-ordering-file=$(CLANG_PROPELLER_PROFILE_PREFIX)_ld_profile.txt --no-warn-symbol-ordering 7 + else 8 + # Starting with Clang v20, the '-fbasic-block-sections=labels' option is 9 + # deprecated. Use the recommended '-fbasic-block-address-map' option. 10 + # Link: https://github.com/llvm/llvm-project/pull/110039 11 + ifeq ($(call clang-min-version, 200000),y) 12 + CFLAGS_PROPELLER_CLANG := -fbasic-block-address-map 13 + else 14 + CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=labels 15 + endif 16 + endif 17 + 18 + # Propeller requires debug information to embed module names in the profiles. 19 + # If CONFIG_DEBUG_INFO is not enabled, set -gmlt option. Skip this for AutoFDO, 20 + # as the option should already be set. 21 + ifndef CONFIG_DEBUG_INFO 22 + ifndef CONFIG_AUTOFDO_CLANG 23 + CFLAGS_PROPELLER_CLANG += -gmlt 24 + endif 25 + endif 26 + 27 + ifdef CONFIG_LTO_CLANG_THIN 28 + ifdef CLANG_PROPELLER_PROFILE_PREFIX 29 + KBUILD_LDFLAGS += --lto-basic-block-sections=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt 30 + else 31 + ifeq ($(call test-ge, $(CONFIG_LLD_VERSION), 200000),y) 32 + KBUILD_LDFLAGS += --lto-basic-block-address-map 33 + else 34 + KBUILD_LDFLAGS += --lto-basic-block-sections=labels 35 + endif 36 + endif 37 + endif 38 + 39 + export CFLAGS_PROPELLER_CLANG
+45 -6
scripts/Makefile.vmlinux
··· 5 5 6 6 include include/config/auto.conf 7 7 include $(srctree)/scripts/Kbuild.include 8 - 9 - # for c_flags 10 8 include $(srctree)/scripts/Makefile.lib 11 9 12 10 targets := 13 11 14 - quiet_cmd_cc_o_c = CC $@ 15 - cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< 16 - 17 12 %.o: %.c FORCE 18 - $(call if_changed_dep,cc_o_c) 13 + $(call if_changed_rule,cc_o_c) 14 + 15 + %.o: %.S FORCE 16 + $(call if_changed_rule,as_o_S) 17 + 18 + # Built-in dtb 19 + # --------------------------------------------------------------------------- 20 + 21 + quiet_cmd_wrap_dtbs = WRAP $@ 22 + cmd_wrap_dtbs = { \ 23 + echo '\#include <asm-generic/vmlinux.lds.h>'; \ 24 + echo '.section .dtb.init.rodata,"a"'; \ 25 + while read dtb; do \ 26 + symbase=__dtb_$$(basename -s .dtb "$${dtb}" | tr - _); \ 27 + echo '.balign STRUCT_ALIGNMENT'; \ 28 + echo ".global $${symbase}_begin"; \ 29 + echo "$${symbase}_begin:"; \ 30 + echo '.incbin "'$$dtb'" '; \ 31 + echo ".global $${symbase}_end"; \ 32 + echo "$${symbase}_end:"; \ 33 + done < $<; \ 34 + } > $@ 35 + 36 + .builtin-dtbs.S: .builtin-dtbs-list FORCE 37 + $(call if_changed,wrap_dtbs) 38 + 39 + quiet_cmd_gen_dtbs_list = GEN $@ 40 + cmd_gen_dtbs_list = \ 41 + $(if $(CONFIG_BUILTIN_DTB_NAME), echo "arch/$(SRCARCH)/boot/dts/$(CONFIG_BUILTIN_DTB_NAME).dtb",:) > $@ 42 + 43 + .builtin-dtbs-list: arch/$(SRCARCH)/boot/dts/dtbs-list FORCE 44 + $(call if_changed,$(if $(CONFIG_BUILTIN_DTB_ALL),copy,gen_dtbs_list)) 45 + 46 + targets += .builtin-dtbs-list 47 + 48 + ifdef CONFIG_GENERIC_BUILTIN_DTB 49 + targets += .builtin-dtbs.S .builtin-dtbs.o 50 + vmlinux: .builtin-dtbs.o 51 + endif 52 + 53 + # vmlinux 54 + # --------------------------------------------------------------------------- 19 55 20 56 ifdef CONFIG_MODULES 21 57 targets += .vmlinux.export.o ··· 75 39 targets += vmlinux 76 40 vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE 77 41 +$(call if_changed_dep,link_vmlinux) 42 + ifdef CONFIG_DEBUG_INFO_BTF 43 + vmlinux: $(RESOLVE_BTFIDS) 44 + endif 78 45 79 46 # module.builtin.ranges 80 47 # ---------------------------------------------------------------------------
+1 -5
scripts/coccicheck
··· 80 80 NPROC=1 81 81 else 82 82 ONLINE=0 83 - if [ "$KBUILD_EXTMOD" = "" ] ; then 84 - OPTIONS="--dir $srctree $COCCIINCLUDE" 85 - else 86 - OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE" 87 - fi 83 + OPTIONS="--dir $srcroot $COCCIINCLUDE" 88 84 89 85 # Use only one thread per core by default if hyperthreading is enabled 90 86 THREADS_PER_CORE=$(LANG=C lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]")
+2 -2
scripts/depmod.sh
··· 12 12 13 13 : ${DEPMOD:=depmod} 14 14 15 - if ! test -r System.map ; then 15 + if ! test -r "${objtree}/System.map" ; then 16 16 echo "Warning: modules_install: missing 'System.map' file. Skipping depmod." >&2 17 17 exit 0 18 18 fi ··· 25 25 exit 0 26 26 fi 27 27 28 - set -- -ae -F System.map 28 + set -- -ae -F "${objtree}/System.map" 29 29 if test -n "$INSTALL_MOD_PATH"; then 30 30 set -- "$@" -b "$INSTALL_MOD_PATH" 31 31 fi
+45 -44
scripts/genksyms/genksyms.c
··· 632 632 void export_symbol(const char *name) 633 633 { 634 634 struct symbol *sym; 635 + unsigned long crc; 636 + int has_changed = 0; 635 637 636 638 sym = find_symbol(name, SYM_NORMAL, 0); 637 - if (!sym) 639 + if (!sym) { 638 640 error_with_pos("export undefined symbol %s", name); 639 - else { 640 - unsigned long crc; 641 - int has_changed = 0; 642 - 643 - if (flag_dump_defs) 644 - fprintf(debugfile, "Export %s == <", name); 645 - 646 - expansion_trail = (struct symbol *)-1L; 647 - 648 - sym->expansion_trail = expansion_trail; 649 - expansion_trail = sym; 650 - crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; 651 - 652 - sym = expansion_trail; 653 - while (sym != (struct symbol *)-1L) { 654 - struct symbol *n = sym->expansion_trail; 655 - 656 - if (sym->status != STATUS_UNCHANGED) { 657 - if (!has_changed) { 658 - print_location(); 659 - fprintf(stderr, "%s: %s: modversion " 660 - "changed because of changes " 661 - "in ", flag_preserve ? "error" : 662 - "warning", name); 663 - } else 664 - fprintf(stderr, ", "); 665 - print_type_name(sym->type, sym->name); 666 - if (sym->status == STATUS_DEFINED) 667 - fprintf(stderr, " (became defined)"); 668 - has_changed = 1; 669 - if (flag_preserve) 670 - errors++; 671 - } 672 - sym->expansion_trail = 0; 673 - sym = n; 674 - } 675 - if (has_changed) 676 - fprintf(stderr, "\n"); 677 - 678 - if (flag_dump_defs) 679 - fputs(">\n", debugfile); 680 - 681 - printf("#SYMVER %s 0x%08lx\n", name, crc); 641 + return; 682 642 } 643 + 644 + if (flag_dump_defs) 645 + fprintf(debugfile, "Export %s == <", name); 646 + 647 + expansion_trail = (struct symbol *)-1L; 648 + 649 + sym->expansion_trail = expansion_trail; 650 + expansion_trail = sym; 651 + crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff; 652 + 653 + sym = expansion_trail; 654 + while (sym != (struct symbol *)-1L) { 655 + struct symbol *n = sym->expansion_trail; 656 + 657 + if (sym->status != STATUS_UNCHANGED) { 658 + if (!has_changed) { 659 + print_location(); 660 + fprintf(stderr, 661 + "%s: %s: modversion changed because of changes in ", 662 + flag_preserve ? "error" : "warning", 663 + name); 664 + } else { 665 + fprintf(stderr, ", "); 666 + } 667 + print_type_name(sym->type, sym->name); 668 + if (sym->status == STATUS_DEFINED) 669 + fprintf(stderr, " (became defined)"); 670 + has_changed = 1; 671 + if (flag_preserve) 672 + errors++; 673 + } 674 + sym->expansion_trail = 0; 675 + sym = n; 676 + } 677 + if (has_changed) 678 + fprintf(stderr, "\n"); 679 + 680 + if (flag_dump_defs) 681 + fputs(">\n", debugfile); 682 + 683 + printf("#SYMVER %s 0x%08lx\n", name, crc); 683 684 } 684 685 685 686 /*----------------------------------------------------------------------*/
-1
scripts/head-object-list.txt
··· 23 23 arch/m68k/kernel/head.o 24 24 arch/m68k/kernel/sun3-head.o 25 25 arch/microblaze/kernel/head.o 26 - arch/mips/kernel/head.o 27 26 arch/nios2/kernel/head.o 28 27 arch/openrisc/kernel/head.o 29 28 arch/parisc/kernel/head.o
+4 -1
scripts/kconfig/conf.c
··· 628 628 629 629 static void conf_usage(const char *progname) 630 630 { 631 - printf("Usage: %s [options] <kconfig-file>\n", progname); 631 + printf("Usage: %s [options] kconfig_file\n", progname); 632 632 printf("\n"); 633 633 printf("Generic options:\n"); 634 634 printf(" -h, --help Print this message and exit.\n"); ··· 653 653 printf(" --mod2yesconfig Change answers from mod to yes if possible\n"); 654 654 printf(" --mod2noconfig Change answers from mod to no if possible\n"); 655 655 printf(" (If none of the above is given, --oldaskconfig is the default)\n"); 656 + printf("\n"); 657 + printf("Arguments:\n"); 658 + printf(" kconfig_file Top-level Kconfig file.\n"); 656 659 } 657 660 658 661 int main(int ac, char **av)
+1
scripts/kconfig/lkc_proto.h
··· 34 34 bool sym_string_within_range(struct symbol *sym, const char *str); 35 35 bool sym_set_string_value(struct symbol *sym, const char *newval); 36 36 bool sym_is_changeable(const struct symbol *sym); 37 + struct menu *sym_get_prompt_menu(const struct symbol *sym); 37 38 struct menu *sym_get_choice_menu(const struct symbol *sym); 38 39 const char * sym_get_string_value(struct symbol *sym); 39 40
+1 -1
scripts/kconfig/nconf.c
··· 467 467 return; 468 468 } 469 469 470 - /* return != 0 to indicate the key was handles */ 470 + /* return != 0 to indicate the key was handled */ 471 471 static int process_special_keys(int *key, struct menu *menu) 472 472 { 473 473 int i;
+9
scripts/kconfig/nconf.gui.c
··· 277 277 case KEY_RIGHT: 278 278 menu_driver(menu, REQ_RIGHT_ITEM); 279 279 break; 280 + case 9: /* TAB */ 281 + if (btn_num > 1) { 282 + /* cycle through buttons */ 283 + if (item_index(current_item(menu)) == btn_num - 1) 284 + menu_driver(menu, REQ_FIRST_ITEM); 285 + else 286 + menu_driver(menu, REQ_NEXT_ITEM); 287 + } 288 + break; 280 289 case 10: /* ENTER */ 281 290 case 27: /* ESCAPE */ 282 291 case ' ':
+5 -23
scripts/kconfig/parser.y
··· 24 24 int cdebug = PRINTD; 25 25 26 26 static void yyerror(const char *err); 27 - static void zconfprint(const char *err, ...); 28 27 static void zconf_error(const char *err, ...); 29 28 static bool zconf_endtoken(const char *tokenname, 30 29 const char *expected_tokenname); ··· 182 183 if (current_entry->prompt) 183 184 current_entry->prompt->type = P_MENU; 184 185 else 185 - zconfprint("warning: menuconfig statement without prompt"); 186 + zconf_error("menuconfig statement without prompt"); 186 187 printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno); 187 188 }; 188 189 ··· 290 291 { 291 292 menu_add_prompt(P_PROMPT, $2, $3); 292 293 printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno); 293 - }; 294 - 295 - choice_option: T_BOOL T_WORD_QUOTE if_expr T_EOL 296 - { 297 - menu_add_prompt(P_PROMPT, $2, $3); 298 - printd(DEBUG_PARSE, "%s:%d:bool\n", cur_filename, cur_lineno); 299 294 }; 300 295 301 296 choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL ··· 401 408 { 402 409 if (current_entry->help) { 403 410 free(current_entry->help); 404 - zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used", 405 - current_entry->sym->name ?: "<choice>"); 411 + zconf_error("'%s' defined with more than one help text", 412 + current_entry->sym->name ?: "<choice>"); 406 413 } 407 414 408 415 /* Is the help text empty or all whitespace? */ 409 416 if ($2[strspn($2, " \f\n\r\t\v")] == '\0') 410 - zconfprint("warning: '%s' defined with blank help text", 411 - current_entry->sym->name ?: "<choice>"); 417 + zconf_error("'%s' defined with blank help text", 418 + current_entry->sym->name ?: "<choice>"); 412 419 413 420 current_entry->help = $2; 414 421 }; ··· 589 596 return false; 590 597 } 591 598 return true; 592 - } 593 - 594 - static void zconfprint(const char *err, ...) 595 - { 596 - va_list ap; 597 - 598 - fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno); 599 - va_start(ap, err); 600 - vfprintf(stderr, err, ap); 601 - va_end(ap); 602 - fprintf(stderr, "\n"); 603 599 } 604 600 605 601 static void zconf_error(const char *err, ...)
+63 -145
scripts/kconfig/qconf.cc
··· 110 110 111 111 if (prop) switch (prop->type) { 112 112 case P_MENU: 113 - if (list->mode == singleMode || list->mode == symbolMode) { 113 + if (list->mode == singleMode) { 114 114 /* a menuconfig entry is displayed differently 115 115 * depending whether it's at the view root or a child. 116 116 */ ··· 159 159 ch = 'M'; 160 160 break; 161 161 default: 162 - if (sym_is_choice_value(sym) && type == S_BOOLEAN) 162 + if (sym_is_choice_value(sym)) 163 163 setIcon(promptColIdx, choiceNoIcon); 164 164 else 165 165 setIcon(promptColIdx, symbolNoIcon); ··· 175 175 setText(dataColIdx, sym_get_string_value(sym)); 176 176 break; 177 177 } 178 - if (!sym_has_value(sym) && visible) 178 + if (!sym_has_value(sym)) 179 179 prompt += " (NEW)"; 180 180 set_prompt: 181 181 setText(promptColIdx, prompt); 182 182 } 183 183 184 - void ConfigItem::testUpdateMenu(bool v) 184 + void ConfigItem::testUpdateMenu(void) 185 185 { 186 186 ConfigItem* i; 187 187 188 - visible = v; 189 188 if (!menu) 190 189 return; 191 190 ··· 306 307 { 307 308 setObjectName(name); 308 309 setSortingEnabled(false); 309 - setRootIsDecorated(true); 310 310 311 311 setVerticalScrollMode(ScrollPerPixel); 312 312 setHorizontalScrollMode(ScrollPerPixel); ··· 428 430 item = (ConfigItem*)(*it); 429 431 if (!item->menu) 430 432 continue; 431 - item->testUpdateMenu(menu_is_visible(item->menu)); 433 + item->testUpdateMenu(); 432 434 433 435 ++it; 434 436 } 435 437 return; 436 438 } 437 439 438 - if (rootEntry != &rootmenu && (mode == singleMode || 439 - (mode == symbolMode && rootEntry->parent != &rootmenu))) { 440 + if (rootEntry != &rootmenu && mode == singleMode) { 440 441 item = (ConfigItem *)topLevelItem(0); 441 442 if (!item) 442 - item = new ConfigItem(this, 0, true); 443 + item = new ConfigItem(this, 0); 443 444 last = item; 444 445 } 445 446 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) && 446 447 rootEntry->sym && rootEntry->prompt) { 447 448 item = last ? last->nextSibling() : nullptr; 448 449 if (!item) 449 - item = new ConfigItem(this, last, rootEntry, true); 450 + item = new ConfigItem(this, last, rootEntry); 450 451 else 451 - item->testUpdateMenu(true); 452 + item->testUpdateMenu(); 452 453 453 454 updateMenuList(item, rootEntry); 454 455 update(); ··· 596 599 struct menu* child; 597 600 ConfigItem* item; 598 601 ConfigItem* last; 599 - bool visible; 600 602 enum prop_type type; 601 603 602 604 if (!menu) { ··· 627 631 break; 628 632 } 629 633 630 - visible = menu_is_visible(child); 631 634 if (!menuSkip(child)) { 632 635 if (!child->sym && !child->list && !child->prompt) 633 636 continue; 634 637 if (!item || item->menu != child) 635 - item = new ConfigItem(parent, last, child, visible); 638 + item = new ConfigItem(parent, last, child); 636 639 else 637 - item->testUpdateMenu(visible); 640 + item->testUpdateMenu(); 638 641 639 642 if (mode == fullMode || mode == menuMode || type != P_MENU) 640 643 updateMenuList(item, child); ··· 659 664 struct menu* child; 660 665 ConfigItem* item; 661 666 ConfigItem* last; 662 - bool visible; 663 667 enum prop_type type; 664 668 665 669 if (!menu) { ··· 690 696 break; 691 697 } 692 698 693 - visible = menu_is_visible(child); 694 699 if (!menuSkip(child)) { 695 700 if (!child->sym && !child->list && !child->prompt) 696 701 continue; 697 702 if (!item || item->menu != child) 698 - item = new ConfigItem(this, last, child, visible); 703 + item = new ConfigItem(this, last, child); 699 704 else 700 - item->testUpdateMenu(visible); 705 + item->testUpdateMenu(); 701 706 702 707 if (mode == fullMode || mode == menuMode || type != P_MENU) 703 708 updateMenuList(item, child); ··· 724 731 struct menu *menu; 725 732 enum prop_type type; 726 733 727 - if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) { 734 + if (ev->key() == Qt::Key_Escape && mode == singleMode) { 728 735 emit parentSelected(); 729 736 ev->accept(); 730 737 return; ··· 774 781 ev->accept(); 775 782 } 776 783 777 - void ConfigList::mousePressEvent(QMouseEvent* e) 778 - { 779 - //QPoint p(contentsToViewport(e->pos())); 780 - //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); 781 - Parent::mousePressEvent(e); 782 - } 783 - 784 784 void ConfigList::mouseReleaseEvent(QMouseEvent* e) 785 785 { 786 786 QPoint p = e->pos(); ··· 818 832 skip: 819 833 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y()); 820 834 Parent::mouseReleaseEvent(e); 821 - } 822 - 823 - void ConfigList::mouseMoveEvent(QMouseEvent* e) 824 - { 825 - //QPoint p(contentsToViewport(e->pos())); 826 - //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); 827 - Parent::mouseMoveEvent(e); 828 835 } 829 836 830 837 void ConfigList::mouseDoubleClickEvent(QMouseEvent* e) ··· 1001 1022 if (sym->name) { 1002 1023 stream << " ("; 1003 1024 if (showDebug()) 1004 - stream << "<a href=\"s" << sym->name << "\">"; 1025 + stream << "<a href=\"" << sym->name << "\">"; 1005 1026 stream << print_filter(sym->name); 1006 1027 if (showDebug()) 1007 1028 stream << "</a>"; ··· 1010 1031 } else if (sym->name) { 1011 1032 stream << "<big><b>"; 1012 1033 if (showDebug()) 1013 - stream << "<a href=\"s" << sym->name << "\">"; 1034 + stream << "<a href=\"" << sym->name << "\">"; 1014 1035 stream << print_filter(sym->name); 1015 1036 if (showDebug()) 1016 1037 stream << "</a>"; ··· 1065 1086 switch (prop->type) { 1066 1087 case P_PROMPT: 1067 1088 case P_MENU: 1068 - stream << "prompt: <a href=\"m" << sym->name << "\">"; 1089 + stream << "prompt: "; 1069 1090 stream << print_filter(prop->text); 1070 - stream << "</a><br>"; 1091 + stream << "<br>"; 1071 1092 break; 1072 1093 case P_DEFAULT: 1073 1094 case P_SELECT: ··· 1101 1122 { 1102 1123 QRegularExpression re("[<>&\"\\n]"); 1103 1124 QString res = str; 1125 + 1126 + QHash<QChar, QString> patterns; 1127 + patterns['<'] = "&lt;"; 1128 + patterns['>'] = "&gt;"; 1129 + patterns['&'] = "&amp;"; 1130 + patterns['"'] = "&quot;"; 1131 + patterns['\n'] = "<br>"; 1132 + 1104 1133 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) { 1105 - switch (res[i].toLatin1()) { 1106 - case '<': 1107 - res.replace(i, 1, "&lt;"); 1108 - i += 4; 1109 - break; 1110 - case '>': 1111 - res.replace(i, 1, "&gt;"); 1112 - i += 4; 1113 - break; 1114 - case '&': 1115 - res.replace(i, 1, "&amp;"); 1116 - i += 5; 1117 - break; 1118 - case '"': 1119 - res.replace(i, 1, "&quot;"); 1120 - i += 6; 1121 - break; 1122 - case '\n': 1123 - res.replace(i, 1, "<br>"); 1124 - i += 4; 1125 - break; 1134 + const QString n = patterns.value(res[i], QString()); 1135 + if (!n.isEmpty()) { 1136 + res.replace(i, 1, n); 1137 + i += n.length(); 1126 1138 } 1127 1139 } 1128 1140 return res; ··· 1124 1154 QTextStream *stream = reinterpret_cast<QTextStream *>(data); 1125 1155 1126 1156 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) { 1127 - *stream << "<a href=\"s" << sym->name << "\">"; 1157 + *stream << "<a href=\"" << sym->name << "\">"; 1128 1158 *stream << print_filter(str); 1129 1159 *stream << "</a>"; 1130 1160 } else { ··· 1134 1164 1135 1165 void ConfigInfoView::clicked(const QUrl &url) 1136 1166 { 1137 - QByteArray str = url.toEncoded(); 1138 - const std::size_t count = str.size(); 1139 - char *data = new char[count + 2]; // '$' + '\0' 1140 - struct symbol **result; 1141 - struct menu *m = NULL; 1167 + struct menu *m; 1142 1168 1143 - if (count < 1) { 1144 - delete[] data; 1145 - return; 1146 - } 1169 + sym = sym_find(url.toEncoded().constData()); 1147 1170 1148 - memcpy(data, str.constData(), count); 1149 - data[count] = '\0'; 1150 - 1151 - /* Seek for exact match */ 1152 - data[0] = '^'; 1153 - strcat(data, "$"); 1154 - result = sym_re_search(data); 1155 - if (!result) { 1156 - delete[] data; 1157 - return; 1158 - } 1159 - 1160 - sym = *result; 1161 - 1162 - /* Seek for the menu which holds the symbol */ 1163 - for (struct property *prop = sym->prop; prop; prop = prop->next) { 1164 - if (prop->type != P_PROMPT && prop->type != P_MENU) 1165 - continue; 1166 - m = prop->menu; 1167 - break; 1168 - } 1169 - 1171 + m = sym_get_prompt_menu(sym); 1170 1172 if (!m) { 1171 1173 /* Symbol is not visible as a menu */ 1172 1174 symbolInfo(); ··· 1146 1204 } else { 1147 1205 emit menuSelected(m); 1148 1206 } 1149 - 1150 - free(result); 1151 - delete[] data; 1152 1207 } 1153 1208 1154 1209 void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event) ··· 1179 1240 layout2->addWidget(searchButton); 1180 1241 layout1->addLayout(layout2); 1181 1242 1182 - split = new QSplitter(this); 1183 - split->setOrientation(Qt::Vertical); 1243 + split = new QSplitter(Qt::Vertical, this); 1184 1244 list = new ConfigList(split, "search"); 1185 1245 list->mode = listMode; 1186 1246 info = new ConfigInfoView(split, "search"); ··· 1238 1300 return; 1239 1301 for (p = result; *p; p++) { 1240 1302 for_all_prompts((*p), prop) 1241 - lastItem = new ConfigItem(list, lastItem, prop->menu, 1242 - menu_is_visible(prop->menu)); 1303 + lastItem = new ConfigItem(list, lastItem, prop->menu); 1243 1304 } 1244 1305 } 1245 1306 ··· 1278 1341 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); 1279 1342 1280 1343 QWidget *widget = new QWidget(this); 1281 - QVBoxLayout *layout = new QVBoxLayout(widget); 1282 1344 setCentralWidget(widget); 1283 1345 1284 - split1 = new QSplitter(widget); 1285 - split1->setOrientation(Qt::Horizontal); 1346 + QVBoxLayout *layout = new QVBoxLayout(widget); 1347 + 1348 + split2 = new QSplitter(Qt::Vertical, widget); 1349 + layout->addWidget(split2); 1350 + split2->setChildrenCollapsible(false); 1351 + 1352 + split1 = new QSplitter(Qt::Horizontal, split2); 1286 1353 split1->setChildrenCollapsible(false); 1287 1354 1288 - menuList = new ConfigList(widget, "menu"); 1355 + configList = new ConfigList(split1, "config"); 1289 1356 1290 - split2 = new QSplitter(widget); 1291 - split2->setChildrenCollapsible(false); 1292 - split2->setOrientation(Qt::Vertical); 1357 + menuList = new ConfigList(split1, "menu"); 1293 1358 1294 - // create config tree 1295 - configList = new ConfigList(widget, "config"); 1296 - 1297 - helpText = new ConfigInfoView(widget, "help"); 1298 - 1299 - layout->addWidget(split2); 1300 - split2->addWidget(split1); 1301 - split1->addWidget(configList); 1302 - split1->addWidget(menuList); 1303 - split2->addWidget(helpText); 1304 - 1359 + helpText = new ConfigInfoView(split2, "help"); 1305 1360 setTabOrder(configList, helpText); 1361 + 1306 1362 configList->setFocus(); 1307 1363 1308 1364 backAction = new QAction(QPixmap(xpm_back), "Back", this); 1365 + backAction->setShortcut(QKeySequence::Back); 1309 1366 connect(backAction, &QAction::triggered, 1310 1367 this, &ConfigMainWindow::goBack); 1311 1368 1312 1369 QAction *quitAction = new QAction("&Quit", this); 1313 - quitAction->setShortcut(Qt::CTRL | Qt::Key_Q); 1370 + quitAction->setShortcut(QKeySequence::Quit); 1314 1371 connect(quitAction, &QAction::triggered, 1315 1372 this, &ConfigMainWindow::close); 1316 1373 1317 - QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); 1318 - loadAction->setShortcut(Qt::CTRL | Qt::Key_L); 1374 + QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this); 1375 + loadAction->setShortcut(QKeySequence::Open); 1319 1376 connect(loadAction, &QAction::triggered, 1320 1377 this, &ConfigMainWindow::loadConfig); 1321 1378 1322 1379 saveAction = new QAction(QPixmap(xpm_save), "&Save", this); 1323 - saveAction->setShortcut(Qt::CTRL | Qt::Key_S); 1380 + saveAction->setShortcut(QKeySequence::Save); 1324 1381 connect(saveAction, &QAction::triggered, 1325 1382 this, &ConfigMainWindow::saveConfig); 1326 1383 1327 1384 conf_set_changed_callback(conf_changed); 1328 1385 1329 - configname = xstrdup(conf_get_configname()); 1386 + configname = conf_get_configname(); 1330 1387 1331 1388 QAction *saveAsAction = new QAction("Save &As...", this); 1389 + saveAsAction->setShortcut(QKeySequence::SaveAs); 1332 1390 connect(saveAsAction, &QAction::triggered, 1333 1391 this, &ConfigMainWindow::saveConfigAs); 1334 1392 QAction *searchAction = new QAction("&Find", this); 1335 - searchAction->setShortcut(Qt::CTRL | Qt::Key_F); 1393 + searchAction->setShortcut(QKeySequence::Find); 1336 1394 connect(searchAction, &QAction::triggered, 1337 1395 this, &ConfigMainWindow::searchConfig); 1338 1396 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); ··· 1437 1505 connect(helpText, &ConfigInfoView::menuSelected, 1438 1506 this, &ConfigMainWindow::setMenuLink); 1439 1507 1508 + connect(configApp, &QApplication::aboutToQuit, 1509 + this, &ConfigMainWindow::saveSettings); 1510 + 1440 1511 conf_read(NULL); 1441 1512 1442 1513 QString listMode = configSettings->value("/listMode", "symbol").toString(); ··· 1463 1528 void ConfigMainWindow::loadConfig(void) 1464 1529 { 1465 1530 QString str; 1466 - QByteArray ba; 1467 - const char *name; 1468 1531 1469 1532 str = QFileDialog::getOpenFileName(this, "", configname); 1470 1533 if (str.isNull()) 1471 1534 return; 1472 1535 1473 - ba = str.toLocal8Bit(); 1474 - name = ba.data(); 1475 - 1476 - if (conf_read(name)) 1536 + if (conf_read(str.toLocal8Bit().constData())) 1477 1537 QMessageBox::information(this, "qconf", "Unable to load configuration!"); 1478 1538 1479 - free(configname); 1480 - configname = xstrdup(name); 1539 + configname = str; 1481 1540 1482 1541 ConfigList::updateListAllForAll(); 1483 1542 } 1484 1543 1485 1544 bool ConfigMainWindow::saveConfig(void) 1486 1545 { 1487 - if (conf_write(configname)) { 1546 + if (conf_write(configname.toLocal8Bit().constData())) { 1488 1547 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1489 1548 return false; 1490 1549 } ··· 1490 1561 void ConfigMainWindow::saveConfigAs(void) 1491 1562 { 1492 1563 QString str; 1493 - QByteArray ba; 1494 - const char *name; 1495 1564 1496 1565 str = QFileDialog::getSaveFileName(this, "", configname); 1497 1566 if (str.isNull()) 1498 1567 return; 1499 1568 1500 - ba = str.toLocal8Bit(); 1501 - name = ba.data(); 1502 - 1503 - if (conf_write(name)) { 1569 + if (conf_write(str.toLocal8Bit().constData())) { 1504 1570 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1505 1571 } 1506 1572 conf_write_autoconf(0); 1507 1573 1508 - free(configname); 1509 - configname = xstrdup(name); 1574 + configname = str; 1510 1575 } 1511 1576 1512 1577 void ConfigMainWindow::searchConfig(void) ··· 1585 1662 1586 1663 void ConfigMainWindow::goBack(void) 1587 1664 { 1588 - if (configList->rootEntry == &rootmenu) 1589 - return; 1590 - 1591 1665 configList->setParentMenu(); 1592 1666 } 1593 1667 ··· 1825 1905 v = new ConfigMainWindow(); 1826 1906 1827 1907 //zconfdump(stdout); 1828 - configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); 1829 - configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); 1830 1908 1831 1909 v->show(); 1832 1910 configApp->exec();
+8 -11
scripts/kconfig/qconf.h
··· 55 55 56 56 protected: 57 57 void keyPressEvent(QKeyEvent *e); 58 - void mousePressEvent(QMouseEvent *e); 59 58 void mouseReleaseEvent(QMouseEvent *e); 60 - void mouseMoveEvent(QMouseEvent *e); 61 59 void mouseDoubleClickEvent(QMouseEvent *e); 62 60 void focusInEvent(QFocusEvent *e); 63 61 void contextMenuEvent(QContextMenuEvent *e); ··· 114 116 class ConfigItem : public QTreeWidgetItem { 115 117 typedef class QTreeWidgetItem Parent; 116 118 public: 117 - ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v) 118 - : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false) 119 + ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m) 120 + : Parent(parent, after), nextItem(0), menu(m), goParent(false) 119 121 { 120 122 init(); 121 123 } 122 - ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) 123 - : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false) 124 + ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m) 125 + : Parent(parent, after), nextItem(0), menu(m), goParent(false) 124 126 { 125 127 init(); 126 128 } 127 - ConfigItem(ConfigList *parent, ConfigItem *after, bool v) 128 - : Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true) 129 + ConfigItem(ConfigList *parent, ConfigItem *after) 130 + : Parent(parent, after), nextItem(0), menu(0), goParent(true) 129 131 { 130 132 init(); 131 133 } 132 134 ~ConfigItem(void); 133 135 void init(void); 134 136 void updateMenu(void); 135 - void testUpdateMenu(bool v); 137 + void testUpdateMenu(void); 136 138 ConfigList* listView() const 137 139 { 138 140 return (ConfigList*)Parent::treeWidget(); ··· 159 161 160 162 ConfigItem* nextItem; 161 163 struct menu *menu; 162 - bool visible; 163 164 bool goParent; 164 165 165 166 static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon; ··· 234 237 class ConfigMainWindow : public QMainWindow { 235 238 Q_OBJECT 236 239 237 - char *configname; 240 + QString configname; 238 241 static QAction *saveAction; 239 242 static void conf_changed(bool); 240 243 public:
+14 -4
scripts/kconfig/streamline_config.pl
··· 144 144 my %prompts; 145 145 my %objects; 146 146 my %config2kfile; 147 + my %defaults; 147 148 my $var; 148 149 my $iflevel = 0; 149 150 my @ifdeps; ··· 221 220 $depends{$config} = $1; 222 221 } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { 223 222 $depends{$config} .= " " . $1; 224 - } elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { 223 + } elsif ($state ne "NONE" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { 225 224 my $dep = $3; 225 + $defaults{$config} = 1; 226 226 if ($dep !~ /^\s*(y|m|n)\s*$/) { 227 227 $dep =~ s/.*\sif\s+//; 228 228 $depends{$config} .= " " . $dep; ··· 505 503 506 504 # Check if something other than a module selects this config 507 505 if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") { 508 - dprint "$conf (non module) selects config, we are good\n"; 506 + dprint "$conf (non module) selects $config, we are good\n"; 509 507 # we are good with this 510 508 return; 511 509 } ··· 525 523 526 524 # If no possible config selected this, then something happened. 527 525 if (!defined($next_config)) { 528 - print STDERR "WARNING: $config is required, but nothing in the\n"; 529 - print STDERR " current config selects it.\n"; 526 + 527 + # Some config options have no prompt, and nothing selects them, but 528 + # they stay turned on once the final checks for the configs 529 + # are done. These configs have a default option, so turn off the 530 + # warnings for configs with default options. 531 + if (!defined($defaults{$config})) { 532 + print STDERR "WARNING: $config is required, but nothing in the\n"; 533 + print STDERR " current config selects it.\n"; 534 + } 535 + 530 536 return; 531 537 } 532 538
+19 -7
scripts/kconfig/symbol.c
··· 71 71 } 72 72 73 73 /** 74 + * sym_get_prompt_menu - get the menu entry with a prompt 75 + * 76 + * @sym: a symbol pointer 77 + * 78 + * Return: the menu entry with a prompt. 79 + */ 80 + struct menu *sym_get_prompt_menu(const struct symbol *sym) 81 + { 82 + struct menu *m; 83 + 84 + list_for_each_entry(m, &sym->menus, link) 85 + if (m->prompt) 86 + return m; 87 + 88 + return NULL; 89 + } 90 + 91 + /** 74 92 * sym_get_choice_menu - get the parent choice menu if present 75 93 * 76 94 * @sym: a symbol pointer ··· 98 80 struct menu *sym_get_choice_menu(const struct symbol *sym) 99 81 { 100 82 struct menu *menu = NULL; 101 - struct menu *m; 102 83 103 84 /* 104 85 * Choice members must have a prompt. Find a menu entry with a prompt, 105 86 * and assume it resides inside a choice block. 106 87 */ 107 - list_for_each_entry(m, &sym->menus, link) 108 - if (m->prompt) { 109 - menu = m; 110 - break; 111 - } 112 - 88 + menu = sym_get_prompt_menu(sym); 113 89 if (!menu) 114 90 return NULL; 115 91
+317 -462
scripts/mod/file2alias.c
··· 10 10 * of the GNU General Public License, incorporated herein by reference. 11 11 */ 12 12 13 + #include <stdarg.h> 14 + #include <stdio.h> 15 + 16 + #include "list.h" 17 + #include "xalloc.h" 18 + 13 19 #include "modpost.h" 14 20 #include "devicetable-offsets.h" 15 21 ··· 36 30 37 31 #include <ctype.h> 38 32 #include <stdbool.h> 33 + 34 + /** 35 + * module_alias_printf - add auto-generated MODULE_ALIAS() 36 + * 37 + * @mod: module 38 + * @append_wildcard: append '*' for future extension if not exist yet 39 + * @fmt: printf(3)-like format 40 + */ 41 + static void __attribute__((format (printf, 3, 4))) 42 + module_alias_printf(struct module *mod, bool append_wildcard, 43 + const char *fmt, ...) 44 + { 45 + struct module_alias *new, *als; 46 + size_t len; 47 + int n; 48 + va_list ap; 49 + 50 + /* Determine required size. */ 51 + va_start(ap, fmt); 52 + n = vsnprintf(NULL, 0, fmt, ap); 53 + va_end(ap); 54 + 55 + if (n < 0) { 56 + error("vsnprintf failed\n"); 57 + return; 58 + } 59 + 60 + len = n + 1; /* extra byte for '\0' */ 61 + 62 + if (append_wildcard) 63 + len++; /* extra byte for '*' */ 64 + 65 + new = xmalloc(sizeof(*new) + len); 66 + 67 + /* Now, really print it to the allocated buffer */ 68 + va_start(ap, fmt); 69 + n = vsnprintf(new->str, len, fmt, ap); 70 + va_end(ap); 71 + 72 + if (n < 0) { 73 + error("vsnprintf failed\n"); 74 + free(new); 75 + return; 76 + } 77 + 78 + if (append_wildcard && (n == 0 || new->str[n - 1] != '*')) { 79 + new->str[n] = '*'; 80 + new->str[n + 1] = '\0'; 81 + } 82 + 83 + /* avoid duplication */ 84 + list_for_each_entry(als, &mod->aliases, node) { 85 + if (!strcmp(als->str, new->str)) { 86 + free(new); 87 + return; 88 + } 89 + } 90 + 91 + list_add_tail(&new->node, &mod->aliases); 92 + } 39 93 40 94 typedef uint32_t __u32; 41 95 typedef uint16_t __u16; ··· 122 56 * we handle those differences explicitly below */ 123 57 #include "../../include/linux/mod_devicetable.h" 124 58 125 - /* This array collects all instances that use the generic do_table */ 126 59 struct devtable { 127 - const char *device_id; /* name of table, __mod_<name>__*_device_table. */ 60 + const char *device_id; 128 61 unsigned long id_size; 129 - int (*do_entry)(const char *filename, void *symval, char *alias); 62 + void (*do_entry)(struct module *mod, void *symval); 130 63 }; 131 - 132 - /* Size of alias provided to do_entry functions */ 133 - #define ALIAS_SIZE 500 134 64 135 65 /* Define a variable f that holds the value of field f of struct devid 136 66 * based at address m. ··· 134 72 #define DEF_FIELD(m, devid, f) \ 135 73 typeof(((struct devid *)0)->f) f = TO_NATIVE(*(typeof(f) *)((m) + OFF_##devid##_##f)) 136 74 137 - /* Define a variable v that holds the address of field f of struct devid 138 - * based at address m. Due to the way typeof works, for a field of type 139 - * T[N] the variable has type T(*)[N], _not_ T*. 140 - */ 141 - #define DEF_FIELD_ADDR_VAR(m, devid, f, v) \ 142 - typeof(((struct devid *)0)->f) *v = ((m) + OFF_##devid##_##f) 143 - 144 75 /* Define a variable f that holds the address of field f of struct devid 145 76 * based at address m. Due to the way typeof works, for a field of type 146 77 * T[N] the variable has type T(*)[N], _not_ T*. 147 78 */ 148 79 #define DEF_FIELD_ADDR(m, devid, f) \ 149 - DEF_FIELD_ADDR_VAR(m, devid, f, f) 80 + typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f) 150 81 151 82 #define ADD(str, sep, cond, field) \ 152 83 do { \ ··· 153 98 else \ 154 99 sprintf(str + strlen(str), "*"); \ 155 100 } while(0) 156 - 157 - /* End in a wildcard, for future extension */ 158 - static inline void add_wildcard(char *str) 159 - { 160 - int len = strlen(str); 161 - 162 - if (str[len - 1] != '*') 163 - strcat(str + len, "*"); 164 - } 165 101 166 102 static inline void add_uuid(char *str, uuid_le uuid) 167 103 { ··· 174 128 guid.b[5], guid.b[4], guid.b[7], guid.b[6], 175 129 guid.b[8], guid.b[9], guid.b[10], guid.b[11], 176 130 guid.b[12], guid.b[13], guid.b[14], guid.b[15]); 177 - } 178 - 179 - /** 180 - * Check that sizeof(device_id type) are consistent with size of section 181 - * in .o file. If in-consistent then userspace and kernel does not agree 182 - * on actual size which is a bug. 183 - * Also verify that the final entry in the table is all zeros. 184 - * Ignore both checks if build host differ from target host and size differs. 185 - **/ 186 - static void device_id_check(const char *modname, const char *device_id, 187 - unsigned long size, unsigned long id_size, 188 - void *symval) 189 - { 190 - int i; 191 - 192 - if (size % id_size || size < id_size) { 193 - fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_%s__<identifier>_device_table=%lu.\n" 194 - "Fix definition of struct %s_device_id in mod_devicetable.h\n", 195 - modname, device_id, id_size, device_id, size, device_id); 196 - } 197 - /* Verify last one is a terminator */ 198 - for (i = 0; i < id_size; i++ ) { 199 - if (*(uint8_t*)(symval+size-id_size+i)) { 200 - fprintf(stderr, 201 - "%s: struct %s_device_id is %lu bytes. The last of %lu is:\n", 202 - modname, device_id, id_size, size / id_size); 203 - for (i = 0; i < id_size; i++ ) 204 - fprintf(stderr,"0x%02x ", 205 - *(uint8_t*)(symval+size-id_size+i) ); 206 - fprintf(stderr,"\n"); 207 - fatal("%s: struct %s_device_id is not terminated with a NULL entry!\n", 208 - modname, device_id); 209 - } 210 - } 211 131 } 212 132 213 133 /* USB is special because the bcdDevice can be matched against a numeric range */ ··· 241 229 ADD(alias, "in", match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER, 242 230 bInterfaceNumber); 243 231 244 - add_wildcard(alias); 245 - buf_printf(&mod->dev_table_buf, 246 - "MODULE_ALIAS(\"%s\");\n", alias); 232 + module_alias_printf(mod, true, "%s", alias); 247 233 } 248 234 249 235 /* Handles increment/decrement of BCD formatted integers */ ··· 283 273 return init; 284 274 } 285 275 286 - static void do_usb_entry_multi(void *symval, struct module *mod) 276 + static void do_usb_entry_multi(struct module *mod, void *symval) 287 277 { 288 278 unsigned int devlo, devhi; 289 279 unsigned char chi, clo, max; ··· 348 338 } 349 339 } 350 340 351 - static void do_usb_table(void *symval, unsigned long size, 352 - struct module *mod) 353 - { 354 - unsigned int i; 355 - const unsigned long id_size = SIZE_usb_device_id; 356 - 357 - device_id_check(mod->name, "usb", size, id_size, symval); 358 - 359 - /* Leave last one: it's the terminator. */ 360 - size -= id_size; 361 - 362 - for (i = 0; i < size; i += id_size) 363 - do_usb_entry_multi(symval + i, mod); 364 - } 365 - 366 - static void do_of_entry_multi(void *symval, struct module *mod) 341 + static void do_of_entry(struct module *mod, void *symval) 367 342 { 368 343 char alias[500]; 369 344 int len; ··· 370 375 if (isspace(*tmp)) 371 376 *tmp = '_'; 372 377 373 - buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); 374 - strcat(alias, "C"); 375 - add_wildcard(alias); 376 - buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); 377 - } 378 - 379 - static void do_of_table(void *symval, unsigned long size, 380 - struct module *mod) 381 - { 382 - unsigned int i; 383 - const unsigned long id_size = SIZE_of_device_id; 384 - 385 - device_id_check(mod->name, "of", size, id_size, symval); 386 - 387 - /* Leave last one: it's the terminator. */ 388 - size -= id_size; 389 - 390 - for (i = 0; i < size; i += id_size) 391 - do_of_entry_multi(symval + i, mod); 378 + module_alias_printf(mod, false, "%s", alias); 379 + module_alias_printf(mod, false, "%sC*", alias); 392 380 } 393 381 394 382 /* Looks like: hid:bNvNpN */ 395 - static int do_hid_entry(const char *filename, 396 - void *symval, char *alias) 383 + static void do_hid_entry(struct module *mod, void *symval) 397 384 { 385 + char alias[256] = {}; 386 + 398 387 DEF_FIELD(symval, hid_device_id, bus); 399 388 DEF_FIELD(symval, hid_device_id, group); 400 389 DEF_FIELD(symval, hid_device_id, vendor); 401 390 DEF_FIELD(symval, hid_device_id, product); 402 391 403 - sprintf(alias, "hid:"); 404 392 ADD(alias, "b", bus != HID_BUS_ANY, bus); 405 393 ADD(alias, "g", group != HID_GROUP_ANY, group); 406 394 ADD(alias, "v", vendor != HID_ANY_ID, vendor); 407 395 ADD(alias, "p", product != HID_ANY_ID, product); 408 396 409 - return 1; 397 + module_alias_printf(mod, false, "hid:%s", alias); 410 398 } 411 399 412 400 /* Looks like: ieee1394:venNmoNspNverN */ 413 - static int do_ieee1394_entry(const char *filename, 414 - void *symval, char *alias) 401 + static void do_ieee1394_entry(struct module *mod, void *symval) 415 402 { 403 + char alias[256] = {}; 404 + 416 405 DEF_FIELD(symval, ieee1394_device_id, match_flags); 417 406 DEF_FIELD(symval, ieee1394_device_id, vendor_id); 418 407 DEF_FIELD(symval, ieee1394_device_id, model_id); 419 408 DEF_FIELD(symval, ieee1394_device_id, specifier_id); 420 409 DEF_FIELD(symval, ieee1394_device_id, version); 421 410 422 - strcpy(alias, "ieee1394:"); 423 411 ADD(alias, "ven", match_flags & IEEE1394_MATCH_VENDOR_ID, 424 412 vendor_id); 425 413 ADD(alias, "mo", match_flags & IEEE1394_MATCH_MODEL_ID, ··· 412 434 ADD(alias, "ver", match_flags & IEEE1394_MATCH_VERSION, 413 435 version); 414 436 415 - add_wildcard(alias); 416 - return 1; 437 + module_alias_printf(mod, true, "ieee1394:%s", alias); 417 438 } 418 439 419 440 /* Looks like: pci:vNdNsvNsdNbcNscNiN or <prefix>_pci:vNdNsvNsdNbcNscNiN. */ 420 - static int do_pci_entry(const char *filename, 421 - void *symval, char *alias) 441 + static void do_pci_entry(struct module *mod, void *symval) 422 442 { 443 + char alias[256]; 423 444 /* Class field can be divided into these three. */ 424 445 unsigned char baseclass, subclass, interface, 425 446 baseclass_mask, subclass_mask, interface_mask; ··· 441 464 default: 442 465 warn("Unknown PCI driver_override alias %08X\n", 443 466 override_only); 444 - return 0; 445 467 } 446 468 447 469 ADD(alias, "v", vendor != PCI_ANY_ID, vendor); ··· 459 483 || (subclass_mask != 0 && subclass_mask != 0xFF) 460 484 || (interface_mask != 0 && interface_mask != 0xFF)) { 461 485 warn("Can't handle masks in %s:%04X\n", 462 - filename, class_mask); 463 - return 0; 486 + mod->name, class_mask); 487 + return; 464 488 } 465 489 466 490 ADD(alias, "bc", baseclass_mask == 0xFF, baseclass); 467 491 ADD(alias, "sc", subclass_mask == 0xFF, subclass); 468 492 ADD(alias, "i", interface_mask == 0xFF, interface); 469 - add_wildcard(alias); 470 - return 1; 493 + 494 + module_alias_printf(mod, true, "%s", alias); 471 495 } 472 496 473 497 /* looks like: "ccw:tNmNdtNdmN" */ 474 - static int do_ccw_entry(const char *filename, 475 - void *symval, char *alias) 498 + static void do_ccw_entry(struct module *mod, void *symval) 476 499 { 500 + char alias[256] = {}; 501 + 477 502 DEF_FIELD(symval, ccw_device_id, match_flags); 478 503 DEF_FIELD(symval, ccw_device_id, cu_type); 479 504 DEF_FIELD(symval, ccw_device_id, cu_model); 480 505 DEF_FIELD(symval, ccw_device_id, dev_type); 481 506 DEF_FIELD(symval, ccw_device_id, dev_model); 482 507 483 - strcpy(alias, "ccw:"); 484 508 ADD(alias, "t", match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE, 485 509 cu_type); 486 510 ADD(alias, "m", match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL, ··· 489 513 dev_type); 490 514 ADD(alias, "dm", match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, 491 515 dev_model); 492 - add_wildcard(alias); 493 - return 1; 516 + 517 + module_alias_printf(mod, true, "ccw:%s", alias); 494 518 } 495 519 496 520 /* looks like: "ap:tN" */ 497 - static int do_ap_entry(const char *filename, 498 - void *symval, char *alias) 521 + static void do_ap_entry(struct module *mod, void *symval) 499 522 { 500 523 DEF_FIELD(symval, ap_device_id, dev_type); 501 524 502 - sprintf(alias, "ap:t%02X*", dev_type); 503 - return 1; 525 + module_alias_printf(mod, false, "ap:t%02X*", dev_type); 504 526 } 505 527 506 528 /* looks like: "css:tN" */ 507 - static int do_css_entry(const char *filename, 508 - void *symval, char *alias) 529 + static void do_css_entry(struct module *mod, void *symval) 509 530 { 510 531 DEF_FIELD(symval, css_device_id, type); 511 532 512 - sprintf(alias, "css:t%01X", type); 513 - return 1; 533 + module_alias_printf(mod, false, "css:t%01X", type); 514 534 } 515 535 516 536 /* Looks like: "serio:tyNprNidNexN" */ 517 - static int do_serio_entry(const char *filename, 518 - void *symval, char *alias) 537 + static void do_serio_entry(struct module *mod, void *symval) 519 538 { 539 + char alias[256] = {}; 540 + 520 541 DEF_FIELD(symval, serio_device_id, type); 521 542 DEF_FIELD(symval, serio_device_id, proto); 522 543 DEF_FIELD(symval, serio_device_id, id); 523 544 DEF_FIELD(symval, serio_device_id, extra); 524 545 525 - strcpy(alias, "serio:"); 526 546 ADD(alias, "ty", type != SERIO_ANY, type); 527 547 ADD(alias, "pr", proto != SERIO_ANY, proto); 528 548 ADD(alias, "id", id != SERIO_ANY, id); 529 549 ADD(alias, "ex", extra != SERIO_ANY, extra); 530 550 531 - add_wildcard(alias); 532 - return 1; 551 + module_alias_printf(mod, true, "serio:%s", alias); 533 552 } 534 553 535 554 /* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or ··· 534 563 * or _CLS. Also, bb, ss, and pp can be substituted with ?? 535 564 * as don't care byte. 536 565 */ 537 - static int do_acpi_entry(const char *filename, 538 - void *symval, char *alias) 566 + static void do_acpi_entry(struct module *mod, void *symval) 539 567 { 540 568 DEF_FIELD_ADDR(symval, acpi_device_id, id); 541 569 DEF_FIELD(symval, acpi_device_id, cls); 542 570 DEF_FIELD(symval, acpi_device_id, cls_msk); 543 571 544 - if (id && strlen((const char *)*id)) 545 - sprintf(alias, "acpi*:%s:*", *id); 572 + if ((*id)[0]) 573 + module_alias_printf(mod, false, "acpi*:%s:*", *id); 546 574 else { 575 + char alias[256]; 547 576 int i, byte_shift, cnt = 0; 548 577 unsigned int msk; 549 578 550 - sprintf(&alias[cnt], "acpi*:"); 551 - cnt = 6; 552 579 for (i = 1; i <= 3; i++) { 553 580 byte_shift = 8 * (3-i); 554 581 msk = (cls_msk >> byte_shift) & 0xFF; ··· 557 588 sprintf(&alias[cnt], "??"); 558 589 cnt += 2; 559 590 } 560 - sprintf(&alias[cnt], ":*"); 591 + module_alias_printf(mod, false, "acpi*:%s:*", alias); 561 592 } 562 - return 1; 563 593 } 564 594 565 595 /* looks like: "pnp:dD" */ 566 - static void do_pnp_device_entry(void *symval, unsigned long size, 567 - struct module *mod) 596 + static void do_pnp_device_entry(struct module *mod, void *symval) 568 597 { 569 - const unsigned long id_size = SIZE_pnp_device_id; 570 - const unsigned int count = (size / id_size)-1; 571 - unsigned int i; 598 + DEF_FIELD_ADDR(symval, pnp_device_id, id); 599 + char acpi_id[sizeof(*id)]; 572 600 573 - device_id_check(mod->name, "pnp", size, id_size, symval); 574 - 575 - for (i = 0; i < count; i++) { 576 - DEF_FIELD_ADDR(symval + i*id_size, pnp_device_id, id); 577 - char acpi_id[sizeof(*id)]; 578 - int j; 579 - 580 - buf_printf(&mod->dev_table_buf, 581 - "MODULE_ALIAS(\"pnp:d%s*\");\n", *id); 582 - 583 - /* fix broken pnp bus lowercasing */ 584 - for (j = 0; j < sizeof(acpi_id); j++) 585 - acpi_id[j] = toupper((*id)[j]); 586 - buf_printf(&mod->dev_table_buf, 587 - "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); 588 - } 601 + /* fix broken pnp bus lowercasing */ 602 + for (unsigned int i = 0; i < sizeof(acpi_id); i++) 603 + acpi_id[i] = toupper((*id)[i]); 604 + module_alias_printf(mod, false, "pnp:d%s*", *id); 605 + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); 589 606 } 590 607 591 608 /* looks like: "pnp:dD" for every device of the card */ 592 - static void do_pnp_card_entries(void *symval, unsigned long size, 593 - struct module *mod) 609 + static void do_pnp_card_entry(struct module *mod, void *symval) 594 610 { 595 - const unsigned long id_size = SIZE_pnp_card_device_id; 596 - const unsigned int count = (size / id_size)-1; 597 - unsigned int i; 611 + DEF_FIELD_ADDR(symval, pnp_card_device_id, devs); 598 612 599 - device_id_check(mod->name, "pnp", size, id_size, symval); 613 + for (unsigned int i = 0; i < PNP_MAX_DEVICES; i++) { 614 + const char *id = (char *)(*devs)[i].id; 615 + char acpi_id[PNP_ID_LEN]; 600 616 601 - for (i = 0; i < count; i++) { 602 - unsigned int j; 603 - DEF_FIELD_ADDR(symval + i * id_size, pnp_card_device_id, devs); 617 + if (!id[0]) 618 + break; 604 619 605 - for (j = 0; j < PNP_MAX_DEVICES; j++) { 606 - const char *id = (char *)(*devs)[j].id; 607 - int i2, j2; 608 - int dup = 0; 620 + /* fix broken pnp bus lowercasing */ 621 + for (unsigned int j = 0; j < sizeof(acpi_id); j++) 622 + acpi_id[j] = toupper(id[j]); 609 623 610 - if (!id[0]) 611 - break; 612 - 613 - /* find duplicate, already added value */ 614 - for (i2 = 0; i2 < i && !dup; i2++) { 615 - DEF_FIELD_ADDR_VAR(symval + i2 * id_size, 616 - pnp_card_device_id, 617 - devs, devs_dup); 618 - 619 - for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) { 620 - const char *id2 = 621 - (char *)(*devs_dup)[j2].id; 622 - 623 - if (!id2[0]) 624 - break; 625 - 626 - if (!strcmp(id, id2)) { 627 - dup = 1; 628 - break; 629 - } 630 - } 631 - } 632 - 633 - /* add an individual alias for every device entry */ 634 - if (!dup) { 635 - char acpi_id[PNP_ID_LEN]; 636 - int k; 637 - 638 - buf_printf(&mod->dev_table_buf, 639 - "MODULE_ALIAS(\"pnp:d%s*\");\n", id); 640 - 641 - /* fix broken pnp bus lowercasing */ 642 - for (k = 0; k < sizeof(acpi_id); k++) 643 - acpi_id[k] = toupper(id[k]); 644 - buf_printf(&mod->dev_table_buf, 645 - "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); 646 - } 647 - } 624 + /* add an individual alias for every device entry */ 625 + module_alias_printf(mod, false, "pnp:d%s*", id); 626 + module_alias_printf(mod, false, "acpi*:%s:*", acpi_id); 648 627 } 649 628 } 650 629 651 630 /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */ 652 - static int do_pcmcia_entry(const char *filename, 653 - void *symval, char *alias) 631 + static void do_pcmcia_entry(struct module *mod, void *symval) 654 632 { 633 + char alias[256] = {}; 655 634 unsigned int i; 656 635 DEF_FIELD(symval, pcmcia_device_id, match_flags); 657 636 DEF_FIELD(symval, pcmcia_device_id, manf_id); ··· 613 696 (*prod_id_hash)[i] = TO_NATIVE((*prod_id_hash)[i]); 614 697 } 615 698 616 - strcpy(alias, "pcmcia:"); 617 699 ADD(alias, "m", match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID, 618 700 manf_id); 619 701 ADD(alias, "c", match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID, ··· 628 712 ADD(alias, "pc", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, (*prod_id_hash)[2]); 629 713 ADD(alias, "pd", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, (*prod_id_hash)[3]); 630 714 631 - add_wildcard(alias); 632 - return 1; 715 + module_alias_printf(mod, true, "pcmcia:%s", alias); 633 716 } 634 717 635 - static int do_vio_entry(const char *filename, void *symval, 636 - char *alias) 718 + static void do_vio_entry(struct module *mod, void *symval) 637 719 { 720 + char alias[256]; 638 721 char *tmp; 639 722 DEF_FIELD_ADDR(symval, vio_device_id, type); 640 723 DEF_FIELD_ADDR(symval, vio_device_id, compat); ··· 646 731 if (isspace (*tmp)) 647 732 *tmp = '_'; 648 733 649 - add_wildcard(alias); 650 - return 1; 734 + module_alias_printf(mod, true, "%s", alias); 651 735 } 652 736 653 737 static void do_input(char *alias, ··· 662 748 } 663 749 664 750 /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ 665 - static int do_input_entry(const char *filename, void *symval, 666 - char *alias) 751 + static void do_input_entry(struct module *mod, void *symval) 667 752 { 753 + char alias[256] = {}; 754 + 668 755 DEF_FIELD(symval, input_device_id, flags); 669 756 DEF_FIELD(symval, input_device_id, bustype); 670 757 DEF_FIELD(symval, input_device_id, vendor); ··· 680 765 DEF_FIELD_ADDR(symval, input_device_id, sndbit); 681 766 DEF_FIELD_ADDR(symval, input_device_id, ffbit); 682 767 DEF_FIELD_ADDR(symval, input_device_id, swbit); 683 - 684 - sprintf(alias, "input:"); 685 768 686 769 ADD(alias, "b", flags & INPUT_DEVICE_ID_MATCH_BUS, bustype); 687 770 ADD(alias, "v", flags & INPUT_DEVICE_ID_MATCH_VENDOR, vendor); ··· 715 802 sprintf(alias + strlen(alias), "w*"); 716 803 if (flags & INPUT_DEVICE_ID_MATCH_SWBIT) 717 804 do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX); 718 - return 1; 805 + 806 + module_alias_printf(mod, false, "input:%s", alias); 719 807 } 720 808 721 - static int do_eisa_entry(const char *filename, void *symval, 722 - char *alias) 809 + static void do_eisa_entry(struct module *mod, void *symval) 723 810 { 724 811 DEF_FIELD_ADDR(symval, eisa_device_id, sig); 725 - if (sig[0]) 726 - sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig); 727 - else 728 - strcat(alias, "*"); 729 - return 1; 812 + module_alias_printf(mod, false, EISA_DEVICE_MODALIAS_FMT "*", *sig); 730 813 } 731 814 732 815 /* Looks like: parisc:tNhvNrevNsvN */ 733 - static int do_parisc_entry(const char *filename, void *symval, 734 - char *alias) 816 + static void do_parisc_entry(struct module *mod, void *symval) 735 817 { 818 + char alias[256] = {}; 819 + 736 820 DEF_FIELD(symval, parisc_device_id, hw_type); 737 821 DEF_FIELD(symval, parisc_device_id, hversion); 738 822 DEF_FIELD(symval, parisc_device_id, hversion_rev); 739 823 DEF_FIELD(symval, parisc_device_id, sversion); 740 824 741 - strcpy(alias, "parisc:"); 742 825 ADD(alias, "t", hw_type != PA_HWTYPE_ANY_ID, hw_type); 743 826 ADD(alias, "hv", hversion != PA_HVERSION_ANY_ID, hversion); 744 827 ADD(alias, "rev", hversion_rev != PA_HVERSION_REV_ANY_ID, hversion_rev); 745 828 ADD(alias, "sv", sversion != PA_SVERSION_ANY_ID, sversion); 746 829 747 - add_wildcard(alias); 748 - return 1; 830 + module_alias_printf(mod, true, "parisc:%s", alias); 749 831 } 750 832 751 833 /* Looks like: sdio:cNvNdN. */ 752 - static int do_sdio_entry(const char *filename, 753 - void *symval, char *alias) 834 + static void do_sdio_entry(struct module *mod, void *symval) 754 835 { 836 + char alias[256] = {}; 837 + 755 838 DEF_FIELD(symval, sdio_device_id, class); 756 839 DEF_FIELD(symval, sdio_device_id, vendor); 757 840 DEF_FIELD(symval, sdio_device_id, device); 758 841 759 - strcpy(alias, "sdio:"); 760 842 ADD(alias, "c", class != (__u8)SDIO_ANY_ID, class); 761 843 ADD(alias, "v", vendor != (__u16)SDIO_ANY_ID, vendor); 762 844 ADD(alias, "d", device != (__u16)SDIO_ANY_ID, device); 763 - add_wildcard(alias); 764 - return 1; 845 + 846 + module_alias_printf(mod, true, "sdio:%s", alias); 765 847 } 766 848 767 849 /* Looks like: ssb:vNidNrevN. */ 768 - static int do_ssb_entry(const char *filename, 769 - void *symval, char *alias) 850 + static void do_ssb_entry(struct module *mod, void *symval) 770 851 { 852 + char alias[256] = {}; 853 + 771 854 DEF_FIELD(symval, ssb_device_id, vendor); 772 855 DEF_FIELD(symval, ssb_device_id, coreid); 773 856 DEF_FIELD(symval, ssb_device_id, revision); 774 857 775 - strcpy(alias, "ssb:"); 776 858 ADD(alias, "v", vendor != SSB_ANY_VENDOR, vendor); 777 859 ADD(alias, "id", coreid != SSB_ANY_ID, coreid); 778 860 ADD(alias, "rev", revision != SSB_ANY_REV, revision); 779 - add_wildcard(alias); 780 - return 1; 861 + 862 + module_alias_printf(mod, true, "ssb:%s", alias); 781 863 } 782 864 783 865 /* Looks like: bcma:mNidNrevNclN. */ 784 - static int do_bcma_entry(const char *filename, 785 - void *symval, char *alias) 866 + static void do_bcma_entry(struct module *mod, void *symval) 786 867 { 868 + char alias[256] = {}; 869 + 787 870 DEF_FIELD(symval, bcma_device_id, manuf); 788 871 DEF_FIELD(symval, bcma_device_id, id); 789 872 DEF_FIELD(symval, bcma_device_id, rev); 790 873 DEF_FIELD(symval, bcma_device_id, class); 791 874 792 - strcpy(alias, "bcma:"); 793 875 ADD(alias, "m", manuf != BCMA_ANY_MANUF, manuf); 794 876 ADD(alias, "id", id != BCMA_ANY_ID, id); 795 877 ADD(alias, "rev", rev != BCMA_ANY_REV, rev); 796 878 ADD(alias, "cl", class != BCMA_ANY_CLASS, class); 797 - add_wildcard(alias); 798 - return 1; 879 + 880 + module_alias_printf(mod, true, "bcma:%s", alias); 799 881 } 800 882 801 883 /* Looks like: virtio:dNvN */ 802 - static int do_virtio_entry(const char *filename, void *symval, 803 - char *alias) 884 + static void do_virtio_entry(struct module *mod, void *symval) 804 885 { 886 + char alias[256] = {}; 887 + 805 888 DEF_FIELD(symval, virtio_device_id, device); 806 889 DEF_FIELD(symval, virtio_device_id, vendor); 807 890 808 - strcpy(alias, "virtio:"); 809 891 ADD(alias, "d", device != VIRTIO_DEV_ANY_ID, device); 810 892 ADD(alias, "v", vendor != VIRTIO_DEV_ANY_ID, vendor); 811 893 812 - add_wildcard(alias); 813 - return 1; 894 + module_alias_printf(mod, true, "virtio:%s", alias); 814 895 } 815 896 816 897 /* ··· 813 906 * in the name. 814 907 */ 815 908 816 - static int do_vmbus_entry(const char *filename, void *symval, 817 - char *alias) 909 + static void do_vmbus_entry(struct module *mod, void *symval) 818 910 { 819 911 int i; 820 912 DEF_FIELD_ADDR(symval, hv_vmbus_device_id, guid); ··· 822 916 for (i = 0; i < (sizeof(*guid) * 2); i += 2) 823 917 sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2])); 824 918 825 - strcpy(alias, "vmbus:"); 826 - strcat(alias, guid_name); 827 - 828 - return 1; 919 + module_alias_printf(mod, false, "vmbus:%s", guid_name); 829 920 } 830 921 831 922 /* Looks like: rpmsg:S */ 832 - static int do_rpmsg_entry(const char *filename, void *symval, 833 - char *alias) 923 + static void do_rpmsg_entry(struct module *mod, void *symval) 834 924 { 835 925 DEF_FIELD_ADDR(symval, rpmsg_device_id, name); 836 - sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name); 837 926 838 - return 1; 927 + module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name); 839 928 } 840 929 841 930 /* Looks like: i2c:S */ 842 - static int do_i2c_entry(const char *filename, void *symval, 843 - char *alias) 931 + static void do_i2c_entry(struct module *mod, void *symval) 844 932 { 845 933 DEF_FIELD_ADDR(symval, i2c_device_id, name); 846 - sprintf(alias, I2C_MODULE_PREFIX "%s", *name); 847 934 848 - return 1; 935 + module_alias_printf(mod, false, I2C_MODULE_PREFIX "%s", *name); 849 936 } 850 937 851 - static int do_i3c_entry(const char *filename, void *symval, 852 - char *alias) 938 + static void do_i3c_entry(struct module *mod, void *symval) 853 939 { 940 + char alias[256] = {}; 941 + 854 942 DEF_FIELD(symval, i3c_device_id, match_flags); 855 943 DEF_FIELD(symval, i3c_device_id, dcr); 856 944 DEF_FIELD(symval, i3c_device_id, manuf_id); 857 945 DEF_FIELD(symval, i3c_device_id, part_id); 858 946 DEF_FIELD(symval, i3c_device_id, extra_info); 859 947 860 - strcpy(alias, "i3c:"); 861 948 ADD(alias, "dcr", match_flags & I3C_MATCH_DCR, dcr); 862 949 ADD(alias, "manuf", match_flags & I3C_MATCH_MANUF, manuf_id); 863 950 ADD(alias, "part", match_flags & I3C_MATCH_PART, part_id); 864 951 ADD(alias, "ext", match_flags & I3C_MATCH_EXTRA_INFO, extra_info); 865 952 866 - return 1; 953 + module_alias_printf(mod, false, "i3c:%s", alias); 867 954 } 868 955 869 - static int do_slim_entry(const char *filename, void *symval, char *alias) 956 + static void do_slim_entry(struct module *mod, void *symval) 870 957 { 871 958 DEF_FIELD(symval, slim_device_id, manf_id); 872 959 DEF_FIELD(symval, slim_device_id, prod_code); 873 960 874 - sprintf(alias, "slim:%x:%x:*", manf_id, prod_code); 875 - 876 - return 1; 961 + module_alias_printf(mod, false, "slim:%x:%x:*", manf_id, prod_code); 877 962 } 878 963 879 964 /* Looks like: spi:S */ 880 - static int do_spi_entry(const char *filename, void *symval, 881 - char *alias) 965 + static void do_spi_entry(struct module *mod, void *symval) 882 966 { 883 967 DEF_FIELD_ADDR(symval, spi_device_id, name); 884 - sprintf(alias, SPI_MODULE_PREFIX "%s", *name); 885 968 886 - return 1; 969 + module_alias_printf(mod, false, SPI_MODULE_PREFIX "%s", *name); 887 970 } 888 971 889 972 static const struct dmifield { ··· 907 1012 } 908 1013 909 1014 910 - static int do_dmi_entry(const char *filename, void *symval, 911 - char *alias) 1015 + static void do_dmi_entry(struct module *mod, void *symval) 912 1016 { 1017 + char alias[256] = {}; 913 1018 int i, j; 914 1019 DEF_FIELD_ADDR(symval, dmi_system_id, matches); 915 - sprintf(alias, "dmi*"); 916 1020 917 1021 for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) { 918 1022 for (j = 0; j < 4; j++) { ··· 926 1032 } 927 1033 } 928 1034 929 - strcat(alias, ":"); 930 - return 1; 1035 + module_alias_printf(mod, false, "dmi*%s:", alias); 931 1036 } 932 1037 933 - static int do_platform_entry(const char *filename, 934 - void *symval, char *alias) 1038 + static void do_platform_entry(struct module *mod, void *symval) 935 1039 { 936 1040 DEF_FIELD_ADDR(symval, platform_device_id, name); 937 - sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name); 938 - return 1; 1041 + 1042 + module_alias_printf(mod, false, PLATFORM_MODULE_PREFIX "%s", *name); 939 1043 } 940 1044 941 - static int do_mdio_entry(const char *filename, 942 - void *symval, char *alias) 1045 + static void do_mdio_entry(struct module *mod, void *symval) 943 1046 { 1047 + char id[33]; 944 1048 int i; 945 1049 DEF_FIELD(symval, mdio_device_id, phy_id); 946 1050 DEF_FIELD(symval, mdio_device_id, phy_id_mask); 947 1051 948 - alias += sprintf(alias, MDIO_MODULE_PREFIX); 949 - 950 1052 for (i = 0; i < 32; i++) { 951 1053 if (!((phy_id_mask >> (31-i)) & 1)) 952 - *(alias++) = '?'; 1054 + id[i] = '?'; 953 1055 else if ((phy_id >> (31-i)) & 1) 954 - *(alias++) = '1'; 1056 + id[i] = '1'; 955 1057 else 956 - *(alias++) = '0'; 1058 + id[i] = '0'; 957 1059 } 958 1060 959 1061 /* Terminate the string */ 960 - *alias = 0; 1062 + id[32] = '\0'; 961 1063 962 - return 1; 1064 + module_alias_printf(mod, false, MDIO_MODULE_PREFIX "%s", id); 963 1065 } 964 1066 965 1067 /* Looks like: zorro:iN. */ 966 - static int do_zorro_entry(const char *filename, void *symval, 967 - char *alias) 1068 + static void do_zorro_entry(struct module *mod, void *symval) 968 1069 { 1070 + char alias[256] = {}; 969 1071 DEF_FIELD(symval, zorro_device_id, id); 970 - strcpy(alias, "zorro:"); 1072 + 971 1073 ADD(alias, "i", id != ZORRO_WILDCARD, id); 972 - return 1; 1074 + 1075 + module_alias_printf(mod, false, "zorro:%s", alias); 973 1076 } 974 1077 975 1078 /* looks like: "pnp:dD" */ 976 - static int do_isapnp_entry(const char *filename, 977 - void *symval, char *alias) 1079 + static void do_isapnp_entry(struct module *mod, void *symval) 978 1080 { 979 1081 DEF_FIELD(symval, isapnp_device_id, vendor); 980 1082 DEF_FIELD(symval, isapnp_device_id, function); 981 - sprintf(alias, "pnp:d%c%c%c%x%x%x%x*", 1083 + module_alias_printf(mod, false, "pnp:d%c%c%c%x%x%x%x*", 982 1084 'A' + ((vendor >> 2) & 0x3f) - 1, 983 1085 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, 984 1086 'A' + ((vendor >> 8) & 0x1f) - 1, 985 1087 (function >> 4) & 0x0f, function & 0x0f, 986 1088 (function >> 12) & 0x0f, (function >> 8) & 0x0f); 987 - return 1; 988 1089 } 989 1090 990 1091 /* Looks like: "ipack:fNvNdN". */ 991 - static int do_ipack_entry(const char *filename, 992 - void *symval, char *alias) 1092 + static void do_ipack_entry(struct module *mod, void *symval) 993 1093 { 1094 + char alias[256] = {}; 994 1095 DEF_FIELD(symval, ipack_device_id, format); 995 1096 DEF_FIELD(symval, ipack_device_id, vendor); 996 1097 DEF_FIELD(symval, ipack_device_id, device); 997 - strcpy(alias, "ipack:"); 1098 + 998 1099 ADD(alias, "f", format != IPACK_ANY_FORMAT, format); 999 1100 ADD(alias, "v", vendor != IPACK_ANY_ID, vendor); 1000 1101 ADD(alias, "d", device != IPACK_ANY_ID, device); 1001 - add_wildcard(alias); 1002 - return 1; 1102 + 1103 + module_alias_printf(mod, true, "ipack:%s", alias); 1003 1104 } 1004 1105 1005 1106 /* ··· 1045 1156 * N is exactly 8 digits, where each is an upper-case hex digit, or 1046 1157 * a ? or [] pattern matching exactly one digit. 1047 1158 */ 1048 - static int do_amba_entry(const char *filename, 1049 - void *symval, char *alias) 1159 + static void do_amba_entry(struct module *mod, void *symval) 1050 1160 { 1161 + char alias[256]; 1051 1162 unsigned int digit; 1052 1163 char *p = alias; 1053 1164 DEF_FIELD(symval, amba_id, id); ··· 1055 1166 1056 1167 if ((id & mask) != id) 1057 1168 fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: id=0x%08X, mask=0x%08X. Please fix this driver.\n", 1058 - filename, id, mask); 1169 + mod->name, id, mask); 1059 1170 1060 - p += sprintf(alias, "amba:d"); 1061 1171 for (digit = 0; digit < 8; digit++) 1062 1172 append_nibble_mask(&p, 1063 1173 (id >> (4 * (7 - digit))) & 0xf, 1064 1174 (mask >> (4 * (7 - digit))) & 0xf); 1065 1175 1066 - return 1; 1176 + module_alias_printf(mod, false, "amba:d%s", alias); 1067 1177 } 1068 1178 1069 1179 /* ··· 1071 1183 * N is exactly 2 digits, where each is an upper-case hex digit, or 1072 1184 * a ? or [] pattern matching exactly one digit. 1073 1185 */ 1074 - static int do_mips_cdmm_entry(const char *filename, 1075 - void *symval, char *alias) 1186 + static void do_mips_cdmm_entry(struct module *mod, void *symval) 1076 1187 { 1077 1188 DEF_FIELD(symval, mips_cdmm_device_id, type); 1078 1189 1079 - sprintf(alias, "mipscdmm:t%02X*", type); 1080 - return 1; 1190 + module_alias_printf(mod, false, "mipscdmm:t%02X*", type); 1081 1191 } 1082 1192 1083 1193 /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* ··· 1084 1198 * complicated. 1085 1199 */ 1086 1200 1087 - static int do_x86cpu_entry(const char *filename, void *symval, 1088 - char *alias) 1201 + static void do_x86cpu_entry(struct module *mod, void *symval) 1089 1202 { 1203 + char alias[256] = {}; 1204 + 1090 1205 DEF_FIELD(symval, x86_cpu_id, feature); 1091 1206 DEF_FIELD(symval, x86_cpu_id, family); 1092 1207 DEF_FIELD(symval, x86_cpu_id, model); 1093 1208 DEF_FIELD(symval, x86_cpu_id, vendor); 1094 1209 1095 - strcpy(alias, "cpu:type:x86,"); 1096 1210 ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor); 1097 1211 ADD(alias, "fam", family != X86_FAMILY_ANY, family); 1098 1212 ADD(alias, "mod", model != X86_MODEL_ANY, model); 1099 1213 strcat(alias, ":feature:*"); 1100 1214 if (feature != X86_FEATURE_ANY) 1101 1215 sprintf(alias + strlen(alias), "%04X*", feature); 1102 - return 1; 1216 + 1217 + module_alias_printf(mod, false, "cpu:type:x86,%s", alias); 1103 1218 } 1104 1219 1105 1220 /* LOOKS like cpu:type:*:feature:*FEAT* */ 1106 - static int do_cpu_entry(const char *filename, void *symval, char *alias) 1221 + static void do_cpu_entry(struct module *mod, void *symval) 1107 1222 { 1108 1223 DEF_FIELD(symval, cpu_feature, feature); 1109 1224 1110 - sprintf(alias, "cpu:type:*:feature:*%04X*", feature); 1111 - return 1; 1225 + module_alias_printf(mod, false, "cpu:type:*:feature:*%04X*", feature); 1112 1226 } 1113 1227 1114 1228 /* Looks like: mei:S:uuid:N:* */ 1115 - static int do_mei_entry(const char *filename, void *symval, 1116 - char *alias) 1229 + static void do_mei_entry(struct module *mod, void *symval) 1117 1230 { 1231 + char alias[256] = {}; 1232 + 1118 1233 DEF_FIELD_ADDR(symval, mei_cl_device_id, name); 1119 1234 DEF_FIELD_ADDR(symval, mei_cl_device_id, uuid); 1120 1235 DEF_FIELD(symval, mei_cl_device_id, version); 1121 1236 1122 - sprintf(alias, MEI_CL_MODULE_PREFIX); 1123 - sprintf(alias + strlen(alias), "%s:", (*name)[0] ? *name : "*"); 1124 1237 add_uuid(alias, *uuid); 1125 1238 ADD(alias, ":", version != MEI_CL_VERSION_ANY, version); 1126 1239 1127 - strcat(alias, ":*"); 1128 - 1129 - return 1; 1240 + module_alias_printf(mod, false, MEI_CL_MODULE_PREFIX "%s:%s:*", 1241 + (*name)[0] ? *name : "*", alias); 1130 1242 } 1131 1243 1132 1244 /* Looks like: rapidio:vNdNavNadN */ 1133 - static int do_rio_entry(const char *filename, 1134 - void *symval, char *alias) 1245 + static void do_rio_entry(struct module *mod, void *symval) 1135 1246 { 1247 + char alias[256] = {}; 1248 + 1136 1249 DEF_FIELD(symval, rio_device_id, did); 1137 1250 DEF_FIELD(symval, rio_device_id, vid); 1138 1251 DEF_FIELD(symval, rio_device_id, asm_did); 1139 1252 DEF_FIELD(symval, rio_device_id, asm_vid); 1140 1253 1141 - strcpy(alias, "rapidio:"); 1142 1254 ADD(alias, "v", vid != RIO_ANY_ID, vid); 1143 1255 ADD(alias, "d", did != RIO_ANY_ID, did); 1144 1256 ADD(alias, "av", asm_vid != RIO_ANY_ID, asm_vid); 1145 1257 ADD(alias, "ad", asm_did != RIO_ANY_ID, asm_did); 1146 1258 1147 - add_wildcard(alias); 1148 - return 1; 1259 + module_alias_printf(mod, true, "rapidio:%s", alias); 1149 1260 } 1150 1261 1151 1262 /* Looks like: ulpi:vNpN */ 1152 - static int do_ulpi_entry(const char *filename, void *symval, 1153 - char *alias) 1263 + static void do_ulpi_entry(struct module *mod, void *symval) 1154 1264 { 1155 1265 DEF_FIELD(symval, ulpi_device_id, vendor); 1156 1266 DEF_FIELD(symval, ulpi_device_id, product); 1157 1267 1158 - sprintf(alias, "ulpi:v%04xp%04x", vendor, product); 1159 - 1160 - return 1; 1268 + module_alias_printf(mod, false, "ulpi:v%04xp%04x", vendor, product); 1161 1269 } 1162 1270 1163 1271 /* Looks like: hdaudio:vNrNaN */ 1164 - static int do_hda_entry(const char *filename, void *symval, char *alias) 1272 + static void do_hda_entry(struct module *mod, void *symval) 1165 1273 { 1274 + char alias[256] = {}; 1275 + 1166 1276 DEF_FIELD(symval, hda_device_id, vendor_id); 1167 1277 DEF_FIELD(symval, hda_device_id, rev_id); 1168 1278 DEF_FIELD(symval, hda_device_id, api_version); 1169 1279 1170 - strcpy(alias, "hdaudio:"); 1171 1280 ADD(alias, "v", vendor_id != 0, vendor_id); 1172 1281 ADD(alias, "r", rev_id != 0, rev_id); 1173 1282 ADD(alias, "a", api_version != 0, api_version); 1174 1283 1175 - add_wildcard(alias); 1176 - return 1; 1284 + module_alias_printf(mod, true, "hdaudio:%s", alias); 1177 1285 } 1178 1286 1179 1287 /* Looks like: sdw:mNpNvNcN */ 1180 - static int do_sdw_entry(const char *filename, void *symval, char *alias) 1288 + static void do_sdw_entry(struct module *mod, void *symval) 1181 1289 { 1290 + char alias[256] = {}; 1291 + 1182 1292 DEF_FIELD(symval, sdw_device_id, mfg_id); 1183 1293 DEF_FIELD(symval, sdw_device_id, part_id); 1184 1294 DEF_FIELD(symval, sdw_device_id, sdw_version); 1185 1295 DEF_FIELD(symval, sdw_device_id, class_id); 1186 1296 1187 - strcpy(alias, "sdw:"); 1188 1297 ADD(alias, "m", mfg_id != 0, mfg_id); 1189 1298 ADD(alias, "p", part_id != 0, part_id); 1190 1299 ADD(alias, "v", sdw_version != 0, sdw_version); 1191 1300 ADD(alias, "c", class_id != 0, class_id); 1192 1301 1193 - add_wildcard(alias); 1194 - return 1; 1302 + module_alias_printf(mod, true, "sdw:%s", alias); 1195 1303 } 1196 1304 1197 1305 /* Looks like: fsl-mc:vNdN */ 1198 - static int do_fsl_mc_entry(const char *filename, void *symval, 1199 - char *alias) 1306 + static void do_fsl_mc_entry(struct module *mod, void *symval) 1200 1307 { 1201 1308 DEF_FIELD(symval, fsl_mc_device_id, vendor); 1202 1309 DEF_FIELD_ADDR(symval, fsl_mc_device_id, obj_type); 1203 1310 1204 - sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type); 1205 - return 1; 1311 + module_alias_printf(mod, false, "fsl-mc:v%08Xd%s", vendor, *obj_type); 1206 1312 } 1207 1313 1208 1314 /* Looks like: tbsvc:kSpNvNrN */ 1209 - static int do_tbsvc_entry(const char *filename, void *symval, char *alias) 1315 + static void do_tbsvc_entry(struct module *mod, void *symval) 1210 1316 { 1317 + char alias[256] = {}; 1318 + 1211 1319 DEF_FIELD(symval, tb_service_id, match_flags); 1212 1320 DEF_FIELD_ADDR(symval, tb_service_id, protocol_key); 1213 1321 DEF_FIELD(symval, tb_service_id, protocol_id); 1214 1322 DEF_FIELD(symval, tb_service_id, protocol_version); 1215 1323 DEF_FIELD(symval, tb_service_id, protocol_revision); 1216 1324 1217 - strcpy(alias, "tbsvc:"); 1218 1325 if (match_flags & TBSVC_MATCH_PROTOCOL_KEY) 1219 1326 sprintf(alias + strlen(alias), "k%s", *protocol_key); 1220 1327 else ··· 1218 1339 ADD(alias, "r", match_flags & TBSVC_MATCH_PROTOCOL_REVISION, 1219 1340 protocol_revision); 1220 1341 1221 - add_wildcard(alias); 1222 - return 1; 1342 + module_alias_printf(mod, true, "tbsvc:%s", alias); 1223 1343 } 1224 1344 1225 1345 /* Looks like: typec:idNmN */ 1226 - static int do_typec_entry(const char *filename, void *symval, char *alias) 1346 + static void do_typec_entry(struct module *mod, void *symval) 1227 1347 { 1348 + char alias[256] = {}; 1349 + 1228 1350 DEF_FIELD(symval, typec_device_id, svid); 1229 1351 DEF_FIELD(symval, typec_device_id, mode); 1230 1352 1231 - sprintf(alias, "typec:id%04X", svid); 1232 1353 ADD(alias, "m", mode != TYPEC_ANY_MODE, mode); 1233 1354 1234 - return 1; 1355 + module_alias_printf(mod, false, "typec:id%04X%s", svid, alias); 1235 1356 } 1236 1357 1237 1358 /* Looks like: tee:uuid */ 1238 - static int do_tee_entry(const char *filename, void *symval, char *alias) 1359 + static void do_tee_entry(struct module *mod, void *symval) 1239 1360 { 1240 1361 DEF_FIELD_ADDR(symval, tee_client_device_id, uuid); 1241 1362 1242 - sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", 1363 + module_alias_printf(mod, true, 1364 + "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", 1243 1365 uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], 1244 1366 uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], 1245 1367 uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], 1246 1368 uuid->b[15]); 1247 - 1248 - add_wildcard(alias); 1249 - return 1; 1250 1369 } 1251 1370 1252 1371 /* Looks like: wmi:guid */ 1253 - static int do_wmi_entry(const char *filename, void *symval, char *alias) 1372 + static void do_wmi_entry(struct module *mod, void *symval) 1254 1373 { 1255 - int len; 1256 1374 DEF_FIELD_ADDR(symval, wmi_device_id, guid_string); 1257 1375 1258 1376 if (strlen(*guid_string) != UUID_STRING_LEN) { 1259 1377 warn("Invalid WMI device id 'wmi:%s' in '%s'\n", 1260 - *guid_string, filename); 1261 - return 0; 1378 + *guid_string, mod->name); 1379 + return; 1262 1380 } 1263 1381 1264 - len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string); 1265 - if (len < 0 || len >= ALIAS_SIZE) { 1266 - warn("Could not generate all MODULE_ALIAS's in '%s'\n", 1267 - filename); 1268 - return 0; 1269 - } 1270 - return 1; 1382 + module_alias_printf(mod, false, WMI_MODULE_PREFIX "%s", *guid_string); 1271 1383 } 1272 1384 1273 1385 /* Looks like: mhi:S */ 1274 - static int do_mhi_entry(const char *filename, void *symval, char *alias) 1386 + static void do_mhi_entry(struct module *mod, void *symval) 1275 1387 { 1276 1388 DEF_FIELD_ADDR(symval, mhi_device_id, chan); 1277 - sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); 1278 - return 1; 1389 + module_alias_printf(mod, false, MHI_DEVICE_MODALIAS_FMT, *chan); 1279 1390 } 1280 1391 1281 1392 /* Looks like: mhi_ep:S */ 1282 - static int do_mhi_ep_entry(const char *filename, void *symval, char *alias) 1393 + static void do_mhi_ep_entry(struct module *mod, void *symval) 1283 1394 { 1284 1395 DEF_FIELD_ADDR(symval, mhi_device_id, chan); 1285 - sprintf(alias, MHI_EP_DEVICE_MODALIAS_FMT, *chan); 1286 1396 1287 - return 1; 1397 + module_alias_printf(mod, false, MHI_EP_DEVICE_MODALIAS_FMT, *chan); 1288 1398 } 1289 1399 1290 1400 /* Looks like: ishtp:{guid} */ 1291 - static int do_ishtp_entry(const char *filename, void *symval, char *alias) 1401 + static void do_ishtp_entry(struct module *mod, void *symval) 1292 1402 { 1403 + char alias[256] = {}; 1293 1404 DEF_FIELD_ADDR(symval, ishtp_device_id, guid); 1294 1405 1295 - strcpy(alias, ISHTP_MODULE_PREFIX "{"); 1296 1406 add_guid(alias, *guid); 1297 - strcat(alias, "}"); 1298 1407 1299 - return 1; 1408 + module_alias_printf(mod, false, ISHTP_MODULE_PREFIX "{%s}", alias); 1300 1409 } 1301 1410 1302 - static int do_auxiliary_entry(const char *filename, void *symval, char *alias) 1411 + static void do_auxiliary_entry(struct module *mod, void *symval) 1303 1412 { 1304 1413 DEF_FIELD_ADDR(symval, auxiliary_device_id, name); 1305 - sprintf(alias, AUXILIARY_MODULE_PREFIX "%s", *name); 1306 1414 1307 - return 1; 1415 + module_alias_printf(mod, false, AUXILIARY_MODULE_PREFIX "%s", *name); 1308 1416 } 1309 1417 1310 1418 /* ··· 1299 1433 * 1300 1434 * N is exactly 2 digits, where each is an upper-case hex digit. 1301 1435 */ 1302 - static int do_ssam_entry(const char *filename, void *symval, char *alias) 1436 + static void do_ssam_entry(struct module *mod, void *symval) 1303 1437 { 1438 + char alias[256] = {}; 1439 + 1304 1440 DEF_FIELD(symval, ssam_device_id, match_flags); 1305 1441 DEF_FIELD(symval, ssam_device_id, domain); 1306 1442 DEF_FIELD(symval, ssam_device_id, category); ··· 1310 1442 DEF_FIELD(symval, ssam_device_id, instance); 1311 1443 DEF_FIELD(symval, ssam_device_id, function); 1312 1444 1313 - sprintf(alias, "ssam:d%02Xc%02X", domain, category); 1314 1445 ADD(alias, "t", match_flags & SSAM_MATCH_TARGET, target); 1315 1446 ADD(alias, "i", match_flags & SSAM_MATCH_INSTANCE, instance); 1316 1447 ADD(alias, "f", match_flags & SSAM_MATCH_FUNCTION, function); 1317 1448 1318 - return 1; 1449 + module_alias_printf(mod, false, "ssam:d%02Xc%02X%s", 1450 + domain, category, alias); 1319 1451 } 1320 1452 1321 1453 /* Looks like: dfl:tNfN */ 1322 - static int do_dfl_entry(const char *filename, void *symval, char *alias) 1454 + static void do_dfl_entry(struct module *mod, void *symval) 1323 1455 { 1324 1456 DEF_FIELD(symval, dfl_device_id, type); 1325 1457 DEF_FIELD(symval, dfl_device_id, feature_id); 1326 1458 1327 - sprintf(alias, "dfl:t%04Xf%04X", type, feature_id); 1328 - 1329 - add_wildcard(alias); 1330 - return 1; 1459 + module_alias_printf(mod, true, "dfl:t%04Xf%04X", type, feature_id); 1331 1460 } 1332 1461 1333 1462 /* Looks like: cdx:vNdN */ 1334 - static int do_cdx_entry(const char *filename, void *symval, 1335 - char *alias) 1463 + static void do_cdx_entry(struct module *mod, void *symval) 1336 1464 { 1465 + char alias[256]; 1466 + 1337 1467 DEF_FIELD(symval, cdx_device_id, vendor); 1338 1468 DEF_FIELD(symval, cdx_device_id, device); 1339 1469 DEF_FIELD(symval, cdx_device_id, subvendor); ··· 1350 1484 default: 1351 1485 warn("Unknown CDX driver_override alias %08X\n", 1352 1486 override_only); 1353 - return 0; 1487 + return; 1354 1488 } 1355 1489 1356 1490 ADD(alias, "v", vendor != CDX_ANY_ID, vendor); ··· 1359 1493 ADD(alias, "sd", subdevice != CDX_ANY_ID, subdevice); 1360 1494 ADD(alias, "c", class_mask == 0xFFFFFF, class); 1361 1495 1362 - return 1; 1496 + module_alias_printf(mod, false, "%s", alias); 1363 1497 } 1364 1498 1365 - static int do_vchiq_entry(const char *filename, void *symval, char *alias) 1499 + static void do_vchiq_entry(struct module *mod, void *symval) 1366 1500 { 1367 1501 DEF_FIELD_ADDR(symval, vchiq_device_id, name); 1368 - sprintf(alias, "vchiq:%s", *name); 1369 1502 1370 - return 1; 1503 + module_alias_printf(mod, false, "vchiq:%s", *name); 1371 1504 } 1372 1505 1373 1506 /* Looks like: coreboot:tN */ 1374 - static int do_coreboot_entry(const char *filename, void *symval, char *alias) 1507 + static void do_coreboot_entry(struct module *mod, void *symval) 1375 1508 { 1376 1509 DEF_FIELD(symval, coreboot_device_id, tag); 1377 - sprintf(alias, "coreboot:t%08X", tag); 1378 1510 1379 - return 1; 1511 + module_alias_printf(mod, false, "coreboot:t%08X", tag); 1380 1512 } 1381 1513 1382 1514 /* Does namelen bytes of name exactly match the symbol? */ ··· 1386 1522 return memcmp(name, symbol, namelen) == 0; 1387 1523 } 1388 1524 1389 - static void do_table(void *symval, unsigned long size, 1525 + static void do_table(const char *name, void *symval, unsigned long size, 1390 1526 unsigned long id_size, 1391 1527 const char *device_id, 1392 - int (*do_entry)(const char *filename, void *symval, char *alias), 1528 + void (*do_entry)(struct module *mod, void *symval), 1393 1529 struct module *mod) 1394 1530 { 1395 1531 unsigned int i; 1396 - char alias[ALIAS_SIZE]; 1397 1532 1398 - device_id_check(mod->name, device_id, size, id_size, symval); 1533 + if (size % id_size || size < id_size) { 1534 + error("%s: type mismatch between %s[] and MODULE_DEVICE_TABLE(%s, ...)\n", 1535 + mod->name, name, device_id); 1536 + return; 1537 + } 1538 + 1539 + /* Verify the last entry is a terminator */ 1540 + for (i = size - id_size; i < size; i++) { 1541 + if (*(uint8_t *)(symval + i)) { 1542 + error("%s: %s[] is not terminated with a NULL entry\n", 1543 + mod->name, name); 1544 + return; 1545 + } 1546 + } 1547 + 1399 1548 /* Leave last one: it's the terminator. */ 1400 1549 size -= id_size; 1401 1550 1402 - for (i = 0; i < size; i += id_size) { 1403 - if (do_entry(mod->name, symval+i, alias)) { 1404 - buf_printf(&mod->dev_table_buf, 1405 - "MODULE_ALIAS(\"%s\");\n", alias); 1406 - } 1407 - } 1551 + for (i = 0; i < size; i += id_size) 1552 + do_entry(mod, symval + i); 1408 1553 } 1409 1554 1410 1555 static const struct devtable devtable[] = { ··· 1469 1596 {"cdx", SIZE_cdx_device_id, do_cdx_entry}, 1470 1597 {"vchiq", SIZE_vchiq_device_id, do_vchiq_entry}, 1471 1598 {"coreboot", SIZE_coreboot_device_id, do_coreboot_entry}, 1599 + {"of", SIZE_of_device_id, do_of_entry}, 1600 + {"usb", SIZE_usb_device_id, do_usb_entry_multi}, 1601 + {"pnp", SIZE_pnp_device_id, do_pnp_device_entry}, 1602 + {"pnp_card", SIZE_pnp_card_device_id, do_pnp_card_entry}, 1472 1603 }; 1473 1604 1474 1605 /* Create MODULE_ALIAS() statements. ··· 1483 1606 { 1484 1607 void *symval; 1485 1608 char *zeros = NULL; 1486 - const char *name, *identifier; 1487 - unsigned int namelen; 1609 + const char *type, *name; 1610 + size_t typelen; 1611 + static const char *prefix = "__mod_device_table__"; 1488 1612 1489 1613 /* We're looking for a section relative symbol */ 1490 1614 if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) ··· 1495 1617 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) 1496 1618 return; 1497 1619 1498 - /* All our symbols are of form __mod_<name>__<identifier>_device_table. */ 1499 - if (strncmp(symname, "__mod_", strlen("__mod_"))) 1620 + /* All our symbols are of form __mod_device_table__<type>__<name>. */ 1621 + if (!strstarts(symname, prefix)) 1500 1622 return; 1501 - name = symname + strlen("__mod_"); 1502 - namelen = strlen(name); 1503 - if (namelen < strlen("_device_table")) 1623 + type = symname + strlen(prefix); 1624 + 1625 + name = strstr(type, "__"); 1626 + if (!name) 1504 1627 return; 1505 - if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) 1506 - return; 1507 - identifier = strstr(name, "__"); 1508 - if (!identifier) 1509 - return; 1510 - namelen = identifier - name; 1628 + typelen = name - type; 1629 + name += strlen("__"); 1511 1630 1512 1631 /* Handle all-NULL symbols allocated into .bss */ 1513 1632 if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { ··· 1514 1639 symval = sym_get_data(info, sym); 1515 1640 } 1516 1641 1517 - /* First handle the "special" cases */ 1518 - if (sym_is(name, namelen, "usb")) 1519 - do_usb_table(symval, sym->st_size, mod); 1520 - else if (sym_is(name, namelen, "of")) 1521 - do_of_table(symval, sym->st_size, mod); 1522 - else if (sym_is(name, namelen, "pnp")) 1523 - do_pnp_device_entry(symval, sym->st_size, mod); 1524 - else if (sym_is(name, namelen, "pnp_card")) 1525 - do_pnp_card_entries(symval, sym->st_size, mod); 1526 - else { 1527 - int i; 1642 + for (int i = 0; i < ARRAY_SIZE(devtable); i++) { 1643 + const struct devtable *p = &devtable[i]; 1528 1644 1529 - for (i = 0; i < ARRAY_SIZE(devtable); i++) { 1530 - const struct devtable *p = &devtable[i]; 1531 - 1532 - if (sym_is(name, namelen, p->device_id)) { 1533 - do_table(symval, sym->st_size, p->id_size, 1534 - p->device_id, p->do_entry, mod); 1535 - break; 1536 - } 1645 + if (sym_is(type, typelen, p->device_id)) { 1646 + do_table(name, symval, sym->st_size, p->id_size, 1647 + p->device_id, p->do_entry, mod); 1648 + break; 1537 1649 } 1538 1650 } 1539 - free(zeros); 1540 - } 1541 1651 1542 - /* Now add out buffered information to the generated C source */ 1543 - void add_moddevtable(struct buffer *buf, struct module *mod) 1544 - { 1545 - buf_printf(buf, "\n"); 1546 - buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos); 1547 - free(mod->dev_table_buf.p); 1652 + free(zeros); 1548 1653 }
+13 -18
scripts/mod/modpost.c
··· 21 21 #include <stdbool.h> 22 22 #include <errno.h> 23 23 24 + #include <hash.h> 24 25 #include <hashtable.h> 25 26 #include <list.h> 26 27 #include <xalloc.h> ··· 177 176 INIT_LIST_HEAD(&mod->unresolved_symbols); 178 177 INIT_LIST_HEAD(&mod->missing_namespaces); 179 178 INIT_LIST_HEAD(&mod->imported_namespaces); 179 + INIT_LIST_HEAD(&mod->aliases); 180 180 181 181 memcpy(mod->name, name, namelen); 182 182 mod->name[namelen] = '\0'; ··· 211 209 212 210 static HASHTABLE_DEFINE(symbol_hashtable, 1U << 10); 213 211 214 - /* This is based on the hash algorithm from gdbm, via tdb */ 215 - static inline unsigned int tdb_hash(const char *name) 216 - { 217 - unsigned value; /* Used to compute the hash value. */ 218 - unsigned i; /* Used to cycle through random values. */ 219 - 220 - /* Set the initial value from the key size. */ 221 - for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) 222 - value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); 223 - 224 - return (1103515243 * value + 12345); 225 - } 226 - 227 212 /** 228 213 * Allocate a new symbols for use in the hash of exported symbols or 229 214 * the list of unresolved symbols per module ··· 228 239 /* For the hash of exported symbols */ 229 240 static void hash_add_symbol(struct symbol *sym) 230 241 { 231 - hash_add(symbol_hashtable, &sym->hnode, tdb_hash(sym->name)); 242 + hash_add(symbol_hashtable, &sym->hnode, hash_str(sym->name)); 232 243 } 233 244 234 245 static void sym_add_unresolved(const char *name, struct module *mod, bool weak) ··· 249 260 if (name[0] == '.') 250 261 name++; 251 262 252 - hash_for_each_possible(symbol_hashtable, s, hnode, tdb_hash(name)) { 263 + hash_for_each_possible(symbol_hashtable, s, hnode, hash_str(name)) { 253 264 if (strcmp(s->name, name) == 0 && (!mod || s->module == mod)) 254 265 return s; 255 266 } ··· 328 339 329 340 return sech_name(info, &info->sechdrs[secindex]); 330 341 } 331 - 332 - #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) 333 342 334 343 static struct symbol *sym_add_exported(const char *name, struct module *mod, 335 344 bool gpl_only, const char *namespace) ··· 1953 1966 static void write_mod_c_file(struct module *mod) 1954 1967 { 1955 1968 struct buffer buf = { }; 1969 + struct module_alias *alias, *next; 1956 1970 char fname[PATH_MAX]; 1957 1971 int ret; 1958 1972 ··· 1961 1973 add_exported_symbols(&buf, mod); 1962 1974 add_versions(&buf, mod); 1963 1975 add_depends(&buf, mod); 1964 - add_moddevtable(&buf, mod); 1976 + 1977 + buf_printf(&buf, "\n"); 1978 + list_for_each_entry_safe(alias, next, &mod->aliases, node) { 1979 + buf_printf(&buf, "MODULE_ALIAS(\"%s\");\n", alias->str); 1980 + list_del(&alias->node); 1981 + free(alias); 1982 + } 1983 + 1965 1984 add_srcversion(&buf, mod); 1966 1985 1967 1986 ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);
+19 -2
scripts/mod/modpost.h
··· 67 67 68 68 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 69 69 70 + #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) 71 + 70 72 struct buffer { 71 73 char *p; 72 74 int pos; ··· 81 79 void 82 80 buf_write(struct buffer *buf, const char *s, int len); 83 81 82 + /** 83 + * struct module_alias - auto-generated MODULE_ALIAS() 84 + * 85 + * @node: linked to module::aliases 86 + * @str: a string for MODULE_ALIAS() 87 + */ 88 + struct module_alias { 89 + struct list_head node; 90 + char str[]; 91 + }; 92 + 93 + /** 94 + * struct module - represent a module (vmlinux or *.ko) 95 + * 96 + * @aliases: list head for module_aliases 97 + */ 84 98 struct module { 85 99 struct list_head list; 86 100 struct list_head exported_symbols; ··· 107 89 bool seen; 108 90 bool has_init; 109 91 bool has_cleanup; 110 - struct buffer dev_table_buf; 111 92 char srcversion[25]; 112 93 // Missing namespace dependencies 113 94 struct list_head missing_namespaces; 114 95 // Actual imported namespaces 115 96 struct list_head imported_namespaces; 97 + struct list_head aliases; 116 98 char name[]; 117 99 }; 118 100 ··· 188 170 /* file2alias.c */ 189 171 void handle_moddevtable(struct module *mod, struct elf_info *info, 190 172 Elf_Sym *sym, const char *symname); 191 - void add_moddevtable(struct buffer *buf, struct module *mod); 192 173 193 174 /* sumversion.c */ 194 175 void get_src_version(const char *modname, char sum[], unsigned sumlen);
+2 -8
scripts/nsdeps
··· 19 19 exit 1 20 20 fi 21 21 22 - if [ "$KBUILD_EXTMOD" ]; then 23 - src_prefix= 24 - else 25 - src_prefix=$srctree/ 26 - fi 27 - 28 22 generate_deps_for_ns() { 29 23 $SPATCH --very-quiet --in-place --sp-file \ 30 24 $srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=$1 $2 ··· 28 34 local mod=${1%.ko:} 29 35 shift 30 36 local namespaces="$*" 31 - local mod_source_files=$(sed "s|^\(.*\)\.o$|${src_prefix}\1.c|" $mod.mod) 37 + local mod_source_files=$(sed "s|^\(.*\)\.o$|${srcroot}/\1.c|" $mod.mod) 32 38 33 39 for ns in $namespaces; do 34 40 echo "Adding namespace $ns to module $mod.ko." ··· 51 57 while read line 52 58 do 53 59 generate_deps $line 54 - done < $MODULES_NSDEPS 60 + done < modules.nsdeps
+11 -9
scripts/package/builddeb
··· 96 96 97 97 # Parse modules.order directly because 'make modules_install' may sign, 98 98 # compress modules, and then run unneeded depmod. 99 - while read -r mod; do 100 - mod="${mod%.o}.ko" 101 - dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}" 102 - buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p') 103 - link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug" 99 + if is_enabled CONFIG_MODULES; then 100 + while read -r mod; do 101 + mod="${mod%.o}.ko" 102 + dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}" 103 + buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p') 104 + link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug" 104 105 105 - mkdir -p "${dbg%/*}" "${link%/*}" 106 - "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}" 107 - ln -sf --relative "${dbg}" "${link}" 108 - done < modules.order 106 + mkdir -p "${dbg%/*}" "${link%/*}" 107 + "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}" 108 + ln -sf --relative "${dbg}" "${link}" 109 + done < modules.order 110 + fi 109 111 110 112 # Build debug package 111 113 # Different tools want the image in different locations
+7
scripts/package/install-extmod-build
··· 51 51 if [ "${CC}" != "${HOSTCC}" ]; then 52 52 echo "Rebuilding host programs with ${CC}..." 53 53 54 + # This leverages external module building. 55 + # - Clear sub_make_done to allow the top-level Makefile to redo sub-make. 56 + # - Filter out --no-print-directory to print "Entering directory" logs 57 + # when Make changes the working directory. 58 + unset sub_make_done 59 + MAKEFLAGS=$(echo "${MAKEFLAGS}" | sed s/--no-print-directory//) 60 + 54 61 cat <<-'EOF' > "${destdir}/Kbuild" 55 62 subdir-y := scripts 56 63 EOF
+1 -1
scripts/package/mkdebian
··· 202 202 gcc-${host_gnu} <!pkg.${sourcename}.nokernelheaders>, 203 203 kmod, libelf-dev:native, 204 204 libssl-dev:native, libssl-dev <!pkg.${sourcename}.nokernelheaders>, 205 - rsync 205 + python3:native, rsync 206 206 Homepage: https://www.kernel.org/ 207 207 208 208 Package: $packagename-$version
+42 -16
scripts/setlocalversion
··· 10 10 # 11 11 # 12 12 13 + set -e 14 + 13 15 usage() { 14 16 echo "Usage: $0 [--no-local] [srctree]" >&2 15 17 exit 1 ··· 31 29 if test $# -gt 0 -o ! -d "$srctree"; then 32 30 usage 33 31 fi 32 + 33 + try_tag() { 34 + tag="$1" 35 + 36 + # Is $tag an annotated tag? 37 + if [ "$(git cat-file -t "$tag" 2> /dev/null)" != tag ]; then 38 + return 39 + fi 40 + 41 + # Is it an ancestor of HEAD, and if so, how many commits are in $tag..HEAD? 42 + # shellcheck disable=SC2046 # word splitting is the point here 43 + set -- $(git rev-list --count --left-right "$tag"...HEAD 2> /dev/null) 44 + 45 + # $1 is 0 if and only if $tag is an ancestor of HEAD. Use 46 + # string comparison, because $1 is empty if the 'git rev-list' 47 + # command somehow failed. 48 + if [ "$1" != 0 ]; then 49 + return 50 + fi 51 + 52 + # $2 is the number of commits in the range $tag..HEAD, possibly 0. 53 + count="$2" 54 + } 34 55 35 56 scm_version() 36 57 { ··· 86 61 # stable kernel: 6.1.7 -> v6.1.7 87 62 version_tag=v$(echo "${KERNELVERSION}" | sed -E 's/^([0-9]+\.[0-9]+)\.0(.*)$/\1\2/') 88 63 64 + # try_tag initializes count if the tag is usable. 65 + count= 66 + 89 67 # If a localversion* file exists, and the corresponding 90 68 # annotated tag exists and is an ancestor of HEAD, use 91 69 # it. This is the case in linux-next. 92 - tag=${file_localversion#-} 93 - desc= 94 - if [ -n "${tag}" ]; then 95 - desc=$(git describe --match=$tag 2>/dev/null) 70 + if [ -n "${file_localversion#-}" ] ; then 71 + try_tag "${file_localversion#-}" 96 72 fi 97 73 98 74 # Otherwise, if a localversion* file exists, and the tag 99 75 # obtained by appending it to the tag derived from 100 76 # KERNELVERSION exists and is an ancestor of HEAD, use 101 77 # it. This is e.g. the case in linux-rt. 102 - if [ -z "${desc}" ] && [ -n "${file_localversion}" ]; then 103 - tag="${version_tag}${file_localversion}" 104 - desc=$(git describe --match=$tag 2>/dev/null) 78 + if [ -z "${count}" ] && [ -n "${file_localversion}" ]; then 79 + try_tag "${version_tag}${file_localversion}" 105 80 fi 106 81 107 82 # Otherwise, default to the annotated tag derived from KERNELVERSION. 108 - if [ -z "${desc}" ]; then 109 - tag="${version_tag}" 110 - desc=$(git describe --match=$tag 2>/dev/null) 83 + if [ -z "${count}" ]; then 84 + try_tag "${version_tag}" 111 85 fi 112 86 113 - # If we are at the tagged commit, we ignore it because the version is 114 - # well-defined. 115 - if [ "${tag}" != "${desc}" ]; then 87 + # If we are at the tagged commit, we ignore it because the 88 + # version is well-defined. If none of the attempted tags exist 89 + # or were usable, $count is still empty. 90 + if [ -z "${count}" ] || [ "${count}" -gt 0 ]; then 116 91 117 92 # If only the short version is requested, don't bother 118 93 # running further git commands ··· 120 95 echo "+" 121 96 return 122 97 fi 98 + 123 99 # If we are past the tagged commit, we pretty print it. 124 100 # (like 6.1.0-14595-g292a089d78d3) 125 - if [ -n "${desc}" ]; then 126 - echo "${desc}" | awk -F- '{printf("-%05d", $(NF-1))}' 101 + if [ -n "${count}" ]; then 102 + printf "%s%05d" "-" "${count}" 127 103 fi 128 104 129 105 # Add -g and exactly 12 hex chars. 130 - printf '%s%s' -g "$(echo $head | cut -c1-12)" 106 + printf '%s%.12s' -g "$head" 131 107 fi 132 108 133 109 if ${no_dirty}; then
+2
tools/objtool/check.c
··· 4573 4573 !strcmp(sec->name, "__jump_table") || 4574 4574 !strcmp(sec->name, "__mcount_loc") || 4575 4575 !strcmp(sec->name, ".kcfi_traps") || 4576 + !strcmp(sec->name, ".llvm.call-graph-profile") || 4577 + !strcmp(sec->name, ".llvm_bb_addr_map") || 4576 4578 !strcmp(sec->name, "__tracepoints") || 4577 4579 strstr(sec->name, "__patchable_function_entries")) 4578 4580 continue;
+10 -5
tools/objtool/elf.c
··· 224 224 if (n) 225 225 return 0; /* not a hole */ 226 226 227 - /* didn't find a symbol for which @offset is after it */ 228 - if (!hole.sym) 229 - return 0; /* not a hole */ 227 + /* 228 + * @offset >= sym->offset + sym->len, find symbol after it. 229 + * When hole.sym is empty, use the first node to compute the hole. 230 + * If there is no symbol in the section, the first node will be NULL, 231 + * in which case, -1 is returned to skip the whole section. 232 + */ 233 + if (hole.sym) 234 + n = rb_next(&hole.sym->node); 235 + else 236 + n = rb_first_cached(&sec->symbol_tree); 230 237 231 - /* @offset >= sym->offset + sym->len, find symbol after it */ 232 - n = rb_next(&hole.sym->node); 233 238 if (!n) 234 239 return -1; /* until end of address space */ 235 240