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

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

Create and Check ELF Link Stubs with llvm-ifs-18

You will finish with two reproducible artefacts: a text-based IFS description of a shared object for ABI review, and a small ELF shared-object stub that a linker can use without carrying the library implementation. The examples use the installed llvm-ifs-18, LLVM 18.1.3 from package llvm-18.

Allow about fifteen minutes. You need a shell, the LLVM 18 package, a readable ELF shared object, and a directory where you can discard generated files. This workflow only reads the input and writes new output. It does not replace a library, alter the linker cache or require sudo.

1. Check the installed command

Start with version and help output. These are ordinary, read-only commands:

$ llvm-ifs-18 --version
Ubuntu LLVM version 18.1.3
  Optimized build.
$ dpkg-query -W -f='${Package} ${Version}\n' llvm-18
llvm-18 1:18.1.3-1ubuntu1

The manpage describes the tool as accepting ELF shared objects or IFS files and producing IFS, ELF or Apple TAPI output. The installed help also shows the current positional form, llvm-ifs-18 <input_file> <output_file>, plus explicit --input-format and output-path options. Prefer the explicit options in scripts because the input and output roles remain visible.

Checkpoint

If llvm-ifs-18 --version reports another release, keep that version in your notes. Option details and IFS fields can vary between LLVM releases.

2. Choose a safe input and workspace

Use a shared object that is readable and not being replaced by a package upgrade. This example uses zlib's system library and writes only below /tmp:

$ input=/usr/lib/x86_64-linux-gnu/libz.so.1
$ work=$(mktemp -d /tmp/llvm-ifs.XXXXXX)
$ test -r "$input" && printf 'input: %s\nworkspace: %s\n' "$input" "$work"
input: /usr/lib/x86_64-linux-gnu/libz.so.1
workspace: /tmp/llvm-ifs.example

The workspace name is generated by mktemp, so the displayed path is only an example. Do not point an output option at a production library or at a path used by a build concurrently. If the input is a private build artefact, check its architecture and ABI separately before comparing it with another file.

3. Export an IFS ABI snapshot

Generate a text IFS file from the ELF input. The command infers the ELF contents, but stating --input-format=ELF makes a failed assumption easier to diagnose:

$ llvm-ifs-18 --input-format=ELF \
    --output-ifs="$work/libz.ifs" \
    "$input"
$ sed -n '1,12p' "$work/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 }

IFS is YAML-based text. It records target information, needed libraries and sorted symbol records, including whether a symbol is undefined or weak where that information exists. That makes it suitable for a review or a diff in an ABI-checking job. A changed file is a signal to investigate, not automatic proof that a release is incompatible.

Checkpoint

Confirm that the file begins with --- !ifs-v1, has an IfsVersion, and names the expected shared object. If generation fails with an interface type mismatch, try another shared object or investigate the input's symbol metadata. Do not treat a failed export as an empty snapshot.

4. Build a linkable ELF stub

Convert the IFS snapshot into an ELF shared-object stub in the same disposable workspace:

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

The stub is for link-time use. It is not a replacement runtime library: it contains the interface needed by the linker, not the implementation. Keep the real library available for execution and packaging, and make sure your build cannot accidentally install the stub over it.

LLVM documents a deliberately minimal ELF layout for this purpose. Some ELF analysis tools expect program headers, while linkers such as LLD can work with the minimal output. Use your actual linker and build tests to confirm compatibility before adopting a stub in a release pipeline.

5. Make repeated generation quiet and stable

For a job that regenerates snapshots, add --write-if-changed. It leaves an existing output untouched when the generated content is identical:

$ sha256sum "$work/libz.ifs"
30ffa4f0a3326e7f976d9c83ad626a8a2230bcd56d97510fdf23a88ce38daff3  /tmp/llvm-ifs.example/libz.ifs
$ llvm-ifs-18 --input-format=ELF \
    --output-ifs="$work/libz.ifs" \
    --write-if-changed "$input"
$ sha256sum "$work/libz.ifs"
30ffa4f0a3326e7f976d9c83ad626a8a2230bcd56d97510fdf23a88ce38daff3  /tmp/llvm-ifs.example/libz.ifs

The hash above is an observed result for the installed library, not a value to hard-code in your checks. Compare the file in version control or with a trusted build artefact instead. There is no persistent undo step here: remove the disposable workspace when you have finished reviewing it, or leave it for inspection and clean it up according to your normal temporary-file policy.

6. Handle target metadata deliberately

When converting IFS to ELF, the target fields in the IFS describe the output architecture, byte order and bit width. If the IFS deliberately omits target details, supply compatible values with --arch, --endianness and --bitwidth, or use one --target triple. Do not mix --target with the other target flags.

Never force a different target merely to make a command complete. The tool reports a conflict when metadata disagrees, and that is a useful safety stop. For example, asking this IFS to produce an AArch64 output while it still describes an ELF x86-64 input fails rather than silently relabelling it:

$ llvm-ifs-18 --input-format=IFS \
    --target=aarch64-linux-gnu \
    --output-elf="$work/wrong-target.so" "$work/libz.ifs"
error: Target triple cannot be used simultaneously with ELF target format
$ printf 'status=%s\n' "$?"
status=1

If you need a portable IFS, generate it with target fields intentionally stripped, then restore them only when the consuming build knows the target. Keep that choice visible in the build configuration and review it when architectures change.

Done means

  • You recorded the installed LLVM version and selected a readable ELF input.
  • You generated an IFS file and inspected its target, dependencies and symbols.
  • You generated an ELF stub in a disposable path and checked it with file or readelf.
  • You use --write-if-changed where stable repeated output matters.
  • You treat target conflicts and interface type errors as diagnostics, not reasons to force output.
  • You kept the generated stub away from runtime library paths and made no system changes.