You are on page 1of 19

Primjer rada linkera

Prikazati proces povezivanja datih fajlova. Smatrati da ciljni


fajl treba da bude relokatibilan i pripremljen tako da se bez
prepravljanja može učitati počev od adrese 0. Smatrati da
redosled prosleđivanja fajlova linkeru odgovara redosledu
prikazanom na slici (s leva na desno).

#ime sek vr vel vid atr


text 1 0 8 l RXP
data 2 0 6 l RWP
bss 3 0 4 l RW
a 1 2 g #ime sek vr vel vid atr #ime sek vr vel vid atr
c 2 4 g data 1 0 4 l RWP text 1 0 8 l RP
b 3 1 g bss 2 0 3 l RW bss 2 0 4 l RW
e UND 0 g f 1 3 g e 1 3 g
#.rel.text g 2 1 g g UND 0 g
0 R_386_PC32 7 c UND 0 g #.rel.text
4 R_386_32 2 #.rel.data 0 R_386_PC32 4
FC FF FF FF 02 00 00 00 0 R_386_32 5 4 R_386_PC32 2
11 11 11 11 11 11 00 00 00 00 FC FF FF FF FE FF FF FF
#ime sek vr vel vid atr #ime sek vr vel vid atr
text 1 0 8 l RXP text 1 0 8 l RP
data 2 0 6 l RWP bss 2 0 4 l RW
bss 3 0 4 l RW e 1 3 g
a 1 2 g g UND 0 g
c 2 4 g #ime sek vr vel vid atr #.rel.text
b 3 1 g text 1 00 10 l RP 0 R_386_PC32 4
e UND 0 g data 2 10 0A l RWP 4 R_386_PC32 2
#.rel.text bss 3 1A 0B l RW FC FF FF FF FE FF FF FF
0 R_386_PC32 7 a 1 02 g
4 R_386_32 2 c 2 14 g
FC FF FF FF 02 00 00 00 b 3 1B g
11 11 11 11 11 11 f 2 19 g
g 3 1F g
#ime sek vr vel vid atr e 1 0B g
data 1 0 4 l RWP #.rel.text
bss 2 0 3 l RW 4 R_386_32 2
f 1 3 g 8 R_386_PC32 3
g 2 1 g 0C R_386_PC32 3
c UND 0 g #.rel.data
#.rel.data 16 R_386_32 2
0 R_386_32 5 07 00 00 00 12 00 00 00 13 00 00 00 13 00 00 00
00 00 00 00 11 11 11 11 11 11 14 00 00 00
#ime sek vr vel vid atr #ime sek vr vel vid atr
text 1 0 8 l RXP text 1 0 8 l RP
data 2 0 6 l RWP bss 2 0 4 l RW
bss 3 0 4 l RW e 1 3 g
a 1 2 g g UND 0 g
c 2 4 g #ime sek vr vel vid atr #.rel.text
b 3 1 g text 1 00 10 l RP 0 R_386_PC32 4
e UND 0 g data 2 10 0A l RWP 4 R_386_PC32 2
#.rel.text bss 3 1A 0B l RW FC FF FF FF FE FF FF FF
0 R_386_PC32 7 a 1 02 g
4 R_386_32 2 c 2 14 g
FC FF FF FF 02 00 00 00 b 3 1B g
11 11 11 11 11 11 f 2 19 g
g 3 1F g
#ime sek vr vel vid atr e 1 0B g
data 1 0 4 l RWP #.rel.text
bss 2 0 3 l RW 4 R_386_32 2
f 1 3 g 8 R_386_PC32 3
g 2 1 g 0C R_386_PC32 3
c UND 0 g #.rel.data
#.rel.data 16 R_386_32 2
0 R_386_32 5 07 00 00 00 12 00 00 00 13 00 00 00 13 00 00 00
00 00 00 00 11 11 11 11 11 11 14 00 00 00
#ime sek vr vel vid atr #ime sek vr vel vid atr
text 1 0 8 l RXP text 1 0 8 l RP
data 2 0 6 l RWP bss 2 0 4 l RW
bss 3 0 4 l RW e 1 3 g
a 1 2 g g UND 0 g
c 2 4 g #ime sek vr vel vid atr #.rel.text
b 3 1 g text 1 00 10 l RP 0 R_386_PC32 4
e UND 0 g data 2 10 0A l RWP 4 R_386_PC32 2
#.rel.text bss 3 1A 0B l RW FC FF FF FF FE FF FF FF
0 R_386_PC32 7 a 1 02 g
4 R_386_32 2 c 2 14 g
FC FF FF FF 02 00 00 00 b 3 1B g
11 11 11 11 11 11 f 2 19 g
g 3 1F g
#ime sek vr vel vid atr e 1 0B g
data 1 0 4 l RWP #.rel.text
bss 2 0 3 l RW 4 R_386_32 2
f 1 3 g 8 R_386_PC32 3
g 2 1 g 0C R_386_PC32 3
c UND 0 g #.rel.data
#.rel.data 16 R_386_32 2
0 R_386_32 5 07 00 00 00 12 00 00 00 13 00 00 00 13 00 00 00
00 00 00 00 11 11 11 11 11 11 14 00 00 00
#ime sek vr vel vid atr #ime sek vr vel vid atr
text 1 0 8 l RXP text 1 0 8 l RP
data 2 0 6 l RWP bss 2 0 4 l RW
bss 3 0 4 l RW e 1 3 g
a 1 2 g g UND 0 g
c 2 4 g #ime sek vr vel vid atr #.rel.text
b 3 1 g text 1 00 10 l RP 0 R_386_PC32 4
e UND 0 g data 2 10 0A l RWP 4 R_386_PC32 2
#.rel.text bss 3 1A 0B l RW FC FF FF FF FE FF FF FF
0 R_386_PC32 7 a 1 02 g
4 R_386_32 2 c 2 14 g
FC FF FF FF 02 00 00 00 b 3 1B g
11 11 11 11 11 11 f 2 19 g
g 3 1F g
#ime sek vr vel vid atr e 1 0B g
data 1 0 4 l RWP #.rel.text
bss 2 0 3 l RW 4 R_386_32 2
f 1 3 g 8 R_386_PC32 3
g 2 1 g 0C R_386_PC32 3
c UND 0 g #.rel.data
#.rel.data 16 R_386_32 2
0 R_386_32 5 07 00 00 00 12 00 00 00 13 00 00 00 13 00 00 00
00 00 00 00 11 11 11 11 11 11 14 00 00 00
Od sledeća dva objektna fajla (sledeća dva slajda) pravi se
deljena biblioteka namenjena za dinamičko vezivanje. Pod
pretpostavkom da će kod biblioteke biti mapiran na adresu
0x1000 i da će podaci biti mapirani na adresu 0x2000,
prikazati relevantni deo sadržaja deljene biblioteke. Radi
lakšeg praćenja u nastavku je dat izvorni kod od kojih
nastaje biblioteka

