|
| 1 | +======================= |
| 2 | +DWARF module versioning |
| 3 | +======================= |
| 4 | + |
| 5 | +1. Introduction |
| 6 | +=============== |
| 7 | + |
| 8 | +When CONFIG_MODVERSIONS is enabled, symbol versions for modules |
| 9 | +are typically calculated from preprocessed source code using the |
| 10 | +**genksyms** tool. However, this is incompatible with languages such |
| 11 | +as Rust, where the source code has insufficient information about |
| 12 | +the resulting ABI. With CONFIG_GENDWARFKSYMS (and CONFIG_DEBUG_INFO) |
| 13 | +selected, **gendwarfksyms** is used instead to calculate symbol versions |
| 14 | +from the DWARF debugging information, which contains the necessary |
| 15 | +details about the final module ABI. |
| 16 | + |
| 17 | +1.1. Usage |
| 18 | +========== |
| 19 | + |
| 20 | +gendwarfksyms accepts a list of object files on the command line, and a |
| 21 | +list of symbol names (one per line) in standard input:: |
| 22 | + |
| 23 | + Usage: gendwarfksyms [options] elf-object-file ... < symbol-list |
| 24 | + |
| 25 | + Options: |
| 26 | + -d, --debug Print debugging information |
| 27 | + --dump-dies Dump DWARF DIE contents |
| 28 | + --dump-die-map Print debugging information about die_map changes |
| 29 | + --dump-types Dump type strings |
| 30 | + --dump-versions Dump expanded type strings used for symbol versions |
| 31 | + -s, --stable Support kABI stability features |
| 32 | + -T, --symtypes file Write a symtypes file |
| 33 | + -h, --help Print this message |
| 34 | + |
| 35 | + |
| 36 | +2. Type information availability |
| 37 | +================================ |
| 38 | + |
| 39 | +While symbols are typically exported in the same translation unit (TU) |
| 40 | +where they're defined, it's also perfectly fine for a TU to export |
| 41 | +external symbols. For example, this is done when calculating symbol |
| 42 | +versions for exports in stand-alone assembly code. |
| 43 | + |
| 44 | +To ensure the compiler emits the necessary DWARF type information in the |
| 45 | +TU where symbols are actually exported, gendwarfksyms adds a pointer |
| 46 | +to exported symbols in the `EXPORT_SYMBOL()` macro using the following |
| 47 | +macro:: |
| 48 | + |
| 49 | + #define __GENDWARFKSYMS_EXPORT(sym) \ |
| 50 | + static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ |
| 51 | + __section(".discard.gendwarfksyms") = &sym; |
| 52 | + |
| 53 | + |
| 54 | +When a symbol pointer is found in DWARF, gendwarfksyms can use its |
| 55 | +type for calculating symbol versions even if the symbol is defined |
| 56 | +elsewhere. The name of the symbol pointer is expected to start with |
| 57 | +`__gendwarfksyms_ptr_`, followed by the name of the exported symbol. |
| 58 | + |
| 59 | +3. Symtypes output format |
| 60 | +========================= |
| 61 | + |
| 62 | +Similarly to genksyms, gendwarfksyms supports writing a symtypes |
| 63 | +file for each processed object that contain types for exported |
| 64 | +symbols and each referenced type that was used in calculating symbol |
| 65 | +versions. These files can be useful when trying to determine what |
| 66 | +exactly caused symbol versions to change between builds. To generate |
| 67 | +symtypes files during a kernel build, set `KBUILD_SYMTYPES=1`. |
| 68 | + |
| 69 | +Matching the existing format, the first column of each line contains |
| 70 | +either a type reference or a symbol name. Type references have a |
| 71 | +one-letter prefix followed by "#" and the name of the type. Four |
| 72 | +reference types are supported:: |
| 73 | + |
| 74 | + e#<type> = enum |
| 75 | + s#<type> = struct |
| 76 | + t#<type> = typedef |
| 77 | + u#<type> = union |
| 78 | + |
| 79 | +Type names with spaces in them are wrapped in single quotes, e.g.:: |
| 80 | + |
| 81 | + s#'core::result::Result<u8, core::num::error::ParseIntError>' |
| 82 | + |
| 83 | +The rest of the line contains a type string. Unlike with genksyms that |
| 84 | +produces C-style type strings, gendwarfksyms uses the same simple parsed |
| 85 | +DWARF format produced by **--dump-dies**, but with type references |
| 86 | +instead of fully expanded strings. |
| 87 | + |
| 88 | +4. Maintaining a stable kABI |
| 89 | +============================ |
| 90 | + |
| 91 | +Distribution maintainers often need the ability to make ABI compatible |
| 92 | +changes to kernel data structures due to LTS updates or backports. Using |
| 93 | +the traditional `#ifndef __GENKSYMS__` to hide these changes from symbol |
| 94 | +versioning won't work when processing object files. To support this |
| 95 | +use case, gendwarfksyms provides kABI stability features designed to |
| 96 | +hide changes that won't affect the ABI when calculating versions. These |
| 97 | +features are all gated behind the **--stable** command line flag and are |
| 98 | +not used in the mainline kernel. To use stable features during a kernel |
| 99 | +build, set `KBUILD_GENDWARFKSYMS_STABLE=1`. |
| 100 | + |
| 101 | +Examples for using these features are provided in the |
| 102 | +**scripts/gendwarfksyms/examples** directory, including helper macros |
| 103 | +for source code annotation. Note that as these features are only used to |
| 104 | +transform the inputs for symbol versioning, the user is responsible for |
| 105 | +ensuring that their changes actually won't break the ABI. |
| 106 | + |
| 107 | +4.1. kABI rules |
| 108 | +=============== |
| 109 | + |
| 110 | +kABI rules allow distributions to fine-tune certain parts |
| 111 | +of gendwarfksyms output and thus control how symbol |
| 112 | +versions are calculated. These rules are defined in the |
| 113 | +`.discard.gendwarfksyms.kabi_rules` section of the object file and |
| 114 | +consist of simple null-terminated strings with the following structure:: |
| 115 | + |
| 116 | + version\0type\0target\0value\0 |
| 117 | + |
| 118 | +This string sequence is repeated as many times as needed to express all |
| 119 | +the rules. The fields are as follows: |
| 120 | + |
| 121 | +- `version`: Ensures backward compatibility for future changes to the |
| 122 | + structure. Currently expected to be "1". |
| 123 | +- `type`: Indicates the type of rule being applied. |
| 124 | +- `target`: Specifies the target of the rule, typically the fully |
| 125 | + qualified name of the DWARF Debugging Information Entry (DIE). |
| 126 | +- `value`: Provides rule-specific data. |
| 127 | + |
| 128 | +The following helper macro, for example, can be used to specify rules |
| 129 | +in the source code:: |
| 130 | + |
| 131 | + #define __KABI_RULE(hint, target, value) \ |
| 132 | + static const char __PASTE(__gendwarfksyms_rule_, \ |
| 133 | + __COUNTER__)[] __used __aligned(1) \ |
| 134 | + __section(".discard.gendwarfksyms.kabi_rules") = \ |
| 135 | + "1\0" #hint "\0" #target "\0" #value |
| 136 | + |
| 137 | + |
| 138 | +Currently, only the rules discussed in this section are supported, but |
| 139 | +the format is extensible enough to allow further rules to be added as |
| 140 | +need arises. |
| 141 | + |
| 142 | +4.1.1. Managing definition visibility |
| 143 | +===================================== |
| 144 | + |
| 145 | +A declaration can change into a full definition when additional includes |
| 146 | +are pulled into the translation unit. This changes the versions of any |
| 147 | +symbol that references the type even if the ABI remains unchanged. As |
| 148 | +it may not be possible to drop includes without breaking the build, the |
| 149 | +`declonly` rule can be used to specify a type as declaration-only, even |
| 150 | +if the debugging information contains the full definition. |
| 151 | + |
| 152 | +The rule fields are expected to be as follows: |
| 153 | + |
| 154 | +- `type`: "declonly" |
| 155 | +- `target`: The fully qualified name of the target data structure |
| 156 | + (as shown in **--dump-dies** output). |
| 157 | +- `value`: This field is ignored. |
| 158 | + |
| 159 | +Using the `__KABI_RULE` macro, this rule can be defined as:: |
| 160 | + |
| 161 | + #define KABI_DECLONLY(fqn) __KABI_RULE(declonly, fqn, ) |
| 162 | + |
| 163 | +Example usage:: |
| 164 | + |
| 165 | + struct s { |
| 166 | + /* definition */ |
| 167 | + }; |
| 168 | + |
| 169 | + KABI_DECLONLY(s); |
| 170 | + |
| 171 | +4.1.2. Adding enumerators |
| 172 | +========================= |
| 173 | + |
| 174 | +For enums, all enumerators and their values are included in calculating |
| 175 | +symbol versions, which becomes a problem if we later need to add more |
| 176 | +enumerators without changing symbol versions. The `enumerator_ignore` |
| 177 | +rule allows us to hide named enumerators from the input. |
| 178 | + |
| 179 | +The rule fields are expected to be as follows: |
| 180 | + |
| 181 | +- `type`: "enumerator_ignore" |
| 182 | +- `target`: The fully qualified name of the target enum |
| 183 | + (as shown in **--dump-dies** output) and the name of the |
| 184 | + enumerator field separated by a space. |
| 185 | +- `value`: This field is ignored. |
| 186 | + |
| 187 | +Using the `__KABI_RULE` macro, this rule can be defined as:: |
| 188 | + |
| 189 | + #define KABI_ENUMERATOR_IGNORE(fqn, field) \ |
| 190 | + __KABI_RULE(enumerator_ignore, fqn field, ) |
| 191 | + |
| 192 | +Example usage:: |
| 193 | + |
| 194 | + enum e { |
| 195 | + A, B, C, D, |
| 196 | + }; |
| 197 | + |
| 198 | + KABI_ENUMERATOR_IGNORE(e, B); |
| 199 | + KABI_ENUMERATOR_IGNORE(e, C); |
| 200 | + |
| 201 | +If the enum additionally includes an end marker and new values must |
| 202 | +be added in the middle, we may need to use the old value for the last |
| 203 | +enumerator when calculating versions. The `enumerator_value` rule allows |
| 204 | +us to override the value of an enumerator for version calculation: |
| 205 | + |
| 206 | +- `type`: "enumerator_value" |
| 207 | +- `target`: The fully qualified name of the target enum |
| 208 | + (as shown in **--dump-dies** output) and the name of the |
| 209 | + enumerator field separated by a space. |
| 210 | +- `value`: Integer value used for the field. |
| 211 | + |
| 212 | +Using the `__KABI_RULE` macro, this rule can be defined as:: |
| 213 | + |
| 214 | + #define KABI_ENUMERATOR_VALUE(fqn, field, value) \ |
| 215 | + __KABI_RULE(enumerator_value, fqn field, value) |
| 216 | + |
| 217 | +Example usage:: |
| 218 | + |
| 219 | + enum e { |
| 220 | + A, B, C, LAST, |
| 221 | + }; |
| 222 | + |
| 223 | + KABI_ENUMERATOR_IGNORE(e, C); |
| 224 | + KABI_ENUMERATOR_VALUE(e, LAST, 2); |
| 225 | + |
| 226 | +4.3. Adding structure members |
| 227 | +============================= |
| 228 | + |
| 229 | +Perhaps the most common ABI compatible change is adding a member to a |
| 230 | +kernel data structure. When changes to a structure are anticipated, |
| 231 | +distribution maintainers can pre-emptively reserve space in the |
| 232 | +structure and take it into use later without breaking the ABI. If |
| 233 | +changes are needed to data structures without reserved space, existing |
| 234 | +alignment holes can potentially be used instead. While kABI rules could |
| 235 | +be added for these type of changes, using unions is typically a more |
| 236 | +natural method. This section describes gendwarfksyms support for using |
| 237 | +reserved space in data structures and hiding members that don't change |
| 238 | +the ABI when calculating symbol versions. |
| 239 | + |
| 240 | +4.3.1. Reserving space and replacing members |
| 241 | +============================================ |
| 242 | + |
| 243 | +Space is typically reserved for later use by appending integer types, or |
| 244 | +arrays, to the end of the data structure, but any type can be used. Each |
| 245 | +reserved member needs a unique name, but as the actual purpose is usually |
| 246 | +not known at the time the space is reserved, for convenience, names that |
| 247 | +start with `__kabi_` are left out when calculating symbol versions:: |
| 248 | + |
| 249 | + struct s { |
| 250 | + long a; |
| 251 | + long __kabi_reserved_0; /* reserved for future use */ |
| 252 | + }; |
| 253 | + |
| 254 | +The reserved space can be taken into use by wrapping the member in a |
| 255 | +union, which includes the original type and the replacement member:: |
| 256 | + |
| 257 | + struct s { |
| 258 | + long a; |
| 259 | + union { |
| 260 | + long __kabi_reserved_0; /* original type */ |
| 261 | + struct b b; /* replaced field */ |
| 262 | + }; |
| 263 | + }; |
| 264 | + |
| 265 | +If the `__kabi_` naming scheme was used when reserving space, the name |
| 266 | +of the first member of the union must start with `__kabi_reserved`. This |
| 267 | +ensures the original type is used when calculating versions, but the name |
| 268 | +is again left out. The rest of the union is ignored. |
| 269 | + |
| 270 | +If we're replacing a member that doesn't follow this naming convention, |
| 271 | +we also need to preserve the original name to avoid changing versions, |
| 272 | +which we can do by changing the first union member's name to start with |
| 273 | +`__kabi_renamed` followed by the original name. |
| 274 | + |
| 275 | +The examples include `KABI_(RESERVE|USE|REPLACE)*` macros that help |
| 276 | +simplify the process and also ensure the replacement member is correctly |
| 277 | +aligned and its size won't exceed the reserved space. |
| 278 | + |
| 279 | +4.3.2. Hiding members |
| 280 | +===================== |
| 281 | + |
| 282 | +Predicting which structures will require changes during the support |
| 283 | +timeframe isn't always possible, in which case one might have to resort |
| 284 | +to placing new members into existing alignment holes:: |
| 285 | + |
| 286 | + struct s { |
| 287 | + int a; |
| 288 | + /* a 4-byte alignment hole */ |
| 289 | + unsigned long b; |
| 290 | + }; |
| 291 | + |
| 292 | + |
| 293 | +While this won't change the size of the data structure, one needs to |
| 294 | +be able to hide the added members from symbol versioning. Similarly |
| 295 | +to reserved fields, this can be accomplished by wrapping the added |
| 296 | +member to a union where one of the fields has a name starting with |
| 297 | +`__kabi_ignored`:: |
| 298 | + |
| 299 | + struct s { |
| 300 | + int a; |
| 301 | + union { |
| 302 | + char __kabi_ignored_0; |
| 303 | + int n; |
| 304 | + }; |
| 305 | + unsigned long b; |
| 306 | + }; |
| 307 | + |
| 308 | +With **--stable**, both versions produce the same symbol version. |
0 commit comments