ABIDW(1)

πŸ¦‹ NAME πŸ¦‹

hiii bestie, welcome to ABIDW(1) β€” straight out of the Libabigail fam, and honestly she's iconic πŸ’…

abidw β€” serialize the ABI of an ELF file

okay so abidw reads a shared library in ELF format and emits an XML representation of its ABI to standard output. no cap, that's the whole vibe. the emitted representation format is named ABIXML, and it includes all the globally defined functions and variables, along with a complete representation of their types. it also includes a representation of the globally defined ELF symbols of the file ✨

and when you hand her the --linux-tree option? she can also handle a Linux kernel tree. yep β€” a directory tree that contains both the vmlinux binary and Linux Kernel modules. she analyses those Linux Kernel binaries and emits an XML representation of the interface between the kernel and its module, to standard output. in this case we don't call it an ABI, we call it a KMI (Kernel Module Interface). the emitted KMI includes all the globally defined functions and variables, along with a complete representation of their types 🫢

to generate either ABI or KMI representation, by default abidw uses debug information in the DWARF format, if present, otherwise it looks for debug information in CTF or BTF formats, if present. and finally, if no debug info in these formats is found, it only considers ELF symbols and reports about their addition or removal. that's the fallback era, periodt πŸ’€

this tool uses the libabigail library to analyze the binary as well as its associated debug information. here's her general mode of operation, bestie πŸ‘‘

when instructed to do so, a binary and its associated debug information is read and analyzed. to that effect, libabigail analyzes by default the descriptions of the types reachable by the interfaces (functions and variables) that are visible outside of their translation unit. once that analysis is done, an Application Binary Interface Corpus is constructed by only considering the subset of types reachable from interfaces associated to ELF symbols that are defined and exported by the binary. it's that final ABI corpus which libabigail considers as representing the ABI of the analyzed binary. main character energy tbh 🌟

libabigail then has capabilities to generate textual representations of ABI Corpora, compare them, analyze their changes and report about them. she contains multitudes πŸ’œ


🌈 ENVIRONMENT 🌈

  • Parallel processing

the environment variable ABIGAIL_THREAD_POOL_SIZE can be set to either an integer, or a percentage value, e.g, 10%. the integer value defines the number of threads used by Libabigail to perform parallel processing when applicable. the percentage defines the percentage of the total available cores to use by Libabigail to perform the parallel processing when applicable 🧚

by default, Libabigail uses all the available cores to perform its parallel processing. she's greedy like that, and honestly? respect πŸ’…


πŸŽ€ INVOCATION πŸŽ€

   abidw [options] [<path-to-elf-file>]

✨ OPTIONS ✨

  • --abidiff β€” load the ABI of the ELF binary given in argument, save it in libabigail's XML format in a temporary file; read the ABI from the temporary XML file and compare the ABI that has been read back against the ABI of the ELF binary given in argument. the ABIs should compare equal. if they don't, the program emits a diagnostic and exits with a non-zero code 😭

this is a debugging and sanity check option 🩺

  • --abixml-version β€” display the version of the ABIXML format emitted by this program and exit. short and sweet, we love a queen who knows when to leave 🌸
  • --add-binaries <bin1,bin2,…> β€” for each of the comma-separated binaries given in argument to this option, if the binary is found in the directory specified by the –added-binaries-dir option, then load the ABI corpus of the binary and add it to a set of ABI corpora (called a ABI Corpus Group) made of the binary denoted by the Argument of abidw. that corpus group is then serialized out πŸ¦‹
  • --added-binaries-dir | --abd <dir-path> β€” this option is to be used in conjunction with the --add-binaries, the --follow-dependencies or the --list-dependencies option. binaries listed as arguments of the --add-binaries option or being dependencies of the input binary in the case of the --follow-dependencies option and found in the directory <dir-path> are going to be loaded as ABI corpus and added to the set of ABI corpora (called an ABI corpus group) built and serialized. it's giving ✨friend group✨ honestly 🫢
  • --allow-non-exported-interfaces β€” when looking at the debug information accompanying a binary, this tool analyzes the descriptions of the types reachable by the interfaces (functions and variables) that are visible outside of their translation unit. once that analysis is done, an ABI corpus is constructed by only considering the subset of types reachable from interfaces associated to ELF symbols that are defined and exported by the binary. it's that final ABI corpus which textual representation is saved as ABIXML πŸ“

