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 12:05
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

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 12/01/2009 v 22:56
zdroj uživatelem

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 06:51
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 12/10/2009 v 22: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 20:14
zdroj uživatelem

hlasů
0

Zdá se, že tam je několik způsobů, jak zvládat exportované symboly na GNU / Linux. Z mé čtení to jsou 3 metody:

  • Zdrojový kód anotace / dekorace:
    • Metoda 1: -fvisibility=hiddenspolu s__attribute__((visibility("default")))
    • Metoda 2 (od GCC 4): #pragma GCC visibility
  • Metoda 3: Verze script (aka „mapuje symboly“) předán do linkeru (např. -Wl,--version-script=<version script file>)

Nebudu se dostat do příkladech zde, protože oni jsou většinou pokryty další odpovědi, ale tady je nějaké poznámky, Klady a zápory různých přístupů z vrcholu mé hlavy:

  • Použitím komentovaný postup umožňuje kompilátor optimalizuje kód ještě trochu (jeden méně indirection).
  • Pokud používáte komentovaný přístupu, zvažte také použití strip --strip-all --discard-all.
  • Komentovaný postup můžete přidat více práce pro jednotkové testy interní funkce na úrovni, protože jednotkové testy nemusí mít přístup k symbolům. To by mohlo vyžadovat vybudování samostatné soubory: jeden pro vnitřní vývoj a testování, a druhý pro výrobu. (Tento přístup je obecně neoptimální z testovacího puristické pohledu jednotku.)
  • Použití verze skriptu ztrácí optimalizaci, ale umožňuje symbol verzí, která se zdá, že nebude k dispozici s poznámkami přístupem.
  • Použití verze skript umožňuje jednotkové testy za předpokladu kód se poprvé postavil do archivního souboru (.a) a potom spojeny do DSO (.so). Jednotkové testy by se spojit s .a.

Jsem si jistý, že jsou jiní.

Zde je několik odkazů (s příklady), které jsem našel užitečné:

Odpovězeno 23/10/2019 v 18:39
zdroj uživatelem

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