可执行的共享库

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

$ ./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: . 

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

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

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

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