Kbuild updates for v6.13

- 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
 -----BEGIN PGP SIGNATURE-----
 
 iQJJBAABCgAzFiEEbmPs18K1szRHjPqEPYsBB53g2wYFAmdKGgEVHG1hc2FoaXJv
 eUBrZXJuZWwub3JnAAoJED2LAQed4NsGrFoQAIgioJPRG+HC6bGmjy4tL4bq1RAm
 78nbD12grrAa+NvQGRZYRs264rWxBGwrNfGGS9BDvlWJZ3fmKEuPlfCIxC0nkKk8
 LVLNxSVvgpHE47RQ+E4V+yYhrlZKb4aWZjH3ZICn7vxRgbQ5Veq61aatluVHyn9c
 I8g+APYN/S1A4JkFzaLe8GV7v5OM3+zGSn3M9n7/DxVkoiNrMOXJm5hRdRgYfEv/
 kMppheY2PPshZsaL+yLAdrJccY5au5vYE/v8wHkMtvM/LF6YwjgqPVDRFQ30BuLM
 sAMMd6AUoopiDZQOpqmXYukU0b0MQPswg3jmB+PWUBrlsuydRa8kkyPwUaFrDd+w
 9d0jZRc8/O/lxUdD1AefRkNcA/dIJ4lTPr+2NpxwHuj2UFo0gLQmtjBggMFHaWvs
 0NQRBPlxfOE4+Htl09gyg230kHuWq+rh7xqbyJCX+hBOaZ6kI2lryl6QkgpAoS+x
 KDOcUKnsgGMGARQRrvCOAXnQs+rjkW8fEm6t7eSBFPuWJMK85k4LmxOog8GVYEdM
 JcwCnCHt9TtcHlSxLRnVXj2aqGTFNLJXE1aLyCp9u8MxZ7qcx01xOuCmwp6FRzNq
 ghal7ngA58Y/S4K/oJ+CW2KupOb6CFne8mpyotpYeWI7MR64t0YWs4voZkuK46E2
 CEBfA4PDehA4BxQe
 =GDKD
 -----END PGP SIGNATURE-----

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()
  ...
This commit is contained in:
Linus Torvalds 2024-11-30 13:41:50 -08:00
commit 6a34dfa15d
73 changed files with 1478 additions and 1017 deletions

1
.gitignore vendored
View File

@ -129,6 +129,7 @@ series
# ctags files
tags
!tags/
TAGS
# cscope files

View File

@ -0,0 +1,168 @@
.. SPDX-License-Identifier: GPL-2.0
===================================
Using AutoFDO with the Linux kernel
===================================
This enables AutoFDO build support for the kernel when using
the Clang compiler. AutoFDO (Auto-Feedback-Directed Optimization)
is a type of profile-guided optimization (PGO) used to enhance the
performance of binary executables. It gathers information about the
frequency of execution of various code paths within a binary using
hardware sampling. This data is then used to guide the compiler's
optimization decisions, resulting in a more efficient binary. AutoFDO
is a powerful optimization technique, and data indicates that it can
significantly improve kernel performance. It's especially beneficial
for workloads affected by front-end stalls.
For AutoFDO builds, unlike non-FDO builds, the user must supply a
profile. Acquiring an AutoFDO profile can be done in several ways.
AutoFDO profiles are created by converting hardware sampling using
the "perf" tool. It is crucial that the workload used to create these
perf files is representative; they must exhibit runtime
characteristics similar to the workloads that are intended to be
optimized. Failure to do so will result in the compiler optimizing
for the wrong objective.
The AutoFDO profile often encapsulates the program's behavior. If the
performance-critical codes are architecture-independent, the profile
can be applied across platforms to achieve performance gains. For
instance, using the profile generated on Intel architecture to build
a kernel for AMD architecture can also yield performance improvements.
There are two methods for acquiring a representative profile:
(1) Sample real workloads using a production environment.
(2) Generate the profile using a representative load test.
When enabling the AutoFDO build configuration without providing an
AutoFDO profile, the compiler only modifies the dwarf information in
the kernel without impacting runtime performance. It's advisable to
use a kernel binary built with the same AutoFDO configuration to
collect the perf profile. While it's possible to use a kernel built
with different options, it may result in inferior performance.
One can collect profiles using AutoFDO build for the previous kernel.
AutoFDO employs relative line numbers to match the profiles, offering
some tolerance for source changes. This mode is commonly used in a
production environment for profile collection.
In a profile collection based on a load test, the AutoFDO collection
process consists of the following steps:
#. Initial build: The kernel is built with AutoFDO options
without a profile.
#. Profiling: The above kernel is then run with a representative
workload to gather execution frequency data. This data is
collected using hardware sampling, via perf. AutoFDO is most
effective on platforms supporting advanced PMU features like
LBR on Intel machines.
#. AutoFDO profile generation: Perf output file is converted to
the AutoFDO profile via offline tools.
The support requires a Clang compiler LLVM 17 or later.
Preparation
===========
Configure the kernel with::
CONFIG_AUTOFDO_CLANG=y
Customization
=============
The default CONFIG_AUTOFDO_CLANG setting covers kernel space objects for
AutoFDO builds. One can, however, enable or disable AutoFDO build for
individual files and directories by adding a line similar to the following
to the respective kernel Makefile:
- For enabling a single file (e.g. foo.o) ::
AUTOFDO_PROFILE_foo.o := y
- For enabling all files in one directory ::
AUTOFDO_PROFILE := y
- For disabling one file ::
AUTOFDO_PROFILE_foo.o := n
- For disabling all files in one directory ::
AUTOFDO_PROFILE := n
Workflow
========
Here is an example workflow for AutoFDO kernel:
1) Build the kernel on the host machine with LLVM enabled,
for example, ::
$ make menuconfig LLVM=1
Turn on AutoFDO build config::
CONFIG_AUTOFDO_CLANG=y
With a configuration that with LLVM enabled, use the following command::
$ scripts/config -e AUTOFDO_CLANG
After getting the config, build with ::
$ make LLVM=1
2) Install the kernel on the test machine.
3) Run the load tests. The '-c' option in perf specifies the sample
event period. We suggest using a suitable prime number, like 500009,
for this purpose.
- For Intel platforms::
$ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c <count> -o <perf_file> -- <loadtest>
- For AMD platforms:
The supported systems are: Zen3 with BRS, or Zen4 with amd_lbr_v2. To check,
For Zen3::
$ cat proc/cpuinfo | grep " brs"
For Zen4::
$ cat proc/cpuinfo | grep amd_lbr_v2
The following command generated the perf data file::
$ perf record --pfm-events RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c <count> -o <perf_file> -- <loadtest>
4) (Optional) Download the raw perf file to the host machine.
5) To generate an AutoFDO profile, two offline tools are available:
create_llvm_prof and llvm_profgen. The create_llvm_prof tool is part
of the AutoFDO project and can be found on GitHub
(https://github.com/google/autofdo), version v0.30.1 or later.
The llvm_profgen tool is included in the LLVM compiler itself. It's
important to note that the version of llvm_profgen doesn't need to match
the version of Clang. It needs to be the LLVM 19 release of Clang
or later, or just from the LLVM trunk. ::
$ llvm-profgen --kernel --binary=<vmlinux> --perfdata=<perf_file> -o <profile_file>
or ::
$ create_llvm_prof --binary=<vmlinux> --profile=<perf_file> --format=extbinary --out=<profile_file>
Note that multiple AutoFDO profile files can be merged into one via::
$ llvm-profdata merge -o <profile_file> <profile_1> <profile_2> ... <profile_n>
6) Rebuild the kernel using the AutoFDO profile file with the same config as step 1,
(Note CONFIG_AUTOFDO_CLANG needs to be enabled)::
$ make LLVM=1 CLANG_AUTOFDO_PROFILE=<profile_file>

View File

@ -250,25 +250,17 @@ variables for .cocciconfig is as follows:
- Your directory from which spatch is called is processed next
- The directory provided with the ``--dir`` option is processed last, if used
Since coccicheck runs through make, it naturally runs from the kernel
proper dir; as such the second rule above would be implied for picking up a
.cocciconfig when using ``make coccicheck``.
``make coccicheck`` also supports using M= targets. If you do not supply
any M= target, it is assumed you want to target the entire kernel.
The kernel coccicheck script has::
if [ "$KBUILD_EXTMOD" = "" ] ; then
OPTIONS="--dir $srctree $COCCIINCLUDE"
else
OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
fi
OPTIONS="--dir $srcroot $COCCIINCLUDE"
KBUILD_EXTMOD is set when an explicit target with M= is used. For both cases
the spatch ``--dir`` argument is used, as such third rule applies when whether
M= is used or not, and when M= is used the target directory can have its own
.cocciconfig file. When M= is not passed as an argument to coccicheck the
target directory is the same as the directory from where spatch was called.
Here, $srcroot refers to the source directory of the target: it points to the
external module's source directory when M= used, and otherwise, to the kernel
source directory. The third rule ensures the spatch reads the .cocciconfig from
the target directory, allowing external modules to have their own .cocciconfig
file.
If not using the kernel's coccicheck target, keep the above precedence
order logic of .cocciconfig reading. If using the kernel's coccicheck target,

View File

@ -34,6 +34,8 @@ Documentation/dev-tools/testing-overview.rst
ktap
checkuapi
gpio-sloppy-logic-analyzer
autofdo
propeller
.. only:: subproject and html

View File

@ -0,0 +1,162 @@
.. SPDX-License-Identifier: GPL-2.0
=====================================
Using Propeller with the Linux kernel
=====================================
This enables Propeller build support for the kernel when using Clang
compiler. Propeller is a profile-guided optimization (PGO) method used
to optimize binary executables. Like AutoFDO, it utilizes hardware
sampling to gather information about the frequency of execution of
different code paths within a binary. Unlike AutoFDO, this information
is then used right before linking phase to optimize (among others)
block layout within and across functions.
A few important notes about adopting Propeller optimization:
#. Although it can be used as a standalone optimization step, it is
strongly recommended to apply Propeller on top of AutoFDO,
AutoFDO+ThinLTO or Instrument FDO. The rest of this document
assumes this paradigm.
#. Propeller uses another round of profiling on top of
AutoFDO/AutoFDO+ThinLTO/iFDO. The whole build process involves
"build-afdo - train-afdo - build-propeller - train-propeller -
build-optimized".
#. Propeller requires LLVM 19 release or later for Clang/Clang++
and the linker(ld.lld).
#. In addition to LLVM toolchain, Propeller requires a profiling
conversion tool: https://github.com/google/autofdo with a release
after v0.30.1: https://github.com/google/autofdo/releases/tag/v0.30.1.
The Propeller optimization process involves the following steps:
#. Initial building: Build the AutoFDO or AutoFDO+ThinLTO binary as
you would normally do, but with a set of compile-time / link-time
flags, so that a special metadata section is created within the
kernel binary. The special section is only intend to be used by the
profiling tool, it is not part of the runtime image, nor does it
change kernel run time text sections.
#. Profiling: The above kernel is then run with a representative
workload to gather execution frequency data. This data is collected
using hardware sampling, via perf. Propeller is most effective on
platforms supporting advanced PMU features like LBR on Intel
machines. This step is the same as profiling the kernel for AutoFDO
(the exact perf parameters can be different).
#. Propeller profile generation: Perf output file is converted to a
pair of Propeller profiles via an offline tool.
#. Optimized build: Build the AutoFDO or AutoFDO+ThinLTO optimized
binary as you would normally do, but with a compile-time /
link-time flag to pick up the Propeller compile time and link time
profiles. This build step uses 3 profiles - the AutoFDO profile,
the Propeller compile-time profile and the Propeller link-time
profile.
#. Deployment: The optimized kernel binary is deployed and used
in production environments, providing improved performance
and reduced latency.
Preparation
===========
Configure the kernel with::
CONFIG_AUTOFDO_CLANG=y
CONFIG_PROPELLER_CLANG=y
Customization
=============
The default CONFIG_PROPELLER_CLANG setting covers kernel space objects
for Propeller builds. One can, however, enable or disable Propeller build
for individual files and directories by adding a line similar to the
following to the respective kernel Makefile:
- For enabling a single file (e.g. foo.o)::
PROPELLER_PROFILE_foo.o := y
- For enabling all files in one directory::
PROPELLER_PROFILE := y
- For disabling one file::
PROPELLER_PROFILE_foo.o := n
- For disabling all files in one directory::
PROPELLER__PROFILE := n
Workflow
========
Here is an example workflow for building an AutoFDO+Propeller kernel:
1) Assuming an AutoFDO profile is already collected following
instructions in the AutoFDO document, build the kernel on the host
machine, with AutoFDO and Propeller build configs ::
CONFIG_AUTOFDO_CLANG=y
CONFIG_PROPELLER_CLANG=y
and ::
$ make LLVM=1 CLANG_AUTOFDO_PROFILE=<autofdo-profile-name>
2) Install the kernel on the test machine.
3) Run the load tests. The '-c' option in perf specifies the sample
event period. We suggest using a suitable prime number, like 500009,
for this purpose.
- For Intel platforms::
$ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c <count> -o <perf_file> -- <loadtest>
- For AMD platforms::
$ perf record --pfm-event RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c <count> -o <perf_file> -- <loadtest>
Note you can repeat the above steps to collect multiple <perf_file>s.
4) (Optional) Download the raw perf file(s) to the host machine.
5) Use the create_llvm_prof tool (https://github.com/google/autofdo) to
generate Propeller profile. ::
$ create_llvm_prof --binary=<vmlinux> --profile=<perf_file>
--format=propeller --propeller_output_module_name
--out=<propeller_profile_prefix>_cc_profile.txt
--propeller_symorder=<propeller_profile_prefix>_ld_profile.txt
"<propeller_profile_prefix>" can be something like "/home/user/dir/any_string".
This command generates a pair of Propeller profiles:
"<propeller_profile_prefix>_cc_profile.txt" and
"<propeller_profile_prefix>_ld_profile.txt".
If there are more than 1 perf_file collected in the previous step,
you can create a temp list file "<perf_file_list>" with each line
containing one perf file name and run::
$ create_llvm_prof --binary=<vmlinux> --profile=@<perf_file_list>
--format=propeller --propeller_output_module_name
--out=<propeller_profile_prefix>_cc_profile.txt
--propeller_symorder=<propeller_profile_prefix>_ld_profile.txt
6) Rebuild the kernel using the AutoFDO and Propeller
profiles. ::
CONFIG_AUTOFDO_CLANG=y
CONFIG_PROPELLER_CLANG=y
and ::
$ make LLVM=1 CLANG_AUTOFDO_PROFILE=<profile_file> CLANG_PROPELLER_PROFILE_PREFIX=<propeller_profile_prefix>

