LLVM IR 链接类型

在LLVM程序中,所有全局变量和函数都具有以下类型的链接之一:

private

“private”链接的全局值只能由当前模块中的对象直接访问。特别地,链接代码到一个包含”private”全局值的模块时在必要情况下可能会造成”private”全局值rename来避免冲突。因为这个symbol是对当前模块私有的,所以所有对这个全局值的引用都可以被更新(名字)。这并不会在object file的任何symbol table中展示出来。

internal

与”private”相似,但该值在object file表现为local symbol (STB_LOCAL in the case of ELF) . 这对应于C中的“static”的关键字的概念。

available_externally

带有available_externally链接标识的全局变量不会存放到当前object file相应的LLVM模块。他们的存在是为了内联和其他优化行为的发生提供当前模块的一份全局定义,切这份定义是从一个外部模块中获得的。带有available_externally链接标志的全局变量允许在任意时刻丢弃,而其他方面与”linkonce_odr”相似。这个链接类型只允许在定义中使用,不允许在声明中使用。

linkonce

带有linkonce链接标识的全局变量会在链接过程中与其他同名的全局变量合并。这可以被用于实现内联函数,模板,或其他必须在每一个编译单元内使用的代码的形式,但主体可以被一个更详细的定义覆盖。

全局用linkonce联动合并具有相同名称的其他全局联动时发生。这可以被用来实现某些形式的内联函数,模板,或者它必须在使用它的每个转换单元中生成的,但其中的主体可以具有更明确的定义以后被覆盖其他代码。

weak

除了未被引用的带”weak”链接标识的全局变量可能会被抛弃外,“weak”链接标识拥有与”linkonce”相同的合并语义。这个标志被使用于在C源代码中被声明为”weak”的全局变量。

common

“common” 链接标识与“weak”链接标识很相似,但“common”链接标识被使用于C中的tentative definition,例如 int X;在全局作用域。带有“common”链接标识的符号以一种与weak symbols相同的方式被合并,但这些符号即使未被引用也不会被删除。 common 符号可能不会有一个明确的section,必须被0值初始化(根据ELF链接规则,0值初始化的符号只通过“.bss section”提供长度占位,但不在文件中占有位置),且不可能被标志为constant。Functions和aliases 不可以带有“common” 链接标识。(因为Functions和aliases不可能被tentative definition)。

appending

“appending”链接标识只能用于数组类型的指针全局变量。但两个带有“appending”链接标识的全局变量被链接到一起,这两个全局数组追加合并到一起。 may This is the LLVM, typesafe, equivalent of having the system linker append together “sections” with identical names when .o files are linked.

不幸的是,这与.o文件中的任何功能都不对应,因此它只能用于llvm.global_ctors llvm特别解释的变量。

extern_weak

这个链接标识的语义遵循ELF object file模型:除非被链接,否则带有extern_weak的symbol是弱的,如果没有被链接该符号会变为null而不是作为未定义引用。

linkonce_odr, weak_odr

某些语言允许不同的全局变量被合并,例如具有不同的语义的两个函数。其他语言,如C++ ,确保只等效的全局变量才可以合并( “one definition rule” – “ ODR ”)。这些语言可以使用linkonce_odr和weak_odr链接标识来表明全局变量将只与等效的全局变量合并。这些链接标识类型的其他语义与其非ODR版本相同。

external

如果上述标识符都没被使用,那么该全局变量的是外部可见的,这意味着它参与链接,可用于解析外部符号引用。

一个函数声明拥有除externalextern_weak以外的链接标识是不合法的。