Ce n'est pas le cas de «presque tous les OS». Les types de zones de mémoire représentés sont assez typiques, mais il n'y a aucune raison pour qu'ils soient dans un ordre particulier, et il peut y avoir plus d'un morceau d'un type donné.
Sous Linux, vous pouvez regarder l'espace d'adressage d'un processus avec cat /proc/$pid/maps
où se $pid
trouve l'ID du processus, par exemple cat /proc/$$/maps
pour regarder le shell à cat
partir duquel vous exécutez , ou cat /proc/self/maps
pour regarder les cat
propres mappages du processus. La commande pmap
produit une sortie légèrement plus agréable.
08048000-08054000 r-xp 00000000 08:01 828061 /bin/cat
08054000-08055000 r--p 0000b000 08:01 828061 /bin/cat
08055000-08056000 rw-p 0000c000 08:01 828061 /bin/cat
08c7f000-08ca0000 rw-p 00000000 00:00 0 [heap]
b755a000-b7599000 r--p 00000000 08:01 273200 /usr/lib/locale/en_US.utf8/LC_CTYPE
b7599000-b759a000 rw-p 00000000 00:00 0
b759a000-b76ed000 r-xp 00000000 08:01 269273 /lib/tls/i686/cmov/libc-2.11.1.so
b76ed000-b76ee000 ---p 00153000 08:01 269273 /lib/tls/i686/cmov/libc-2.11.1.so
b76ee000-b76f0000 r--p 00153000 08:01 269273 /lib/tls/i686/cmov/libc-2.11.1.so
b76f0000-b76f1000 rw-p 00155000 08:01 269273 /lib/tls/i686/cmov/libc-2.11.1.so
b76f1000-b76f4000 rw-p 00000000 00:00 0
b770b000-b7712000 r--s 00000000 08:01 271618 /usr/lib/gconv/gconv-modules.cache
b7712000-b7714000 rw-p 00000000 00:00 0
b7714000-b7715000 r-xp 00000000 00:00 0 [vdso]
b7715000-b7730000 r-xp 00000000 08:01 263049 /lib/ld-2.11.1.so
b7730000-b7731000 r--p 0001a000 08:01 263049 /lib/ld-2.11.1.so
b7731000-b7732000 rw-p 0001b000 08:01 263049 /lib/ld-2.11.1.so
bfbec000-bfc01000 rw-p 00000000 00:00 0 [stack]
Vous pouvez voir le code et les données en lecture-écriture (texte et BSS) de l'exécutable, puis le tas, puis un fichier mappé en mémoire, puis un peu plus de données en lecture-écriture, puis du code, des données en lecture seule et en lecture- écrire des données à partir d'une bibliothèque partagée (texte et BSS à nouveau), davantage de données en lecture-écriture, une autre bibliothèque partagée (plus précisément, l'éditeur de liens dynamique), et enfin la pile du seul thread.
Le code du noyau utilise ses propres plages d'adresses. Sur de nombreuses plates-formes, Linux utilise la partie supérieure de l'espace d'adressage pour le noyau, souvent le 1 Go supérieur. Idéalement, cet espace serait suffisant pour mapper le code du noyau, les données du noyau et la mémoire système (RAM) et chaque périphérique mappé en mémoire. Sur les PC 32 bits typiques d'aujourd'hui, ce n'est pas possible, ce qui nécessite des contorsions qui n'intéressent que les pirates du noyau.
Pendant que le code du noyau gère un appel système, idéalement (lorsque les contorsions susmentionnées ne sont pas en place), la mémoire du processus est mappée aux mêmes adresses. Cela permet aux processus de transmettre des données au noyau, et le noyau peut lire directement à partir du pointeur. Ce n'est pas un gros gain, cependant, car les pointeurs doivent être validés de toute façon (afin que le processus ne puisse pas inciter le noyau à lire dans la mémoire auquel le processus n'est pas censé avoir accès).
Les zones de mémoire à l'intérieur de l'espace du noyau Linux sont assez complexes. Il existe plusieurs pools de mémoire différents, et les principales distinctions ne concernent pas l'origine de la mémoire, mais plutôt avec qui elle est partagée. Si vous êtes curieux à leur sujet, commencez par LDD3 .
where.c
, sur Ubuntu 11.04 en utilisantgcc where.c -o where
; signale "principal à 0x80483c4". Essayéreadelf -S where
, et il rapporte, dire "[13] .text PROGBITS 08048310 ..." qui ressemble à peu près non? Bien que j'obtienne également "ac at 0xbfb035a0" et "local at 0xbfb0358c", cette plage d'adresses (0xbf ...) ne semble pas être signalée parreadelf -S
.