4 #include <libelfu/libelfu.h>
7 /* Apply relocation information from section *msrt to data in
8 * section *mstarget (which is stored in *metarget). */
9 int elfu_mRelocate(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt)
17 ELFU_DEBUG("Relocating in section of type %u size %x\n",
18 mstarget->shdr.sh_type,
19 (unsigned)mstarget->shdr.sh_size);
21 CIRCLEQ_FOREACH(rel, &msrt->reltab.rels, elem) {
22 Elf32_Word *dest32 = (Elf32_Word*)(mstarget->databuf + rel->offset);
23 Elf64_Word *dest64 = (Elf64_Word*)(mstarget->databuf + rel->offset);
27 sym = elfu_mSymtabIndexToSym(msrt->linkptr, rel->sym);
30 haveSymval = !elfu_mSymtabLookupSymToAddr(metarget,
35 if (sym->shndx == SHN_UNDEF) {
36 haveSymval = !elfu_mDynLookupPltAddrByName(metarget,
37 elfu_mSymtabSymToName(msrt->linkptr, sym),
39 } else if (sym->shndx == SHN_COMMON) {
40 // TODO: Lookup in .rel.dyn
44 if (metarget->elfclass == ELFCLASS32) {
45 Elf32_Word a32 = rel->addendUsed ? rel->addend : *dest32;
46 Elf32_Addr p32 = mstarget->shdr.sh_addr + rel->offset;
47 Elf32_Addr s32 = (Elf32_Addr)s;
49 switch(metarget->ehdr.e_machine) {
53 ELFU_DEBUG("Skipping relocation: R_386_NONE\n");
65 *dest32 = s32 + a32 - p32;
68 ELFU_DEBUG("elfu_mRelocate: Skipping unknown relocation type %d\n", rel->type);
72 ELFU_WARN("elfu_mRelocate: Unknown machine type. Aborting.\n");
74 } else if (metarget->elfclass == ELFCLASS64) {
75 Elf64_Word a64 = rel->addendUsed ? rel->addend : *dest64;
76 Elf64_Addr p64 = mstarget->shdr.sh_addr + rel->offset;
77 Elf64_Addr s64 = (Elf64_Addr)s;
79 switch(metarget->ehdr.e_machine) {
83 ELFU_DEBUG("Skipping relocation: R_386_NONE\n");
95 *dest32 = s64 + a64 - p64;
104 ELFU_DEBUG("elfu_mRelocate: Skipping unknown relocation type %d", rel->type);
108 ELFU_WARN("elfu_mRelocate: Unknown machine type. Aborting.\n");
116 ELFU_WARN("elfu_mRelocate: Could not resolve symbol %s. Aborting.\n",
117 elfu_mSymtabSymToName(msrt->linkptr, sym));