int cnt = 1; extern int cnt;


int flag = 2; int flag1 = 2;

int saberi(int a, int b){ int oduzmi(int a, int b){


cnt=3; cnt=1;
flag=4; flag1=2;
return a+b; return saberi(a, -b);
} }

Prevođenje: gcc -shared -fPIC -o bib.so bib.c bib1.c


Povezivanje: gcc -o p p.c ./bib.so (pogledati i zabilješke uz slajd)
Relokacije:
4: R_386_PC32 __i686.get_pc_thunk.cx
a: R_386_GOTPC _GLOBAL_OFFSET_TABLE_
10: R_386_GOT32 cnt
1c: R_386_GOT32 flag

00000000 <saberi>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: e8 fc ff ff ff call __i686.get_pc_thunk.cx
8: 81 c1 02 00 00 00 add $0x2,%ecx
e: 8b 81 00 00 00 00 mov 0x0(%ecx),%eax
14: c7 00 03 00 00 00 movl $0x3,(%eax)
1a: 8b 81 00 00 00 00 mov 0x0(%ecx),%eax
20: c7 00 04 00 00 00 movl $0x4,(%eax)
26: 8b 45 0c mov 0xc(%ebp),%eax
29: 8b 55 08 mov 0x8(%ebp),%edx
2c: 01 d0 add %edx,%eax
2e: 5d pop %ebp
2f: c3 ret
Relokacije
8: R_386_PC32 __i686.get_pc_thunk.bx
00000000 <oduzmi>: e: R_386_GOTPC
0: 55 push %ebp _GLOBAL_OFFSET_TABLE_
1: 89 e5 mov %esp,%ebp 14: R_386_GOT32 cnt
3: 53 push %ebx 20: R_386_GOT32 flag1
4: 83 ec 14 sub $0x14,%esp 3a: R_386_PLT32 saberi
7: e8 fc ff ff ff call __i686.get_pc_thunk.bx
c: 81 c3 02 00 00 00 add $0x2,%ebx
12: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax
18: c7 00 01 00 00 00 movl $0x1,(%eax)
1e: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax
24: c7 00 02 00 00 00 movl $0x2,(%eax)
2a: 8b 45 0c mov 0xc(%ebp),%eax
2d: f7 d8 neg %eax
2f: 89 44 24 04 mov %eax,0x4(%esp)
33: 8b 45 08 mov 0x8(%ebp),%eax
36: 89 04 24 mov %eax,(%esp)
39: e8 fc ff ff ff call saberi
3e: 83 c4 14 add $0x14,%esp
41: 5b pop %ebx
42: 5d pop %ebp
43: c3 ret
0x1000
saberi