the problem with that approach however is that analyzing all the interfaces that are visible from outside their translation unit can amount to a lot of data, especially when those binaries are applications, as opposed to shared libraries. one example of such applications is the Linux Kernel. analyzing massive ABI corpora like these can be extremely slow 😴

in the presence of an "average sized" binary however one can afford having libabigail analyze all interfaces that are visible outside of their translation unit, using this option πŸ’–

note that this option is turned on by default, unless we are in the presence of the Linux Kernel πŸ‘€
  • --annotate β€” annotate the ABIXML output with comments above most elements. the comments are made of the pretty-printed form types, declaration or even ELF symbols. the purpose is to make the ABIXML output more human-readable for debugging or documenting purposes. it's the difference between a cryptic wall of text and a cryptic wall of text with ✨notes✨ πŸŽ€
  • --btf β€” extract ABI information from BTF debug information, if present in the given object 🧚
  • --check-alternate-debug-info <elf-path> β€” if the debug info for the file elf-path contains a reference to an alternate debug info file, abidw checks that it can find that alternate debug info file. in that case, it emits a meaningful success message mentioning the full path to the alternate debug info file found. otherwise, it emits an error code πŸ’€
  • --check-alternate-debug-info-base-name <elf-path> β€” like --check-alternate-debug-info, but in the success message, only mention the base name of the debug info file; not its full path. she's keeping it lowkey 🌸
  • --debug-abidiff β€” same as --abidiff but in debug mode. in this mode, error messages are emitted for types which fail type canonicalization πŸ”

this is an optional debugging and sanity check option. to enable it the libabigail package needs to be configured with the –enable-debug-self-comparison option. so like, it's not just gonna work out of the box, bestie 🫠

  • --ctf β€” extract ABI information from CTF debug information, if present in the given object πŸ¦‹
  • --debug-info-dir | -d <dir-path> β€” in cases where the debug info for path-to-elf-file is in a separate file that is located in a non-standard place, this tells abidw where to look for that debug info file πŸ‘‘

note that dir-path must point to the root directory under which the debug information is arranged in a tree-like manner. under Red Hat based systems, that directory is usually <root>/usr/lib/debug πŸ“

this option can be provided several times with different root directories. in that case, abidw will potentially look into all those root directories to find the split debug info for the elf file. she's thorough, we stan πŸ”₯

note that this option is not mandatory for split debug information installed by your system's package manager because then abidw knows where to find it. she already has the map, iykyk πŸ—ΊοΈ

  • --debug-type-canonicalization | --debug-tc β€” debug the type canonicalization process. this is done by using structural and canonical equality when canonicalizing every single type. structural and canonical equality should yield the same result. if they don't yield the same result for a given type, then it means that the canonicalization of that type went wrong. in that case, an error message is emitted and the execution of the program is aborted 😭
this option is available only if the package was configured with the –enable-debug-type-canonicalization option 🧚
  • --drop-private-types β€” this option is implicitly set by option –headers-dir and –header-file options πŸ™ˆ

with this option, types that are NOT defined in the headers are entirely dropped from the internal representation build by Libabigail to represent the ABI and will not end up in the abi XML file πŸ’…

