linux 动态链接器相关

linux下程序的链接方式分为两种:静态链接 动态链接。

静态链接就是在生成可执行文件的时候,把程序用到的各个库和目标文件链接到一块儿生成一个可执行文件。静态链接看起来很简单,但是有些不足。其中之一就对磁盘空间和内存空间的浪费。标准库中那些函数会被放到每个静态链接的可执行文件中,在运行的时候,这些重复的内容也会被不同的可执行文件加载到内存中去。同时,如果静态库有更新的话,所有可执行文件都得重新链接才能用上新的静态库。动态链接就是为了解决这个问题而出现的。

所谓动态链接就是在运行的时候再去链接。理解动态链接需要从两个角度来看,一是从动态库的角度,二是从使用动态库的可执行文件的角度。

动态库和普通的可执行文件一样,有代码段和数据段。为了实现动态库在不同程序之间的共享,需要做到不管动态库被装在到内存的什么位置,都不需要修改动态库代码段的内容,也就是要做到PICposition independent code),为了达到这个目的,动态库把变化的部分全部放到了数据段中,代码段采用相对定位的方式实现。

动态链接的程序由于用到了外部动态库中的函数和变量,因此不能直接运行,需要动态链接器帮助加载该可执行文件需要的外部动态库,并完成符号解析和变量的重定位,之后才会从入口点开始运行。


Linux下,这一过程大致如下。

假如我们要运行linuxls命令,在ls可执行文件的头部记录了动态链接器的路径,如:


$readelf -l /bin/ls


Elf file type is EXEC (Executable file)

Entry point 0x4048c5

There are 9 program headers, starting at offset 64


Program Headers:

  Type           Offset             VirtAddr           PhysAddr

                 FileSiz            MemSiz              Flags  Align

  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040

                 0x00000000000001f8 0x00000000000001f8  R E    8

  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238

                 0x000000000000001c 0x000000000000001c  R      1

      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000

                 0x000000000001bad4 0x000000000001bad4  R E    200000

  LOAD           0x000000000001bdf0 0x000000000061bdf0 0x000000000061bdf0

                 0x0000000000000864 0x00000000000016d0  RW     200000

  DYNAMIC        0x000000000001be08 0x000000000061be08 0x000000000061be08

                 0x00000000000001f0 0x00000000000001f0  RW     8

  NOTE           0x0000000000000254 0x0000000000400254 0x0000000000400254

                 0x0000000000000044 0x0000000000000044  R      4

  GNU_EH_FRAME   0x0000000000018cdc 0x0000000000418cdc 0x0000000000418cdc

                 0x0000000000000744 0x0000000000000744  R      4

  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000

                 0x0000000000000000 0x0000000000000000  RW     10

  GNU_RELRO      0x000000000001bdf0 0x000000000061bdf0 0x000000000061bdf0

                 0x0000000000000210 0x0000000000000210  R      1



其中/lib64/ld-linux-x86-64.so.2就是该系统用到的动态链接器,动态链接器本身也是一个可执行文件,相关参数如下:

Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]

  --list                list all dependencies and how they are resolved

  --verify              verify that given object really is a dynamically linked object we can handle

  --inhibit-cache       Do not use /etc/ld.so.cache

  --library-path PATH   use given PATH instead of content of the environment variable LD_LIBRARY_PATH

  --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names in LIST

  --audit LIST          use objects named in LIST as auditors


—list参数显示一个可执行文件用到的动态库列表,例如:

$/lib64/ld-linux-x86-64.so.2 --list /bin/ls

  linux-vdso.so.1 =>  (0x00007fffded4d000)

libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f9b1b3d3000)

libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f9b1b1ca000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9b1adff000)

libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f9b1ab92000)

libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9b1a98e000)

/lib64/ld-linux-x86-64.so.2 (0x00007f9b1b602000)

libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f9b1a788000)

libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9b1a56a000)


关于动态链接器的更多选项可以man ld.so来查看,例如想调试动态链接器工作的具体细节,可以通过设置LD_DEBUG环境变量来进行,

$LD_DEBUG=help ls

Valid options for the LD_DEBUG environment variable are:


  libs        display library search paths

  reloc       display relocation processing

  files       display progress for input file

  symbols     display symbol table processing

  bindings    display information about symbol binding

  versions    display version dependencies

  scopes      display scope information

  all         all previous options combined

  statistics  display relocation statistics

  unused      determined unused DSOs

  help        display this help message and exit

LD_DEBUGlibs的时候,可以查看动态库的搜索路径,如LD_DEBUG=libs ls





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值