Linux
為什麼以及如何執行某些共享庫,就好像它們是執行檔一樣?
在 32 位 Linux 系統上,呼叫此
$ /lib/libc.so.6
在 64 位系統上,這
$ /lib/x86_64-linux-gnu/libc.so.6
在 shell 中,提供如下輸出:
GNU C Library stable release version 2.10.1, 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.0 20090506 (Red Hat 4.4.0-4). Compiled on a Linux >>2.6.18-128.4.1.el5<< system on 2009-08-19. Available extensions: The C stubs add-on version 2.1.2. 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 RT using linux kernel aio For bug reporting instructions, please see: <http://www.gnu.org/software/libc/bugs.html>.
為什麼以及如何發生這種情況,以及如何在其他共享庫中做同樣的事情?
我查看了
/usr/lib
執行檔,發現/usr/lib/libvlc.so.5.5.0
. 執行它會導致分段錯誤。:-/
該庫具有
main()
函式或等效入口點,並且以這樣一種方式編譯,即它既可用作執行檔,也可用作共享對象。這是有關如何執行此操作的一個建議,儘管它對我不起作用。
這是關於 SO 的類似問題的另一個答案,我將無恥地抄襲、調整併添加一些解釋。
首先,我們範例庫的來源
test.c
:#include <stdio.h> void sayHello (char *tag) { printf("%s: Hello!\n", tag); } int main (int argc, char *argv[]) { sayHello(argv[0]); return 0; }
編譯:
gcc -fPIC -pie -o libtest.so test.c -Wl,-E
在這裡,我們正在編譯一個共享庫
-fPIC
(-pie``-Wl,-E
而且,雖然
file
會說它是一個共享對象,但它確實可以作為執行檔工作:> ./libtest.so ./libtest.so: Hello!
現在我們需要看看它是否真的可以動態連結。一個範常式序,
program.c
:#include <stdio.h> extern void sayHello (char*); int main (int argc, char *argv[]) { puts("Test program."); sayHello(argv[0]); return 0; }
使用
extern
使我們不必創建標題。現在編譯:gcc program.c -L. -ltest
在執行之前,我們需要添加
libtest.so
動態載入器的路徑:export LD_LIBRARY_PATH=./
現在:
> ./a.out Test program. ./a.out: Hello!
並將
ldd a.out
顯示連結到libtest.so
。請注意,我懷疑這就是 glibc 的實際編譯方式,因為它可能不像 glibc 本身那樣可移植(參見
man gcc
and開關)-fPIC
,-pie
但它展示了基本機制。有關真正的詳細資訊,您必須查看源 makefile。