2013-01-12 13 views
5

Czy jest jakaś nadzieja na uruchomienie dlopen(NULL, ...) i uzyskanie symboli statycznie skompilowanego pliku binarnego?Użyj dlsym na statycznym binarnym

Na przykład za pomocą następującego kodu mogę uzyskać symbole, jeśli program jest kompilowany dynamicznie i używam -rdynamic.

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

Ale z -static dostaję tajemniczy komunikat o błędzie:

$ 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 

Źródłem foo.c następująco:

#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; 
} 

Odpowiedz

4

Czy istnieje jakaś nadzieja prowadzenia dlopen (NULL,. ..) i uzyskanie symboli dla statycznie skompilowanego pliku binarnego?

nr

Na większości UNIX-ów nawet nie można powiązać z -static i -ldl w tym samym czasie. Korzystając z glibc, możesz, ale użyteczność tego jest ograniczona (very). Zasadniczo ta zdolność jest obecna tylko dla obsługi /etc/nsswitch.conf i nic więcej.

Istnieje również bez punktu w trakcie wykonywania dynamicznego wyszukiwania.

Jeśli chcesz zezwolić na wywołanie jednego z foo, bar lub baz w zależności od argumentów wiersza poleceń, po prostu wstaw do tabeli, np.

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)(); 

Jeśli próbujesz „może” wywołać foo jeżeli jest ona związana w, i nic poza tym, a następnie użyć słabe odwołania:

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

if (&foo != 0) { 
    // foo was linked in, call it 
    foo(); 
} 
Powiązane problemy