Operating Systems 2014F Lecture 7
Modern systems do not do static linking, instead they do dynamic linking.
- fPIC
ASLR
dynamic linking at compile time
- insert stubs
at runtime - mmap libraries - update tables
Wonder what system calls happen when I run a statically linked version of the program. Multithreaded support, there are some system calls that happen, no matter what that's there to set the thread state, even if your program isn't multithreaded. Complicated. Key things in the tutorial today: looking in the face of some of this complexity. ok what does the assembly look like. What does the object code look like, what is this linking that happens? Do expect you to understand a couple of key bits, and why it is all there. The main idea here is dynamic linking.
One real benefit of having a library being loaded dynamically, it will be mapped into different addresses, and different address spaces for different processes. You might have 100 copies, how many copies of the c library is loaded into memory. When you mmap a file into one process, and you mmap it into another process, it doesn't take any additional memory. The data is the same. The position in memory will be different for different processes. That's when you talk about shared libraries. We are talking about shared in memory. THat means you can have these very big libraries loaded in. Only the parts of the library that are loaded are those that are referenced. The other part is stored on disk. As a user space programmer you don't have to worry about this. If you do low level programming, you will see segments.
Why do we have this model of how the program works? Somehow it's historic. Forget this whole virtual address space. We are doing the redirection inside the address space. Why don't we just access the physical memory. You could still keep things separate. That's not how most of the code we have that expects how the world to work. It's done, now it runs all the code.
the mental model you have in your head: while there are absolute addresses, much of the code in data we reference, are not in terms of absolute addresses, they are in terms of relative addresses. There is some sort of base, a base address, this is added to the relative address.
for a "segment"
base + offset (relative) => absolute address relative - addresses that you see
you have to have the name of the segment, know which segment you are talking about. Which register you are using relative to the base address. Whatever data we want to access. We keep one register with the base address of the data segment. This is the stuff the compiler worries about and we don't.
Can you run out of virtual memory? You don't have room to allocate anything because your address space is full? It is possible. The 32 bit address space only has 4 GB. Not that much space. We are moving towards / we have 64 bit address space. It's not like you would actually allocate that much memory.
This is the low level mechanism, - base and bounds. One thing to keep in mind about segments - the size of the segment is variable. The range of valid offsets may vary in size alot. There is a different size to each segment, when you load it into memory, you have to keep in mind the size.
None of this has anything to do with physical addresses. These are absolute virtual addresses. Before computers used to run one program at a time in a single address space. It is easier to emulate having multiple physical computers in a sense, then to have everyone share a computer.
You want multiple address spaces you have multiple computers, with processes talking to each other. But then you are talking about networking.