summaryrefslogtreecommitdiff
path: root/src/modelops
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2013-06-20 01:56:24 +0100
committernorly <ny-git@enpas.org>2013-06-20 22:10:25 +0100
commitb70b3ff9b1679bb1e0a215b7acd9b6d55497a46b (patch)
treed6e95ad143c7e2ec9ca39c1dd32c046fb9006eb9 /src/modelops
parent7f1a29e9e33059dfebdc24bb3ffaa3dac46b58f1 (diff)
Separate library code, build .a/.so
Diffstat (limited to 'src/modelops')
-rw-r--r--src/modelops/check.c54
-rw-r--r--src/modelops/clone.c41
-rw-r--r--src/modelops/detour.c51
-rw-r--r--src/modelops/dump.c239
-rw-r--r--src/modelops/fromFile.c490
-rw-r--r--src/modelops/layout.c324
-rw-r--r--src/modelops/phdr.c36
-rw-r--r--src/modelops/reladd.c323
-rw-r--r--src/modelops/relocate.c70
-rw-r--r--src/modelops/section.c196
-rw-r--r--src/modelops/symtab.c269
-rw-r--r--src/modelops/toFile.c121
12 files changed, 0 insertions, 2214 deletions
diff --git a/src/modelops/check.c b/src/modelops/check.c
deleted file mode 100644
index 5234bef..0000000
--- a/src/modelops/check.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <libelfu/libelfu.h>
-
-
-int elfu_mCheck(ElfuElf *me)
-{
- size_t numSecs;
- ElfuScn **sortedSecs;
- size_t i;
-
- sortedSecs = elfu_mScnSortedByOffset(me, &numSecs);
- if (!sortedSecs) {
- return -1;
- }
-
-
- /* Check for overlapping sections */
- for (i = 0; i < numSecs - 1; i++) {
- if (sortedSecs[i]->shdr.sh_offset + SCNFILESIZE(&sortedSecs[i]->shdr)
- > sortedSecs[i+1]->shdr.sh_offset) {
- ELFU_WARN("elfu_check: Found overlapping sections: %s and %s.\n",
- elfu_mScnName(me, sortedSecs[i]),
- elfu_mScnName(me, sortedSecs[i+1]));
- }
- }
-
-
- /* Check for sections overlapping with EHDR */
- for (i = 0; i < numSecs; i++) {
- if (sortedSecs[i]->shdr.sh_offset < me->ehdr.e_ehsize) {
- ELFU_WARN("elfu_check: Found section overlapping with EHDR: %s.\n",
- elfu_mScnName(me, sortedSecs[i]));
- }
- }
-
-
- /* Check for sections overlapping with PHDRs */
- for (i = 0; i < numSecs; i++) {
- if (OVERLAPPING(sortedSecs[i]->shdr.sh_offset,
- SCNFILESIZE(&sortedSecs[i]->shdr),
- me->ehdr.e_phoff,
- me->ehdr.e_phentsize * me->ehdr.e_phnum)) {
- ELFU_WARN("elfu_check: Found section overlapping with PHDRs: %s.\n",
- elfu_mScnName(me, sortedSecs[i]));
- }
- }
-
-
- free(sortedSecs);
-
- return 0;
-}
diff --git a/src/modelops/clone.c b/src/modelops/clone.c
deleted file mode 100644
index 8f92919..0000000
--- a/src/modelops/clone.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libelfu/libelfu.h>
-
-ElfuScn* elfu_mCloneScn(ElfuScn *ms)
-{
- ElfuScn *newscn;
-
- assert(ms);
-
- newscn = malloc(sizeof(ElfuScn));
- if (!newscn) {
- ELFU_WARN("elfu_nCloneScn: Could not allocate memory for new ElfuScn.\n");
- return NULL;
- }
-
- newscn->shdr = ms->shdr;
- newscn->data = ms->data;
- if (ms->data.d_buf) {
- void *newbuf = malloc(ms->data.d_size);
- if (!newbuf) {
- ELFU_WARN("elfu_nCloneScn: Could not allocate memory for new data buffer.\n");
- free(newscn);
- return NULL;
- }
-
- memcpy(newbuf, ms->data.d_buf, ms->data.d_size);
- newscn->data.d_buf = newbuf;
- }
-
- newscn->linkptr = NULL;
- newscn->infoptr = NULL;
-
- newscn->oldptr = ms;
-
- CIRCLEQ_INIT(&ms->symtab.syms);
- CIRCLEQ_INIT(&ms->reltab.rels);
-
- return newscn;
-}
diff --git a/src/modelops/detour.c b/src/modelops/detour.c
deleted file mode 100644
index 075d945..0000000
--- a/src/modelops/detour.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <libelfu/libelfu.h>
-#include <string.h>
-
-static void* subFindByAddr(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
- GElf_Addr a = *(GElf_Addr*)aux1;
-
- if (OVERLAPPING(ms->shdr.sh_addr, ms->shdr.sh_size, a, 1)) {
- return ms;
- }
-
- /* Continue */
- return NULL;
-}
-
-
-void elfu_mDetour(ElfuElf *me, GElf_Addr from, GElf_Addr to)
-{
- ElfuScn *ms;
- GElf_Word scnoffset;
- unsigned char detourcode[] = {0xe9, 0xfc, 0xff, 0xff, 0xff};
-
- ms = elfu_mScnForall(me, subFindByAddr, &from, NULL);
-
- if (!ms) {
- ELFU_WARN("mDetour: Cannot find address %x in any section.\n",
- (unsigned)from);
- return;
- }
-
- if (ms->shdr.sh_type != SHT_PROGBITS) {
- ELFU_WARN("mDetour: Cannot detour in non-PROGBITS section %s.\n",
- elfu_mScnName(me, ms));
- return;
- }
-
- scnoffset = from - ms->shdr.sh_addr;
-
- if (ms->shdr.sh_size - scnoffset < 5) {
- ELFU_WARN("mDetour: Not enough space to insert a detour.\n");
- return;
- }
-
- ELFU_DEBUG("mDetour: Detouring at address %x in section %s to %x.\n",
- (unsigned)from,
- elfu_mScnName(me, ms),
- (unsigned)to);
-
- *(Elf32_Word*)(detourcode + 1) = to - from - 5;
- memcpy((char*)ms->data.d_buf + scnoffset, detourcode, 5);
-}
diff --git a/src/modelops/dump.c b/src/modelops/dump.c
deleted file mode 100644
index b2e172e..0000000
--- a/src/modelops/dump.c
+++ /dev/null
@@ -1,239 +0,0 @@
-#include <assert.h>
-#include <libelfu/libelfu.h>
-
-
-static char* segmentTypeStr(Elf32_Word p_type)
-{
- switch(p_type) {
- case PT_NULL: /* 0 */
- return "NULL";
- case PT_LOAD: /* 1 */
- return "LOAD";
- case PT_DYNAMIC: /* 2 */
- return "DYNAMIC";
- case PT_INTERP: /* 3 */
- return "INTERP";
- case PT_NOTE: /* 4 */
- return "NOTE";
- case PT_SHLIB: /* 5 */
- return "SHLIB";
- case PT_PHDR: /* 6 */
- return "PHDR";
- case PT_TLS: /* 7 */
- return "TLS";
- case PT_NUM: /* 8 */
- return "NUM";
- case PT_GNU_EH_FRAME: /* 0x6474e550 */
- return "GNU_EH_FRAME";
- case PT_GNU_STACK: /* 0x6474e551 */
- return "GNU_STACK";
- case PT_GNU_RELRO: /* 0x6474e552 */
- return "GNU_RELRO";
- }
-
- return "-?-";
-}
-
-static char* sectionTypeStr(Elf32_Word sh_type)
-{
- switch(sh_type) {
- case SHT_NULL: /* 0 */
- return "NULL";
- case SHT_PROGBITS: /* 1 */
- return "PROGBITS";
- case SHT_SYMTAB: /* 2 */
- return "SYMTAB";
- case SHT_STRTAB: /* 3 */
- return "STRTAB";
- case SHT_RELA: /* 4 */
- return "RELA";
- case SHT_HASH: /* 5 */
- return "HASH";
- case SHT_DYNAMIC: /* 6 */
- return "DYNAMIC";
- case SHT_NOTE: /* 7 */
- return "NOTE";
- case SHT_NOBITS: /* 8 */
- return "NOBITS";
- case SHT_REL: /* 9 */
- return "REL";
- case SHT_SHLIB: /* 10 */
- return "SHLIB";
- case SHT_DYNSYM: /* 11 */
- return "DYNSYM";
- case SHT_INIT_ARRAY: /* 14 */
- return "INIT_ARRAY";
- case SHT_FINI_ARRAY: /* 15 */
- return "FINI_ARRAY";
- case SHT_PREINIT_ARRAY: /* 16 */
- return "PREINIT_ARRAY";
- case SHT_GROUP: /* 17 */
- return "SHT_GROUP";
- case SHT_SYMTAB_SHNDX: /* 18 */
- return "SYMTAB_SHNDX";
- case SHT_NUM: /* 19 */
- return "NUM";
-
- case SHT_GNU_ATTRIBUTES: /* 0x6ffffff5 */
- return "GNU_ATTRIBUTES";
- case SHT_GNU_HASH: /* 0x6ffffff6 */
- return "GNU_HASH";
- case SHT_GNU_LIBLIST: /* 0x6ffffff7 */
- return "GNU_LIBLIST";
- case SHT_GNU_verdef: /* 0x6ffffffd */
- return "GNU_verdef";
- case SHT_GNU_verneed: /* 0x6ffffffe */
- return "GNU_verneed";
- case SHT_GNU_versym: /* 0x6fffffff */
- return "GNU_versym";
- }
-
- return "-?-";
-}
-
-
-
-
-void elfu_mDumpPhdr(ElfuElf *me, ElfuPhdr *mp)
-{
- assert(me);
- assert(mp);
-
- ELFU_INFO("%12s %8x %8x %8x %8x %8x %8x %8x %8x\n",
- segmentTypeStr(mp->phdr.p_type),
- (unsigned)mp->phdr.p_type,
- (unsigned)mp->phdr.p_offset,
- (unsigned)mp->phdr.p_vaddr,
- (unsigned)mp->phdr.p_paddr,
- (unsigned)mp->phdr.p_filesz,
- (unsigned)mp->phdr.p_memsz,
- (unsigned)mp->phdr.p_flags,
- (unsigned)mp->phdr.p_align);
-
- if (!CIRCLEQ_EMPTY(&mp->childPhdrList)) {
- ElfuPhdr *mpc;
-
- ELFU_INFO(" -> Child PHDRs:\n");
- CIRCLEQ_FOREACH(mpc, &mp->childPhdrList, elemChildPhdr) {
- ELFU_INFO(" * %-8s @ %8x\n",
- segmentTypeStr(mpc->phdr.p_type),
- (unsigned)mpc->phdr.p_vaddr);
- }
- }
-
- if (!CIRCLEQ_EMPTY(&mp->childScnList)) {
- ElfuScn *msc;
-
- ELFU_INFO(" -> Child sections:\n");
- CIRCLEQ_FOREACH(msc, &mp->childScnList, elemChildScn) {
- ELFU_INFO(" * %-17s @ %8x\n",
- elfu_mScnName(me, msc),
- (unsigned)msc->shdr.sh_addr);
- }
- }
-}
-
-
-void elfu_mDumpScn(ElfuElf *me, ElfuScn *ms)
-{
- char *namestr, *typestr, *linkstr, *infostr;
-
- assert(me);
- assert(ms);
-
- namestr = elfu_mScnName(me, ms);
- typestr = sectionTypeStr(ms->shdr.sh_type);
- linkstr = ms->linkptr ? elfu_mScnName(me, ms->linkptr) : "";
- infostr = ms->infoptr ? elfu_mScnName(me, ms->infoptr) : "";
-
- ELFU_INFO("%-17s %-15s %8x %9x %8x %2x %2x %2d %-17s %-17s\n",
- namestr,
- typestr,
- (unsigned)ms->shdr.sh_addr,
- (unsigned)ms->shdr.sh_offset,
- (unsigned)ms->shdr.sh_size,
- (unsigned)ms->shdr.sh_entsize,
- (unsigned)ms->shdr.sh_flags,
- (unsigned)ms->shdr.sh_addralign,
- linkstr,
- infostr);
-}
-
-
-void elfu_mDumpEhdr(ElfuElf *me)
-{
- assert(me);
-
- ELFU_INFO("ELF header:\n");
- ELFU_INFO(" %d-bit ELF object\n", me->elfclass == ELFCLASS32 ? 32 : 64);
-
- ELFU_INFO(" EHDR:\n");
-
- ELFU_INFO(" e_type %8x\n", me->ehdr.e_type);
- ELFU_INFO(" e_machine %8x\n", me->ehdr.e_machine);
- ELFU_INFO(" e_version %8x\n", me->ehdr.e_version);
- ELFU_INFO(" e_entry %8x\n", (unsigned)me->ehdr.e_entry);
- ELFU_INFO(" e_phoff %8x\n", (unsigned)me->ehdr.e_phoff);
- ELFU_INFO(" e_shoff %8x\n", (unsigned)me->ehdr.e_shoff);
- ELFU_INFO(" e_flags %8x\n", me->ehdr.e_flags);
- ELFU_INFO(" e_ehsize %8x\n", me->ehdr.e_ehsize);
- ELFU_INFO(" e_phentsize %8x\n", me->ehdr.e_phentsize);
- ELFU_INFO(" e_shentsize %8x\n", me->ehdr.e_shentsize);
-
- ELFU_INFO(" shstrtab: %s\n", me->shstrtab ? elfu_mScnName(me, me->shstrtab) : "(none)");
-}
-
-
-
-static void* subScnDump(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
- (void) aux1;
- (void) aux2;
-
- printf(" [%4d] ", elfu_mScnIndex(me, ms));
- elfu_mDumpScn(me, ms);
-
- return NULL;
-}
-
-
-void elfu_mDumpElf(ElfuElf *me)
-{
- ElfuPhdr *mp;
- ElfuScn *ms;
- size_t i;
-
- assert(me);
-
-
- elfu_mDumpEhdr(me);
- ELFU_INFO("\n");
-
-
- ELFU_INFO("Segments:\n");
- ELFU_INFO(" # (type) p_type p_offset p_vaddr p_paddr p_filesz p_memsz p_flags p_align\n");
- ELFU_INFO(" | | | | | | | | | \n");
- i = 0;
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- printf(" [%4d] ", i);
- elfu_mDumpPhdr(me, mp);
- i++;
- }
- ELFU_INFO("\n");
-
-
- ELFU_INFO("Orphaned sections:\n");
- CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
- ELFU_INFO(" * %-17s @ %8x\n",
- elfu_mScnName(me, ms),
- (unsigned)ms->shdr.sh_addr);
- }
- ELFU_INFO("\n");
-
-
- ELFU_INFO("Sections:\n");
- ELFU_INFO(" # Name sh_type sh_addr sh_offset sh_size ES Fl Al sh_link sh_info \n");
- ELFU_INFO(" | | | | | | | | | | \n");
- elfu_mScnForall(me, subScnDump, &i, NULL);
- ELFU_INFO("\n");
-}
diff --git a/src/modelops/fromFile.c b/src/modelops/fromFile.c
deleted file mode 100644
index dd8b462..0000000
--- a/src/modelops/fromFile.c
+++ /dev/null
@@ -1,490 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <libelfu/libelfu.h>
-
-
-static void parseSymtab(ElfuElf *me, ElfuScn *ms, ElfuScn**origScnArr)
-{
- ElfuSym *sym;
- size_t i;
-
- assert(ms);
- assert(ms->data.d_buf);
- assert(origScnArr);
-
- /* Parse symbols from their elfclass-specific format */
- if (me->elfclass == ELFCLASS32) {
- for (i = 1; (i + 1) * sizeof(Elf32_Sym) <= ms->shdr.sh_size; i++) {
- Elf32_Sym *cursym = ((Elf32_Sym*)ms->data.d_buf) + i;
- ElfuSym *newsym = malloc(sizeof(*sym));
- assert(newsym);
-
- newsym->name = cursym->st_name;
- newsym->value = cursym->st_value;
- newsym->size = cursym->st_size;
- newsym->bind = ELF32_ST_BIND(cursym->st_info);
- newsym->type = ELF32_ST_TYPE(cursym->st_info);
- newsym->other = cursym->st_other;
- newsym->shndx = cursym->st_shndx;
-
-
-
- CIRCLEQ_INSERT_TAIL(&ms->symtab.syms, newsym, elem);
- }
- } else if (me->elfclass == ELFCLASS64) {
- for (i = 1; (i + 1) * sizeof(Elf64_Sym) <= ms->shdr.sh_size; i++) {
- Elf64_Sym *cursym = ((Elf64_Sym*)ms->data.d_buf) + i;
- ElfuSym *newsym = malloc(sizeof(*sym));
- assert(newsym);
-
- newsym->name = cursym->st_name;
- newsym->value = cursym->st_value;
- newsym->size = cursym->st_size;
- newsym->bind = ELF64_ST_BIND(cursym->st_info);
- newsym->type = ELF64_ST_TYPE(cursym->st_info);
- newsym->other = cursym->st_other;
- newsym->shndx = cursym->st_shndx;
-
-
-
- CIRCLEQ_INSERT_TAIL(&ms->symtab.syms, newsym, elem);
- }
- } else {
- /* Unknown elfclass */
- assert(0);
- }
-
- /* For each section, find the section it points to if any. */
- CIRCLEQ_FOREACH(sym, &ms->symtab.syms, elem) {
- switch (sym->shndx) {
- case SHN_UNDEF:
- case SHN_ABS:
- case SHN_COMMON:
- sym->scnptr = NULL;
- break;
- default:
- sym->scnptr = origScnArr[sym->shndx - 1];
- break;
- }
- }
-}
-
-
-static void parseReltab32(ElfuScn *ms)
-{
- size_t i;
-
- assert(ms);
- assert(ms->data.d_buf);
-
-
- 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 = malloc(sizeof(*rel));
- assert(rel);
-
- rel->offset = currel->r_offset;
- rel->sym = ELF32_R_SYM(currel->r_info);
- rel->type = ELF32_R_TYPE(currel->r_info);
- rel->addendUsed = 0;
- rel->addend = 0;
-
- CIRCLEQ_INSERT_TAIL(&ms->reltab.rels, rel, elem);
- }
-}
-
-
-static void parseRelatab64(ElfuScn *ms)
-{
- size_t i;
-
- assert(ms);
- assert(ms->data.d_buf);
-
-
- for (i = 0; (i + 1) * sizeof(Elf64_Rela) <= ms->shdr.sh_size; i++) {
- Elf64_Rela *currel = &(((Elf64_Rela*)ms->data.d_buf)[i]);
- ElfuRel *rel;
-
- rel = malloc(sizeof(*rel));
- assert(rel);
-
- rel->offset = currel->r_offset;
- rel->sym = ELF64_R_SYM(currel->r_info);
- rel->type = ELF64_R_TYPE(currel->r_info);
- rel->addendUsed = 1;
- rel->addend = currel->r_addend;
-
- CIRCLEQ_INSERT_TAIL(&ms->reltab.rels, rel, elem);
- }
-}
-
-
-static int cmpScnOffs(const void *ms1, const void *ms2)
-{
- ElfuScn *s1 = *(ElfuScn**)ms1;
- ElfuScn *s2 = *(ElfuScn**)ms2;
-
- assert(ms1);
- assert(ms2);
-
- s1 = *(ElfuScn**)ms1;
- s2 = *(ElfuScn**)ms2;
-
- assert(s1);
- assert(s2);
-
-
- if (s1->shdr.sh_offset < s2->shdr.sh_offset) {
- return -1;
- } else if (s1->shdr.sh_offset == s2->shdr.sh_offset) {
- return 0;
- } else /* if (s1->shdr.sh_offset > s2->shdr.sh_offset) */ {
- return 1;
- }
-}
-
-
-
-static ElfuPhdr* parentPhdr(ElfuElf *me, ElfuScn *ms)
-{
- ElfuPhdr *mp;
-
- assert(me);
- assert(ms);
-
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- if (mp->phdr.p_type != PT_LOAD) {
- continue;
- }
-
- if (PHDR_CONTAINS_SCN_IN_MEMORY(&mp->phdr, &ms->shdr)) {
- return mp;
- }
-
- /* Give sections a second chance if they do not have any sh_addr
- * at all. */
- /* Actually we don't, because it's ambiguous.
- * Re-enable for experiments with strangely-formatted files.
- if (ms->shdr.sh_addr == 0
- && PHDR_CONTAINS_SCN_IN_FILE(&mp->phdr, &ms->shdr)
- && OFFS_END(ms->shdr.sh_offset, ms->shdr.sh_size)
- <= OFFS_END(mp->phdr.p_offset, mp->phdr.p_memsz)) {
- return mp;
- }
- */
- }
-
- return NULL;
-}
-
-
-static ElfuPhdr* modelFromPhdr(GElf_Phdr *phdr)
-{
- ElfuPhdr *mp;
-
- assert(phdr);
-
- mp = malloc(sizeof(ElfuPhdr));
- if (!mp) {
- ELFU_WARN("modelFromPhdr: malloc() failed for ElfuPhdr.\n");
- return NULL;
- }
-
- mp->phdr = *phdr;
-
- CIRCLEQ_INIT(&mp->childScnList);
- CIRCLEQ_INIT(&mp->childPhdrList);
-
- return mp;
-}
-
-
-static ElfuScn* modelFromSection(Elf_Scn *scn)
-{
- ElfuScn *ms;
-
- assert(scn);
-
- ms = malloc(sizeof(ElfuScn));
- if (!ms) {
- ELFU_WARN("modelFromSection: malloc() failed for ElfuScn.\n");
- goto ERROR;
- }
-
-
- assert(gelf_getshdr(scn, &ms->shdr) == &ms->shdr);
-
-
- /* Copy each data part in source segment */
- ms->data.d_align = 1;
- ms->data.d_buf = NULL;
- ms->data.d_off = 0;
- ms->data.d_type = ELF_T_BYTE;
- ms->data.d_size = ms->shdr.sh_size;
- ms->data.d_version = elf_version(EV_NONE);
- if (ms->shdr.sh_type != SHT_NOBITS
- && ms->shdr.sh_size > 0) {
- Elf_Data *data;
-
- ms->data.d_buf = malloc(ms->shdr.sh_size);
- if (!ms->data.d_buf) {
- ELFU_WARN("modelFromSection: malloc() failed for data buffer (%x bytes).\n", (unsigned)ms->shdr.sh_size);
- goto ERROR;
- }
-
- /* A non-empty section should contain at least one data block. */
- data = elf_rawdata(scn, NULL);
- assert(data);
-
- ms->data.d_align = data->d_align;
- ms->data.d_type = data->d_type;
- ms->data.d_version = data->d_version;
-
- while (data) {
- if (data->d_off + data->d_size > ms->shdr.sh_size) {
- ELFU_WARN("modelFromSection: libelf delivered a bogus data blob. Skipping\n");
- } else {
- memcpy((char*)ms->data.d_buf + data->d_off, data->d_buf, data->d_size);
- }
-
- data = elf_rawdata(scn, data);
- }
- }
-
- ms->linkptr = NULL;
- ms->infoptr = NULL;
-
- ms->oldptr = NULL;
-
- CIRCLEQ_INIT(&ms->symtab.syms);
- CIRCLEQ_INIT(&ms->reltab.rels);
-
-
- return ms;
-
- ERROR:
- if (ms) {
- free(ms);
- }
- return NULL;
-}
-
-
-
-
-ElfuElf* elfu_mFromElf(Elf *e)
-{
- ElfuElf *me;
- size_t shstrndx;
- size_t i, numPhdr, numShdr;
- ElfuScn **secArray = NULL;
-
- assert(e);
- if (elfu_eCheck(e)) {
- goto ERROR;
- }
-
- me = malloc(sizeof(ElfuElf));
- if (!me) {
- ELFU_WARN("elfu_mFromElf: malloc() failed for ElfuElf.\n");
- goto ERROR;
- }
-
-
- /* General stuff */
- CIRCLEQ_INIT(&me->phdrList);
- CIRCLEQ_INIT(&me->orphanScnList);
- me->shstrtab = NULL;
- me->symtab = NULL;
-
- me->elfclass = gelf_getclass(e);
- assert(me->elfclass != ELFCLASSNONE);
- assert(gelf_getehdr(e, &me->ehdr) == &me->ehdr);
-
-
- /* Get the section string table index */
- if (elf_getshdrstrndx(e, &shstrndx) != 0) {
- shstrndx = 0;
- }
-
-
- /* Load segments */
- assert(!elf_getphdrnum(e, &numPhdr));
- for (i = 0; i < numPhdr; i++) {
- GElf_Phdr phdr;
- ElfuPhdr *mp;
-
- assert(gelf_getphdr(e, i, &phdr) == &phdr);
-
- mp = modelFromPhdr(&phdr);
- if (!mp) {
- goto ERROR;
- }
-
- CIRCLEQ_INSERT_TAIL(&me->phdrList, mp, elem);
- }
-
- if (numPhdr > 0) {
- ElfuPhdr *mp;
-
- /* Find PHDR -> PHDR dependencies (needs sorted sections) */
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- ElfuPhdr *mp2;
-
- if (mp->phdr.p_type != PT_LOAD) {
- continue;
- }
-
- CIRCLEQ_FOREACH(mp2, &me->phdrList, elem) {
- if (mp2 == mp) {
- continue;
- }
-
- if (mp->phdr.p_vaddr <= mp2->phdr.p_vaddr
- && OFFS_END(mp2->phdr.p_vaddr, mp2->phdr.p_memsz) <= OFFS_END(mp->phdr.p_vaddr, mp->phdr.p_memsz)) {
- CIRCLEQ_INSERT_TAIL(&mp->childPhdrList, mp2, elemChildPhdr);
- }
- }
- }
- }
-
-
- /* Load sections */
- assert(!elf_getshdrnum(e, &numShdr));
- if (numShdr > 1) {
- secArray = malloc((numShdr - 1) * sizeof(*secArray));
- if (!secArray) {
- ELFU_WARN("elfu_mFromElf: malloc() failed for secArray.\n");
- goto ERROR;
- }
-
- for (i = 1; i < numShdr; i++) {
- Elf_Scn *scn;
- ElfuScn *ms;
-
- scn = elf_getscn(e, i);
- assert(scn);
-
- ms = modelFromSection(scn);
- if (!ms) {
- goto ERROR;
- }
-
- secArray[i-1] = ms;
-
- if (i == shstrndx) {
- me->shstrtab = ms;
- }
- }
-
-
- /* Find sh_link and sh_info dependencies (needs sections in original order) */
- for (i = 0; i < numShdr - 1; i++) {
- ElfuScn *ms = secArray[i];
-
- switch (ms->shdr.sh_type) {
- case SHT_REL:
- case SHT_RELA:
- if (ms->shdr.sh_info > 0) {
- ms->infoptr = secArray[ms->shdr.sh_info - 1];
- }
- case SHT_DYNAMIC:
- case SHT_HASH:
- case SHT_SYMTAB:
- case SHT_DYNSYM:
- case SHT_GNU_versym:
- case SHT_GNU_verdef:
- case SHT_GNU_verneed:
- if (ms->shdr.sh_link > 0) {
- ms->linkptr = secArray[ms->shdr.sh_link - 1];
- }
- }
- }
-
-
- /* Parse symtabs (needs sections in original order) */
- for (i = 0; i < numShdr - 1; i++) {
- ElfuScn *ms = secArray[i];
-
- switch (ms->shdr.sh_type) {
- case SHT_SYMTAB:
- me->symtab = ms;
- case SHT_DYNSYM:
- parseSymtab(me, ms, secArray);
- break;
- }
- }
-
-
- /* Parse relocations */
- for (i = 0; i < numShdr - 1; i++) {
- ElfuScn *ms = secArray[i];
-
- switch (ms->shdr.sh_type) {
- case SHT_REL:
- if (me->elfclass == ELFCLASS32) {
- parseReltab32(ms);
- } else if (me->elfclass == ELFCLASS64) {
- /* Not used on x86-64 */
- assert(0);
- }
- break;
- case SHT_RELA:
- if (me->elfclass == ELFCLASS32) {
- /* Not used on x86-32 */
- assert(0);
- } else if (me->elfclass == ELFCLASS64) {
- parseRelatab64(ms);
- }
- break;
- }
- }
-
-
- /* Sort sections by file offset */
- qsort(secArray, numShdr - 1, sizeof(*secArray), cmpScnOffs);
-
-
- /* Find PHDR -> Section dependencies (needs sorted sections) */
- for (i = 0; i < numShdr - 1; i++) {
- ElfuScn *ms = secArray[i];
-
- ElfuPhdr *parent = parentPhdr(me, ms);
-
- if (parent) {
- GElf_Off shaddr = parent->phdr.p_vaddr +
- (ms->shdr.sh_offset - parent->phdr.p_offset);
-
- if (ms->shdr.sh_addr == 0) {
- ms->shdr.sh_addr = shaddr;
- } else {
- assert(ms->shdr.sh_addr == shaddr);
- }
-
- CIRCLEQ_INSERT_TAIL(&parent->childScnList, ms, elemChildScn);
- } else {
- CIRCLEQ_INSERT_TAIL(&me->orphanScnList, ms, elemChildScn);
- }
- }
- }
-
-
- return me;
-
-
- ERROR:
- if (secArray) {
- free(secArray);
- }
- if (me) {
- // TODO: Free data structures
- }
-
- ELFU_WARN("elfu_mFromElf: Failed to load file.\n");
- return NULL;
-}
diff --git a/src/modelops/layout.c b/src/modelops/layout.c
deleted file mode 100644
index 8abc766..0000000
--- a/src/modelops/layout.c
+++ /dev/null
@@ -1,324 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libelfu/libelfu.h>
-
-
-
-static GElf_Word shiftStuffAtAfterOffset(ElfuElf *me,
- GElf_Off offset,
- GElf_Word size)
-{
- ElfuPhdr *mp;
- ElfuScn *ms;
- /* Force a minimum alignment, just to be sure. */
- GElf_Word align = 64;
-
- /* Find maximum alignment size by which we have to shift.
- * Assumes alignment sizes are always 2^x. */
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- if (mp->phdr.p_offset >= offset) {
- if (mp->phdr.p_align > align) {
- align = mp->phdr.p_align;
- }
- }
- }
-
- CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
- if (ms->shdr.sh_offset >= offset) {
- if (ms->shdr.sh_addralign > align) {
- align = ms->shdr.sh_addralign;
- }
- }
- }
-
- size = ROUNDUP(size, align);
-
- /* Shift stuff */
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- if (mp->phdr.p_type != PT_LOAD) {
- continue;
- }
-
- if (mp->phdr.p_offset >= offset) {
- mp->phdr.p_offset += size;
-
- elfu_mPhdrUpdateChildOffsets(mp);
- }
- }
-
- CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
- if (ms->shdr.sh_offset >= offset) {
- ms->shdr.sh_offset += size;
- }
- }
-
- if (me->ehdr.e_phoff >= offset) {
- me->ehdr.e_phoff += size;
- }
-
- if (me->ehdr.e_shoff >= offset) {
- me->ehdr.e_shoff += size;
- }
-
- return size;
-}
-
-
-
-
-
-/* Finds a suitable PHDR to insert a hole into and expands it
- * if necessary.
- * Returns memory address the hole will be mapped to, or 0 if
- * the operation failed. */
-GElf_Addr elfu_mLayoutGetSpaceInPhdr(ElfuElf *me, GElf_Word size,
- GElf_Word align, int w, int x,
- ElfuPhdr **injPhdr)
-{
- ElfuPhdr *first = NULL;
- ElfuPhdr *last = NULL;
- ElfuPhdr *mp;
-
- assert(!(w && x));
-
- /* Treat read-only data as executable.
- * That's what the GNU toolchain does on x86. */
- if (!w && !x) {
- x = 1;
- }
-
- /* Find first and last LOAD PHDRs.
- * Don't compare p_memsz - segments don't overlap in memory. */
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- if (mp->phdr.p_type != PT_LOAD) {
- continue;
- }
- if (!first || mp->phdr.p_vaddr < first->phdr.p_vaddr) {
- first = mp;
- }
- if (!last || mp->phdr.p_vaddr > last->phdr.p_vaddr) {
- last = mp;
- }
- }
-
- if ((w && (last->phdr.p_flags & PF_W))
- || (x && (last->phdr.p_flags & PF_X))) {
- /* Need to append. */
- GElf_Off injOffset = OFFS_END(last->phdr.p_offset, last->phdr.p_filesz);
- GElf_Word injSpace = 0;
- GElf_Word nobitsize = last->phdr.p_memsz - last->phdr.p_filesz;
-
- /* Expand NOBITS if any */
- if (nobitsize > 0) {
- GElf_Off endOff = OFFS_END(last->phdr.p_offset, last->phdr.p_filesz);
- GElf_Off endAddr = OFFS_END(last->phdr.p_vaddr, last->phdr.p_filesz);
- ElfuScn *ms;
-
- ELFU_INFO("Expanding NOBITS at address 0x%x...\n", (unsigned)endAddr);
-
- CIRCLEQ_FOREACH(ms, &last->childScnList, elemChildScn) {
- if (ms->shdr.sh_offset == endOff) {
- assert(ms->shdr.sh_type == SHT_NOBITS);
- assert(ms->shdr.sh_size == nobitsize);
- ms->data.d_buf = malloc(ms->shdr.sh_size);
- memset(ms->data.d_buf, '\0', ms->shdr.sh_size);
- if (!ms->data.d_buf) {
- ELFU_WARN("mExpandNobits: Could not allocate %u bytes for NOBITS expansion. Data may be inconsistent.\n",
- (unsigned)ms->shdr.sh_size);
- assert(0);
- goto ERROR;
- }
-
- ms->data.d_align = 1;
- ms->data.d_off = 0;
- ms->data.d_type = ELF_T_BYTE;
- ms->data.d_size = ms->shdr.sh_size;
- ms->data.d_version = elf_version(EV_NONE);
-
- ms->shdr.sh_type = SHT_PROGBITS;
- ms->shdr.sh_addr = endAddr;
- }
- }
-
- injSpace += shiftStuffAtAfterOffset(me, endOff, nobitsize);
- injSpace -= nobitsize;
- injOffset += nobitsize;
- last->phdr.p_filesz += nobitsize;
- assert(last->phdr.p_filesz == last->phdr.p_memsz);
- }
-
- /* Calculate how much space we need, taking alignment into account */
- size += ROUNDUP(injOffset, align) - injOffset;
-
- /* If there is not enough space left, create even more. */
- if (injSpace < size) {
- injSpace += shiftStuffAtAfterOffset(me, injOffset, size - injSpace);
- }
- assert(injSpace >= size);
-
- /* Remap ourselves */
- last->phdr.p_filesz += size;
- last->phdr.p_memsz += size;
-
- injOffset = ROUNDUP(injOffset, align);
-
- if (injPhdr) {
- *injPhdr = last;
- }
- return last->phdr.p_vaddr + (injOffset - last->phdr.p_offset);
- } else if ((w && (first->phdr.p_flags & PF_W))
- || (x && (first->phdr.p_flags & PF_X))) {
- /* Need to prepend or split up the PHDR. */
- GElf_Off injOffset = OFFS_END(first->phdr.p_offset, first->phdr.p_filesz);
- ElfuScn *ms;
-
- /* Round up size to take PHDR alignment into account.
- * We assume that this is a multiple of the alignment asked for. */
- assert(first->phdr.p_align >= align);
- size = ROUNDUP(size, first->phdr.p_align);
-
- /* Find first section. We assume there is at least one. */
- assert(!CIRCLEQ_EMPTY(&first->childScnList));
- injOffset = CIRCLEQ_FIRST(&first->childScnList)->shdr.sh_offset;
-
- /* Move our sections */
- CIRCLEQ_FOREACH(ms, &first->childScnList, elemChildScn) {
- if (ms->shdr.sh_offset >= injOffset) {
- ms->shdr.sh_offset += size;
- }
- }
-
- /* Move our PHDRs */
- CIRCLEQ_FOREACH(mp, &first->childPhdrList, elemChildPhdr) {
- if (mp->phdr.p_offset >= injOffset) {
- mp->phdr.p_offset += size;
- } else {
- mp->phdr.p_vaddr -= size;
- mp->phdr.p_paddr -= size;
- }
- }
-
- /* Move other PHDRs and sections */
- assert(size <= shiftStuffAtAfterOffset(me, injOffset, size));
-
- /* Remap ourselves */
- first->phdr.p_vaddr -= size;
- first->phdr.p_paddr -= size;
- first->phdr.p_filesz += size;
- first->phdr.p_memsz += size;
-
- injOffset = ROUNDUP(injOffset, align);
-
- if (injPhdr) {
- *injPhdr = first;
- }
- return first->phdr.p_vaddr + (injOffset - first->phdr.p_offset);
- }
-
- ERROR:
- if (injPhdr) {
- *injPhdr = NULL;
- }
- return 0;
-}
-
-
-
-
-static int cmpPhdrOffs(const void *mp1, const void *mp2)
-{
- ElfuPhdr *p1;
- ElfuPhdr *p2;
-
- assert(mp1);
- assert(mp2);
-
- p1 = *(ElfuPhdr**)mp1;
- p2 = *(ElfuPhdr**)mp2;
-
- assert(p1);
- assert(p2);
-
-
- if (p1->phdr.p_offset < p2->phdr.p_offset) {
- return -1;
- } else if (p1->phdr.p_offset == p2->phdr.p_offset) {
- return 0;
- } else /* if (p1->phdr.p_offset > p2->phdr.p_offset) */ {
- return 1;
- }
-}
-
-int elfu_mLayoutAuto(ElfuElf *me)
-{
- ElfuPhdr *mp;
- ElfuScn *ms;
- ElfuPhdr **phdrArr;
- GElf_Off lastend = 0;
- size_t i, j;
-
- assert(me);
-
- phdrArr = malloc(elfu_mPhdrCount(me) * sizeof(*phdrArr));
- if (!phdrArr) {
- ELFU_WARN("elfu_mLayoutAuto: malloc failed for phdrArr.\n");
- return 1;
- }
-
- i = 0;
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- if (mp->phdr.p_type != PT_LOAD) {
- continue;
- }
-
- phdrArr[i] = mp;
- i++;
- }
-
- /* Assume we have at least one LOAD PHDR,
- * and that it ends after EHDR and PHDRs */
- assert(i > 1);
-
- /* Sort array by file offset */
- qsort(phdrArr, i, sizeof(*phdrArr), cmpPhdrOffs);
-
- lastend = OFFS_END(phdrArr[0]->phdr.p_offset, phdrArr[0]->phdr.p_filesz);
-
- /* Wiggle offsets of 2nd, 3rd etc so take minimum space */
- for (j = 1; j < i; j++) {
- GElf_Off subalign = phdrArr[j]->phdr.p_offset % phdrArr[j]->phdr.p_align;
-
- if ((lastend % phdrArr[j]->phdr.p_align) <= subalign) {
- lastend += subalign - (lastend % phdrArr[j]->phdr.p_align);
- } else {
- lastend += phdrArr[j]->phdr.p_align - ((lastend % phdrArr[j]->phdr.p_align) - subalign);
- }
-
- phdrArr[j]->phdr.p_offset = lastend;
-
- elfu_mPhdrUpdateChildOffsets(phdrArr[j]);
-
- lastend = OFFS_END(phdrArr[j]->phdr.p_offset, phdrArr[j]->phdr.p_filesz);
- }
-
- free(phdrArr);
-
-
- /* Place orphaned sections afterwards, maintaining alignment */
- CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
- lastend = ROUNDUP(lastend, ms->shdr.sh_addralign);
-
- ms->shdr.sh_offset = lastend;
-
- lastend = OFFS_END(ms->shdr.sh_offset, SCNFILESIZE(&ms->shdr));
- }
-
-
- /* Move SHDRs to end */
- lastend = ROUNDUP(lastend, 8);
- me->ehdr.e_shoff = lastend;
-
-
- return 0;
-}
diff --git a/src/modelops/phdr.c b/src/modelops/phdr.c
deleted file mode 100644
index d26eb77..0000000
--- a/src/modelops/phdr.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <assert.h>
-#include <libelfu/libelfu.h>
-
-
-size_t elfu_mPhdrCount(ElfuElf *me)
-{
- ElfuPhdr *mp;
- size_t i = 0;
-
- assert(me);
-
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- i++;
- }
-
- return i;
-}
-
-
-
-void elfu_mPhdrUpdateChildOffsets(ElfuPhdr *mp)
-{
- ElfuScn *ms;
- ElfuPhdr *mpc;
-
- assert(mp);
- assert(mp->phdr.p_type == PT_LOAD);
-
- CIRCLEQ_FOREACH(mpc, &mp->childPhdrList, elemChildPhdr) {
- mpc->phdr.p_offset = mp->phdr.p_offset + (mpc->phdr.p_vaddr - mp->phdr.p_vaddr);
- }
-
- CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
- ms->shdr.sh_offset = mp->phdr.p_offset + (ms->shdr.sh_addr - mp->phdr.p_vaddr);
- }
-}
diff --git a/src/modelops/reladd.c b/src/modelops/reladd.c
deleted file mode 100644
index bc909e4..0000000
--- a/src/modelops/reladd.c
+++ /dev/null
@@ -1,323 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <libelfu/libelfu.h>
-
-
-static int appendData(ElfuScn *ms, void *buf, size_t len)
-{
- char *newbuf;
-
- assert(ms);
- assert(ms->shdr.sh_type != SHT_NOBITS);
- assert(ms->data.d_buf);
-
- newbuf = realloc(ms->data.d_buf, ms->shdr.sh_size + len);
- if (!newbuf) {
- ELFU_WARN("appendData: malloc() failed for newbuf.\n");
- return 1;
- }
-
- ms->data.d_buf = newbuf;
- memcpy(newbuf + ms->shdr.sh_size, buf, len);
- ms->shdr.sh_size += len;
- ms->data.d_size += len;
- assert(ms->shdr.sh_size == ms->data.d_size);
-
- return 0;
-}
-
-
-static ElfuScn* insertSection(ElfuElf *me, ElfuElf *mrel, ElfuScn *oldscn)
-{
- ElfuScn *newscn = NULL;
- GElf_Addr injAddr;
- GElf_Off injOffset;
- ElfuPhdr *injPhdr;
-
- if (oldscn->shdr.sh_flags & SHF_ALLOC) {
- newscn = elfu_mCloneScn(oldscn);
- if (!newscn) {
- return NULL;
- }
-
- if (newscn->shdr.sh_type == SHT_NOBITS) {
- /* Expand this to SHT_PROGBITS, then insert as such. */
-
- assert(!newscn->data.d_buf);
-
- newscn->data.d_buf = malloc(newscn->shdr.sh_size);
- if (!newscn->data.d_buf) {
- goto ERROR;
- }
- newscn->data.d_size = newscn->shdr.sh_size;
- newscn->shdr.sh_type = SHT_PROGBITS;
- }
-
- injAddr = elfu_mLayoutGetSpaceInPhdr(me,
- newscn->shdr.sh_size,
- newscn->shdr.sh_addralign,
- newscn->shdr.sh_flags & SHF_WRITE,
- newscn->shdr.sh_flags & SHF_EXECINSTR,
- &injPhdr);
-
- if (!injPhdr) {
- ELFU_WARN("insertSection: Could not find a place to insert section.\n");
- goto ERROR;
- }
-
- ELFU_INFO("Inserting %s at address 0x%x...\n",
- elfu_mScnName(mrel, oldscn),
- (unsigned)injAddr);
-
- injOffset = injAddr - injPhdr->phdr.p_vaddr + injPhdr->phdr.p_offset;
-
- newscn->shdr.sh_addr = injAddr;
- newscn->shdr.sh_offset = injOffset;
-
- if (CIRCLEQ_EMPTY(&injPhdr->childScnList)
- || CIRCLEQ_LAST(&injPhdr->childScnList)->shdr.sh_offset < injOffset) {
- CIRCLEQ_INSERT_TAIL(&injPhdr->childScnList, newscn, elemChildScn);
- } else {
- ElfuScn *ms;
- CIRCLEQ_FOREACH(ms, &injPhdr->childScnList, elemChildScn) {
- if (injOffset < ms->shdr.sh_offset) {
- CIRCLEQ_INSERT_BEFORE(&injPhdr->childScnList, ms, newscn, elemChildScn);
- break;
- }
- }
- }
-
-
- /* Inject name */
- if (me->shstrtab) {
- char *newname;
- size_t newnamelen;
-
- newnamelen = strlen("reladd") + 1;
- if (elfu_mScnName(mrel, oldscn)) {
- newnamelen += strlen(elfu_mScnName(mrel, oldscn));
- }
-
- newname = malloc(newnamelen);
- strcpy(newname, "reladd");
- strcat(newname, elfu_mScnName(mrel, oldscn));
-
- if (!newname) {
- ELFU_WARN("insertSection: malloc() failed for newname. Leaving section name empty.\n");
- newscn->shdr.sh_name = 0;
- } else {
- size_t offset = me->shstrtab->shdr.sh_size;
-
- if (!appendData(me->shstrtab, newname, newnamelen)) {
- newscn->shdr.sh_name = offset;
- }
-
- free(newname);
- }
- }
-
- return newscn;
- } else {
- ELFU_WARN("insertSection: Skipping non-memory section %s (type %d flags %u).\n",
- elfu_mScnName(mrel, oldscn),
- oldscn->shdr.sh_type,
- (unsigned)oldscn->shdr.sh_flags);
- goto ERROR;
- }
-
- ERROR:
- if (newscn) {
- // TODO: Destroy newscn
- }
- return NULL;
-}
-
-
-static void* subScnAdd1(ElfuElf *mrel, ElfuScn *ms, void *aux1, void *aux2)
-{
- ElfuScn *newscn;
- ElfuElf *me = (ElfuElf*)aux1;
- (void)aux2;
-
-
- switch(ms->shdr.sh_type) {
- case SHT_PROGBITS: /* 1 */
- case SHT_NOBITS: /* 8 */
- /* Ignore empty sections */
- if (ms->shdr.sh_size == 0) {
- break;
- }
-
- /* Find a place where it belongs and shove it in. */
- newscn = insertSection(me, mrel, ms);
- if (!newscn) {
- ELFU_WARN("mReladd: Could not insert section %s (type %d), skipping.\n",
- elfu_mScnName(mrel, ms),
- ms->shdr.sh_type);
- }
- break;
- }
-
- return NULL;
-}
-
-
-static void* subScnAdd2(ElfuElf *mrel, ElfuScn *ms, void *aux1, void *aux2)
-{
- ElfuElf *me = (ElfuElf*)aux1;
- (void)aux2;
-
- switch(ms->shdr.sh_type) {
- case SHT_NULL: /* 0 */
- case SHT_PROGBITS: /* 1 */
- case SHT_STRTAB: /* 3 */
- case SHT_NOBITS: /* 8 */
- break;
-
-
- case SHT_REL: /* 9 */
- /* Relocate. */
- elfu_mRelocate(me, elfu_mScnByOldscn(me, ms->infoptr), ms);
- break;
-
- case SHT_RELA: /* 4 */
- // TODO: Needs a parser
- //elfu_mRelocate(elfu_mScnByOldscn(me, ms->infoptr), ms);
-
- case SHT_SYMTAB: /* 2 */
- /* Merge with the existing table. Take care of string tables also. */
-
- /* The next section types either do not occur in .o files, or are
- * not strictly necessary to process here. */
- case SHT_NOTE: /* 7 */
- case SHT_HASH: /* 5 */
- case SHT_DYNAMIC: /* 6 */
- case SHT_SHLIB: /* 10 */
- case SHT_DYNSYM: /* 11 */
- case SHT_INIT_ARRAY: /* 14 */
- case SHT_FINI_ARRAY: /* 15 */
- case SHT_PREINIT_ARRAY: /* 16 */
- case SHT_GROUP: /* 17 */
- case SHT_SYMTAB_SHNDX: /* 18 */
- case SHT_NUM: /* 19 */
- default:
- ELFU_WARN("mReladd: Skipping section %s (type %d).\n",
- elfu_mScnName(mrel, ms),
- ms->shdr.sh_type);
- }
-
- return NULL;
-}
-
-
-
-static void insertSymClone(ElfuElf *me, const ElfuScn *oldmsst, const ElfuSym *oldsym)
-{
- GElf_Xword newsize;
- char *newbuf;
- ElfuScn *newscn = NULL;
- ElfuSym *newsym;
- char *oldsymname;
-
- assert(me);
- assert(oldmsst);
- assert(oldsym);
-
- /* If the old symbol pointed to a section, find its clone in the target */
- if (oldsym->scnptr) {
- newscn = elfu_mScnByOldscn(me, oldsym->scnptr);
-
- /* If we didn't copy the section referenced, we won't
- * copy this symbol either */
- if (!newscn) {
- return;
- }
- }
-
- // TODO: Allocate symtab if none present
- assert(me->symtab);
-
- /* Allocate memory for the cloned symbol */
- newsym = malloc(sizeof(*newsym));
- if (!newsym) {
- ELFU_WARN("insertSymClone: malloc() failed for newsym.\n");
- goto ERROR;
- }
-
- oldsymname = ELFU_SYMSTR(oldmsst, oldsym->name);
-
- /* Expand .strtab, append symbol name, link newsym to it */
- newsize = me->symtab->linkptr->shdr.sh_size + strlen(oldsymname) + 1;
- newbuf = realloc(me->symtab->linkptr->data.d_buf, newsize);
- if (!newbuf) {
- ELFU_WARN("insertSymClone: realloc() failed for strtab.\n");
- goto ERROR;
- }
-
- me->symtab->linkptr->data.d_buf = newbuf;
-
- newsym->name = me->symtab->linkptr->shdr.sh_size;
-
- strcpy(newbuf + newsym->name, oldsymname);
-
- me->symtab->linkptr->data.d_size = newsize;
- me->symtab->linkptr->shdr.sh_size = newsize;
-
-
- /* Copy all other fields */
- newsym->scnptr = newscn;
- newsym->shndx = oldsym->shndx; /* If scnptr == NULL, this becomes relevant */
- newsym->bind = oldsym->bind;
- newsym->other = oldsym->other;
- newsym->size = oldsym->size;
- newsym->type = oldsym->type;
- newsym->value = oldsym->value;
-
- /* In executables, symbol addresses need to be in memory */
- if (newscn) {
- newsym->value += newscn->shdr.sh_addr;
- }
-
- /* Insert symbol */
- CIRCLEQ_INSERT_TAIL(&me->symtab->symtab.syms, newsym, elem);
-
- return;
-
- ERROR:
- if (newsym) {
- free(newsym);
- }
-}
-
-static void mergeSymtab(ElfuElf *me, const ElfuElf *mrel)
-{
- ElfuSym *sym;
-
- assert(me);
- assert(mrel);
-
- CIRCLEQ_FOREACH(sym, &mrel->symtab->symtab.syms, elem) {
- insertSymClone(me, mrel->symtab, sym);
- }
-}
-
-
-
-void elfu_mReladd(ElfuElf *me, const ElfuElf *mrel)
-{
- assert(me);
- assert(mrel);
-
- /* For each section in object file, guess how to insert it */
- elfu_mScnForall((ElfuElf*)mrel, subScnAdd1, me, NULL);
-
- mergeSymtab(me, mrel);
-
- /* Do relocations and other stuff */
- elfu_mScnForall((ElfuElf*)mrel, subScnAdd2, me, NULL);
-
- /* Re-layout to accommodate new contents */
- elfu_mLayoutAuto(me);
-}
diff --git a/src/modelops/relocate.c b/src/modelops/relocate.c
deleted file mode 100644
index eefed02..0000000
--- a/src/modelops/relocate.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libelfu/libelfu.h>
-
-
-/* Apply relocation information from section *msrt to data in
- * section *mstarget (which is stored in *metarget). */
-void elfu_mRelocate(ElfuElf *metarget, ElfuScn *mstarget, ElfuScn *msrt)
-{
- ElfuRel *rel;
-
- assert(mstarget);
- assert(msrt);
-
- ELFU_DEBUG("Relocating in section of type %u size %x\n",
- mstarget->shdr.sh_type,
- (unsigned)mstarget->shdr.sh_size);
-
- CIRCLEQ_FOREACH(rel, &msrt->reltab.rels, elem) {
- Elf32_Word *dest32 = (Elf32_Word*)(((char*)(mstarget->data.d_buf)) + rel->offset);
- Elf64_Word *dest64 = (Elf64_Word*)(((char*)(mstarget->data.d_buf)) + rel->offset);
-
-
- if (metarget->elfclass == ELFCLASS32) {
- Elf32_Word a32 = rel->addendUsed ? rel->addend : *dest32;
- Elf32_Addr p32 = mstarget->shdr.sh_addr + rel->offset;
- Elf32_Addr s32 = elfu_mSymtabLookupVal(metarget, msrt->linkptr, rel->sym);
- switch(rel->type) {
- case R_386_NONE:
- ELFU_DEBUG("Skipping relocation: R_386_NONE\n");
- break;
- case R_386_32:
- *dest32 = s32 + a32;
- break;
- case R_386_PC32:
- *dest32 = s32 + a32 - p32;
- break;
-
- default:
- ELFU_DEBUG("Skipping relocation: Unknown type %d\n", rel->type);
- }
- } else if (metarget->elfclass == ELFCLASS64) {
- Elf64_Word a64 = rel->addend;
- Elf64_Addr p64 = mstarget->shdr.sh_addr + rel->offset;
- Elf64_Addr s64 = elfu_mSymtabLookupVal(metarget, msrt->linkptr, rel->sym);
-
- /* x86-64 only uses RELA with explicit addend. */
- assert(rel->addendUsed);
-
- switch(rel->type) {
- case R_X86_64_NONE:
- ELFU_DEBUG("Skipping relocation: R_386_NONE\n");
- break;
- case R_X86_64_64:
- *dest64 = s64 + a64;
- break;
- case R_X86_64_PC32:
- *dest32 = s64 + a64 - p64;
- break;
- case R_X86_64_32:
- *dest32 = s64 + a64;
- break;
-
- default:
- ELFU_DEBUG("Skipping relocation: Unknown type %d", rel->type);
- }
- }
- }
-}
diff --git a/src/modelops/section.c b/src/modelops/section.c
deleted file mode 100644
index 2675126..0000000
--- a/src/modelops/section.c
+++ /dev/null
@@ -1,196 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <libelfu/libelfu.h>
-
-
-/* Meta-functions */
-
-void* elfu_mScnForall(ElfuElf *me, SectionHandlerFunc f, void *aux1, void *aux2)
-{
- ElfuPhdr *mp;
- ElfuScn *ms;
-
- // TODO: Sort PHDRs by offset before interating
-
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- if (mp->phdr.p_type != PT_LOAD) {
- continue;
- }
-
- CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
- void *rv = f(me, ms, aux1, aux2);
-
- if (rv) {
- return rv;
- }
- }
- }
-
- CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
- void *rv = f(me, ms, aux1, aux2);
-
- if (rv) {
- return rv;
- }
- }
-
- return NULL;
-}
-
-
-
-
-/* Counting */
-
-static void* subCounter(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
- size_t *i = (size_t*)aux1;
- ElfuScn *otherScn = (ElfuScn*)aux2;
-
- if (ms == otherScn) {
- return ms;
- }
-
- *i += 1;
-
- /* Continue */
- return NULL;
-}
-
-
-size_t elfu_mScnCount(ElfuElf *me)
-{
- /* NULL section *is not* counted */
- size_t i = 0;
-
- assert(me);
-
- elfu_mScnForall(me, subCounter, &i, NULL);
-
- return i;
-}
-
-
-/* Returns the index a section would have in the flattened ELF */
-size_t elfu_mScnIndex(ElfuElf *me, ElfuScn *ms)
-{
- /* NULL section *is* counted */
- size_t i = 1;
-
- assert(me);
- assert(ms);
-
- elfu_mScnForall(me, subCounter, &i, ms);
-
- /* If this assertion is broken then ms is not a section in me. */
- assert(i <= elfu_mScnCount(me));
- return i;
-}
-
-
-static void* subOldscn(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
- ElfuScn *otherScn = (ElfuScn*)aux1;
- (void)aux2;
-
- if (ms->oldptr == otherScn) {
- return ms;
- }
-
- /* Continue */
- return NULL;
-}
-
-/* Returns the section with oldscn == oldscn */
-ElfuScn* elfu_mScnByOldscn(ElfuElf *me, ElfuScn *oldscn)
-{
- assert(me);
- assert(oldscn);
-
- return elfu_mScnForall(me, subOldscn, oldscn, NULL);
-}
-
-
-
-
-/* Convenience */
-
-char* elfu_mScnName(ElfuElf *me, ElfuScn *ms)
-{
- assert(me);
- assert(ms);
-
- if (!me->shstrtab) {
- return NULL;
- }
-
- if (!me->shstrtab->data.d_buf) {
- return NULL;
- }
-
- return &((char*)me->shstrtab->data.d_buf)[ms->shdr.sh_name];
-}
-
-
-static void* subScnsToArray(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
- ElfuScn **arr = (ElfuScn**)aux1;
- size_t *i = (size_t*)aux2;
-
- arr[(*i)] = ms;
- *i += 1;
-
- /* Continue */
- return NULL;
-}
-
-static int cmpScnOffs(const void *ms1, const void *ms2)
-{
- ElfuScn *s1;
- ElfuScn *s2;
-
- assert(ms1);
- assert(ms2);
-
- s1 = *(ElfuScn**)ms1;
- s2 = *(ElfuScn**)ms2;
-
- assert(s1);
- assert(s2);
-
-
- if (s1->shdr.sh_offset < s2->shdr.sh_offset) {
- return -1;
- } else if (s1->shdr.sh_offset == s2->shdr.sh_offset) {
- return 0;
- } else /* if (s1->shdr.sh_offset > s2->shdr.sh_offset) */ {
- return 1;
- }
-}
-
-ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count)
-{
- size_t numSecs;
- ElfuScn **sortedSecs;
- size_t i;
-
- assert(me);
-
- /* Sort sections by offset in file */
- numSecs = elfu_mScnCount(me);
- sortedSecs = malloc(numSecs * sizeof(*sortedSecs));
- if (!sortedSecs) {
- ELFU_WARN("elfu_mScnSortedByOffset: Failed to allocate memory.\n");
- return NULL;
- }
-
- i = 0;
- elfu_mScnForall(me, subScnsToArray, sortedSecs, &i);
- assert(i == numSecs);
-
- qsort(sortedSecs, numSecs, sizeof(*sortedSecs), cmpScnOffs);
-
- *count = numSecs;
-
- return sortedSecs;
-}
diff --git a/src/modelops/symtab.c b/src/modelops/symtab.c
deleted file mode 100644
index ef8443f..0000000
--- a/src/modelops/symtab.c
+++ /dev/null
@@ -1,269 +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 *me, char *name)
-{
- ElfuScn *relplt;
- ElfuScn *plt;
- ElfuRel *rel;
- GElf_Word j;
-
- relplt = elfu_mScnForall(me, subFindByName, ".rel.plt", NULL);
- if (!relplt) {
- ELFU_WARN("dynsymLookupVal: Could not find .rel.plt section in destination ELF.\n");
- return 0;
- }
-
- plt = elfu_mScnForall(me, subFindByName, ".plt", NULL);
- if (!plt) {
- ELFU_WARN("dynsymLookupVal: Could not find .plt section in destination ELF.\n");
- return 0;
- }
-
-
- /* Look up name. If the j-th entry in .rel.plt has the name we are
- * looking for, we assume that the (j+1)-th entry in .plt is machine
- * code to jump to the function.
- * Your mileage may vary, but it works on my GNU binaries. */
- assert(relplt->linkptr);
- j = 0;
- CIRCLEQ_FOREACH(rel, &relplt->reltab.rels, elem) {
- GElf_Word i;
- ElfuSym *sym;
- char *symname;
-
- j++;
-
- /* We only consider runtime relocations for functions.
- * Technically, these relocations write the functions' addresses
- * to the GOT, not the PLT, after the dynamic linker has found
- * them. */
- if ((me->elfclass == ELFCLASS32 && rel->type != R_386_JMP_SLOT)
- || (me->elfclass == ELFCLASS64 && rel->type != R_X86_64_JUMP_SLOT)) {
- continue;
- }
-
- /* Get the (rel->sym)-th symbol from the symbol table that
- * .rel.plt points to. */
- sym = CIRCLEQ_FIRST(&relplt->linkptr->symtab.syms);
- for (i = 1; i < rel->sym; i++) {
- sym = CIRCLEQ_NEXT(sym, elem);
- }
-
- symname = ELFU_SYMSTR(relplt->linkptr, sym->name);
- if (!strcmp(symname, 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 %x (PLT entry #%u).\n", name, (unsigned)addr, j);
- return addr;
- }
- }
-
- ELFU_WARN("dynsymLookupVal: Could not find symbol '%s' in destination ELF.\n", name);
-
- return 0;
-}
-
-
-
-/* Look up a value in the symbol table section *msst which is in *me.
- * If it is not found there, see if we can find it in *me's PLT. */
-GElf_Word elfu_mSymtabLookupVal(ElfuElf *me, ElfuScn *msst, GElf_Word entry)
-{
- GElf_Word i;
- ElfuSym *sym;
- char *symname;
-
- assert(me);
- assert(msst);
- 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);
- }
- symname = ELFU_SYMSTR(msst, sym->name);
-
- switch (sym->type) {
- case STT_NOTYPE:
- case STT_OBJECT:
- case STT_FUNC:
- if (sym->scnptr) {
- ElfuScn *newscn = elfu_mScnByOldscn(me, sym->scnptr);
- assert(newscn);
- return newscn->shdr.sh_addr + sym->value;
- } else if (sym->shndx == SHN_UNDEF) {
- /* Look the symbol up in .rel.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(me, symname);
- } 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(me, sym->scnptr));
- return elfu_mScnByOldscn(me, 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, symname);
- return 0;
- }
-}
-
-
-/* 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)
-{
- ElfuSym *sym;
- size_t numsyms = 0;
-
- elfu_mLayoutAuto(me);
-
- /* Update section indexes and count symbols */
- CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
- if (sym->scnptr) {
- sym->shndx = elfu_mScnIndex(me, sym->scnptr);
- }
-
- numsyms++;
- }
-
- /* Copy symbols to elfclass-specific format */
- if (me->elfclass == ELFCLASS32) {
- size_t newsize = (numsyms + 1) * sizeof(Elf32_Sym);
- size_t i;
-
- if (me->symtab->data.d_buf) {
- free(me->symtab->data.d_buf);
- }
- me->symtab->data.d_buf = malloc(newsize);
- assert(me->symtab->data.d_buf);
-
- me->symtab->data.d_size = newsize;
- me->symtab->shdr.sh_size = newsize;
- memset(me->symtab->data.d_buf, 0, newsize);
-
- i = 1;
- CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
- Elf32_Sym *es = ((Elf32_Sym*)me->symtab->data.d_buf) + i;
-
- es->st_name = sym->name;
- es->st_value = sym->value;
- es->st_size = sym->size;
- es->st_info = ELF32_ST_INFO(sym->bind, sym->type);
- es->st_other = sym->other;
- es->st_shndx = sym->shndx;
-
- i++;
- }
- } else if (me->elfclass == ELFCLASS64) {
- size_t newsize = (numsyms + 1) * sizeof(Elf64_Sym);
- size_t i;
-
- if (me->symtab->data.d_buf) {
- free(me->symtab->data.d_buf);
- }
- me->symtab->data.d_buf = malloc(newsize);
- assert(me->symtab->data.d_buf);
-
- me->symtab->data.d_size = newsize;
- me->symtab->shdr.sh_size = newsize;
- memset(me->symtab->data.d_buf, 0, newsize);
-
- i = 1;
- CIRCLEQ_FOREACH(sym, &me->symtab->symtab.syms, elem) {
- Elf64_Sym *es = ((Elf64_Sym*)me->symtab->data.d_buf) + i;
-
- es->st_name = sym->name;
- es->st_value = sym->value;
- es->st_size = sym->size;
- es->st_info = ELF64_ST_INFO(sym->bind, sym->type);
- es->st_other = sym->other;
- es->st_shndx = sym->shndx;
-
- i++;
- }
- } else {
- /* Unknown elfclass */
- assert(0);
- }
-
- elfu_mLayoutAuto(me);
-}
diff --git a/src/modelops/toFile.c b/src/modelops/toFile.c
deleted file mode 100644
index 368f12a..0000000
--- a/src/modelops/toFile.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libelfu/libelfu.h>
-
-
-static void modelToPhdrs(ElfuElf *me, Elf *e)
-{
- ElfuPhdr *mp;
- size_t i;
-
- /* Count PHDRs */
- i = 0;
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- i++;
- }
-
- if (!gelf_newphdr(e, i)) {
- ELFU_WARNELF("gelf_newphdr");
- }
-
- /* Copy PHDRs */
- i = 0;
- CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
- if (!gelf_update_phdr (e, i, &mp->phdr)) {
- ELFU_WARNELF("gelf_update_phdr");
- }
-
- i++;
- }
-}
-
-
-
-static void* modelToSection(ElfuElf *me, ElfuScn *ms, void *aux1, void *aux2)
-{
- Elf_Scn *scnOut;
- Elf *e = (Elf*)aux1;
- (void) me;
- (void) aux2;
-
- scnOut = elf_newscn(e);
- if (!scnOut) {
- ELFU_WARNELF("elf_newscn");
- return (void*)-1;
- }
-
-
- /* SHDR */
- if (ms->linkptr) {
- ms->shdr.sh_link = elfu_mScnIndex(me, ms->linkptr);
- }
- if (ms->infoptr) {
- ms->shdr.sh_info = elfu_mScnIndex(me, ms->infoptr);
- }
- if (!gelf_update_shdr(scnOut, &ms->shdr)) {
- ELFU_WARNELF("gelf_update_shdr");
- }
-
-
- /* Data */
- if (ms->data.d_buf) {
- Elf_Data *dataOut = elf_newdata(scnOut);
- if (!dataOut) {
- ELFU_WARNELF("elf_newdata");
- }
-
- dataOut->d_align = ms->data.d_align;
- dataOut->d_buf = ms->data.d_buf;
- dataOut->d_off = ms->data.d_off;
- dataOut->d_type = ms->data.d_type;
- dataOut->d_size = ms->data.d_size;
- dataOut->d_version = ms->data.d_version;
- }
-
- return NULL;
-}
-
-
-
-
-
-void elfu_mToElf(ElfuElf *me, Elf *e)
-{
- if (me->symtab) {
- elfu_mSymtabFlatten(me);
- }
-
-
- /* We control the ELF file's layout now. */
- /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections,
- * but we don't want that since we filtered it out in the reading stage
- * already. It would be too mind-blowing to handle the dependencies between
- * the PHDRs and sections then... */
- elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
-
-
- /* EHDR */
- if (!gelf_newehdr(e, me->elfclass)) {
- ELFU_WARNELF("gelf_newehdr");
- }
-
- if (me->shstrtab) {
- me->ehdr.e_shstrndx = elfu_mScnIndex(me, me->shstrtab);
- }
-
- if (!gelf_update_ehdr(e, &me->ehdr)) {
- ELFU_WARNELF("gelf_update_ehdr");
- }
-
-
- /* Sections */
- elfu_mScnForall(me, modelToSection, e, NULL);
-
-
- /* PHDRs */
- modelToPhdrs(me, e);
-
-
- elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);
-}