oduzmi

plt0:
plt
plt1:

0x2000 &cnt
got sadržaj: &flag
&flag1
ent0
ent1
got.plt
ent2
ent.plt1
cnt
data sadržaj: flag
flag1
Relokacije:
4: R_386_PC32 __i686.get_pc_thunk.cx
a: R_386_GOTPC _GLOBAL_OFFSET_TABLE_
10: R_386_GOT32 cnt
1c: R_386_GOT32 flag

00000000 <saberi>: 00001000 <saberi>:


0: 55 push %ebp 1000: 55
1: 89 e5 mov %esp,%ebp 1001: 89 e5
3: e8 fc ff ff ff call __i686.get_pc_thunk.cx 1003: e8 28 00 00 00
8: 81 c1 02 00 00 00 add $0x2,%ecx 1008: 81 c1 04 10 00 00
e: 8b 81 00 00 00 00 mov 0x0(%ecx),%eax 100e: 8b 81 f4 ff ff ff
14: c7 00 03 00 00 00 movl $0x3,(%eax) 1014: c7 00 03 00 00 00
1a: 8b 81 00 00 00 00 mov 0x0(%ecx),%eax 101a: 8b 81 f8 ff ff ff
20: c7 00 04 00 00 00 movl $0x4,(%eax) 1020: c7 00 04 00 00 00
26: 8b 45 0c mov 0xc(%ebp),%eax 1026: 8b 45 0c
29: 8b 55 08 mov 0x8(%ebp),%edx 1029: 8b 55 08
2c: 01 d0 add %edx,%eax 102c: 01 d0
2e: 5d pop %ebp 102e: 5d
2f: c3 ret 102f: c3

