[so] Rezolvarea subiectelor de la examen

Stefan Bucur stefan.bucur at gmail.com
Sun Feb 17 22:44:24 EET 2008


2008/2/17 Mihai Balan <mihai.balan at gmail.com>:

>
> 5. De ce o bibliotecă dinamică are nevoie de relocări la încărcare? De ce
> intră acest lucru în conflict cu partajarea codului şi a datelor read-only
> între instanţele folosite în mai multe procese? Ce soluţie este folosită în
> cazul bibliotecilor dinamice partajabile?

O sa incerc sa ma exprim cat mai simplu si mai "plastic" :)

A: Relativ la prima intrebare: orice biblioteca, pentru a fi utilizata
de catre un proces, trebuie sa aiba continutul (cod + date) mapat
undeva in spatiul de adrese al procesului respectiv. O compilare
standard genereaza cod si date "statice" (adica pozitia lor in memorie
este cunoscuta de la inceput, retinuta in executabilul generat), iar
modul in care acestea sunt asezate in memorie este, evident, depedent
de continutul programului. Atunci cand o biblioteca este incarcata
dinamic in memorie, ea trebuie "sa-si gaseasca loc" printre codul si
datele deja existente in spatiul de memorie al procesului. Din pacate
codul generat de un compilator, in mod normal, contine in instructiuni
adrese fixe de memorie, astfel ca este nevoie de procedura de relocare
(modificarea instructiunilor care includ adresele de memorie ce
trebuie "ajustate") pentru a putea aseza codul in alta locatie din
spatiul de adrese al procesului.

Relativ la cea de-a doua intrebare: Partajarea codului si a datelor
read-only presupune maparea acelorasi pagini de memorie in spatiile de
adrese ale mai multor procese. Din pacate relocarea presupune
modificarea acelor portiuni de cod care contin adrese de memorie, iar
modificarile sunt specifice fiecarui proces (depinzand de locul unde a
fost relocat codul); de aici rezulta ca nu mai putem partaja codul
intre procese, fiecare avand nevoie de o varianta diferita a codului
bibliotecii.

Relativ la a treia intrebare: La o examinare mai atenta a problemei,
ajungem la concluzia ca modificarile care trebuie facute nu sunt asa
mari (in fond si la urma urmei, cat de mult cod contine adrese de
memorie, mai ales unul compilat, unde GCC-ul se foloseste cat de mult
poate de registri?). Problema e ca acele instructiuni sunt imprastiate
peste tot prin cod, si e suficient ca doar una intr-o pagina sa
trebuiasca sa fie modificata, si toata pagina nu mai poate fi
partajata. Solutia e sa se grupeze cumva intr-o parte toate adresele
ce trebuie modificate (relocate), si acelea sa fie specifice fiecarui
proces, si codul ramas (adica majoritatea spatiului ocupat) sa fie
constant si partajabil intre procese. In mod concret, se foloseste o
tabela (Global Offset Table), in care fiecare element e o adresa
relocata, iar codul face referire indirect la adresa respectiva
printr-un index in tabela respectiva, iar indexul este acelasi pentru
toate procesele :)

Stefan Bucur


More information about the so mailing list