summaryrefslogtreecommitdiff
path: root/src/model/relocate.c
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2013-06-12 18:41:42 +0100
committernorly <ny-git@enpas.org>2013-06-12 18:41:42 +0100
commit164b3a3a62a0577f9a28078771dd6fdc102598dc (patch)
tree2fedb22c74164b536f0bd8e09c8faf2d3f809254 /src/model/relocate.c
parentf661dd3e9708687574ad193b24a5d3d37b825bd7 (diff)
Rename elfedit to centaur, model to modelops
Diffstat (limited to 'src/model/relocate.c')
-rw-r--r--src/model/relocate.c169
1 files changed, 0 insertions, 169 deletions
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 <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libelfu/libelfu.h>
-
-
-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;
- }
-}