Zadanie 1: Post-linker

Data ogłoszenia: 10.03.2020

Termin oddania: 07.04.2020 (ostateczny 21.04.2020)

Materiały dodatkowe

test_z1.tar.gz

Post-linker

Zadaniem zwyczajnego linkera jest zebranie kilku plików kodu pośredniego (ET_REL) i złożenie z nich pliku wykonywalnego bądź biblioteki współdzielonej (ET_EXEC lub ET_DYN). Czasem jednak zdarza się, że chcielibyśmy dolinkować trochę kodu do już zlinkowanego pliku binarnego. Niestety, zwykły linker nie obsługuje tego przypadku.

Zadanie

Napisać post-linker: program pozwalający na “dolinkowanie” fragmentu kodu (będącego ELFem typu ET_REL) do już zlinkowanego programu wykonywalnego (będącego ELFem typu ET_EXEC).

Założenia

  1. Wejściem do procesu linkowania będzie 1 (jeden) plik wykonywalny w formacie ET_EXEC i 1 (jeden) plik kodu pośredniego w formacie ET_REL

  2. Obydwa pliki będą 64-bitowymi plikami o architekturze EM_X86_64.

  3. Można założyć, że poniżej najniższego (w sensie adresów wirtualnych) segmentu pliku ET_EXEC będzie wystarczająco dużo miejsca, by zmieścić nowe nagłówki ELF i nagłówki programu

  4. Plik ET_REL może zawierać:

    • dowolne sekcje z flagą SHF_ALLOC (należy je posklejać w kilka nowych segmentów na podstawie ich flag SHF_WRITE i SHF_EXECINSTR i dokleić)

    • własne symbole typu STT_NOTYPE, STT_FUNC, STT_OBJECT, STT_SECTION (mogą też istnieć symbole STT_FILE, ale można je zignorować)

    • symbol _start (jeśli jest obecny, powinien nadpisać e_start z pliku ET_EXEC)

    • relokacje następujących typów: R_X86_64_64, R_X86_64_32, R_X86_64_32S, R_X86_64_PC32, R_X86_64_PLT32 (które można traktować tak samo jak R_X86_64_PC32)

    • relokacje mogą się odwoływać do następujących symboli:

      • symboli zdefiniowanych we własnych sekcjach pliku ET_REL

      • symboli globalnych zdefiniowanych w tabeli symbolu (SHT_SYMTAB) pliku ET_EXEC

      • specjalnego symbolu orig_start, który powinien mieć wartość równą oryginalnej wartości e_start pliku wykonywalnego

  5. Nie trzeba obsługiwać następujących funkcjonalności:

    • odwołań z pliku ET_EXEC do symboli w ET_REL

    • symboli w “sekcji” SHN_COMMON bądź innych specjalnych sekcjach

    • innych typów symboli i relokacji niż podane powyżej

    • dopisywania symboli z ET_REL do tabeli symboli pliku wykonywalnego (wystarczy dokleić sam kod)

Forma rozwiązania

Jako rozwiązanie należy dostarczyć paczkę zawierającą:

  • dowolną liczbę plików źródłowych z kodem rozwiązania

  • jeśli rozwiązanie jest napisane w języku kompilowanym, plik Makefile kompilujący rozwiązanie, lub odpowiadający plik z innego sensownego systemu budowania (np. cmake)

  • plik readme z krótkim opisem rozwiązania i instrukcjami kompilacji na obrazie qemu z pierwszych zajęć

Rozwiązanie (po ew. kompilacji) powinno znajdować się w pliku wykonywalnym o nazwie postlinker. Program powinien mieć następujący interfejs:

./postlinker <plik ET_EXEC> <plik ET_REL> <docelowy plik ET_EXEC>

Rozwiązania będą testowane wewnątrz qemu, uruchomionego z obrazem z pierwszych zajęć. Polecamy sprawdzenie, czy rozwiązania kompilują się w tym obrazie.

Rozwiązania prosimy nadsyłać na adres p.zuk@mimuw.edu.pl z kopią do mwk@mimuw.edu.pl.

Zasady oceniania

Za zadanie można uzyskać do 10 punktów. Na ocenę zadania składają się dwie części:

  • wynik automatycznych testów (od 0 do 10 punktów)

  • ocena kodu rozwiązania (od 0 do -10 punktów)

Najczęstsze błędy - spis oznaczeń w USOSwebie

  1. Brak README (-0.1)

  2. Inna nazwa pliku wykonywalnego niż postlinker (-0.1)

  3. Problem z uruchomieniem z innego katalogu (/path/to/postlinker) (-0.1)

  4. Skrypt uruchomieniowy zawierający CRLF w pierwszej linii (#!…) (-0.1)

  5. Wynikowy plik nie ma atrybutu +x (-0.1)

  6. Śmieci w requirements.txt (pełny pip freeze) (-0.1)

  7. Niepoprawna obsługa ścieżek zawierających spację (-0.1)

  8. Niepoprawne atrybuty otwarcia pliku (-0.1)

  9. Brak weryfikacji wejściowych typów ELF (EXEC, REL) (-0.1)

  10. Wywoływanie system() zamiast użycia istniejących funkcji bibliotecznych (-0.0)

  11. Nieignorowanie symboli lokalnych z EXEC (-0.1)

  12. Tworzenie segmentów z nieprawidłowymi atrybutami (RWE) lub pustych (-0.1)

  13. Brak skryptu instalującego zależności (-0.1)

  14. Brak obsługi wyjątku przy odwołaniu do nieistniejącego _start (-0.1)

Wskazówki

Rozwiązanie zadania będzie wymagało dopisania kilku segmentów PT_LOAD do pliku wykonywalnego. Spowoduje to zwiększenie rozmiaru nagłówków programu, a przez to konieczność przemieszczenia ich w nowe miejsce. Ze względu na sposób działania linkera dynamicznego, konieczne będzie powiększenie najniższego segmentu (tego, który już zawiera nagłówek ELF i nagłówki programu) w dół i wklejenie w dopisany obszar nowych nagłówków.

Należy pamiętać o:

  • poprawieniu offsetów w pliku w nagłówkach programu i nagłówkach sekcji (jeśli objdump -xtrds <wynik> wygląda sensownie, prawdopodobnie się udało).

  • poprawieniu wpisu PT_PHDR, by wskazywał na nowe nagłówki