链接-静态链接

前言

链接这个操作分为两个部分 :

  • 符号解析
  • 重定位
    简单点说就是找到符号(如何找呢??通过符号表找到) ,然后将正确的地址填上

文章先从符号到符号解

回顾链接过程

img

img

符号的类型及相关的段

链接符号的类型

包括三种类型

  • 全局符号 ,里面还分强弱
  • 外部定的全局符号
  • 本模块的局部符号
    img

可以看一下下面的例子
img

目标文件中的符号表 (.symtab)

img

符号表是一个 section (段),我们在前面介绍 ELF 段结构的时候是有看到这个段的 , 符号表的结构包含了符号的各种属性, 什么类型的, 在哪个地方,多大, 叫什么名字

img

全局符号分类

img
分强弱

符号解析

再介绍符号解析之前我们先介绍一下静态库 ,原因是我们现在写的程序都会用到这东西

什么是静态库

img

静态库的创建

img

常用的静态库
img

自定义静态库

img

符号解析-解析规则

最终的目标就是将代码中的地址替换成正确的地址或是数值 ,根据以下的规则进行解析
img

这个规则有时候在一些复杂的场景会解析出"意想不到的结果" ,看下面的例子

img

符号解析-解析过程

img

目的这一行 , 这一步会将引用符号目标模块的符号相关联

下面是解析的过程 , 用了三个集合, 目的就是给引用找到对应的地址 , 注意我们用的实例是上面 自定义静态库章节里的例子
img

img

需要注意的是符号解析还需要注意顺序 ,例如 :

img

额 ,有点不智能吧

重定位

回顾

img

img

用到的例子代码

main.c

int buf[2] = {1, 2};
void swap();
int main()
{
    swap();
    return 0;
}

swap.c

extern int buf[];
int *bufp0 = &buf[0];
static int *bufp1;
void swap()
{
    int temp;
    bufp1 = &buf[1];
    temp = *bufp0;
    *bufp0 = *bufp1;
    *bufp1 = temp;
}

重定位表

重定位就是将那些符号定义和符号引用替代掉 ,那么要去"去代替"这个动作需要知道 ,将要替代的符号在哪里 ,应该替换成那种类型 ,替代成什么这些信息 ,而
这些信息就记录在重定位表中

img

重定位过程

img

从上面这张图我们可以知道 main 长度占了12个字节.
根据前面的重定位表我们可以看到, 这个地方重定位的类型是相对定位 , 需要替代的符号是 swap , 相对指的是相对于当前之前的偏移量 . 我们给出一个假设然后推理出一个相对定位的过程

img

img

而绝对位置定位就简单多了, 说白了就是那个符号的地址在哪里就是那里

img

img

总结

该篇介绍了符号表和符号解析 ,以及重定位相关的知识 ,主要是学习的课件 .

参考

  • <<程序员的自我修改--链接,装载与库>> 书
  • mooc上袁春风老师的课
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章