揭开连接器的面纱(上)

揭开连接器的面纱(上)_第1张图片

 

 

揭开连接器的面纱(上)_第2张图片

 

揭开连接器的面纱(上)_第3张图片

 

揭开连接器的面纱(上)_第4张图片

 

 链接器在合并各个目标文件中的段时需要将标识符的最终地址给确定了。这就是重定位的过程(确定各个段的最终起始地址以及各个标识符的地址)。

示例:

test.c如下:

揭开连接器的面纱(上)_第5张图片

func.c如下:

揭开连接器的面纱(上)_第6张图片

 

 编译func.c,并查看符号信息:

揭开连接器的面纱(上)_第7张图片

 

 可以看到func这个标识符相对于代码段的偏移位置为0。

g_pointer前面有一个C标志,意思是暂时还不知道该将g_pointer这个标识符放在哪一个段。能知道的就是这个标识符的大小为4个字节,就是前面显示的00000004。

 标识符的具体地址是没有确定的,因此目标文件不能执行。

编译test.o:

揭开连接器的面纱(上)_第8张图片

上图中的func意味着在test.c文件中用到了func这个标识符,但是不是在test.c中定义的。这个标识符具体位于哪里是不清楚的。

g_pointer和printf是同样的道理。

这三个表示符都不是在test.c中定义的。

上图中还可以看出,g_global位于bss段(由前面的B指示),相对于bss段的起始地址为0.

g_test位于data段(由前面的D标识),相对于data段的偏移为0.

main位于text段,具体地址不确定。

开始进行链接:

揭开连接器的面纱(上)_第9张图片

nm查看符号:

揭开连接器的面纱(上)_第10张图片

 

链接之后这些符号都有了地址。

链接器对这些符号进行了重定位(指的是给段中的各个标识符一个最终的地址)。

 

揭开连接器的面纱(上)_第11张图片

 

 

揭开连接器的面纱(上)_第12张图片

 

 

上面的情况是针对linux的(gcc编译)。

实验:

揭开连接器的面纱(上)_第13张图片

 

 

 

程序正常执行了。

使用objdump反编译:

 

 得到的文件内容如下:

揭开连接器的面纱(上)_第14张图片

 

找到main函数:

揭开连接器的面纱(上)_第15张图片查找main函数中第一条指令80483e4:

揭开连接器的面纱(上)_第16张图片

 

在第68行发现了。

 这意味着main可能被其他函数调用了。

上图中,在start将main函数的地址压入栈中,然后调用libc_start_main函数,其中压入栈中的main函数的地址作为libc_start_main的参数。

证明第一个被调用的函数是start:

我们只需要查看这个函数是不是在text段的起始地址处。

使用objdump -h查看可执行文件:

揭开连接器的面纱(上)_第17张图片

可以看到start函数的地址正好是text段的起始地址。

linux下程序加载的过程:

创建虚存空间。

将对应的段从可执行程序文件里面拷贝到内存当中。

执行程序(将pc指针指向代码段的第一条指令)。

 

上图中第65行将一个地址0x8048420压入栈中,现在我们来查找一下这个地址:

揭开连接器的面纱(上)_第18张图片

可以看到这个地址是libc_csu_init函数的地址,这个函数里面又调用了init函数。

接着查找init函数:

揭开连接器的面纱(上)_第19张图片

 

可以看到第20行调用了一个全局的构造函数(不是c++中的构造函数)。

 

经过分析可知,lic_start_main做了一些环境初始化的工作。

揭开连接器的面纱(上)_第20张图片

反汇编中第64行就是清理函数地址。

 

启动流程总结:

揭开连接器的面纱(上)_第21张图片

 

 

main函数只是c语言的入口函数,而不是整个程序加载执行的入口。

揭开连接器的面纱(上)_第22张图片

程序如下:

揭开连接器的面纱(上)_第23张图片

 

 先编译生成目标文件program.o。再执行链接。

正常执行和退出了。

使用nm查看符号:

揭开连接器的面纱(上)_第24张图片

 

 

使用objdump -h查看:

揭开连接器的面纱(上)_第25张图片

可以看到program的地址正好是text段的起始地址。可以看到没有了系统提供的启动函数。

 

揭开连接器的面纱(上)_第26张图片

 

揭开连接器的面纱(上)_第27张图片

使用了nostartfiles选项就不会使用系统中的启动文件。

 

转载于:https://www.cnblogs.com/wanmeishenghuo/p/9826286.html

你可能感兴趣的:(操作系统,c/c++)