Kbuild updates for v6.8

- Make Kconfig parse the input .config more precisely
 
  - Support W=c and W=e options for Kconfig
 
  - Set Kconfig int/hex symbols to zero if the 'default' property is
    missing
 
  - Add .editorconfig
 
  - Add scripts/git.orderFile
 
  - Add a script to detect backward-incompatible changes in UAPI headers
 
  - Resolve the symlink passed to O= option properly
 
  - Use the user-supplied mtime for all files in the builtin initramfs,
    which provides better reproducible builds
 
  - Fix the direct execution of debian/rules for Debian package builds
 
  - Use build ID instead of the .gnu_debuglink section for the Debian dbg
    package
 -----BEGIN PGP SIGNATURE-----
 
 iQJJBAABCgAzFiEEbmPs18K1szRHjPqEPYsBB53g2wYFAmWnEQ8VHG1hc2FoaXJv
 eUBrZXJuZWwub3JnAAoJED2LAQed4NsGbn8P/RpJ6f4eYAVG/Jnsf5xkkuoOCdWP
 ADA9I5VfgiUzEZV48tjjUOOhk9LO/QDwlxtbLZjlo9jC5TI+IVrXzCu4ShRhmE+4
 eM/VXFur9RN6CuNWNmkf7yzd0dawiwL4QR/0L82ZNmwXGymeEUzzmFviD5KfJRY8
 z6bgA4jLu9qsHNzX8eYA2LU+jpOoNiRQAlGzTE0oDgQnv/ZXJB/H+8tEhzH85oZk
 F087IQCct25yGAbZhEkuX2PHx5kus9ICF72Pkqxh075aOQzfKIO8S3PPkt4nAiHK
 Cb6sahRcO7QwxH7MJVWgmfbXNMbs9p8fOj9Aiudl2EEWVRav1mw9UuA5kCnTh6vi
 LpI4bYNChl8fNTX2gX+Dfkmbc5r2Yl65ufW23VlRdZfdrXbJWlQbkkdvJeb7NoEj
 u6z26b/2WMaTecxr0Bw50PbleHYZwWIscN5lGoK6rgUU04mr4t8g1ejpcxfj+79S
 MfbpEvPGKMJjelRBHf2x4qzzHQZHeqIbaItCNt8wGSVipgTvrWED2UaaEnW02SoL
 pwIcBjV9xiUo8UUVil/R8W6xr/Ybv0lWYcIBzQjibiCzhFgw4adPnzZ6eTlaV+6e
 ne527SqxQ0gF3xgDhxOz4VUF/b4TlnVycArIl80Kk/sFd8jX+AObkCtamZEPc0Rz
 GjsorSF/s+Fw7XMp
 =HXZB
 -----END PGP SIGNATURE-----

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

Pull Kbuild updates from Masahiro Yamada:

 - Make Kconfig parse the input .config more precisely

 - Support W=c and W=e options for Kconfig

 - Set Kconfig int/hex symbols to zero if the 'default' property is
   missing

 - Add .editorconfig

 - Add scripts/git.orderFile

 - Add a script to detect backward-incompatible changes in UAPI headers

 - Resolve the symlink passed to O= option properly

 - Use the user-supplied mtime for all files in the builtin initramfs,
   which provides better reproducible builds

 - Fix the direct execution of debian/rules for Debian package builds

 - Use build ID instead of the .gnu_debuglink section for the Debian dbg
   package

* tag 'kbuild-v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (53 commits)
  kbuild: deb-pkg: use debian/<package> for tmpdir
  kbuild: deb-pkg: move 'make headers' to build-arch
  kbuild: deb-pkg: do not search for 'scripts' directory under arch/
  kbuild: deb-pkg: use build ID instead of debug link for dbg package
  kbuild: deb-pkg: use more debhelper commands in builddeb
  kbuild: deb-pkg: remove unneeded '-f $srctree/Makefile' in debian/rules
  kbuild: deb-pkg: allow to run debian/rules from output directory
  kbuild: deb-pkg: set DEB_* variables if debian/rules is directly executed
  kbuild: deb-pkg: squash scripts/package/deb-build-option to debian/rules
  kbuild: deb-pkg: factor out common Make options in debian/rules
  kbuild: deb-pkg: hard-code Build-Depends
  kbuild: deb-pkg: split debian/copyright from the mkdebian script
  gen_init_cpio: Apply mtime supplied by user to all file types
  kbuild: resolve symlinks for O= properly
  docs: dev-tools: Add UAPI checker documentation
  check-uapi: Introduce check-uapi.sh
  scripts: Introduce a default git.orderFile
  kconfig: WERROR unmet symbol dependency
  Add .editorconfig file for basic formatting
  kconfig: Use KCONFIG_CONFIG instead of .config
  ...
This commit is contained in:
Linus Torvalds 2024-01-18 17:57:07 -08:00
commit b5f66ba2d0
46 changed files with 1490 additions and 509 deletions

32
.editorconfig Normal file
View File

