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
+ 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
+ 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
Type information availability
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;
+ #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
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
+ 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>'
+ 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
The following helper macros, for example, can be used to specify rules
in the source code::
- #define ___KABI_RULE(hint, target, value) \
- static const char __PASTE(__gendwarfksyms_rule_, \
+ #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
Using the `__KABI_RULE` macro, this rule can be defined as::
- #define KABI_BYTE_SIZE(fqn, value) \
- __KABI_RULE(byte_size, fqn, value)
+ #define KABI_BYTE_SIZE(fqn, value) \
+ __KABI_RULE(byte_size, fqn, value)
Example usage::
struct s {
- /* Unchanged original members */
+ /* Unchanged original members */
unsigned long a;
- void *p;
+ void *p;
- /* Appended new members */
- KABI_IGNORE(0, unsigned long n);
+ /* Appended new members */
+ KABI_IGNORE(0, unsigned long n);
};
KABI_BYTE_SIZE(s, 16);
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 */
- };
+ 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 */
- };
- };
+ 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
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;
- };
+ 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
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;
- };
+ struct s {
+ int a;
+ union {
+ char __kabi_ignored_0;
+ int n;
+ };
+ unsigned long b;
+ };
With **--stable**, both versions produce the same symbol version. The
examples include a `KABI_IGNORE` macro to simplify the code.