一部の共有ライブラリが実行可能ファイルであるかのように実行される理由と方法は何ですか?

一部の共有ライブラリが実行可能ファイルであるかのように実行される理由と方法は何ですか?

32ビットLinuxシステムでは、以下を呼び出します。

$ /lib/libc.so.6

64ビットシステムの場合

$ /lib/x86_64-linux-gnu/libc.so.6

シェルから次の出力を提供します。

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実行結果が出ました。セグメンテーションエラー。 :-/

ベストアンサー1

ライブラリには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-fPIC-pie基本的なメカニズムを示しているからです。実際の詳細については、ソースmakefileを見てください。

おすすめ記事