summaryrefslogtreecommitdiff
path: root/src/modelops/symtab.c
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2013-06-18 08:47:33 +0100
committernorly <ny-git@enpas.org>2013-06-18 08:49:07 +0100
commitc98d704a812502c34d82e34949f37c8b87ae6018 (patch)
treeab0ea9890143ab40ead5e07bb9be29ac874e8ccd /src/modelops/symtab.c
parentf88e1ad7d9db8a41abecc795200f21138af65c74 (diff)
Basic detour support
Diffstat (limited to 'src/modelops/symtab.c')
-rw-r--r--src/modelops/symtab.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/modelops/symtab.c b/src/modelops/symtab.c
index e62871f..ef8443f 100644
--- a/src/modelops/symtab.c
+++ b/src/modelops/symtab.c
@@ -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)