我正在尝试为准系统ARM应用程序创建一个简单的链接器。当前,加载模块的加载器将简单地将偏移量添加到.got
和.data.rel
节内的所有记录中。这在.got
中以及在.data.rel
中需要重定位的所有符号都可以正常工作。对于所有不可重定位的数据,它都会中断,因为那些数据也将获得此偏移量。
例子:
void some_function() { return; }
struct a {
void* fptr;
int number;
};
static struct a = {
.fptr = some_function,
.number = 0x1000,
};
此处
a.fptr
将正确解决函数的实际位置,但是a.number
将错误地保留0x1000 + offset
,而不仅仅是0x1000
。我应该如何区分两者?仅检查
.symtab
部分并仅重定位在那里找到的地址就足够了吗?但是,如果符号实际上位于0x1000
位置,该怎么办?还是链接程序解决了这个问题(因此它不会将函数放在地址0x1000
上)? .symtabs
实际上是否包含可以在.got
和.data.rel
中找到的所有符号? 最佳答案
不久前,我写了一个基本的ELF加载器,回想起您只向标有“R_ARM_ABS32”的重定位条目添加偏移量。
您可以在这里找到代码https://github.com/tangrs/ndless-elfloader/blob/master/elf/elf_load.c
我只是将ELF文件与--emit-relocs链接在一起。这样,链接器完成了所有链接,它只是告诉我它做了什么,因此您可以在加载期间修复偏移。