我一直在阅读John R. Levine的Linkers和Loaders,我读到目标文件的属性将包含以下一个或多个。
现在,考虑这个例子:
#include<stdio.h>
int main() {
printf("testing\n");
return 0;
}
我将编译和链接:
$ gcc -c t.c $ gcc -o t t.o
我尝试使用t.o
检查objdump
,其类型显示为REL
。所有属性t.o
满足的是什么?我相信它的可链接,不可执行。我原以为它不可加载(除非你从.o文件创建一个.so文件);但是类型REL
意味着它应该被重新定位,并且重定位只会在加载的上下文中发生,所以我在这里有一个混乱。
我的疑惑总结如下: -
loadable
?答案 0 :(得分:1)
只是将上下文this link状态设置为相似(仅强调可读性);
文件可能可链接,用作链接编辑器或链接的输入 装载机。它是可执行文件,能够被加载到 内存并作为程序运行,可加载,能够加载 作为一个库与一个程序,或任何组合的内存 这三个。
.o文件是一个链接器对象文件,根据此定义不可执行和绝对可链接。可加载是一个更强硬的调用,但由于.o文件不能加载而没有一些绝对不是跨平台的欺骗,我会说精神是它无法加载。
答案 1 :(得分:1)
目标文件(即扩展名为.o的文件)不可加载。这是因为它缺乏关于如何解析其中所有符号的关键信息:在这种情况下,println
符号尤其需要其他信息。 (C编译器不会将库标识绑定到它们创建的目标文件中,这有时甚至是有用的。)
将目标文件链接到共享库(.so)时,您将添加该绑定。通常,您还要将多个目标文件组合在一起并解析它们之间的引用(以及一些更深奥的东西)。然后,结果可以加载,因为加载器可以只是解析引用和加载它还不知道的依赖项。
从那里到可执行文件通常只是添加OS定义的程序引导程序。这是操作系统将通过调用启动程序的一小段代码,它通常通过加载程序和依赖项的其余部分,然后使用有关参数的信息调用main()
来工作。 (如果主要回归,它还负责干净地退出。)