Skip to content

Commit

Permalink
Merge tag 'kbuild-v6.14' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/masahiroy/linux-kbuild

Pull Kbuild updates from Masahiro Yamada:

 - Support multiple hook locations for maint scripts of Debian package

 - Remove 'cpio' from the build tool requirement

 - Introduce gendwarfksyms tool, which computes CRCs for export symbols
   based on the DWARF information

 - Support CONFIG_MODVERSIONS for Rust

 - Resolve all conflicts in the genksyms parser

 - Fix several syntax errors in genksyms

* tag 'kbuild-v6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (64 commits)
  kbuild: fix Clang LTO with CONFIG_OBJTOOL=n
  kbuild: Strip runtime const RELA sections correctly
  kconfig: fix memory leak in sym_warn_unmet_dep()
  kconfig: fix file name in warnings when loading KCONFIG_DEFCONFIG_LIST
  genksyms: fix syntax error for attribute before init-declarator
  genksyms: fix syntax error for builtin (u)int*x*_t types
  genksyms: fix syntax error for attribute after 'union'
  genksyms: fix syntax error for attribute after 'struct'
  genksyms: fix syntax error for attribute after abstact_declarator
  genksyms: fix syntax error for attribute before nested_declarator
  genksyms: fix syntax error for attribute before abstract_declarator
  genksyms: decouple ATTRIBUTE_PHRASE from type-qualifier
  genksyms: record attributes consistently for init-declarator
  genksyms: restrict direct-declarator to take one parameter-type-list
  genksyms: restrict direct-abstract-declarator to take one parameter-type-list
  genksyms: remove Makefile hack
  genksyms: fix last 3 shift/reduce conflicts
  genksyms: fix 6 shift/reduce conflicts and 5 reduce/reduce conflicts
  genksyms: reduce type_qualifier directly to decl_specifier
  genksyms: rename cvar_qualifier to type_qualifier
  ...
  • Loading branch information
torvalds committed Jan 31, 2025
2 parents 9755ffd + 695ed93 commit fd8c09a
Show file tree
Hide file tree
Showing 68 changed files with 4,491 additions and 306 deletions.
308 changes: 308 additions & 0 deletions Documentation/kbuild/gendwarfksyms.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
=======================
DWARF module versioning
=======================

1. Introduction
===============

When CONFIG_MODVERSIONS is enabled, symbol versions for modules
are typically calculated from preprocessed source code using the
**genksyms** tool. However, this is incompatible with languages such
as Rust, where the source code has insufficient information about
the resulting ABI. With CONFIG_GENDWARFKSYMS (and CONFIG_DEBUG_INFO)
selected, **gendwarfksyms** is used instead to calculate symbol versions
from the DWARF debugging information, which contains the necessary
details about the final module ABI.

1.1. Usage
==========

gendwarfksyms accepts a list of object files on the command line, and a
list of symbol names (one per line) in standard input::

Usage: gendwarfksyms [options] elf-object-file ... < symbol-list

Options:
-d, --debug Print debugging information
--dump-dies Dump DWARF DIE contents
--dump-die-map Print debugging information about die_map changes
--dump-types Dump type strings
--dump-versions Dump expanded type strings used for symbol versions
-s, --stable Support kABI stability features
-T, --symtypes file Write a symtypes file
-h, --help Print this message


2. Type information availability
================================

While symbols are typically exported in the same translation unit (TU)
where they're defined, it's also perfectly fine for a TU to export
external symbols. For example, this is done when calculating symbol
versions for exports in stand-alone assembly code.

To ensure the compiler emits the necessary DWARF type information in the
TU where symbols are actually exported, gendwarfksyms adds a pointer
to exported symbols in the `EXPORT_SYMBOL()` macro using the following
macro::

#define __GENDWARFKSYMS_EXPORT(sym) \
static typeof(sym) *__gendwarfksyms_ptr_##sym __used \
__section(".discard.gendwarfksyms") = &sym;


When a symbol pointer is found in DWARF, gendwarfksyms can use its
type for calculating symbol versions even if the symbol is defined
elsewhere. The name of the symbol pointer is expected to start with
`__gendwarfksyms_ptr_`, followed by the name of the exported symbol.

3. Symtypes output format
=========================

Similarly to genksyms, gendwarfksyms supports writing a symtypes
file for each processed object that contain types for exported
symbols and each referenced type that was used in calculating symbol
versions. These files can be useful when trying to determine what
exactly caused symbol versions to change between builds. To generate
symtypes files during a kernel build, set `KBUILD_SYMTYPES=1`.

Matching the existing format, the first column of each line contains
either a type reference or a symbol name. Type references have a
one-letter prefix followed by "#" and the name of the type. Four
reference types are supported::

e#<type> = enum
s#<type> = struct
t#<type> = typedef
u#<type> = union

Type names with spaces in them are wrapped in single quotes, e.g.::

