mv main.c -> elfucli.c, make it scriptable via args symrel
authornorly <ny-git@enpas.org>
Sat, 15 Jun 2013 23:47:23 +0000 (00:47 +0100)
committernorly <ny-git@enpas.org>
Sat, 15 Jun 2013 23:51:22 +0000 (00:51 +0100)
include/options.h [deleted file]
include/printing.h [deleted file]
src/elfucli.c [new file with mode: 0644]
src/main.c [deleted file]
src/options.c [deleted file]

diff --git a/include/options.h b/include/options.h
deleted file mode 100644 (file)
index 2210c85..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef __OPTIONS_H__
-#define __OPTIONS_H__
-
-
-typedef struct {
-  char *fnInput;
-  char *fnOutput;
-  int printHeader;
-  int printSegments;
-  int printSections;
-  unsigned insertBeforeOffs;
-  unsigned insertBeforeSz;
-  unsigned insertAfterOffs;
-  unsigned insertAfterSz;
-  unsigned expandNobitsOffs;
-  char *fnReladd;
-} CLIOpts;
-
-
-void parseOptions(CLIOpts *opts, int argc, char **argv);
-
-#endif
diff --git a/include/printing.h b/include/printing.h
deleted file mode 100644 (file)
index bda2fc1..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __PRINTING_H__
-#define __PRINTING_H__
-
-#include <libelf.h>
-
-
-void printHeader(Elf *e);
-
-void printSegmentsWithSection(Elf *e, Elf_Scn *scn);
-void printSection(Elf *e, Elf_Scn *scn);
-void printSections(Elf *e);
-
-char* segmentTypeStr(size_t pt);
-void printSectionsInSegment(Elf *e, GElf_Phdr *phdr);
-void printSegments(Elf *e);
-
-
-#endif
diff --git a/src/elfucli.c b/src/elfucli.c
new file mode 100644 (file)
index 0000000..0fd5a2d
--- /dev/null
@@ -0,0 +1,178 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <libelfu/libelfu.h>
+
+#include "elfhandle.h"
+
+
+
+static void printUsage(char *progname)
+{
+  printf("Usage: %s -i <inputfile> [OPTIONS]\n", progname);
+  printf("\n"
+         "Options, executed in order given:\n"
+         "  -h, --help                     Print this help message\n"
+         "\n"
+         "  -i, --input         infile     Load new ELF file (must be first command)\n"
+         "\n"
+         "  -c, --check                    Do a few sanity checks and print any errors\n"
+         "  -d, --dump                     Dump current model state (debug only)\n"
+         "      --reladd        obj.o      Insert object file contents\n"
+         "  -o, --output        outfile    Where to write the modified ELF file to\n"
+         "\n");
+}
+
+
+
+
+int main(int argc, char **argv)
+{
+  ELFHandles hIn = { 0 };
+  int exitval = EXIT_SUCCESS;
+  char *progname = argv[0];
+  int c;
+  int option_index = 0;
+  ElfuElf *me = NULL;
+
+  static struct option long_options[] = {
+    {"help", 0, 0, 'h'},
+    {"check", 0, 0, 'c'},
+    {"dump", 0, 0, 'd'},
+    {"input", 1, 0, 'i'},
+    {"output", 1, 0, 'o'},
+    {"reladd", 1, 0, 10001},
+    {NULL, 0, NULL, 0}
+  };
+
+
+  if (argc < 3) {
+    printUsage(progname);
+    goto EXIT;
+  }
+
+
+  /* Is libelf alive and well? */
+  if (elf_version(EV_CURRENT) == EV_NONE) {
+    fprintf(stderr, "libelf init error: %s\n", elf_errmsg(-1));
+  }
+
+
+  /* Parse and and execute user commands */
+  while ((c = getopt_long(argc, argv, "hcdi:o:",
+                          long_options, &option_index)) != -1) {
+    switch (c) {
+      case 'h':
+        printUsage(progname);
+        goto EXIT;
+      case 'c':
+        if (!me) {
+          goto ERR_NO_INPUT;
+        } else {
+          printf("Checking model validity...\n");
+          elfu_mCheck(me);
+        }
+        break;
+      case 'd':
+        if (!me) {
+          goto ERR_NO_INPUT;
+        } else {
+          elfu_mDumpElf(me);
+        }
+        break;
+      case 'i':
+        printf("Opening input file %s.\n", optarg);
+        openElf(&hIn, optarg, ELF_C_READ);
+        if (!hIn.e) {
+          printf("Error: Failed to open input file. Aborting.\n");
+          exitval = EXIT_FAILURE;
+          goto EXIT;
+        }
+
+        me = elfu_mFromElf(hIn.e);
+        closeElf(&hIn);
+
+        if (!me) {
+          printf("Error: Failed to load model, aborting.\n");
+          goto EXIT;
+        }
+        break;
+      case 'o':
+        if (!me) {
+          goto ERR_NO_INPUT;
+        } else {
+          ELFHandles hOut = { 0 };
+
+          printf("Writing modified file to %s.\n", optarg);
+
+          openElf(&hOut, optarg, ELF_C_WRITE);
+          if (!hOut.e) {
+            printf("Failed to open output file. Aborting.\n");
+            closeElf(&hOut);
+            exitval = EXIT_FAILURE;
+            goto EXIT;
+          }
+
+          elfu_mToElf(me, hOut.e);
+
+          if (elf_update(hOut.e, ELF_C_WRITE) < 0) {
+            fprintf(stderr, "elf_update() failed: %s\n", elf_errmsg(-1));
+          }
+          closeElf(&hOut);
+        }
+        break;
+      case 10001:
+        if (!me) {
+          goto ERR_NO_INPUT;
+        } else {
+          ELFHandles hRel = { 0 };
+          ElfuElf *mrel = NULL;
+
+          openElf(&hRel, optarg, ELF_C_READ);
+          if (!hRel.e) {
+            printf("--reladd: Failed to open file for --reladd, aborting.\n");
+            closeElf(&hRel);
+            goto ERR;
+          }
+
+          mrel = elfu_mFromElf(hRel.e);
+          closeElf(&hRel);
+          if (!mrel) {
+            printf("--reladd: Failed to load model for --reladd, aborting.\n");
+            goto ERR;
+          } else {
+            printf("--reladd: Injecting %s...\n", optarg);
+            elfu_mCheck(mrel);
+            elfu_mReladd(me, mrel);
+            printf("--reladd: Injected %s.\n", optarg);
+          }
+        }
+        break;
+      case '?':
+      default:
+        printUsage(progname);
+        goto EXIT;
+    }
+  }
+
+  while (optind < argc) {
+    optind++;
+  }
+
+
+
+EXIT:
+  if (hIn.e) {
+    closeElf(&hIn);
+  }
+
+  return (exitval);
+
+
+ERR_NO_INPUT:
+  printf("Error: No input file opened. Aborting.\n");
+
+ERR:
+  exitval = EXIT_FAILURE;
+  goto EXIT;
+}
diff --git a/src/main.c b/src/main.c
deleted file mode 100644 (file)
index eda76e5..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <libelfu/libelfu.h>
-
-#include "elfhandle.h"
-#include "options.h"
-#include "printing.h"
-
-
-int main(int argc, char **argv)
-{
-  CLIOpts opts = { 0 };
-  ELFHandles hIn = { 0 };
-  ELFHandles hOut = { 0 };
-  int exitval = EXIT_SUCCESS;
-  ElfuElf *me;
-
-  /* Is libelf alive and well? */
-  if (elf_version(EV_CURRENT) == EV_NONE) {
-    fprintf(stderr, "libelf init error: %s\n", elf_errmsg(-1));
-  }
-
-
-  /* Parse and validate user input */
-  parseOptions(&opts, argc, argv);
-
-
-  /* Open input/output files */
-  openElf(&hIn, opts.fnInput, ELF_C_READ);
-  if (!hIn.e) {
-    exitval = EXIT_FAILURE;
-    goto EXIT;
-  }
-
-  /* Now that we have a (hopefully) sane environment, execute commands. */
-  me = elfu_mFromElf(hIn.e);
-  closeElf(&hIn);
-  if (!me) {
-    printf("Failed to load model, aborting.\n");
-    goto EXIT;
-  }
-
-  elfu_mCheck(me);
-
-  //elfu_mDumpElf(me);
-
-  /* Perform requested transformations on the memory model on-the-fly. */
-  if (opts.fnReladd) {
-    ELFHandles hRel = { 0 };
-    ElfuElf *mrel = NULL;
-
-    openElf(&hRel, opts.fnReladd, ELF_C_READ);
-    if (!hRel.e) {
-      printf("--reladd: Failed to open file for --reladd, skipping operation.\n");
-    } else {
-      mrel = elfu_mFromElf(hRel.e);
-      closeElf(&hRel);
-      if (!mrel) {
-        printf("--reladd: Failed to load model for --reladd, skipping operation.\n");
-      } else {
-        elfu_mCheck(mrel);
-        elfu_mReladd(me, mrel);
-        printf("--reladd: Injected %s.\n", opts.fnReladd);
-      }
-    }
-  }
-
-  //elfu_mDumpElf(me);
-
-  /* Copy the input ELF to the output file if one is specified. */
-  if (opts.fnOutput) {
-    printf("Writing modified file to %s.\n", opts.fnOutput);
-    elfu_mCheck(me);
-
-
-    openElf(&hOut, opts.fnOutput, ELF_C_WRITE);
-    if (!hOut.e) {
-      printf("Failed to open output file. Aborting.\n");
-      exitval = EXIT_FAILURE;
-      goto EXIT;
-    }
-
-    elfu_mToElf(me, hOut.e);
-
-    if (elf_update(hOut.e, ELF_C_WRITE) < 0) {
-      fprintf(stderr, "elf_update() failed: %s\n", elf_errmsg(-1));
-    }
-    closeElf(&hOut);
-  }
-
-
-
-EXIT:
-  if (hIn.e) {
-    closeElf(&hIn);
-  }
-
-  return (exitval);
-}
diff --git a/src/options.c b/src/options.c
deleted file mode 100644 (file)
index b5018d3..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include "options.h"
-
-
-static void printUsage(char *progname)
-{
-  printf("Usage: %s [OPTIONS] <elf-file>\n", progname);
-  printf("\n"
-          "Options:\n"
-          "  -h, --help                     Print this help message\n"
-          "  -o, --output                   Where to write the modified ELF file to\n"
-          "\n"
-//          "ELF dump:\n"
-//          "      --print-header             Print ELF header\n"
-//          "      --print-segments           Print program headers\n"
-//          "      --print-sections           Print sections\n"
-//          "\n"
-//          "Space insertion:\n"
-//          "    off: File offset, not within any structure (headers or sections).\n"
-//          "    sz:  A multiple of the maximum alignment of all PHDRs.\n"
-//          "\n"
-//          "      --expand-nobits off        Expand virtual areas (NOBITS sections and similar PHDRs).\n"
-//          "      --insert-before off,sz     Insert spacing at given offset,\n"
-//          "                                 mapping everything before it to lower mem addresses.\n"
-//          "      --insert-after  off,sz     Insert spacing at given offset,\n"
-//          "                                 mapping everything after it to higher mem addresses.\n"
-//          "\n"
-          "High-level insertion:\n"
-          "      --reladd        obj.o      Automatically insert object file contents\n"
-          "\n");
-}
-
-
-
-void parseOptions(CLIOpts *opts, int argc, char **argv)
-{
-  char *progname = argv[0];
-  int c;
-  int option_index = 0;
-  char *endptr;
-
-  static struct option long_options[] = {
-    {"help", 0, 0, 'h'},
-    {"output", 1, 0, 'o'},
-    {"print-header", 0, 0, 10001},
-    {"print-segments", 0, 0, 10002},
-    {"print-sections", 0, 0, 10003},
-    {"insert-before", 1, 0, 10004},
-    {"insert-after", 1, 0, 10005},
-    {"expand-nobits", 1, 0, 10006},
-    {"reladd", 1, 0, 10007},
-    {NULL, 0, NULL, 0}
-  };
-
-  while ((c = getopt_long(argc, argv, "e:ho:",
-                          long_options, &option_index)) != -1) {
-    switch (c) {
-      case 'h':
-        printUsage(progname);
-        exit(EXIT_SUCCESS);
-      case 'o':
-        opts->fnOutput = optarg;
-        break;
-      case 10001:
-        opts->printHeader = 1;
-        break;
-      case 10002:
-        opts->printSegments = 1;
-        break;
-      case 10003:
-        opts->printSections = 1;
-        break;
-      case 10004:
-        opts->insertBeforeOffs = strtoul(optarg, &endptr, 0);
-        if (endptr[0] != ',') {
-          goto USAGE;
-        }
-        opts->insertBeforeSz = strtoul(endptr + 1, &endptr, 0);
-        if (endptr[0] != '\0' || opts->insertBeforeSz == 0) {
-          goto USAGE;
-        }
-        break;
-      case 10005:
-        opts->insertAfterOffs = strtoul(optarg, &endptr, 0);
-        if (endptr[0] != ',') {
-          goto USAGE;
-        }
-        opts->insertAfterSz = strtoul(endptr + 1, &endptr, 0);
-        if (endptr[0] != '\0' || opts->insertAfterSz == 0) {
-          goto USAGE;
-        }
-        break;
-      case 10006:
-        opts->expandNobitsOffs = strtoul(optarg, &endptr, 0);
-        if (endptr[0] != '\0' || opts->expandNobitsOffs < 1) {
-          goto USAGE;
-        }
-        break;
-      case 10007:
-        opts->fnReladd = optarg;
-        break;
-      case '?':
-      default:
-        goto USAGE;
-    }
-  }
-
-  while (optind < argc) {
-    if (!opts->fnInput) {
-      opts->fnInput = argv[optind];
-    }
-    optind++;
-  }
-
-  if (!opts->fnInput) {
-    fprintf(stderr, "Error: No input file specified.\n\n");
-    goto USAGE;
-  }
-
-  return;
-
-USAGE:
-  printUsage(progname);
-  exit(1);
-}