【发布时间】:2018-01-06 07:13:54
【问题描述】:
我读到,在两遍链接中,在第一遍中,所有目标代码的符号表都被合并到一个全局表中,所有段都与其地址一起存储到段表中。
在第二遍中,通过使用全局符号表和段表进行符号解析。
我的问题是,符号表只包含值、符号名称和类型条目,那么链接器如何在第二遍符号解析期间从全局符号表中知道每个符号的地址?
【问题讨论】:
标签: compiler-construction linker
我读到,在两遍链接中,在第一遍中,所有目标代码的符号表都被合并到一个全局表中,所有段都与其地址一起存储到段表中。
在第二遍中,通过使用全局符号表和段表进行符号解析。
我的问题是,符号表只包含值、符号名称和类型条目,那么链接器如何在第二遍符号解析期间从全局符号表中知道每个符号的地址?
【问题讨论】:
标签: compiler-construction linker
在装配时定义符号时,会为其分配段:偏移量。如果它被声明为 PUBLIC,则它存储在全局符号表中。
当段被链接到可执行映像中时,每个段获得其相对虚拟地址。将此段的 RVA 的偏移量添加到符号的值。典型的公共符号是库函数的入口。
所以您的问题的答案是:偏移量由编译器在汇编时指定,以及段的名称。当段一个接一个地排序时,链接器在链接时指定段地址。它们一起产生所需的符号值(地址)。
如果另一个目标代码引用这个公共符号(调用库函数),它被声明为 EXTERN 并且它的值在汇编时是未知的,因此它被临时设置为零并伴随着称为 的数据结构搬迁。 重定位指定此临时零的地址和外部符号的名称。链接器读取重定位,找到具有匹配名称的相应公共符号,然后用公共符号的值替换临时零。
【讨论】: