It depends on the operating system, and underlying architecture.
In Linux, for example, you can examine the /proc/self/maps pseudofile, which is actually a kernel view of the memory mappings for the current process. There's documentation here. You can also use dl_iterate_phdr() if you're only interested about shared libraries. For individual dynamic symbols (functions, global variables), there is the dlsym() function (provided by the dl library that interfaces to the dynamic linker). For all symbols, you can use the library names (or /proc/self/exe pseudo-symlink for the current executable) and examine them (even in run time) via binutils utilities, especially objdump and readelf.
(Unlike some other operating systems, in Linux and POSIXy systems in general, you can open executables (read-only) even when they are being executed. You can also rename or delete an executable file even if it is being executed, as the underlying inode (file data and metadata) is only released after the final process accessing it exits. Replacing an executable with another file thus only affects those processes that execute it after the replacement. Other systems behave differently.)
Here's what /proc/self/maps looks for the bash shell on my system:
Code:
00400000-004ef000 r-xp 00000000 08:05 1181680 /bin/bash
006ef000-006f0000 r--p 000ef000 08:05 1181680 /bin/bash
006f0000-006f9000 rw-p 000f0000 08:05 1181680 /bin/bash
006f9000-006ff000 rw-p 00000000 00:00 0
02414000-026e3000 rw-p 00000000 00:00 0 [heap]
7f3751237000-7f3751242000 r-xp 00000000 08:05 1437385 /lib/x86_64-linux-gnu/libnss_files-2.19.so
7f3751242000-7f3751441000 ---p 0000b000 08:05 1437385 /lib/x86_64-linux-gnu/libnss_files-2.19.so
7f3751441000-7f3751442000 r--p 0000a000 08:05 1437385 /lib/x86_64-linux-gnu/libnss_files-2.19.so
7f3751442000-7f3751443000 rw-p 0000b000 08:05 1437385 /lib/x86_64-linux-gnu/libnss_files-2.19.so
7f3751443000-7f375144e000 r-xp 00000000 08:05 1437413 /lib/x86_64-linux-gnu/libnss_nis-2.19.so
7f375144e000-7f375164d000 ---p 0000b000 08:05 1437413 /lib/x86_64-linux-gnu/libnss_nis-2.19.so
7f375164d000-7f375164e000 r--p 0000a000 08:05 1437413 /lib/x86_64-linux-gnu/libnss_nis-2.19.so
7f375164e000-7f375164f000 rw-p 0000b000 08:05 1437413 /lib/x86_64-linux-gnu/libnss_nis-2.19.so
7f375164f000-7f3751666000 r-xp 00000000 08:05 1437397 /lib/x86_64-linux-gnu/libnsl-2.19.so
7f3751666000-7f3751865000 ---p 00017000 08:05 1437397 /lib/x86_64-linux-gnu/libnsl-2.19.so
7f3751865000-7f3751866000 r--p 00016000 08:05 1437397 /lib/x86_64-linux-gnu/libnsl-2.19.so
7f3751866000-7f3751867000 rw-p 00017000 08:05 1437397 /lib/x86_64-linux-gnu/libnsl-2.19.so
7f3751867000-7f3751869000 rw-p 00000000 00:00 0
7f3751869000-7f3751872000 r-xp 00000000 08:05 1437396 /lib/x86_64-linux-gnu/libnss_compat-2.19.so
7f3751872000-7f3751a71000 ---p 00009000 08:05 1437396 /lib/x86_64-linux-gnu/libnss_compat-2.19.so
7f3751a71000-7f3751a72000 r--p 00008000 08:05 1437396 /lib/x86_64-linux-gnu/libnss_compat-2.19.so
7f3751a72000-7f3751a73000 rw-p 00009000 08:05 1437396 /lib/x86_64-linux-gnu/libnss_compat-2.19.so
7f3751a73000-7f3752079000 r--p 00000000 08:05 1044632 /usr/lib/locale/locale-archive
7f3752079000-7f3752234000 r-xp 00000000 08:05 1437402 /lib/x86_64-linux-gnu/libc-2.19.so
7f3752234000-7f3752433000 ---p 001bb000 08:05 1437402 /lib/x86_64-linux-gnu/libc-2.19.so
7f3752433000-7f3752437000 r--p 001ba000 08:05 1437402 /lib/x86_64-linux-gnu/libc-2.19.so
7f3752437000-7f3752439000 rw-p 001be000 08:05 1437402 /lib/x86_64-linux-gnu/libc-2.19.so
7f3752439000-7f375243e000 rw-p 00000000 00:00 0
7f375243e000-7f3752441000 r-xp 00000000 08:05 1437389 /lib/x86_64-linux-gnu/libdl-2.19.so
7f3752441000-7f3752640000 ---p 00003000 08:05 1437389 /lib/x86_64-linux-gnu/libdl-2.19.so
7f3752640000-7f3752641000 r--p 00002000 08:05 1437389 /lib/x86_64-linux-gnu/libdl-2.19.so
7f3752641000-7f3752642000 rw-p 00003000 08:05 1437389 /lib/x86_64-linux-gnu/libdl-2.19.so
7f3752642000-7f3752667000 r-xp 00000000 08:05 1436281 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f3752667000-7f3752866000 ---p 00025000 08:05 1436281 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f3752866000-7f375286a000 r--p 00024000 08:05 1436281 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f375286a000-7f375286b000 rw-p 00028000 08:05 1436281 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f375286b000-7f375288e000 r-xp 00000000 08:05 1437399 /lib/x86_64-linux-gnu/ld-2.19.so
7f3752a62000-7f3752a65000 rw-p 00000000 00:00 0
7f3752a7c000-7f3752a84000 r--p 00000000 08:05 1312704 /usr/share/locale-langpack/en_GB/LC_MESSAGES/bash.mo
7f3752a84000-7f3752a8b000 r--s 00000000 08:05 1062844 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
7f3752a8b000-7f3752a8d000 rw-p 00000000 00:00 0
7f3752a8d000-7f3752a8e000 r--p 00022000 08:05 1437399 /lib/x86_64-linux-gnu/ld-2.19.so
7f3752a8e000-7f3752a8f000 rw-p 00023000 08:05 1437399 /lib/x86_64-linux-gnu/ld-2.19.so
7f3752a8f000-7f3752a90000 rw-p 00000000 00:00 0
7ffe2fa79000-7ffe2fa9a000 rw-p 00000000 00:00 0 [stack]
7ffe2fabf000-7ffe2fac1000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Because it is a kernel-generated pseudofile (generated by the kernel directly, whenever accessed), it is never localized, and the format is stable; it will not change in incompatible ways. (The Linux kernel developers are strict about that, and that's why there are a number of pseudofiles in the /proc/PID/ directory with overlapping contents.)
The entries with no filename/description attached are memory the process allocated via mmap(). [heap] refers to initial heap only, the one that can be grown via sbrk(). (The GNU C library, for example, uses the latter for small allocations, but mmap() for larger allocations. Other POSIXy systems have different heuristics, but in general behave roughly similarly.)
To track individual dynamic allocations, the malloc() et al. memory allocation functions can be interposed (by a dynamic library, using LD_PRELOAD_LIB environment variable to load an extra dynamic library to the process, which replaces/interposes the original functions), and tracked that way.