Tema 4 Rustyloader

Informatii

Date limite: Le 30 mai, 23h59
Note: 2 points de la note
Lien: Devoir 4
Télécharger en retard: 2 points / jour (maximum 4 jours)

Obiectivele temei

  • Aprofundarea modului în care un executabil este încărcat și rulat de Sistemul de Operare.
  • Obținerea de deprinderi pentru lucrul cu excepții de memorie pe sistemele Linux.
  • Aprofundarea API-ului Linux de lucru cu spațiul de adrese, memorie virtuală și demand paging.

Recomandări

  • Înainte de a începe implementarea temei este recomandată acomodarea cu noțiunile și conceptele specifice, precum:
    • spațiu de adresă
    • drepturi de acces la pagină
    • formatul fișierelor executabile
    • demand paging
    • page fault
    • maparea de fișiere în spațu de adresă – file mapping
  • Urmăriți resursele descrise în secțiunea Resurse de suport.

Enunț

Să se implementeze un loader de fișiere executabile în format ELF pentru Linux. Loader-ul va încărca fișierul executabil în memorie pagină cu pagină, folosind un mecanism de tipul demand paging - o pagină va fi încărcată doar în momentul în care este nevoie de ea. Pentru simplitate, loader-ul va rula doar executabile statice - care nu sunt link-ate cu biblioteci partajate/dinamice.

Pentru a rula un fișier executabil, loader-ul va executa următorii pași:

  • Își va inițializa structurile interne.
  • Va afisa pe stderr (2) lista de segmente ale fisierului executabil
  • Va afisa pe stderr (2) base address pentru fisierul executabil (adresa de memorie minima la care se incarca segmente)
  • Va afisa pe stderr (2) entry point address
  • Va parsa fișierul binar - pentru a face asta aveți la dispozitie biblioteca object.
  • Va rula prima instrucțiune a executabilului (entry point-ul).
    • de-a lungul execuției, se va genera câte un page fault pentru fiecare acces la o pagină nemapată în memorie;
  • Va detecta fiecare acces la o pagină nemapată, și va verifica din ce segment al executabilului face parte.
    • dacă nu se găsește într-un segment, înseamnă că este un acces invalid la memorie – programul iese cu eroarea -200;
    • dacă page fault-ul este generat într-o pagină deja mapată, atunci se încearcă un acces la memorie nepermis (segmentul respectiv nu are permisiunile necesare) – la fel, programul iese cu eroarea -200;
    • dacă pagina se găsește într-un segment, și ea încă nu a fost încă mapată, atunci se mapează la adresa aferentă, cu permisiunile acelui segment;
  • Veți folosi funcțiile mmap (varianta rust.
  • Pagina trebuie mapată fix la adresa indicată în cadrul segmentului.

Formatul afisarii

Segments
#       address         size    offset  length  flags
0       0x8048000       1012    0x0     1012    r-x
1       0x804a000       8192    0x1000  8192    rw-
Entry point 8048120
Base address 8048000

Alinierea campurilor se face cu TAB (\t). Daca alinierea nu este buna, adaugati doua caratere TAB.

Biblioteca object

Biblioteca object va pune la dispozitie un parser pentru fisiere binare (ELF in Linux). Aveti nevoie de lista de segmente (File).

În imaginea de mai jos aveți o reprezentare grafică a unui segment.

  • mem_size este reprezentata de campul size
  • file_size este reprezentat de una din valorile din tupul file_range

Precizări/recomandări pentru implementare

  • Implementarea page fault handler-ului se realizează prin intermediul unei rutine pentru tratarea semnalului SIGSEGV.
  • Pentru a implementa logica de demand paging trebuie să interceptați page fault-urile produse în momentul unui acces nevalid la o zonă de memorie. La interceptarea page fault-urilor, tratați-o corespunzător, în funcție de segmentul din care face parte:
    • dacă nu este într-un segment cunoscut, rulați handler-ul default;
    • dacă este într-o pagină ne-mapată, mapați-o în memorie, apoi copiați din segmentul din fișier datele;
    • dacă este într-o pagină deja mapată, rulați handler-ul default (întrucât este un acces ne-permis la memorie);
  • Paginile din două segmente diferite nu se pot suprapune.
  • Dimensiunea unui segment nu este aliniată la nivel de pagină; memoria care nu face parte dintr-un segment nu trebuie tratată în niciun fel – comportamentul unui acces în cadrul acelei zone este nedefinit.

Precizări

  • Pentru gestiunea memoriei virtuale folosiți funcțiile mmap, munmap și mprotect.
  • Pentru interceptarea accesului nevalid la o zonă de memorie va trebui să interceptați semnalul SIGSEGV folosind apeluri din familia sigaction.
    • Veți înregistra un handler în câmpul sa_sigaction al structurii struct sigaction.
    • Pentru a determina adresa care a generat page fault-ul folosiți câmpul si_addr din cadrul structurii siginfo_t.
  • În momentul în care este accesată o pagină nouă din cadrul unui segment, mapați pagina în care s-a generat page fault-ul, folosind MAP_FIXED, apoi copiați în pagină datele din executabil

Resurse de suport

sde2/teme/tema_fr_4_rust_2023.txt · Last modified: 2023/05/14 20:32 by alexandru.radovici
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0