【问题标题】:Executable shared libraries可执行的共享库
【发布时间】:2011-08-01 13:48:52
【问题描述】:

大多数时候,当你编译一个共享库时,执行它是没有意义的,这样做没有任何用处:

$ ./libfoobarbaz.so
Segmentation fault

然而,当 glibc 被执行时,GNU 的人已经能够坚持一些输出:

$ /lib/libc.so.6
GNU C Library (Debian EGLIBC 2.11.2-10) stable release version 2.11.2, by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.5.
Compiled on a Linux 2.6.32 system on 2011-01-23.
Available extensions:
    crypt add-on version 2.1 by Michael Glad and others
    GNU Libidn by Simon Josefsson
    Native POSIX Threads Library by Ulrich Drepper et al
    BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

虽然这种特殊用途对我来说似乎是老生常谈,但他们是如何实现创建一个也可作为工作可执行文件的共享库的?

【问题讨论】:

标签: c shared-libraries


【解决方案1】:

这里的技巧是,可执行文件和共享对象库使用与 libc.so 相同的名为 ELF 的格式,并与 crt0 中的代码协作.o(在 *nixes 上)是编译器的一部分,实际上负责设置运行时环境,然后调用正确的 int main(...) 函数。如果没有链接到 libc.socrt0.o,只有 int main(...) 的程序将不会执行。从技术上讲,可以将 main 函数设置为可执行入口点,但是像这样启动程序将不会接收命令行参数,没有环境等,这都是标准的责任运行时库libc.so

所以libc.so,还负责准备int main(...) 函数的调用,可以很容易地确定它是否被其他程序链接,或者它是否“独立”。如果进程通过 libc.so 入口点启动,它将显示此消息,然后退出。只有当进程通过可执行二进制入口点启动时,二进制通过那个神奇的 crt0.o 接收该入口点,该进程才会像往常一样运行。

【讨论】:

    【解决方案2】:

    答案在于名称“可执行和链接格式”。相同的文件格式用于可执行文件和库。

    【讨论】:

      【解决方案3】:

      有一个关于这个主题的操作指南here。原理是在库中定义一个入口点,并用解释器的路径名填充 ELF 文件的 interp 部分(例如 /lib/ld-linux.so.2)。

      【讨论】:

        猜你喜欢
        • 2015-09-05
        • 2014-01-14
        • 2021-10-25
        • 2019-11-16
        • 2014-10-06
        • 2022-01-19
        • 1970-01-01
        • 2023-03-15
        • 2012-08-13
        相关资源
        最近更新 更多