生成静态库和动态库的方法:
静态库直接用ar工具,例子:
ar -crv libstaticmath.a StaticMath.o
动态库的例子:
gcc -c -fPIC max.c
gcc -shared -o libmax.so max.o
生成动态库分为编译和链接两步, -fPIC是编译选项,PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性; -shared是链接选项,告诉gcc生成动态库而不是可执行文件。
查看符号可以用nm。
实现方式:
有两个表got和plt表,用于动态库的实现。表放在.data段的开头。动态库的代码和数据通过mmap映射到进程,代码段是共享的,数据段不是共享的。
对于动态库中的全局变量都会由got表重定位到真实的内存地址。就是说如果引用了某个动态库的全局变量那么他在读取的时候会先读got表得到正确的虚拟地址再去找到数据。
函数调用则是用的延迟加载方式。
1.先找plt表的表项,plt表项会映射到got表项。
2.找到got表项,第一次调用则直接返回到plt表项的下一条指令的地址,非首次则直接跳转到真实的函数地址。
3.若首次,则把参数压栈,跳转到plt[0],plt[0]会根据当前的信息(具体请看CS:APP)确定运行时的位置,并把这个地址写到got表项中,然后跳转到函数的地址实现函数调用。