首页 > 系统相关 >Linux动态库soname的使用

Linux动态库soname的使用

时间:2023-01-17 16:33:07浏览次数:44  
标签:soname libbar libz alisentry so.1 so Linux lib64 动态

通过一个简单的例子,体验一下Linux动态库soname的使用。

假设有一个动态库:libbar.so.1.1.0,其对应的三个名称如下。

  1. realname:libbar.so.1.1.0
  2. soname:libbar.so.1
  3. linkname:libbar.so

先生成一个libbar.so,通过-Wl,-soname指定soname为libbar.so.1

$ g++ -fPIC -shared -Wl,-soname,libbar.so.1 -o libbar.so.1.1.0

$ readelf -d libbar.so.1.1.0

Dynamic section at offset 0x520 contains 24 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libbar.so.1]
 0x000000000000000c (INIT)               0x398
 0x000000000000000d (FINI)               0x4d8
 0x000000006ffffef5 (GNU_HASH)           0x120
 0x0000000000000005 (STRTAB)             0x248
 0x0000000000000006 (SYMTAB)             0x158
 0x000000000000000a (STRSZ)              160 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x2006f8
 0x0000000000000002 (PLTRELSZ)           24 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x380
 0x0000000000000007 (RELA)               0x320
 0x0000000000000008 (RELASZ)             96 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x300
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x2e8
 0x000000006ffffff9 (RELACOUNT)          1
 0x0000000000000000 (NULL)               0x0

使用ldconfig生成soname对应的符号链接文件。

$ ldconfig -n /tmp/

$ ll libbar.so.1
lrwxrwxrwx 1 henshao users 15 Nov 28 01:00 libbar.so.1 -> libbar.so.1.1.0

接着写一个程序使用libbar.so。

#链接需要linkname,否则会提示找不到动态库。
$ gcc foo.c -o foo -L. -lbar
/usr/bin/ld: cannot find -lbar
collect2: ld returned 1 exit status

#生成linkname的服务链接文件
$ ln -s libbar.so.1 libbar.so

#这次编译能成功
$ gcc foo.c -o foo -L. -lbar

#可见foo依赖的是soname,而不是linkname。
$ ldd foo
    linux-vdso.so.1 =>  (0x00007fffa27ff000)
    /opt/alisentry/$LIB/alisentry_exec.so => /opt/alisentry/lib64/alisentry_exec.so (0x00007fabfda17000)
    /opt/alisentry/$LIB/alisentry_kill.so => /opt/alisentry/lib64/alisentry_kill.so (0x00007fabfd814000)
    libbar.so.1 => not found
    libc.so.6 => /lib64/libc.so.6 (0x00007fabfd4b0000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fabfd2ac000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fabfdc1d000)

为什么主程序会依赖soname,而不是linkname和realname?这是因为Linux的动态库的命名格式是libbar.so.x.y.z,最后一个z版本的变动一定是兼容的。y版本升级一般向前兼容。所以这个y和z不能写死。x版本变动一般是不兼容升级。所以使用soname是最为合理的。

再做一个有意思的测试。将libbar.so.1重命名为aaa,然后同样创建aaa的符号链接为libbar.so

$ ll libbar.so* aaa
lrwxrwxrwx 1 henshao users    3 Nov 28 01:28 libbar.so -> aaa
lrwxrwxrwx 1 henshao users   15 Nov 28 01:27 aaa -> libbar.so.1.1.0
-rwxr-xr-x 1 henshao users 5301 Nov 28 01:27 libbar.so.1.1.0

有趣的是,foo依然知道依赖libbar.so.1,而不是aaa

$ gcc foo.c -o foo -L. -lbar

$ ldd foo
    linux-vdso.so.1 =>  (0x00007fff19ce7000)
    /opt/alisentry/$LIB/alisentry_exec.so => /opt/alisentry/lib64/alisentry_exec.so (0x00007fb07c389000)
    /opt/alisentry/$LIB/alisentry_kill.so => /opt/alisentry/lib64/alisentry_kill.so (0x00007fb07c186000)
    libbar.so.1 => not found
    libc.so.6 => /lib64/libc.so.6 (0x00007fb07be22000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fb07bc1e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fb07c58f000)

在Linux系统里面找个实际的例子看看。wget依赖libz.so.1。

$ ldd /usr/bin/wget
    linux-vdso.so.1 =>  (0x00007fff631ff000)
    /opt/alisentry/$LIB/alisentry_exec.so => /opt/alisentry/lib64/alisentry_exec.so (0x00007fe75c93e000)
    /opt/alisentry/$LIB/alisentry_kill.so => /opt/alisentry/lib64/alisentry_kill.so (0x00007fe75c73b000)
    libssl.so.6 => /lib64/libssl.so.6 (0x00007fe75c4e1000)
    libcrypto.so.6 => /lib64/libcrypto.so.6 (0x00007fe75c190000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fe75bf8c000)
    libz.so.1 => /usr/lib64/libz.so.1 (0x00007fe75bd78000)
    librt.so.1 => /lib64/librt.so.1 (0x00007fe75bb6f000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fe75b816000)
    libgssapi_krb5.so.2 => /usr/lib64/libgssapi_krb5.so.2 (0x00007fe75b5e8000)
    libkrb5.so.3 => /usr/lib64/libkrb5.so.3 (0x00007fe75b353000)
    libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fe75b150000)
    libk5crypto.so.3 => /usr/lib64/libk5crypto.so.3 (0x00007fe75af2b000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fe75cb44000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe75ad10000)
    libkrb5support.so.0 => /usr/lib64/libkrb5support.so.0 (0x00007fe75ab07000)
    libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fe75a905000)
    libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fe75a6f0000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fe75a4d7000)
    libsepol.so.1 => /lib64/libsepol.so.1 (0x00007fe75a291000)

