zoukankan      html  css  js  c++  java
  • 静态链接过程

    转自:博客1, http://chuquan.me/2018/06/03/linking-static-linking-dynamic-linking/

    1.为什么需要重定位?

    执行函数:

    程序的运行过程就是CPU不断的从内存中取出指令然后执行的过程。

    假设对g_num做++操作,那么汇编指令:

    call 0x4004fd    #地址为函数add在内存中的地址,调用时会跳转到0x4004fd来执行指令函数add对应的机器指令
    mov 0x400fda %eax   #将0x400fda地址的内容放到eax寄存器中,g_num的地址就是0x400fda
    add $0x1 %eax   #将寄存器内容+1

    那么地址从哪里获取?确定程序运行时地址的过程就是 重定位(Relocation)。

    2.编译为 .o文件的过程

    目标文件.o包括:

    1. 数据段:全局变量的定义
    2. 代码段:所有函数的定义
    3. 符号表:对外部变量的引用

    编译过程可以确定:

    • 定义在该源文件中函数的内存地址
    • 定义在该源文件中全局变量的内存地址

    //都是针对本文件内部的相对地址

    而如果针对引用其他文件中定义的变量或函数,那么编译时就将调用的地址设置为空,并且生成一条记录,之后的任务交给链接器。

    例如:

    // a.c
    extern int shared;//引用了其他文件中定义的全局变量
    
    int main() {
        int a = 100;
        swap(&a, &shared);//引用了其他文件中定义的函数
    }
    // b.c
    int shared = 1;
    
    void swap(int *a, int *b) {
        *a ^= *b ^= *a ^= *b;
    }

     那么在编译为汇编文件.i时,调用其他文件中的函数,汇编指令为空地址,表示不确定:

    call 0x000000

     并且生成一条记录放在.rel.text中,对外部定义的全局变量的使用,放在.rel.text中,链接器根据上述两者内容填写空白位置。

    .o文件内容

    对外部函数的引用放在.rel.text中,对外部全局变量的引用放在.rel.data段中。

    编译过程确定了该源文件中函数和变量的相对地址,以及引用其他文件的相对地址,需要链接时确定的信息放在.rel.data/.rel.text中,以修正地址。

    3.链接器的工作

    3.1 重定位第一个过程:链接合并段

    链接器会将所有需要的目标文件.o合并,即将对应段合并,这样就能确定相对地址,以更新目标文件中的相对地址。

    上图中,蓝色部分表示为代码段,依次合并;

    黄色是数据段,主要观察数据段的相对地址变化,目标文件2经过合并更新相对地址后是6,目标文件3经过合并更新相对地址后是8.

    相对地址 + offset(偏移) = 最终内存地址

    在合并时会产生偏移。段的偏移只有在链接的时候才能确定,因为连接时才会发生段的合并,确定最终地址。编译过程是无法确定的。

    3.2 引用符号重定位

    已经确定了相对地址和偏移,确定了变量和函数的最终内存地址,所以就可以更新.rel.data/.ref.text的最终值。

    其中rel是Relocation Table的缩写,保存着需要重定位的符号,即重定位表。

    4.#include的所有都会被包含?

    可以认为在静态编译时,形成可执行文件时,会将头文件中的函数也一并有个副本,进行段合并,在代码段合并,共同生成可执行文件。

    即每生成一个可执行文件,就会有一份函数的拷贝,在调用时,比如说scanf这样,直接call 最终内存地址即可。

  • 相关阅读:
    suse linux编译安装GCC报错
    suse linux 编译安装Apache时报“APR NOT FOUND”的解决方法
    LoadRunner监控Windows和Linux常见问题
    LR报-27727错误解决办法
    主机在virtualbox在NAT方式SSH访问
    清除hao123浏览器劫持小尾巴病毒
    在CentOS上,Servlet出现java.lang.NoClassDefFoundError
    构建第一个SSH的maven项目
    关于Oracle数据库sys用户登入的解惑
    ip route-static 命令的参数
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/15361938.html
Copyright © 2011-2022 走看看