Model to ELF (writing) support
authornorly <ny-git@enpas.org>
Sun, 10 Feb 2013 18:39:15 +0000 (18:39 +0000)
committernorly <ny-git@enpas.org>
Sun, 10 Feb 2013 18:40:44 +0000 (18:40 +0000)
include/libelfu/model.h
src/main.c
src/model/toFile.c [new file with mode: 0644]

index 05f31ca6761aab1227af9891e027f63171b13da7..aaf754f06a4c6b288ac98609f421443afa7fb8ce 100644 (file)
@@ -47,4 +47,6 @@ ElfuPhdr* elfu_modelFromPhdr(GElf_Phdr *phdr);
 ElfuScn* elfu_modelFromSection(Elf_Scn *scn);
 ElfuElf* elfu_modelFromElf(Elf *e);
 
+void elfu_modelToElf(ElfuElf *me, Elf *e);
+
 #endif
index fc166548e8d7ff44dc856df0a1d61c1f9536aedc..850e49d3bea68e0d3f7590e7815519b7666d5b06 100644 (file)
@@ -77,6 +77,12 @@ int main(int argc, char **argv)
 
     if (me) {
       printf("Model successfully loaded.\n");
+
+      elfu_modelToElf(me, hOut.e);
+
+      printf("Model converted to ELF, ready to be written.\n");
+    } else {
+      printf("Failed to load model.\n");
     }
   }
 
diff --git a/src/model/toFile.c b/src/model/toFile.c
new file mode 100644 (file)
index 0000000..294cfe4
--- /dev/null
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libelf.h>
+#include <gelf.h>
+
+#include <libelfu/libelfu.h>
+
+
+
+static void elfu_modelToPhdrs(ElfuElf *me, Elf *e)
+{
+  ElfuPhdr *mp;
+  size_t i;
+
+  /* Count PHDRs */
+  i = 0;
+  for (mp = me->phdrList.cqh_first;
+        mp != (void *)&me->phdrList;
+        mp = mp->elem.cqe_next) {
+    i++;
+  }
+
+  if (!gelf_newphdr(e, i)) {
+    fprintf(stderr, "gelf_newphdr() failed: %s\n", elf_errmsg(-1));
+  }
+
+  /* Copy PHDRs */
+  i = 0;
+  for (mp = me->phdrList.cqh_first;
+        mp != (void *)&me->phdrList;
+        mp = mp->elem.cqe_next) {
+    if (!gelf_update_phdr (e, i, &mp->phdr)) {
+      fprintf(stderr, "gelf_update_phdr() failed: %s\n", elf_errmsg(-1));
+    }
+
+    i++;
+  }
+}
+
+
+
+static void elfu_modelToSection(ElfuScn *ms, Elf *e)
+{
+  Elf_Scn *scnOut;
+
+  scnOut = elf_newscn(e);
+  if (!scnOut) {
+    fprintf(stderr, "elf_newscn() failed: %s\n", elf_errmsg(-1));
+    return;
+  }
+
+
+  /* SHDR */
+  if (!gelf_update_shdr(scnOut, &ms->shdr)) {
+    fprintf(stderr, "gelf_update_shdr() failed: %s\n", elf_errmsg(-1));
+  }
+
+
+  /* Data */
+  ElfuData *md;
+  for (md = ms->dataList.cqh_first;
+        md != (void *)&ms->dataList;
+        md = md->elem.cqe_next) {
+    Elf_Data *dataOut = elf_newdata(scnOut);
+    if (!dataOut) {
+      fprintf(stderr, "elf_newdata() failed: %s\n", elf_errmsg(-1));
+    }
+
+    dataOut->d_align = md->data.d_align;
+    dataOut->d_buf  = md->data.d_buf;
+    dataOut->d_off  = md->data.d_off;
+    dataOut->d_type = md->data.d_type;
+    dataOut->d_size = md->data.d_size;
+    dataOut->d_version = md->data.d_version;
+  }
+}
+
+
+
+
+
+void elfu_modelToElf(ElfuElf *me, Elf *e)
+{
+  ElfuScn *ms;
+
+  /* We control the ELF file's layout now. */
+  /* tired's libelf also offers ELF_F_LAYOUT_OVERLAP for overlapping sections. */
+  elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT);
+
+
+  /* EHDR */
+  if (!gelf_newehdr(e, me->elfclass)) {
+    fprintf(stderr, "gelf_newehdr() failed: %s\n", elf_errmsg(-1));
+  }
+
+  if (!gelf_update_ehdr(e, &me->ehdr)) {
+    fprintf(stderr, "gelf_update_ehdr() failed: %s\n", elf_errmsg(-1));
+  }
+
+
+  /* Sections */
+  for (ms = me->scnList.cqh_first;
+        ms != (void *)&me->scnList;
+        ms = ms->elem.cqe_next) {
+    elfu_modelToSection(ms, e);
+  }
+
+
+  /* PHDRs */
+  elfu_modelToPhdrs(me, e);
+
+
+  elf_flagelf(e, ELF_C_SET, ELF_F_DIRTY);
+}