LLVM-IFS(1)

πŸ“¦ version 23.1.3, in centos-stream 9

πŸ’… LLVM-IFS

okay bestie, buckle up β€” this is llvm-ifs, straight out of the LLVM manual (yes, that LLVM). It's the shared object stubbing tool, and honestly? underrated icon behavior. πŸŽ€

✨ SYNOPSIS ✨

llvm-ifs [options] inputs

🌸 DESCRIPTION 🌸

so llvm-ifs is that girl who does two jobs at once and makes it look effortless πŸ’… β€” it jointly produces human-readable text-based stubs (.ifs files) for shared objects and linkable shared object stubs (.so files), and it can do that starting from either ELF shared objects or text-based stubs. no cap.

the text-based stubs? lowkey perfect for monitoring ABI changes of the shared object πŸ‘€. and the linkable shared object stubs? they exist so you can dodge unnecessary relinks when the ABI of shared libraries hasn't changed. literally saving you from recompiling for no reason. we love a efficiencies queen πŸ¦‹

🧚 IFS FORMATS 🧚

here's an example of the text representation (IFS) of a shared object that llvm-ifs produces β€” drink it in ✨:

--- !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 }
...

okay now let's break down every single one of those fields, because they all matter:

  • IFSVersion β€” the version of the IFS file, there for reader compatibility. it's giving "know what you're reading before you read it" πŸ“–
  • 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. flexible much? πŸ’«
  • NeededLibs β€” the list of 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. and inside it:
    • Name β€” symbol name.
    • Type β€” whether the symbol is an object, function, no-type, thread local storage, or unknown. any symbol types that aren't explicitly supported get mapped as unknown, to improve signal-to-noise ratio πŸ“ˆ (we stan a clean signal).
    • 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. helpful little heads-up 🫢

this YAML based text format literally contains everything that's needed to generate a linkable ELF shared object as well as an Apple TAPI format file. and because the ordering of symbols is sorted, you can diff these files with actual diff tools, easily. πŸŽ€ so if the content of the file changes, that indicates a potentially ABI breaking change β€” like a little vibe check for your ABI πŸ’€

πŸ”₯ ELF STUB FORMAT πŸ”₯

a minimum ELF file that can be used by a linker should have the following sections properly populated (no skipping, bestie, all of them):

  • 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: this ELF file may have compatibility issues with ELF analysis tools that rely on the program headers. but linkers like LLD work fine with such a minimum ELF file, without errors. so like... know your audience 😭

πŸ‘‘ OPTIONS πŸ‘‘

  • --input-format=[IFS|ELF|OtherObjectFileFormats] β€” specify the input file format. rn only text IFS files and ELF shared object files are supported. this flag is optional because the input format can be inferred (she's smart like that πŸ’…).
  • --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|...] β€” optional, and it should only be used when reading an IFS file that doesn't 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 conflicts with the IFS file, an error gets reported and the program stops. πŸ›‘
  • --endianness=[little|big] β€” optional, and it should only be used when reading an IFS file that doesn't define the Endianness. this flag defines the endianness of the output file. if the value conflicts with the IFS file, an error gets reported and the program stops.
  • --bitwidth=[32|64] β€” optional, and it should only be used when reading an IFS file that doesn't define the BitWidth. this flag defines the bit width of the output file. if the value conflicts with the input IFS file, an error gets reported and the program stops.
  • --target=<target triple> β€” optional, and should only be used when reading an IFS file that doesn't define any target information. this flag defines the architecture, endianness and bit width of the output file using an llvm target triple. and important: this flag cannot be used simultaneously with the other target related flags 🚫 (pick a lane, babe).
  • --hint-ifs-target=<target triple> β€” optional, and should only be used when reading an ELF shared object and generating an IFS file. by default, llvm-ifs uses the 'Arch, Endianness and BitWidth' fields to reflect the target information from the input object file. using this flag tells llvm-ifs the expected target triple in the output IFS file. if the value matches the target information from the object file, this value gets used in the 'Target:' field in the generated IFS. if it conflicts with the input object file, an error gets reported and the program stops. 😀
  • --hint-ifs-target β€” 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. yes, it's a second --hint-ifs-target, and yes, that's exactly what the manual says β€” we don't editorialize ✨
  • --strip-ifs-endianness β€” 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 β€” 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 β€” 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 doesn't already exist, or if the content would be different from the existing file. no unnecessary writes, we're minimalist now πŸŽ€
  • --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 isn't a useful part of the abi to track. iykyk πŸ’œ

🌈 EXIT STATUS 🌈

if llvm-ifs succeeds, it exits with 0. otherwise, if an error occurs, it exits with a non-zero value. simple as that, bestie 😌

⭐ AUTHOR ⭐

maintained by the LLVM Team (https://llvm.org/). slay 🫢

2003-2026, LLVM Project


πŸ’– okay that's the whole page!! and before you go β€” this lil manual page is dated 23 / 2026-10-06, and it's page LLVM-IFS(1) from the LLVM manual set. go forth and stub your shared objects, icon πŸ’…βœ¨
πŸ“¦ where this page comes from