this option is provided or compatibility reasons only and should not be explicitly used anymore. so like, legacy behavior, we don't touch her ⭐
  • --drop-undefined-syms β€” with this option functions or variables for which the (exported) ELF symbol is undefined are dropped from the internal representation build by Libabigail to represent the ABI and will not end up in the abi XML file 🫢
  • --emit-member-hashes β€” emit hashes for data members and virtual member functions in the ABIXML file πŸ”’
  • --emit-native-offsets β€” emit the offsets of the debug information entries which ABI artifacts originate from. this is useful for debug purposes πŸ”
  • --exported-interfaces-only β€” by default, when looking at the debug information accompanying a binary, this tool analyzes the descriptions of the types reachable by the interfaces (functions and variables) that are visible outside of their translation unit. once that analysis is done, an ABI corpus is constructed by only considering the subset of types reachable from interfaces associated to ELF symbols that are defined and exported by the binary. it's that final ABI corpus which textual representation is saved as ABIXML πŸ“

the problem with that approach however is that analyzing all the interfaces that are visible from outside their translation unit can amount to a lot of data, especially when those binaries are applications, as opposed to shared libraries. one example of such applications is the Linux Kernel. analyzing massive ABI corpora like these can be extremely slow 😴

to mitigate that performance issue, this option allows libabigail to only analyze types that are reachable from interfaces associated with defined and exported ELF symbols πŸš€

ok tiny footnote before we keep going, bestie 🫢 β€” that last option? it's on by default when you're analyzing the Linux Kernel. Everywhere else it's off by default. iykyk.
  • --fail-no-debug-info β€” if the program can't find debug info for the input binary, it straight up dips with a non-zero error code. no debug info, no vibes. without this option it just emits the ABI info about ELF symbols instead β€” but heads up, in that case type information is omitted. πŸ’€
  • --follow-dependencies β€” for each dependency of the input binary of abidw, if it's found in the directory you gave to --added-binaries-dir, then it builds an ABI corpus out of that dependency and adds it to a set of ABI corpora β€” that set is called an ABI Corpus Group β€” right alongside the ABI corpus of the input binary. Then the whole ABI Corpus Group gets serialized out. it's giving family reunion ✨
  • --force-early-suppression β€” must be used alongside --suppression. it forces suppression specs to be applied in early suppression mode, meaning artifacts of the internal representation that match suppression specs get suppressed from memory. if you don't use this option, only suppression specs with the drop property set to 'yes' actually do anything β€” every other suppression specification directive just sits there looking ignored. πŸ™ˆ
  • --headers-dir | --hd <headers-directory-path-1> β€” tells the tool where to find the public headers of the binary it has to consider, so it can filter out types that aren't defined in public headers. this option implicitly sets --drop-private-types. πŸ’…

and yes, you can give it several public header directories β€” just repeat the --header-dir option on the command line, like this:

$ abidw --header-dir /some/path       \
        --header-dir /some/other/path \
        binary > binary.abi
  • --header-file | --hf <header-file-path> β€” points at one of the public headers of the abi file that the tool has to consider, so it filters out types not defined in public headers. this one also implicitly sets --drop-private-types. πŸŽ€
  • --help | -h β€” short help about the command, then exit. the classic "wait what does this do again" save πŸ’–
  • --kmi-whitelist | --kmi-stablelist | -w <path-to-stablelist> β€” when you're analyzing a Linux Kernel binary, this points to the list of names of ELF symbols of functions and variables whose ABI must be written out. any function or variable whose name isn't in that list will not ignored β€” yeah, that's the original wording, blame the manpage author not me 😭 β€” the list is called a "Kernel Module Interface stable list". why KMI and not KABI? because for the Kernel we don't talk about the ABI, we talk about the interface between the Kernel and its module. hence KMI, periodt. πŸ‘‘

any other function or variable whose ELF symbol isn't in that stable list just won't be considered by the KMI writing process.

