GPLv2 release
[centaur.git] / src / libelfu / model / section.c
index c93c5c80b37114a9a3470bd803af553a9dfcbb83..3e6c89f2afc6923d3dbf88aa29c79965d6b9fe84 100644 (file)
@@ -1,3 +1,18 @@
+/* This file is part of centaur.
+ *
+ * centaur is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 2 as
+ * published by the Free Software Foundation.
+
+ * centaur is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with centaur.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
@@ -11,8 +26,6 @@ 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;
@@ -198,6 +211,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
  */
@@ -219,3 +256,38 @@ ElfuScn* elfu_mScnAlloc()
 
   return ms;
 }
+
+void elfu_mScnDestroy(ElfuScn* ms)
+{
+  assert(ms);
+
+  if (!CIRCLEQ_EMPTY(&ms->symtab.syms)) {
+    ElfuSym *nextsym;
+
+    nextsym = CIRCLEQ_FIRST(&ms->symtab.syms);
+    while ((void*)nextsym != (void*)&ms->symtab.syms) {
+      ElfuSym *cursym = nextsym;
+      nextsym = CIRCLEQ_NEXT(cursym, elem);
+      CIRCLEQ_REMOVE(&ms->symtab.syms, cursym, elem);
+      free(cursym);
+    }
+  }
+
+  if (!CIRCLEQ_EMPTY(&ms->reltab.rels)) {
+    ElfuRel *nextrel;
+
+    nextrel = CIRCLEQ_FIRST(&ms->reltab.rels);
+    while ((void*)nextrel != (void*)&ms->reltab.rels) {
+      ElfuRel *currel = nextrel;
+      nextrel = CIRCLEQ_NEXT(currel, elem);
+      CIRCLEQ_REMOVE(&ms->reltab.rels, currel, elem);
+      free(currel);
+    }
+  }
+
+  if (ms->databuf) {
+    free(ms->databuf);
+  }
+
+  free(ms);
+}