Dynamiczny linker
W informatyce dynamiczny linker to część systemu operacyjnego , która ładuje i łączy biblioteki współdzielone potrzebne do pliku wykonywalnego , gdy jest on wykonywany (w „ czasie wykonywania ”), kopiując zawartość bibliotek z pamięci trwałej do pamięci RAM , wypełniając skok tabele i przenoszenie wskaźników . Konkretny system operacyjny i format pliku wykonywalnego określają sposób działania dynamicznego linkera i sposób jego implementacji.
Łączenie jest często określane jako proces wykonywany podczas kompilacji pliku wykonywalnego , podczas gdy dynamiczny linker to specjalna część systemu operacyjnego, która ładuje zewnętrzne biblioteki współdzielone do uruchomionego procesu , a następnie dynamicznie wiąże te biblioteki współdzielone z uruchomionym procesem. Takie podejście jest również nazywane dynamicznym łączeniem lub późnym łączeniem .
Implementacje
Microsoft Windows
Biblioteka dołączana dynamicznie lub DLL to implementacja koncepcji biblioteki udostępnionej przez firmę Microsoft w systemach operacyjnych Microsoft Windows i OS/2 . Biblioteki te mają zwykle rozszerzenie pliku DLL
, OCX
(dla bibliotek zawierających formanty ActiveX ) lub DRV
(dla starszych sterowników systemowych ). Formaty plików dla bibliotek DLL są takie same jak dla plików Windows EXE — to znaczy Portable Executable (PE) dla 32-bitowego i 64-bitowego systemu Windows oraz New Executable (NE) dla 16-bitowego systemu Windows. Podobnie jak w przypadku plików EXE, biblioteki DLL mogą zawierać kod , dane i zasoby w dowolnej kombinacji.
Pliki danych o tym samym formacie pliku co biblioteka DLL, ale z różnymi rozszerzeniami plików i prawdopodobnie zawierające tylko sekcje zasobów, można nazwać bibliotekami DLL zasobów. Przykładami takich bibliotek DLL są wielojęzyczne biblioteki interfejsu użytkownika z rozszerzeniem MUI
, biblioteki ikon , czasami mające rozszerzenie ICL
, oraz pliki czcionek , mające rozszerzenia FON
i FOT
.
Systemy uniksopodobne wykorzystujące ELF i systemy oparte na Darwin
W większości systemów uniksopodobnych większość kodu maszynowego tworzącego dynamiczny linker jest w rzeczywistości zewnętrznym plikiem wykonywalnym, który jądro systemu operacyjnego ładuje i wykonuje jako pierwsze w nowo utworzonej przestrzeni adresowej procesu w wyniku wywołania funkcji exec
lub posix_spawn .
W czasie łączenia ścieżka dynamicznego linkera, który powinien być użyty, jest osadzona w wykonywalnym obrazie.
Kiedy ładowany jest plik wykonywalny, jądro systemu operacyjnego odczytuje z niego ścieżkę do dynamicznego linkera, a następnie próbuje załadować i wykonać ten inny wykonywalny plik binarny; jeśli ta próba się nie powiedzie, ponieważ na przykład nie ma pliku o tej ścieżce, próba wykonania oryginalnego pliku wykonywalnego kończy się niepowodzeniem. Następnie dynamiczny linker ładuje początkowy obraz wykonywalny i wszystkie dynamicznie połączone biblioteki, od których jest zależny, i uruchamia plik wykonywalny. binarnego interfejsu aplikacji systemu operacyjnego .
Systemy wykorzystujące ELF
W systemach typu Unix, które używają ELF do obrazów wykonywalnych i bibliotek dynamicznych, takich jak Solaris , 64-bitowe wersje HP-UX , Linux , FreeBSD , NetBSD , OpenBSD i DragonFly BSD , ścieżka dynamicznego linkera, który powinien być używany jest osadzony w czasie łącza w sekcji .interp segmentu
PT_INTERP
pliku wykonywalnego . W tych systemach dynamicznie ładowane biblioteki współdzielone można rozpoznać po przyrostku nazwy pliku .so
(obiekt współdzielony).
Można wpłynąć na dynamiczny linker, aby zmodyfikował swoje zachowanie podczas wykonywania programu lub łączenia programu, a przykłady tego można zobaczyć na stronach podręcznika konsolidatora w czasie wykonywania dla różnych systemów uniksopodobnych. Typową modyfikacją tego zachowania jest użycie zmiennych środowiskowych LD_LIBRARY_PATH
i LD_PRELOAD
, które dostosowują proces łączenia w czasie wykonywania, odpowiednio wyszukując biblioteki współużytkowane w alternatywnych lokalizacjach oraz wymuszając ładowanie i łączenie bibliotek, które w innym przypadku by nie istniały. Przykładem jest zlibc, znany również jako uncompress.so
, który ułatwia przezroczystą dekompresję, gdy jest używany przez hack LD_PRELOAD
; w konsekwencji możliwe jest odczytywanie wstępnie skompresowanych (skompresowanych gzipem) danych plików w systemach BSD i Linux tak, jakby pliki nie były skompresowane, zasadniczo umożliwiając użytkownikowi dodanie przezroczystej kompresji do bazowego systemu plików, chociaż z pewnymi zastrzeżeniami. Mechanizm jest elastyczny, pozwalając na trywialne dostosowanie tego samego kodu do dodatkowego lub alternatywnego przetwarzania danych podczas odczytu pliku, przed dostarczeniem tych danych żądającemu procesowi użytkownika.
macOS i iOS
W systemie operacyjnym Apple Darwin oraz w zbudowanych na nim systemach operacyjnych macOS i iOS ścieżka dynamicznego linkera, który powinien być używany, jest osadzona w czasie łączenia w jednym z poleceń ładowania Mach-O w obrazie wykonywalnym. W tych systemach dynamicznie ładowane biblioteki współdzielone można rozpoznać po przyrostku nazwy pliku .dylib
lub po umieszczeniu ich w pakiecie dla struktury.
Dynamiczny linker nie tylko łączy docelowy plik wykonywalny z bibliotekami współdzielonymi, ale także umieszcza funkcje kodu maszynowego w określonych punktach adresowych w pamięci, o których docelowy plik wykonywalny wie w czasie łączenia. Kiedy plik wykonywalny chce wejść w interakcję z dynamicznym linkerem, po prostu wykonuje specyficzne dla maszyny wywołanie lub instrukcję skoku do jednego z tych dobrze znanych punktów adresowych. Pliki wykonywalne na platformach macOS i iOS często wchodzą w interakcję z dynamicznym linkerem podczas wykonywania procesu; wiadomo nawet, że plik wykonywalny może wchodzić w interakcję z dynamicznym linkerem, powodując ładowanie większej liczby bibliotek i rozpoznawanie większej liczby symboli w kilka godzin po pierwszym uruchomieniu. Powodem, dla którego program macOS lub iOS tak często wchodzi w interakcję z dynamicznym linkerem, są zarówno interfejsy API Cocoa i Cocoa Touch firmy Apple , jak i język Objective-C , w którym są one implementowane (więcej informacji można znaleźć w ich głównych artykułach).
Dynamiczny linker można zmusić do zmodyfikowania niektórych jego zachowań; jednak w przeciwieństwie do innych systemów operacyjnych typu Unix, te modyfikacje są wskazówkami, które mogą być (i czasami są) ignorowane przez linker dynamiczny. Przykłady tego można zobaczyć na stronie podręcznika użytkownika dyld .
Typową modyfikacją tego zachowania jest użycie zmiennych środowiskowych DYLD_FRAMEWORK_PATH
i DYLD_PRINT_LIBRARIES
. Pierwsza ze wspomnianych wcześniej zmiennych dostosowuje ścieżkę wyszukiwania plików wykonywalnych dla bibliotek współdzielonych, podczas gdy druga wyświetla nazwy bibliotek podczas ich ładowania i łączenia.
Dynamiczny linker macOS firmy Apple to projekt typu open source wydany jako część Darwin i można go znaleźć w projekcie dyld
typu open source firmy Apple .
Systemy uniksopodobne oparte na XCOFF
W systemach operacyjnych typu Unix korzystających z XCOFF , takich jak AIX , dynamicznie ładowane biblioteki współdzielone używają przyrostka nazwy pliku .a
.
Można wpłynąć na dynamiczny linker, aby zmodyfikował swoje zachowanie podczas wykonywania programu lub łączenia programu. Typową modyfikacją tego zachowania jest użycie zmiennej środowiskowej LIBPATH
. Ta zmienna dostosowuje proces łączenia w czasie wykonywania, wyszukując biblioteki współdzielone w alternatywnych lokalizacjach oraz odpowiednio ładując i łącząc biblioteki, które w innym przypadku nie byłyby dostępne.
OS/360 i następcy
Dynamiczne łączenie z programów języka asemblera w systemie IBM OS/360 i jego następcach odbywa się zwykle przy użyciu makroinstrukcji LINK zawierającej instrukcję Supervisor Call , która aktywuje procedury systemu operacyjnego, dzięki którym moduł biblioteki, który ma być dołączony, jest dostępny dla programu. Moduły biblioteczne mogą znajdować się w „STEPLIB” lub „JOBLIB” określonym na kartach kontrolnych i dostępnym tylko dla określonego wykonania programu, w bibliotece zawartej w LIŚCIE LINKÓW w PARMLIB (określonej podczas uruchamiania systemu) lub w „ link pack area”, w którym określone moduły reentrant są ładowane podczas uruchamiania systemu.
Multiki
W systemie operacyjnym Multics wszystkie pliki, w tym pliki wykonywalne, są segmentami . Wywołanie procedury, która nie jest częścią bieżącego segmentu, spowoduje, że system znajdzie segment, do którego się odwołuje, w pamięci lub na dysku, i doda go do przestrzeni adresowej uruchomionego procesu. Łączenie dynamiczne jest normalną metodą działania, a łączenie statyczne (przy użyciu bindera ) stanowi wyjątek.
Efektywność
Łączenie dynamiczne jest generalnie wolniejsze (wymaga większej liczby cykli procesora) niż łączenie w czasie kompilacji, jak ma to miejsce w przypadku większości procesów wykonywanych w czasie wykonywania. Jednak dynamiczne łączenie jest często bardziej efektywne pod względem miejsca (na dysku iw pamięci w czasie wykonywania). Gdy biblioteka jest powiązana statycznie, każdy uruchamiany proces jest powiązany z własną kopią wywoływanych funkcji bibliotecznych. Dlatego, jeśli biblioteka jest wielokrotnie wywoływana przez różne programy, te same funkcje w tej bibliotece są duplikowane w kilku miejscach w pamięci systemu. Używanie współdzielonych, dynamicznych bibliotek oznacza, że zamiast łączyć każdy plik z jego własną kopią biblioteki w czasie kompilacji i potencjalnie marnować miejsce w pamięci, tylko jedna kopia biblioteki jest zawsze przechowywana w pamięci, zwalniając miejsce w pamięci do używany gdzie indziej. Ponadto w dynamicznym łączeniu biblioteka jest ładowana tylko wtedy, gdy jest faktycznie używana.
Zobacz też
- Bezpośrednie wiązanie
- DLL Piekło
- Ładowanie dynamiczne
- Późne wiązanie
- prelink
- Dynamiczna eliminacja martwego kodu
Notatki
Dalsza lektura
- Levine, John R. (2000) [październik 1999]. Łączniki i ładowarki . Seria Morgana Kaufmanna w inżynierii oprogramowania i programowaniu (1 wyd.). San Francisco, USA: Morgan Kaufmann . ISBN 1-55860-496-0 . OCLC 42413382 . Zarchiwizowane od oryginału w dniu 05.12.2012 . Źródło 2020-01-12 . Kod: [1] [2] Errata: [3]
Linki zewnętrzne
- Dynamiczne łączenie i ładowanie , IECC.com
- Dynamiczne łączenie w systemach Linux i Windows, część pierwsza , Symantec.com
- Anatomia bibliotek dynamicznych Linuksa , IBM.com