00001030 <__i686.get_pc_thunk.cx>:
1030: 8b 0c 24 mov (%esp),%ecx
1033: c3 ret
Relokacije
8: R_386_PC32 __i686.get_pc_thunk.bx
00000000 <oduzmi>: e: R_386_GOTPC
0: 55 push %ebp _GLOBAL_OFFSET_TABLE_
1: 89 e5 mov %esp,%ebp 14: R_386_GOT32 cnt
3: 53 push %ebx 20: R_386_GOT32 flag1
4: 83 ec 14 3a: R_386_PLT32
sub $0x14,%esp saberi
7: e8 fc ff ff ff call __i686.get_pc_thunk.bx 103b: e8 38 00 00 00
c: 81 c3 02 00 00 00 add $0x2,%ebx 1040: 81 c3 cc 0f 00 00
12: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax 1046: 8b 83 f4 ff ff ff
18: c7 00 01 00 00 00 movl $0x1,(%eax) 104c: c7 00 01 00 00 00
1e: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax 1052: 8b 83 fc ff ff ff
24: c7 00 02 00 00 00 movl $0x2,(%eax) 1058: c7 00 02 00 00 00
2a: 8b 45 0c mov 0xc(%ebp),%eax 105e: 8b 45 0c
2d: f7 d8 neg %eax 1061: f7 d8
2f: 89 44 24 04 mov %eax,0x4(%esp) 1063: 89 44 24 04
33: 8b 45 08 mov 0x8(%ebp),%eax 1067: 8b 45 08
36: 89 04 24 mov %eax,(%esp) 106a: 89 04 24
39: e8 fc ff ff ff call saberi 106d: e8 1a 00 00 00
3e: 83 c4 14 add $0x14,%esp
41: 5b pop %ebx
42: 5d pop %ebp 00001078 <__i686.get_pc_thunk.bx>:
43: c3 ret 1078: 8b 1c 24 mov (%esp),%ebx
107b: c3 ret
plt:
0000107c <__cxa_finalize@plt-0x10>:
107c: ff b3 04 00 00 00 pushl 0x4(%ebx)
1082: ff a3 08 00 00 00 jmp *0x8(%ebx)
1088: 00 00 00 00
0000108c <saberi@plt>:
108c: ff a3 0c 00 00 00 jmp *0xc(%ebx)
1092: 68 00 00 00 00 push $0x0
1097: e9 e0 ff ff ff jmp 107c

got:
2000: R_386_GLOB_DATA cnt
2004: R_386_GLOB_DATA flag
2008: R_386_GLOB_DATA flag1
got.plt:
200c: adresa sekcije sa podacima za din.vez.
2010: informacije o linkeru
2014: ulazna tacka dinamickog linkera
2018: R_386_JUMP_SLOT saberi (početni sadržaj ove lokacije je 0x1092)
…l .dynsym 00000000 .dynsym
…l .dynstr 00000000 .dynstr
…l .rel.dyn 00000000 .rel.dyn
…l .rel.plt 00000000 .rel.plt

0000107c l .plt .plt


00001000 l .text .text
00002000 l .got .got
0000200c l .got.plt .got.plt
0000201c l .data .data
00002028 l .bss .bss
00001078 l .text __i686.get_pc_thunk.bx
00001030 l .text __i686.get_pc_thunk.cx
0000200c l *ABS* _GLOBAL_OFFSET_TABLE_
00002024 g .data flag1
00001000 g .text saberi
00001034 g .text oduzmi
0000201c g .data cnt
00002020 g .data flag
Zadatak
• Deljena biblioteka "math.so" je učitana u adresni prostor procesa "p" počev od adrese 0x2000.
Biblioteka je inicijalno napravljena za učitavanje na adresu 0x1000. Poznato je da u biblioteci
postoje funkcije saberi i pomnozi čije su adrese 0x1050 i 0x1230 redom. Takođe, poznato je i da
program "p” koristi samo jednu deljenu biblioteku ("math.so") i njene dve funkcije saberi i pomnozi.
Binarni sadržaj plt sekcije programa "p" je dat u nastavku:

4000: ff 35 f4 60 00 00 #push podatka sa zadate adrese


