Omezení viditelnosti symbolů při propojování sdílené knihovny

hlasů
38

Některé platformy mandát, který vám poskytne seznam vnějších symbolů sdílené knihovny na spojce. Nicméně u většiny unixish systémů, které to není nutné: bude k dispozici ve výchozím nastavení jsou všechny non-statické symboly.

Já to chápu tak, že GNU toolchain může případně omezit viditelnost jen symboly explicitně deklarované. Jak je to možné dosáhnout použitím GNU ld?

Položena 12/01/2009 v 14:05
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
60

GNU ldmůže dělat, že na ELF platformách.

Tady je, jak to udělat s linker verze scénáře:

/* foo.c */
int foo() { return 42; }
int bar() { return foo() + 1; }
int baz() { return bar() - 1; }

gcc -fPIC -shared -o libfoo.so foo.c && nm -D libfoo.so | grep ' T '

Ve výchozím nastavení jsou všechny symboly jsou exportovány:

0000000000000718 T _fini
00000000000005b8 T _init
00000000000006b7 T bar
00000000000006c9 T baz
00000000000006ac T foo

Řekněme, že chcete exportovat pouze bar()a baz(). Vytvoření „verze skript“ libfoo.version:

FOO {
  global: bar; baz; # explicitly list symbols to be exported
  local: *;         # hide everything else
};

Předat je linker:

gcc -fPIC -shared -o libfoo.so foo.c -Wl,--version-script=libfoo.version

Pozorovat exportovaných symbolů:

nm -D libfoo.so | grep ' T '
00000000000005f7 T bar
0000000000000609 T baz
Odpovězeno 17/01/2009 v 08:51
zdroj uživatelem

hlasů
35

Myslím, že nejjednodušší způsob, jak toho dosáhnout, je přidáním -fvisibility=hiddenGCC možnosti a explicitně vytvořit viditelnost některých symbolů veřejné v kódu (o __attribute__((visibility("default")))). Naleznete v dokumentaci zde .

Tam může být způsob, jak toho dosáhnout tím, ld spojovacích skripty, ale já moc nevím o tom.

Odpovězeno 13/01/2009 v 00:56
zdroj uživatelem

hlasů
5

Kód generovaný zavolat některou z exportovaných funkcí ani používat žádné exportované globals je méně efektivní než ty, které nejsou exportovány. K dispozici je navíc míra indirection zapojeni. To se vztahuje na všechny funkce, které by mohly být vyvezeno na kompilaci čase. gcc bude i nadále vyrábět navíc indirection na funkci, která je později un-vyváženého linkerovou skriptu. Takže pomocí atributu viditelnost bude produkovat lepší kód, než je linker skriptu.

Odpovězeno 13/10/2009 v 00:04
zdroj uživatelem

hlasů
0

Pokud používáte libtool, tam je další možností podobně jako zaměstnán Rusa odpověď.

Používat jeho příkladu, bylo by to něco jako:

cat export.sym
bar
baz

Pak spusťte libtool s následující možnosti:

libtool -export-symbols export.sym ...

Všimněte si, že při použití -EXPORT symbolů všechny symboly nejsou exportovány ve výchozím nastavení a pouze ty export.sym jsou vyváženy (takže „local: *“ řádek v libfoo.version je vlastně implicitně v tomto přístupu).

Odpovězeno 27/02/2017 v 22:14
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more