Implement memory management TODOs
authornorly <ny-git@enpas.org>
Fri, 28 Jun 2013 02:00:05 +0000 (03:00 +0100)
committernorly <ny-git@enpas.org>
Fri, 28 Jun 2013 02:00:05 +0000 (03:00 +0100)
src/elfucli.c
src/libelfu/model/elf.c
src/libelfu/model/phdr.c
src/libelfu/model/section.c
src/libelfu/modelops/fromFile.c
src/libelfu/modelops/layout.c
src/libelfu/modelops/reladd.c

index d5f55be88b11eadc81ee30d9caeee9bdd03cb838..b01c91a1c6992aecac7fbce4e5ec890eca20912c 100644 (file)
@@ -151,13 +151,16 @@ int main(int argc, char **argv)
             printf("--reladd: Injecting %s...\n", optarg);
             if (elfu_mCheck(mrel)) {
               printf("--reladd: Check for input file failed.\n");
+              elfu_mElfDestroy(mrel);
               goto ERR;
             }
             if (elfu_mReladd(me, mrel)) {
               printf("--reladd: Failed.\n");
+              elfu_mElfDestroy(mrel);
               goto ERR;
             }
             printf("--reladd: Injected %s.\n", optarg);
+            elfu_mElfDestroy(mrel);
           }
         }
         break;
