The answer is "Other". You can get a glimpse of the memory layout with
cat /proc/self/maps. On my 64-bit Arch laptop::
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]
You can see that the executable gets loaded in low memory, apparently .text segment, read-only data, and .bss. Just about that is "heap". In much higher memory the C library and the "ELF file interpreter", "ld-so" get loaded. Then comes the stack. There's only one stack and one heap for any given address space, no matter how many shared libraries get loaded.
cat only seems to get the C library loaded.
cat /proc/$$/maps will get you the memory mappings of the shell from which you invoked
cat. Any shell is going to have a number of dynamically loaded libraries, but
bash will load in a large number. You'll see that there's just one "[heap]", and one "[stack]".
If you call
dlopen(), the shared object file will get mapped in the address space at a higher address than
/usr/lib/libc-2.21.so. There's something of an "implementation dependent" memory mapping segment, where all addresses returned by
mmap() show up. See Anatomy of a Program in Memory for a nice graphic.
The source for
/usr/lib/ld-2.21.so is a bit tricky, but it shares a good deal of its internals with
dlopen() isn't a second class citizen.
"vdso" and "vsyscall" are somewhat mysterious, but this Stackoverflow question has a good explanation, as does Wikipedia.