and if you don't provide this option β€” so, no stable list at all β€” then the entire KMI gets emitted: all publicly defined and exported functions and global variables by the Linux Kernel binaries. the whole thing. no filter. 🌈

  • --list-dependencies β€” for each dependency of the input binary of abidw, if it's found in the directory specified by the --added-binaries-dir option, the name of that dependency gets printed out. just the names. lil roll call πŸ¦‹
  • --load-all-types β€” by default, libabigail (and therefore abidw) only loads types that are reachable from function and variable declarations that are publicly defined and exported by the binary. so only those types show up in the output. this option makes abidw load all the types defined in the binaries β€” even the ones that aren't reachable from public declarations. deep dive mode πŸ”₯
  • --linux-tree | --lt β€” makes abidw treat the input path as a path to a directory containing the vmlinux binary as well as several kernel modules binaries. in that case, the program emits the representation of the Kernel Module Interface (KMI) on standard output. 🌸

here's an example of using abidw on a Linux Kernel tree. first, check out a Linux Kernel source tree and build it. then install the kernel modules somewhere in a directory. copy the vmlinux binary into that directory too. then serialize the KMI of that kernel to disk with abidw:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux && git checkout v4.5
$ make allyesconfig all
$ mkdir build-output
$ make INSTALL_MOD_PATH=./build-output modules_install
$ cp vmlinux build-output/modules/4.5.0
$ abidw --linux-tree build-output/modules/4.5.0 > build-output/linux-4.5.0.kmi
  • --no-assume-odr-for-cplusplus β€” when analyzing a binary coming from C++ code using DWARF debug info, libabigail assumes the One Definition Rule to speed things up. basically, when several types share the same name in the binary, they're assumed to all be equal. this option disables that assumption and tells libabigail to actually actually compare the types to determine if they're equal. yes, "actually actually" β€” it's in the source, it's iconic, we keep it πŸ’…
  • --no-corpus-path β€” do not emit the path attribute for the ABI corpus. simple as that πŸŽ€
  • --no-elf-needed β€” do not include the list of DT_NEEDED dependency names in the corpus.
  • --no-leverage-dwarf-factorization β€” when analyzing a binary whose DWARF debug info was processed with the DWZ tool, the type information is supposed to already be factorized. libabigail uses that context to do some speed optimizations. this option disables those optimizations. it's giving "you're not wrong, but no" 😌
  • --no-load-undefined-interfaces β€” by default, libabigail (and therefore abidw) loads info about undefined function and variable symbols, plus the functions and variables associated with those undefined symbols. those are called undefined interfaces. this option makes makes abidw skip loading info about undefined interfaces, so the resulting XML file won't contain info about them. (the double "makes makes" is canon, don't @ me πŸ’€)
  • --no-linux-kernel-mode β€” without this option, if abipkgiff detects that the binaries it's looking at are Linux Kernel binaries (either vmlinux or modules), it only considers functions and variables whose ELF symbols are listed in the __ksymtab and __ksymtab_gpl sections. with this option, abipkgdiff treats the binary as a non-special ELF binary, so it considers functions and variables that are defined and exported in the ELF sense. 🧚
  • --noout β€” tells abidw to not emit the XML representation of the ABI. so it just reads the ELF and debug information, builds the internal representation of the ABI, and exits. usually useful for debugging purposes. all vibes, zero output 🫢
  • --no-parameter-names β€” in the emitted ABI representation, don't show names of function parameters, just the types. minimalism ✨
  • --no-show-locs β€” in the emitted ABI representation, do not show the file, line, or column where ABI artifacts are defined. location privacy era πŸ™ˆ
  • --no-write-default-sizes β€” in the XML ABI representation, don't write the size-in-bits for pointer type definitions, reference type definitions, function declarations, and function types when they equal the default address size of the translation unit. ⚠️ heads up though: libabigail before 1.8 will not set the default size and will interpret types without a size-in-bits attribute as zero sized. so like, be careful mixing versions, bestie 😭
  • --nullout β€” emit the ABIXML output to /dev/null. yeet it into the void πŸ•³οΈ
  • --out-file | -o <file-path> β€” tells abidw to emit the XML representation of path-to-elf-file into the file file-path, instead of dumping it to standard output. πŸ“
  • --parameter-names β€” emit function parameter names in the ABIXML output. names are back, baby 🌟
  • --show-locs β€” show location information of ABI artifacts in the ABIXML output. where everything lives πŸ“
  • --stats β€” emit statistics about various internal things. numbers!! we love numbers πŸ“Š
  • --suppressions | suppr <path-to-suppression-specifications-file> β€” use a suppression specification file located at path-to-suppression-specifications-file. this option can totally appear multiple times on the command line, and if it does, all the provided suppression specification files get taken into account. ABI artifacts matched by the suppression specs get suppressed from the output of this tool. πŸŽ€
