可执行的共享库

Del*_*ani 5 c shared-libraries

大多数情况下,当您编译共享库时,执行它是没有意义的,这样做没有任何用处:

$ ./libfoobarbaz.so
Segmentation fault
Run Code Online (Sandbox Code Playgroud)

但是,当执行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/>.
Run Code Online (Sandbox Code Playgroud)

虽然这个特殊用途对我来说似乎很普通,但他们是如何实现创建一个同时充当工作可执行文件的共享库的呢?

dat*_*olf 2

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

因此libc.so还负责准备函数的调用,int main(...)可以轻松确定它是否被其他程序链接,或者它是否是“独立的”。如果进程通过libc.so入口点启动,则会显示此消息,然后退出。仅当进程通过可执行二进制入口点启动时(二进制文件通过神奇的crt0.o接收该入口点),进程才会照常运行。