View File

@ -137,12 +137,18 @@ Specify the output directory when building the kernel.
This variable can also be used to point to the kernel output directory when
building external modules against a pre-built kernel in a separate build
directory. Please note that this does NOT specify the output directory for the
external modules themselves.
external modules themselves. (Use KBUILD_EXTMOD_OUTPUT for that purpose.)
The output directory can also be specified using "O=...".
Setting "O=..." takes precedence over KBUILD_OUTPUT.
KBUILD_EXTMOD_OUTPUT
--------------------
Specify the output directory for external modules.
Setting "MO=..." takes precedence over KBUILD_EXTMOD_OUTPUT.
KBUILD_EXTRA_WARN
-----------------
Specify the extra build checks. The same value can be assigned by passing

View File

@ -412,8 +412,8 @@ choices::
<choice block>
"endchoice"
This defines a choice group and accepts any of the above attributes as
options.
This defines a choice group and accepts "prompt", "default", "depends on", and
"help" attributes as options.
A choice only allows a single config entry to be selected.

View File

@ -449,6 +449,20 @@ $(obj)
to prerequisites are referenced with $(src) (because they are not
generated files).
$(srcroot)
$(srcroot) refers to the root of the source you are building, which can be
either the kernel source or the external modules source, depending on whether
KBUILD_EXTMOD is set. This can be either a relative or an absolute path, but
if KBUILD_ABS_SRCTREE=1 is set, it is always an absolute path.
$(srctree)
$(srctree) refers to the root of the kernel source tree. When building the
kernel, this is the same as $(srcroot).
$(objtree)
$(objtree) refers to the root of the kernel object tree. It is ``.`` when
building the kernel, but it is different when building external modules.
$(kecho)
echoing information to user in a rule is often a good practice
but when execution ``make -s`` one does not expect to see any output

View File

@ -59,6 +59,12 @@ Command Syntax
$ make -C /lib/modules/`uname -r`/build M=$PWD modules_install
Starting from Linux 6.13, you can use the -f option instead of -C. This
will avoid unnecessary change of the working directory. The external
module will be output to the directory where you invoke make.
$ make -f /lib/modules/`uname -r`/build/Makefile M=$PWD
Options
-------
@ -66,7 +72,10 @@ Options
of the kernel output directory if the kernel was built in a separate
build directory.)
make -C $KDIR M=$PWD
You can optionally pass MO= option if you want to build the modules in
a separate directory.
make -C $KDIR M=$PWD [MO=$BUILD_DIR]
-C $KDIR
The directory that contains the kernel and relevant build
@ -80,6 +89,9 @@ Options
directory where the external module (kbuild file) is
located.
MO=$BUILD_DIR
Specifies a separate output directory for the external module.
Targets
-------
@ -215,6 +227,21 @@ Separate Kbuild File and Makefile
consisting of several hundred lines, and here it really pays
off to separate the kbuild part from the rest.
Linux 6.13 and later support another way. The external module Makefile
can include the kernel Makefile directly, rather than invoking sub Make.
Example 3::
--> filename: Kbuild
obj-m := 8123.o
8123-y := 8123_if.o 8123_pci.o
--> filename: Makefile
KDIR ?= /lib/modules/$(shell uname -r)/build
export KBUILD_EXTMOD := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
include $(KDIR)/Makefile
Building Multiple Modules
-------------------------

View File