@ -0,0 +1,32 @@
# SPDX-License-Identifier: GPL-2.0-only
root = true
[{*.{awk,c,dts,dtsi,dtso,h,mk,s,S},Kconfig,Makefile,Makefile.*}]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = tab
indent_size = 8
[*.{json,py,rs}]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4
# this must be below the general *.py to overwrite it
[tools/{perf,power,rcu,testing/kunit}/**.py,]
indent_style = tab
indent_size = 8
[*.yaml]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = unset
insert_final_newline = true
indent_style = space
indent_size = 2

1
.gitignore vendored
View File

@ -96,6 +96,7 @@ modules.order
#
!.clang-format
!.cocciconfig
!.editorconfig
!.get_maintainer.ignore
!.gitattributes
!.gitignore

View File

@ -0,0 +1,477 @@
.. SPDX-License-Identifier: GPL-2.0-only
============
UAPI Checker
============
The UAPI checker (``scripts/check-uapi.sh``) is a shell script which
checks UAPI header files for userspace backwards-compatibility across
the git tree.
Options
=======
This section will describe the options with which ``check-uapi.sh``
can be run.
Usage::
check-uapi.sh [-b BASE_REF] [-p PAST_REF] [-j N] [-l ERROR_LOG] [-i] [-q] [-v]
Available options::
-b BASE_REF Base git reference to use for comparison. If unspecified or empty,
will use any dirty changes in tree to UAPI files. If there are no
dirty changes, HEAD will be used.
-p PAST_REF Compare BASE_REF to PAST_REF (e.g. -p v6.1). If unspecified or empty,
will use BASE_REF^1. Must be an ancestor of BASE_REF. Only headers
that exist on PAST_REF will be checked for compatibility.
-j JOBS Number of checks to run in parallel (default: number of CPU cores).
-l ERROR_LOG Write error log to file (default: no error log is generated).
-i Ignore ambiguous changes that may or may not break UAPI compatibility.
-q Quiet operation.
-v Verbose operation (print more information about each header being checked).
Environmental args::
ABIDIFF Custom path to abidiff binary
CC C compiler (default is "gcc")
ARCH Target architecture of C compiler (default is host arch)
Exit codes::
0) Success
1) ABI difference detected
2) Prerequisite not met
Examples
========
Basic Usage
-----------
First, let's try making a change to a UAPI header file that obviously
won't break userspace::
cat << 'EOF' | patch -l -p1
--- a/include/uapi/linux/acct.h
+++ b/include/uapi/linux/acct.h
@@ -21,7 +21,9 @@
#include <asm/param.h>
#include <asm/byteorder.h>
-/*
+#define FOO
+
+/*
* comp_t is a 16-bit "floating" point number with a 3-bit base 8
* exponent and a 13-bit fraction.
* comp2_t is 24-bit with 5-bit base 2 exponent and 20 bit fraction
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
EOF
Now, let's use the script to validate::
% ./scripts/check-uapi.sh
Installing user-facing UAPI headers from dirty tree... OK
Installing user-facing UAPI headers from HEAD... OK
Checking changes to UAPI headers between HEAD and dirty tree...
All 912 UAPI headers compatible with x86 appear to be backwards compatible
Let's add another change that *might* break userspace::
cat << 'EOF' | patch -l -p1
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -74,7 +74,7 @@ struct bpf_insn {
__u8 dst_reg:4; /* dest register */
__u8 src_reg:4; /* source register */
__s16 off; /* signed offset */
- __s32 imm; /* signed immediate constant */
+ __u32 imm; /* unsigned immediate constant */
};
/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */
EOF
The script will catch this::
% ./scripts/check-uapi.sh
Installing user-facing UAPI headers from dirty tree... OK
Installing user-facing UAPI headers from HEAD... OK
Checking changes to UAPI headers between HEAD and dirty tree...
==== ABI differences detected in include/linux/bpf.h from HEAD -> dirty tree ====
[C] 'struct bpf_insn' changed:
type size hasn't changed
1 data member change:
type of '__s32 imm' changed:
typedef name changed from __s32 to __u32 at int-ll64.h:27:1
underlying type 'int' changed:
type name changed from 'int' to 'unsigned int'
type size hasn't changed
==================================================================================
error - 1/912 UAPI headers compatible with x86 appear _not_ to be backwards compatible
In this case, the script is reporting the type change because it could
break a userspace program that passes in a negative number. Now, let's
say you know that no userspace program could possibly be using a negative
value in ``imm``, so changing to an unsigned type there shouldn't hurt
anything. You can pass the ``-i`` flag to the script to ignore changes
in which the userspace backwards compatibility is ambiguous::
% ./scripts/check-uapi.sh -i
Installing user-facing UAPI headers from dirty tree... OK
Installing user-facing UAPI headers from HEAD... OK
Checking changes to UAPI headers between HEAD and dirty tree...
All 912 UAPI headers compatible with x86 appear to be backwards compatible
Now, let's make a similar change that *will* break userspace::
cat << 'EOF' | patch -l -p1
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -71,8 +71,8 @@ enum {
struct bpf_insn {
__u8 code; /* opcode */
- __u8 dst_reg:4; /* dest register */
__u8 src_reg:4; /* source register */
+ __u8 dst_reg:4; /* dest register */
__s16 off; /* signed offset */
__s32 imm; /* signed immediate constant */
};
EOF
Since we're re-ordering an existing struct member, there's no ambiguity,
and the script will report the breakage even if you pass ``-i``::
% ./scripts/check-uapi.sh -i
Installing user-facing UAPI headers from dirty tree... OK
Installing user-facing UAPI headers from HEAD... OK
Checking changes to UAPI headers between HEAD and dirty tree...
==== ABI differences detected in include/linux/bpf.h from HEAD -> dirty tree ====
[C] 'struct bpf_insn' changed:
type size hasn't changed
2 data member changes:
'__u8 dst_reg' offset changed from 8 to 12 (in bits) (by +4 bits)
'__u8 src_reg' offset changed from 12 to 8 (in bits) (by -4 bits)
==================================================================================
error - 1/912 UAPI headers compatible with x86 appear _not_ to be backwards compatible
Let's commit the breaking change, then commit the innocuous change::
% git commit -m 'Breaking UAPI change' include/uapi/linux/bpf.h
[detached HEAD f758e574663a] Breaking UAPI change
1 file changed, 1 insertion(+), 1 deletion(-)
% git commit -m 'Innocuous UAPI change' include/uapi/linux/acct.h
[detached HEAD 2e87df769081] Innocuous UAPI change
1 file changed, 3 insertions(+), 1 deletion(-)
Now, let's run the script again with no arguments::
% ./scripts/check-uapi.sh
Installing user-facing UAPI headers from HEAD... OK
Installing user-facing UAPI headers from HEAD^1... OK
Checking changes to UAPI headers between HEAD^1 and HEAD...
All 912 UAPI headers compatible with x86 appear to be backwards compatible
It doesn't catch any breaking change because, by default, it only
compares ``HEAD`` to ``HEAD^1``. The breaking change was committed on
``HEAD~2``. If we wanted the search scope to go back further, we'd have to
use the ``-p`` option to pass a different past reference. In this case,
let's pass ``-p HEAD~2`` to the script so it checks UAPI changes between
``HEAD~2`` and ``HEAD``::
% ./scripts/check-uapi.sh -p HEAD~2
Installing user-facing UAPI headers from HEAD... OK
Installing user-facing UAPI headers from HEAD~2... OK
Checking changes to UAPI headers between HEAD~2 and HEAD...
==== ABI differences detected in include/linux/bpf.h from HEAD~2 -> HEAD ====
[C] 'struct bpf_insn' changed:
type size hasn't changed
2 data member changes:
'__u8 dst_reg' offset changed from 8 to 12 (in bits) (by +4 bits)
'__u8 src_reg' offset changed from 12 to 8 (in bits) (by -4 bits)
==============================================================================
error - 1/912 UAPI headers compatible with x86 appear _not_ to be backwards compatible
Alternatively, we could have also run with ``-b HEAD~``. This would set the
base reference to ``HEAD~`` so then the script would compare it to ``HEAD~^1``.
Architecture-specific Headers
-----------------------------
Consider this change::
cat << 'EOF' | patch -l -p1
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -70,6 +70,7 @@ struct sigcontext {
struct _aarch64_ctx {
__u32 magic;
__u32 size;
+ __u32 new_var;
};
#define FPSIMD_MAGIC 0x46508001
EOF
This is a change to an arm64-specific UAPI header file. In this example, I'm
running the script from an x86 machine with an x86 compiler, so, by default,
the script only checks x86-compatible UAPI header files::
% ./scripts/check-uapi.sh
Installing user-facing UAPI headers from dirty tree... OK
Installing user-facing UAPI headers from HEAD... OK
No changes to UAPI headers were applied between HEAD and dirty tree
With an x86 compiler, we can't check header files in ``arch/arm64``, so the
script doesn't even try.
If we want to check the header file, we'll have to use an arm64 compiler and
set ``ARCH`` accordingly::
% CC=aarch64-linux-gnu-gcc ARCH=arm64 ./scripts/check-uapi.sh
Installing user-facing UAPI headers from dirty tree... OK
Installing user-facing UAPI headers from HEAD... OK
Checking changes to UAPI headers between HEAD and dirty tree...
==== ABI differences detected in include/asm/sigcontext.h from HEAD -> dirty tree ====
[C] 'struct _aarch64_ctx' changed:
type size changed from 64 to 96 (in bits)
1 data member insertion:
'__u32 new_var', at offset 64 (in bits) at sigcontext.h:73:1
-- snip --
[C] 'struct zt_context' changed:
type size changed from 128 to 160 (in bits)
2 data member changes (1 filtered):
'__u16 nregs' offset changed from 64 to 96 (in bits) (by +32 bits)
'__u16 __reserved[3]' offset changed from 80 to 112 (in bits) (by +32 bits)
=======================================================================================
error - 1/884 UAPI headers compatible with arm64 appear _not_ to be backwards compatible
We can see with ``ARCH`` and ``CC`` set properly for the file, the ABI
change is reported properly. Also notice that the total number of UAPI
header files checked by the script changes. This is because the number
of headers installed for arm64 platforms is different than x86.
Cross-Dependency Breakages
--------------------------
Consider this change::
cat << 'EOF' | patch -l -p1
--- a/include/uapi/linux/types.h
+++ b/include/uapi/linux/types.h
@@ -52,7 +52,7 @@ typedef __u32 __bitwise __wsum;
#define __aligned_be64 __be64 __attribute__((aligned(8)))
#define __aligned_le64 __le64 __attribute__((aligned(8)))
-typedef unsigned __bitwise __poll_t;
+typedef unsigned short __bitwise __poll_t;
#endif /* __ASSEMBLY__ */
#endif /* _UAPI_LINUX_TYPES_H */
EOF
Here, we're changing a ``typedef`` in ``types.h``. This doesn't break
a UAPI in ``types.h``, but other UAPIs in the tree may break due to
this change::
% ./scripts/check-uapi.sh
Installing user-facing UAPI headers from dirty tree... OK
Installing user-facing UAPI headers from HEAD... OK
Checking changes to UAPI headers between HEAD and dirty tree...
==== ABI differences detected in include/linux/eventpoll.h from HEAD -> dirty tree ====
[C] 'struct epoll_event' changed:
type size changed from 96 to 80 (in bits)
2 data member changes:
type of '__poll_t events' changed:
underlying type 'unsigned int' changed:
type name changed from 'unsigned int' to 'unsigned short int'
type size changed from 32 to 16 (in bits)
'__u64 data' offset changed from 32 to 16 (in bits) (by -16 bits)
========================================================================================
include/linux/eventpoll.h did not change between HEAD and dirty tree...
It's possible a change to one of the headers it includes caused this error:
#include <linux/fcntl.h>
#include <linux/types.h>
Note that the script noticed the failing header file did not change,
so it assumes one of its includes must have caused the breakage. Indeed,
we can see ``linux/types.h`` is used from ``eventpoll.h``.
UAPI Header Removals
--------------------
Consider this change::
cat << 'EOF' | patch -l -p1
diff --git a/include/uapi/asm-generic/Kbuild b/include/uapi/asm-generic/Kbuild
index ebb180aac74e..a9c88b0a8b3b 100644
--- a/include/uapi/asm-generic/Kbuild
+++ b/include/uapi/asm-generic/Kbuild
@@ -31,6 +31,6 @@ mandatory-y += stat.h
mandatory-y += statfs.h
mandatory-y += swab.h
mandatory-y += termbits.h
-mandatory-y += termios.h
+#mandatory-y += termios.h
mandatory-y += types.h
mandatory-y += unistd.h
EOF
This script removes a UAPI header file from the install list. Let's run
the script::
% ./scripts/check-uapi.sh
Installing user-facing UAPI headers from dirty tree... OK
Installing user-facing UAPI headers from HEAD... OK
Checking changes to UAPI headers between HEAD and dirty tree...
==== UAPI header include/asm/termios.h was removed between HEAD and dirty tree ====
error - 1/912 UAPI headers compatible with x86 appear _not_ to be backwards compatible
Removing a UAPI header is considered a breaking change, and the script
will flag it as such.
Checking Historic UAPI Compatibility
------------------------------------
You can use the ``-b`` and ``-p`` options to examine different chunks of your
git tree. For example, to check all changed UAPI header files between tags
v6.0 and v6.1, you'd run::
% ./scripts/check-uapi.sh -b v6.1 -p v6.0
Installing user-facing UAPI headers from v6.1... OK
Installing user-facing UAPI headers from v6.0... OK
Checking changes to UAPI headers between v6.0 and v6.1...
--- snip ---
error - 37/907 UAPI headers compatible with x86 appear _not_ to be backwards compatible
Note: Before v5.3, a header file needed by the script is not present,
so the script is unable to check changes before then.
You'll notice that the script detected many UAPI changes that are not
backwards compatible. Knowing that kernel UAPIs are supposed to be stable
forever, this is an alarming result. This brings us to the next section:
caveats.
Caveats
=======
The UAPI checker makes no assumptions about the author's intention, so some
types of changes may be flagged even though they intentionally break UAPI.
Removals For Refactoring or Deprecation
---------------------------------------
Sometimes drivers for very old hardware are removed, such as in this example::
% ./scripts/check-uapi.sh -b ba47652ba655
Installing user-facing UAPI headers from ba47652ba655... OK
Installing user-facing UAPI headers from ba47652ba655^1... OK
Checking changes to UAPI headers between ba47652ba655^1 and ba47652ba655...
==== UAPI header include/linux/meye.h was removed between ba47652ba655^1 and ba47652ba655 ====
error - 1/910 UAPI headers compatible with x86 appear _not_ to be backwards compatible
The script will always flag removals (even if they're intentional).
Struct Expansions
-----------------
Depending on how a structure is handled in kernelspace, a change which
expands a struct could be non-breaking.
If a struct is used as the argument to an ioctl, then the kernel driver
must be able to handle ioctl commands of any size. Beyond that, you need
to be careful when copying data from the user. Say, for example, that
``struct foo`` is changed like this::
struct foo {
__u64 a; /* added in version 1 */
+ __u32 b; /* added in version 2 */
+ __u32 c; /* added in version 2 */
}
By default, the script will flag this kind of change for further review::
[C] 'struct foo' changed:
type size changed from 64 to 128 (in bits)
2 data member insertions:
'__u32 b', at offset 64 (in bits)
'__u32 c', at offset 96 (in bits)
However, it is possible that this change was made safely.
If a userspace program was built with version 1, it will think
``sizeof(struct foo)`` is 8. That size will be encoded in the
ioctl value that gets sent to the kernel. If the kernel is built
with version 2, it will think the ``sizeof(struct foo)`` is 16.
The kernel can use the ``_IOC_SIZE`` macro to get the size encoded
in the ioctl code that the user passed in and then use
``copy_struct_from_user()`` to safely copy the value::
int handle_ioctl(unsigned long cmd, unsigned long arg)
{
switch _IOC_NR(cmd) {
0x01: {
struct foo my_cmd; /* size 16 in the kernel */
ret = copy_struct_from_user(&my_cmd, arg, sizeof(struct foo), _IOC_SIZE(cmd));
...
``copy_struct_from_user`` will zero the struct in the kernel and then copy
only the bytes passed in from the user (leaving new members zeroized).
If the user passed in a larger struct, the extra members are ignored.
If you know this situation is accounted for in the kernel code, you can
pass ``-i`` to the script, and struct expansions like this will be ignored.
Flex Array Migration
--------------------
While the script handles expansion into an existing flex array, it does
still flag initial migration to flex arrays from 1-element fake flex
arrays. For example::
struct foo {
__u32 x;
- __u32 flex[1]; /* fake flex */
+ __u32 flex[]; /* real flex */
};
This change would be flagged by the script::
[C] 'struct foo' changed:
type size changed from 64 to 32 (in bits)
1 data member change:
type of '__u32 flex[1]' changed:
type name changed from '__u32[1]' to '__u32[]'
array type size changed from 32 to 'unknown'
array type subrange 1 changed length from 1 to 'unknown'
At this time, there's no way to filter these types of changes, so be
aware of this possible false positive.
Summary
-------
While many types of false positives are filtered out by the script,
it's possible there are some cases where the script flags a change
which does not break UAPI. It's also possible a change which *does*
break userspace would not be flagged by this script. While the script
has been run on much of the kernel history, there could still be corner
cases that are not accounted for.
The intention is for this script to be used as a quick check for
maintainers or automated tooling, not as the end-all authority on
patch compatibility. It's best to remember: use your best judgment
(and ideally a unit test in userspace) to make sure your UAPI changes
are backwards-compatible!

View File

@ -31,6 +31,7 @@ Documentation/dev-tools/testing-overview.rst
kselftest
kunit/index
ktap
checkuapi
.. only:: subproject and html

View File

@ -66,6 +66,10 @@ for aligning variables/macros, for reflowing text and other similar tasks.
See the file :ref:`Documentation/process/clang-format.rst <clangformat>`
for more details.
Some basic editor settings, such as indentation and line endings, will be
set automatically if you are using an editor that is compatible with
EditorConfig. See the official EditorConfig website for more information:
https://editorconfig.org/
Abstraction layers
******************

View File

@ -735,6 +735,10 @@ for aligning variables/macros, for reflowing text and other similar tasks.
See the file :ref:`Documentation/process/clang-format.rst <clangformat>`
for more details.
Some basic editor settings, such as indentation and line endings, will be
set automatically if you are using an editor that is compatible with
EditorConfig. See the official EditorConfig website for more information:
https://editorconfig.org/
10) Kconfig configuration files
-------------------------------

View File

@ -155,6 +155,15 @@ endif
export KBUILD_EXTMOD
# backward compatibility
KBUILD_EXTRA_WARN ?= $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)
ifeq ("$(origin W)", "command line")
KBUILD_EXTRA_WARN := $(W)
endif
export KBUILD_EXTRA_WARN
# Kbuild will save output files in the current working directory.
# This does not need to match to the root of the kernel source tree.
#
@ -181,14 +190,11 @@ ifeq ("$(origin O)", "command line")
endif
ifneq ($(KBUILD_OUTPUT),)
# Make's built-in functions such as $(abspath ...), $(realpath ...) cannot
# expand a shell special character '~'. We use a somewhat tedious way here.
abs_objtree := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd)
$(if $(abs_objtree),, \
$(error failed to create output directory "$(KBUILD_OUTPUT)"))
# $(realpath ...) gets empty if the path does not exist. Run 'mkdir -p' first.
$(shell mkdir -p "$(KBUILD_OUTPUT)")
# $(realpath ...) resolves symlinks
abs_objtree := $(realpath $(abs_objtree))
abs_objtree := $(realpath $(KBUILD_OUTPUT))
$(if $(abs_objtree),,$(error failed to create output directory "$(KBUILD_OUTPUT)"))
endif # ifneq ($(KBUILD_OUTPUT),)
ifneq ($(words $(subst :, ,$(abs_srctree))), 1)
@ -609,8 +615,6 @@ export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL KBUILD_RUSTFLAGS_KERNEL
export RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o \
-name CVS -o -name .pc -o -name .hg -o -name .git \) \
-prune -o
export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \
--exclude CVS --exclude .pc --exclude .hg --exclude .git
# ===========================================================================
# Rules shared between *config targets and build targets
@ -1662,6 +1666,7 @@ help:
@echo ' 1: warnings which may be relevant and do not occur too often'
@echo ' 2: warnings which occur quite often but may still be relevant'
@echo ' 3: more obscure warnings, can most likely be ignored'
@echo ' c: extra checks in the configuration stage (Kconfig)'
@echo ' e: warnings are being treated as errors'
@echo ' Multiple levels can be combined with W=12 or W=123'
@$(if $(dtstree), \

View File

@ -3,9 +3,6 @@
# Building vDSO images for sparc.
#
VDSO64-$(CONFIG_SPARC64) := y
VDSOCOMPAT-$(CONFIG_COMPAT) := y
# files to link into the vdso
vobjs-y := vdso-note.o vclock_gettime.o
@ -13,22 +10,15 @@ vobjs-y := vdso-note.o vclock_gettime.o
obj-y += vma.o
# vDSO images to build
vdso_img-$(VDSO64-y) += 64
vdso_img-$(VDSOCOMPAT-y) += 32
obj-$(CONFIG_SPARC64) += vdso-image-64.o
obj-$(CONFIG_COMPAT) += vdso-image-32.o
vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
vobjs := $(addprefix $(obj)/, $(vobjs-y))
$(obj)/vdso.o: $(obj)/vdso.so
targets += vdso.lds $(vobjs-y)
# Build the vDSO image C files and link them in.
vdso_img_objs := $(vdso_img-y:%=vdso-image-%.o)
vdso_img_cfiles := $(vdso_img-y:%=vdso-image-%.c)
vdso_img_sodbg := $(vdso_img-y:%=vdso%.so.dbg)
obj-y += $(vdso_img_objs)
targets += $(vdso_img_cfiles)
targets += $(vdso_img_sodbg) $(vdso_img-y:%=vdso%.so)
targets += $(foreach x, 32 64, vdso-image-$(x).c vdso$(x).so vdso$(x).so.dbg)
CPPFLAGS_vdso.lds += -P -C

View File

@ -6,15 +6,6 @@
#include <linux/linkage.h>
#include <linux/stringify.h>
/*
* Export symbols from the kernel to modules. Forked from module.h
* to reduce the amount of pointless cruft we feed to gcc when only
* exporting a simple symbol or two.
*
* Try not to add #includes here. It slows compilation and makes kernel
* hackers place grumpy comments in header files.
*/
/*
* This comment block is used by fixdep. Please do not remove.
*
@ -23,15 +14,6 @@
* side effect of the *.o build rule.
*/
#ifndef __ASSEMBLY__
#ifdef MODULE
extern struct module __this_module;
#define THIS_MODULE (&__this_module)
#else
#define THIS_MODULE ((struct module *)0)
#endif
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_64BIT
#define __EXPORT_SYMBOL_REF(sym) \
.balign 8 ASM_NL \

View File

@ -179,6 +179,13 @@ extern void (*late_time_init)(void);
extern bool initcall_debug;
#ifdef MODULE
extern struct module __this_module;
#define THIS_MODULE (&__this_module)
#else
#define THIS_MODULE ((struct module *)0)
#endif
#endif
#ifndef MODULE

View File

@ -82,15 +82,6 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
# Warn if there is an enum types mismatch
KBUILD_CFLAGS += $(call cc-option,-Wenum-conversion)
# backward compatibility
KBUILD_EXTRA_WARN ?= $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)
ifeq ("$(origin W)", "command line")
KBUILD_EXTRA_WARN := $(W)
endif
export KBUILD_EXTRA_WARN
#
# W=1 - warnings which may be relevant and do not occur too often
#

View File

@ -83,8 +83,8 @@ dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
multi-dtb-y := $(call multi-search, $(dtb-y), .dtb, -dtbs)
# Primitive DTB compiled from *.dts
real-dtb-y := $(call real-search, $(dtb-y), .dtb, -dtbs)
# Base DTB that overlay is applied onto (each first word of $(*-dtbs) expansion)
base-dtb-y := $(foreach m, $(multi-dtb-y), $(firstword $(call suffix-search, $m, .dtb, -dtbs)))
# Base DTB that overlay is applied onto
base-dtb-y := $(filter %.dtb, $(call real-search, $(multi-dtb-y), .dtb, -dtbs))
always-y += $(dtb-y)

View File

@ -4,27 +4,6 @@
include $(srctree)/scripts/Kbuild.include
include $(srctree)/scripts/Makefile.lib
KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE))
# Include only those top-level files that are needed by make, plus the GPL copy
TAR_CONTENT := Documentation LICENSES arch block certs crypto drivers fs \
include init io_uring ipc kernel lib mm net rust \
samples scripts security sound tools usr virt \
.config Makefile \
Kbuild Kconfig COPYING $(wildcard localversion*)
quiet_cmd_src_tar = TAR $(2).tar.gz
cmd_src_tar = \
if test "$(objtree)" != "$(srctree)"; then \
echo >&2; \
echo >&2 " ERROR:"; \
echo >&2 " Building source tarball is not possible outside the"; \
echo >&2 " kernel source tree. Don't set KBUILD_OUTPUT"; \
echo >&2; \
false; \
fi ; \
tar -I $(KGZIP) -c $(RCS_TAR_IGNORE) -f $(2).tar.gz \
--transform 's:^:$(2)/:S' $(TAR_CONTENT) $(3)
# Git
# ---------------------------------------------------------------------------
@ -130,8 +109,6 @@ debian-orig: linux.tar$(debian-orig-suffix) debian
cp $< ../$(orig-name); \
fi
KBUILD_PKG_ROOTCMD ?= 'fakeroot -u'
PHONY += deb-pkg srcdeb-pkg bindeb-pkg
deb-pkg: private build-type := source,binary
@ -146,7 +123,7 @@ deb-pkg srcdeb-pkg bindeb-pkg:
$(if $(findstring source, $(build-type)), \
--unsigned-source --compression=$(KDEB_SOURCE_COMPRESS)) \
$(if $(findstring binary, $(build-type)), \
--rules-file='$(MAKE) -f debian/rules' --jobs=1 -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch), \
-R'$(MAKE) -f debian/rules' -j1 -a$$(cat debian/arch), \
--no-check-builddeps) \
$(DPKG_FLAGS))
@ -157,9 +134,8 @@ snap-pkg:
rm -rf $(objtree)/snap
mkdir $(objtree)/snap
$(MAKE) clean
$(call cmd,src_tar,$(KERNELPATH))
sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \
s@SRCTREE@$(shell realpath $(KERNELPATH).tar.gz)@" \
s@SRCTREE@$(abs_srctree)@" \
$(srctree)/scripts/package/snapcraft.template > \
$(objtree)/snap/snapcraft.yaml
cd $(objtree)/snap && \

