1
1
这些信息可以在二进制文件的符号表中找到,尽管它可能不是您所期望的那样。
链接器获取一个或多个对象文件,组合这些部分(将每个对象文件中的所有代码和数据放入一个大的代码和数据部分),并编写一个输出文件。此输出文件可以是可执行文件,也可以是共享库。磁盘上的可执行文件仍然没有每个变量的指针;它仍然存储从节开始到变量的偏移量。 运行可执行文件时,操作系统的动态加载程序读取可执行文件,查找每个节,并为该节分配内存(它还可以在每个部分上设置不同的权限,“.text”段通常被标记为只读,并且(在支持它的处理器上)数据段有时被标记为不可执行。)只有这样,当代码需要访问特定变量时,变量才会获得指针,它将节开头的地址添加到距节开头的偏移量,以获取指针。
您可以使用各种工具来研究每个二进制文件的符号表。GNU工具链的
对于一个简单的C hello world程序:
我在Linux上编译(但不链接):
现在我可以看看符号表:
第一列是每个符号相对于节开头的地址。每个符号都有不同的标志,其中一些符号被用作工具链和调试器其余部分的提示(如果我使用调试符号构建,我也会看到许多专门用于调试符号的条目。)我的简单程序只有一个变量:
|
2
3
|
3
1
虽然不需要编译器来输出这些数据,但大多数 链接器 我可以把这些信息都倒出来。例如,Microsoft的链接器映射文件包含可执行文件/dll中的所有公共符号,以及它们相对于所在节的地址(只读、读写、代码、零初始化等)。尺寸可以从中导出,尽管它主要是一个近似值。 您还可以找到一种方法来检查为可执行文件生成的调试符号,因为这正是调试器必须要做的。 |
4
1
通常情况下,你会从链接器而不是编译器那里得到这些信息——链接器是为事物分配地址的工具。大多数链接器可以生成包含全局变量地址的映射文件 和 |
Community wiki · safe_ptr实现 1 年前 |
lplplplp · 为什么不能访问函数外的结构指针 2 年前 |
Fabio · 在c中将指针赋给常数指针++ 2 年前 |
Gabe Tucker · 无法在golang中分配接口对象指针 2 年前 |