We finished up deadlock, covering the banker's algorithm. See notes from last lecture for details.
The address space of a process contains all the data that needs to be present for the process to execute:
address | contents | description |
---|---|---|
high | kernel code | to service traps, the processor needs to jump to the trap handler routine. This means the code must be present in memory at all times. |
heap | dynamically allocated memory (allocated using malloc or new). Typically placed at the top of the address space so that it can grow down into empty space | |
empty space | for the heap to grow into | |
mapped files | for the operating system to place special addresses, such as memory-mapped device addresses in a microkernel, or memory shared between processes | |
empty space | for the stack to grow into | |
stack | stores local variables; grows when a function is called | |
data | stores global variables | |
low | text | the executable code |
The process by which symbolic labels (such as function names or global variables) in assembly code become actual addresses in a program is called linking. Linking can happen at many places in the compilation process:
during compilation (static linking). When the program is compiled, all of the symbolic names are known, as are the sizes of each of the memory ranges they refer to. It is therefore possible to allocate addresses at compilation time and bake them into the executable file.
during loading. Static linking may be undesirable if programs make use of many shared libraries. With static linking, each of a large number of executable files will contain copies of each of several library functions. These will not be identical copies, because the pointers will have been linked differently.
These libraries can be shared between applications by deferring linking until the programs are loaded.
On unix, the ldd
command will print the list of shared libraries that will be linked with an executable when it is loaded.
$ ldd `which true`
linux-vdso.so.1 => (0x00007ffc1e191000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd776925000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd776cea000)
$ ldd firefox
linux-vdso.so.1 => (0x00007ffd5666e000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f45e1446000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f45e1242000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f45e0f3e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f45e0c38000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f45e0873000)
/lib64/ld-linux-x86-64.so.2 (0x00007f45e1880000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f45e065d000)