From 164b3a3a62a0577f9a28078771dd6fdc102598dc Mon Sep 17 00:00:00 2001 From: norly Date: Wed, 12 Jun 2013 18:41:42 +0100 Subject: Rename elfedit to centaur, model to modelops --- src/model/relocate.c | 169 --------------------------------------------------- 1 file changed, 169 deletions(-) delete mode 100644 src/model/relocate.c (limited to 'src/model/relocate.c') diff --git a/src/model/relocate.c b/src/model/relocate.c deleted file mode 100644 index 972bda3..0000000 --- a/src/model/relocate.c +++ /dev/null @@ -1,169 +0,0 @@ -#include -#include -#include -#include - - -static void* subFindByName(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2) -{ - char *name = (char*)aux1; - (void)aux2; - - if (elfu_mScnName(me, ms)) { - if (!strcmp(elfu_mScnName(me, ms), name)) { - return ms; - } - } - - /* Continue */ - return NULL; -} - -/* Hazard a guess where a function may be found in the PLT */ -static GElf_Word pltLookupVal(ElfuElf *metarget, char *name) -{ - ElfuScn *relplt; - ElfuScn *plt; - ElfuRel *rel; - GElf_Word j; - - relplt = elfu_mScnForall(metarget, subFindByName, ".rel.plt", NULL); - if (!relplt) { - ELFU_WARN("dynsymLookupVal: Could not find .rel.plt section in destination ELF.\n"); - return 0; - } - - plt = elfu_mScnForall(metarget, subFindByName, ".plt", NULL); - if (!plt) { - ELFU_WARN("dynsymLookupVal: Could not find .plt section in destination ELF.\n"); - return 0; - } - - - /* Look up name */ - assert(relplt->reltab); - assert(relplt->linkptr); - assert(relplt->linkptr->symtab); - j = 0; - CIRCLEQ_FOREACH(rel, &relplt->reltab->rels, elem) { - GElf_Word i; - ElfuSym *sym; - - j++; - - if (rel->type != R_386_JMP_SLOT) { - continue; - } - - sym = CIRCLEQ_FIRST(&relplt->linkptr->symtab->syms); - for (i = 1; i < rel->sym; i++) { - sym = CIRCLEQ_NEXT(sym, elem); - } - - if (!sym->name) { - continue; - } - - if (!strcmp(sym->name, name)) { - /* If this is the symbol we are looking for, then in an x86 binary - * the jump to the dynamic symbol is probably at offset (j * 16) - * from the start of the PLT, where j is the PLT entry and 16 is - * the number of bytes the machine code in a PLT entry take. */ - GElf_Addr addr = plt->shdr.sh_addr + (16 * j); - ELFU_DEBUG("dynsymLookupVal: Guessing symbol '%s' is in destination memory at %jx (PLT entry #%d).\n", name, addr, j); - return addr; - } - } - - ELFU_WARN("dynsymLookupVal: Could not find symbol '%s' in destination ELF.\n", name); - - return 0; -} - - -static GElf_Word symtabLookupVal(ElfuElf *metarget, ElfuScn *msst, GElf_Word entry) -{ - GElf_Word i; - ElfuSym *sym; - - assert(metarget); - assert(msst); - assert(msst->symtab); - assert(entry > 0); - assert(!CIRCLEQ_EMPTY(&msst->symtab->syms)); - - sym = CIRCLEQ_FIRST(&msst->symtab->syms); - for (i = 1; i < entry; i++) { - sym = CIRCLEQ_NEXT(sym, elem); - } - - switch (sym->type) { - case STT_NOTYPE: - case STT_OBJECT: - case STT_FUNC: - if (sym->scnptr) { - assert(elfu_mScnByOldscn(metarget, sym->scnptr)); - return elfu_mScnByOldscn(metarget, sym->scnptr)->shdr.sh_addr + sym->value; - } else if (sym->shndx == SHN_UNDEF) { - /* Look the symbol up in .dyn.plt. If it cannot be found there then - * .rel.dyn may need to be expanded with a COPY relocation so the - * dynamic linker fixes up the (TODO). */ - return pltLookupVal(metarget, sym->name); - } else if (sym->shndx == SHN_ABS) { - return sym->value; - } else { - ELFU_WARN("symtabLookupVal: Symbol binding COMMON is not supported, using 0.\n"); - return 0; - } - break; - case STT_SECTION: - assert(sym->scnptr); - assert(elfu_mScnByOldscn(metarget, sym->scnptr)); - return elfu_mScnByOldscn(metarget, sym->scnptr)->shdr.sh_addr; - case STT_FILE: - ELFU_WARN("symtabLookupVal: Symbol type FILE is not supported, using 0.\n"); - return 0; - default: - ELFU_WARN("symtabLookupVal: Unknown symbol type %d for %s.\n", sym->type, sym->name); - return 0; - } -} - -void elfu_mRelocate32(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt) -{ - ElfuRel *rel; - - assert(mstarget); - assert(msrt); - - ELFU_DEBUG("Relocating in section of type %d size %jx\n", - mstarget->shdr.sh_type, - mstarget->shdr.sh_size); - - CIRCLEQ_FOREACH(rel, &msrt->reltab->rels, elem) { - Elf32_Word *dest = (Elf32_Word*)(((char*)(mstarget->data.d_buf)) + rel->offset); - Elf32_Word a = rel->addendUsed ? rel->addend : *dest; - Elf32_Addr p = mstarget->shdr.sh_addr + rel->offset; - Elf32_Addr s = symtabLookupVal(metarget, msrt->linkptr, rel->sym); - Elf32_Word newval = *dest; - - switch(rel->type) { - case R_386_NONE: - ELFU_DEBUG("Skipping relocation: R_386_NONE"); - break; - case R_386_32: - ELFU_DEBUG("Relocation: R_386_32"); - newval = s + a; - break; - case R_386_PC32: - ELFU_DEBUG("Relocation: R_386_PC32"); - newval = s + a - p; - break; - - default: - ELFU_DEBUG("Skipping relocation: Unknown type %d", rel->type); - } - ELFU_DEBUG(", overwriting %x with %x.\n", *dest, newval); - *dest = newval; - } -} -- cgit v1.2.3