only suppression specifications that have the drop property set to 'yes' are going to be effective. every other suppression specification directive just looks ignored β€” unless you pass --force-early-suppression on the command line.
  • --type-id-style <sequence|hash> β€” controls how types are identified in the generated XML files. the default sequence style just numbers the types in the order they're encountered, with type-id- as the prefix. the hash style uses a (stable, portable) hash of libabigail's internal type names, and it's meant to make the XML files easier to diff. πŸ’…
  • --thread-pool-size <N|N%> | -j <N|N%> β€” sets the size of the thread pool libabigail uses for parallel processing. the size is either the number of threads or a percentage of the total number of available cores on the machine. by default, all available cores on the machine get used. ⚑
fyi the environment variable ABIGAIL_THREAD_POOL_SIZE can be set to similar values too. but this command line option, if present, supersedes the value of the environment variable. option wins, always πŸ‘‘
  • --verbose β€” emit verbose logs about the progress of miscellaneous internal things. it's giving commentary track πŸ“
  • --version | -v β€” display the version of the program and exit. πŸ’–

🌸 USAGE EXAMPLES 🌸

okay bestie, here's where it gets fun. real commands, real output, let's go πŸ’…

  1. emitting an ABIXML representation of a binary β€” the classic, the icon, the one you'll use like 90% of the time:
$ abidw binary > binary.abi

literally just point it at a binary and yeet the XML into a file. slay ✨

  1. emitting an ABIXML representation of a set of binaries specified on the command line β€” when one binary isn't enough and you need the whole squad:
$ abidw --added-binaries=bin1,bin2,bin3  \
        --added-binaries-dir /some/where \
        binary > binaries.abi

so here's the tea πŸ«–: the binaries bin1, bin2 and bin3 are to be found in the directory /some/where. a representation of the ABI of the set of binaries binary, bin1, bin2 and bin3 β€” called an ABI corpus group β€” is serialized in the file binaries.abi. it's giving group project but everyone actually showed up πŸ’–

  1. emitting an ABIXML representation of a binary and its dependencies β€” the full lore drop, main character binary plus its entire entourage:
$ abidw --follow-dependencies              \
        --added-binaries-dir /some/where   \
        binary > binary.abi

note β€” and this is important, no cap β€” that only the dependencies that are found in the directory /some/where are analysed. their ABIs, along with the ABI the binary named binary are represented as an ABI corpus group and serialized in the file binary.abi, in the ABIXML format. iconic behavior tbh πŸ‘‘


πŸ¦‹ NOTES πŸ¦‹

alternate debug info files

so as of the version 4 of the DWARF specification, Alternate debug information is a GNU extension to the DWARF specification. it has however been proposed for inclusion into the upcoming version 5 of the DWARF standard. you can read more about the GNU extensions to the DWARF standard here. 🧚✨

like… it's a whole GNU-exclusive moment, but the DWARF girlies are lowkey trying to make it official in v5. watch this space, iykyk πŸ‘€


πŸ‘‘ AUTHOR πŸ‘‘

Dodji Seketeli β€” the goat, fr fr πŸ™Œ

2014-2026, Red Hat, Inc.


okay that's the whole page bestie, you made it to the end!! πŸŽ€ this one's abidw, as documented on Oct 08, 2026 β€” huge shoutout to Red Hat, Inc. for the copyright from 2014 all the way through 2026, and to the manpage source for stamping that date on it. go forth and dump some ABIs, you absolute legend πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from