问题描述
假设我们有以下代码:
main.c
extern void some_function();
int main()
{
some_function();
return 0;
}
mylib.c
void some_function()
{
...
}
我已经创建了一个共享库mylib.so
,并将我链接到可执行对象文件prog
linux> gcc -shared -fpic -o mylib.so mylib.c
linux> gcc -o prog main.c ./mylib.so
我们假设下图是prog
通过动态链接,我们知道此时mylib.so的代码段或数据段实际上均未复制到可执行文件prog2l中。相反,链接器将复制一些重定位和符号表信息,以允许在加载时解析对mylib.so中的代码和数据的引用。
我只想仔细检查一下我的理解是否正确:
当prog
由加载程序加载到内存中时,如下图所示
然后,动态链接器将修改内存中.data
的{{1}}部分,以便可以将其链接/重定位到prog
部分中的some_function
的指令地址。的.text
。
我的理解正确吗?
解决方法
完全关闭。动态链接器将修改数据段中的某些内容,而不是.data
节中的特定内容-这些段是粗粒度的内容,与文件如何映射到内存而不是原始语义分解相对应。实际部分通常称为.got
或.got.plt
,但可能因平台而异。修改不是“将其重定位到指令地址”,而是解析对函数名称的重定位引用以获取加载该地址的地址,然后将该地址填充到其中。