llvm-ifs - 共享对象桩生成工具

概要

llvm-ifs [选项] 输入

描述

llvm-ifs 是一个工具,它可以从 ELF 共享对象或基于文本的桩文件中联合生成人类可读的基于文本的桩文件(.ifs 文件)和可链接的共享对象桩文件(.so 文件)。基于文本的桩文件对于监视共享对象的 ABI 更改非常有用。可链接的共享对象桩文件可用于避免在共享库的 ABI 没有更改时进行不必要的重链接。

IFS 格式

以下是由 llvm-ifs 生成的共享对象的文本表示 (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:IFS 文件的版本,用于读取器兼容性。

  • SoName(可选):正在生成桩文件的共享对象文件的名称。

  • Target(可选):此共享对象的体系结构、字节序和位宽信息。它可以是显式格式或隐式 LLVM 三元组格式。它可以是可选的,并且可以从命令行选项中覆盖。

  • NeededLibs:此库依赖的外部共享对象列表。

  • Symbols:链接对象所需的每个符号的所有数据集合,按名称升序排序。

    • Name:符号名称。

    • Type:符号是对象、函数、无类型、线程本地存储还是未知。未显式支持的符号类型被映射为未知,以提高信噪比。

    • Size:所讨论符号的大小,不适用于函数,对于 NoType 符号是可选的。

    • Undefined:符号是否在此共享对象文件中定义。

    • Weak:符号是否应被视为弱符号。

    • Warning(可选):当链接到此符号时输出的警告文本。

这种基于 YAML 的文本格式包含生成可链接的 ELF 共享对象以及 Apple TAPI 格式文件所需的一切。符号的顺序是排序的,因此可以使用 diff 工具轻松比较这些文件。如果文件内容发生更改,则表明可能存在 ABI 破坏性更改。

ELF 桩格式

链接器可以使用的最小 ELF 文件应正确填充以下部分

  • ELF 头部。

  • 节头部。

  • 动态符号表(.dynsym 节)。

  • 动态字符串表(.dynstr 节)。

  • 动态表(.dynamic 节)。

    • DT_SYMTAB 条目。

    • DT_STRTAB 条目。

    • DT_STRSZ 条目。

    • DT_NEEDED 条目。(可选)

    • DT_SONAME 条目。(可选)

  • 节头部字符串表(.shstrtab 节)

此 ELF 文件可能与依赖于程序头部的 ELF 分析工具存在兼容性问题。像 LLD 这样的链接器可以很好地处理这种最小的 ELF 文件,而不会出错。

选项

--input-format=[IFS|ELF|OtherObjectFileFormats]

指定输入文件格式。目前,仅支持文本 IFS 文件和 ELF 共享对象文件。此标志是可选的,因为可以推断输入格式。

--output-elf=<output-filename>

指定 ELF 共享对象桩的输出文件名。

--output-ifs=<output-filename>

指定文本 IFS 的输出文件名。

--output-tbd=<output-filename>

指定 Apple TAPI tbd 的输出文件名。

--arch=[x86_64|AArch64|...]

此标志是可选的,仅当读取未定义 Arch(体系结构)的 IFS 文件时才应使用。此标志定义输出文件的体系结构,可以是 ELF 'e_machine' 字段支持的任何字符串。如果该值与 IFS 文件冲突,则会报告错误并且程序将停止。

--endianness=[little|big]

此标志是可选的,仅当读取未定义 Endianness 的 IFS 文件时才应使用。此标志定义输出文件的字节序。如果该值与 IFS 文件冲突,则会报告错误并且程序将停止。

--bitwidth=[32|64]

此标志是可选的,仅当读取未定义 BitWidth 的 IFS 文件时才应使用。此标志定义输出文件的位宽。如果该值与输入 IFS 文件冲突,则会报告错误并且程序将停止。

--target=<target triple>

此标志是可选的,仅当读取未定义任何目标信息的 IFS 文件时才应使用。此标志使用 llvm 目标三元组定义输出文件的体系结构、字节序和位宽。此标志不能与其他目标相关标志同时使用。

--hint-ifs-target=<target triple>

此标志是可选的,仅当读取 ELF 共享对象并生成 IFS 文件时才应使用。默认情况下,llvm-ifs 将使用 'ArchEndiannessBitWidth' 字段来反映来自输入对象文件的目标信息。使用此标志将告诉 llvm-ifs 输出 IFS 文件中期望的目标三元组。如果该值与来自对象文件的目标信息匹配,则此值将用于生成的 IFS 中的“Target:”字段。如果它与输入对象文件冲突,则会报告错误并且程序将停止。

--hint-ifs-target

此标志是可选的,仅当输出 IFS 文件时才应使用。此标志从 IFS 文件中删除 Arch 字段,以便稍后可以覆盖它。

--strip-ifs-endianness

此标志是可选的,仅当输出 IFS 文件时才应使用。此标志从 IFS 文件中删除 Endianness 字段,以便稍后可以覆盖它。

--strip-ifs-bitwidth

此标志是可选的,仅当输出 IFS 文件时才应使用。此标志从 IFS 文件中删除 BitWidth 字段,以便稍后可以覆盖它。

--strip-ifs-target

此标志是可选的,仅当输出 IFS 文件时才应使用。此标志从 IFS 文件中删除 Target 字段,以便稍后可以覆盖它。

--write-if-changed

设置此标志后,llvm-ifs 将仅在输出文件尚不存在或内容与现有文件不同时写入输出文件。

--strip-size

设置此标志后,llvm-ifs 将从输出 ifs 文件中删除 size 字段。这对于仅旨在链接到不需要复制重定位的位置无关代码,或者对象大小不是要跟踪的 abi 的有用部分的共享对象很有用。

退出状态

如果 llvm-ifs 成功,它将以 0 退出。否则,如果发生错误,它将以非零值退出。