@ -3715,6 +3715,13 @@ F: kernel/audit*
F: lib/*audit.c
K: \baudit_[a-z_0-9]\+\b
AUTOFDO BUILD
M: Rong Xu <xur@google.com>
M: Han Shen <shenhan@google.com>
S: Supported
F: Documentation/dev-tools/autofdo.rst
F: scripts/Makefile.autofdo
AUXILIARY BUS DRIVER
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
R: Dave Ertman <david.m.ertman@intel.com>
@ -18708,6 +18715,13 @@ S: Maintained
F: include/linux/psi*
F: kernel/sched/psi.c
PROPELLER BUILD
M: Rong Xu <xur@google.com>
M: Han Shen <shenhan@google.com>
S: Supported
F: Documentation/dev-tools/propeller.rst
F: scripts/Makefile.propeller
PRINTK
M: Petr Mladek <pmladek@suse.com>
R: Steven Rostedt <rostedt@goodmis.org>

221
Makefile
View File

@ -40,7 +40,7 @@ __all:
this-makefile := $(lastword $(MAKEFILE_LIST))
abs_srctree := $(realpath $(dir $(this-makefile)))
abs_objtree := $(CURDIR)
abs_output := $(CURDIR)
ifneq ($(sub_make_done),1)
@ -134,6 +134,10 @@ ifeq ("$(origin M)", "command line")
KBUILD_EXTMOD := $(M)
endif
ifeq ("$(origin MO)", "command line")
KBUILD_EXTMOD_OUTPUT := $(MO)
endif
$(if $(word 2, $(KBUILD_EXTMOD)), \
$(error building multiple external modules is not supported))
@ -176,18 +180,41 @@ export KBUILD_EXTRA_WARN
# The O= assignment takes precedence over the KBUILD_OUTPUT environment
# variable.
# Do we want to change the working directory?
ifeq ("$(origin O)", "command line")
KBUILD_OUTPUT := $(O)
endif
ifneq ($(KBUILD_OUTPUT),)
ifdef KBUILD_EXTMOD
ifdef KBUILD_OUTPUT
objtree := $(realpath $(KBUILD_OUTPUT))
$(if $(objtree),,$(error specified kernel directory "$(KBUILD_OUTPUT)" does not exist))
else
objtree := $(abs_srctree)
endif
# If Make is invoked from the kernel directory (either kernel
# source directory or kernel build directory), external modules
# are built in $(KBUILD_EXTMOD) for backward compatibility,
# otherwise, built in the current directory.
output := $(or $(KBUILD_EXTMOD_OUTPUT),$(if $(filter $(CURDIR),$(objtree) $(abs_srctree)),$(KBUILD_EXTMOD)))
# KBUILD_EXTMOD might be a relative path. Remember its absolute path before
# Make changes the working directory.
srcroot := $(realpath $(KBUILD_EXTMOD))
$(if $(srcroot),,$(error specified external module directory "$(KBUILD_EXTMOD)" does not exist))
else
objtree := .
output := $(KBUILD_OUTPUT)
endif
export objtree srcroot
# Do we want to change the working directory?
ifneq ($(output),)
# $(realpath ...) gets empty if the path does not exist. Run 'mkdir -p' first.
$(shell mkdir -p "$(KBUILD_OUTPUT)")
$(shell mkdir -p "$(output)")
# $(realpath ...) resolves symlinks
abs_objtree := $(realpath $(KBUILD_OUTPUT))
$(if $(abs_objtree),,$(error failed to create output directory "$(KBUILD_OUTPUT)"))
endif # ifneq ($(KBUILD_OUTPUT),)
abs_output := $(realpath $(output))
$(if $(abs_output),,$(error failed to create output directory "$(output)"))
endif
ifneq ($(words $(subst :, ,$(abs_srctree))), 1)
$(error source directory cannot contain spaces or colons)
@ -197,7 +224,7 @@ export sub_make_done := 1
endif # sub_make_done
ifeq ($(abs_objtree),$(CURDIR))
ifeq ($(abs_output),$(CURDIR))
# Suppress "Entering directory ..." if we are at the final work directory.
no-print-directory := --no-print-directory
else
@ -221,42 +248,40 @@ $(filter-out $(this-makefile), $(MAKECMDGOALS)) __all: __sub-make
# Invoke a second make in the output directory, passing relevant variables
__sub-make:
$(Q)$(MAKE) $(no-print-directory) -C $(abs_objtree) \
$(Q)$(MAKE) $(no-print-directory) -C $(abs_output) \
-f $(abs_srctree)/Makefile $(MAKECMDGOALS)
else # need-sub-make
# We process the rest of the Makefile if this is the final invocation of make
ifeq ($(abs_srctree),$(abs_objtree))
# building in the source tree
srctree := .
building_out_of_srctree :=
ifndef KBUILD_EXTMOD
srcroot := $(abs_srctree)
endif
ifeq ($(srcroot),$(CURDIR))
building_out_of_srctree :=
else
ifeq ($(abs_srctree)/,$(dir $(abs_objtree)))
# building in a subdirectory of the source tree
srctree := ..
else
srctree := $(abs_srctree)
endif
building_out_of_srctree := 1
export building_out_of_srctree := 1
endif
ifneq ($(KBUILD_ABS_SRCTREE),)
srctree := $(abs_srctree)
ifdef KBUILD_ABS_SRCTREE
# Do nothing. Use the absolute path.
else ifeq ($(srcroot),$(CURDIR))
# Building in the source.
srcroot := .
else ifeq ($(srcroot)/,$(dir $(CURDIR)))
# Building in a subdirectory of the source.
srcroot := ..
endif
objtree := .
export srctree := $(if $(KBUILD_EXTMOD),$(abs_srctree),$(srcroot))
VPATH :=
ifeq ($(KBUILD_EXTMOD),)
ifdef building_out_of_srctree
VPATH := $(srctree)
export VPATH := $(srcroot)
else
VPATH :=
endif
endif
export building_out_of_srctree srctree objtree VPATH
# To make sure we do not include .config for any of the *config targets
# catch them early, and hand them over to scripts/kconfig/Makefile
@ -276,7 +301,7 @@ no-dot-config-targets := $(clean-targets) \
outputmakefile rustavailable rustfmt rustfmtcheck
no-sync-config-targets := $(no-dot-config-targets) %install modules_sign kernelrelease \
image_name
single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %.symtypes %/
single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.rsi %.s %/
config-build :=
mixed-build :=
@ -354,7 +379,7 @@ else # !mixed-build
include $(srctree)/scripts/Kbuild.include
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
KERNELRELEASE = $(call read-file, include/config/kernel.release)
KERNELRELEASE = $(call read-file, $(objtree)/include/config/kernel.release)
KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
@ -513,7 +538,7 @@ KGZIP = gzip
KBZIP2 = bzip2
KLZOP = lzop
LZMA = lzma
LZ4 = lz4c
LZ4 = lz4
XZ = xz
ZSTD = zstd
@ -543,7 +568,7 @@ USERINCLUDE := \
LINUXINCLUDE := \
-I$(srctree)/arch/$(SRCARCH)/include \
-I$(objtree)/arch/$(SRCARCH)/include/generated \
$(if $(building_out_of_srctree),-I$(srctree)/include) \
-I$(srctree)/include \
-I$(objtree)/include \
$(USERINCLUDE)
@ -629,13 +654,25 @@ ifdef building_out_of_srctree
# At the same time when output Makefile generated, generate .gitignore to
# ignore whole output directory
ifdef KBUILD_EXTMOD
print_env_for_makefile = \
echo "export KBUILD_OUTPUT = $(objtree)"; \
echo "export KBUILD_EXTMOD = $(realpath $(srcroot))" ; \
echo "export KBUILD_EXTMOD_OUTPUT = $(CURDIR)"
else
print_env_for_makefile = \
echo "export KBUILD_OUTPUT = $(CURDIR)"
endif
quiet_cmd_makefile = GEN Makefile
cmd_makefile = { \
echo "\# Automatically generated by $(srctree)/Makefile: don't edit"; \
echo "include $(srctree)/Makefile"; \
echo "\# Automatically generated by $(abs_srctree)/Makefile: don't edit"; \
$(print_env_for_makefile); \
echo "include $(abs_srctree)/Makefile"; \
} > Makefile
outputmakefile:
ifeq ($(KBUILD_EXTMOD),)
@if [ -f $(srctree)/.config -o \
-d $(srctree)/include/config -o \
-d $(srctree)/arch/$(SRCARCH)/include/generated ]; then \
@ -645,7 +682,16 @@ outputmakefile:
echo >&2 "***"; \
false; \
fi
$(Q)ln -fsn $(srctree) source
else
@if [ -f $(srcroot)/modules.order ]; then \
echo >&2 "***"; \
echo >&2 "*** The external module source tree is not clean."; \
echo >&2 "*** Please run 'make -C $(abs_srctree) M=$(realpath $(srcroot)) clean'"; \
echo >&2 "***"; \
false; \
fi
endif
$(Q)ln -fsn $(srcroot) source
$(call cmd,makefile)
$(Q)test -e .gitignore || \
{ echo "# this is build directory, ignore it"; echo "*"; } > .gitignore
@ -717,7 +763,7 @@ endif
# in addition to whatever we do anyway.
# Just "make" or "make all" shall build modules as well
ifneq ($(filter all modules nsdeps %compile_commands.json clang-%,$(MAKECMDGOALS)),)
ifneq ($(filter all modules nsdeps compile_commands.json clang-%,$(MAKECMDGOALS)),)
KBUILD_MODULES := 1
endif
@ -728,7 +774,7 @@ endif
export KBUILD_MODULES KBUILD_BUILTIN
ifdef need-config
include include/config/auto.conf
include $(objtree)/include/config/auto.conf
endif
ifeq ($(KBUILD_EXTMOD),)
@ -789,17 +835,22 @@ $(KCONFIG_CONFIG):
else # !may-sync-config
# External modules and some install targets need include/generated/autoconf.h
# and include/config/auto.conf but do not care if they are up-to-date.
# Use auto.conf to trigger the test
PHONY += include/config/auto.conf
# Use auto.conf to show the error message
include/config/auto.conf:
@test -e include/generated/autoconf.h -a -e $@ || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or $@ are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
checked-configs := $(addprefix $(objtree)/, include/generated/autoconf.h include/generated/rustc_cfg include/config/auto.conf)
missing-configs := $(filter-out $(wildcard $(checked-configs)), $(checked-configs))
ifdef missing-configs
PHONY += $(objtree)/include/config/auto.conf
$(objtree)/include/config/auto.conf:
@echo >&2 '***'
@echo >&2 '*** ERROR: Kernel configuration is invalid. The following files are missing:'
@printf >&2 '*** - %s\n' $(missing-configs)
@echo >&2 '*** Run "make oldconfig && make prepare" on kernel source to fix it.'
@echo >&2 '***'
@/bin/false
endif
endif # may-sync-config
endif # need-config
@ -1013,8 +1064,10 @@ ifdef CONFIG_CC_IS_GCC
KBUILD_CFLAGS += -fconserve-stack
endif
# change __FILE__ to the relative path from the srctree
KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
# change __FILE__ to the relative path to the source directory
ifdef building_out_of_srctree
KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=)
endif
# include additional Makefiles when needed
include-y := scripts/Makefile.extrawarn
@ -1026,6 +1079,8 @@ include-$(CONFIG_KMSAN) += scripts/Makefile.kmsan
include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan
include-$(CONFIG_KCOV) += scripts/Makefile.kcov
include-$(CONFIG_RANDSTRUCT) += scripts/Makefile.randstruct
include-$(CONFIG_AUTOFDO_CLANG) += scripts/Makefile.autofdo
include-$(CONFIG_PROPELLER_CLANG) += scripts/Makefile.propeller
include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins
include $(addprefix $(srctree)/, $(include-y))
@ -1106,10 +1161,6 @@ export MODLIB
PHONY += prepare0
export extmod_prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)
export MODORDER := $(extmod_prefix)modules.order
export MODULES_NSDEPS := $(extmod_prefix)modules.nsdeps
ifeq ($(KBUILD_EXTMOD),)
build-dir := .
@ -1204,7 +1255,8 @@ PHONY += prepare archprepare
archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \
asm-generic $(version_h) include/generated/utsrelease.h \
include/generated/compile.h include/generated/autoconf.h remove-stale-files
include/generated/compile.h include/generated/autoconf.h \
include/generated/rustc_cfg remove-stale-files
prepare0: archprepare
$(Q)$(MAKE) $(build)=scripts/mod
@ -1435,6 +1487,10 @@ ifdef CONFIG_OF_EARLY_FLATTREE
all: dtbs
endif
ifdef CONFIG_GENERIC_BUILTIN_DTB
vmlinux: dtbs
endif
endif
PHONY += scripts_dtc
@ -1502,7 +1558,8 @@ CLEAN_FILES += vmlinux.symvers modules-only.symvers \
modules.builtin modules.builtin.modinfo modules.nsdeps \
modules.builtin.ranges vmlinux.o.map \
compile_commands.json rust/test \
rust-project.json .vmlinux.objs .vmlinux.export.c
rust-project.json .vmlinux.objs .vmlinux.export.c \
.builtin-dtbs-list .builtin-dtb.S
# Directories & files removed with 'make mrproper'
MRPROPER_FILES += include/config include/generated \
@ -1750,18 +1807,9 @@ rusttest: prepare
# Formatting targets
PHONY += rustfmt rustfmtcheck
# We skip `rust/alloc` since we want to minimize the diff w.r.t. upstream.
#
# We match using absolute paths since `find` does not resolve them
# when matching, which is a problem when e.g. `srctree` is `..`.
# We `grep` afterwards in order to remove the directory entry itself.
rustfmt:
$(Q)find $(abs_srctree) -type f -name '*.rs' \
-o -path $(abs_srctree)/rust/alloc -prune \
-o -path $(abs_objtree)/rust/test -prune \
| grep -Fv $(abs_srctree)/rust/alloc \
| grep -Fv $(abs_objtree)/rust/test \
| grep -Fv generated \
$(Q)find $(srctree) $(RCS_FIND_IGNORE) \
-type f -a -name '*.rs' -a ! -name '*generated*' -print \
| xargs $(RUSTFMT) $(rustfmt_flags)
rustfmtcheck: rustfmt_flags = --check
@ -1800,14 +1848,10 @@ filechk_kernel.release = echo $(KERNELRELEASE)
KBUILD_BUILTIN :=
KBUILD_MODULES := 1
build-dir := $(KBUILD_EXTMOD)
build-dir := .
compile_commands.json: $(extmod_prefix)compile_commands.json
PHONY += compile_commands.json
clean-dirs := $(KBUILD_EXTMOD)
clean: private rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \
$(KBUILD_EXTMOD)/compile_commands.json
clean-dirs := .
clean: private rm-files := Module.symvers modules.nsdeps compile_commands.json
PHONY += prepare
# now expand this into a simple variable to reduce the cost of shell evaluations
@ -1866,7 +1910,7 @@ endif
ifdef CONFIG_MODULES
$(MODORDER): $(build-dir)
modules.order: $(build-dir)
@:
# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
@ -1877,7 +1921,7 @@ ifneq ($(KBUILD_MODPOST_NOFINAL),1)
endif
PHONY += modules_check
modules_check: $(MODORDER)
modules_check: modules.order
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/modules-check.sh $<
else # CONFIG_MODULES
@ -1918,15 +1962,15 @@ $(single-ko): single_modules
$(single-no-ko): $(build-dir)
@:
# Remove MODORDER when done because it is not the real one.
# Remove modules.order when done because it is not the real one.
PHONY += single_modules
single_modules: $(single-no-ko) modules_prepare
$(Q){ $(foreach m, $(single-ko), echo $(extmod_prefix)$(m:%.ko=%.o);) } > $(MODORDER)
$(Q){ $(foreach m, $(single-ko), echo $(m:%.ko=%.o);) } > modules.order
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
ifneq ($(KBUILD_MODPOST_NOFINAL),1)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal
endif
$(Q)rm -f $(MODORDER)
$(Q)rm -f modules.order
single-goals := $(addprefix $(build-dir)/, $(single-no-ko))
@ -1934,6 +1978,8 @@ KBUILD_MODULES := 1
endif
prepare: outputmakefile
# Preset locale variables to speed up the build process. Limit locale
# tweaks to this spot to avoid wrong language settings when running
# make menuconfig etc.
@ -1949,7 +1995,7 @@ $(clean-dirs):
clean: $(clean-dirs)
$(call cmd,rmfiles)
@find $(or $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
@find . $(RCS_FIND_IGNORE) \
\( -name '*.[aios]' -o -name '*.rsi' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '*.ko.*' \
-o -name '*.dtb' -o -name '*.dtbo' \
@ -1982,7 +2028,12 @@ tags TAGS cscope gtags: FORCE
PHONY += rust-analyzer
rust-analyzer:
+$(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh
ifdef KBUILD_EXTMOD
# FIXME: external modules must not descend into a sub-directory of the kernel
$(Q)$(MAKE) $(build)=$(objtree)/rust src=$(srctree)/rust $@
else
$(Q)$(MAKE) $(build)=rust $@
endif
# Script to generate missing namespace dependencies
# ---------------------------------------------------------------------------
@ -1998,12 +2049,12 @@ nsdeps: modules
quiet_cmd_gen_compile_commands = GEN $@
cmd_gen_compile_commands = $(PYTHON3) $< -a $(AR) -o $@ $(filter-out $<, $(real-prereqs))
$(extmod_prefix)compile_commands.json: $(srctree)/scripts/clang-tools/gen_compile_commands.py \
compile_commands.json: $(srctree)/scripts/clang-tools/gen_compile_commands.py \
$(if $(KBUILD_EXTMOD),, vmlinux.a $(KBUILD_VMLINUX_LIBS)) \
$(if $(CONFIG_MODULES), $(MODORDER)) FORCE
$(if $(CONFIG_MODULES), modules.order) FORCE
$(call if_changed,gen_compile_commands)
targets += $(extmod_prefix)compile_commands.json
targets += compile_commands.json
PHONY += clang-tidy clang-analyzer
@ -2011,7 +2062,7 @@ ifdef CONFIG_CC_IS_CLANG
quiet_cmd_clang_tools = CHECK $<
cmd_clang_tools = $(PYTHON3) $(srctree)/scripts/clang-tools/run-clang-tools.py $@ $<
clang-tidy clang-analyzer: $(extmod_prefix)compile_commands.json
clang-tidy clang-analyzer: compile_commands.json
$(call cmd,clang_tools)
else
clang-tidy clang-analyzer:

View File

@ -812,6 +812,45 @@ config LTO_CLANG_THIN
If unsure, say Y.
endchoice
config ARCH_SUPPORTS_AUTOFDO_CLANG
bool
config AUTOFDO_CLANG
bool "Enable Clang's AutoFDO build (EXPERIMENTAL)"
depends on ARCH_SUPPORTS_AUTOFDO_CLANG
depends on CC_IS_CLANG && CLANG_VERSION >= 170000
help
This option enables Clangs AutoFDO build. When
an AutoFDO profile is specified in variable
CLANG_AUTOFDO_PROFILE during the build process,
Clang uses the profile to optimize the kernel.
If no profile is specified, AutoFDO options are
still passed to Clang to facilitate the collection
of perf data for creating an AutoFDO profile in
subsequent builds.
If unsure, say N.
config ARCH_SUPPORTS_PROPELLER_CLANG
bool
config PROPELLER_CLANG
bool "Enable Clang's Propeller build"
depends on ARCH_SUPPORTS_PROPELLER_CLANG
depends on CC_IS_CLANG && CLANG_VERSION >= 190000
help
This option enables Clangs Propeller build. When the Propeller
profiles is specified in variable CLANG_PROPELLER_PROFILE_PREFIX
during the build process, Clang uses the profiles to optimize
the kernel.
If no profile is specified, Propeller options are still passed
to Clang to facilitate the collection of perf data for creating
the Propeller profiles in subsequent builds.
If unsure, say N.
config ARCH_SUPPORTS_CFI_CLANG
bool
help

View File

@ -264,13 +264,13 @@ stack_protector_prepare: prepare0
-mstack-protector-guard=tls \
-mstack-protector-guard-offset=$(shell \
awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\
include/generated/asm-offsets.h))
$(objtree)/include/generated/asm-offsets.h))
else
stack_protector_prepare: prepare0
$(eval SSP_PLUGIN_CFLAGS := \
-fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \
awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\
include/generated/asm-offsets.h))
$(objtree)/include/generated/asm-offsets.h))
$(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS))
$(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS))
endif

View File

@ -71,7 +71,7 @@ stack_protector_prepare: prepare0
-mstack-protector-guard-reg=sp_el0 \
-mstack-protector-guard-offset=$(shell \
awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \
include/generated/asm-offsets.h))
$(objtree)/include/generated/asm-offsets.h))
endif
ifeq ($(CONFIG_ARM64_BTI_KERNEL),y)

View File

@ -59,6 +59,7 @@
#endif
.endm
__HEAD
#ifndef CONFIG_NO_EXCEPT_FILL
/*
* Reserved space for exception handlers.

View File

@ -61,6 +61,7 @@ SECTIONS
/* read-only */
_text = .; /* Text and read-only data */
.text : {
HEAD_TEXT
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT

View File

@ -403,10 +403,12 @@ PHONY += stack_protector_prepare
stack_protector_prepare: prepare0
ifdef CONFIG_PPC64
$(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 \
-mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h))
-mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' \
$(objtree)/include/generated/asm-offsets.h))
else
$(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \
-mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h))
-mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' \
$(objtree)/include/generated/asm-offsets.h))
endif
endif

View File

@ -135,7 +135,7 @@ stack_protector_prepare: prepare0
-mstack-protector-guard-reg=tp \
-mstack-protector-guard-offset=$(shell \
awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}' \
include/generated/asm-offsets.h))
$(objtree)/include/generated/asm-offsets.h))
endif
# arch specific predefines for sparse

View File

@ -48,6 +48,11 @@ SECTIONS
{
_text = .;
HEAD_TEXT
ALIGN_FUNCTION();
#ifdef CONFIG_SPARC64
/* Match text section symbols in head_64.S first */
*head_64.o(.text)
#endif
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT

View File

@ -128,6 +128,8 @@ config X86
select ARCH_SUPPORTS_LTO_CLANG
select ARCH_SUPPORTS_LTO_CLANG_THIN
select ARCH_SUPPORTS_RT
select ARCH_SUPPORTS_AUTOFDO_CLANG
select ARCH_SUPPORTS_PROPELLER_CLANG if X86_64
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF if X86_CMPXCHG64
select ARCH_USE_MEMTEST

View File

@ -420,6 +420,10 @@ SECTIONS
STABS_DEBUG
DWARF_DEBUG
#ifdef CONFIG_PROPELLER_CLANG
.llvm_bb_addr_map : { *(.llvm_bb_addr_map) }
#endif
ELF_DETAILS
DISCARDS

View File

@ -40,9 +40,7 @@ hostprogs += makemapdata
makemapdata-objs := makemapdata.o
quiet_cmd_mkmap = MKMAP $@
cmd_mkmap = TOPDIR=$(srctree) \
SPKDIR=$(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD),$(srctree)/drivers/accessibility/speakup) \
$(obj)/makemapdata > $@
cmd_mkmap = TOPDIR=$(srctree) SPKDIR=$(src) $(obj)/makemapdata > $@
$(obj)/mapdata.h: $(obj)/makemapdata
$(call cmd,mkmap)

View File

@ -2,6 +2,12 @@
config DTC
bool
config GENERIC_BUILTIN_DTB
bool
config BUILTIN_DTB_ALL
bool
menuconfig OF
bool "Device Tree and Open Firmware support"
help

