######## 该系列博文为书籍《程序员的自我修养》的笔记 ##########
【说明】
链接中最基本的概念,就是符号了,如果没有符号,链接是没办法进行的,既然这么重要,当然要来一篇总结一下啦。
【符号的分类】
当目标文件A.o中引用了B.o的 一个变量(或者函数)的时候,其实就是引用了B.o 中的符号,在编译目标文件的时候,会把所有的变量名,函数名,都保存到符号表中(可能不是原来的变量函数名,不过在C中一般就是原来名字),在编译A.o 的时候,由于找不到引用的B.o 中的变量,所以这个符号在A.o 的符号表中就应该和其他符号的雷兴国有所区别,它们分为下面几种类型:
1)本目标文件的全局符号,它可以被外部引用。
2)外部目标文件的符号,也叫“外部符号”
3)段名,它也是符号,它由编译器产生
4)局部符号,无视他吧!也就是调试的时候有用
5)行号,同上。。。。
【符号表】
好吧,我们用同样的方式介绍符号表,,首先是他的C语言定义,同样的在elf.h 中
接下来就是对应的一张 各个成员的作用
然后就是重点地方的详细介绍了
1】符号类型和绑定信息 st_info
这个成员其实记录了2个东西 ,,低4位表示符号类型,高28位表示绑定的信息,这2个配合才是st_info 的具体意义,如下
2】符号所在段 st_shndx
这个特别值得注意
1)如果符号定义在本目标文件中,那么这个成员表示符号所在的段在段表中的下标,
2)如果不是,那么应该是下面的含义
3】符号值 st_value ,这个值其实含义有好多种呢,
1)在目标文件中,如果是符号的定义并且符号不是"COMMON"类型,则表示符号在段中的偏移
2)在目标文件中,如果是"COMMON"类型,则表示符号的对齐属性
3)在可执行文件中,表示虚拟地址。
4】有了这些知识,在来看看我们的 simp.o
利用 readelf -s simp.o
具体的分析我就不写了。。
【特殊符号】
其实有很多符号我们没有定义,我们也可以直接使用,ld链接器会帮你处理,称之为“特殊符号”,下面的C语言例子中使用了特殊符号
#include <stdio.h>
extern char __executable_start[];
extern char etext[], _etext[], __etext[];
extern char edata[], _edata[];
extern char end[], _end[];
int main()
{
printf("Executable start 0x%x\n", __executable_start);
printf("Text End 0x%x 0x%x 0x%x\n", etext, _etext, __etext);
printf("Data End 0x%x 0x%x\n", edata, _edata);
printf("Executable End 0x%x 0x%x\n", end, _end);
return 0;
}
看下编译执行后的输出。。。。