LLVM-IFS(1)

πŸ’… LLVM-IFS(1) β€” the shared object stubbing tool, bestie edition ✨

okay so real talk, this is llvm-ifs, and it lives in the LLVM manual, section 1 (general commands, iykyk). it's a shared object stubbing tool, and honestly? she's iconic and nobody talks about her enough. let's get into it 🫢


🌸 NAME 🌸

llvm-ifs β€” shared object stubbing tool


✨ SYNOPSIS ✨

llvm-ifs [options] inputs

πŸ¦‹ DESCRIPTION πŸ¦‹

so llvm-ifs is the bestie that jointly produces, from either ELF shared objects or text-based stubs:

  • human readable text-based stubs (.ifs files) for shared objects, and
  • linkable shared object stubs (.so files).

the text-based stubs are literally made for monitoring ABI changes of the shared object, no cap. and the linkable shared object stubs? they exist so you can avoid unnecessary relinks when the ABI of shared libraries does not change. periodt πŸ’…


πŸŽ€ IFS FORMATS πŸŽ€

here's an example of the text representation (IFS) of a shared object produced by llvm-ifs, and yes it's giving very much YAML main character energy:

--- !ifs-v1
IFSVersion: 3.0
SoName: libtest.so /* Optional */
Target: x86_64-unknown-linux-gnu   /* Optional, format 1, same format as llvm target triple */
Target: { Arch: x86_64, Endianness: little, Bitwidth: 64 } /* Optional, format 2 */
NeededLibs:
  - libc.so.6
Symbols:
  - { Name: sym0, Type: Notype }
  - { Name: sym1, Type: Object, Size: 0 }
  - { Name: sym2, Type: Func, Weak: false }
  - { Name: sym3, Type: TLS }
  - { Name: sym4, Type: Unknown, Warning: foo }
...

and here's the field-by-field breakdown πŸ”

  • IFSVersion β€” the version of the IFS file, so readers stay compatible. reader compatibility slay.
  • SoName (optional) β€” the name of the shared object file that's being stubbed.
  • Target (optional) β€” the architecture, endianness and bitwise information of this shared object. it can be either in explicit format or in implicit LLVM triple format. it's optional, and it can be overridden from command line options. versatile queen.
  • NeededLibs β€” the list of the external shared objects that this library depends on.
  • Symbols β€” a collection of all data needed to link objects for each symbol, sorted by name in ascending order.
    • Name β€” symbol name.
    • Type β€” whether the symbol is an object, function, no-type, thread local storage, or unknown. symbol types that aren't explicitly supported get mapped as unknown, to improve signal-to-noise ratio (a very "we don't do noise here" move).
    • Size β€” the size of the symbol in question. doesn't apply to functions, and it's optional for NoType symbols.
    • Undefined β€” whether or not the symbol is defined in this shared object file.
    • Weak β€” whether or not the symbol should be treated as weak.
    • Warning (optional) β€” warning text to output when this symbol is linked against.

this YAML based text format contains everything needed to generate a linkable ELF shared object as well as an Apple TAPI format file. and the ordering of symbols is sorted, so these files can be easily compared using diff tools β€” so clean, so demure. if the content of the file changes, that indicates a potentially ABI breaking change ⚠️


πŸ’œ ELF STUB FORMAT πŸ’œ

a minimum ELF file that a linker can actually use should have the following sections properly populated:

  • ELF header.
  • Section headers.
  • Dynamic symbol table (.dynsym section).
  • Dynamic string table (.dynstr section).
  • Dynamic table (.dynamic section), which contains:
    • DT_SYMTAB entry.
    • DT_STRTAB entry.
    • DT_STRSZ entry.
    • DT_NEEDED entries. (optional)
    • DT_SONAME entry. (optional)
  • Section header string table (.shstrtab section)
heads up bestie: this ELF file may have compatibility issues with ELF analysis tools that rely on the program headers. linkers like LLD work fine with such a minimum ELF file without errors, but like… know what you're getting into πŸ’€

πŸ‘‘ OPTIONS πŸ‘‘

  • --input-format=[IFS|ELF|OtherObjectFileFormats] β€” specify input file format. currently, only text IFS files and ELF shared object files are supported. this flag is optional since the input format can be inferred. she'll figure it out.
  • --output-elf=<output-filename> β€” specify the output file for the ELF shared object stub.
  • --output-ifs=<output-filename> β€” specify the output file for the text IFS.
  • --output-tbd=<output-filename> β€” specify the output file for the Apple TAPI tbd.
  • --arch=[x86_64|AArch64|...] β€” this flag is optional and it should only be used when reading an IFS file which does not define the Arch (architecture). this flag defines the architecture of the output file, and can be any string supported by the ELF e_machine field. if the value is conflicting with the IFS file, an error will be reported and the program will stop. no vibes-based guessing, sorry 🫠
  • --endianness=[little|big] β€” this flag is optional and it should only be used when reading an IFS file which does not define the Endianness. this flag defines the endianness of the output file. if the value is conflicting with the IFS file, an error will be reported and the program will stop.
  • --bitwidth=[32|64] β€” this flag is optional and it should only be used when reading an IFS file which does not define the BitWidth. this flag defines the bit width of the output file. if the value is conflicting with the input IFS file, an error will be reported and the program will stop.
  • --target=<target triple> β€” this flag is optional and should only be used when reading an IFS file which does not define any target information. this flag defines architecture, endianness and bit width of the output file using an llvm target triple. this flag cannot be used simultaneously with other target related flags. pick a lane, babe.
  • --hint-ifs-target=<target triple> β€” this flag is optional and should only be used when reading an ELF shared object and generating an IFS file. by default, llvm-ifs will use the Arch, Endianness and BitWidth fields to reflect the target information from the input object file. using this flag will tell llvm-ifs the expected target triple in the output IFS file. if the value matches the target information from the object file, this value will be used in the Target: field in the generated IFS. if it conflicts with the input object file, an error will be reported and the program will stop.
  • --hint-ifs-target β€” this flag is optional and should only be used when outputting an IFS file. this flag strips the Arch field from the IFS file so it can be overridden later.
  • --strip-ifs-endianness β€” this flag is optional and should only be used when outputting an IFS file. this flag strips the Endianness field from the IFS file so it can be overridden later.
  • --strip-ifs-bitwidth β€” this flag is optional and should only be used when outputting an IFS file. this flag strips the BitWidth field from the IFS file so it can be overridden later.
  • --strip-ifs-target β€” this flag is optional and should only be used when outputting an IFS file. this flag strips the Target field from the IFS file so it can be overridden later.
  • --write-if-changed β€” when this flag is set, llvm-ifs will only write the output file if it does not already exist or the content will be different from the existing file. so considerate, honestly.
  • --strip-size β€” when this flag is set, llvm-ifs will remove the size field from the output ifs file. this is useful for shared objects that only intend to be linked against position independent code which doesn't need copy relocations, or where the size of an object is not a useful part of the abi to track.

πŸ“ EXIT STATUS πŸ“

if llvm-ifs succeeds, it will exit with 0 ✨. otherwise, if an error occurs, it will exit with a non-zero value. (that's the "not me, not today" exit code πŸ’€)


🌈 AUTHOR 🌈

maintained by the LLVM Team (https://llvm.org/). shoutout, they ate.


2003-2026, LLVM Project


and that's the whole page, bestie! brought to you by LLVM version 15, dated 2026-09-09 β€” go forth and stub responsibly, mwah πŸ’–πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from