View File

@ -21,7 +21,7 @@ config USB_DWC2
if USB_DWC2
choice
bool "DWC2 Mode Selection"
prompt "DWC2 Mode Selection"
default USB_DWC2_DUAL_ROLE if (USB && USB_GADGET)
default USB_DWC2_HOST if (USB && !USB_GADGET)
default USB_DWC2_PERIPHERAL if (!USB && USB_GADGET)

View File

@ -23,7 +23,7 @@ config USB_DWC3_ULPI
controller.
choice
bool "DWC3 Mode Selection"
prompt "DWC3 Mode Selection"
default USB_DWC3_DUAL_ROLE if (USB && USB_GADGET)
default USB_DWC3_HOST if (USB && !USB_GADGET)
default USB_DWC3_GADGET if (!USB && USB_GADGET)

View File

@ -26,7 +26,7 @@ config USB_ISP1761_UDC
if USB_ISP1760
choice
bool "ISP1760 Mode Selection"
prompt "ISP1760 Mode Selection"
default USB_ISP1760_DUAL_ROLE if (USB && USB_GADGET)
default USB_ISP1760_HOST_ROLE if (USB && !USB_GADGET)
default USB_ISP1760_GADGET_ROLE if (!USB && USB_GADGET)

View File

@ -21,7 +21,7 @@ config USB_MTU3
if USB_MTU3
choice
bool "MTU3 Mode Selection"
prompt "MTU3 Mode Selection"
default USB_MTU3_DUAL_ROLE if (USB && USB_GADGET)
default USB_MTU3_HOST if (USB && !USB_GADGET)
default USB_MTU3_GADGET if (!USB && USB_GADGET)

View File

@ -29,7 +29,7 @@ config USB_MUSB_HDRC
if USB_MUSB_HDRC
choice
bool "MUSB Mode Selection"
prompt "MUSB Mode Selection"
default USB_MUSB_DUAL_ROLE if (USB && USB_GADGET)
default USB_MUSB_HOST if (USB && !USB_GADGET)
default USB_MUSB_GADGET if (!USB && USB_GADGET)

View File

@ -95,18 +95,25 @@
* With LTO_CLANG, the linker also splits sections by default, so we need
* these macros to combine the sections during the final link.
*
* With AUTOFDO_CLANG and PROPELLER_CLANG, by default, the linker splits
* text sections and regroups functions into subsections.
*
* RODATA_MAIN is not used because existing code already defines .rodata.x
* sections to be brought in with rodata.
*/
#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG)
#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG) || \
defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)
#define TEXT_MAIN .text .text.[0-9a-zA-Z_]*
#else
#define TEXT_MAIN .text
#endif
#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CLANG)
#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral* .data.$__unnamed_* .data.$L*
#define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]*
#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L*
#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..L* .bss..compoundliteral*
#define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]*
#else
#define TEXT_MAIN .text
#define DATA_MAIN .data
#define SDATA_MAIN .sdata
#define RODATA_MAIN .rodata
@ -350,9 +357,9 @@
*(.data..decrypted) \
*(.ref.data) \
*(.data..shared_aligned) /* percpu related */ \
*(.data.unlikely) \
*(.data..unlikely) \
__start_once = .; \
*(.data.once) \
*(.data..once) \
__end_once = .; \
STRUCT_ALIGN(); \
*(__tracepoints) \
@ -549,24 +556,44 @@
__cpuidle_text_end = .; \
__noinstr_text_end = .;
#define TEXT_SPLIT \
__split_text_start = .; \
*(.text.split .text.split.[0-9a-zA-Z_]*) \
__split_text_end = .;
#define TEXT_UNLIKELY \
__unlikely_text_start = .; \
*(.text.unlikely .text.unlikely.*) \
__unlikely_text_end = .;
#define TEXT_HOT \
__hot_text_start = .; \
*(.text.hot .text.hot.*) \
__hot_text_end = .;
/*
* .text section. Map to function alignment to avoid address changes
* during second ld run in second ld pass when generating System.map
*
* TEXT_MAIN here will match .text.fixup and .text.unlikely if dead
* code elimination is enabled, so these sections should be converted
* to use ".." first.
* TEXT_MAIN here will match symbols with a fixed pattern (for example,
* .text.hot or .text.unlikely) if dead code elimination or
* function-section is enabled. Match these symbols first before
* TEXT_MAIN to ensure they are grouped together.
*
* Also placing .text.hot section at the beginning of a page, this
* would help the TLB performance.
*/
#define TEXT_TEXT \
ALIGN_FUNCTION(); \
*(.text.hot .text.hot.*) \
*(TEXT_MAIN .text.fixup) \
*(.text.unlikely .text.unlikely.*) \
*(.text.asan.* .text.tsan.*) \
*(.text.unknown .text.unknown.*) \
TEXT_SPLIT \
TEXT_UNLIKELY \
. = ALIGN(PAGE_SIZE); \
TEXT_HOT \
*(TEXT_MAIN .text.fixup) \
NOINSTR_TEXT \
*(.ref.text) \
*(.text.asan.* .text.tsan.*)
*(.ref.text)
/* sched.text is aling to function alignment to secure we have same
* address even at second ld pass when generating System.map */

View File

