Basic detour support
[centaur.git] / src / modelops / symtab.c
index a7c1485c9d74bb9b41fcef6797e1b8cdfe480157..ef8443fab79cd1c03acd75160afadf8bc993ae06 100644 (file)
@@ -76,7 +76,7 @@ static GElf_Word pltLookupVal(ElfuElf *me, char *name)
        * 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);
+      ELFU_DEBUG("dynsymLookupVal: Guessing symbol '%s' is in destination memory at %x (PLT entry #%u).\n", name, (unsigned)addr, j);
       return addr;
     }
   }
@@ -141,6 +141,52 @@ GElf_Word elfu_mSymtabLookupVal(ElfuElf *me, ElfuScn *msst, GElf_Word entry)
 }
 
 
+/* Look up a value in the symbol table section *msst which is in *me. */
+GElf_Word elfu_mSymtabLookupAddrByName(ElfuElf *me, ElfuScn *msst, char *name)
+{
+  ElfuSym *sym;
+
+  assert(me);
+  assert(msst);
+  assert(name);
+  assert(strlen(name) > 0);
+  assert(!CIRCLEQ_EMPTY(&msst->symtab.syms));
+
+  CIRCLEQ_FOREACH(sym, &msst->symtab.syms, elem) {
+    char *symname = ELFU_SYMSTR(msst, sym->name);
+
+    if (!strcmp(symname, name)) {
+      goto SYMBOL_FOUND;
+    }
+  }
+  return 0;
+
+
+  SYMBOL_FOUND:
+
+  switch (sym->type) {
+    case STT_NOTYPE:
+    case STT_OBJECT:
+    case STT_FUNC:
+      if (sym->scnptr) {
+        GElf_Addr a = sym->value;
+        a += me->ehdr.e_type == ET_REL ? sym->scnptr->shdr.sh_addr : 0;
+        return a;
+      } else if (sym->shndx == SHN_UNDEF) {
+        return 0;
+      } else if (sym->shndx == SHN_ABS) {
+        return sym->value;
+      } else {
+        ELFU_WARN("elfu_mSymtabLookupAddrByName: Symbol binding COMMON is not supported, using 0.\n");
+        return 0;
+      }
+      break;
+    default:
+      return 0;
+  }
+}
+
+
 
 /* Convert symtab from memory model to elfclass specific format */
 void elfu_mSymtabFlatten(ElfuElf *me)
@@ -215,7 +261,7 @@ void elfu_mSymtabFlatten(ElfuElf *me)
       i++;
     }
   } else {
-    // Unknown elfclass
+    /* Unknown elfclass */
     assert(0);
   }