Relax restrictions on NOBITS sections
[centaur.git] / src / libelfu / modelops / fromFile.c
index 9671b5fc0f402858ef3f53bb58ffa5ef6637dae0..ef7add9a17ab7fcbd6152437b6748f53c7038b48 100644 (file)
@@ -252,9 +252,6 @@ static ElfuScn* modelFromSection(Elf_Scn *scn)
     data = elf_rawdata(scn, NULL);
     assert(data);
 
-    /* elf_rawdata() always returns ELF_T_BYTE */
-    assert(data->d_type == ELF_T_BYTE);
-
     while (data) {
       if (data->d_off + data->d_size > ms->shdr.sh_size) {
         ELFU_WARN("modelFromSection: libelf delivered a bogus data blob. Skipping\n");
@@ -280,7 +277,7 @@ static ElfuScn* modelFromSection(Elf_Scn *scn)
 
 ElfuElf* elfu_mFromElf(Elf *e)
 {
-  ElfuElf *me;
+  ElfuElf *me = NULL;
   size_t shstrndx;
   size_t i, numPhdr, numShdr;
   ElfuScn **secArray = NULL;
@@ -290,19 +287,11 @@ ElfuElf* elfu_mFromElf(Elf *e)
     goto ERROR;
   }
 
-  me = malloc(sizeof(ElfuElf));
+  me = elfu_mElfAlloc();
   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);
@@ -348,6 +337,8 @@ ElfuElf* elfu_mFromElf(Elf *e)
 
         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)) {
+          /* Remove from the main list so only LOADs remain there */
+          CIRCLEQ_REMOVE(&me->phdrList, mp2, elem);
           CIRCLEQ_INSERT_TAIL(&mp->childPhdrList, mp2, elemChildPhdr);
         }
       }
@@ -454,7 +445,12 @@ ElfuElf* elfu_mFromElf(Elf *e)
         if (ms->shdr.sh_addr == 0) {
           ms->shdr.sh_addr = shaddr;
         } else {
-          assert(ms->shdr.sh_addr == shaddr);
+          if (ms->shdr.sh_type != SHT_NOBITS) {
+            assert(ms->shdr.sh_addr == shaddr);
+          } else if (ms->shdr.sh_addr > shaddr) {
+            parent->phdr.p_filesz = MAX(parent->phdr.p_filesz,
+                                        ms->shdr.sh_addr - parent->phdr.p_vaddr);
+          }
         }
 
         CIRCLEQ_INSERT_TAIL(&parent->childScnList, ms, elemChildScn);
@@ -473,7 +469,7 @@ ElfuElf* elfu_mFromElf(Elf *e)
     free(secArray);
   }
   if (me) {
-    // TODO: Free data structures
+    elfu_mElfDestroy(me);
   }
 
   ELFU_WARN("elfu_mFromElf: Failed to load file.\n");