2016-04-18 12 views
14

Was genau tut (oder --export-dynamic auf der Linker-Ebene) und wie bezieht es sich auf die Symbolsichtbarkeit, wie durch die -fvisibility* Flags oder Sichtbarkeit pragma s und __attribute__ s definiert?Was genau macht `-rdynamic` und wann genau wird es benötigt?

Für --export-dynamic, ld(1) erwähnt:

... Wenn Sie „dlopen“ verwenden, um ein dynamisches Objekt zu laden, die zurück auf die Symbole, die durch das Programm definiert nachschlagen muss, anstatt eine andere dynamische Objekt, dann benötigen Sie wahrscheinlich , um diese Option zu verwenden, wenn Sie das Programm selbst verknüpfen. ...

Ich bin mir nicht sicher, ob ich das vollständig verstehe. Könnten Sie bitte ein Beispiel geben, das ohne nicht funktioniert, aber damit macht?

bearbeiten: ich ein paar Dummy-Bibliotheken tatsächlich versucht Kompilieren (einzelne Datei, Multi-Datei, verschiedene -O Ebenen, einige Inter-Funktionsaufrufe, einige versteckte Symbole, einige sichtbar), mit und ohne -rdynamic, und bis jetzt habe ich byte-identischen Ausgänge bekommen (wenn alle anderen Flags natürlich konstant gehalten werden), was ziemlich rätselhaft ist.

Antwort

16

Hier ist ein einfaches Beispielprojekt zur Veranschaulichung der Verwendung von.

bar.c

extern void foo(void); 

void bar(void) 
{ 
    foo(); 
} 

main.c

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

void foo(void) 
{ 
    puts("Hello world"); 
} 

int main(void) 
{ 
    void * dlh = dlopen("./libbar.so", RTLD_NOW); 
    if (!dlh) { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(EXIT_FAILURE); 
    } 
    void (*bar)(void) = dlsym(dlh,"bar"); 
    if (!bar) { 
     fprintf(stderr, "%s\n", dlerror()); 
     exit(EXIT_FAILURE); 
    } 
    bar(); 
    return 0; 
} 

Makefile

.PHONY: all clean test 

LDEXTRAFLAGS ?= 

all: prog 

bar.o: bar.c 
    gcc -c -Wall -fpic -o [email protected] $< 

libbar.so: bar.o 
    gcc -shared -o [email protected] $< 

main.o: main.c 
    gcc -c -Wall -o [email protected] $< 

prog: main.o | libbar.so 
    gcc $(LDEXTRAFLAGS) -o [email protected] $< -L. -lbar -ldl 

clean: 
    rm -f *.o *.so prog 

test: prog 
    ./$< 

Hier bar.c sein kommt eine gemeinsame Bibliothek libbar.so und main.c wird ein Programm, das dlopen s libbar und ruft bar() von dieser Bibliothek. bar() Aufrufe foo(), die in bar.c extern und in main.c definiert ist.

Also, ohne -rdynamic:

$ make test 
gcc -c -Wall -o main.o main.c 
gcc -c -Wall -fpic -o bar.o bar.c 
gcc -shared -o libbar.so bar.o 
gcc -o prog main.o -L. -lbar -ldl 
./prog 
./libbar.so: undefined symbol: foo 
Makefile:23: recipe for target 'test' failed 

Und mit -rdynamic:

$ make clean 
rm -f *.o *.so prog 
$ make test LDEXTRAFLAGS=-rdynamic 
gcc -c -Wall -o main.o main.c 
gcc -c -Wall -fpic -o bar.o bar.c 
gcc -shared -o libbar.so bar.o 
gcc -rdynamic -o prog main.o -L. -lbar -ldl 
./prog 
Hello world 
+0

Sie Beispiel ist es völlig klar, was die manpage bedeutet. Danke vielmals! – PSkocik