Home / Alt manpages / llvm-ifs-20(1)

  • llvm-ifs-20(1)
  • User command
  • linux

Generate and Check ELF ABI Stubs with llvm-ifs-20

You will finish with a text-based IFS description of a shared library and, when needed, a linkable ELF stub generated from it. The IFS file is useful in ABI review because it records the target, needed libraries and exported symbols in a form that can be diffed.

Allow about fifteen minutes. You need the llvm-20 package, a readable ELF shared object and a writable working directory. The examples use the installed llvm-ifs-20 20.1.8 package. They do not need sudo; use elevated privileges only to read a library that your account cannot access, or to write into a protected build directory.

1. Confirm the installed interface

Start with read-only checks. This catches a common source of confusion: the installed binary's help is newer and more detailed than the local manpage's synopsis.

$ command -v llvm-ifs-20
/usr/bin/llvm-ifs-20
$ llvm-ifs-20 --version
Ubuntu LLVM version 20.1.8
  Optimized build.
$ dpkg-query -W -f='${Package} ${Version}\n' llvm-20
llvm-20 1:20.1.8~++20250804090239+87f0227cb601-1~exp1~20250804210352.139

The practical command shape on this installation is one input path followed by an output option. For an IFS file use --output-ifs=PATH; for a binary stub use --output-elf=PATH. Do not put an output path in the positional arguments. Although the help text displays llvm-ifs-20 <input_file> <output_file>, doing that makes the second path another input and can produce a misleading parse error.

Checkpoint

If the version or option names differ, stop and read that binary's --help before copying the commands below.

2. Choose an input without changing it

Pick the actual shared object, not a generated output file. This example follows the system's zlib symlink so the command reads the ELF file directly:

$ realpath /usr/lib/x86_64-linux-gnu/libz.so.1
/usr/lib/x86_64-linux-gnu/libz.so.1.3
$ test -r /usr/lib/x86_64-linux-gnu/libz.so.1.3 && echo readable
readable

Replace the path with your library. Do not guess its architecture from the filename. If you are preparing a release artefact, record the library's build and package version alongside the generated IFS so a later diff has context.

3. Write an IFS ABI description

Create a temporary output directory and generate the text representation. The explicit input format makes the operation predictable and avoids relying on format inference:

$ mkdir -p build/abi
$ llvm-ifs-20 /usr/lib/x86_64-linux-gnu/libz.so.1.3 \
    --input-format=ELF \
    --output-ifs=build/abi/libz.ifs
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ sed -n '1,12p' build/abi/libz.ifs
--- !ifs-v1
IfsVersion:      3.0
SoName:          libz.so.1
Target:          { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
NeededLibs:
  - libc.so.6
Symbols:
  - { Name: ZLIB_1.2.0, Type: Object, Size: 0 }

On this build the field is spelled IfsVersion and the target member is BitWidth. The installed manpage example uses IFSVersion and Bitwidth, which the 20.1.8 binary does not accept when reading an IFS file. Treat the generated file as the machine-readable contract rather than hand-correcting its spelling.

The symbols are sorted, so a normal diff is useful:

$ file build/abi/libz.ifs
build/abi/libz.ifs: ASCII text
$ diff -u previous/libz.ifs build/abi/libz.ifs

No diff is not proof that an ABI is safe in every context, but a changed symbol, size, target or needed library deserves review before you skip a relink.

4. Generate a linkable ELF stub

If a build needs an ELF object rather than a review file, read the IFS and request an ELF output. This writes only the named destination:

$ llvm-ifs-20 build/abi/libz.ifs \
    --input-format=IFS \
    --output-elf=build/abi/libz.stub.so
$ file build/abi/libz.stub.so
build/abi/libz.stub.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), no program header, stripped
$ readelf -h build/abi/libz.stub.so | sed -n '1,14p'
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64

This is a linker-facing stub, not a replacement runtime library. It has no program headers in this tested output, and ordinary ELF analysis tools may not understand every such stub. Keep the real shared object for execution and package testing. Use the stub to avoid an unnecessary relink when the recorded ABI remains unchanged.

Safety boundary

Do not install the stub over a system library or put it ahead of the real library in a production runtime search path. That can break programs. Keep it in a build-specific directory and pass it only to the link step that expects an ABI stub.

5. Keep repeatable generation quiet

For generated files, --write-if-changed preserves the existing output when the new content is identical. This helps build systems avoid needless downstream work:

$ llvm-ifs-20 /usr/lib/x86_64-linux-gnu/libz.so.1.3 \
    --input-format=ELF \
    --output-ifs=build/abi/libz.ifs \
    --write-if-changed
$ sha256sum build/abi/libz.ifs
2b9f...  build/abi/libz.ifs

The hash is an example shape, not a value to copy. Calculate it on your own output. If an earlier file was produced from a different library or target, do not let this option hide that mistake: compare the input path, target and IFS content first.

6. Diagnose failures before retrying

A missing or unreadable input should return a non-zero status:

$ llvm-ifs-20 /path/to/missing.so --input-format=ELF --output-ifs=build/abi/missing.ifs
error: Could not open `/path/to/missing.so`
$ printf 'exit status: %s\n' "$?"
exit status: 1

Check the path and permissions without changing anything:

$ ls -l /path/to/library.so
$ test -r /path/to/library.so && echo readable

If an IFS read fails, inspect its first lines and compare the keys with a file generated by this same binary. In particular, use IfsVersion, BitWidth and a valid target. Do not "fix" a conflict by adding both spellings. If the target in the file conflicts with --arch, --endianness, --bitwidth or --target, remove the conflicting override or regenerate the IFS for the intended target.

The local 20.1.8 binary can crash when an ELF input and an output path are both supplied positionally. It can also crash while reading malformed IFS data. Use one positional input and an explicit output option as shown above, and keep malformed or untrusted IFS files out of automated jobs. If a correctly shaped command still crashes, save the exact command, version and input details and report it to the LLVM project rather than treating the output as valid.

Done means

  • llvm-ifs-20 --version and the package version are recorded.
  • The input is a readable ELF shared object and remains untouched.
  • An IFS file was generated with one positional input and --output-ifs.
  • The IFS target and symbols were inspected or diffed before use.
  • Any ELF stub was written to a build directory and checked with file or readelf.
  • No stub replaced a runtime library or changed a service.