index a25aa89e89637c5a1d0feccc2e0deec04b1f0084..11346a5d11bac85448cf955df4a37d9e6995cbf5 100644 (file)
@@ -29,22 +29,30 @@ ElfuElf* elfu_mElfAlloc()
 
 void elfu_mElfDestroy(ElfuElf* me)
 {
-  ElfuPhdr *mp;
-  ElfuScn *ms;
-
   assert(me);
 
-  CIRCLEQ_INIT(&me->phdrList);
-  CIRCLEQ_INIT(&me->orphanScnList);
+  if (!CIRCLEQ_EMPTY(&me->phdrList)) {
+    ElfuPhdr *nextmp;
 
-  CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
-    CIRCLEQ_REMOVE(&me->phdrList, mp, elem);
-    elfu_mPhdrDestroy(mp);
+    nextmp = CIRCLEQ_FIRST(&me->phdrList);
+    while ((void*)nextmp != (void*)&me->phdrList) {
+      ElfuPhdr *curmp = nextmp;
+      nextmp = CIRCLEQ_NEXT(curmp, elem);
+      CIRCLEQ_REMOVE(&me->phdrList, curmp, elem);
+      elfu_mPhdrDestroy(curmp);
+    }
   }
 
-  CIRCLEQ_FOREACH(ms, &me->orphanScnList, elemChildScn) {
-    CIRCLEQ_REMOVE(&me->orphanScnList, ms, elemChildScn);
-    elfu_mScnDestroy(ms);
+  if (!CIRCLEQ_EMPTY(&me->orphanScnList)) {
+    ElfuScn *nextms;
+
+    nextms = CIRCLEQ_FIRST(&me->orphanScnList);
+    while ((void*)nextms != (void*)&me->orphanScnList) {
+      ElfuScn *curms = nextms;
+      nextms = CIRCLEQ_NEXT(curms, elemChildScn);
+      CIRCLEQ_REMOVE(&me->orphanScnList, curms, elemChildScn);
+      elfu_mScnDestroy(curms);
+    }
   }
 
   free(me);
index b694eb9598928b1e9ef38de2747cfab34ab633cd..6f31e6b742567c2ba094161372909bacc2d4c53d 100644 (file)
@@ -194,19 +194,30 @@ ElfuPhdr* elfu_mPhdrAlloc()
 
 void elfu_mPhdrDestroy(ElfuPhdr* mp)
 {
-  ElfuPhdr *mp2;
-  ElfuScn *ms;
-
   assert(mp);
 
-  CIRCLEQ_FOREACH(mp2, &mp->childPhdrList, elemChildPhdr) {
-    CIRCLEQ_REMOVE(&mp->childPhdrList, mp2, elemChildPhdr);
-    elfu_mPhdrDestroy(mp2);
+  if (!CIRCLEQ_EMPTY(&mp->childPhdrList)) {
+    ElfuPhdr *nextmp;
+
+    nextmp = CIRCLEQ_FIRST(&mp->childPhdrList);
+    while ((void*)nextmp != (void*)&mp->childPhdrList) {
+      ElfuPhdr *curmp = nextmp;
+      nextmp = CIRCLEQ_NEXT(curmp, elemChildPhdr);
+      CIRCLEQ_REMOVE(&mp->childPhdrList, curmp, elemChildPhdr);
+      elfu_mPhdrDestroy(curmp);
+    }
   }
 
-  CIRCLEQ_FOREACH(ms, &mp->childScnList, elemChildScn) {
-    CIRCLEQ_REMOVE(&mp->childScnList, ms, elemChildScn);
-    elfu_mScnDestroy(ms);
+  if (!CIRCLEQ_EMPTY(&mp->childScnList)) {
+    ElfuScn *nextms;
+
+    nextms = CIRCLEQ_FIRST(&mp->childScnList);
+    while ((void*)nextms != (void*)&mp->childScnList) {
+      ElfuScn *curms = nextms;
+      nextms = CIRCLEQ_NEXT(curms, elemChildScn);
+      CIRCLEQ_REMOVE(&mp->childScnList, curms, elemChildScn);
+      elfu_mScnDestroy(curms);
+    }
   }
 
   free(mp);
index 74fbc3acb19ece9fc26932accb5a25b81cd8333e..d29b510928dbae0613fcf7b3ca504d1c205398f3 100644 (file)
@@ -11,8 +11,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;
@@ -248,7 +246,29 @@ void elfu_mScnDestroy(ElfuScn* ms)
 {
   assert(ms);
 
-  // TODO: Free symtab/reltab
+  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);
index ef7add9a17ab7fcbd6152437b6748f53c7038b48..a4f0384b1b2f6dfd44a0671af60755f0cf7a8640 100644 (file)
@@ -460,7 +460,9 @@ ElfuElf* elfu_mFromElf(Elf *e)
     }
   }
 
-
+  if (secArray) {
+    free(secArray);
+  }
   return me;
 
 
index 2fd610ce3b0808f6858854c0aca0666b3d5ac4d4..182ed2e4ec6d9e30339e13c4ceef0c854771a49d 100644 (file)
@@ -345,7 +345,6 @@ int elfu_mLayoutAuto(ElfuElf *me)
   ElfuPhdr *highestOffsEnd;
   ElfuPhdr *mp;
   ElfuScn *ms;
-  ElfuPhdr **phdrArr;
   GElf_Off lastend = 0;
 
   assert(me);
@@ -354,12 +353,6 @@ int elfu_mLayoutAuto(ElfuElf *me)
   elfu_mPhdrLoadLowestHighest(me, &lowestAddr, &highestAddr,
                               &lowestOffs, &highestOffsEnd);
 
-  phdrArr = malloc(elfu_mPhdrCount(me) * sizeof(*phdrArr));
-  if (!phdrArr) {
-    ELFU_WARN("elfu_mLayoutAuto: malloc failed for phdrArr.\n");
-    return 1;
-  }
-
 
   lastend = OFFS_END(highestOffsEnd->phdr.p_offset, highestOffsEnd->phdr.p_filesz);
 
index 1980c765aff0c3c1158439476e363fb4e2900d41..4bc6e40aef84fc0a1a0a9ddae29f4b4a3c4549f1 100644 (file)
@@ -130,7 +130,7 @@ static ElfuScn* insertSection(ElfuElf *me, ElfuElf *mrel, ElfuScn *oldscn)
 
   ERROR:
   if (newscn) {
-    // TODO: Destroy newscn
+    elfu_mScnDestroy(newscn);
   }
   return NULL;
 }