NAZWA
ld.so, ld-linux.so* - dynamiczny konsolidator/ładowacz
SKŁADNIA
Konsolidator dynamiczny może być uruchomiony albo pośrednio przez uruchomienie jakiegokolwiek skonsolidowanego dynamicznie programu lub obiektu dzielonego (w tym przypadku żadna opcja linii poleceń nie będzie przekazana do konsolidatora dynamicznego i w przypadku ELF-a uruchomiony zostanie konsolidator dynamiczny przechowywany w sekcji .interp programu), albo bezpośrednio przez uruchomienie:
/lib/ld-linux.so.* [OPCJE] [PROGRAM [ARGUMENTY]]
OPIS
Programy ld.so i ld-linux.so* wyszukują i uruchamiają obiekty dzielone (biblioteki dzielone) wymagane przez program, przygotowują program do uruchomienia, a w końcu go uruchamiają.
Binarki linuksowe wymagają konsolidacji dynamicznej (czyli konsolidacji podczas uruchamiania), chyba że podczas kompilacji programowi ld(1) przekazano opcję -static.
Program ld.so obsługuje binarki w używanym dawno temu formacie a.out; ld-linux.so* obsługuje format ELF (/lib/ld-linux.so.1 dla libc5, /lib/ld-linux.so.2 dla glibc2), który jest używany przez wszystkich już od ładnych paru lat. Poza tym oba programy zachowują się tak samo i używają tych samych plików pomocniczych i programów: ldd(1), ldconfig(8) oraz /etc/ld.so.conf.
Podczas rozwiązywania zależności obiektów dzielonych, konsolidator dynamiczny najpierw przegląda każdy łańcuch znaków zależności w poszukiwaniu znaku ukośnika (może wystąpić, jeśli podczas linkowania obiektu dzielonego podano nazwę ścieżki zawierającą ukośniki). Jeśli taki znak zostanie znaleziony, to łańcuch znaków zależności jest interpretowany jako nazwa (względnej lub bezwzględnej) ścieżki i obiekt dzielony jest ładowany, używając tej nazwy ścieżki.
Jeśli zależność od obiektu dzielonego nie zawiera znaku ukośnika, to potrzebne biblioteki dzielone są szukane w następującej kolejności:
o |
(Tylko ELF). Używa katalogów podanych w sekcji atrybutów dynamicznych DT_RPATH binarki, jeśli jest obecna i nie istnieje atrybut DT_RUNPATH. Użycie DT_RPATH jest przestarzałe. | ||
o |
Przy użyciu zmiennej środowiskowej LD_LIBRARY_PATH, chyba że plik wykonywalny jest uruchomiony w trybie bezpiecznego wykonania; (zob. niżej), gdy jest ignorowana. | ||
o |
(Tylko ELF) Używając katalogów podanych w sekcji atrybutów dynamicznych DT_RUNPATH binarki, jeśli taka sekcja istnieje. | ||
o |
Z pliku bufora /etc/ld.so.cache, zawierającego skompilowaną listę obiektów dzielonych poprzednio znalezionych w ścieżce obiektów dzielonych. Jeśli jednakże program binarny został skonsolidowany z opcją linkera -z nodeflib, to pomijane są obiekty dzielone z domyślnych ścieżek obiektów dzielonych. Preferowane są obiekty dzielone zainstalowane w katalogach zgodnych z właściwościami sprzętu (patrz niżej). | ||
o |
W domyślnej ścieżce /lib a potem w /usr/lib (na niektórych architekturach 64-bitowych domyślną ścieżką 64-bitowych obiektów dzielonych jest /lib64, a potem /usr/lib64). Ten krok jest pomijany, jeśli program binarny został skonsolidowany z opcją -z nodeflib konsolidatora. |
Rozwijanie
zmiennych w rpath
ld.so rozumie pewne łańcuchy znaków w
specyfikacji rpath (DT_RPATH lub DT_RUNPATH);
łańcuch ty są zamieniane
następująco:
$ORIGIN (lub równoważnie
${ORIGIN})
Rozwija się do katalogu zawierającego program lub obiekt dzielony. Tak więc aplikacja znajdująca się w jakimśkatalogu/app może zostać skompilowana z
gcc -Wl,-rpath,'$ORIGIN/../lib'
tak żeby przypisane jej obiekty dzielone mogły być umieszczone w jakimśkatalogu/lib, niezależnie od tego, gdzie jakiśkatalog jest umieszczony w hierarchii katalogów. Umożliwia to tworzenie aplikacji, które nie muszą być instalowane w specjalnych katalogów, ale mogą po prostu być rozpakowane w dowolnym katalogu i wciąż będą mogły znaleźć swoje obiekty dzielone.
$LIB (lub równoważnie ${LIB})
Rozwija się do lib lub lib64 w zależności od architektury (np. na x86-64 rozwija się lib64, a na x86-32 rozwija się do lib).
$PLATFORM (lub równoważnie ${PLATFORM})
Rozwija się do łańcucha znaków odpowiadającemu typowi procesora systemu (np. "x86_64"). Na niektórych architekturach jądro Linuksa nie przekazuje konsolidatorowi dynamicznemu oznaczenia platformy. Wartość tego łańcucha znaków jest pobierana z wartości AT_PLATFORM pomocniczego wektora (patrz getauxval(3)).
OPCJE
--list |
Wyświetla wszystkie zależności wraz ze sposobem ich rozwiązania. |
--verify
Sprawdza, że program jest konsolidowany dynamicznie i że ten konsolidator dynamiczny może go obsłużyć.
--inhibit-cache
Nie używa /etc/ld.so.cache.
--library-path ścieżka
Używa ścieżki zamiast ustawienia zmiennej środowiska LD_LIBRARY_PATH (patrz niżej).
--inhibit-rpath lista
Ignoruje informacje RPATH i RUNPATH w nazwach obiektów w liście. Opcja jest ignorowana podczas działania w trybie bezpiecznego wykonania (zob. niżej)
--audit lista
Używa obiektów wymienionych w liście jako audytorów.
ŚRODOWISKO
Różne zmienne środowiska wpływają na działanie dynamicznego konsolidatora
Tryb
bezpiecznego wykonania
Ze względów bezpieczeństwa, działania
niektórych zmiennych środowiskowych jest
anulowane lub modyfikowane, jeśli dynamiczny
konsolidator określi, że plik binarny powinien
być uruchomiony w trybie bezpiecznego wykonania.
To określenie dokonywane jest na podstawie sprawdzenia,
czy wpis AT_SECURE w dodatkowym wektorze (zob.
getauxval(3)) ma niezerową wartość.
Wpis ten może mieć niezerową
wartość z różnych powodów,
m.in.:
* |
Rzeczywisty i efektywny identyfikator użytkownika procesu różnią się lub rzeczywisty i efektywny identyfikator grupy różnią się. Zwykle ma to miejsce jako rezultat wykonywania programu z set-user-ID lub set-group-ID. | ||
* |
Proces użytkownika z identyfikatorem niebędącym ID roota wykonuje plik binarny z nadanymi przywilejami permitted lub effective. | ||
* |
Niezerowa wartość mogła być ustawiona przez linuksowy moduł bezpieczeństwa - Linux Security Module. |
Zmienne
środowiskowe
Wśród ważniejszych zmiennych
środowiskowych są następujące:
LD_ASSUME_KERNEL (glibc od wersji 2.2.3)
Każdy obiekt dzielony może informować konsolidator dynamiczny o wymaganej minimalnej wersji ABI jądra (To wymaganie jest zakodowane w sekcji "note" ELF-a; sekcja ta jest widoczna w readelf -n jako sekcja oznaczona NT_GNU_ABI_TAG). Podczas działania konsolidator dynamiczny określa wersję ABI uruchomionego jądra i odrzuca obiekty dzielone, które wymagają minimalnej wersji ABI większej niż wersja ABI uruchomionego jądra.
LD_ASSUME_KERNEL może zostać użyta do spowodowania, że konsolidator dynamiczny założy, że jest uruchomiony na systemie z inną wersją ABI jądra. Na przykład następująca linia poleceń powoduje, że konsolidator dynamiczny podczas ładowania obiektów dzielonych wymaganych przez mójprog zakłada, że działa w systemie Linux 2.2.5
$ LD_ASSUME_KERNEL=2.2.5 ./mójprog
W systemach, które dostarczają wielu wersji obiektu dzielonego (w różnych katalogach w ścieżce wyszukiwania) o różnych minimalnych wymaganiach wersji ABI jądra, LD_ASSUME_KERNEL może zostać użyte do wybrania tej wersji obiektu, która zostanie użyta (w zależności od porządku przeszukiwania katalogów). Historycznie najczęstszym użyciem LD_ASSUME_KERNEL było ręczne wybieranie starszej implementacji POSIX-owych wątków LinuxThreads w systemach, które miały zainstalowane zarówno LinuxThreads, jak i NPTL (który był domyślną wersją na takich systemach); patrz pthreads(7).
LD_BIND_NOW
(libc5; glibc od wersji 2.1.1) Gdy zmienna ta jest obecna, sprawia, że dynamiczny konsolidator rozwiąże wszystkie symbole podczas startu programu, a nie wtedy gdy będzie do nich pierwsze odniesienie. Jest to użyteczne podczas używania debuggera.
LD_LIBRARY_PATH
Lista katalogów, w których szukać bibliotek ELF podczas wykonywania. Składniki listy mogą być oddzielone dwukropkiem lub średnikiem. Podobne do zmiennej środowiskowej PATH. Ta zmienna jest ignorowana w trybie bezpiecznego wykonania.
LD_PRELOAD
Lista dodatkowych, podanych przez użytkownika obiektów dzielonych ELF, którą należy załadować przed wszystkimi innymi. Elementy listy mogą być oddzielone od siebie spacjami lub dwukropkami. Umożliwia to wybiórczą zamianę funkcji w innych obiektach dzielonych. Może być używane do wybiórczego nadpisywania funkcji z innych obiektów dzielonych. Obiekty są wyszukiwane zgodnie z regułami podanymi w rozdziale OPIS. W trybie bezpiecznego wykonania, załadowane wstępnie ścieżki zawierające ukośniki są ignorowane, a obiekty dzielone ze standardowej ścieżki katalogów ładowane będą tylko wtedy, gdy mają także ustawiony bit set-user-ID.
LD_TRACE_LOADED_OBJECTS
(tylko ELF) Gdy zmienna ta jest ustawiona (na dowolną wartość) powoduje, że program wypisze swoje dynamiczne zależności, tak jakby był uruchomiany przez ldd(1), a nie normalnie.
Jest także
wiele bardziej lub mniej mętnych zmiennych, wiele
przestarzałych lub przeznaczonych do użytku
wewnętrznego.
LD_AOUT_LIBRARY_PATH
(libc5) Wersja LD_LIBRARY_PATH tylko dla binariów a.out. Starsze wersje ld-linux.so.1 wspierały także LD_ELF_LIBRARY_PATH.
LD_AOUT_PRELOAD
(libc5) Wersja LD_PRELOAD tylko dla binariów a.out. Starsze wersje ld-linux.so.1 wspierały także LD_ELF_PRELOAD.
LD_AUDIT
(glibc od wersji 2.4). Rozdzielona dwukropkami lista określonych przez użytkownika dzielonych obiektów ELF do załadowania przez wszystkimi innymi obiektami w oddzielnej przestrzeni nazw konsolidatora (to jest w przestrzeni nazw, która nie wpływa na przyporządkowania symboli, które odbywa się w procesie). Obiektów tych można użyć do audytu operacji konsolidatora dynamicznego. LD_AUDIT jest ignorowane w trybie bezpiecznego wykonania.
Konsolidator dynamiczny powiadomi obiekty dzielone audytu w tak zwanych punktach sprawdzeń audytu \m na przykład ładowanie nowego dzielonego obiektu, rozwiązanie symbolu lub wywołanie symbolu z innego obiektu dzielonego \m przez wywołanie odpowiedniej funkcji obiektu dzielonego. Szczegóły można znaleźć w rtld-audit(7). Interfejs audytu jest w dużej mierze zgodny z tym udostępnianym przez Solarisa, opisanym w jego Przewodniku po konsolidatorze i bibliotekach w rozdziale Interfejs audytu konsolidatora.
LD_BIND_NOT
(glibc od wersji 2.1.95) Jeśli ta zmienna środowiskowa jest ustawiona na niepusty łańcuch, to nie zachodzi aktualizacja GOT (global offset table) ani PLT (procedure linkage table) po rozwinięciu symbolu.
LD_DEBUG
(glibc od wersji 2.1) Wypisuje rozwlekłe informacje debugowania konsolidatora dynamicznego. Jeśli ustawione na all wypisuje wszystkie dostępne informacje debugowania, jeśli ustawione na help wyświetla listę kategorii, które można podać jako wartość tej zmiennej środowiskowej. Od glibc wersji 2.3.4 LD_DEBUG jest ignorowana w trybie bezpiecznego wykonania, chyba że istnieje plik /etc/suid-debug (jest zawartość jest nieistotna).
LD_DEBUG_OUTPUT
(glibc od wersji 2.1) Plik, do którego będzie zapisane wyjście LD_DEBUG. Domyślnie jest to standardowe wyjście błędów. LD_DEBUG_OUTPUT jest ignorowane w trybie bezpiecznego wykonania.
LD_DYNAMIC_WEAK
(glibc od wersji 2.1.91) Jeśli ta zmienna środowiskowa jest zdefiniowana (z dowolną wartością), to pozwala na nadpisywanie słabych (ang. weak) symboli (przywracając poprzednie zachowanie glibc). Od wersji 2.3.4 biblioteki glibc LD_DYNAMIC_WEAK jest ignorowana w trybie bezpiecznego wykonania.
LD_HWCAP_MASK
(glibc od wersji 2.1) Maska właściwości sprzętowych.
LD_KEEPDIR
(tylko a.out)(libc5) Nie ignoruju katalogu w nazwach ładowanych bibliotek a.out. Używanie tej opcji nie jest zalecane.
LD_NOWARN
(tylko a.out)(libc5) Powstrzymuje ostrzeżenia o bibliotekach a.out o niekompatybilnych numerach minorowych wersji.
LD_ORIGIN_PATH
(glibc od wersji 2.1) Ścieżka, w której znaleziono program binarny (dla programów bez bitu set-user-ID). Od wersji 2.4 biblioteki glibc LD_ORIGIN_PATH jest ignorowana w trybie bezpiecznego wykonania.
LD_POINTER_GUARD
(glibc od wersji 2.4 do 2.22) Ustawione na 0 powoduje wyłączenie ochrony wskaźników. Jakakolwiek inna wartość włącza ochronę wskaźników, co jest także zachowaniem domyślnym. Ochrona wskaźników jest mechanizmem bezpieczeństwa, w którym niektóre wskaźniki do kodu przechowywanego w zapisywalnej pamięci programu (adresy powrotu zwrócone przez setjmp(3) lub wskaźniki do funkcji używane przez różne funkcje wewnętrzne biblioteki glibc) są w sposób pseudolosowy zmieniane, aby utrudnić hakerowi przejęcie tych wskaźników i przeprowadzenie ataków typu przepełnienie bufora lub stosu. Od glibc 2.23 LD_POINTER_GUARD nie można już użyć do wyłączenia ochrony wskaźników, która jest teraz zawsze aktywna.
LD_PROFILE
(glibc od wersji 2.1) Nazwa (pojedynczego) obiektu dzielonego przeznaczonego do profilowania, podane albo jako nazwa ścieżki, albo nazwa pliku so. Wyjście profilowania jest dopisywane do pliku o nazwie "$LD_PROFILE_OUTPUT/$LD_PROFILE.profile".
LD_PROFILE_OUTPUT
(glibc od wersji 2.1) Katalog, w którym powinno być zapisane wyjście LD_PROFILE. Jeśli ta zmienna nie jest zdefiniowana lub jeśli wartość tej zmiennej jest pusta, to domyślnym katalogiem jest /var/tmp. LD_PROFILE_OUTPUT jest ignorowane w trybie bezpiecznego wykonania; wówczas zawsze używany jest /var/profile.
LD_SHOW_AUXV
(glibc od wersji 2.1) Jeśli ta zmienna środowiskowa jest zdefiniowana (z dowolną wartością), wyświetla tablicę pomocniczą przekazaną przez jądro. Od wersji 2.3.5 biblioteki glibc LD_SHOW_AUXV jest ignorowana w trybie bezpiecznego wykonania.
LD_TRACE_PRELINKING
(glibc od wersji 2.4) Jeśli ta zmienna środowiskowa jest zdefiniowana (z dowolną wartością) śledzi prekonsolidację obiektu, którego nazwa jest przypisana do tej zmiennej środowiskowej (ldd(1) służy do pozyskania listy obiektów, które mogą być śledzone). Jeśli nazwa obiektu nie zostanie rozpoznana, to śledzona jest cała aktywność prekonsolidacji.
LD_USE_LOAD_BIAS
Domyślnie (czyli jeśli ta zmienna nie jest zdefiniowana) programy wykonywalne i prekonsolidowane obiekty dzielone będą uwzględniały adresy bazowe obiektów dzielonych, od których zależą, a (nieprekonsolidowane) programy wykonywalne niezależne od pozycji (position-independent executable, PIE) i inne obiekty dzielone nie będą ich uwzględniały. Jeśli LD_USE_LOAD_BIAS jest zdefiniowana z jakąś wartością, to zarówno programy wykonywalne, jak i PIE, będą uwzględniały adresy bazowe. Jeśli LD_USE_LOAD_BIAS jest zdefiniowana z wartością 1, to ani programy wykonywalne, ani PIE nie będą uwzględniały adresów bazowych. Zmienna ta jest ignorowana w trybie bezpiecznego wykonania.
LD_VERBOSE
(glibc od wersji 2.1). Jeśli ustawione na niepusty łańcuch znaków i jeśli została ustawiona zmienna środowiskowa LD_TRACE_LOADED_OBJECTS, to wypisuje informacje o wersjonowaniu symboli programu.
LD_WARN
(tylko ELF)(glibc od wersji 2.1.3) Jeśli ustawione na niepusty łańcuch znaków, to włącza ostrzeganie o nierozwijalnych symbolach.
LD_PREFER_MAP_32BIT_EXEC
(tylko x86-64)(glibc w wersji od 2.23) Zgodnie z przewodnikiem optymalizacji oprogramowania Intel Silvermont, dla aplikacji 64-bitowych wydajność przewidywania rozgałęzień może być zmniejszona, gdy cel gałęzi jest oddalony o ponad 4GB. Jeśli ta zmienna środowiskowa jest ustawiona (na dowolną wartość), to ld.so spróbuje najpierw przypisać flagi wykonywalności za pomocą flagi MAP_32BIT mmap(2), a jeśli się to nie powiedzie — bez tej flagi. Przy okazji: MAP_32BIT przypisze niższe 2GB (nie 4GB) przestrzeni adresowej. Ponieważ MAP_32BIT redukuje zakres adresowy dostępny dla losowego rozmieszczania obszarów pamięci (ang. ASLR - adress space layout randomization), w trybie bezpiecznego wykonania LD_PREFER_MAP_32BIT_EXEC jest zawsze wyłączona.
LDD_ARGV0
(libc5) argv[0] do użycia przez ldd(1), jeśli żadne argumenty nie są obecne.
PLIKI
/lib/ld.so
Dynamiczny konsolidator/ładowacz a.out
/lib/ld-linux.so.{1,2}
Dynamiczny konsolidator/ładowacz ELF
/etc/ld.so.cache
Plik zawierający skompilowaną listę katalogów, w których należy szukać obiektów dzielonych oraz uporządkowaną listę kandydujących obiektów dzielonych.
/etc/ld.so.preload
Plik zawierający oddzieloną spacjami listę obiektów dzielonych ELF, które mają być załadowane przed programem.
lib*.so*
obiekty dzielone
UWAGI
Możliwości ld.so dostępne są tylko dla programów binarnych, skompilowanych przy użyciu libc w wersji 4.4.3 lub wyższej. Funkcjonalności ELF-a są dostępne od Linuksa 1.1.52 i libc5.
Możliwości
sprzętowe
Niektóre obiekty dzielone są kompilowane z
użyciem specyficznych dla danego sprzętu
instrukcji, które nie muszą istnieć na
każdym CPU. Takie obiektypowinny
być instalowane w katalogach, których nazwy
określają wymagane właściwości
sprzętu, na przykład /usr/lib/sse2/.
Konsolidator dynamiczny porównuje nazwy takich
katalogów ze sprzętem maszyny i wybiera
najbardziej odpowiednią wersję danego obiektu
dzielonego. Katalogi właściwości sprzętu
mogą tworzyć kaskady, dopuszczając kombinacje
cech CPU. Lista nazw wspieranych właściwości
sprzętowych zależy od CPU. Obecnie rozpoznawane
są następujące nazwy:
Alpha |
ev4, ev5, ev56, ev6, ev67 |
|||
MIPS |
loongson2e, loongson2f, octeon, octeon2 |
PowerPC
4xxmac, altivec, arch_2_05, arch_2_06, booke, cellbe, dfp, efpdouble, efpsingle, fpu, ic_snoop, mmu, notb, pa6t, power4, power5, power5+, power6x, ppc32, ppc601, ppc64, smt, spe, ucache, vsx
SPARC |
flush, muldiv, stbar, swap, ultra3, v9, v9v, v9v2 | ||
s390 |
dfp, eimm, esan3, etf3enh, g5, highgprs, hpage, ldisp, msa, stfle, z900, z990, z9-109, z10, zarch |
x86 (tylko 32-bitowe)
acpi, apic, clflush, cmov, cx8, dts, fxsr, ht, i386, i486, i586, i686, mca, mmx, mtrr, pat, pbe, pge, pn, pse36, sep, ss, sse, sse2, tm
ZOBACZ TAKŻE
ld(1), ldd(1), pldd(1), sprof(1), dlopen(3), getauxval(3), capabilities(7), rtld-audit(7), ldconfig(8), sln(8)
O STRONIE
Angielska wersja tej strony pochodzi z wydania 4.05 projektu Linux man-pages. Opis projektu, informacje dotyczące zgłaszania błędów, oraz najnowszą wersję oryginału można znaleźć pod adresem https://www.kernel.org/doc/man-pages/.
TŁUMACZENIE
Autorami polskiego tłumaczenia niniejszej strony podręcznika man są: Przemek Borys (PTM) <pborys [AT] dione.pl>, Grzegorz Goławski (PTM) <grzegol [AT] pld.pl>, Robert Luberda <robert [AT] debian.org> i Michał Kułach <michal.kulach [AT] gmail.com>.
Polskie tłumaczenie jest częścią projektu manpages-pl; uwagi, pomoc, zgłaszanie błędów na stronie http://sourceforge.net/projects/manpages-pl/. Jest zgodne z wersją 4.05 oryginału.