c - 将可执行文件复制到内存后,动态链接器会修改引用吗?
问题描述
假设我们有以下代码:
主程序
extern void some_function();
int main()
{
some_function();
return 0;
}
mylib.c
void some_function()
{
...
}
我创建了一个共享库mylib.so
并将 i 链接到可执行目标文件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
部分,prog
以便它可以链接/重定位到 部分中some_function
的指令地址。.text
mylib.so
我的理解正确吗?
解决方案
相当接近。动态链接器将修改数据段中的某些内容,而不是具体的.data
部分 - 段是与文件如何映射到内存而不是原始语义分解相对应的粗粒度事物。实际部分通常被称为.got
或.got.plt
但可能因平台而异。修改不是“将其重定位到指令地址”,而是解析对函数名称的重定位引用以获取加载它的地址,并填写该地址。
推荐阅读
- clojure - 带有外部绑定符号的 core.async go 块可以工作,但不能进行宏扩展
- date - 如何忽略空白以返回从列中返回最接近今天的日期?
- python - 将零更改为数组中最近的左侧非零邻居
- typo3 - TYPO3:微型网站上的新闻详细信息视图
- python-3.x - 有没有办法在 Raspbian 等 Linux 操作系统中模拟击键和鼠标点击?
- python - 在 Outlook 正文中调整 HTML 表格的大小不起作用
- android - 我无法从 Google Codelab 在 AndroidStudio 上打开项目
- flutter - 无法使用 AudioPlayer 包在 iOS 上播放来自 URL 的音频 - Flutter
- c# - 无法从 CouchDB 反序列化 Json
- python - 从文件夹安装 Python 模块