s#'core::result::Result<u8, core::num::error::ParseIntError>'

The rest of the line contains a type string. Unlike with genksyms that
produces C-style type strings, gendwarfksyms uses the same simple parsed
DWARF format produced by **--dump-dies**, but with type references
instead of fully expanded strings.

4. Maintaining a stable kABI
============================

Distribution maintainers often need the ability to make ABI compatible
changes to kernel data structures due to LTS updates or backports. Using
the traditional `#ifndef __GENKSYMS__` to hide these changes from symbol
versioning won't work when processing object files. To support this
use case, gendwarfksyms provides kABI stability features designed to
hide changes that won't affect the ABI when calculating versions. These
features are all gated behind the **--stable** command line flag and are
not used in the mainline kernel. To use stable features during a kernel
build, set `KBUILD_GENDWARFKSYMS_STABLE=1`.

Examples for using these features are provided in the
**scripts/gendwarfksyms/examples** directory, including helper macros
for source code annotation. Note that as these features are only used to
transform the inputs for symbol versioning, the user is responsible for
ensuring that their changes actually won't break the ABI.

4.1. kABI rules
===============

kABI rules allow distributions to fine-tune certain parts
of gendwarfksyms output and thus control how symbol
versions are calculated. These rules are defined in the
`.discard.gendwarfksyms.kabi_rules` section of the object file and
consist of simple null-terminated strings with the following structure::

version\0type\0target\0value\0

This string sequence is repeated as many times as needed to express all
the rules. The fields are as follows:

- `version`: Ensures backward compatibility for future changes to the
structure. Currently expected to be "1".
- `type`: Indicates the type of rule being applied.
- `target`: Specifies the target of the rule, typically the fully
qualified name of the DWARF Debugging Information Entry (DIE).
- `value`: Provides rule-specific data.

The following helper macro, for example, can be used to specify rules
in the source code::

#define __KABI_RULE(hint, target, value) \
static const char __PASTE(__gendwarfksyms_rule_, \
__COUNTER__)[] __used __aligned(1) \
__section(".discard.gendwarfksyms.kabi_rules") = \
"1\0" #hint "\0" #target "\0" #value


Currently, only the rules discussed in this section are supported, but
the format is extensible enough to allow further rules to be added as
need arises.

4.1.1. Managing definition visibility
=====================================

A declaration can change into a full definition when additional includes
are pulled into the translation unit. This changes the versions of any
symbol that references the type even if the ABI remains unchanged. As
it may not be possible to drop includes without breaking the build, the
`declonly` rule can be used to specify a type as declaration-only, even
if the debugging information contains the full definition.

The rule fields are expected to be as follows:

- `type`: "declonly"
- `target`: The fully qualified name of the target data structure
(as shown in **--dump-dies** output).
- `value`: This field is ignored.

Using the `__KABI_RULE` macro, this rule can be defined as::

#define KABI_DECLONLY(fqn) __KABI_RULE(declonly, fqn, )

Example usage::

struct s {
/* definition */
};

KABI_DECLONLY(s);

4.1.2. Adding enumerators
=========================

For enums, all enumerators and their values are included in calculating
symbol versions, which becomes a problem if we later need to add more
enumerators without changing symbol versions. The `enumerator_ignore`
rule allows us to hide named enumerators from the input.

The rule fields are expected to be as follows:

- `type`: "enumerator_ignore"
- `target`: The fully qualified name of the target enum
(as shown in **--dump-dies** output) and the name of the
enumerator field separated by a space.
- `value`: This field is ignored.

Using the `__KABI_RULE` macro, this rule can be defined as::

#define KABI_ENUMERATOR_IGNORE(fqn, field) \
__KABI_RULE(enumerator_ignore, fqn field, )

Example usage::

enum e {
A, B, C, D,
};

KABI_ENUMERATOR_IGNORE(e, B);
KABI_ENUMERATOR_IGNORE(e, C);

If the enum additionally includes an end marker and new values must
be added in the middle, we may need to use the old value for the last
enumerator when calculating versions. The `enumerator_value` rule allows
us to override the value of an enumerator for version calculation:

- `type`: "enumerator_value"
- `target`: The fully qualified name of the target enum
(as shown in **--dump-dies** output) and the name of the
enumerator field separated by a space.
- `value`: Integer value used for the field.

Using the `__KABI_RULE` macro, this rule can be defined as::

#define KABI_ENUMERATOR_VALUE(fqn, field, value) \
__KABI_RULE(enumerator_value, fqn field, value)

Example usage::

enum e {
A, B, C, LAST,
};

KABI_ENUMERATOR_IGNORE(e, C);
KABI_ENUMERATOR_VALUE(e, LAST, 2);

4.3. Adding structure members
=============================

