动态链接

动态链接

与动态链接相关的节

程序头表中包含着对于所有跟动态链接相关的节的概括节.dynamic,.dynamic会包含与动态链接相关的部分,它的存在充分保证了动态链接器的首地址可以安排在用户空间任意一个地方

根据.dynamic节中的entry种类,动态链接器会做出不同的处理,几个主要的entry种类如下

  • needed 依赖库

  • hash 符号字符串哈希表

  • RELA 符号重定位即.rela.dyn节

  • JMPREL 符号重定位即.rela.plt节

  • ...... 其他节比如.dysym记录了需要动态符号的信息内容,.dynstr是这些符号的字符串表,通过.dynsym的name字段查询

.rela.dyn节和.rela.plt节都是需要对其内容重定位的地址,这些都需要函数在动态链接器的地址加上动态链接器或者可执行程序的基地址,然后再填入对应的内存中,以便访问时取出该地址进行访问

动态链接过程

自举

动态链接器会先进行在dl_start中自举,读取.dynamic节对自己的符号进行重定位,它自己的基地址是通过pc寄存器与查询到的dl_start符号差值得到的 自举过后才能正常调用其他函数

加载用户程序

用户程序的基地址靠内核传参AT_BASE得到

它会将要执行的程序根据需要加载进来,内核会传递phdr参数,如果phdr参数与动态链接器的phdr一致,则判定内核还没加载可执行文件,会读取内核传递的argv[0]作为要执行的文件路径,并将该文件通过mmap映射到用户空间中

如果phdr参数与动态链接器的phdr不一致,则判定内核加载了可执行文件,跳过这个步骤

加载依赖库

读取可执行程序的.dynamic节中needed的entry,加载其他依赖库,同样是通过mmap系统调用将库映射到用户空间中,需要注意的是此处的依赖库会从内核传递的环境变量LD_LIBRARY_PATH的路径下查找

dlopen

dlopen可以打开一个共享库,执行时其实跟加载依赖库时做法差不多

Last updated