A resposta é "Outro". Você pode obter um vislumbre do layout de memória com cat /proc/self/maps
. No meu laptop Arch de 64 bits ::
00400000-0040c000 r-xp 00000000 08:02 1186758 /usr/bin/cat
0060b000-0060c000 r--p 0000b000 08:02 1186758 /usr/bin/cat
0060c000-0060d000 rw-p 0000c000 08:02 1186758 /usr/bin/cat
02598000-025b9000 rw-p 00000000 00:00 0 [heap]
7fe4b805c000-7fe4b81f5000 r-xp 00000000 08:02 1182914 /usr/lib/libc-2.21.so
7fe4b81f5000-7fe4b83f5000 ---p 00199000 08:02 1182914 /usr/lib/libc-2.21.so
7fe4b83f5000-7fe4b83f9000 r--p 00199000 08:02 1182914 /usr/lib/libc-2.21.so
7fe4b83f9000-7fe4b83fb000 rw-p 0019d000 08:02 1182914 /usr/lib/libc-2.21.so
7fe4b83fb000-7fe4b83ff000 rw-p 00000000 00:00 0
7fe4b83ff000-7fe4b8421000 r-xp 00000000 08:02 1183072 /usr/lib/ld-2.21.so
7fe4b85f9000-7fe4b85fc000 rw-p 00000000 00:00 0
7fe4b85fe000-7fe4b8620000 rw-p 00000000 00:00 0
7fe4b8620000-7fe4b8621000 r--p 00021000 08:02 1183072 /usr/lib/ld-2.21.so
7fe4b8621000-7fe4b8622000 rw-p 00022000 08:02 1183072 /usr/lib/ld-2.21.so
7fe4b8622000-7fe4b8623000 rw-p 00000000 00:00 0
7ffe430c4000-7ffe430e5000 rw-p 00000000 00:00 0 [stack]
7ffe431ed000-7ffe431ef000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Você pode ver que o executável é carregado em pouca memória, aparentemente. segmento de texto, dados somente leitura e .bss. Apenas sobre isso é "heap". Em uma memória muito maior, a biblioteca C e o "interpretador de arquivos ELF", "ld-so" são carregados. Então vem a pilha. Há apenas uma pilha e um heap para qualquer espaço de endereço, não importa quantas bibliotecas compartilhadas sejam carregadas. cat
parece apenas obter a biblioteca C carregada.
Fazer cat /proc/$$/maps
fornecerá os mapeamentos de memória do shell a partir do qual você chamou cat
. Qualquer shell terá várias bibliotecas carregadas dinamicamente, mas zsh
e bash
serão carregadas em um grande número. Você verá que há apenas um "[heap]" e um "[pilha]".
Se você chamar dlopen()
, o arquivo de objeto compartilhado será mapeado no espaço de endereço em um endereço superior a /usr/lib/libc-2.21.so
. Há um segmento de mapeamento de memória "dependente da implementação", em que todos os endereços retornados por mmap()
são exibidos. Veja Anatomia de um programa na memória para um bom gráfico.
A fonte para /usr/lib/ld-2.21.so
é um pouco complicada, mas compartilha uma boa parte de seus internos com dlopen()
. dlopen()
não é um cidadão de segunda classe.
"vdso" e "vsyscall" são um tanto misteriosos, mas esta questão do Stackoverflow tem uma boa explicação, assim como a Wikipedia.