It is operating system specific; I am answering for Linux only.
First your figure is grossly incorrect in practice, since most programs are dynamically linked to several shared object libraries (including libc6.so
...). See also ld.so(8), elf(5), execve(2). There is no single text
section (but many "text" like segments). Read about the pmap and objdump commands.
Then, you can understand the address space of a process of pid 1234 with cat /proc/1234/maps
; read more about proc(5)... From inside the program, read /proc/self/maps
; for instance try cat /proc/$$/maps
in a shell to show the address space of the shell process, and cat /proc/self/maps
for the address space of the process running that cat
command. See also mmap(2).
You cannot really "relocate" (you actually mean "move") the text section. Some addresses are built inside the code. However, read about the -fPIE option of gcc
(for position independent executable ....).
Of course, you can access the symbols of a program (from inside) if you link it with the -rdynamic flag and if you use dlopen(3) (and dlsym
and even perhaps dladdr
....) with a NULL
first filename
argument.
See also wikipages about address space, virtual memory, ASLR, position independent code, relocation, ABI, JIT compilation, name mangling and the x86-64 ABI spec and the Advanced Linux Programming book.