Programowanie w asemblerze Linkowanie
Transkrypt
Programowanie w asemblerze Linkowanie
Programowanie w asemblerze Linkowanie Zbigniew Jurkiewicz, Instytut Informatyki UW January 17, 2017 Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Problem rozmieszczenia (relokacji) Ponieważ w pamieci ˛ równocześnie może znajdować sie˛ kilka programów, nie można w trakcie kompilacji przewidzieć ich rzeczywistych adresów. Podział pracy: linker: rozmieszczenie pamieci ˛ = przygotowanie adresów wzglednych ˛ w programie loader: finalna relokacja Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Rozwiazania ˛ architektoniczne Relokacja sprz˛etowa (rejestry relokacji) i pamieć ˛ wirtualna uprościły prace˛ linkera. Każdy program dostaje cała˛ (wirtualna) ˛ przestrzeń adresowa. ˛ Ale za to pojawiło sie˛ dzielenie kodu: podział programu na sekcje kodu i danych. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Zadania linkera Scala moduły binarne Łaczy ˛ binarne moduły relokowalne w pojedynczy plik wykonywalny, który można bedzie ˛ załadować loaderem. Rozwiazuje ˛ odwołania zewnetrzne ˛ Musza˛ być rozwiazywane ˛ w trakcie procesu scalania Odwołanie zewnetrzne: ˛ odwołanie do symbolu w innym module. Relokuje symbole Wiaże ˛ nazwy symbolicznych opisane wzglednymi ˛ adresami w ramach modułów (plików .o) z konkretnymi adresami absolutnymi w kodzie wykonywalnym. Na przykład: getline w module iosys ↔ adres 612 bajtów od poczatku ˛ wykonywalnego kodu. Wykonuje code fixups: aktualizuje wszystkie odwołania do tych symboli tak, aby odpowiadały ich nowym adresom. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Relokacja Asembler generuje adresy nierelokowane. Załóżmy np., że dla mov eax,[a] mov [b],eax a ma adres lokalny 0x1234, zaś b jest importowany. Kod po asemblacji A1 34 12 00 00 A3 00 00 00 00 mov eax,[a] mov [b],eax Przy linkowaniu linker ustala, że sekcja zawierajaca ˛ a ma być relokowana 0x10000 bajtów, zaś b ma adres 0x9A12 A1 34 12 01 00 A3 12 9A 00 00 mov eax,[a] mov [b],eax Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Relokacja Podobne modyfikacja sa˛ wymagane w sekcji danych, jeśli wystepuj ˛ a˛ tam wskaźniki, np. tablica adresów procedur. Problemy w procesorach RISC, gdzie adres cz˛esto budowany przez 2 lub 3 kolejne instrukcje. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Formaty plików binarnych W Unixie pliki binarne (i nie tylko) rozpoczynaja˛ sie˛ od 32-bitowej liczby magicznej (magic number ), określajacej ˛ typ pliku. Tradycyjnym, choć obecnie rzadko używanym, formatem pliku binarnego w Unixie jest a.out. Jego liczba˛ magiczna to 0x407. Zastapiony ˛ formatem ELF. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Format a.out Nagłówek a.out Sekcja text Sekcja data Inne sekcje Opcjonalna informacja o relokacji Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Format ELF Nagłówek ELF Tablica nagłówków programów (dla loadera) Sekcja .text Sekcja .data Sekcja .bss .symtab .rel.text .rel.data .debug Tablica nagłówków sekcji (informacje o relokacji dla linkera) Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Format ELF (Executable and Linking Format) Obecnie podstawowy format w Linuxie o liczbie magicznej 0x177 = ’ELF’ Nadaje sie˛ zarówno do zapisywania programów wykonywalnych, jak i modułów i bibliotek (a także obrazów pamieci). ˛ Ma kilka typów: relokowalny, wykonywalny, shared, core image. Tak wiec ˛ można w nim umieszczać informacje potrzebne zarówno linkerowi, jak i loaderowi. Na poczatku ˛ pliku znajduje sie˛ nagłówek, nastepnie ˛ tablica nagłówków programów (opis segmentów dla loadera). Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Format ELF Potem nastepuje ˛ właściwa zawartość pliku, czyli sekcje: kod .text dane inicjowane .data dane nieinicjowane .bss .symtab: tablica symboli .rel.text: informacje o relokacjach dla .text .rel.data: informacje o relokacjach dla .data .debug: informacja dla debuggera (gdy użyto gcc -g) Na końcu tablica nagłówków sekcji, opisujaca ˛ poszczególne sekcje i przeznaczona dla linkera. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Biblioteki Biblioteki dziela˛ sie˛ na statyczne i dzielone. Wszelkie biblioteki statyczne wymagaja˛ relinkowania programu po każdej modyfikacji bibliotek. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Biblioteki dzielone Biblioteki dzielone dziela˛ sie˛ na ładowane statycznie i dynamicznie. dla bibliotek ładowanych statycznie adresy (rozmieszczenie) sa˛ ustalane w trakcie ładowania programu biblioteki ładowane dynamicznie moga˛ być doładowywane w miare˛ potrzeby w trakcie pracy, przy pierwszym wywołaniu ich procedur W bibliotekach dzielonych używa sie˛ Position Independent Code (PIC), aby można je było ładować w dowolne miejsce w pamieci ˛ (np. w kompilatorze gcc jest do tego opcja). Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Linkowanie dynamiczne: metody Implicit linking Z programem zwiazujemy ˛ linkage segment, opisujacy ˛ wołane procedury zewnetrzne ˛ z biblioteki dynamicznej jako pary [nazwa, adres(poczatkowo równy 0, czyli błedny)]. ˛ W kodzie wywołania pośrednie przez te adresy, z wyjatkiem ˛ pierwszego razu, bo poczatkowo ˛ jest to pułapka (trap) do dynamicznego linkera, powodujaca ˛ dolinkowanie docelowej biblioteki i wypełnienie pola adresu. Explicit linking Program w swoim prologu podaje wszystkie używane biblioteki dzielone i łaczy ˛ sie˛ z nimi. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Tworzenie biblioteki dynamicznej Aby zbudować bibliotek˛e dynamiczna, ˛ plik asemblujemy normalnie nasm -f elf pakiet.asm W deklaracjach eksportowanych symboli powinniśmy jednak podawać ich typ: function lub data, np. global random:function,seed:data Inaczej natomiast bedziemy ˛ go linkować ld -shared -o libpakiet.so pakiet.o Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie Tworzenie biblioteki dynamicznej Tak zbudowanej biblioteki można teraz używać podobnie jak systemowej ld -L . -dynamic-linker /lib/ld-linux.so.2 \ -o program program.o -l pakiet Dodatkowo przed uruchomieniem program musimy odpowiednio ustawić zmienna˛ środowiska LD_LIBRARY_PATH=. export LD_LIBRARY_PATH Polecenie systemowe ldd podaje, jakich bibliotek dzielonych używa program, natomiast polecenie nm podaje wszystkie symbole zewnetrzne ˛ modułu binarnego. Zbigniew Jurkiewicz, Instytut Informatyki UW Programowanie w asemblerze Linkowanie