如何定义导出符号的地址

How to define an exported symbol's address

本文关键字:符号 地址 何定义 定义      更新时间:2023-10-16

假设我正在编写一个c++库,它必须导出一个变量,一个数据结构,例如,称为ExpData。因此,链接到我的库的程序可以访问这个变量(有一个公共头文件将其定义为extern void *ExpData[])。

然而,这个数据结构在内部是c++类的虚变量表。例如:InternalType。因此,在查看生成的汇编代码之后,我发现InternalType的虚表被导出为_ZTV12InternalType

然后,我需要一种方法使我的库导出变量ExpData被解析为与_ZTV12InternalType相同的地址,这样,当外部程序读取我的库的ExpData变量时,它实际上正在读取InternalType的vtable。

为了澄清,InternalType的虚函数表汇编代码是:

    .type   _ZTV12InternalType,@object # @_ZTV12InternalType
    .section    .data.rel.ro._ZTV12InternalType,"aGw",@progbits,_ZTV12InternalType,comdat
    .weak   _ZTV12InternalType
    .align  16
_ZTV12InternalType:
    .quad   0
    .quad   _ZTI12InternalType
    .quad   _ZN12InternalType8vMethodXEi
    .size   _ZTV12InternalType, 24

所以,我需要一种方法来实现这一点(或其他具有相同效果的东西):

    .type   ExpData,@object
    .globl  ExpData
    .type   _ZTV12InternalType,@object
    .section    .data.rel.ro._ZTV12InternalType,"aGw",@progbits,_ZTV12InternalType,comdat
    .weak   _ZTV12InternalType
    .align  16
_ZTV12InternalType:
ExpData:
    .quad   0
    .quad   _ZTI12InternalType
    .quad   _ZN12InternalType8vMethodXEi
    .size   _ZTV12InternalType, 24

在c++端是可能的吗?

注::我知道我不应该依赖于实现相关的细节,比如名称混淆和c++类的内部数据,但只要考虑到我的库将运行在非常特定的环境中。

编辑

我可以通过传递--defsym ExpData=_ZTV12InternalType到链接器来解决我的问题。但是,我不想将实现细节附加到外部资源。假设我决定将类的虚函数表映射为一个名为InternalTypeVTable的C结构。因此,我可以将ExpData声明为InternalTypeVTable ExpData;。如果我只需要修改源文件,而不需要修改makefiles和链接器脚本,那就太好了。

GCC的__attribute__ ((alias()))正是我需要的。

如果我这样声明ExpData:

void *ExpData[0] __attribute__ ((alias("_ZTV12InternalType")));
在库的源文件

中,我得到以下汇编代码:

    .globl  ExpData
ExpData = _ZTV12InternalType

因此,导出的符号ExpData引用的内存地址与_ZTV12InternalType相同。