【问题标题】:Is the address of a C function symbol constant between compiles是编译之间的 C 函数符号常量的地址
【发布时间】:2019-04-07 22:31:42
【问题描述】:

我一直在我的共享库中试验符号可见性,并注意到导出函数符号的地址/值似乎没有改变。这些地址在编译之间是不变的,还是巧合?

在运行 Arch Linux 的虚拟机上使用命令 readelf 和选项 -W--dyn-syms 获得的地址。

我问的原因是 我想知道模板化 C++ 函数的地址是否可以用作对象类型的 uuid。 这对我的序列化例程很感兴趣想设置一个在编译之间保持不变的 id 系统(对象类型在初始化时静态注册,因此没有定义顺序)。

【问题讨论】:

标签: c++ c serialization dll shared-libraries


【解决方案1】:

如果构建过程没有改变(即编译器、链接器、Makefiles 和代码保持不变),ELF 文件中的 static 地址也不会改变。但如果任何组件发生变化,所有赌注都将被取消。

更重要的是,由于现代 Linux 发行版中的 address-space randomization动态 地址(由动态加载程序分配)在每次运行时都会有所不同,因此您不应依赖它。

【讨论】:

    【解决方案2】:

    当您构建代码时,您可以选择将其构建在 dependentindependent 位置,这与静态构建无关(尽管您无法构建位置无关的静态二进制文件)。位置相关的二进制文件(给定相同的源、编译器和构建标志)将始终生成相同的地址,但正如我在下文中所说的那样,我不会在发布时依赖它。

    这是由 GCC 的选项 -fPIE(与位置无关的可执行文件)、-fPIC(与位置无关的代码)、-pie 提供的。 ELF 可执行文件可以构建为位置依赖独立,但共享对象(库)将始终构建为位置独立 因为您需要能够将它们加载到操作系统给您的随机位置。来自 GCC 的 MAN 页面:

    -fPIC
    If supported for the target machine, emit position-independent code, suitable for dynamic linking and avoiding any limit on the size of the global offset table. 
    
    -fpie
    -fPIE
    These options are similar to -fpic and -fPIC, but generated position independent code can be only linked into executables. Usually these options are used when -pie GCC option will be used during linking.
    
    -pie
    Produce a position independent executable on targets which support it. For predictable results, you must also specify the same set of options that were used to generate code (-fpie, -fPIE, or model suboptions) when you specify this option.
    

    在加载 PIC 共享对象时,您不能假设每次运行它都会驻留在同一个位置,因为它可能会受到内核驱动的 ASLR 的影响。

    无论如何,我认为将内存地址用作类的 uuid 不是一个好习惯,因为这些可能会发生变化,如果这些模板类作为共享对象的一部分实现则更是如此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-01
      • 2020-06-18
      相关资源
      最近更新 更多