第七章-链接(2)

可执行目标文件

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

库打桩机制

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容