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

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 ddd44be0c73f7b0f3c297c548aa208b5fb3f8a84..c43c811a5ae0e5c61d754735a93bc731f7cdc490 100644 (file)
@@ -8,7 +8,7 @@ typedef struct {
   int printHeader;
   int printSegments;
   int printSections;
-  int model;
+  int copy;
 } CLIOpts;
 
 
index 87b47efc4ebe92b49c9db535ef627b711878676a..bd6d294c021bb61f87b4287ecaab178fe5ec661d 100644 (file)
@@ -59,14 +59,26 @@ int main(int argc, char **argv)
   }
 
 
-  /* Generate a memory model of the file */
-  if (opts.model) {
-    ElfuElf *me;
+  /* Copy the input ELF to the output file */
+  if (!opts.fnOutput) {
+    if (opts.copy) {
+      fprintf(stderr, "Error: Missing output file name for requested operation.\n");
+    }
+  } else {
+    if (opts.copy) {
+      ElfuElf *me;
+
+      me = elfu_modelFromElf(hIn.e);
+
+      if (me) {
+        printf("Model successfully loaded.\n");
 
-    me = elfu_modelFromElf(hIn.e);
+        elfu_modelToElf(me, hOut.e);
 
-    if (me) {
-      printf("Model successfully loaded.\n");
+        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);
+}
index 42637f04c1940961ea00c22bd91e27f5edd402f7..3975bada10e3d12215d3b63974fe2b72f524da74 100644 (file)
@@ -17,6 +17,8 @@ static void printUsage(char *progname)
           "      --print-header         Print ELF header\n"
           "      --print-segments       Print program headers\n"
           "      --print-sections       Print sections\n"
+          "\n"
+          "      --copy                 Copy input to output\n"
           "\n");
 }
 
@@ -34,7 +36,7 @@ void parseOptions(CLIOpts *opts, int argc, char **argv)
     {"print-header", 0, 0, 10001},
     {"print-segments", 0, 0, 10002},
     {"print-sections", 0, 0, 10003},
-    {"model", 0, 0, 10004},
+    {"copy", 0, 0, 10004},
     {NULL, 0, NULL, 0}
   };
 
@@ -57,7 +59,7 @@ void parseOptions(CLIOpts *opts, int argc, char **argv)
         opts->printSections = 1;
         break;
       case 10004:
-        opts->model = 1;
+        opts->copy = 1;
         break;
       case '?':
       default: