Page 2 of 2

Re: 浅析Linux动态链接的全过程

Posted: 2025-03-25T03:17:40+00:00
by 擎天殿
共享库的创建和安装

为什么会产生共享库?大量的程序开始使用动态链接机制,导致系统里面存在数量极为庞大的共享对象,如果没有很好的方法将这些共享对象组织起来,整个系统的共享对象文件则会散落在各个目录下,造成巨大困难,所以操作系统一般会对共享对象的目录组织和使用方法有一定的规则,即共享库。
共享库的创建

与创建共享对象过程一致,需要两个参数-shared表示输出结果是共享库类型的,-fPIC表示是地址无关代码技术来产生输出文件,
构造和析构函数

很多时候在共享库被加载的时候能够进行一些初始化工作,比如打开文件,网络连接等等,使得共享库里面的函数接口能够正常工作,GCC提供了一种共享库的构造函数,只要在函数声明时加上__attribute__((constructor))的属性,即指定该函数为共享库构造函数,拥有这种属性的函数会在共享库加载时被执行,即在程序的main函数之前执行。

如果我们使用dlopen()打开共享库,共享库构造函数会在dlopen()返回之前被执行。

与共享库构造函数相对于的是析构函数__attribute__((destructor))的属性,这种函数会在main()函数执行完毕之后执行(或者是程序调用exit()时执行)

如果共享库是运行时加载的,那么使用dlclose()来卸载共享库时,析构函数将会在他返回之前执行。

Code: Select all

void __attribute__((constructor)) init_function(void);
void __attribute__((constructor)) fini_function(void);

Re: 浅析Linux动态链接的全过程

Posted: 2025-03-25T03:19:49+00:00
by 擎天殿
总结

写了那么多,知识点貌似有点分散,但是每一个部分都有他的作用,先来口语简略的说一下不在显示运行时链接的程序执行过程(显示链接无法就是把主动权交给了程序,被动转为 了主动,差别不大)。

源程序(.c)经过预处理、编译(.s)、汇编(.o)形成对象文件(或者叫目标文件),接着进行链接(在.interp段中指定链接器地址,生成重定位表.rel.dyn和.rel.plt,生成字符表。symtab,生成.got(直接存放绝对地址)和.got.plt段(存放假地址),PLT存放所有函数的假地址,初始化堆栈信息,此时都是虚存),执行文件,链接器进行自举和重定位,然后进入进程地址空间,读取进程堆栈信息,合并一个全局符号表,因为是PIC技术,所以暂时不加载函数引用。当进行函数引用的时候,寻找相关函数位置,进程代码进入到GOT表中寻找,无法找到,则跳转到PLT表的地址,PLT通过dl_runtime_close()函数找到地址并放入下标为n的位置,并填入GOT中,代码直接从GOT表中即可得到该函数地址,并执行该函数。

以上