573
scripts/check-uapi.sh Executable file
View File

@ -0,0 +1,573 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
# Script to check commits for UAPI backwards compatibility
set -o errexit
set -o pipefail
print_usage() {
name=$(basename "$0")
cat << EOF
$name - check for UAPI header stability across Git commits
By default, the script will check to make sure the latest commit (or current
dirty changes) did not introduce ABI changes when compared to HEAD^1. You can
check against additional commit ranges with the -b and -p options.
The script will not check UAPI headers for architectures other than the one
defined in ARCH.
Usage: $name [-b BASE_REF] [-p PAST_REF] [-j N] [-l ERROR_LOG] [-i] [-q] [-v]
Options:
-b BASE_REF Base git reference to use for comparison. If unspecified or empty,
will use any dirty changes in tree to UAPI files. If there are no
dirty changes, HEAD will be used.
-p PAST_REF Compare BASE_REF to PAST_REF (e.g. -p v6.1). If unspecified or empty,
will use BASE_REF^1. Must be an ancestor of BASE_REF. Only headers
that exist on PAST_REF will be checked for compatibility.
-j JOBS Number of checks to run in parallel (default: number of CPU cores).
-l ERROR_LOG Write error log to file (default: no error log is generated).
-i Ignore ambiguous changes that may or may not break UAPI compatibility.
-q Quiet operation.
-v Verbose operation (print more information about each header being checked).
Environmental args:
ABIDIFF Custom path to abidiff binary
CC C compiler (default is "gcc")
ARCH Target architecture for the UAPI check (default is host arch)
Exit codes:
$SUCCESS) Success
$FAIL_ABI) ABI difference detected
$FAIL_PREREQ) Prerequisite not met
EOF
}
readonly SUCCESS=0
readonly FAIL_ABI=1
readonly FAIL_PREREQ=2
# Print to stderr
eprintf() {
# shellcheck disable=SC2059
printf "$@" >&2
}
# Expand an array with a specific character (similar to Python string.join())
join() {
local IFS="$1"
shift
printf "%s" "$*"
}
# Create abidiff suppressions
gen_suppressions() {
# Common enum variant names which we don't want to worry about
# being shifted when new variants are added.
local -a enum_regex=(
".*_AFTER_LAST$"
".*_CNT$"
".*_COUNT$"
".*_END$"
".*_LAST$"
".*_MASK$"
".*_MAX$"
".*_MAX_BIT$"
".*_MAX_BPF_ATTACH_TYPE$"
".*_MAX_ID$"
".*_MAX_SHIFT$"
".*_NBITS$"
".*_NETDEV_NUMHOOKS$"
".*_NFT_META_IIFTYPE$"
".*_NL80211_ATTR$"
".*_NLDEV_NUM_OPS$"
".*_NUM$"
".*_NUM_ELEMS$"
".*_NUM_IRQS$"
".*_SIZE$"
".*_TLSMAX$"
"^MAX_.*"
"^NUM_.*"
)
# Common padding field names which can be expanded into
# without worrying about users.
local -a padding_regex=(
".*end$"
".*pad$"
".*pad[0-9]?$"
".*pad_[0-9]?$"
".*padding$"
".*padding[0-9]?$"
".*padding_[0-9]?$"
".*res$"
".*resv$"
".*resv[0-9]?$"
".*resv_[0-9]?$"
".*reserved$"
".*reserved[0-9]?$"
".*reserved_[0-9]?$"
".*rsvd[0-9]?$"
".*unused$"
)
cat << EOF
[suppress_type]
type_kind = enum
changed_enumerators_regexp = $(join , "${enum_regex[@]}")
EOF
for p in "${padding_regex[@]}"; do
cat << EOF
[suppress_type]
type_kind = struct
has_data_member_inserted_at = offset_of_first_data_member_regexp(${p})
EOF
done
if [ "$IGNORE_AMBIGUOUS_CHANGES" = "true" ]; then
cat << EOF
[suppress_type]
type_kind = struct
has_data_member_inserted_at = end
has_size_change = yes
EOF
fi
}
# Check if git tree is dirty
tree_is_dirty() {
! git diff --quiet
}
# Get list of files installed in $ref
get_file_list() {
local -r ref="$1"
local -r tree="$(get_header_tree "$ref")"
# Print all installed headers, filtering out ones that can't be compiled
find "$tree" -type f -name '*.h' -printf '%P\n' | grep -v -f "$INCOMPAT_LIST"
}
# Add to the list of incompatible headers
add_to_incompat_list() {
local -r ref="$1"
# Start with the usr/include/Makefile to get a list of the headers
# that don't compile using this method.
if [ ! -f usr/include/Makefile ]; then
eprintf "error - no usr/include/Makefile present at %s\n" "$ref"
eprintf "Note: usr/include/Makefile was added in the v5.3 kernel release\n"
exit "$FAIL_PREREQ"
fi
{
# shellcheck disable=SC2016
printf 'all: ; @echo $(no-header-test)\n'
cat usr/include/Makefile
} | SRCARCH="$ARCH" make --always-make -f - | tr " " "\n" \
| grep -v "asm-generic" >> "$INCOMPAT_LIST"
# The makefile also skips all asm-generic files, but prints "asm-generic/%"
# which won't work for our grep match. Instead, print something grep will match.
printf "asm-generic/.*\.h\n" >> "$INCOMPAT_LIST"
}
# Compile the simple test app
do_compile() {
local -r inc_dir="$1"
local -r header="$2"
local -r out="$3"
printf "int main(void) { return 0; }\n" | \
"$CC" -c \
-o "$out" \
-x c \
-O0 \
-std=c90 \
-fno-eliminate-unused-debug-types \
-g \
"-I${inc_dir}" \
-include "$header" \
-
}
# Run make headers_install
run_make_headers_install() {
local -r ref="$1"
local -r install_dir="$(get_header_tree "$ref")"
make -j "$MAX_THREADS" ARCH="$ARCH" INSTALL_HDR_PATH="$install_dir" \
headers_install > /dev/null
}
# Install headers for both git refs
install_headers() {
local -r base_ref="$1"
local -r past_ref="$2"
for ref in "$base_ref" "$past_ref"; do
printf "Installing user-facing UAPI headers from %s... " "${ref:-dirty tree}"
if [ -n "$ref" ]; then
git archive --format=tar --prefix="${ref}-archive/" "$ref" \
| (cd "$TMP_DIR" && tar xf -)
(
cd "${TMP_DIR}/${ref}-archive"
run_make_headers_install "$ref"
add_to_incompat_list "$ref" "$INCOMPAT_LIST"
)
else
run_make_headers_install "$ref"
add_to_incompat_list "$ref" "$INCOMPAT_LIST"
fi
printf "OK\n"
done
sort -u -o "$INCOMPAT_LIST" "$INCOMPAT_LIST"
sed -i -e '/^$/d' "$INCOMPAT_LIST"
}
# Print the path to the headers_install tree for a given ref
get_header_tree() {
local -r ref="$1"
printf "%s" "${TMP_DIR}/${ref}/usr"
}
# Check file list for UAPI compatibility
check_uapi_files() {
local -r base_ref="$1"
local -r past_ref="$2"
local -r abi_error_log="$3"
local passed=0;
local failed=0;
local -a threads=()
set -o errexit
printf "Checking changes to UAPI headers between %s and %s...\n" "$past_ref" "${base_ref:-dirty tree}"
# Loop over all UAPI headers that were installed by $past_ref (if they only exist on $base_ref,
# there's no way they're broken and no way to compare anyway)
while read -r file; do
if [ "${#threads[@]}" -ge "$MAX_THREADS" ]; then
if wait "${threads[0]}"; then
passed=$((passed + 1))
else
failed=$((failed + 1))
fi
threads=("${threads[@]:1}")
fi
check_individual_file "$base_ref" "$past_ref" "$file" &
threads+=("$!")
done < <(get_file_list "$past_ref")
for t in "${threads[@]}"; do
if wait "$t"; then
passed=$((passed + 1))
else
failed=$((failed + 1))
fi
done
if [ -n "$abi_error_log" ]; then
printf 'Generated by "%s %s" from git ref %s\n\n' \
"$0" "$*" "$(git rev-parse HEAD)" > "$abi_error_log"
fi
while read -r error_file; do
{
cat "$error_file"
printf "\n\n"
} | tee -a "${abi_error_log:-/dev/null}" >&2
done < <(find "$TMP_DIR" -type f -name '*.error' | sort)
total="$((passed + failed))"
if [ "$failed" -gt 0 ]; then
eprintf "error - %d/%d UAPI headers compatible with %s appear _not_ to be backwards compatible\n" \
"$failed" "$total" "$ARCH"
if [ -n "$abi_error_log" ]; then
eprintf "Failure summary saved to %s\n" "$abi_error_log"
fi
else
printf "All %d UAPI headers compatible with %s appear to be backwards compatible\n" \
"$total" "$ARCH"
fi
return "$failed"
}
# Check an individual file for UAPI compatibility
check_individual_file() {
local -r base_ref="$1"
local -r past_ref="$2"
local -r file="$3"
local -r base_header="$(get_header_tree "$base_ref")/${file}"
local -r past_header="$(get_header_tree "$past_ref")/${file}"
if [ ! -f "$base_header" ]; then
mkdir -p "$(dirname "$base_header")"
printf "==== UAPI header %s was removed between %s and %s ====" \
"$file" "$past_ref" "$base_ref" \
> "${base_header}.error"
return 1
fi
compare_abi "$file" "$base_header" "$past_header" "$base_ref" "$past_ref"
}
# Perform the A/B compilation and compare output ABI
compare_abi() {
local -r file="$1"
local -r base_header="$2"
local -r past_header="$3"
local -r base_ref="$4"
local -r past_ref="$5"
local -r log="${TMP_DIR}/log/${file}.log"
local -r error_log="${TMP_DIR}/log/${file}.error"
mkdir -p "$(dirname "$log")"
if ! do_compile "$(get_header_tree "$base_ref")/include" "$base_header" "${base_header}.bin" 2> "$log"; then
{
warn_str=$(printf "==== Could not compile version of UAPI header %s at %s ====\n" \
"$file" "$base_ref")
printf "%s\n" "$warn_str"
cat "$log"
printf -- "=%.0s" $(seq 0 ${#warn_str})
} > "$error_log"
return 1
fi
if ! do_compile "$(get_header_tree "$past_ref")/include" "$past_header" "${past_header}.bin" 2> "$log"; then
{
warn_str=$(printf "==== Could not compile version of UAPI header %s at %s ====\n" \
"$file" "$past_ref")
printf "%s\n" "$warn_str"
cat "$log"
printf -- "=%.0s" $(seq 0 ${#warn_str})
} > "$error_log"
return 1
fi
local ret=0
"$ABIDIFF" --non-reachable-types \
--suppressions "$SUPPRESSIONS" \
"${past_header}.bin" "${base_header}.bin" > "$log" || ret="$?"
if [ "$ret" -eq 0 ]; then
if [ "$VERBOSE" = "true" ]; then
printf "No ABI differences detected in %s from %s -> %s\n" \
"$file" "$past_ref" "$base_ref"
fi
else
# Bits in abidiff's return code can be used to determine the type of error
if [ $((ret & 0x2)) -gt 0 ]; then
eprintf "error - abidiff did not run properly\n"
exit 1
fi
if [ "$IGNORE_AMBIGUOUS_CHANGES" = "true" ] && [ "$ret" -eq 4 ]; then
return 0
fi
# If the only changes were additions (not modifications to existing APIs), then
# there's no problem. Ignore these diffs.
if grep "Unreachable types summary" "$log" | grep -q "0 removed" &&
grep "Unreachable types summary" "$log" | grep -q "0 changed"; then
return 0
fi
{
warn_str=$(printf "==== ABI differences detected in %s from %s -> %s ====" \
"$file" "$past_ref" "$base_ref")
printf "%s\n" "$warn_str"
sed -e '/summary:/d' -e '/changed type/d' -e '/^$/d' -e 's/^/ /g' "$log"
printf -- "=%.0s" $(seq 0 ${#warn_str})
if cmp "$past_header" "$base_header" > /dev/null 2>&1; then
printf "\n%s did not change between %s and %s...\n" "$file" "$past_ref" "${base_ref:-dirty tree}"
printf "It's possible a change to one of the headers it includes caused this error:\n"
grep '^#include' "$base_header"
printf "\n"
fi
} > "$error_log"
return 1
fi
}
# Check that a minimum software version number is satisfied
min_version_is_satisfied() {
local -r min_version="$1"
local -r version_installed="$2"
printf "%s\n%s\n" "$min_version" "$version_installed" \
| sort -Vc > /dev/null 2>&1
}
# Make sure we have the tools we need and the arguments make sense
check_deps() {
ABIDIFF="${ABIDIFF:-abidiff}"
CC="${CC:-gcc}"
ARCH="${ARCH:-$(uname -m)}"
if [ "$ARCH" = "x86_64" ]; then
ARCH="x86"
fi
local -r abidiff_min_version="2.4"
local -r libdw_min_version_if_clang="0.171"
if ! command -v "$ABIDIFF" > /dev/null 2>&1; then
eprintf "error - abidiff not found!\n"
eprintf "Please install abigail-tools version %s or greater\n" "$abidiff_min_version"
eprintf "See: https://sourceware.org/libabigail/manual/libabigail-overview.html\n"
return 1
fi
local -r abidiff_version="$("$ABIDIFF" --version | cut -d ' ' -f 2)"
if ! min_version_is_satisfied "$abidiff_min_version" "$abidiff_version"; then
eprintf "error - abidiff version too old: %s\n" "$abidiff_version"
eprintf "Please install abigail-tools version %s or greater\n" "$abidiff_min_version"
eprintf "See: https://sourceware.org/libabigail/manual/libabigail-overview.html\n"
return 1
fi
if ! command -v "$CC" > /dev/null 2>&1; then
eprintf 'error - %s not found\n' "$CC"
return 1
fi
if "$CC" --version | grep -q clang; then
local -r libdw_version="$(ldconfig -v 2>/dev/null | grep -v SKIPPED | grep -m 1 -o 'libdw-[0-9]\+.[0-9]\+' | cut -c 7-)"
if ! min_version_is_satisfied "$libdw_min_version_if_clang" "$libdw_version"; then
eprintf "error - libdw version too old for use with clang: %s\n" "$libdw_version"
eprintf "Please install libdw from elfutils version %s or greater\n" "$libdw_min_version_if_clang"
eprintf "See: https://sourceware.org/elfutils/\n"
return 1
fi
fi
if [ ! -d "arch/${ARCH}" ]; then
eprintf 'error - ARCH "%s" is not a subdirectory under arch/\n' "$ARCH"
eprintf "Please set ARCH to one of:\n%s\n" "$(find arch -maxdepth 1 -mindepth 1 -type d -printf '%f ' | fmt)"
return 1
fi
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
eprintf "error - this script requires the kernel tree to be initialized with Git\n"
return 1
fi
if ! git rev-parse --verify "$past_ref" > /dev/null 2>&1; then
printf 'error - invalid git reference "%s"\n' "$past_ref"
return 1
fi
if [ -n "$base_ref" ]; then
if ! git merge-base --is-ancestor "$past_ref" "$base_ref" > /dev/null 2>&1; then
printf 'error - "%s" is not an ancestor of base ref "%s"\n' "$past_ref" "$base_ref"
return 1
fi
if [ "$(git rev-parse "$base_ref")" = "$(git rev-parse "$past_ref")" ]; then
printf 'error - "%s" and "%s" are the same reference\n' "$past_ref" "$base_ref"
return 1
fi
fi
}
run() {
local base_ref="$1"
local past_ref="$2"
local abi_error_log="$3"
shift 3
if [ -z "$KERNEL_SRC" ]; then
KERNEL_SRC="$(realpath "$(dirname "$0")"/..)"
fi
cd "$KERNEL_SRC"
if [ -z "$base_ref" ] && ! tree_is_dirty; then
base_ref=HEAD
fi
if [ -z "$past_ref" ]; then
if [ -n "$base_ref" ]; then
past_ref="${base_ref}^1"
else
past_ref=HEAD
fi
fi
if ! check_deps; then
exit "$FAIL_PREREQ"
fi
TMP_DIR=$(mktemp -d)
readonly TMP_DIR
trap 'rm -rf "$TMP_DIR"' EXIT
readonly INCOMPAT_LIST="${TMP_DIR}/incompat_list.txt"
touch "$INCOMPAT_LIST"
readonly SUPPRESSIONS="${TMP_DIR}/suppressions.txt"
gen_suppressions > "$SUPPRESSIONS"
# Run make install_headers for both refs
install_headers "$base_ref" "$past_ref"
# Check for any differences in the installed header trees
if diff -r -q "$(get_header_tree "$base_ref")" "$(get_header_tree "$past_ref")" > /dev/null 2>&1; then
printf "No changes to UAPI headers were applied between %s and %s\n" "$past_ref" "${base_ref:-dirty tree}"
exit "$SUCCESS"
fi
if ! check_uapi_files "$base_ref" "$past_ref" "$abi_error_log"; then
exit "$FAIL_ABI"
fi
}
main() {
MAX_THREADS=$(nproc)
VERBOSE="false"
IGNORE_AMBIGUOUS_CHANGES="false"
quiet="false"
local base_ref=""
while getopts "hb:p:j:l:iqv" opt; do
case $opt in
h)
print_usage
exit "$SUCCESS"
;;
b)
base_ref="$OPTARG"
;;
p)
past_ref="$OPTARG"
;;
j)
MAX_THREADS="$OPTARG"
;;
l)
abi_error_log="$OPTARG"
;;
i)
IGNORE_AMBIGUOUS_CHANGES="true"
;;
q)
quiet="true"
VERBOSE="false"
;;
v)
VERBOSE="true"
quiet="false"
;;
*)
exit "$FAIL_PREREQ"
esac
done
if [ "$quiet" = "true" ]; then
exec > /dev/null 2>&1
fi
run "$base_ref" "$past_ref" "$abi_error_log" "$@"
}
main "$@"

