Linux动态库加载研究

        引子(ELF文件格式)

        在分析Linux动态库加载过程之前,首先介绍Linux系统中的可执行与可链接格式(Executable and Linkable Format,ELF),该文件格式是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface,ABI)而开发和发布的,也是Linux的主要可执行文件格式,Linux下的执行体、so、o和bin等文件都符合该格式。

        ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。ELF文件格式的结构如下图所示,实际上一个ELF文件中不一定包含全部内容,而且它们的位置也未必如图所示这样安排,只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。

         ELF文件的相关信息可以通过readelf命令(有关readelf命令详情可在网上查询,本文不详细讲)来查看,其中文件中有一个.dynamic的节,里面的信息可通过命令: readelf –d xxx.so来查看,例如:readelf  –d  libProtoPackLib.so来查看libProtoPackLib.so文件的.dynamic节信息,如下图所示:

 

         在该段中记录有依赖的动态库(NEEDED)信息和动态库搜索路径(RPATH)。

        动态库加载机制

         Linux操作系统中对于动态链接库都是利用ld-linux.so.2去加载的,加载过程如下:

         总体来说,就是在加载一个动态库之前会按照ELF文件格式,去读取这个动态库还依赖的动态库,并读取动态库搜索路径(如果这个RPATH存在),并以该搜索路径为起点,依次搜索LD_LIBRARY_PATH,/etc/ld.so.conf中指定的路径,最后到/lib或者/lib64中去搜索,在其中任意一个位置搜索到后完成依赖库的加载后便返回。

         动态库搜索路径指定

  1. 通过RPATH指定搜索路径

       只需要在编译生成动态库的连接选项中增加-rpath选项即可,多个搜索路径以::分隔,以CodeBlocks平台为例,如下所示:

               其格式为:-Wl,-rpath=serch path1: serch path2

               加入该选项后,最终执行的链接命令最终的编译指令就是:

                gcc test.c -lhello -L . -Wl,-rpath serch path1: serch path2

               在编译生成共享库后就会将serch path1和serch path2写入对应的.dynamic节中。

​​​​​​​        2. 通过LD_LIBRARY_PATH指定搜索路径

         可以通过echo $ LD_LIBRARY_PATH查看当前的LD_LIBRARY_PATH

         临时性的指定,可以执行命令来增加一个路径/tmp

        export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tmp 

        若需要持久性地增加一个路径/tmp,可修改~/.bashrc或~/.bash_profile或系统级别的/etc/profile等文件,在其文件中增加:

        export LD_LIBRARY_PATH=/tmp:$LD_LIBRARY_PATH

        然后保存改文件,并执行

        source .bashrc 或者source .bash_profile或者source/etc/profile

        修改了哪个文件对改文件执行source生效。

​​​​​​​        3. 通过/etc/ld.so.conf指定搜索路径

       打开该文件在其中增加需要指定的路径如:    /tmp

        然后执行ldconfig命令,使得修改生效,ldconfig 命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件.缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。​​​​​​​

        4. 将动态库拷贝至/lib或者/lib64

        将需要的动态库直接拷贝至该目录下即可。

 

 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

saint198

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值