summaryrefslogtreecommitdiff
path: root/src/libelfu
diff options
context:
space:
mode:
Diffstat (limited to 'src/libelfu')
-rw-r--r--src/libelfu/model/section.c24
-rw-r--r--src/libelfu/model/symtab.c45
-rw-r--r--src/libelfu/modelops/reladd.c44
3 files changed, 77 insertions, 36 deletions
diff --git a/src/libelfu/model/section.c b/src/libelfu/model/section.c
index 9ef6fd8..74fbc3a 100644
--- a/src/libelfu/model/section.c
+++ b/src/libelfu/model/section.c
@@ -198,6 +198,30 @@ ElfuScn** elfu_mScnSortedByOffset(ElfuElf *me, size_t *count)
+int elfu_mScnAppendData(ElfuScn *ms, void *buf, size_t len)
+{
+ char *newbuf;
+
+ assert(ms);
+ assert(ms->shdr.sh_type != SHT_NOBITS);
+ assert(ms->databuf);
+
+ newbuf = realloc(ms->databuf, ms->shdr.sh_size + len);
+ if (!newbuf) {
+ ELFU_WARN("elfu_mScnAppendData: malloc() failed for newbuf.\n");
+ return -1;
+ }
+
+ ms->databuf = newbuf;
+ memcpy(newbuf + ms->shdr.sh_size, buf, len);
+ ms->shdr.sh_size += len;
+ assert(ms->shdr.sh_size == ms->shdr.sh_size);
+
+ return 0;
+}
+
+
+
/*
* Allocation, destruction
*/
diff --git a/src/libelfu/model/symtab.c b/src/libelfu/model/symtab.c
index 0cf107b..439c4d3 100644
--- a/src/libelfu/model/symtab.c
+++ b/src/libelfu/model/symtab.c
@@ -198,3 +198,48 @@ void elfu_mSymtabFlatten(ElfuElf *me)
elfu_mLayoutAuto(me);
}
+
+
+
+void elfu_mSymtabAddGlobalDymtabIfNotPresent(ElfuElf *me)
+{
+ assert(me);
+
+ if (!me->symtab) {
+ ElfuScn *symtab;
+ ElfuScn *strtab;
+
+ symtab = elfu_mScnAlloc();
+ assert(symtab);
+ strtab = elfu_mScnAlloc();
+ assert(strtab);
+
+ symtab->linkptr = strtab;
+ symtab->shdr.sh_entsize = me->elfclass == ELFCLASS32 ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym);
+ symtab->shdr.sh_addralign = 4;
+ strtab->shdr.sh_addralign = 1;
+ symtab->shdr.sh_type = SHT_SYMTAB;
+ strtab->shdr.sh_type = SHT_STRTAB;
+
+ strtab->databuf = malloc(1);
+ assert(strtab->databuf);
+ strtab->databuf[0] = 0;
+
+ CIRCLEQ_INSERT_TAIL(&me->orphanScnList, symtab, elemChildScn);
+ CIRCLEQ_INSERT_TAIL(&me->orphanScnList, strtab, elemChildScn);
+
+ me->symtab = symtab;
+
+ if (me->shstrtab) {
+ symtab->shdr.sh_name = me->shstrtab->shdr.sh_size;
+ if (elfu_mScnAppendData(me->shstrtab, ".symtab", 8)) {
+ symtab->shdr.sh_name = 0;
+ }
+
+ strtab->shdr.sh_name = me->shstrtab->shdr.sh_size;
+ if (elfu_mScnAppendData(me->shstrtab, ".strtab", 8)) {
+ strtab->shdr.sh_name = 0;
+ }
+ }
+ }
+}
diff --git a/src/libelfu/modelops/reladd.c b/src/libelfu/modelops/reladd.c
index fc0adc3..1980c76 100644
--- a/src/libelfu/modelops/reladd.c
+++ b/src/libelfu/modelops/reladd.c
@@ -36,28 +36,6 @@ static ElfuScn* cloneScn(ElfuScn *ms)
}
-static int appendData(ElfuScn *ms, void *buf, size_t len)
-{
- char *newbuf;
-
- assert(ms);
- assert(ms->shdr.sh_type != SHT_NOBITS);
- assert(ms->databuf);
-
- newbuf = realloc(ms->databuf, ms->shdr.sh_size + len);
- if (!newbuf) {
- ELFU_WARN("appendData: malloc() failed for newbuf.\n");
- return 1;
- }
-
- ms->databuf = newbuf;
- memcpy(newbuf + ms->shdr.sh_size, buf, len);
- ms->shdr.sh_size += len;
- assert(ms->shdr.sh_size == ms->shdr.sh_size);
-
- return 0;
-}
-
static ElfuScn* insertSection(ElfuElf *me, ElfuElf *mrel, ElfuScn *oldscn)
{
@@ -128,7 +106,6 @@ static ElfuScn* insertSection(ElfuElf *me, ElfuElf *mrel, ElfuScn *oldscn)
/* Inject name */
if (me->shstrtab) {
- char *newname;
size_t newnamelen;
newnamelen = strlen("reladd") + 1;
@@ -136,21 +113,15 @@ static ElfuScn* insertSection(ElfuElf *me, ElfuElf *mrel, ElfuScn *oldscn)
newnamelen += strlen(elfu_mScnName(mrel, oldscn));
}
- newname = malloc(newnamelen);
+ char newname[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;
- }
+ newscn->shdr.sh_name = me->shstrtab->shdr.sh_size;
- free(newname);
+ if (elfu_mScnAppendData(me->shstrtab, newname, newnamelen)) {
+ newscn->shdr.sh_name = 0;
}
}
@@ -262,8 +233,9 @@ static void insertSymClone(ElfuElf *me, const ElfuScn *oldmsst, const ElfuSym *o
}
}
- // TODO: Allocate symtab if none present
- assert(me->symtab);
+ /* If we don't have a symbol table, create one so we have somewhere to
+ * write our new symbols to. */
+ elfu_mSymtabAddGlobalDymtabIfNotPresent(me);
/* Allocate memory for the cloned symbol */
newsym = malloc(sizeof(*newsym));