简体   繁体   中英

ELF relocation on ARM Cortex-M3

I'm trying to figure out how relocation works, but I can't seem to get my head around it. This document describes the different types one can encounter when relocating an ELF file.

Let's take R_ARM_ALU_SB_G0_NC (#70) for example.

  • Type: static
  • Class: ARM, describes the type of place being relocated (which I do not understand)
  • Operation: ((S + A) | T) – B(S))

I'm guessing that the mathematical expression is the operation I'm looking for. However, I do not completely understand how this fits in my function. The method where the relocation takes place looks as follows:

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

input_fd is a file descriptor for the ELF file, *output is used when writing the output segment, sectionoffset is the file offset at which the relocation can be found, *sectionaddr is the section start address (absolute runtime) and *addr is the relocated address. The 32-bit relocation structure looks like this

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

On page 26 of the above mentioned document the nomenclature is explained:

  • S (when used on its own) is the address of the symbol.
  • A is the addend for the relocation.
  • T is 1 if the target symbol S has type STT_FUNC and the symbol addresses a Thumb instruction; it is 0 otherwise.
  • B(S) is the addressing origin of the output segment defining the symbol

So my question is, which of the parameters in the relocate function correspond to the ones used in the formula?

If I'm reading this right, and I'm not sure I am, it goes like this:

  • S is addr .
  • B(S) is sectionaddr .
  • A is rela->r_addend .
  • T may be derivable from information in rela->r_info ; if not, I don't know where you need to look.

This is a really complicated-looking relocation. Consider starting with the simple ones (like R_ARM_ABS16 ). In a dynamic loader, you should not have to implement all of the relocation typess in the spec you linked to, only a small subset. If it seems like you need a lot of relocation types, this is probably because you are trying to feed unlinked object files to the dynamic loader; you should turn them into shared objects, using your existing ARM linker. (With the GNU toolchain, a first approximation to how you do that is gcc -shared foo.o -o foo.so .)

Cribbing off an existing dynamic loader for the architecture is often a good plan; there tends to be a lot of undocumented wisdom buried in the code for such things. For instance, here is GNU libc's ld.so's ARM relocator . (LGPL)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM