深入Os--静态链接
1.一个实例
#include <iostream>
int main()
{
printf("main\n");
return 0;
}
执行:g++ -std=c++11 main.cpp
,我们得到a.out
。
执行:objdump -dx a.out > 1.txt
,查看1.txt。
截取以下信息:
我们上述简单的实例可执行程序引用了来自C库的符号printf
。
这里的C库是动态库,程序执行时如何通过callq找到printf
符号定义位置属于动态库引用重定位范畴。
2.一个扩展的实例
// main.cpp
#include <iostream>
extern "C" int fun(int i, int j);
int main()
{
printf("main\n");
printf("1+2=%d\n", fun(1,2));
return 0;
}
// func.cpp
extern "C" int fun(int i, int j)
{
return i+j;
}
执行:g++ -std=c++11 func.cpp -c
得到func.o。
执行:g++ -std=c++11 main.cpp -c
得到main.o
。
执行:objdump -dx main.o > 1.txt
,查看1.txt。
截取以下信息:
上述main.o中引用了符号fun。但1.txt中并不包含符号fun的定义。
我们继续执行:g++ -std=c++11 main.cpp fun.cpp
执行:objdum -dx a.out > 11.txt
,查漏11.txt。
截取以下信息:
可以看到此时有两处改变:
(1).引用符号fun处,由0xe8 00 00 00 00变为0xe8 6a 00 00 00。
(2).fun符号的定义被拷贝到可执行文件a.out内代码段内了。
上述两处改变正是静态链接所作的工作。
(1).将符号引用对应到符号定义。
(2).将符号定义拷贝到可执行文件内。