diff mbox series

[v6,18/18] Documentation/kbuild: Add DWARF module versioning

Message ID 20241121204220.2378181-38-samitolvanen@google.com (mailing list archive)
State New
Headers show
Series Implement DWARF modversions | expand

Commit Message

Sami Tolvanen Nov. 21, 2024, 8:42 p.m. UTC
Add documentation for gendwarfksyms changes, and the kABI stability
features that can be useful for distributions even though they're not
used in mainline kernels.

Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
---
 Documentation/kbuild/gendwarfksyms.rst | 308 +++++++++++++++++++++++++
 Documentation/kbuild/index.rst         |   1 +
 2 files changed, 309 insertions(+)
 create mode 100644 Documentation/kbuild/gendwarfksyms.rst

Comments

Masahiro Yamada Dec. 14, 2024, 11:33 a.m. UTC | #1
On Fri, Nov 22, 2024 at 5:43 AM Sami Tolvanen <samitolvanen@google.com> wrote:
>
> Add documentation for gendwarfksyms changes, and the kABI stability
> features that can be useful for distributions even though they're not
> used in mainline kernels.
>
> Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
> ---
>  Documentation/kbuild/gendwarfksyms.rst | 308 +++++++++++++++++++++++++
>  Documentation/kbuild/index.rst         |   1 +
>  2 files changed, 309 insertions(+)
>  create mode 100644 Documentation/kbuild/gendwarfksyms.rst
>
> diff --git a/Documentation/kbuild/gendwarfksyms.rst b/Documentation/kbuild/gendwarfksyms.rst
> new file mode 100644
> index 000000000000..7725d7f57131
> --- /dev/null
> +++ b/Documentation/kbuild/gendwarfksyms.rst
> @@ -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.

I am interested in this sentence.

__GENDWARFKSYMS_EXPORT() is primarily introduced to handle
EXPORT_SYMBOL() in *.S files.
In fact, .discard.gendwarfksyms is always output for EXPORT_SYMBOL()
from *.c files.

Can we make it faster by processing only symbol references in the
.dscard.gendwarfksyms section, and skipping all other sections entirely?




> +4.3. Adding structure members
> +=============================
> +
> +Perhaps the most common ABI compatible changeis adding a member to a

changeis -> change is







> +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.
> diff --git a/Documentation/kbuild/index.rst b/Documentation/kbuild/index.rst
> index cee2f99f734b..e82af05cd652 100644
> --- a/Documentation/kbuild/index.rst
> +++ b/Documentation/kbuild/index.rst
> @@ -21,6 +21,7 @@ Kernel Build System
>      reproducible-builds
>      gcc-plugins
>      llvm
> +    gendwarfksyms
>
>  .. only::  subproject and html
>
> --
> 2.47.0.371.ga323438b13-goog
>


--
Best Regards



Masahiro Yamada
Sedat Dilek Dec. 14, 2024, 1:04 p.m. UTC | #2
On Sat, Dec 14, 2024 at 12:34 PM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Fri, Nov 22, 2024 at 5:43 AM Sami Tolvanen <samitolvanen@google.com> wrote:
> >
> > Add documentation for gendwarfksyms changes, and the kABI stability
> > features that can be useful for distributions even though they're not
> > used in mainline kernels.
> >
> > Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
> > ---
> >  Documentation/kbuild/gendwarfksyms.rst | 308 +++++++++++++++++++++++++
> >  Documentation/kbuild/index.rst         |   1 +
> >  2 files changed, 309 insertions(+)
> >  create mode 100644 Documentation/kbuild/gendwarfksyms.rst
> >
> > diff --git a/Documentation/kbuild/gendwarfksyms.rst b/Documentation/kbuild/gendwarfksyms.rst
> > new file mode 100644
> > index 000000000000..7725d7f57131
> > --- /dev/null
> > +++ b/Documentation/kbuild/gendwarfksyms.rst
> > @@ -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.
>
> I am interested in this sentence.
>
> __GENDWARFKSYMS_EXPORT() is primarily introduced to handle
> EXPORT_SYMBOL() in *.S files.
> In fact, .discard.gendwarfksyms is always output for EXPORT_SYMBOL()
> from *.c files.
>
> Can we make it faster by processing only symbol references in the
> .dscard.gendwarfksyms section, and skipping all other sections entirely?
>

Hi Masahiro,

I am interested in everything making my build faster.

v6 introduced a longer build-time for me.
Sami wanted to check after his vacancies see [1].

Just for the records.

Best regards,
-Sedat-

[1] https://lore.kernel.org/all/CABCJKudwpKX1_j46Tp6=eAJ0JU2zWE15+c8OFq9LMAnSqwesOw@mail.gmail.com/

>
>
> > +4.3. Adding structure members
> > +=============================
> > +
> > +Perhaps the most common ABI compatible changeis adding a member to a
>
> changeis -> change is
>
>
>
>
>
>
>
> > +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.
> > diff --git a/Documentation/kbuild/index.rst b/Documentation/kbuild/index.rst
> > index cee2f99f734b..e82af05cd652 100644
> > --- a/Documentation/kbuild/index.rst
> > +++ b/Documentation/kbuild/index.rst
> > @@ -21,6 +21,7 @@ Kernel Build System
> >      reproducible-builds
> >      gcc-plugins
> >      llvm
> > +    gendwarfksyms
> >
> >  .. only::  subproject and html
> >
> > --
> > 2.47.0.371.ga323438b13-goog
> >
>
>
> --
> Best Regards
>
>
>
> Masahiro Yamada
Sami Tolvanen Dec. 17, 2024, 12:28 a.m. UTC | #3
Hi,

On Sat, Dec 14, 2024 at 3:34 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Fri, Nov 22, 2024 at 5:43 AM Sami Tolvanen <samitolvanen@google.com> wrote:
> >
> > +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.
>
> I am interested in this sentence.
>
> __GENDWARFKSYMS_EXPORT() is primarily introduced to handle
> EXPORT_SYMBOL() in *.S files.
> In fact, .discard.gendwarfksyms is always output for EXPORT_SYMBOL()
> from *.c files.
>
> Can we make it faster by processing only symbol references in the
> .dscard.gendwarfksyms section, and skipping all other sections entirely?

I don't think we can, because the DWARF type information is still all
in the same .debug_info section no matter where we place the actual
symbol references. Also, locating exported symbols from the debugging
information is already pretty quick, the slow part is actually
recursing through the types, which would still be the same amount of
work even if we had separate debugging information only for
.discard.gendwarfksyms.

> > +4.3. Adding structure members
> > +=============================
> > +
> > +Perhaps the most common ABI compatible changeis adding a member to a
>
> changeis -> change is

Thanks, I'll fix this.

Sami
diff mbox series

Patch

diff --git a/Documentation/kbuild/gendwarfksyms.rst b/Documentation/kbuild/gendwarfksyms.rst
new file mode 100644
index 000000000000..7725d7f57131
--- /dev/null
+++ b/Documentation/kbuild/gendwarfksyms.rst
@@ -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 changeis 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.
diff --git a/Documentation/kbuild/index.rst b/Documentation/kbuild/index.rst
index cee2f99f734b..e82af05cd652 100644
--- a/Documentation/kbuild/index.rst
+++ b/Documentation/kbuild/index.rst
@@ -21,6 +21,7 @@  Kernel Build System
     reproducible-builds
     gcc-plugins
     llvm
+    gendwarfksyms
 
 .. only::  subproject and html