2013-01-12 9 views
5

dlopen(NULL, ...)を実行し、静的にコンパイルされたバイナリのシンボルを取得する予定はありますか?スタティックバイナリにdlsymを使用

たとえば、プログラムが動的にコンパイルされ、-rdynamicを使用すると、次のコードでシンボルを取得できます。 foo.cため

$ gcc -static -o foo foo.c -ldl -rdynamic 
/tmp/cc5LSrI5.o: In function `main': 
foo.c:(.text+0x3a): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking 
$ ./foo bar 
/lib/x86_64-linux-gnu/: cannot read file data: Is a directory 

ソースは、次のとおりです:

#include <dlfcn.h> 
#include <stdio.h> 

int foo() { printf("In foo!\n"); } 
int bar() { printf("In bar!\n"); } 

int main(int argc, char**argv) 
{ 
    void *handle; 
    handle = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL); 
    if (handle == NULL) { 
    fprintf(stderr, "%s\n", dlerror()); 
    return 1; 
    } 

    typedef void (*function)(); 
    function f = (function) dlsym(handle, argv[1]); 
    if (f == NULL) { 
    fprintf(stderr, "%s\n", dlerror()); 
    return 2; 
    } 
    f(); 

    return 0; 
} 

答えて

4

のdlopen(NULLを実行しているのいずれかの希望がある

$ gcc -o foo foo.c -ldl -rdynamic 
$ ./foo bar 
In bar! 

はしかし-staticで、私は不可解なエラーメッセージが表示されます。 ..)と静的にコンパイルされたバイナリのシンボルを取得する?ほとんどのUNIX上で

あなたも同時に-static-ldlにリンクすることはできません。 glibcを使用することはできますが、そうすることの有用性はと非常にです。基本的に、この機能は/etc/nsswitch.confをサポートするためだけに存在し、それ以外のものは存在しません。

ポイントがありませんダイナミックルックアップしています。

foo,barまたはbazのいずれかをコマンドライン引数に応じて呼び出そうとしている場合は、

extern void foo(void) __attribute((weak)); 

if (&foo != 0) { 
    // foo was linked in, call it 
    foo(); 
} 
:あなたはそれがでリンクされている場合、「多分」 fooを呼び出し、それ以外何もしないようにしようとしている場合

struct { const char *fname, void (*fn)(void) } table[] = 
    { {"foo", &foo}, {"bar", &bar}, ...}; 

for (int i = 0; i < ...; ++i) 
    if (strcmp(argv[1], table[i].fname) == 0) 
    // found the entry, call it 
    (*table[i].fn)(); 

、その後、弱参照を使います

関連する問題