Sistemski softver/Avgust 2022

Izvor: SI Wiki
Pređi na navigaciju Pređi na pretragu

Ispit u avgustovskom roku 2022. godine održan je 24. avgusta. Svaki zadatak vredi ukupno 10 poena. Ispit traje 2 sata.

1. zadatak

Postavka

Odrediti vrednost pri obradi od strane asemblera za hipotetičku mašinu (ukoliko vrednost nije poznata napisati znak pitanja) i indeks klasifikacije za svaki izraz u okviru izvornog asemblerskog koda datog u nastavku.

        BEG
        USE LAB1
        ORG 0x60
        SCT DAT
LAB2    DC LAB1
        DC 7 + LAB2
        SCT TXT
LAB3    LDA LAB2 - 1
        ADX * - LAB3
        END

Rešenje

Naredba Indeks klasifikacije Vrednost
DC LAB1 1.unique() ?
DC 7 + LAB2 0 + 1.DAT = 1.DAT 0x67
LDA LAB2 - 1 1.DAT - 0 = 1.DAT 0x5f
ADX * - LAB3 1.TXT - 1.TXT = 0 0x2

2. zadatak

Postavka

Navesti šta je rezultat ekspanzije sledećeg koda od strane C pretprocesora i objasniti kako je dobijen.

#define M1(x1) M2(x1)
#define M2(x1) M3(x1,A)
#define M3(x1,x2) x2 M3(x1,x2) M1(x1)
M3(M1(C), B)

Rešenje

Pojavljivanje nekog makroa u svojoj definiciji se ne smatra makropozivom. Videti 3.10.5 Self-Referential Macros iz dokumentacije C pretprocesora.

B M3(A M3(C, A) M1(C), B) M3(A M3(C,A) M1(C), A)

3. zadatak

Postavka

Za neki emulator potrebno je napisati funkciju void write(unsigned addr, unsigned data) za upis u memoriju. Adresni prostor je veličine 4 GB, a adresabilna jedinica je bajt. Smatrati da je pristup reči uvek poravnat na adresu deljivu sa 4. Na raspolaganju su funkcije unsigned rphy(unsigned addr), koja dohvata reč sa date fizičke adrese i void wphy(unsigned addr, unsigned data), koja upisuje zadatu reč na zadatu fizičku adresu. Emulirana mašina poseduje virtuelnu memoriju organizovanu stranično. Veličina stranice je 16 KB. Registar PMTP (koji se emulira istoimenom globalnom promenljivom) sadrži adresu tabele za preslikavanje stranica. Svaki ulaz u tabeli je 32 bita, pri čemu su najviša dva bita V i D bitovi. Ukoliko je V bit jednak 0, u najnižih 30 bitova je zapisana adresa na disku, dok je u slučaju da je bit V jednak 1, u najnižim bitovima ulaza zapisan redni broj bloka u koji je smeštena stranica. U slučaju da stranica nije u memoriji, učitava se u memoriju pozivom funkcije void load(unsigned hddaddr), koja u pozadini generiše page fault i blokira pozivajuću nit dok stranica ne bude učitana sa diska. Jedini argument funkcije predstavlja adresu kojoj se pristupa.

Rešenje

Adresni prostor je 4 GB, što znači da je adresa 32-bitna. Ako je veličina stranice 16 KB, najnižih 14 bita virtuelne adrese je pomeraj u stranici, a viših 18 je broj ulaza. Pošto je svaka reč poravnata sa 4, ulaz u tabelu ne mora da sadrži dva najniža bita jer su ona uvek 0. Ulaz u tabelu preslikavanja stranica i virtuealna adresa izgledaju ovako:

VA(32): PageNumber(18), Offset(14)

PMT(32): V(1), D(1), PhyAddress/BlockNumber(30)

void write(unsigned addr, unsigned data) {
    unsigned offset = addr & 0x3FFF;
    unsigned blk_no = addr >> 14;
    // Проверавамо присутност блока у меморији
    if (PMTP[blk_no] & 0x8000_0000) {
        // Блок се налази у меморији
        unsigned phy_addr = PMT[blk_no] << 2;
        wphy(phy_addr + offset, data);

        // Постављање dirty бита није било стриктно тражено на испиту
        PMTP[blk_no] |= 0x4000_0000;
    } else {
        // Блок се мора довући са диска
        unsigned block_no = PMT[blk_no] & 0x3FFF_FFFF;
        load(block_no);
        // Рекурзивни позив упада у горњу грану if-а.
        write(addr, data);
    }
}

4. zadatak

Postavka

Posmatra se proces pokrenut nad programom run dobijenim povezivanjem sa deljenom bibliotekom libfoo.so. Deljena biblioteka libfoo.so sadrži funkcije bar i baz čije su adrese unutar libfoo.so 0x1218 i 0x12C4 respektivno, a sama deljena biblioteka libfoo.so mapirana je počev od adrese 0x4FFF0000 unutar adresnog prostora posmatranog procesa.

