Static initialization
Let’s start simply with a global static variable
Although it looks like an uninitialized variable, the C language guarantees that global variables are zeroed by default. (And it’s cheap to implement, since the variables reside in well known memory, which is zeroed when allocated.)
Another step is
initialization with a constant. Piece of cake, the value will be stored written
into the .data
section.
Let’s get indirect
We can’t store a constant into .data
section because we don’t know what the
address of val
will be.
That’s where relocations come handy. We only reserve sufficient space in
.data
under given offset and add a respective relocation entry into a
relocation table.
Basically, the entry says: “After sections are mapped into memory, take address
of val
and patch it onto offset ptr_val
.”
Let’s say that for some reason we want to store additional data in lower bits of a pointer variable
Trying to compile this spits the error:
No wonder, we modify the address and that operation does not fit into the relocations table, so compiler complains about non-constant expression.
What about the following code?
The compilation succeeds :-o If you are thinking of arrays right now, you are nailing it.
The relocation entries actually allow specifing an addend for each resolved address.
As a closing note, let’s try different compiler for the mark_ptr
example
Succeeded, but that is another language and another story…