2016-04-18 20 views
14

Chính xác thì -rdynamic (hoặc --export-dynamic ở cấp độ liên kết) làm gì và nó liên quan đến mức hiển thị biểu tượng như được xác định bởi cờ -fvisibility* hoặc mức độ hiển thị pragma s và __attribute__?Chính xác `-rdynamic` làm gì và khi nào cần thiết?

Đối --export-dynamic, ld(1) đề cập:

... Nếu bạn sử dụng "dlopen" để tải một đối tượng năng động mà cần phải tham khảo lại để những biểu tượng được xác định bởi các chương trình, chứ không phải là một số động khác đối tượng, sau đó bạn có thể sẽ cần để sử dụng tùy chọn này khi liên kết chính chương trình. ...

Tôi không chắc mình hoàn toàn hiểu điều này. Bạn có thể vui lòng cung cấp một ví dụ không hoạt động mà không có -rdynamic nhưng có làm việc với nó không?

Sửa: Tôi thực sự cố gắng biên soạn một vài thư viện hình nộm (tập tin duy nhất, đa tập tin, mức -O khác nhau, một số cuộc gọi liên chức năng, một số biểu tượng ẩn, một số có thể nhìn thấy), có và không có -rdynamic, và cho đến nay tôi đã nhận được byte giống hệt nhau kết quả đầu ra (khi vẫn giữ tất cả các cờ khác liên tục), điều này khá khó hiểu.

Trả lời

16

Đây là một ví dụ đơn giản để minh họa việc sử dụng -rdynamic.

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 
    ./$< 

Ở đây, bar.c được đến thư viện được chia sẻ libbar.somain.c trở thành chương trình dlopen s libbar và gọi bar() từ thư viện đó. bar() gọi foo(), nằm ngoài trong bar.c và được xác định trong main.c.

Vì vậy, không -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 

Và với -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

Ví dụ bạn làm cho nó hoàn toàn rõ ràng ý nghĩa của manpage. Cảm ơn rất nhiều! – PSkocik

Các vấn đề liên quan