Les bibliotheques dynamiques

Elles sont references dans les programmes par nom (pas par path).
Versionning : Major.Minor.Patch_number
Patch number : Juste la fixation d’un bug. Mais l’API reste la meme.
Minor : Ajout d’une fonctionnalite. Mais reste binary compatible
Major : On casse le code existant. L’API voit son fonctionnement modifie.

Pour les bibliotheques :
libc.so.6 : SONAME
libc.so : NAME

A l’interieur du fichier portant le NOM, il y a marque son SONAME.
Ce jeu est fait avec un systeme de liens symboliques.

libtoto.so.1.0.0<-| CODE
                  |
    libtoto.so.1 -| SONAME
                  |
      libtoto.so -  LIB

Il y a aussi dans une bibliotheque avec plusieurs versions de symboles pour
eviter une multiplication inutile de binaire.

Mecanisme vs policy
Mecanisme : La fonctionnalite qui permet de…
C’est une partie qui n’est modifie souvent, sous peine de planter toute la
machine
Policy : La maniere dont je m’en sers…
C’est une partie qui est modifie tres regulierement.
Le kernel m’expose un mecanisme.

Le kernel ne connait pas les .so, par contre s’il voit INTERP, il va charger
un interpreteur ld.so. A l’execution, on charge le programme, charge
l’interpreteur. On saute dans l’interpreteur et on charge les biblio dyn puis
on revient dans le programme.

AS           STACK
|-------|
| LD.SO |    |------|
|-------|  --| AUXV |
|       | |  |------|
|       | |  | ENV  |
|-------| |  |------|
|  EXE  |<   | ARGV |
|-------|    |------|
|       |    | ARGC |
             |------|

Segments :

Casser du programme deja compiler est tres simple
En C, seul la taille d’un pointeur ne bouge pas.
Pour eviter de tous casser, on n’expose pas la structure mais un pointeur sur
la structure.

Au linkage, on “bouche les trous”. Mais pour les .so, on l’appelle plus tard.
Donc il reste encore des trous.
On construit une table avec les differents reloc de la lib. Il s’agit d’une
table de data.
Faire du chargement a la demande. On ne fait pas le realloc dans le tableau de
toute la lib, mais uniquement pour les symboles necessaires.

On appelle pas puts directement mais call puts@plt.
PLT : Procedure Linked Table
GOT : Global Object Table

puts@PLT                GOT
                        |------------------|
plt0:               |-->|       value      |
    push    *GOT[0]-|   |------------------|
    jmp     *GOT[1]---->|dl_runtime_resolve|
                        |------------------|
jmp     *GOT[N]      |->|                  |
push    $0 ----------|  |------------------|
jmp     plt0            |                  |

Le comportement ci-dessus est le meme pour tous les symboles avec une
visibilitee default.

Executer une instruction

                    Registry
     ----------------|------|
    IN        IN     |      |
      __      __     |      |
     \  \___/  /     |      |
OP--> \  ALU  /      |      |
       -------       |      |
       OUT---------->|      |


Pipeline :

Fetch   Decode   Execute   Memory   Writeback
 I1
 I2       I1
 I3       I2        I1

Bypass unit : On recupere les resultats des instructions precedentes ou
suivantes directement sur le bus.

jmp xxx :
Le RISC detecte au decode les jmp, et skip le jmp en executant la ligne
d’apres

Predicteur de branchement :
Maintenir une stats local sur un jmp dans les deux sens.

Rowhammer : Attaque sur le cache sur les barrettes memoires.
Clementine Maurice : Lien persistant entre deux CPU fiables.
Spectre/Meltdown : Leak entre deux programmes