4006: ff 25 f8 60 00 00 #jmp na adresu koja se nalazi na adresi zadatoj u instrukciji
400c: 00 00 00 00
4010: ff 25 ?? ?? ?? ?? #indirektni skok
4016: 68 00 00 00 00 #push neposrednog podatka
401B: e9 ?? ?? ?? ?? #relativni bezuslovni skok
4020: ff 25 ?? ?? ?? ?? #indirektni skok
4026: 68 04 00 00 00 #push neposrednog podatka
402B: e9 ?? ?? ?? ?? #relativni bezuslovni skok

• a) Na kojoj adresi se nalazi got.plt sekcija programa "p"?


• b) Koristeći adresu pod a) navesti vrednosti koje treba upisati na mesto upitnika. Pri odgovaranju,
prepisati sve redove koji sadrže upitnike, s tim što umesto upitnika treba upisati odgovarajuće
vrednosti za opisanu situaciju. Ulaz u plt za funkciju saberi je ispred ulaza za funkciju pomnoži.
• c) Prikazati sadržaj ulaza got.plt sekcije koji se odnose na korišćenje simbola saberi i pomnozi, i to
u trenutku nakon što je program izvršio jedan poziv potprograma saberi, a prije prvog poziva
potprograma pomnozi.
• 4000: ff 35 f4 60 00 00 #push podatka sa zadate adrese
4006: ff 25 f8 60 00 00 #jmp na adresu koja se nalazi na adresi zadatoj u instrukciji
400c: 00 00 00 00
4010: ff 25 ?? ?? ?? ?? #indirektni skok
4016: 68 00 00 00 00 #push neposrednog podatka
401B: e9 ?? ?? ?? ?? #relativni bezuslovni skok
4020: ff 25 ?? ?? ?? ?? #indirektni skok
4026: 68 04 00 00 00 #push neposrednog podatka
402B: e9 ?? ?? ?? ?? #relativni bezuslovni skok

• a) Na kojoj adresi se nalazi got.plt sekcija programa "p"?

• Kako nulti ulaz u PLT treba da prenese kontrolu linkeru, instrukcija skoka na adresi
0x4006, i kako ze zna da got.plt[2] sadrzi adresu linkera, moze se zakljuciti da je adresa
ulaza u got.plt sa indeksom 2 vec zapisana u navedenoj instrukciji (instrukcija koristi
apsolutno indirektno adresiranje). Odatle se zakljucuje da je 0x60f8 adresa ulaza u got.plt
sa indeksom 2, pa je adresa pocetka got.plt 0x60f0.
• b) Koristeći adresu pod a) navesti vrednosti koje treba upisati na mesto upitnika. Pri odgovaranju,
prepisati sve redove koji sadrže upitnike, s tim što umesto upitnika treba upisati odgovarajuće
vrednosti za opisanu situaciju. Ulaz u plt za funkciju saberi je ispred ulaza za funkciju pomnoži.
• Instrukcije skoka na adresama 0x4010 i 0x4020 treba da skacu indirektno, koristeci kao adresu
odredista sadrzaj iz got.plt sa indeksa 3 i 4 redom. To su adrese 0x60fc i 0x6100 (u instrukcijama
se zapisuje fc 60 00 00 i 00 61 00 00). U trenutku pokretanja (prije prvog poziva ka svakoj od dvije
funkcije iz biblioteke), sadrzaj got.plt[3] treba da sadrzi adresu 0x4016, tako da instrukcija sa
adrese 0x4010 skoci na prvu sledecu instrukciju (kao da do skoka uopste nije doslo). U nastavku
izvrsavanja, na stek se stavlja indeks odgovarajuceg relokacionog zapisa (instrukcija na adresi
0x4016), a potom je potrebno skociti na nulti ulaz plt, koji ce dalje preneti kontrolu dinamickom
linkeru. Posto se radi o relativnom skoku, u instrukciju na adresi 0x401b je potrebno upisati
odgovarajući pomjeraj, tako da se skoči na adresu 0x4000 (nulti ulaz u plt). Računanje pomjeraja:
0x4000 - 0x4020 = - 0x20, a to se u drugom komplementu zapisuje kao 0xffff_ffe0, sto je sadrzaj
koji treba upisati u instrukciju na adresi 0x401b. Na slican nacin se za instrukciju na adresi nalazi
vrijednost 0x4000-0x4030, sto se zapisuje kao 0xffff_ffd0.