Perhaps the most common ABI compatible change is adding a member to a
kernel data structure. When changes to a structure are anticipated,
distribution maintainers can pre-emptively reserve space in the
structure and take it into use later without breaking the ABI. If
changes are needed to data structures without reserved space, existing
alignment holes can potentially be used instead. While kABI rules could
be added for these type of changes, using unions is typically a more
natural method. This section describes gendwarfksyms support for using
reserved space in data structures and hiding members that don't change
the ABI when calculating symbol versions.

4.3.1. Reserving space and replacing members
============================================

Space is typically reserved for later use by appending integer types, or
arrays, to the end of the data structure, but any type can be used. Each
reserved member needs a unique name, but as the actual purpose is usually
not known at the time the space is reserved, for convenience, names that
start with `__kabi_` are left out when calculating symbol versions::

struct s {
long a;
long __kabi_reserved_0; /* reserved for future use */
};

The reserved space can be taken into use by wrapping the member in a
union, which includes the original type and the replacement member::

struct s {
long a;
union {
long __kabi_reserved_0; /* original type */
struct b b; /* replaced field */
};
};

If the `__kabi_` naming scheme was used when reserving space, the name
of the first member of the union must start with `__kabi_reserved`. This
ensures the original type is used when calculating versions, but the name
is again left out. The rest of the union is ignored.

If we're replacing a member that doesn't follow this naming convention,
we also need to preserve the original name to avoid changing versions,
which we can do by changing the first union member's name to start with
`__kabi_renamed` followed by the original name.

The examples include `KABI_(RESERVE|USE|REPLACE)*` macros that help
simplify the process and also ensure the replacement member is correctly
aligned and its size won't exceed the reserved space.

4.3.2. Hiding members
=====================

Predicting which structures will require changes during the support
timeframe isn't always possible, in which case one might have to resort
to placing new members into existing alignment holes::

struct s {
int a;
/* a 4-byte alignment hole */
unsigned long b;
};


While this won't change the size of the data structure, one needs to
be able to hide the added members from symbol versioning. Similarly
to reserved fields, this can be accomplished by wrapping the added
member to a union where one of the fields has a name starting with
`__kabi_ignored`::

struct s {
int a;
union {
char __kabi_ignored_0;
int n;
};
unsigned long b;
};

With **--stable**, both versions produce the same symbol version.
1 change: 1 addition & 0 deletions Documentation/kbuild/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Kernel Build System
reproducible-builds
gcc-plugins
llvm
gendwarfksyms

.. only:: subproject and html

Expand Down
20 changes: 20 additions & 0 deletions Documentation/kbuild/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,26 @@ Symbols From the Kernel (vmlinux + modules)
1) It lists all exported symbols from vmlinux and all modules.
2) It lists the CRC if CONFIG_MODVERSIONS is enabled.

Version Information Formats
---------------------------

Exported symbols have information stored in __ksymtab or __ksymtab_gpl
sections. Symbol names and namespaces are stored in __ksymtab_strings,
using a format similar to the string table used for ELF. If
CONFIG_MODVERSIONS is enabled, the CRCs corresponding to exported
symbols will be added to the __kcrctab or __kcrctab_gpl.

If CONFIG_BASIC_MODVERSIONS is enabled (default with
CONFIG_MODVERSIONS), imported symbols will have their symbol name and
CRC stored in the __versions section of the importing module. This
mode only supports symbols of length up to 64 bytes.

If CONFIG_EXTENDED_MODVERSIONS is enabled (required to enable both
CONFIG_MODVERSIONS and CONFIG_RUST at the same time), imported symbols
will have their symbol name recorded in the __version_ext_names
section as a series of concatenated, null-terminated strings. CRCs for
these symbols will be recorded in the __version_ext_crcs section.

Symbols and External Modules
----------------------------

Expand Down
6 changes: 0 additions & 6 deletions Documentation/process/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ iptables 1.4.2 iptables -V
openssl & libcrypto 1.0.0 openssl version
bc 1.06.95 bc --version
Sphinx\ [#f1]_ 2.4.4 sphinx-build --version
cpio any cpio --version
GNU tar 1.28 tar --version
gtags (optional) 6.6.5 gtags --version
mkimage (optional) 2017.01 mkimage --version
Expand Down Expand Up @@ -536,11 +535,6 @@ mcelog

- <https://www.mcelog.org/>

cpio
----

- <https://www.gnu.org/software/cpio/>

Networking
**********

Expand Down
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -9641,6 +9641,13 @@ W: https://linuxtv.org
T: git git://linuxtv.org/media.git
F: drivers/media/radio/radio-gemtek*

GENDWARFKSYMS
M: Sami Tolvanen <[email protected]>
L: [email protected]
L: [email protected]
S: Maintained
F: scripts/gendwarfksyms/

GENERIC ARCHITECTURE TOPOLOGY
M: Sudeep Holla <[email protected]>
L: [email protected]
Expand Down
Loading

0 comments on commit fd8c09a

Please sign in to comment.