2017-04-12 91 views
0

我想弄清楚重定位是如何工作的,但我似乎无法摆脱困境。 This document描述了重定位ELF文件时可能遇到的不同类型。在ARM Cortex-M3上的ELF重定位

例如,我们以R_ARM_ALU_SB_G0_NC(#70)为例。

  • 类型:静态
  • 类:ARM,描述了被搬迁的地点类型(我不明白)
  • 操作:((S + A)| T) - B(S))

我猜数学表达式是我正在寻找的操作。但是,我并不完全理解这如何适合我的功能。 其中重定位发生的方法,如下所示:

int elfloader_arch_relocate(int input_fd, struct elfloader_output *output, 
    unsigned int sectionoffset, char *sectionaddr, struct elf32_rela *rela, char *addr) 

input_fd对于ELF文件的文件描述符,*output被写入输出段时使用的,sectionoffset是文件偏移量,重定位可以发现,*sectionaddr是段开始地址(绝对运行时间),*addr是重定位地址。 32位重定位结构看起来像这样

struct elf32_rela { 
    elf32_addr r_offset; 
    elf32_word r_info; 
    elf32_sword r_addend; 
}; 

在上述26中提到document的命名法是说明页:

  • S(单独使用时)是符号的地址。
  • A是重新安置的加数。
  • 如果目标符号S具有类型STT_FUNC并且符号寻址Thumb指令,则T为1;否则为0。
  • B(S)是输出段定义符号

所以我的问题是,其在重定位函数的参数的对应于式中所使用的那些的寻址原点?

+0

你在哪里做重定位,你有一个在cortex-m3上有一个elf分析器的操作系统吗? –

+0

我正在使用Contiki OS 2.7,因此我只需要编写一些与处理器相关的函数,如'elfloader_arch_relocate()' – boortmans

+0

我不清楚您是在实现_linker_还是_loader_。链接器作为编译的最后阶段运行,将“目标文件”转换为“可执行文件”和“共享库”。加载程序作为执行的第一阶段运行,以便在将可执行程序和共享库引入内存时“修复”它们。链接器必须处理比装载器更多的重定位类型。请说出你的意思。 – zwol

回答

0

如果我读这个权利,我不知道我,它是这样的:

  • Saddr
  • B(S)sectionaddr
  • Arela->r_addend
  • T可能可从rela->r_info中的信息推导出;如果不是,我不知道你需要看什么。

这是一个非常复杂的重定位。考虑从简单的开始(如R_ARM_ABS16)。在一个动态加载器中,你应该不是而是必须实现你链接的规范中的所有重定位类型,只有一小部分。如果您似乎需要大量的重定位类型,这可能是因为您试图将未链接的目标文件提供给动态装载程序;您应该使用现有的ARM链接器将它们转换为共享对象。 (使用GNU工具链,你如何做到这一点的第一个近似值是gcc -shared foo.o -o foo.so。)

为架构拆除现有动态加载器通常是一个很好的计划;在这些事情的代码中往往会隐藏许多无证的智慧。例如,这里是GNU libc's ld.so's ARM relocator。 (LGPL)

+0

当我测试当前的实现时,出现一个关于不支持的重定位类型(#70)的错误。那么通过使用更简单的重定位可以克服这个错误吗? – boortmans

+0

从长远来看,尽管您仍然在实施这个实现,但您仍然可以测试逐渐增加复杂性的共享对象。 – zwol

+0

(可能你试图将一个未链接的对象文件提供给一个加载器,这不是首先应该工作的东西,请参阅这个问题的评论。) – zwol