Reputation: 10536
I'm trying to create a simple linker for a barebone ARM application. Currently the loader, that loads the module, will simply add the offset to all records inside the .got
and .data.rel
sections. This works fine in .got
, and for all symbols that need relocation inside .data.rel
. It will break though for all non-relocatable data, as those will get this offset too.
Example:
void some_function() { return; }
struct a {
void* fptr;
int number;
};
static struct a = {
.fptr = some_function,
.number = 0x1000,
};
Here a.fptr
will correctly address the actual location of the function, but a.number
will incorrectly hold 0x1000 + offset
, instead of just 0x1000
.
How should I distinguish between the two? Is it enough that I check the .symtab
section and only relocate addresses that are found there? But what if a symbol is actually at location 0x1000
? Or does the linker address this issue (so it will not put a function at address 0x1000
)? Does .symtabs
actuall contain all symbols that can be found inside .got
and .data.rel
?
Upvotes: 5
Views: 1526
Reputation: 9930
I wrote a basic ELF loader a while ago and I recall that you only add offsets to relocation entries marked as "R_ARM_ABS32".
You can find the code here https://github.com/tangrs/ndless-elfloader/blob/master/elf/elf_load.c
I simply linked my ELF files with --emit-relocs turned on. That way, the linker does all the linking, it just tells me what it did so you can fix up offsets during load time.
Upvotes: 3