Fedora 17に含まれる実行可能な共有ライブラリ

一般的な共有ライブラリ(shared library。lib*.so)は実行可能ではありませんが、その構造は実行ファイルと同じELF形式で、大きな違いはありません。( →参考: http://mkosaki.blog46.fc2.com/blog-entry-107.html )
例外的に、glibc ( /lib64/libc-*.so ) は、ほぼあらゆる実行バイナリからリンクされる共有ライブラリですが、実はそれ自身が実行可能でもあります。
実際に実行してみると、自分自身のバージョンを表示して終了します。

% /lib64/libc-2.15.so
GNU C Library stable release version 2.15, by Roland McGrath et al.
Copyright (C) 2012 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.7.0 20120504 (Red Hat 4.7.0-4).
Compiled on a Linux 3.3.4 system on 2012-05-11.
Available extensions:
	Support for some architectures added on, not maintained in glibc core.
	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
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.


何となく、Fedora 17に、こういったライブラリがどれくらいあるか調べてみました。調べ方はこんな感じ。"(*)" というのはzshの拡張グロブで実行可能なものだけを取り出しています。なお、Fedora 17からは /lib64 は /usr/lib64 へのsymbolic linkになったので、/usr/lib64 だけで十分です。

zsh% for x in /usr/lib{,64}/*(*); do echo "Trying $x ..."; $x && echo $x >> /tmp/lib-exectable.txt; done

/tmp/lib-exectable.txt には、こんな感じのものが表示されました。...

/usr/lib/libc-2.15.so
/usr/lib/libpthread-2.15.so
/usr/lib64/libQtCore.so.4.8.1
/usr/lib64/libc-2.15.so
/usr/lib64/libpthread-2.15.so


いずれもバージョンやライセンスなどの情報を表示するようです。

% /usr/lib64/libQtCore.so.4.8.1
This is the QtCore library version 4.8.1
Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
Contact: Nokia Corporation (qt-info@nokia.com)

Build key:           x86_64 linux g++-4 full-config
Compat build key:    | x86_64 Linux g++-4 full-config |
Build date:          2012-05-10
Installation prefix: /usr/lib64/qt4
Library path:        /usr/lib64
Include path:        /usr/include
Processor features:  mmx sse sse2 cmov sse3 ssse3 sse4.1 sse4.2 avx

% /usr/lib64/libpthread-2.15.so
Native POSIX Threads Library by Ulrich Drepper et al
Copyright (C) 2006 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.
Forced unwind support included.


上記はSEGVなどにならずに正常終了したものだけですが、他にもメッセージを出力するものがありました。


まずは /usr/lib64/ld-2.15.so 。これはDynamic Linker/Loaderで、動的リンクされたプログラムに必要なライブラリを探し出してリンクしてくれるものです。動的リンクされたプログラムでは、一般にプログラムヘッダのインタープリタ情報(INTERP)にこの ld を指定しており、これを見てカーネルが起動時に ld を呼び出すことで、動的リンクを解決しています。(→参考: http://www.ibm.com/developerworks/jp/linux/library/l-dynamic-libraries/
直接実行した場合、 --list オプションをつけて実行バイナリを渡すと、リンクされているライブラリ一覧を表示したりするなど、ちゃんと機能があります。(ちなみに ldd コマンドの中身は、これをやってくれるシェルスクリプトです。)


次に、/usr/lib64/libSegFault.so 。これは、SEGVが発生するプログラムにLD_PRELOADなどを使ってリンクすると、SEGV発生時にレジスタなどの情報を表示してくれるライブラリです。(→参考: http://0xcc.net/blog/archives/000067.html )

直接実行すると、SEGV handlerを登録した後、リンクされたプログラムのmain関数を呼び出そうとして失敗し、自分自身がSEGVを起こすため、詳細情報を表示してくれます(笑)。

% /usr/lib64/libSegFault.so
*** Segmentation fault
Register dump:

 RAX: 0000000000000000   RBX: 0000000000000000   RCX: 0000000000000047
 RDX: 0000000000000000   RSI: 00007fb6a0b9d3f0   RDI: 00007fffb3c68d48
 RBP: 0000000000000000   R8 : 0000000000000000   R9 : 0000000000000000
 R10: 0000000000000008   R11: 0000000000000012   R12: 00007fb6a0b9ad00
 R13: 00007fffb3c66770   R14: 0000000000000000   R15: 0000000000000000
 RSP: 00007fffb3c66778

 RIP: 0000000000000001   EFLAGS: 00010202

 CS: 0033   FS: 0000   GS: 0000

 Trap: 0000000e   Error: 00000014   OldMask: 00000000   CR2: 00000001

 FPUCW: 0000037f   FPUSW: 00000000   TAG: 00000000
 RIP: 00000000   RDP: 00000000

 ST(0) 0000 0000000000000000   ST(1) 0000 0000000000000000
 ST(2) 0000 0000000000000000   ST(3) 0000 0000000000000000
 ST(4) 0000 0000000000000000   ST(5) 0000 0000000000000000
 ST(6) 0000 0000000000000000   ST(7) 0000 0000000000000000
 mxcsr: 1f80
 XMM0:  00000000000000000000000000000000 XMM1:  00000000000000000000000000000000
 XMM2:  00000000000000000000000000000000 XMM3:  00000000000000000000000000000000
 XMM4:  00000000000000000000000000000000 XMM5:  00000000000000000000000000000000
 XMM6:  00000000000000000000000000000000 XMM7:  00000000000000000000000000000000
 XMM8:  00000000000000000000000000000000 XMM9:  00000000000000000000000000000000
 XMM10: 00000000000000000000000000000000 XMM11: 00000000000000000000000000000000
 XMM12: 00000000000000000000000000000000 XMM13: 00000000000000000000000000000000
 XMM14: 00000000000000000000000000000000 XMM15: 00000000000000000000000000000000

Backtrace:
zsh: segmentation fault  /usr/lib64/libSegFault.so


もう一つ、/usr/lib64/libmemusage.so も出力を出した後SEGVしていました。これはmalloc等を乗っ取ってプログラムのメモリ使用量を調べてくれるツールのものです。(→ http://d.hatena.ne.jp/strkpy/20100317/1268801864 )

% /usr/lib64/libmemusage.so

Memory usage summary: heap total: 0, heap peak: 0, stack peak: 0
         total calls   total memory   failed calls
 malloc|          0              0              0
realloc|          0              0              0  (nomove:0, dec:0, free:0)
 calloc|          0              0              0
   free|          0              0
Histogram for block sizes:
zsh: segmentation fault  /usr/lib64/libmemusage.so

途中で死んでる…?