I have always believed that resolving absolute addresses is completely the linker's job. That is, after the linker combines all object files into one executable, it will then modify all absolute addresses to reflect the new location inside the executable. But after reading in here that the loader does not have to place programs text at the address specified by the linker, I got really confused.
Take this code for example
Main.c
void printMe();
int main(){
printMe();
return 0;
}
Foo.c
/* Lots of other functions*/
void printMe(){
printf("Hello");
}
Say that after linking, the code for main
gets placed at address 0x00000010 and the code for printMe
gets placed at address 0x00000020. Then when the program is launched, the loader will indeed load main and printMe
to their virtual addresses as specified by the linker. But if the loader does not load the program in that manner, then won't that break all absolute address references.
A program is normally composed of several modules created by a linker. There is the executable and usually a number of shared libraries. On some systems one executable can load another executable and call it's starting routine as a function.
If all these compiled uses had fixed addresses, it is likely there would be conflicts upon loading. If two linked modules used the same address, the application could not load.
For decades, relocatable code has been the solution to that problem. A module can be loaded anywhere. Some system take this to the next step and randomly place modules in memory for security.
There are some situations where code cannot be purely relocatable.
If you have something like this:
static int b, *a = &b ;
the initialization depends upon where the model is placed in memory (and where "b" is located). Linkers usually generate information for such constructs so that the loader can fix them up.
Thus, this is not correct:
I have always believed that resolving absolute addresses is completely the linker's job.