美文网首页
第七章-链接(2)

第七章-链接(2)

作者: CSU_IceLee | 来源:发表于2018-12-16 17:06 被阅读8次

    可执行目标文件

    image.png

    可执行目标文件还包括了程序的入口点,即第一条指令的地址。
    各个段会被映射到连续的内存区域,段头部表描述了这种映射关系。

    加载可执行目标文件

    将程序复制到内存并运行的过程叫加载。


    image.png

    堆是从低地址向高地址分配空间,而栈是从高地址向低地址分配空间。
    从地址2^48开始,是为内核中的代码和数据保留的(操作系统驻留在内存的部分)。

    动态链接共享库

    静态库是在链接的时候合并到可执行目标文件里面,这样有一些缺点:

    • 每次更新了目标文件都需要重新链接
    • 多个程序都需要使用标准库函数,都需要进行链接并载入内存,是对内存空间的浪费
      共享库就是为了解决这部分问题而产生的。共享库可以在运行或加载时,加载到任意的内存地址,并和一个内存中的程序链接起来。这个过程称为动态链接,由动态链接器来执行。
      共享库也叫共享目标,Linux中通常用.so后缀表示,Windows被称为DLL。
      编译共享目标文件:
      gcc -shared -fpic -o libvector.so addvec.c multvec.c
      这样生成的libvector.so就是共享目标文件,再将文件链接到其他程序中:
      gcc -o prog main.c ./libvector.so
      这样prog程序在运行的时候就会和libvector.so链接。在创建可执行文件时,静态执行一些链接,在程序加载时,动态完成链接过程。链接器没有复制so文件的代码和数据节,只复制了一些重定位和符号表信息,使得在运行时可以对libvector.so中的代码和数据的引用。

    从应用程序中加载和链接共享库

    上面那种方式要在编译时指定共享库,而另外一种方式是在应用程序中,通过接口直接加载和链接共享库,在编译时无需指定。
    步骤:

    //加载共享库
    handle = dlopen("filename",flag);
    //链接共享库
    func = dlsym(handle,"func_name");
    func();
    //关闭共享库
    dlclose(handle);
    //产生的错误
    dlerror();
    
    image.png

    库打桩机制

    类似于设计模式中的代理模式,允许截获对共享库函数的调用,取而代之执行自己的代码。打桩可以发生在编译时、链接时或当程序被加载和执行的运行时。即定义一个完全一样的函数接口,在实现的时候通过调用真正的函数完成功能,同时可以记录调用的参数与结果等。

    相关文章

      网友评论

          本文标题:第七章-链接(2)

          本文链接:https://www.haomeiwen.com/subject/zejxkqtx.html