@ -46,7 +46,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi);
} \
} while (0)
#define VM_WARN_ON_ONCE_PAGE(cond, page) ({ \
static bool __section(".data.once") __warned; \
static bool __section(".data..once") __warned; \
int __ret_warn_once = !!(cond); \
\
if (unlikely(__ret_warn_once && !__warned)) { \
@ -66,7 +66,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi);
unlikely(__ret_warn); \
})
#define VM_WARN_ON_ONCE_FOLIO(cond, folio) ({ \
static bool __section(".data.once") __warned; \
static bool __section(".data..once") __warned; \
int __ret_warn_once = !!(cond); \
\
if (unlikely(__ret_warn_once && !__warned)) { \
@ -77,7 +77,7 @@ void vma_iter_dump_tree(const struct vma_iterator *vmi);
unlikely(__ret_warn_once); \
})
#define VM_WARN_ON_ONCE_MM(cond, mm) ({ \
static bool __section(".data.once") __warned; \
static bool __section(".data..once") __warned; \
int __ret_warn_once = !!(cond); \
\
if (unlikely(__ret_warn_once && !__warned)) { \

View File

@ -247,7 +247,7 @@ extern void cleanup_module(void);
#ifdef MODULE
/* Creates an alias so file2alias.c can find device table. */
#define MODULE_DEVICE_TABLE(type, name) \
extern typeof(name) __mod_##type##__##name##_device_table \
extern typeof(name) __mod_device_table__##type##__##name \
__attribute__ ((unused, alias(__stringify(name))))
#else /* !MODULE */
#define MODULE_DEVICE_TABLE(type, name)

View File

@ -46,7 +46,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
#define DO_ONCE(func, ...) \
({ \
bool ___ret = false; \
static bool __section(".data.once") ___done = false; \
static bool __section(".data..once") ___done = false; \
static DEFINE_STATIC_KEY_TRUE(___once_key); \
if (static_branch_unlikely(&___once_key)) { \
unsigned long ___flags; \
@ -64,7 +64,7 @@ void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
#define DO_ONCE_SLEEPABLE(func, ...) \
({ \
bool ___ret = false; \
static bool __section(".data.once") ___done = false; \
static bool __section(".data..once") ___done = false; \
static DEFINE_STATIC_KEY_TRUE(___once_key); \
if (static_branch_unlikely(&___once_key)) { \
___ret = __do_once_sleepable_start(&___done); \

View File

@ -12,7 +12,7 @@
#define __ONCE_LITE_IF(condition) \
({ \
static bool __section(".data.once") __already_done; \
static bool __section(".data..once") __already_done; \
bool __ret_cond = !!(condition); \
bool __ret_once = false; \
\

View File

@ -401,7 +401,7 @@ static inline int debug_lockdep_rcu_enabled(void)
*/
#define RCU_LOCKDEP_WARN(c, s) \
do { \
static bool __section(".data.unlikely") __warned; \
static bool __section(".data..unlikely") __warned; \
if (debug_lockdep_rcu_enabled() && (c) && \
debug_lockdep_rcu_enabled() && !__warned) { \
__warned = true; \

View File

@ -27,7 +27,7 @@ void netdev_info(const struct net_device *dev, const char *format, ...);
#define netdev_level_once(level, dev, fmt, ...) \
do { \
static bool __section(".data.once") __print_once; \
static bool __section(".data..once") __print_once; \
\
if (!__print_once) { \
__print_once = true; \

View File

@ -49,7 +49,7 @@ struct folio_batch;
* when we specify __GFP_NOWARN.
*/
#define WARN_ON_ONCE_GFP(cond, gfp) ({ \
static bool __section(".data.once") __warned; \
static bool __section(".data..once") __warned; \
int __ret_warn_once = !!(cond); \
\
if (unlikely(!(gfp & __GFP_NOWARN) && __ret_warn_once && !__warned)) { \

View File

@ -372,8 +372,8 @@ rust-analyzer:
$(Q)$(srctree)/scripts/generate_rust_analyzer.py \
--cfgs='core=$(core-cfgs)' \
$(realpath $(srctree)) $(realpath $(objtree)) \
$(rustc_sysroot) $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \
$(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json
$(rustc_sysroot) $(RUST_LIB_SRC) $(if $(KBUILD_EXTMOD),$(srcroot)) \
> rust-project.json
redirect-intrinsics = \
__addsf3 __eqsf2 __extendsfdf2 __gesf2 __lesf2 __ltsf2 __mulsf3 __nesf2 __truncdfsf2 __unordsf2 \

View File

@ -205,7 +205,7 @@ if_changed_dep = $(if $(if-changed-cond),$(cmd_and_fixdep),@:)
cmd_and_fixdep = \
$(cmd); \
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
$(objtree)/scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).cmd;\
rm -f $(depfile)
# Usage: $(call if_changed_rule,foo)

24
scripts/Makefile.autofdo Normal file
View File

@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-2.0
# Enable available and selected Clang AutoFDO features.
CFLAGS_AUTOFDO_CLANG := -fdebug-info-for-profiling -mllvm -enable-fs-discriminator=true -mllvm -improved-fs-discriminator=true
ifndef CONFIG_DEBUG_INFO
CFLAGS_AUTOFDO_CLANG += -gmlt
endif
ifdef CLANG_AUTOFDO_PROFILE
CFLAGS_AUTOFDO_CLANG += -fprofile-sample-use=$(CLANG_AUTOFDO_PROFILE) -ffunction-sections
CFLAGS_AUTOFDO_CLANG += -fsplit-machine-functions
endif
ifdef CONFIG_LTO_CLANG_THIN
ifdef CLANG_AUTOFDO_PROFILE
KBUILD_LDFLAGS += --lto-sample-profile=$(CLANG_AUTOFDO_PROFILE)
endif
KBUILD_LDFLAGS += --mllvm=-enable-fs-discriminator=true --mllvm=-improved-fs-discriminator=true -plugin-opt=thinlto
KBUILD_LDFLAGS += -plugin-opt=-split-machine-functions
endif
export CFLAGS_AUTOFDO_CLANG

View File

@ -3,7 +3,7 @@
# Building
# ==========================================================================
src := $(if $(VPATH),$(VPATH)/)$(obj)
src := $(srcroot)/$(obj)
PHONY := $(obj)/
$(obj)/:
@ -34,7 +34,7 @@ subdir-asflags-y :=
subdir-ccflags-y :=
# Read auto.conf if it exists, otherwise ignore
-include include/config/auto.conf
-include $(objtree)/include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
include $(srctree)/scripts/Makefile.compiler
@ -107,20 +107,14 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $<
$(obj)/%.i: $(obj)/%.c FORCE
$(call if_changed_dep,cpp_i_c)
genksyms = scripts/genksyms/genksyms \
$(if $(1), -T $(2)) \
$(if $(KBUILD_PRESERVE), -p) \
-r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null)
genksyms = $(objtree)/scripts/genksyms/genksyms \
$(if $(KBUILD_SYMTYPES), -T $(@:.o=.symtypes)) \
$(if $(KBUILD_PRESERVE), -p) \
$(addprefix -r , $(wildcard $(@:.o=.symref)))
# These mirror gensymtypes_S and co below, keep them in synch.
cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms)
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null
$(obj)/%.symtypes : $(obj)/%.c FORCE
$(call cmd,cc_symtypes_c)
# LLVM assembly
# Generate .ll files from .c
quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@
@ -135,17 +129,6 @@ $(obj)/%.ll: $(obj)/%.c FORCE
is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y)
# When a module consists of a single object, there is no reason to keep LLVM IR.
# Make $(LD) covert LLVM IR to ELF here.
ifdef CONFIG_LTO_CLANG
cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@)
endif
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \
$(cmd_ld_single_m) \
$(cmd_objtool)
ifdef CONFIG_MODVERSIONS
# When module versioning is enabled the following steps are executed:
# o compile a <file>.o from <file>.c
@ -158,8 +141,7 @@ ifdef CONFIG_MODVERSIONS
gen_symversions = \
if $(NM) $@ 2>/dev/null | grep -q ' __export_symbol_'; then \
$(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
>> $(dot-target).cmd; \
$(cmd_gensymtypes_$1) >> $(dot-target).cmd; \
fi
cmd_gen_symversions_c = $(call gen_symversions,c)
@ -207,23 +189,6 @@ ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),)
cmd_warn_shared_object = $(if $(word 2, $(modname-multi)),$(warning $(kbuild-file): $*.o is added to multiple modules: $(modname-multi)))
endif
define rule_cc_o_c
$(call cmd_and_fixdep,cc_o_c)
$(call cmd,checksrc)
$(call cmd,checkdoc)
$(call cmd,gen_objtooldep)
$(call cmd,gen_symversions_c)
$(call cmd,record_mcount)
$(call cmd,warn_shared_object)
endef
define rule_as_o_S
$(call cmd_and_fixdep,as_o_S)
$(call cmd,gen_objtooldep)
$(call cmd,gen_symversions_S)
$(call cmd,warn_shared_object)
endef
# Built-in and composite module parts
$(obj)/%.o: $(obj)/%.c $(recordmcount_source) FORCE
$(call if_changed_rule,cc_o_c)
@ -330,22 +295,12 @@ cmd_gensymtypes_S = \
$(NM) $@ | sed -n 's/.* __export_symbol_\(.*\)/EXPORT_SYMBOL(\1);/p' ; } | \
$(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms)
quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@
cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null
$(obj)/%.symtypes : $(obj)/%.S FORCE
$(call cmd,cc_symtypes_S)
quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@
cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $<
$(obj)/%.s: $(obj)/%.S FORCE
$(call if_changed_dep,cpp_s_S)
quiet_cmd_as_o_S = AS $(quiet_modtag) $@
cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool)
ifdef CONFIG_ASM_MODVERSIONS
# versioning matches the C process described above, with difference that

View File

@ -3,7 +3,7 @@
# Cleaning up
# ==========================================================================
src := $(if $(VPATH),$(VPATH)/)$(obj)
src := $(srcroot)/$(obj)
PHONY := __clean
__clean:

View File

@ -13,7 +13,7 @@ cc-cross-prefix = $(firstword $(foreach c, $(1), \
$(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c))))
# output directory for tests below
TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$
TMPOUT = .tmp_$$$$
# try-run
# Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)

View File

@ -96,12 +96,10 @@ hostrust_flags = --out-dir $(dir $@) --emit=dep-info=$(depfile) \
$(KBUILD_HOSTRUSTFLAGS) $(HOST_EXTRARUSTFLAGS) \
$(HOSTRUSTFLAGS_$(target-stem))
# $(objtree)/$(obj) for including generated headers from checkin source files
ifeq ($(KBUILD_EXTMOD),)
# $(obj) for including generated headers from checkin source files
ifdef building_out_of_srctree
hostc_flags += -I $(objtree)/$(obj)
hostcxx_flags += -I $(objtree)/$(obj)
endif
hostc_flags += -I $(obj)
hostcxx_flags += -I $(obj)
endif
#####

View File

@ -191,15 +191,33 @@ _c_flags += $(if $(patsubst n%,, \
-D__KCSAN_INSTRUMENT_BARRIERS__)
endif
#
# Enable AutoFDO build flags except some files or directories we don't want to
# enable (depends on variables AUTOFDO_PROFILE_obj.o and AUTOFDO_PROFILE).
#
ifeq ($(CONFIG_AUTOFDO_CLANG),y)
_c_flags += $(if $(patsubst n%,, \
$(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(is-kernel-object)), \
$(CFLAGS_AUTOFDO_CLANG))
endif
#
# Enable Propeller build flags except some files or directories we don't want to
# enable (depends on variables AUTOFDO_PROPELLER_obj.o and PROPELLER_PROFILE).
#
ifdef CONFIG_PROPELLER_CLANG
_c_flags += $(if $(patsubst n%,, \
$(AUTOFDO_PROFILE_$(target-stem).o)$(AUTOFDO_PROFILE)$(PROPELLER_PROFILE))$(is-kernel-object), \
$(CFLAGS_PROPELLER_CLANG))
endif
# $(src) for including checkin headers from generated source files
# $(obj) for including generated headers from checkin source files
ifeq ($(KBUILD_EXTMOD),)
ifdef building_out_of_srctree
_c_flags += $(addprefix -I, $(src) $(obj))
_a_flags += $(addprefix -I, $(src) $(obj))
_cpp_flags += $(addprefix -I, $(src) $(obj))
endif
endif
# If $(is-kernel-object) is 'y', this object will be linked to vmlinux or modules
is-kernel-object = $(or $(part-of-builtin),$(part-of-module))
@ -280,6 +298,42 @@ $(foreach m, $1, \
$(addprefix $(obj)/, $(call suffix-search, $(patsubst $(obj)/%,%,$m), $2, $3))))
endef
# Build commands
# ===========================================================================
# These are shared by some Makefile.* files.
objtool-enabled := y
ifdef CONFIG_LTO_CLANG
# objtool cannot process LLVM IR. Make $(LD) covert LLVM IR to ELF here.
cmd_ld_single = $(if $(objtool-enabled), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@)
endif
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \
$(cmd_ld_single) \
$(cmd_objtool)
define rule_cc_o_c
$(call cmd_and_fixdep,cc_o_c)
$(call cmd,checksrc)
$(call cmd,checkdoc)
$(call cmd,gen_objtooldep)
$(call cmd,gen_symversions_c)
$(call cmd,record_mcount)
$(call cmd,warn_shared_object)
endef
quiet_cmd_as_o_S = AS $(quiet_modtag) $@
cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< $(cmd_objtool)
define rule_as_o_S
$(call cmd_and_fixdep,as_o_S)
$(call cmd,gen_objtooldep)
$(call cmd,gen_symversions_S)
$(call cmd,warn_shared_object)
endef
# Copy a file
# ===========================================================================
# 'cp' preserves permissions. If you use it to copy a file in read-only srctree,
@ -371,10 +425,10 @@ quiet_cmd_lzo_with_size = LZO $@
cmd_lzo_with_size = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
quiet_cmd_lz4 = LZ4 $@
cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout > $@
cmd_lz4 = cat $(real-prereqs) | $(LZ4) -l -9 - - > $@
quiet_cmd_lz4_with_size = LZ4 $@
cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -c1 stdin stdout; \
cmd_lz4_with_size = { cat $(real-prereqs) | $(LZ4) -l -9 - -; \
$(size_append); } > $@
# U-Boot mkimage

View File

@ -6,14 +6,12 @@
PHONY := __modfinal
__modfinal:
include include/config/auto.conf
include $(objtree)/include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
# for c_flags
include $(srctree)/scripts/Makefile.lib
# find all modules listed in modules.order
modules := $(call read-file, $(MODORDER))
modules := $(call read-file, modules.order)
__modfinal: $(modules:%.o=%.ko)
@:
@ -22,30 +20,27 @@ __modfinal: $(modules:%.o=%.ko)
modname = $(notdir $(@:.mod.o=))
part-of-module = y
GCOV_PROFILE := n
KCSAN_SANITIZE := n
quiet_cmd_cc_o_c = CC [M] $@
cmd_cc_o_c = $(CC) $(filter-out $(CC_FLAGS_CFI), $(c_flags)) -c -o $@ $<
ccflags-remove-y := $(CC_FLAGS_CFI)
%.mod.o: %.mod.c FORCE
$(call if_changed_dep,cc_o_c)
$(call if_changed_rule,cc_o_c)
$(extmod_prefix).module-common.o: $(srctree)/scripts/module-common.c FORCE
$(call if_changed_dep,cc_o_c)
.module-common.o: $(srctree)/scripts/module-common.c FORCE
$(call if_changed_rule,cc_o_c)
quiet_cmd_ld_ko_o = LD [M] $@
cmd_ld_ko_o = \
$(LD) -r $(KBUILD_LDFLAGS) \
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
-T scripts/module.lds -o $@ $(filter %.o, $^)
-T $(objtree)/scripts/module.lds -o $@ $(filter %.o, $^)
quiet_cmd_btf_ko = BTF [M] $@
cmd_btf_ko = \
if [ ! -f vmlinux ]; then \
if [ ! -f $(objtree)/vmlinux ]; then \
printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
else \
LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base vmlinux $@; \
$(RESOLVE_BTFIDS) -b vmlinux $@; \
LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) $(MODULE_PAHOLE_FLAGS) --btf_base $(objtree)/vmlinux $@; \
$(RESOLVE_BTFIDS) -b $(objtree)/vmlinux $@; \
fi;
# Same as newer-prereqs, but allows to exclude specified extra dependencies
@ -57,13 +52,13 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \
printf '%s\n' 'savedcmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
# Re-generate module BTFs if either module's .ko or vmlinux changed
%.ko: %.o %.mod.o $(extmod_prefix).module-common.o scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),vmlinux) FORCE
+$(call if_changed_except,ld_ko_o,vmlinux)
%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(CONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE
+$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux)
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+$(if $(newer-prereqs),$(call cmd,btf_ko))
endif
targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) $(extmod_prefix).module-common.o
targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) .module-common.o
# Add FORCE to the prerequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------

View File

@ -6,7 +6,7 @@
PHONY := __modinst
__modinst:
include include/config/auto.conf
include $(objtree)/include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
install-y :=
@ -40,7 +40,7 @@ $(addprefix $(MODLIB)/, modules.builtin modules.builtin.modinfo modules.builtin.
endif
modules := $(call read-file, $(MODORDER))
modules := $(call read-file, modules.order)
ifeq ($(KBUILD_EXTMOD),)
dst := $(MODLIB)/kernel
@ -59,7 +59,7 @@ suffix-$(CONFIG_MODULE_COMPRESS_XZ) := .xz
suffix-$(CONFIG_MODULE_COMPRESS_ZSTD) := .zst
endif
modules := $(patsubst $(extmod_prefix)%.o, $(dst)/%.ko$(suffix-y), $(modules))
modules := $(patsubst %.o, $(dst)/%.ko$(suffix-y), $(modules))
install-$(CONFIG_MODULES) += $(modules)
__modinst: $(install-y)
@ -119,7 +119,7 @@ endif
# Create necessary directories
$(foreach dir, $(sort $(dir $(install-y))), $(shell mkdir -p $(dir)))
$(dst)/%.ko: $(extmod_prefix)%.ko FORCE
$(dst)/%.ko: %.ko FORCE
$(call cmd,install)
$(call cmd,strip)
$(call cmd,sign)

View File

@ -35,10 +35,10 @@
PHONY := __modpost
__modpost:
include include/config/auto.conf
include $(objtree)/include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
MODPOST = scripts/mod/modpost
MODPOST = $(objtree)/scripts/mod/modpost
modpost-args = \
$(if $(CONFIG_MODULES),-M) \
@ -46,7 +46,7 @@ modpost-args = \
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
$(if $(KBUILD_MODPOST_WARN),-w) \
$(if $(KBUILD_NSDEPS),-d $(MODULES_NSDEPS)) \
$(if $(KBUILD_NSDEPS),-d modules.nsdeps) \
$(if $(CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS)$(KBUILD_NSDEPS),-N) \
$(if $(findstring 1, $(KBUILD_EXTRA_WARN)),-W) \
-o $@
@ -61,8 +61,8 @@ endif
# Read out modules.order to pass in modpost.
# Otherwise, allmodconfig would fail with "Argument list too long".
ifdef KBUILD_MODULES
modpost-args += -T $(MODORDER)
modpost-deps += $(MODORDER)
modpost-args += -T modules.order
modpost-deps += modules.order
endif
ifeq ($(KBUILD_EXTMOD),)
@ -111,19 +111,19 @@ endif
else
# set src + obj - they may be used in the modules's Makefile
obj := $(KBUILD_EXTMOD)
src := $(if $(VPATH),$(VPATH)/)$(obj)
obj := .
src := $(srcroot)
# Include the module's Makefile to find KBUILD_EXTRA_SYMBOLS
include $(kbuild-file)
output-symdump := $(KBUILD_EXTMOD)/Module.symvers
output-symdump := Module.symvers
ifeq ($(wildcard Module.symvers),)
missing-input := Module.symvers
ifeq ($(wildcard $(objtree)/Module.symvers),)
missing-input := $(objtree)/Module.symvers
else
modpost-args += -i Module.symvers
modpost-deps += Module.symvers
modpost-args += -i $(objtree)/Module.symvers
modpost-deps += $(objtree)/Module.symvers
endif
modpost-args += -e $(addprefix -i , $(KBUILD_EXTRA_SYMBOLS))

View File

@ -0,0 +1,39 @@
# SPDX-License-Identifier: GPL-2.0
# Enable available and selected Clang Propeller features.
ifdef CLANG_PROPELLER_PROFILE_PREFIX
CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=list=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt -ffunction-sections
KBUILD_LDFLAGS += --symbol-ordering-file=$(CLANG_PROPELLER_PROFILE_PREFIX)_ld_profile.txt --no-warn-symbol-ordering
else
# Starting with Clang v20, the '-fbasic-block-sections=labels' option is
# deprecated. Use the recommended '-fbasic-block-address-map' option.
# Link: https://github.com/llvm/llvm-project/pull/110039
ifeq ($(call clang-min-version, 200000),y)
CFLAGS_PROPELLER_CLANG := -fbasic-block-address-map
else
CFLAGS_PROPELLER_CLANG := -fbasic-block-sections=labels
endif
endif
# Propeller requires debug information to embed module names in the profiles.
# If CONFIG_DEBUG_INFO is not enabled, set -gmlt option. Skip this for AutoFDO,
# as the option should already be set.
ifndef CONFIG_DEBUG_INFO
ifndef CONFIG_AUTOFDO_CLANG
CFLAGS_PROPELLER_CLANG += -gmlt
endif
endif
ifdef CONFIG_LTO_CLANG_THIN
ifdef CLANG_PROPELLER_PROFILE_PREFIX
KBUILD_LDFLAGS += --lto-basic-block-sections=$(CLANG_PROPELLER_PROFILE_PREFIX)_cc_profile.txt
else
ifeq ($(call test-ge, $(CONFIG_LLD_VERSION), 200000),y)
KBUILD_LDFLAGS += --lto-basic-block-address-map
else
KBUILD_LDFLAGS += --lto-basic-block-sections=labels
endif
endif
endif
export CFLAGS_PROPELLER_CLANG

View File

@ -5,17 +5,53 @@ __default: vmlinux
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
# for c_flags
include $(srctree)/scripts/Makefile.lib
targets :=
quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
%.o: %.c FORCE
$(call if_changed_dep,cc_o_c)
$(call if_changed_rule,cc_o_c)
%.o: %.S FORCE
$(call if_changed_rule,as_o_S)
# Built-in dtb
# ---------------------------------------------------------------------------
quiet_cmd_wrap_dtbs = WRAP $@
cmd_wrap_dtbs = { \
echo '\#include <asm-generic/vmlinux.lds.h>'; \
echo '.section .dtb.init.rodata,"a"'; \
while read dtb; do \
symbase=__dtb_$$(basename -s .dtb "$${dtb}" | tr - _); \
echo '.balign STRUCT_ALIGNMENT'; \
echo ".global $${symbase}_begin"; \
echo "$${symbase}_begin:"; \
echo '.incbin "'$$dtb'" '; \
echo ".global $${symbase}_end"; \
echo "$${symbase}_end:"; \
done < $<; \
} > $@
.builtin-dtbs.S: .builtin-dtbs-list FORCE
$(call if_changed,wrap_dtbs)
quiet_cmd_gen_dtbs_list = GEN $@
cmd_gen_dtbs_list = \
$(if $(CONFIG_BUILTIN_DTB_NAME), echo "arch/$(SRCARCH)/boot/dts/$(CONFIG_BUILTIN_DTB_NAME).dtb",:) > $@
.builtin-dtbs-list: arch/$(SRCARCH)/boot/dts/dtbs-list FORCE
$(call if_changed,$(if $(CONFIG_BUILTIN_DTB_ALL),copy,gen_dtbs_list))
targets += .builtin-dtbs-list
ifdef CONFIG_GENERIC_BUILTIN_DTB
targets += .builtin-dtbs.S .builtin-dtbs.o
vmlinux: .builtin-dtbs.o
endif
# vmlinux
# ---------------------------------------------------------------------------
ifdef CONFIG_MODULES
targets += .vmlinux.export.o
@ -39,6 +75,9 @@ cmd_link_vmlinux = \
targets += vmlinux
vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
+$(call if_changed_dep,link_vmlinux)
ifdef CONFIG_DEBUG_INFO_BTF
vmlinux: $(RESOLVE_BTFIDS)
endif
# module.builtin.ranges
# ---------------------------------------------------------------------------

View File

@ -80,11 +80,7 @@ command results in a shift count error.'
NPROC=1
else
ONLINE=0
if [ "$KBUILD_EXTMOD" = "" ] ; then
OPTIONS="--dir $srctree $COCCIINCLUDE"
else
OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
fi
OPTIONS="--dir $srcroot $COCCIINCLUDE"
# Use only one thread per core by default if hyperthreading is enabled
THREADS_PER_CORE=$(LANG=C lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]")

View File

@ -12,7 +12,7 @@ KERNELRELEASE=$1
: ${DEPMOD:=depmod}
if ! test -r System.map ; then
if ! test -r "${objtree}/System.map" ; then
echo "Warning: modules_install: missing 'System.map' file. Skipping depmod." >&2
exit 0
fi
@ -25,7 +25,7 @@ if [ -z $(command -v $DEPMOD) ]; then
exit 0
fi
set -- -ae -F System.map
set -- -ae -F "${objtree}/System.map"
if test -n "$INSTALL_MOD_PATH"; then
set -- "$@" -b "$INSTALL_MOD_PATH"
fi

View File

@ -632,54 +632,55 @@ static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
void export_symbol(const char *name)
{
struct symbol *sym;
unsigned long crc;
int has_changed = 0;
sym = find_symbol(name, SYM_NORMAL, 0);
if (!sym)
if (!sym) {
error_with_pos("export undefined symbol %s", name);
else {
unsigned long crc;
int has_changed = 0;
if (flag_dump_defs)
fprintf(debugfile, "Export %s == <", name);
expansion_trail = (struct symbol *)-1L;
sym->expansion_trail = expansion_trail;
expansion_trail = sym;
crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
sym = expansion_trail;
while (sym != (struct symbol *)-1L) {
struct symbol *n = sym->expansion_trail;
if (sym->status != STATUS_UNCHANGED) {
if (!has_changed) {
print_location();
fprintf(stderr, "%s: %s: modversion "
"changed because of changes "
"in ", flag_preserve ? "error" :
"warning", name);
} else
fprintf(stderr, ", ");
print_type_name(sym->type, sym->name);
if (sym->status == STATUS_DEFINED)
fprintf(stderr, " (became defined)");
has_changed = 1;
if (flag_preserve)
errors++;
}
sym->expansion_trail = 0;
sym = n;
}
if (has_changed)
fprintf(stderr, "\n");
if (flag_dump_defs)
fputs(">\n", debugfile);
printf("#SYMVER %s 0x%08lx\n", name, crc);
return;
}
if (flag_dump_defs)
fprintf(debugfile, "Export %s == <", name);
expansion_trail = (struct symbol *)-1L;
sym->expansion_trail = expansion_trail;
expansion_trail = sym;
crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
sym = expansion_trail;
while (sym != (struct symbol *)-1L) {
struct symbol *n = sym->expansion_trail;
if (sym->status != STATUS_UNCHANGED) {
if (!has_changed) {
print_location();
fprintf(stderr,
"%s: %s: modversion changed because of changes in ",
flag_preserve ? "error" : "warning",
name);
} else {
fprintf(stderr, ", ");
}
print_type_name(sym->type, sym->name);
if (sym->status == STATUS_DEFINED)
fprintf(stderr, " (became defined)");
has_changed = 1;
if (flag_preserve)
errors++;
}
sym->expansion_trail = 0;
sym = n;
}
if (has_changed)
fprintf(stderr, "\n");
if (flag_dump_defs)
fputs(">\n", debugfile);
printf("#SYMVER %s 0x%08lx\n", name, crc);
}
/*----------------------------------------------------------------------*/

View File

@ -23,7 +23,6 @@ arch/m68k/coldfire/head.o
arch/m68k/kernel/head.o
arch/m68k/kernel/sun3-head.o
arch/microblaze/kernel/head.o
arch/mips/kernel/head.o
arch/nios2/kernel/head.o
arch/openrisc/kernel/head.o
arch/parisc/kernel/head.o

View File

@ -628,7 +628,7 @@ static const struct option long_opts[] = {
static void conf_usage(const char *progname)
{
printf("Usage: %s [options] <kconfig-file>\n", progname);
printf("Usage: %s [options] kconfig_file\n", progname);
printf("\n");
printf("Generic options:\n");
printf(" -h, --help Print this message and exit.\n");
@ -653,6 +653,9 @@ static void conf_usage(const char *progname)
printf(" --mod2yesconfig Change answers from mod to yes if possible\n");
printf(" --mod2noconfig Change answers from mod to no if possible\n");
printf(" (If none of the above is given, --oldaskconfig is the default)\n");
printf("\n");
printf("Arguments:\n");
printf(" kconfig_file Top-level Kconfig file.\n");
}
int main(int ac, char **av)

View File

@ -34,6 +34,7 @@ bool sym_string_valid(struct symbol *sym, const char *newval);
bool sym_string_within_range(struct symbol *sym, const char *str);
bool sym_set_string_value(struct symbol *sym, const char *newval);
bool sym_is_changeable(const struct symbol *sym);
struct menu *sym_get_prompt_menu(const struct symbol *sym);
struct menu *sym_get_choice_menu(const struct symbol *sym);
const char * sym_get_string_value(struct symbol *sym);

View File

@ -467,7 +467,7 @@ static void handle_f9(int *key, struct menu *current_item)
return;
}
/* return != 0 to indicate the key was handles */
/* return != 0 to indicate the key was handled */
static int process_special_keys(int *key, struct menu *menu)
{
int i;

View File

@ -277,6 +277,15 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
case KEY_RIGHT:
menu_driver(menu, REQ_RIGHT_ITEM);
break;
case 9: /* TAB */
if (btn_num > 1) {
/* cycle through buttons */
if (item_index(current_item(menu)) == btn_num - 1)
menu_driver(menu, REQ_FIRST_ITEM);
else
menu_driver(menu, REQ_NEXT_ITEM);
}
break;
case 10: /* ENTER */
case 27: /* ESCAPE */
case ' ':

View File

@ -24,7 +24,6 @@
int cdebug = PRINTD;
static void yyerror(const char *err);
static void zconfprint(const char *err, ...);
static void zconf_error(const char *err, ...);
static bool zconf_endtoken(const char *tokenname,
const char *expected_tokenname);
@ -183,7 +182,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
if (current_entry->prompt)
current_entry->prompt->type = P_MENU;
else
zconfprint("warning: menuconfig statement without prompt");
zconf_error("menuconfig statement without prompt");
printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
};
@ -293,12 +292,6 @@ choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);
};
choice_option: T_BOOL T_WORD_QUOTE if_expr T_EOL
{
menu_add_prompt(P_PROMPT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:bool\n", cur_filename, cur_lineno);
};
choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
{
menu_add_symbol(P_DEFAULT, $2, $3);
@ -408,14 +401,14 @@ help: help_start T_HELPTEXT
{
if (current_entry->help) {
free(current_entry->help);
zconfprint("warning: '%s' defined with more than one help text -- only the last one will be used",
current_entry->sym->name ?: "<choice>");
zconf_error("'%s' defined with more than one help text",
current_entry->sym->name ?: "<choice>");
}
/* Is the help text empty or all whitespace? */
if ($2[strspn($2, " \f\n\r\t\v")] == '\0')
zconfprint("warning: '%s' defined with blank help text",
current_entry->sym->name ?: "<choice>");
zconf_error("'%s' defined with blank help text",
current_entry->sym->name ?: "<choice>");
current_entry->help = $2;
};
@ -598,17 +591,6 @@ static bool zconf_endtoken(const char *tokenname,
return true;
}
static void zconfprint(const char *err, ...)
{
va_list ap;
fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno);
va_start(ap, err);
vfprintf(stderr, err, ap);
va_end(ap);
fprintf(stderr, "\n");
}
static void zconf_error(const char *err, ...)
{
va_list ap;

View File

@ -110,7 +110,7 @@ void ConfigItem::updateMenu(void)
if (prop) switch (prop->type) {
case P_MENU:
if (list->mode == singleMode || list->mode == symbolMode) {
if (list->mode == singleMode) {
/* a menuconfig entry is displayed differently
* depending whether it's at the view root or a child.
*/
@ -159,7 +159,7 @@ void ConfigItem::updateMenu(void)
ch = 'M';
break;
default:
if (sym_is_choice_value(sym) && type == S_BOOLEAN)
if (sym_is_choice_value(sym))
setIcon(promptColIdx, choiceNoIcon);
else
setIcon(promptColIdx, symbolNoIcon);
@ -175,17 +175,16 @@ void ConfigItem::updateMenu(void)
setText(dataColIdx, sym_get_string_value(sym));
break;
}
if (!sym_has_value(sym) && visible)
if (!sym_has_value(sym))
prompt += " (NEW)";
set_prompt:
setText(promptColIdx, prompt);
}
void ConfigItem::testUpdateMenu(bool v)
void ConfigItem::testUpdateMenu(void)
{
ConfigItem* i;
visible = v;
if (!menu)
return;
@ -307,7 +306,6 @@ ConfigList::ConfigList(QWidget *parent, const char *name)
{
setObjectName(name);
setSortingEnabled(false);
setRootIsDecorated(true);
setVerticalScrollMode(ScrollPerPixel);
setHorizontalScrollMode(ScrollPerPixel);
@ -430,27 +428,26 @@ void ConfigList::updateList()
item = (ConfigItem*)(*it);
if (!item->menu)
continue;
item->testUpdateMenu(menu_is_visible(item->menu));
item->testUpdateMenu();
++it;
}
return;
}
if (rootEntry != &rootmenu && (mode == singleMode ||
(mode == symbolMode && rootEntry->parent != &rootmenu))) {
if (rootEntry != &rootmenu && mode == singleMode) {
item = (ConfigItem *)topLevelItem(0);
if (!item)
item = new ConfigItem(this, 0, true);
item = new ConfigItem(this, 0);
last = item;
}
if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
rootEntry->sym && rootEntry->prompt) {
item = last ? last->nextSibling() : nullptr;
if (!item)
item = new ConfigItem(this, last, rootEntry, true);
item = new ConfigItem(this, last, rootEntry);
else
item->testUpdateMenu(true);
item->testUpdateMenu();
updateMenuList(item, rootEntry);
update();
@ -599,7 +596,6 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
struct menu* child;
ConfigItem* item;
ConfigItem* last;
bool visible;
enum prop_type type;
if (!menu) {
@ -631,14 +627,13 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
break;
}
visible = menu_is_visible(child);
if (!menuSkip(child)) {
if (!child->sym && !child->list && !child->prompt)
continue;
if (!item || item->menu != child)
item = new ConfigItem(parent, last, child, visible);
item = new ConfigItem(parent, last, child);
else
item->testUpdateMenu(visible);
item->testUpdateMenu();
if (mode == fullMode || mode == menuMode || type != P_MENU)
updateMenuList(item, child);
@ -664,7 +659,6 @@ void ConfigList::updateMenuList(struct menu *menu)
struct menu* child;
ConfigItem* item;
ConfigItem* last;
bool visible;
enum prop_type type;
if (!menu) {
@ -696,14 +690,13 @@ void ConfigList::updateMenuList(struct menu *menu)
break;
}
visible = menu_is_visible(child);
if (!menuSkip(child)) {
if (!child->sym && !child->list && !child->prompt)
continue;
if (!item || item->menu != child)
item = new ConfigItem(this, last, child, visible);
item = new ConfigItem(this, last, child);
else
item->testUpdateMenu(visible);
item->testUpdateMenu();
if (mode == fullMode || mode == menuMode || type != P_MENU)
updateMenuList(item, child);
@ -731,7 +724,7 @@ void ConfigList::keyPressEvent(QKeyEvent* ev)
struct menu *menu;
enum prop_type type;
if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
if (ev->key() == Qt::Key_Escape && mode == singleMode) {
emit parentSelected();
ev->accept();
return;
@ -781,13 +774,6 @@ void ConfigList::keyPressEvent(QKeyEvent* ev)
ev->accept();
}
void ConfigList::mousePressEvent(QMouseEvent* e)
{
//QPoint p(contentsToViewport(e->pos()));
//printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
Parent::mousePressEvent(e);
}
void ConfigList::mouseReleaseEvent(QMouseEvent* e)
{
QPoint p = e->pos();
@ -834,13 +820,6 @@ skip:
Parent::mouseReleaseEvent(e);
}
void ConfigList::mouseMoveEvent(QMouseEvent* e)
{
//QPoint p(contentsToViewport(e->pos()));
//printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
Parent::mouseMoveEvent(e);
}
void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
{
QPoint p = e->pos();
@ -1022,7 +1001,7 @@ void ConfigInfoView::menuInfo(void)
if (sym->name) {
stream << " (";
if (showDebug())
stream << "<a href=\"s" << sym->name << "\">";
stream << "<a href=\"" << sym->name << "\">";
stream << print_filter(sym->name);
if (showDebug())
stream << "</a>";
@ -1031,7 +1010,7 @@ void ConfigInfoView::menuInfo(void)
} else if (sym->name) {
stream << "<big><b>";
if (showDebug())
stream << "<a href=\"s" << sym->name << "\">";
stream << "<a href=\"" << sym->name << "\">";
stream << print_filter(sym->name);
if (showDebug())
stream << "</a>";
@ -1086,9 +1065,9 @@ QString ConfigInfoView::debug_info(struct symbol *sym)
switch (prop->type) {
case P_PROMPT:
case P_MENU:
stream << "prompt: <a href=\"m" << sym->name << "\">";
stream << "prompt: ";
stream << print_filter(prop->text);
stream << "</a><br>";
stream << "<br>";
break;
case P_DEFAULT:
case P_SELECT:
@ -1122,28 +1101,19 @@ QString ConfigInfoView::print_filter(const QString &str)
{
QRegularExpression re("[<>&\"\\n]");
QString res = str;
QHash<QChar, QString> patterns;
patterns['<'] = "&lt;";
patterns['>'] = "&gt;";
patterns['&'] = "&amp;";
patterns['"'] = "&quot;";
patterns['\n'] = "<br>";
for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
switch (res[i].toLatin1()) {
case '<':
res.replace(i, 1, "&lt;");
i += 4;
break;
case '>':
res.replace(i, 1, "&gt;");
i += 4;
break;
case '&':
res.replace(i, 1, "&amp;");
i += 5;
break;
case '"':
res.replace(i, 1, "&quot;");
i += 6;
break;
case '\n':
res.replace(i, 1, "<br>");
i += 4;
break;
const QString n = patterns.value(res[i], QString());
if (!n.isEmpty()) {
res.replace(i, 1, n);
i += n.length();
}
}
return res;
@ -1154,7 +1124,7 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
QTextStream *stream = reinterpret_cast<QTextStream *>(data);
if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
*stream << "<a href=\"s" << sym->name << "\">";
*stream << "<a href=\"" << sym->name << "\">";
*stream << print_filter(str);
*stream << "</a>";
} else {
@ -1164,39 +1134,11 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
void ConfigInfoView::clicked(const QUrl &url)
{
QByteArray str = url.toEncoded();
const std::size_t count = str.size();
char *data = new char[count + 2]; // '$' + '\0'
struct symbol **result;
struct menu *m = NULL;
struct menu *m;
if (count < 1) {
delete[] data;
return;
}
memcpy(data, str.constData(), count);
data[count] = '\0';
/* Seek for exact match */
data[0] = '^';
strcat(data, "$");
result = sym_re_search(data);
if (!result) {
delete[] data;
return;
}
sym = *result;
/* Seek for the menu which holds the symbol */
for (struct property *prop = sym->prop; prop; prop = prop->next) {
if (prop->type != P_PROMPT && prop->type != P_MENU)
continue;
m = prop->menu;
break;
}
sym = sym_find(url.toEncoded().constData());
m = sym_get_prompt_menu(sym);
if (!m) {
/* Symbol is not visible as a menu */
symbolInfo();
@ -1204,9 +1146,6 @@ void ConfigInfoView::clicked(const QUrl &url)
} else {
emit menuSelected(m);
}
free(result);
delete[] data;
}
void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
@ -1240,8 +1179,7 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
layout2->addWidget(searchButton);
layout1->addLayout(layout2);
split = new QSplitter(this);
split->setOrientation(Qt::Vertical);
split = new QSplitter(Qt::Vertical, this);
list = new ConfigList(split, "search");
list->mode = listMode;
info = new ConfigInfoView(split, "search");
@ -1300,8 +1238,7 @@ void ConfigSearchWindow::search(void)
return;
for (p = result; *p; p++) {
for_all_prompts((*p), prop)
lastItem = new ConfigItem(list, lastItem, prop->menu,
menu_is_visible(prop->menu));
lastItem = new ConfigItem(list, lastItem, prop->menu);
}
}
@ -1341,61 +1278,56 @@ ConfigMainWindow::ConfigMainWindow(void)
ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
QWidget *widget = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout(widget);
setCentralWidget(widget);
split1 = new QSplitter(widget);
split1->setOrientation(Qt::Horizontal);
QVBoxLayout *layout = new QVBoxLayout(widget);
split2 = new QSplitter(Qt::Vertical, widget);
layout->addWidget(split2);
split2->setChildrenCollapsible(false);
split1 = new QSplitter(Qt::Horizontal, split2);
split1->setChildrenCollapsible(false);
menuList = new ConfigList(widget, "menu");
configList = new ConfigList(split1, "config");
split2 = new QSplitter(widget);
split2->setChildrenCollapsible(false);
split2->setOrientation(Qt::Vertical);
// create config tree
configList = new ConfigList(widget, "config");
helpText = new ConfigInfoView(widget, "help");
layout->addWidget(split2);
split2->addWidget(split1);
split1->addWidget(configList);
split1->addWidget(menuList);
split2->addWidget(helpText);
menuList = new ConfigList(split1, "menu");
helpText = new ConfigInfoView(split2, "help");
setTabOrder(configList, helpText);
configList->setFocus();
backAction = new QAction(QPixmap(xpm_back), "Back", this);
backAction->setShortcut(QKeySequence::Back);
connect(backAction, &QAction::triggered,
this, &ConfigMainWindow::goBack);
QAction *quitAction = new QAction("&Quit", this);
quitAction->setShortcut(Qt::CTRL | Qt::Key_Q);
quitAction->setShortcut(QKeySequence::Quit);
connect(quitAction, &QAction::triggered,
this, &ConfigMainWindow::close);
QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
loadAction->setShortcut(Qt::CTRL | Qt::Key_L);
QAction *loadAction = new QAction(QPixmap(xpm_load), "&Open", this);
loadAction->setShortcut(QKeySequence::Open);
connect(loadAction, &QAction::triggered,
this, &ConfigMainWindow::loadConfig);
saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
saveAction->setShortcut(Qt::CTRL | Qt::Key_S);
saveAction->setShortcut(QKeySequence::Save);
connect(saveAction, &QAction::triggered,
this, &ConfigMainWindow::saveConfig);
conf_set_changed_callback(conf_changed);
configname = xstrdup(conf_get_configname());
configname = conf_get_configname();
QAction *saveAsAction = new QAction("Save &As...", this);
saveAsAction->setShortcut(QKeySequence::SaveAs);
connect(saveAsAction, &QAction::triggered,
this, &ConfigMainWindow::saveConfigAs);
QAction *searchAction = new QAction("&Find", this);
searchAction->setShortcut(Qt::CTRL | Qt::Key_F);
searchAction->setShortcut(QKeySequence::Find);
connect(searchAction, &QAction::triggered,
this, &ConfigMainWindow::searchConfig);
singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
@ -1505,6 +1437,9 @@ ConfigMainWindow::ConfigMainWindow(void)
connect(helpText, &ConfigInfoView::menuSelected,
this, &ConfigMainWindow::setMenuLink);
connect(configApp, &QApplication::aboutToQuit,
this, &ConfigMainWindow::saveSettings);
conf_read(NULL);
QString listMode = configSettings->value("/listMode", "symbol").toString();
@ -1528,28 +1463,22 @@ ConfigMainWindow::ConfigMainWindow(void)
void ConfigMainWindow::loadConfig(void)
{
QString str;
QByteArray ba;
const char *name;
str = QFileDialog::getOpenFileName(this, "", configname);
if (str.isNull())
return;
ba = str.toLocal8Bit();
name = ba.data();
if (conf_read(name))
if (conf_read(str.toLocal8Bit().constData()))
QMessageBox::information(this, "qconf", "Unable to load configuration!");
free(configname);
configname = xstrdup(name);
configname = str;
ConfigList::updateListAllForAll();
}
bool ConfigMainWindow::saveConfig(void)
{
if (conf_write(configname)) {
if (conf_write(configname.toLocal8Bit().constData())) {
QMessageBox::information(this, "qconf", "Unable to save configuration!");
return false;
}
@ -1561,23 +1490,17 @@ bool ConfigMainWindow::saveConfig(void)
void ConfigMainWindow::saveConfigAs(void)
{
QString str;
QByteArray ba;
const char *name;
str = QFileDialog::getSaveFileName(this, "", configname);
if (str.isNull())
return;
ba = str.toLocal8Bit();
name = ba.data();
if (conf_write(name)) {
if (conf_write(str.toLocal8Bit().constData())) {
QMessageBox::information(this, "qconf", "Unable to save configuration!");
}
conf_write_autoconf(0);
free(configname);
configname = xstrdup(name);
configname = str;
}
void ConfigMainWindow::searchConfig(void)
@ -1662,9 +1585,6 @@ void ConfigMainWindow::listFocusChanged(void)
void ConfigMainWindow::goBack(void)
{
if (configList->rootEntry == &rootmenu)
return;
configList->setParentMenu();
}
@ -1905,8 +1825,6 @@ int main(int ac, char** av)
v = new ConfigMainWindow();
//zconfdump(stdout);
configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
v->show();
configApp->exec();

View File

@ -55,9 +55,7 @@ public:
protected:
void keyPressEvent(QKeyEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseDoubleClickEvent(QMouseEvent *e);
void focusInEvent(QFocusEvent *e);
void contextMenuEvent(QContextMenuEvent *e);
@ -116,25 +114,25 @@ public:
class ConfigItem : public QTreeWidgetItem {
typedef class QTreeWidgetItem Parent;
public:
ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v)
: Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m)
: Parent(parent, after), nextItem(0), menu(m), goParent(false)
{
init();
}
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
: Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m)
: Parent(parent, after), nextItem(0), menu(m), goParent(false)
{
init();
}
ConfigItem(ConfigList *parent, ConfigItem *after, bool v)
: Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true)
ConfigItem(ConfigList *parent, ConfigItem *after)
: Parent(parent, after), nextItem(0), menu(0), goParent(true)
{
init();
}
~ConfigItem(void);
void init(void);
void updateMenu(void);
void testUpdateMenu(bool v);
void testUpdateMenu(void);
ConfigList* listView() const
{
return (ConfigList*)Parent::treeWidget();
@ -161,7 +159,6 @@ public:
ConfigItem* nextItem;
struct menu *menu;
bool visible;
bool goParent;
static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon;
@ -237,7 +234,7 @@ protected:
class ConfigMainWindow : public QMainWindow {
Q_OBJECT
char *configname;
QString configname;
static QAction *saveAction;
static void conf_changed(bool);
public:

View File

@ -144,6 +144,7 @@ my %selects;
my %prompts;
my %objects;
my %config2kfile;
my %defaults;
my $var;
my $iflevel = 0;
my @ifdeps;
@ -220,8 +221,9 @@ sub read_kconfig {
$depends{$config} = $1;
} elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) {
$depends{$config} .= " " . $1;
} elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) {
} elsif ($state ne "NONE" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) {
my $dep = $3;
$defaults{$config} = 1;
if ($dep !~ /^\s*(y|m|n)\s*$/) {
$dep =~ s/.*\sif\s+//;
$depends{$config} .= " " . $dep;
@ -503,7 +505,7 @@ sub parse_config_selects
# Check if something other than a module selects this config
if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") {
dprint "$conf (non module) selects config, we are good\n";
dprint "$conf (non module) selects $config, we are good\n";
# we are good with this
return;
}
@ -523,8 +525,16 @@ sub parse_config_selects
# If no possible config selected this, then something happened.
if (!defined($next_config)) {
print STDERR "WARNING: $config is required, but nothing in the\n";
print STDERR " current config selects it.\n";
# Some config options have no prompt, and nothing selects them, but
# they stay turned on once the final checks for the configs
# are done. These configs have a default option, so turn off the
# warnings for configs with default options.
if (!defined($defaults{$config})) {
print STDERR "WARNING: $config is required, but nothing in the\n";
print STDERR " current config selects it.\n";
}
return;
}

View File

@ -70,6 +70,24 @@ const char *sym_type_name(enum symbol_type type)
return "???";
}
/**
* sym_get_prompt_menu - get the menu entry with a prompt
*
* @sym: a symbol pointer
*
* Return: the menu entry with a prompt.
*/
struct menu *sym_get_prompt_menu(const struct symbol *sym)
{
struct menu *m;
list_for_each_entry(m, &sym->menus, link)
if (m->prompt)
return m;
return NULL;
}
/**
* sym_get_choice_menu - get the parent choice menu if present
*
@ -80,18 +98,12 @@ const char *sym_type_name(enum symbol_type type)
struct menu *sym_get_choice_menu(const struct symbol *sym)
{
struct menu *menu = NULL;
struct menu *m;
/*
* Choice members must have a prompt. Find a menu entry with a prompt,
* and assume it resides inside a choice block.
*/
list_for_each_entry(m, &sym->menus, link)
if (m->prompt) {
menu = m;
break;
}
menu = sym_get_prompt_menu(sym);
if (!menu)
return NULL;

View File

@ -68,6 +68,10 @@ vmlinux_link()
libs="${KBUILD_VMLINUX_LIBS}"
fi
if is_enabled CONFIG_GENERIC_BUILTIN_DTB; then
objs="${objs} .builtin-dtbs.o"
fi
if is_enabled CONFIG_MODULES; then
objs="${objs} .vmlinux.export.o"
fi
@ -208,8 +212,8 @@ kallsymso=
strip_debug=
if is_enabled CONFIG_KALLSYMS; then
true > .tmp_vmlinux.kallsyms0.syms
kallsyms .tmp_vmlinux.kallsyms0.syms .tmp_vmlinux0.kallsyms
true > .tmp_vmlinux0.syms
kallsyms .tmp_vmlinux0.syms .tmp_vmlinux0.kallsyms
fi
if is_enabled CONFIG_KALLSYMS || is_enabled CONFIG_DEBUG_INFO_BTF; then
@ -236,14 +240,14 @@ if is_enabled CONFIG_KALLSYMS; then
# Generate section listing all symbols and add it into vmlinux
# It's a four step process:
# 0) Generate a dummy __kallsyms with empty symbol list.
# 1) Link .tmp_vmlinux.kallsyms1 so it has all symbols and sections,
# 1) Link .tmp_vmlinux1.kallsyms so it has all symbols and sections,
# with a dummy __kallsyms.
# Running kallsyms on that gives us .tmp_kallsyms1.o with
# Running kallsyms on that gives us .tmp_vmlinux1.kallsyms.o with
# the right size
# 2) Link .tmp_vmlinux.kallsyms2 so it now has a __kallsyms section of
# 2) Link .tmp_vmlinux2.kallsyms so it now has a __kallsyms section of
# the right size, but due to the added section, some
# addresses have shifted.
# From here, we generate a correct .tmp_vmlinux.kallsyms2.o
# From here, we generate a correct .tmp_vmlinux2.kallsyms.o
# 3) That link may have expanded the kernel image enough that
# more linker branch stubs / trampolines had to be added, which
# introduces new names, which further expands kallsyms. Do another

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
#include <stdbool.h>
#include <errno.h>
#include <hash.h>
#include <hashtable.h>
#include <list.h>
#include <xalloc.h>
@ -176,6 +177,7 @@ static struct module *new_module(const char *name, size_t namelen)
INIT_LIST_HEAD(&mod->unresolved_symbols);
INIT_LIST_HEAD(&mod->missing_namespaces);
INIT_LIST_HEAD(&mod->imported_namespaces);
INIT_LIST_HEAD(&mod->aliases);
memcpy(mod->name, name, namelen);
mod->name[namelen] = '\0';
@ -209,19 +211,6 @@ struct symbol {
static HASHTABLE_DEFINE(symbol_hashtable, 1U << 10);
/* This is based on the hash algorithm from gdbm, via tdb */
static inline unsigned int tdb_hash(const char *name)
{
unsigned value; /* Used to compute the hash value. */
unsigned i; /* Used to cycle through random values. */
/* Set the initial value from the key size. */
for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
return (1103515243 * value + 12345);
}
/**
* Allocate a new symbols for use in the hash of exported symbols or
* the list of unresolved symbols per module
@ -239,7 +228,7 @@ static struct symbol *alloc_symbol(const char *name)
/* For the hash of exported symbols */
static void hash_add_symbol(struct symbol *sym)
{
hash_add(symbol_hashtable, &sym->hnode, tdb_hash(sym->name));
hash_add(symbol_hashtable, &sym->hnode, hash_str(sym->name));
}
static void sym_add_unresolved(const char *name, struct module *mod, bool weak)
@ -260,7 +249,7 @@ static struct symbol *sym_find_with_module(const char *name, struct module *mod)
if (name[0] == '.')
name++;
hash_for_each_possible(symbol_hashtable, s, hnode, tdb_hash(name)) {
hash_for_each_possible(symbol_hashtable, s, hnode, hash_str(name)) {
if (strcmp(s->name, name) == 0 && (!mod || s->module == mod))
return s;
}
@ -340,8 +329,6 @@ static const char *sec_name(const struct elf_info *info, unsigned int secindex)
return sech_name(info, &info->sechdrs[secindex]);
}
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
static struct symbol *sym_add_exported(const char *name, struct module *mod,
bool gpl_only, const char *namespace)
{
@ -1966,6 +1953,7 @@ static void write_vmlinux_export_c_file(struct module *mod)
static void write_mod_c_file(struct module *mod)
{
struct buffer buf = { };
struct module_alias *alias, *next;
char fname[PATH_MAX];
int ret;
@ -1973,7 +1961,14 @@ static void write_mod_c_file(struct module *mod)
add_exported_symbols(&buf, mod);
add_versions(&buf, mod);
add_depends(&buf, mod);
add_moddevtable(&buf, mod);
buf_printf(&buf, "\n");
list_for_each_entry_safe(alias, next, &mod->aliases, node) {
buf_printf(&buf, "MODULE_ALIAS(\"%s\");\n", alias->str);
list_del(&alias->node);
free(alias);
}
add_srcversion(&buf, mod);
ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);

View File

@ -67,6 +67,8 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
struct buffer {
char *p;
int pos;
@ -79,6 +81,22 @@ buf_printf(struct buffer *buf, const char *fmt, ...);
void
buf_write(struct buffer *buf, const char *s, int len);
/**
* struct module_alias - auto-generated MODULE_ALIAS()
*
* @node: linked to module::aliases
* @str: a string for MODULE_ALIAS()
*/
struct module_alias {
struct list_head node;
char str[];
};
/**
* struct module - represent a module (vmlinux or *.ko)
*
* @aliases: list head for module_aliases
*/
struct module {
struct list_head list;
struct list_head exported_symbols;
@ -89,12 +107,12 @@ struct module {
bool seen;
bool has_init;
bool has_cleanup;
struct buffer dev_table_buf;
char srcversion[25];
// Missing namespace dependencies
struct list_head missing_namespaces;
// Actual imported namespaces
struct list_head imported_namespaces;
struct list_head aliases;
char name[];
};
@ -170,7 +188,6 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr,
/* file2alias.c */
void handle_moddevtable(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname);
void add_moddevtable(struct buffer *buf, struct module *mod);
/* sumversion.c */
void get_src_version(const char *modname, char sum[], unsigned sumlen);

View File

@ -19,12 +19,6 @@ if ! { echo "$SPATCH_REQ_VERSION"; echo "$SPATCH_VERSION"; } | sort -CV ; then
exit 1
fi
if [ "$KBUILD_EXTMOD" ]; then
src_prefix=
else
src_prefix=$srctree/
fi
generate_deps_for_ns() {
$SPATCH --very-quiet --in-place --sp-file \
$srctree/scripts/coccinelle/misc/add_namespace.cocci -D nsdeps -D ns=$1 $2
@ -34,7 +28,7 @@ generate_deps() {
local mod=${1%.ko:}
shift
local namespaces="$*"
local mod_source_files=$(sed "s|^\(.*\)\.o$|${src_prefix}\1.c|" $mod.mod)
local mod_source_files=$(sed "s|^\(.*\)\.o$|${srcroot}/\1.c|" $mod.mod)
for ns in $namespaces; do
echo "Adding namespace $ns to module $mod.ko."
@ -57,4 +51,4 @@ generate_deps() {
while read line
do
generate_deps $line
done < $MODULES_NSDEPS
done < modules.nsdeps

View File

@ -96,16 +96,18 @@ install_linux_image_dbg () {
# Parse modules.order directly because 'make modules_install' may sign,
# compress modules, and then run unneeded depmod.
while read -r mod; do
mod="${mod%.o}.ko"
dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}"
buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p')
link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug"
if is_enabled CONFIG_MODULES; then
while read -r mod; do
mod="${mod%.o}.ko"
dbg="${pdir}/usr/lib/debug/lib/modules/${KERNELRELEASE}/kernel/${mod}"
buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p')
link="${pdir}/usr/lib/debug/.build-id/${buildid}.debug"
mkdir -p "${dbg%/*}" "${link%/*}"
"${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}"
ln -sf --relative "${dbg}" "${link}"
done < modules.order
mkdir -p "${dbg%/*}" "${link%/*}"
"${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}"
ln -sf --relative "${dbg}" "${link}"
done < modules.order
fi
# Build debug package
# Different tools want the image in different locations

View File

@ -51,6 +51,13 @@ mkdir -p "${destdir}"
if [ "${CC}" != "${HOSTCC}" ]; then
echo "Rebuilding host programs with ${CC}..."
# This leverages external module building.
# - Clear sub_make_done to allow the top-level Makefile to redo sub-make.
# - Filter out --no-print-directory to print "Entering directory" logs
# when Make changes the working directory.
unset sub_make_done
MAKEFLAGS=$(echo "${MAKEFLAGS}" | sed s/--no-print-directory//)
cat <<-'EOF' > "${destdir}/Kbuild"
subdir-y := scripts
EOF

View File

@ -202,7 +202,7 @@ Build-Depends-Arch: bc, bison, cpio, flex,
gcc-${host_gnu} <!pkg.${sourcename}.nokernelheaders>,
kmod, libelf-dev:native,
libssl-dev:native, libssl-dev <!pkg.${sourcename}.nokernelheaders>,
rsync
python3:native, rsync
Homepage: https://www.kernel.org/
Package: $packagename-$version

View File

@ -10,6 +10,8 @@
#
#
set -e
usage() {
echo "Usage: $0 [--no-local] [srctree]" >&2
exit 1
@ -30,6 +32,29 @@ if test $# -gt 0 -o ! -d "$srctree"; then
usage
fi
try_tag() {
tag="$1"
# Is $tag an annotated tag?
if [ "$(git cat-file -t "$tag" 2> /dev/null)" != tag ]; then
return
fi
# Is it an ancestor of HEAD, and if so, how many commits are in $tag..HEAD?
# shellcheck disable=SC2046 # word splitting is the point here
set -- $(git rev-list --count --left-right "$tag"...HEAD 2> /dev/null)
# $1 is 0 if and only if $tag is an ancestor of HEAD. Use
# string comparison, because $1 is empty if the 'git rev-list'
# command somehow failed.
if [ "$1" != 0 ]; then
return
fi
# $2 is the number of commits in the range $tag..HEAD, possibly 0.
count="$2"
}
scm_version()
{
local short=false
@ -61,33 +86,33 @@ scm_version()
# stable kernel: 6.1.7 -> v6.1.7
version_tag=v$(echo "${KERNELVERSION}" | sed -E 's/^([0-9]+\.[0-9]+)\.0(.*)$/\1\2/')
# try_tag initializes count if the tag is usable.
count=
# If a localversion* file exists, and the corresponding
# annotated tag exists and is an ancestor of HEAD, use
# it. This is the case in linux-next.
tag=${file_localversion#-}
desc=
if [ -n "${tag}" ]; then
desc=$(git describe --match=$tag 2>/dev/null)
if [ -n "${file_localversion#-}" ] ; then
try_tag "${file_localversion#-}"
fi
# Otherwise, if a localversion* file exists, and the tag
# obtained by appending it to the tag derived from
# KERNELVERSION exists and is an ancestor of HEAD, use
# it. This is e.g. the case in linux-rt.
if [ -z "${desc}" ] && [ -n "${file_localversion}" ]; then
tag="${version_tag}${file_localversion}"
desc=$(git describe --match=$tag 2>/dev/null)
if [ -z "${count}" ] && [ -n "${file_localversion}" ]; then
try_tag "${version_tag}${file_localversion}"
fi
# Otherwise, default to the annotated tag derived from KERNELVERSION.
if [ -z "${desc}" ]; then
tag="${version_tag}"
desc=$(git describe --match=$tag 2>/dev/null)
if [ -z "${count}" ]; then
try_tag "${version_tag}"
fi
# If we are at the tagged commit, we ignore it because the version is
# well-defined.
if [ "${tag}" != "${desc}" ]; then
# If we are at the tagged commit, we ignore it because the
# version is well-defined. If none of the attempted tags exist
# or were usable, $count is still empty.
if [ -z "${count}" ] || [ "${count}" -gt 0 ]; then
# If only the short version is requested, don't bother
# running further git commands
@ -95,14 +120,15 @@ scm_version()
echo "+"
return
fi
# If we are past the tagged commit, we pretty print it.
# (like 6.1.0-14595-g292a089d78d3)
if [ -n "${desc}" ]; then
echo "${desc}" | awk -F- '{printf("-%05d", $(NF-1))}'
if [ -n "${count}" ]; then
printf "%s%05d" "-" "${count}"
fi
# Add -g and exactly 12 hex chars.
printf '%s%s' -g "$(echo $head | cut -c1-12)"
printf '%s%.12s' -g "$head"
fi
if ${no_dirty}; then

View File

@ -4573,6 +4573,8 @@ static int validate_ibt(struct objtool_file *file)
!strcmp(sec->name, "__jump_table") ||
!strcmp(sec->name, "__mcount_loc") ||
!strcmp(sec->name, ".kcfi_traps") ||
!strcmp(sec->name, ".llvm.call-graph-profile") ||
!strcmp(sec->name, ".llvm_bb_addr_map") ||
!strcmp(sec->name, "__tracepoints") ||
strstr(sec->name, "__patchable_function_entries"))
continue;

View File

@ -224,12 +224,17 @@ int find_symbol_hole_containing(const struct section *sec, unsigned long offset)
if (n)
return 0; /* not a hole */
/* didn't find a symbol for which @offset is after it */
if (!hole.sym)
return 0; /* not a hole */
/*
* @offset >= sym->offset + sym->len, find symbol after it.
* When hole.sym is empty, use the first node to compute the hole.
* If there is no symbol in the section, the first node will be NULL,
* in which case, -1 is returned to skip the whole section.
*/
if (hole.sym)
n = rb_next(&hole.sym->node);
else
n = rb_first_cached(&sec->symbol_tree);
/* @offset >= sym->offset + sym->len, find symbol after it */
n = rb_next(&hole.sym->node);
if (!n)
return -1; /* until end of address space */