4000: ff 35 f4 60 00 00 #push podatka sa zadate adrese


4006: ff 25 f8 60 00 00 #jmp na adresu koja se nalazi na adresi zadatoj u instrukciji
400c: 00 00 00 00
4010: ff 25 fc 60 00 00 #indirektni skok
4016: 68 00 00 00 00 #push neposrednog podatka
401B: e9 e0 ff ff ff #relativni bezuslovni skok
4020: ff 25 00 61 00 00 #indirektni skok
4026: 68 04 00 00 00 #push neposrednog podatka
402B: e9 d0 ff ff ff #relativni bezuslovni skok

60fc: 16 40 00 00
6100: 26 40 00 00
• c) Prikazati sadržaj ulaza got.plt sekcije koji se odnose na korišćenje simbola saberi i
pomnozi, i to u trenutku nakon što je program izvršio jedan poziv potprograma saberi, a
prije prvog poziva potprograma pomnozi. Posto je program izvrsio poziv funkcije saberi,
odgovarajuci ulaz u got.plt (sa indeksom 3) je popunjen apsolutnom adresom funkcije
saberi u okviru pokrenutog programa p. Kako je opisano u postavci, ako se biblioteka ucita
na adresu 0x1000, adresa funkcije saberi je 0x1050. Posto je u okviru programa p
biblioteka ucitana na adresu 0x2000, i funkcija se pomjerila na adresu 0x2050 (na
originalnu adresu 0x1050 se doda pomjeraj pocetne adrese biblioteke 0x2000-0x1000).
Stoga je sadrzaj ulaza koji odgovara funkciji saberi 50 20 00 00, dok je sadrzaj ulaza koji
odgovara funkciji pomnozi neizmjenjen u odnosu na trenutak pokretanja opisan pod b), a
to je 26 40 00 00. Na ovaj nacin je postignuto da kada se funkcija saberi pozove sledeci
put, instrukcija na adresi 0x4010 skace direktno na pocetak funkcije saberi (pri tome koristi
indirektno adresiranje), sto znaci da za funkciju saberi vise nije potrebno pozivati dinamicki
linker.

4000: ff 35 f4 60 00 00 #push podatka sa zadate adrese


4006: ff 25 f8 60 00 00 #jmp na adresu koja se nalazi na adresi zadatoj u instrukciji
400c: 00 00 00 00
4010: ff 25 fc 60 00 00 #indirektni skok
4016: 68 00 00 00 00 #push neposrednog podatka
401B: e9 e0 ff ff ff #relativni bezuslovni skok
4020: ff 25 00 61 00 00 #indirektni skok
4026: 68 04 00 00 00 #push neposrednog podatka
402B: e9 d0 ff ff ff #relativni bezuslovni skok

60fc: 50 20 00 00
6100: 26 40 00 00
Odgovori
• a) 0x60f0
• b) 4010: ff 25 ?? ?? ?? ?? #fc 60 00 00
4016: 68 00 00 00 00
401B: e9 ?? ?? ?? ?? #e0 ff ff ff
4020: ff 25 ?? ?? ?? ?? #00 61 00 00
4026: 68 04 00 00 00
402B: e9 ?? ?? ?? ?? #d0 ff ff ff
• c) ulazi 3 i 4 u got.plt:
50 20 00 00
26 40 00 00

You might also like