Program run, koji predstavnja PIC shared object ELF datoteku, mapiran je počev od adrese 0x7EEE0000 unutar adresnog prostora posmatranog procesa. Program run od deljenih biblioteka koristi isključivo libfoo.so i poziva njene dve funkcije bar i baz koristeći lenjo povezivanje. Ukoliko je poznat deo .plt sekcije programa run, naveden u nastavku, potrebno je uraditi sledeće.

  1. [2] Odrediti na kojoj adresi se nalazi .got.plt sekcija programa run.
  2. [4] Popuniti .plt sekciju (zameniti svako pojavljivanje znakova pitanja odgovarajućom vrednošću) ukoliko je poznato da se ulaz za funkciju bar unutar .plt sekcije nalazi ispred ulaza za funkciju baz unutar .plt sekcije.
  3. [2] Navesti vrednosti koje se nalaze u ulazima .got.plt sekcije, koji odgovaraju simbolima bar i baz, u trenutku pre nego što je posmatrani proces izvršio prvi poziv bilo koje funkcije iz deljene biblioteke libfoo.so.
  4. [2] Navesti vrednosti koje se nalaze u ulazima .got.plt sekcije, koji odgovaraju simbolima bar i baz, u trenutku nakon što je posmatrani proces izvršio poziv funkcije bar, a pre poziva funkcije baz.
Disassembly of section .plt:
0000000000001060 <.plt>:
  1060: ff 35 a2 42 00 00                push QWORD PTR [rip + 0x42a2]
  1066: ff 25 a4 42 00 00                jmp QWORD PTR [rip + 0x42a4]
  106c: 0f 1f 40 00                      nop DWORD PTR [rax + 0x00]
  1070: ff 25 ?? ?? ?? ??                jmp QWORD PTR [rip + ??]
  1076: 68 00 00 00 00                   push 0x00
  107b: e9 ?? ?? ?? ??                   jmp ??
  1080: ff 25 ?? ?? ?? ??                jmp QWORD PTR [rip + ??]
  1086: 68 01 00 00 00                   push 0x01
  108b: e9 ?? ?? ?? ??                   jmp ??

Rešenje

Adresu .got.plt sekcije može se naći razrešavanjem pomeraja u nultom ulazu .plt sekcije. Instrukcija push na 0x1060 kao operand ima prvi ulaz u GOT tabeli. Veličina ulaza u GOT tabeli je 8 bajta. Odatle:

GOT[1] = rip + 0x42a2
GOT[1] = 0x1066 + 0x42a2
GOT[1] = 0x5308
GOT[0] = GOT[1] - 1 * 8 = 0x5308 - 8 = 0x5300

Isti rezultat se dobija korišćenjem operanda jmp instrukcije na 0x1066, koja ukazuje na drugi ulaz:

GOT[2] = rip + 0x42a4
GOT[2] = 0x106c + 0x42a4
GOT[2] = 0x5310
GOT[0] = GOT[2] - 2 * 8 = 0x5310 - 0x10 = 0x5300

Struktura GOT tabele:

Adresa Ulaz Sadržaj
0x5300
0 .dynamic
0x5308 1 .rel.dyn
0x5310 2 dinamički linker
0x5318 3 bar()
0x5320 4 baz()

Prvi ulaz PLT-a pripada funkciji bar. Instrukcija jmp na 0x1070 treba da skače na treći ulaz u GOT, a jmp na 0x107b na nulti ulaz PLT-a:

0x5318 - 0x1076 = 0x42a2
0x1060 - 0x1080 = 0xffffffe0

Drugi ulaz PLT-a pripada funkciji baz. Instrukcija jmp na 0x1080 treba da skače na četvrti ulaz u GOT, a jmp na 0x108b na nulti ulaz PLT-a:

0x5320 - 0x1086 = 0x429a
0x1060 - 0x1090 = 0xffffffd0

Sadržaj .plt sekcije:

Disassembly of section .plt:
0000000000001060 <.plt>:
  1060: ff 35 a2 42 00 00                push QWORD PTR [rip + 0x42a2]
  1066: ff 25 a4 42 00 00                jmp QWORD PTR [rip + 0x42a4]
  106c: 0f 1f 40 00                      nop DWORD PTR [rax + 0x00]
  1070: ff 25 a2 42 00 00                jmp QWORD PTR [rip + 0x42a2]
  1076: 68 00 00 00 00                   push 0x00
  107b: e9 e0 ff ff ff                   jmp 1060
  1080: ff 25 9a 42 00 00                jmp QWORD PTR [rip + 0x429a]
  1086: 68 01 00 00 00                   push 0x01
  108b: e9 d0 ff ff ff                   jmp 1060

Sadržaj GOT tabele pre pozivanja bilo koje funkcije iz libfoo.so:

  5318: 76 10 ee 7e 00 00 00 00
  5320: 86 10 ee 7e 00 00 00 00

Sadržaj GOT tabele nakon što je posmatrani proces izvršio poziv funkcije bar, a pre poziva funkcije baz:

  5318: 18 12 ff 4f 00 00 00 00
  5320: 86 10 ee 7e 00 00 00 00