$ll /usr/lib64/libz.so*
lrwxrwxrwx 1 root root 19 Dec  3  2015 /usr/lib64/libz.so -> ../../lib64/libz.so
lrwxrwxrwx 1 root root 21 Dec  3  2015 /usr/lib64/libz.so.1 -> ../../lib64/libz.so.1
lrwxrwxrwx 1 root root 25 Dec  3  2015 /usr/lib64/libz.so.1.2.3 -> ../../lib64/libz.so.1.2.3

$ ll /lib64/libz*
lrwxrwxrwx 1 root root    13 Dec  3  2015 /lib64/libz.so -> libz.so.1.2.3
lrwxrwxrwx 1 root root    13 Dec  3  2015 /lib64/libz.so.1 -> libz.so.1.2.3
-rwxr-xr-x 1 root root 83280 May 28  2014 /lib64/libz.so.1.2.3

$ readelf -d /usr/lib64/libz.so.1.2.3

Dynamic section at offset 0x139f8 contains 21 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libz.so.1]
 0x000000000000000c (INIT)               0x1b48
 0x000000000000000d (FINI)               0xc958
 0x000000006ffffef5 (GNU_HASH)           0x158
 0x0000000000000005 (STRTAB)             0xdd8
 0x0000000000000006 (SYMTAB)             0x3e8
 0x000000000000000a (STRSZ)              1148 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x213bc8
 0x0000000000000002 (PLTRELSZ)           1200 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x1698
 0x0000000000000007 (RELA)               0x1368
 0x0000000000000008 (RELASZ)             816 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x1328
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x1254
 0x000000006ffffff9 (RELACOUNT)          26
 0x0000000000000000 (NULL)               0x0

 

标签:soname,libbar,libz,alisentry,so.1,so,Linux,lib64,动态
From: https://www.cnblogs.com/lidabo/p/17058113.html

相关文章

  • Linux执行SQLSERVER语句的简单方法
    背景因为WTF的原因.经常有人让执行各种乱七八槽的删除语句因为产品支持了10多种数据库.这个工作量非常复杂.为了简单起见,想着能够批量执行部分SQL.其他的都处理过了......
  • Linux动态链接库.so文件的命名及用途总结
    我们在linux下开发项目,有时会对外提供动态库,像***.so.1.0.0这样子的文件,另外提供相应的头文件。用户拿到动态库和头文件说明,就可以使用动态库里的function。那随之而来......
  • linux添加dns配置
    named.conf是DNS服务器bind的配置文件resolv.conf是系统的DNS配置系统的DNS配置1、编辑DNS配置文件vim/etc/resolv.conf没有resolv.conf文件,touch创建一个2......
  • Linux应用程序启动过程的静态分析
    这是一篇分析Linux应用程序启动过程的文章,从ELF的基本格式,段和节如何组成一个ELF可执行文件,到应用程序的加载和启动运行的流程做了一个完整的介绍,最后也稍稍涉及到安全性相......
  • openkylin (linux内核)微信(wechat)安装介绍
    1.Openkylin介绍Openkylin是麒麟软件公司主导的开源操作系统,正在逐步与该公司的银河麒麟操作系统保持基础库的同源。时至2022年12月,开源操作系统Openkylin的默认软件商......
  • Linux部署Java项目【reggie_take_out】
    方式1:手工命令https://www.bilibili.com/video/BV13a411q753/?p=139方式2:shell脚本自动https://www.bilibili.com/video/BV13a411q753/?p=140https://www.bilibili.com......
  • 小满Linux(第十章Nginx-Go-Access-日志分析器)
    将我们的Linux服务器设置为中文版$localectlset-localeLANG=zh_CN.UTF8重启服务器即可GoAccess是一款开源、实时,运行在命令行终端下的web日志分析工具。该工具提供快速......
  • linux jar包自启动
    https://blog.csdn.net/qq_34200979/article/details/124117675?spm=1001.2014.3001.55011、编写启动脚本jarrun.shexportJAVA_HOME=/usr/lib/jdk1.8.0_321##jdk路径ex......
  • 如何获取LINUX主机所有的IP
    上个月写了一篇文章,介绍了如何获取本机的第一个IP。后面我再想是否有办法获取LINUX主机的所有的IP,通过查询资料,找到了方法。借助对象ifaddrs以及getifaddrs函数可以实现这......
  • React: 动态添加样式
    问题背景在软件开发过程中,经常会出现动态添加style或className,比如:同一个表格组件在A处调用,需要固定前四列数据,B处调用则不用,那这时候,动态添加元素就派上了用场。解决方......