View File

@ -82,21 +82,12 @@ LxPs()
thread_info_type = utils.CachedType("struct thread_info")
ia64_task_size = None
def get_thread_info(task):
thread_info_ptr_type = thread_info_type.get_type().pointer()
if utils.is_target_arch("ia64"):
global ia64_task_size
if ia64_task_size is None:
ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)")
thread_info_addr = task.address + ia64_task_size
thread_info = thread_info_addr.cast(thread_info_ptr_type)
else:
if task.type.fields()[0].type == thread_info_type.get_type():
return task['thread_info']
thread_info = task['stack'].cast(thread_info_ptr_type)
if task.type.fields()[0].type == thread_info_type.get_type():
return task['thread_info']
thread_info = task['stack'].cast(thread_info_ptr_type)
return thread_info.dereference()

View File

@ -16,9 +16,7 @@
#include <unistd.h>
#include <assert.h>
#include <stdarg.h>
#ifdef __GNU_LIBRARY__
#include <getopt.h>
#endif /* __GNU_LIBRARY__ */
#include "genksyms.h"
/*----------------------------------------------------------------------*/
@ -718,8 +716,6 @@ void error_with_pos(const char *fmt, ...)
static void genksyms_usage(void)
{
fputs("Usage:\n" "genksyms [-adDTwqhVR] > /path/to/.tmp_obj.ver\n" "\n"
#ifdef __GNU_LIBRARY__
" -s, --symbol-prefix Select symbol prefix\n"
" -d, --debug Increment the debug level (repeatable)\n"
" -D, --dump Dump expanded symbol defs (for debugging only)\n"
" -r, --reference file Read reference symbols from a file\n"
@ -729,18 +725,6 @@ static void genksyms_usage(void)
" -q, --quiet Disable warnings (default)\n"
" -h, --help Print this message\n"
" -V, --version Print the release version\n"
#else /* __GNU_LIBRARY__ */
" -s Select symbol prefix\n"
" -d Increment the debug level (repeatable)\n"
" -D Dump expanded symbol defs (for debugging only)\n"
" -r file Read reference symbols from a file\n"
" -T file Dump expanded types into file\n"
" -p Preserve reference modversions or fail\n"
" -w Enable warnings\n"
" -q Disable warnings (default)\n"
" -h Print this message\n"
" -V Print the release version\n"
#endif /* __GNU_LIBRARY__ */
, stderr);
}
@ -749,7 +733,6 @@ int main(int argc, char **argv)
FILE *dumpfile = NULL, *ref_file = NULL;
int o;
#ifdef __GNU_LIBRARY__
struct option long_opts[] = {
{"debug", 0, 0, 'd'},
{"warnings", 0, 0, 'w'},
@ -763,11 +746,8 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};
while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph",
while ((o = getopt_long(argc, argv, "dwqVDr:T:ph",
&long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */
while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF)
#endif /* __GNU_LIBRARY__ */
switch (o) {
case 'd':
flag_debug++;

42
scripts/git.orderFile Normal file
View File

@ -0,0 +1,42 @@
# SPDX-License-Identifier: GPL-2.0
# order file for git, to produce patches which are easier to review
# by diffing the important stuff like header changes first.
#
# one-off usage:
# git diff -O scripts/git.orderFile ...
#
# add to git config:
# git config diff.orderFile scripts/git.orderFile
#
MAINTAINERS
# Documentation
Documentation/*
*.rst
# git-specific
.gitignore
scripts/git.orderFile
# build system
Kconfig*
*/Kconfig*
Kbuild*
*/Kbuild*
Makefile*
*/Makefile*
*.mak
*.mk
scripts/*
# semantic patches
*.cocci
# headers
*types.h
*.h
# code
*.c

View File

@ -17,7 +17,6 @@ arch/arm/kernel/head-nommu.o
arch/arm/kernel/head.o
arch/csky/kernel/head.o
arch/hexagon/kernel/head.o
arch/ia64/kernel/head.o
arch/loongarch/kernel/head.o
arch/m68k/68000/head.o
arch/m68k/coldfire/head.o

View File

@ -27,6 +27,14 @@ KCONFIG_DEFCONFIG_LIST += \
endif
KCONFIG_DEFCONFIG_LIST += arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)
ifneq ($(findstring c, $(KBUILD_EXTRA_WARN)),)
export KCONFIG_WARN_UNKNOWN_SYMBOLS=1
endif
ifneq ($(findstring e, $(KBUILD_EXTRA_WARN)),)
export KCONFIG_WERROR=1
endif
# We need this, in case the user has it in its environment
unexport CONFIG_
@ -99,7 +107,7 @@ config-fragments = $(call configfiles,$@)
%.config: $(obj)/conf
$(if $(config-fragments),, $(error $@ fragment does not exists on this architecture))
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(config-fragments)
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m $(KCONFIG_CONFIG) $(config-fragments)
$(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig
PHONY += tinyconfig
@ -166,7 +174,7 @@ conf-objs := conf.o $(common-objs)
# nconf: Used for the nconfig target based on ncurses
hostprogs += nconf
nconf-objs := nconf.o nconf.gui.o $(common-objs)
nconf-objs := nconf.o nconf.gui.o mnconf-common.o $(common-objs)
HOSTLDLIBS_nconf = $(call read-file, $(obj)/nconf-libs)
HOSTCFLAGS_nconf.o = $(call read-file, $(obj)/nconf-cflags)
@ -179,7 +187,7 @@ $(obj)/nconf.o $(obj)/nconf.gui.o: | $(obj)/nconf-cflags
hostprogs += mconf
lxdialog := $(addprefix lxdialog/, \
checklist.o inputbox.o menubox.o textbox.o util.o yesno.o)
mconf-objs := mconf.o $(lxdialog) $(common-objs)
mconf-objs := mconf.o $(lxdialog) mnconf-common.o $(common-objs)
HOSTLDLIBS_mconf = $(call read-file, $(obj)/mconf-libs)
$(foreach f, mconf.o $(lxdialog), \

View File

@ -827,6 +827,9 @@ int main(int ac, char **av)
break;
}
if (conf_errors())
exit(1);
if (sync_kconfig) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
@ -890,6 +893,9 @@ int main(int ac, char **av)
break;
}
if (sym_dep_errors())
exit(1);
if (input_mode == savedefconfig) {
if (conf_write_defconfig(defconfig_file)) {
fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",

View File

@ -155,6 +155,13 @@ static void conf_message(const char *fmt, ...)
static const char *conf_filename;
static int conf_lineno, conf_warnings;
bool conf_errors(void)
{
if (conf_warnings)
return getenv("KCONFIG_WERROR");
return false;
}
static void conf_warning(const char *fmt, ...)
{
va_list ap;
@ -289,16 +296,12 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
#define LINE_GROWTH 16
static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
{
char *nline;
size_t new_size = slen + 1;
if (new_size > *n) {
new_size += LINE_GROWTH - 1;
new_size *= 2;
nline = xrealloc(*lineptr, new_size);
if (!nline)
return -1;
*lineptr = nline;
*lineptr = xrealloc(*lineptr, new_size);
*n = new_size;
}
@ -341,19 +344,37 @@ static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
return -1;
}
/* like getline(), but the newline character is stripped away */
static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
{
ssize_t len;
len = compat_getline(lineptr, n, stream);
if (len > 0 && (*lineptr)[len - 1] == '\n') {
len--;
(*lineptr)[len] = '\0';
if (len > 0 && (*lineptr)[len - 1] == '\r') {
len--;
(*lineptr)[len] = '\0';
}
}
return len;
}
int conf_read_simple(const char *name, int def)
{
FILE *in = NULL;
char *line = NULL;
size_t line_asize = 0;
char *p, *p2;
char *p, *val;
struct symbol *sym;
int i, def_flags;
const char *warn_unknown;
const char *werror;
const char *warn_unknown, *sym_name;
warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
werror = getenv("KCONFIG_WERROR");
if (name) {
in = zconf_fopen(name);
} else {
@ -417,8 +438,7 @@ int conf_read_simple(const char *name, int def)
case S_INT:
case S_HEX:
case S_STRING:
if (sym->def[def].val)
free(sym->def[def].val);
free(sym->def[def].val);
/* fall through */
default:
sym->def[def].val = NULL;
@ -426,90 +446,68 @@ int conf_read_simple(const char *name, int def)
}
}
while (compat_getline(&line, &line_asize, in) != -1) {
while (getline_stripped(&line, &line_asize, in) != -1) {
conf_lineno++;
sym = NULL;
if (!line[0]) /* blank line */
continue;
if (line[0] == '#') {
if (memcmp(line + 2, CONFIG_, strlen(CONFIG_)))
if (line[1] != ' ')
continue;
p = strchr(line + 2 + strlen(CONFIG_), ' ');
p = line + 2;
if (memcmp(p, CONFIG_, strlen(CONFIG_)))
continue;
sym_name = p + strlen(CONFIG_);
p = strchr(sym_name, ' ');
if (!p)
continue;
*p++ = 0;
if (strncmp(p, "is not set", 10))
if (strcmp(p, "is not set"))
continue;
if (def == S_DEF_USER) {
sym = sym_find(line + 2 + strlen(CONFIG_));
if (!sym) {
if (warn_unknown)
conf_warning("unknown symbol: %s",
line + 2 + strlen(CONFIG_));
conf_set_changed(true);
continue;
}
} else {
sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
if (sym->type == S_UNKNOWN)
sym->type = S_BOOLEAN;
}
if (sym->flags & def_flags) {
conf_warning("override: reassigning to symbol %s", sym->name);
}
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
sym->def[def].tri = no;
sym->flags |= def_flags;
break;
default:
;
}
} else if (memcmp(line, CONFIG_, strlen(CONFIG_)) == 0) {
p = strchr(line + strlen(CONFIG_), '=');
if (!p)
continue;
*p++ = 0;
p2 = strchr(p, '\n');
if (p2) {
*p2-- = 0;
if (*p2 == '\r')
*p2 = 0;
}
sym = sym_find(line + strlen(CONFIG_));
if (!sym) {
if (def == S_DEF_AUTO) {
/*
* Reading from include/config/auto.conf
* If CONFIG_FOO previously existed in
* auto.conf but it is missing now,
* include/config/FOO must be touched.
*/
conf_touch_dep(line + strlen(CONFIG_));
} else {
if (warn_unknown)
conf_warning("unknown symbol: %s",
line + strlen(CONFIG_));
conf_set_changed(true);
}
continue;
}
if (sym->flags & def_flags) {
conf_warning("override: reassigning to symbol %s", sym->name);
}
if (conf_set_sym_val(sym, def, def_flags, p))
continue;
val = "n";
} else {
if (line[0] != '\r' && line[0] != '\n')
conf_warning("unexpected data: %.*s",
(int)strcspn(line, "\r\n"), line);
if (memcmp(line, CONFIG_, strlen(CONFIG_))) {
conf_warning("unexpected data: %s", line);
continue;
}
sym_name = line + strlen(CONFIG_);
p = strchr(sym_name, '=');
if (!p) {
conf_warning("unexpected data: %s", line);
continue;
}
*p = 0;
val = p + 1;
}
sym = sym_find(sym_name);
if (!sym) {
if (def == S_DEF_AUTO) {
/*
* Reading from include/config/auto.conf.
* If CONFIG_FOO previously existed in auto.conf
* but it is missing now, include/config/FOO
* must be touched.
*/
conf_touch_dep(sym_name);
} else {
if (warn_unknown)
conf_warning("unknown symbol: %s", sym_name);
conf_set_changed(true);
}
continue;
}
if (sym->flags & def_flags)
conf_warning("override: reassigning to symbol %s", sym->name);
if (conf_set_sym_val(sym, def, def_flags, val))
continue;
if (sym && sym_is_choice_value(sym)) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
switch (sym->def[def].tri) {
@ -533,9 +531,6 @@ int conf_read_simple(const char *name, int def)
free(line);
fclose(in);
if (conf_warnings && werror)
exit(1);
return 0;
}
@ -594,7 +589,7 @@ int conf_read(const char *name)
/* Reset a string value if it's out of range */
if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
break;
sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
sym->flags &= ~SYMBOL_VALID;
conf_unsaved++;
break;
default:

View File

@ -1131,7 +1131,6 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
default:
return -1;
}
printf("[%dgt%d?]", t1, t2);
return 0;
}

View File

@ -99,8 +99,6 @@ bool menu_is_visible(struct menu *menu);
bool menu_has_prompt(struct menu *menu);
const char *menu_get_prompt(struct menu *menu);
struct menu *menu_get_parent_menu(struct menu *menu);
bool menu_has_help(struct menu *menu);
const char *menu_get_help(struct menu *menu);
int get_jump_key_char(void);
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
void menu_get_ext_help(struct menu *menu, struct gstr *help);

View File

@ -1,4 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LKC_PROTO_H
#define LKC_PROTO_H
#include <stdarg.h>
/* confdata.c */
@ -12,6 +15,7 @@ void conf_set_changed(bool val);
bool conf_get_changed(void);
void conf_set_changed_callback(void (*fn)(void));
void conf_set_message_callback(void (*fn)(const char *s));
bool conf_errors(void);
/* symbol.c */
extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
@ -22,6 +26,7 @@ void print_symbol_for_listconfig(struct symbol *sym);
struct symbol ** sym_re_search(const char *pattern);
const char * sym_type_name(enum symbol_type type);
void sym_calc_value(struct symbol *sym);
bool sym_dep_errors(void);
enum symbol_type sym_get_type(struct symbol *sym);
bool sym_tristate_within_range(struct symbol *sym,tristate tri);
bool sym_set_tristate_value(struct symbol *sym,tristate tri);
@ -50,3 +55,5 @@ char *expand_one_token(const char **str);
/* expr.c */
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
#endif /* LKC_PROTO_H */

View File

@ -21,6 +21,7 @@
#include "lkc.h"
#include "lxdialog/dialog.h"
#include "mnconf-common.h"
static const char mconf_readme[] =
"Overview\n"
@ -247,7 +248,7 @@ search_help[] =
" -> PCI support (PCI [=y])\n"
"(1) -> PCI access mode (<choice> [=y])\n"
" Defined at drivers/pci/Kconfig:47\n"
" Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
" Depends on: X86_LOCAL_APIC && X86_IO_APIC\n"
" Selects: LIBCRC32\n"
" Selected by: BAR [=n]\n"
"-----------------------------------------------------------------\n"
@ -286,7 +287,6 @@ static int single_menu_mode;
static int show_all_options;
static int save_and_exit;
static int silent;
static int jump_key_char;
static void conf(struct menu *menu, struct menu *active_menu);
@ -378,58 +378,6 @@ static void show_help(struct menu *menu)
str_free(&help);
}
struct search_data {
struct list_head *head;
struct menu *target;
};
static int next_jump_key(int key)
{
if (key < '1' || key > '9')
return '1';
key++;
if (key > '9')
key = '1';
return key;
}
static int handle_search_keys(int key, size_t start, size_t end, void *_data)
{
struct search_data *data = _data;
struct jump_key *pos;
int index = 0;
if (key < '1' || key > '9')
return 0;
list_for_each_entry(pos, data->head, entries) {
index = next_jump_key(index);
if (pos->offset < start)
continue;
if (pos->offset >= end)
break;
if (key == index) {
data->target = pos->target;
return 1;
}
}
return 0;
}
int get_jump_key_char(void)
{
jump_key_char = next_jump_key(jump_key_char);
return jump_key_char;
}
static void search_conf(void)
{
struct symbol **sym_arr;

View File

@ -673,19 +673,6 @@ struct menu *menu_get_parent_menu(struct menu *menu)
return menu;
}
bool menu_has_help(struct menu *menu)
{
return menu->help != NULL;
}
const char *menu_get_help(struct menu *menu)
{
if (menu->help)
return menu->help;
else
return "";
}
static void get_def_str(struct gstr *r, struct menu *menu)
{
str_printf(r, "Defined at %s:%d\n",
@ -856,10 +843,10 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
struct symbol *sym = menu->sym;
const char *help_text = nohelp_text;
if (menu_has_help(menu)) {
if (menu->help) {
if (sym->name)
str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
help_text = menu_get_help(menu);
help_text = menu->help;
}
str_printf(help, "%s\n", help_text);
if (sym)

View File

@ -0,0 +1,53 @@
// SPDX-License-Identifier: GPL-2.0-only
#include "expr.h"
#include "list.h"
#include "mnconf-common.h"
int jump_key_char;
int next_jump_key(int key)
{
if (key < '1' || key > '9')
return '1';
key++;
if (key > '9')
key = '1';
return key;
}
int handle_search_keys(int key, size_t start, size_t end, void *_data)
{
struct search_data *data = _data;
struct jump_key *pos;
int index = 0;
if (key < '1' || key > '9')
return 0;
list_for_each_entry(pos, data->head, entries) {
index = next_jump_key(index);
if (pos->offset < start)
continue;
if (pos->offset >= end)
break;
if (key == index) {
data->target = pos->target;
return 1;
}
}
return 0;
}
int get_jump_key_char(void)
{
jump_key_char = next_jump_key(jump_key_char);
return jump_key_char;
}

View File

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef MNCONF_COMMON_H
#define MNCONF_COMMON_H
#include <stddef.h>
struct search_data {
struct list_head *head;
struct menu *target;
};
extern int jump_key_char;
int next_jump_key(int key);
int handle_search_keys(int key, size_t start, size_t end, void *_data);
int get_jump_key_char(void);
#endif /* MNCONF_COMMON_H */

View File

@ -12,6 +12,7 @@
#include <stdlib.h>
#include "lkc.h"
#include "mnconf-common.h"
#include "nconf.h"
#include <ctype.h>
@ -216,7 +217,7 @@ search_help[] =
"Symbol: FOO [ = m]\n"
"Prompt: Foo bus is used to drive the bar HW\n"
"Defined at drivers/pci/Kconfig:47\n"
"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
"Depends on: X86_LOCAL_APIC && X86_IO_APIC\n"
"Location:\n"
" -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
" -> PCI support (PCI [ = y])\n"
@ -279,7 +280,6 @@ static const char *current_instructions = menu_instructions;
static char *dialog_input_result;
static int dialog_input_result_len;
static int jump_key_char;
static void selected_conf(struct menu *menu, struct menu *active_menu);
static void conf(struct menu *menu);
@ -691,57 +691,6 @@ static int do_exit(void)
return 0;
}
struct search_data {
struct list_head *head;
struct menu *target;
};
static int next_jump_key(int key)
{
if (key < '1' || key > '9')
return '1';
key++;
if (key > '9')
key = '1';
return key;
}
static int handle_search_keys(int key, size_t start, size_t end, void *_data)
{
struct search_data *data = _data;
struct jump_key *pos;
int index = 0;
if (key < '1' || key > '9')
return 0;
list_for_each_entry(pos, data->head, entries) {
index = next_jump_key(index);
if (pos->offset < start)
continue;
if (pos->offset >= end)
break;
if (key == index) {
data->target = pos->target;
return 1;
}
}
return 0;
}
int get_jump_key_char(void)
{
jump_key_char = next_jump_key(jump_key_char);
return jump_key_char;
}
static void search_conf(void)
{

View File

@ -29,14 +29,9 @@ struct symbol symbol_no = {
.flags = SYMBOL_CONST|SYMBOL_VALID,
};
static struct symbol symbol_empty = {
.name = "",
.curr = { "", no },
.flags = SYMBOL_VALID,
};
struct symbol *modules_sym;
static tristate modules_val;
static int sym_warnings;
enum symbol_type sym_get_type(struct symbol *sym)
{
@ -317,6 +312,14 @@ static void sym_warn_unmet_dep(struct symbol *sym)
" Selected by [m]:\n");
fputs(str_get(&gs), stderr);
sym_warnings++;
}
bool sym_dep_errors(void)
{
if (sym_warnings)
return getenv("KCONFIG_WERROR");
return false;
}
void sym_calc_value(struct symbol *sym)
@ -344,9 +347,13 @@ void sym_calc_value(struct symbol *sym)
switch (sym->type) {
case S_INT:
newval.val = "0";
break;
case S_HEX:
newval.val = "0x0";
break;
case S_STRING:
newval = symbol_empty.curr;
newval.val = "";
break;
case S_BOOLEAN:
case S_TRISTATE:
@ -697,13 +704,12 @@ const char *sym_get_string_default(struct symbol *sym)
{
struct property *prop;
struct symbol *ds;
const char *str;
const char *str = "";
tristate val;
sym_calc_visibility(sym);
sym_calc_value(modules_sym);
val = symbol_no.curr.tri;
str = symbol_empty.curr.val;
/* If symbol has a default value look it up */
prop = sym_get_default_prop(sym);
@ -753,14 +759,17 @@ const char *sym_get_string_default(struct symbol *sym)
case yes: return "y";
}
case S_INT:
if (!str[0])
str = "0";
break;
case S_HEX:
return str;
case S_STRING:
return str;
case S_UNKNOWN:
if (!str[0])
str = "0x0";
break;
default:
break;
}
return "";
return str;
}
const char *sym_get_string_value(struct symbol *sym)

View File

@ -42,8 +42,7 @@ struct gstr str_new(void)
/* Free storage for growable string */
void str_free(struct gstr *gs)
{
if (gs->s)
free(gs->s);
free(gs->s);
gs->s = NULL;
gs->len = 0;
}

View File

@ -60,8 +60,7 @@ static unsigned int nr_unresolved;
#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
void __attribute__((format(printf, 2, 3)))
modpost_log(enum loglevel loglevel, const char *fmt, ...)
void modpost_log(enum loglevel loglevel, const char *fmt, ...)
{
va_list arglist;
@ -91,6 +90,9 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...)
error_occurred = true;
}
void __attribute__((alias("modpost_log")))
modpost_log_noret(enum loglevel loglevel, const char *fmt, ...);
static inline bool strends(const char *str, const char *postfix)
{
if (strlen(str) < strlen(postfix))
@ -474,11 +476,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
fatal("%s: not relocatable object.", filename);
/* Check if file offset is correct */
if (hdr->e_shoff > info->size) {
if (hdr->e_shoff > info->size)
fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
(unsigned long)hdr->e_shoff, filename, info->size);
return 0;
}
if (hdr->e_shnum == SHN_UNDEF) {
/*
@ -516,12 +516,11 @@ static int parse_elf(struct elf_info *info, const char *filename)
const char *secname;
int nobits = sechdrs[i].sh_type == SHT_NOBITS;
if (!nobits && sechdrs[i].sh_offset > info->size) {
if (!nobits && sechdrs[i].sh_offset > info->size)
fatal("%s is truncated. sechdrs[i].sh_offset=%lu > sizeof(*hrd)=%zu\n",
filename, (unsigned long)sechdrs[i].sh_offset,
sizeof(*hdr));
return 0;
}
secname = secstrings + sechdrs[i].sh_name;
if (strcmp(secname, ".modinfo") == 0) {
if (nobits)
@ -1419,7 +1418,7 @@ static void section_rel(struct module *mod, struct elf_info *elf,
for (rel = start; rel < stop; rel++) {
Elf_Sym *tsym;
Elf_Addr taddr = 0, r_offset;
Elf_Addr taddr, r_offset;
unsigned int r_type, r_sym;
void *loc;

View File

@ -197,7 +197,11 @@ enum loglevel {
LOG_FATAL
};
void modpost_log(enum loglevel loglevel, const char *fmt, ...);
void __attribute__((format(printf, 2, 3)))
modpost_log(enum loglevel loglevel, const char *fmt, ...);
void __attribute__((format(printf, 2, 3), noreturn))
modpost_log_noret(enum loglevel loglevel, const char *fmt, ...);
/*
* warn - show the given message, then let modpost continue running, still
@ -214,4 +218,4 @@ void modpost_log(enum loglevel loglevel, const char *fmt, ...);
*/
#define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args)
#define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args)
#define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args)
#define fatal(fmt, args...) modpost_log_noret(LOG_FATAL, fmt, ##args)

View File

@ -25,35 +25,20 @@ if_enabled_echo() {
}
create_package() {
local pname="$1" pdir="$2"
local dpkg_deb_opts
export DH_OPTIONS="-p${1}"
mkdir -m 755 -p "$pdir/DEBIAN"
mkdir -p "$pdir/usr/share/doc/$pname"
cp debian/copyright "$pdir/usr/share/doc/$pname/"
cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian"
gzip -n -9 "$pdir/usr/share/doc/$pname/changelog.Debian"
sh -c "cd '$pdir'; find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
| xargs -r0 md5sum > DEBIAN/md5sums"
# Fix ownership and permissions
if [ "$DEB_RULES_REQUIRES_ROOT" = "no" ]; then
dpkg_deb_opts="--root-owner-group"
else
chown -R root:root "$pdir"
fi
# a+rX in case we are in a restrictive umask environment like 0077
# ug-s in case we build in a setuid/setgid directory
chmod -R go-w,a+rX,ug-s "$pdir"
# Create the package
dpkg-gencontrol -p$pname -P"$pdir"
dpkg-deb $dpkg_deb_opts ${KDEB_COMPRESS:+-Z$KDEB_COMPRESS} --build "$pdir" ..
dh_installdocs
dh_installchangelogs
dh_compress
dh_fixperms
dh_gencontrol
dh_md5sums
dh_builddeb -- ${KDEB_COMPRESS:+-Z$KDEB_COMPRESS}
}
install_linux_image () {
pdir=$1
pname=$2
pname=$1
pdir=debian/$1
rm -rf ${pdir}
@ -62,7 +47,7 @@ install_linux_image () {
${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/usr/lib/linux-image-${KERNELRELEASE}" dtbs_install
fi
${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" modules_install
${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${pdir}" INSTALL_MOD_STRIP=1 modules_install
rm -f "${pdir}/lib/modules/${KERNELRELEASE}/build"
# Install the kernel
@ -122,26 +107,22 @@ install_linux_image () {
}
install_linux_image_dbg () {
pdir=$1
image_pdir=$2
pdir=debian/$1
rm -rf ${pdir}
for module in $(find ${image_pdir}/lib/modules/ -name *.ko -printf '%P\n'); do
module=lib/modules/${module}
mkdir -p $(dirname ${pdir}/usr/lib/debug/${module})
# only keep debug symbols in the debug file
${OBJCOPY} --only-keep-debug ${image_pdir}/${module} ${pdir}/usr/lib/debug/${module}
# strip original module from debug symbols
${OBJCOPY} --strip-debug ${image_pdir}/${module}
# then add a link to those
${OBJCOPY} --add-gnu-debuglink=${pdir}/usr/lib/debug/${module} ${image_pdir}/${module}
done
# 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"
# re-sign stripped modules
if is_enabled CONFIG_MODULE_SIG_ALL; then
${MAKE} -f ${srctree}/Makefile INSTALL_MOD_PATH="${image_pdir}" modules_sign
fi
mkdir -p "${dbg%/*}" "${link%/*}"
"${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}"
ln -sf --relative "${dbg}" "${link}"
done < modules.order
# Build debug package
# Different tools want the image in different locations
@ -156,8 +137,8 @@ install_linux_image_dbg () {
}
install_kernel_headers () {
pdir=$1
version=$2
pdir=debian/$1
version=${1#linux-headers-}
rm -rf $pdir
@ -168,18 +149,16 @@ install_kernel_headers () {
}
install_libc_headers () {
pdir=$1
pdir=debian/$1
rm -rf $pdir
$MAKE -f $srctree/Makefile headers
$MAKE -f $srctree/Makefile headers_install INSTALL_HDR_PATH=$pdir/usr
# move asm headers to /usr/include/<libc-machine>/asm to match the structure
# used by Debian-based distros (to support multi-arch)
host_arch=$(dpkg-architecture -a$DEB_HOST_ARCH -qDEB_HOST_MULTIARCH)
mkdir $pdir/usr/include/$host_arch
mv $pdir/usr/include/asm $pdir/usr/include/$host_arch/
mkdir "$pdir/usr/include/${DEB_HOST_MULTIARCH}"
mv "$pdir/usr/include/asm" "$pdir/usr/include/${DEB_HOST_MULTIARCH}"
}
rm -f debian/files
@ -190,30 +169,13 @@ for package in ${packages_enabled}
do
case ${package} in
*-dbg)
# This must be done after linux-image, that is, we expect the
# debug package appears after linux-image in debian/control.
install_linux_image_dbg debian/linux-image-dbg debian/linux-image;;
install_linux_image_dbg "${package}";;
linux-image-*|user-mode-linux-*)
install_linux_image debian/linux-image ${package};;
install_linux_image "${package}";;
linux-libc-dev)
install_libc_headers debian/linux-libc-dev;;
install_libc_headers "${package}";;
linux-headers-*)
install_kernel_headers debian/linux-headers ${package#linux-headers-};;
install_kernel_headers "${package}";;
esac
create_package "${package}"
done
for package in ${packages_enabled}
do
case ${package} in
*-dbg)
create_package ${package} debian/linux-image-dbg;;
linux-image-*|user-mode-linux-*)
create_package ${package} debian/linux-image;;
linux-libc-dev)
create_package ${package} debian/linux-libc-dev;;
linux-headers-*)
create_package ${package} debian/linux-headers;;
esac
done
exit 0

View File

@ -23,7 +23,6 @@ tmpdir=$1
#
rm -rf -- "${tmpdir}"
mkdir -p -- "${tmpdir}/boot"
dirs=boot
#
@ -38,12 +37,9 @@ fi
#
# Try to install modules
# Install modules
#
if grep -q '^CONFIG_MODULES=y' include/config/auto.conf; then
make ARCH="${ARCH}" -f ${srctree}/Makefile INSTALL_MOD_PATH="${tmpdir}" modules_install
dirs="$dirs lib"
fi
make ARCH="${ARCH}" -f ${srctree}/Makefile INSTALL_MOD_PATH="${tmpdir}" modules_install
#

View File

@ -1,14 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
# Set up CROSS_COMPILE if not defined yet
if [ "${CROSS_COMPILE+set}" != "set" -a "${DEB_HOST_ARCH}" != "${DEB_BUILD_ARCH}" ]; then
echo CROSS_COMPILE=${DEB_HOST_GNU_TYPE}-
fi
version=$(dpkg-parsechangelog -S Version)
debian_revision="${version##*-}"
if [ "${version}" != "${debian_revision}" ]; then
echo KBUILD_BUILD_VERSION=${debian_revision}
fi

View File

@ -0,0 +1,16 @@
This is a packaged upstream version of the Linux kernel.
The sources may be found at most Linux archive sites, including:
https://www.kernel.org/pub/linux/kernel
Copyright: 1991 - 2023 Linus Torvalds and others.
The git repository for mainline kernel development is at:
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991.
On Debian GNU/Linux systems, the complete text of the GNU General Public
License version 2 can be found in `/usr/share/common-licenses/GPL-2'.

View File

@ -1,33 +1,46 @@
#!/usr/bin/make -f
# SPDX-License-Identifier: GPL-2.0-only
include debian/rules.vars
# in case debian/rules is executed directly
export DEB_RULES_REQUIRES_ROOT := no
srctree ?= .
include debian/rules.vars
ifneq (,$(filter-out parallel=1,$(filter parallel=%,$(DEB_BUILD_OPTIONS))))
NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
MAKEFLAGS += -j$(NUMJOBS)
endif
revision = $(lastword $(subst -, ,$(shell dpkg-parsechangelog -S Version)))
CROSS_COMPILE ?= $(filter-out $(DEB_BUILD_GNU_TYPE)-, $(DEB_HOST_GNU_TYPE)-)
make-opts = ARCH=$(ARCH) KERNELRELEASE=$(KERNELRELEASE) KBUILD_BUILD_VERSION=$(revision) $(addprefix CROSS_COMPILE=,$(CROSS_COMPILE))
.PHONY: binary binary-indep binary-arch
binary: binary-arch binary-indep
binary-indep: build-indep
binary-arch: build-arch
$(MAKE) -f $(srctree)/Makefile ARCH=$(ARCH) \
KERNELRELEASE=$(KERNELRELEASE) \
run-command KBUILD_RUN_COMMAND=+$(srctree)/scripts/package/builddeb
$(MAKE) $(make-opts) \
run-command KBUILD_RUN_COMMAND='+$$(srctree)/scripts/package/builddeb'
.PHONY: build build-indep build-arch
build: build-arch build-indep
build-indep:
build-arch:
$(MAKE) -f $(srctree)/Makefile ARCH=$(ARCH) \
KERNELRELEASE=$(KERNELRELEASE) \
$(shell $(srctree)/scripts/package/deb-build-option) \
olddefconfig all
$(MAKE) $(make-opts) olddefconfig
$(MAKE) $(make-opts) $(if $(filter um,$(ARCH)),,headers) all
.PHONY: clean
clean:
rm -rf debian/files debian/linux-*
$(MAKE) -f $(srctree)/Makefile ARCH=$(ARCH) clean
rm -rf debian/files debian/linux-* debian/deb-env.vars*
$(MAKE) ARCH=$(ARCH) clean
# If DEB_HOST_ARCH is empty, it is likely that debian/rules was executed
# directly. Run 'dpkg-architecture --print-set --print-format=make' to
# generate a makefile construct that exports all DEB_* variables.
ifndef DEB_HOST_ARCH
include debian/deb-env.vars
debian/deb-env.vars:
dpkg-architecture -a$$(cat debian/arch) --print-set --print-format=make > $@.tmp
mv $@.tmp $@
endif

View File

@ -20,7 +20,7 @@ mkdir -p "${destdir}"
find "arch/${SRCARCH}" -maxdepth 1 -name 'Makefile*'
find include scripts -type f -o -type l
find "arch/${SRCARCH}" -name Kbuild.platforms -o -name Platform
find "arch/${SRCARCH}" -name include -o -name scripts -type d
find "arch/${SRCARCH}" -name include -type d
) | tar -c -f - -C "${srctree}" -T - | tar -xf - -C "${destdir}"
{

View File

@ -56,13 +56,7 @@ patch -p1 < %{SOURCE2}
%install
mkdir -p %{buildroot}/boot
%ifarch ia64
mkdir -p %{buildroot}/boot/efi
cp $(%{make} %{makeflags} -s image_name) %{buildroot}/boot/efi/vmlinuz-%{KERNELRELEASE}
ln -s efi/vmlinuz-%{KERNELRELEASE} %{buildroot}/boot/
%else
cp $(%{make} %{makeflags} -s image_name) %{buildroot}/boot/vmlinuz-%{KERNELRELEASE}
%endif
%{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} modules_install
%{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
cp System.map %{buildroot}/boot/System.map-%{KERNELRELEASE}

View File

@ -26,7 +26,7 @@ set_debarch() {
# Attempt to find the correct Debian architecture
case "$UTS_MACHINE" in
i386|ia64|alpha|m68k|riscv*)
i386|alpha|m68k|riscv*)
debarch="$UTS_MACHINE" ;;
x86_64)
debarch=amd64 ;;
@ -176,8 +176,6 @@ else
fi
echo $debarch > debian/arch
extra_build_depends=", $(if_enabled_echo CONFIG_UNWINDER_ORC libelf-dev:native)"
extra_build_depends="$extra_build_depends, $(if_enabled_echo CONFIG_SYSTEM_TRUSTED_KEYRING libssl-dev:native)"
# Generate a simple changelog template
cat <<EOF > debian/changelog
@ -188,26 +186,6 @@ $sourcename ($packageversion) $distribution; urgency=low
-- $maintainer $(date -R)
EOF
# Generate copyright file
cat <<EOF > debian/copyright
This is a packaged upstream version of the Linux kernel.
The sources may be found at most Linux archive sites, including:
https://www.kernel.org/pub/linux/kernel
Copyright: 1991 - 2018 Linus Torvalds and others.
The git repository for mainline kernel development is at:
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991.
On Debian GNU/Linux systems, the complete text of the GNU General Public
License version 2 can be found in \`/usr/share/common-licenses/GPL-2'.
EOF
# Generate a control file
cat <<EOF > debian/control
Source: $sourcename
@ -215,7 +193,8 @@ Section: kernel
Priority: optional
Maintainer: $maintainer
Rules-Requires-Root: no
Build-Depends: bc, debhelper, rsync, kmod, cpio, bison, flex $extra_build_depends
Build-Depends: debhelper-compat (= 12)
Build-Depends-Arch: bc, bison, cpio, flex, kmod, libelf-dev:native, libssl-dev:native, rsync
Homepage: https://www.kernel.org/
Package: $packagename-$version
@ -268,6 +247,7 @@ ARCH := ${ARCH}
KERNELRELEASE := ${KERNELRELEASE}
EOF
cp "${srctree}/scripts/package/debian/copyright" debian/
cp "${srctree}/scripts/package/debian/rules" debian/
exit 0

View File

@ -10,5 +10,5 @@ parts:
kernel:
plugin: kernel
source: SRCTREE
source-type: tar
source-type: local
kernel-with-firmware: false

View File

@ -590,7 +590,6 @@ static int do_file(char const *const fname)
ideal_nop = ideal_nop4_arm64;
is_fake_mcount64 = arm64_is_fake_mcount;
break;
case EM_IA_64: reltype = R_IA64_IMM64; break;
case EM_MIPS: /* reltype: e_class */ break;
case EM_LOONGARCH: /* reltype: e_class */ break;
case EM_PPC: reltype = R_PPC_ADDR32; break;

View File

@ -275,13 +275,6 @@ if ($arch eq "x86_64") {
$section_type = '%progbits';
$mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_AARCH64_CALL26\\s+_mcount\$";
$type = ".quad";
} elsif ($arch eq "ia64") {
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
$type = "data8";
if ($is_module eq "0") {
$cc .= " -mconstant-gp";
}
} elsif ($arch eq "sparc64") {
# In the objdump output there are giblets like:
# 0000000000000000 <igmp_net_exit-0x18>:

View File

@ -15,7 +15,6 @@ LZMA2OPTS=
case $SRCARCH in
x86) BCJ=--x86 ;;
powerpc) BCJ=--powerpc ;;
ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;;
arm) BCJ=--arm ;;
sparc) BCJ=--sparc ;;
esac

View File

@ -27,6 +27,7 @@
static unsigned int offset;
static unsigned int ino = 721;
static time_t default_mtime;
static bool do_file_mtime;
static bool do_csum = false;
struct file_handler {
@ -329,6 +330,7 @@ static int cpio_mkfile(const char *name, const char *location,
int file;
int retval;
int rc = -1;
time_t mtime;
int namesize;
unsigned int i;
uint32_t csum = 0;
@ -347,16 +349,21 @@ static int cpio_mkfile(const char *name, const char *location,
goto error;
}
if (buf.st_mtime > 0xffffffff) {
fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n",
location);
buf.st_mtime = 0xffffffff;
}
if (do_file_mtime) {
mtime = default_mtime;
} else {
mtime = buf.st_mtime;
if (mtime > 0xffffffff) {
fprintf(stderr, "%s: Timestamp exceeds maximum cpio timestamp, clipping.\n",
location);
mtime = 0xffffffff;
}
if (buf.st_mtime < 0) {
fprintf(stderr, "%s: Timestamp negative, clipping.\n",
location);
buf.st_mtime = 0;
if (mtime < 0) {
fprintf(stderr, "%s: Timestamp negative, clipping.\n",
location);
mtime = 0;
}
}
if (buf.st_size > 0xffffffff) {
@ -387,7 +394,7 @@ static int cpio_mkfile(const char *name, const char *location,
(long) uid, /* uid */
(long) gid, /* gid */
nlinks, /* nlink */
(long) buf.st_mtime, /* mtime */
(long) mtime, /* mtime */
size, /* filesize */
3, /* major */
1, /* minor */
@ -536,8 +543,9 @@ static void usage(const char *prog)
"file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n"
"\n"
"<timestamp> is time in seconds since Epoch that will be used\n"
"as mtime for symlinks, special files and directories. The default\n"
"is to use the current time for these entries.\n"
"as mtime for symlinks, directories, regular and special files.\n"
"The default is to use the current time for all files, but\n"
"preserve modification time for regular files.\n"
"-c: calculate and store 32-bit checksums for file data.\n",
prog);
}
@ -594,6 +602,7 @@ int main (int argc, char *argv[])
usage(argv[0]);
exit(1);
}
do_file_mtime = true;
break;
case 'c':
do_csum = true;