【问题标题】:How is /usr/lib64/libc.so generated?/usr/lib64/libc.so 是如何生成的?
【发布时间】:2011-07-31 18:15:17
【问题描述】:
[root@xx test]# cat /usr/lib64/libc.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )

有人知道这种东西是怎么产生的吗?

【问题讨论】:

    标签: linux glibc ld


    【解决方案1】:

    这是在使用 Make 工具编译 glibc 时生成的。

    glibc 的 Makefile 中有一条规则(由 make install 开始),它只是将需要的行回显到一些临时文件 $@.new

    (echo '/* GNU ld script';\
     echo '   Use the shared library, but some functions are only in';\
     echo '   the static library, so try that secondarily.  */';\
     cat $<; \
     echo 'GROUP ( $(slibdir)/libc.so$(libc.so-version)' \
          '$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)$(libc-name))'\
          ' AS_NEEDED (' $(slibdir)/$(rtld-installed-name) ') )' \
    ) > $@.new
    

    然后这个文件被重命名为libc.so

    mv -f $@.new $@
    

    这是来自 Makefile 的评论,解释了一下:

    # What we install as libc.so for programs to link against is in fact a
    # link script.  It contains references for the various libraries we need.
    # The libc.so object is not complete since some functions are only defined
    # in libc_nonshared.a.
    # We need to use absolute paths since otherwise local copies (if they exist)
    # of the files are taken by the linker.
    

    我的理解是:libc.so.6 不完整,需要一些不能存储在共享库中的东西。因此,glibc 开发人员将这个东西移到了 glibc 的静态部分 - libc_nonshared.a。为了强制始终链接 libc.so.6libc_nonstared.a,他们创建了一个特殊的链接脚本,指示 ld 链接器在要求 -lc (libc) 时使用两者

    非共享部分是什么?让我们检查一下:

    $ objdump -t /usr/lib/libc_nonshared.a |grep " F "|grep -v __
    00000000 g     F .text  00000058 .hidden atexit
    00000000  w    F .text  00000050 .hidden stat
    00000000  w    F .text  00000050 .hidden fstat
    00000000  w    F .text  00000050 .hidden lstat
    00000000 g     F .text  00000050 .hidden stat64
    00000000 g     F .text  00000050 .hidden fstat64
    00000000 g     F .text  00000050 .hidden lstat64
    00000000 g     F .text  00000050 .hidden fstatat
    00000000 g     F .text  00000050 .hidden fstatat64
    00000000  w    F .text  00000058 .hidden mknod
    00000000 g     F .text  00000050 .hidden mknodat
    00000000 l     F .text  00000001 nop
    

    atexit()*stat*()mknod 函数。为什么?真的不知道,但这是glibc的事实。

    这是一些很长的解释http://giraffe-data.com/~bryanh/giraffehome/d/note/proglib,我引用了它的开头:

    The stat() family of functions and mknod() are special.  Their
    interfaces are tied so tightly to the underlying operating system that
    they change occasionally. 
    

    【讨论】:

    • 所以每次 glibc 更新时,它都会指向最新的实现版本。那些依赖于旧版本的二进制文件呢?如何确保这些二进制文件仍然适用于新的 glibc?
    • @compile-fan,编译后的二进制文件中有一个硬编码的 glibc 版本。使用 *stat 和 mknod 的不同 ABI 版本是内核的任务,因此如果您尝试使用来自 redhat 5 的程序(不是 rhel,而是来自 199x 的 linux),内核将模拟旧的 abi,​​因为它大多是向后兼容的。该程序的 Glibc 版本来自 redhat 5(例如 glibc-2.0 或更早版本;文件 libc.so.5),而不是 libc.so.6
    • 如果程序与旧版本的 libc.so.6 链接,并且使用了一些在较新的 glibc 中已过时或更改的库接口,则库必须提供多个版本的函数才能向后兼容。您可以使用 objdump -T /bin/echo|grep GLIBC 查看函数的版本化版本
    • @osgx ,我知道普通的.so文件使用ldconfig创建必要的链接并缓存到最新的共享库(即使用ln -s),为什么@987654341 @使用不同的方式(通过使用脚本文件/usr/lib64/libc.so)?
    • compile-fan,glibc很不一样,它是一个基础库,内部解决了很多问题。这是一个设计决定。
    【解决方案2】:

    在托管系统上,您可能需要安装 glibc-devel 和/或 glibc-devel.i686。

    【讨论】:

      猜你喜欢
      • 2014-12-29
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      相关资源
      最近更新 更多