| # llvm-ifs - shared object stubbing tool | |
| ```{program} llvm-ifs | |
| ``` | |
| ## SYNOPSIS | |
| {program}`llvm-ifs` \[*options*\] *inputs* | |
| ## DESCRIPTION | |
| {program}`llvm-ifs` is a tool that jointly produces human-readable text-based | |
| stubs (.ifs files) for shared objects and linkable shared object stubs | |
| (.so files) from either ELF shared objects or text-based stubs. The text-based | |
| stubs is useful for monitoring ABI changes of the shared object. The linkable | |
| shared object stubs can be used to avoid unnecessary relinks when the ABI of | |
| shared libraries does not change. | |
| ## IFS FORMATS | |
| Here is an example of the text representation (IFS) of a shared object produced | |
| by the {program}`llvm-ifs`: | |
| ``` | |
| --- !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 } | |
| ... | |
| ``` | |
| - `IFSVersion`: Version of the IFS file for reader compatibility. | |
| - `SoName` (optional): Name of the shared object file that is 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 can be optional and can be overridden from command line | |
| options. | |
| - `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 not explicitly supported are mapped as unknown to improve signal-to-noise ratio. | |
| - `Size`: The size of the symbol in question, doesn't apply to functions, and is 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 that is needed to generate a | |
| linkable ELF shared object as well as an Apple TAPI format file. The ordering | |
| of symbols is sorted, so these files can be easily compared using diff tools. | |
| If the content of the file changes, it indicates a potentially ABI breaking | |
| change. | |
| ## ELF STUB FORMAT | |
| A minimum ELF file that can be used by linker should have following sections properly populated: | |
| - ELF header. | |
| - Section headers. | |
| - Dynamic symbol table (`.dynsym` section). | |
| - Dynamic string table (`.dynstr` section). | |
| - Dynamic table (`.dynamic` section). | |
| - `DT_SYMTAB` entry. | |
| - `DT_STRTAB` entry. | |
| - `DT_STRSZ` entry. | |
| - `DT_NEEDED` entries. (optional) | |
| - `DT_SONAME` entry. (optional) | |
| - Section header string table (`.shstrtab` section) | |
| 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. | |
| ## OPTIONS | |
| :::{option} --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 as the input format can be | |
| inferred. | |
| ::: | |
| :::{option} --output-elf=<output-filename> | |
| Specify the output file for ELF shared object stub. | |
| ::: | |
| :::{option} --output-ifs=<output-filename> | |
| Specify the output file for text IFS. | |
| ::: | |
| :::{option} --output-tbd=<output-filename> | |
| Specify the output file for Apple TAPI tbd. | |
| ::: | |
| :::{option} --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 ELF | |
| 'e_machine' field. If the value is conflicting with the IFS file, an error | |
| will be reported and the program will stop. | |
| ::: | |
| :::{option} --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. | |
| ::: | |
| :::{option} --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. | |
| ::: | |
| :::{option} --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 llvm target triple. | |
| This flag cannot be used simultaneously with other target related flags. | |
| ::: | |
| :::{option} --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 '`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:' filed in the | |
| generated IFS. If it conflicts with the input object file, an error will be | |
| reported and the program will stop. | |
| ::: | |
| :::{option} --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. | |
| ::: | |
| :::{option} --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. | |
| ::: | |
| :::{option} --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. | |
| ::: | |
| :::{option} --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. | |
| ::: | |
| :::{option} --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. | |
| ::: | |
| :::{option} --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 {program}`llvm-ifs` succeeds, it will exit with 0. Otherwise, if an | |
| error occurs, it will exit with a non-zero value. | |