#include <gelf.h>
-typedef struct ElfuScn {
- GElf_Shdr shdr;
-
- Elf_Data data;
-
- struct ElfuScn *linkptr;
- struct ElfuScn *infoptr;
-
- struct ElfuScn *oldptr;
-
- struct ElfuSymtab *symtab;
- struct ElfuReltab *reltab;
-
- CIRCLEQ_ENTRY(ElfuScn) elemChildScn;
- CIRCLEQ_ENTRY(ElfuScn) elem;
-} ElfuScn;
-
-
-typedef struct ElfuPhdr {
- GElf_Phdr phdr;
-
- CIRCLEQ_HEAD(ChildScnList, ElfuScn) childScnList;
- CIRCLEQ_HEAD(ChildPhdrList, ElfuPhdr) childPhdrList;
-
- CIRCLEQ_ENTRY(ElfuPhdr) elemChildPhdr;
- CIRCLEQ_ENTRY(ElfuPhdr) elem;
-} ElfuPhdr;
-
-
-typedef struct {
- int elfclass;
- GElf_Ehdr ehdr;
-
- CIRCLEQ_HEAD(PhdrList, ElfuPhdr) phdrList;
- CIRCLEQ_HEAD(OrphanScnList, ElfuScn) orphanScnList;
-
- ElfuScn *shstrtab;
-} ElfuElf;
-
-
-
-
-
typedef struct ElfuSym {
char *name;
unsigned char type;
unsigned char other;
- ElfuScn *scnptr;
+ struct ElfuScn *scnptr;
int shndx;
CIRCLEQ_ENTRY(ElfuSym) elem;
} ElfuReltab;
+
+
+
+
+typedef struct ElfuScn {
+ GElf_Shdr shdr;
+
+ Elf_Data data;
+
+ struct ElfuScn *linkptr;
+ struct ElfuScn *infoptr;
+
+ struct ElfuScn *oldptr;
+
+ struct ElfuSymtab symtab;
+ struct ElfuReltab reltab;
+
+ CIRCLEQ_ENTRY(ElfuScn) elemChildScn;
+ CIRCLEQ_ENTRY(ElfuScn) elem;
+} ElfuScn;
+
+
+typedef struct ElfuPhdr {
+ GElf_Phdr phdr;
+
+ CIRCLEQ_HEAD(ChildScnList, ElfuScn) childScnList;
+ CIRCLEQ_HEAD(ChildPhdrList, ElfuPhdr) childPhdrList;
+
+ CIRCLEQ_ENTRY(ElfuPhdr) elemChildPhdr;
+ CIRCLEQ_ENTRY(ElfuPhdr) elem;
+} ElfuPhdr;
+
+
+typedef struct {
+ int elfclass;
+ GElf_Ehdr ehdr;
+
+ CIRCLEQ_HEAD(PhdrList, ElfuPhdr) phdrList;
+ CIRCLEQ_HEAD(OrphanScnList, ElfuScn) orphanScnList;
+
+ ElfuScn *shstrtab;
+} ElfuElf;
+
#endif
newscn->oldptr = ms;
- ms->symtab = NULL;
- ms->reltab = NULL;
+ CIRCLEQ_INIT(&ms->symtab.syms);
+ CIRCLEQ_INIT(&ms->reltab.rels);
return newscn;
}
}
-static ElfuSymtab* symtabFromScn32(ElfuScn *ms, ElfuScn**origScnArr)
+static void parseSymtab32(ElfuScn *ms, ElfuScn**origScnArr)
{
- ElfuSymtab *st;
size_t i;
assert(ms);
assert(origScnArr);
- st = malloc(sizeof(*st));
- if (!st) {
- ELFU_WARN("elfu_mSymtabFromScn32: malloc() failed for st.\n");
- goto ERROR;
- }
-
- CIRCLEQ_INIT(&st->syms);
-
-
for (i = 1; (i + 1) * sizeof(Elf32_Sym) <= ms->shdr.sh_size; i++) {
Elf32_Sym *cursym = &(((Elf32_Sym*)ms->data.d_buf)[i]);
ElfuSym *sym = malloc(sizeof(*sym));
}
- CIRCLEQ_INSERT_TAIL(&st->syms, sym, elem);
+ CIRCLEQ_INSERT_TAIL(&ms->symtab.syms, sym, elem);
}
-
-
- return st;
-
- ERROR:
- if (st) {
- free(st);
- }
- return NULL;
}
-static ElfuReltab* reltabFromScn32(ElfuScn *ms)
+static void parseReltab32(ElfuScn *ms)
{
- ElfuReltab *rt;
size_t i;
assert(ms);
assert(ms->data.d_buf);
- rt = malloc(sizeof(*rt));
- if (!rt) {
- ELFU_WARN("elfu_mReltabFromScn32: malloc() failed for rt.\n");
- goto ERROR;
- }
-
- CIRCLEQ_INIT(&rt->rels);
-
-
for (i = 0; (i + 1) * sizeof(Elf32_Rel) <= ms->shdr.sh_size; i++) {
Elf32_Rel *currel = &(((Elf32_Rel*)ms->data.d_buf)[i]);
ElfuRel *rel;
rel->addendUsed = 0;
rel->addend = 0;
- CIRCLEQ_INSERT_TAIL(&rt->rels, rel, elem);
+ CIRCLEQ_INSERT_TAIL(&ms->reltab.rels, rel, elem);
}
-
-
- return rt;
-
- ERROR:
- if (rt) {
- free(rt);
- }
- return NULL;
}
ms->oldptr = NULL;
- ms->symtab = NULL;
- ms->reltab = NULL;
+ CIRCLEQ_INIT(&ms->symtab.syms);
+ CIRCLEQ_INIT(&ms->reltab.rels);
return ms;
case SHT_SYMTAB:
case SHT_DYNSYM:
if (me->elfclass == ELFCLASS32) {
- ms->symtab = symtabFromScn32(ms, secArray);
+ parseSymtab32(ms, secArray);
} else if (me->elfclass == ELFCLASS64) {
// TODO
}
- assert(ms->symtab);
break;
}
}
switch (ms->shdr.sh_type) {
case SHT_REL:
if (me->elfclass == ELFCLASS32) {
- ms->reltab = reltabFromScn32(ms);
+ parseReltab32(ms);
} else if (me->elfclass == ELFCLASS64) {
// TODO
}
- assert(ms->reltab);
break;
case SHT_RELA:
if (me->elfclass == ELFCLASS32) {
} else if (me->elfclass == ELFCLASS64) {
// TODO
}
- assert(ms->reltab);
break;
}
}
/* Look up name */
- assert(relplt->reltab);
assert(relplt->linkptr);
- assert(relplt->linkptr->symtab);
j = 0;
- CIRCLEQ_FOREACH(rel, &relplt->reltab->rels, elem) {
+ CIRCLEQ_FOREACH(rel, &relplt->reltab.rels, elem) {
GElf_Word i;
ElfuSym *sym;
continue;
}
- sym = CIRCLEQ_FIRST(&relplt->linkptr->symtab->syms);
+ sym = CIRCLEQ_FIRST(&relplt->linkptr->symtab.syms);
for (i = 1; i < rel->sym; i++) {
sym = CIRCLEQ_NEXT(sym, elem);
}
assert(metarget);
assert(msst);
- assert(msst->symtab);
assert(entry > 0);
- assert(!CIRCLEQ_EMPTY(&msst->symtab->syms));
+ assert(!CIRCLEQ_EMPTY(&msst->symtab.syms));
- sym = CIRCLEQ_FIRST(&msst->symtab->syms);
+ sym = CIRCLEQ_FIRST(&msst->symtab.syms);
for (i = 1; i < entry; i++) {
sym = CIRCLEQ_NEXT(sym, elem);
}
mstarget->shdr.sh_type,
mstarget->shdr.sh_size);
- CIRCLEQ_FOREACH(rel, &msrt->reltab->rels, elem) {
+ 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;