0fd5a2d0ad752ec8af635123a301d4b8c532419a
[centaur.git] / src / elfucli.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <getopt.h>
4 #include <libelfu/libelfu.h>
5
6 #include "elfhandle.h"
7
8
9
10 static void printUsage(char *progname)
11 {
12   printf("Usage: %s -i <inputfile> [OPTIONS]\n", progname);
13   printf("\n"
14          "Options, executed in order given:\n"
15          "  -h, --help                     Print this help message\n"
16          "\n"
17          "  -i, --input         infile     Load new ELF file (must be first command)\n"
18          "\n"
19          "  -c, --check                    Do a few sanity checks and print any errors\n"
20          "  -d, --dump                     Dump current model state (debug only)\n"
21          "      --reladd        obj.o      Insert object file contents\n"
22          "  -o, --output        outfile    Where to write the modified ELF file to\n"
23          "\n");
24 }
25
26
27
28
29 int main(int argc, char **argv)
30 {
31   ELFHandles hIn = { 0 };
32   int exitval = EXIT_SUCCESS;
33   char *progname = argv[0];
34   int c;
35   int option_index = 0;
36   ElfuElf *me = NULL;
37
38   static struct option long_options[] = {
39     {"help", 0, 0, 'h'},
40     {"check", 0, 0, 'c'},
41     {"dump", 0, 0, 'd'},
42     {"input", 1, 0, 'i'},
43     {"output", 1, 0, 'o'},
44     {"reladd", 1, 0, 10001},
45     {NULL, 0, NULL, 0}
46   };
47
48
49   if (argc < 3) {
50     printUsage(progname);
51     goto EXIT;
52   }
53
54
55   /* Is libelf alive and well? */
56   if (elf_version(EV_CURRENT) == EV_NONE) {
57     fprintf(stderr, "libelf init error: %s\n", elf_errmsg(-1));
58   }
59
60
61   /* Parse and and execute user commands */
62   while ((c = getopt_long(argc, argv, "hcdi:o:",
63                           long_options, &option_index)) != -1) {
64     switch (c) {
65       case 'h':
66         printUsage(progname);
67         goto EXIT;
68       case 'c':
69         if (!me) {
70           goto ERR_NO_INPUT;
71         } else {
72           printf("Checking model validity...\n");
73           elfu_mCheck(me);
74         }
75         break;
76       case 'd':
77         if (!me) {
78           goto ERR_NO_INPUT;
79         } else {
80           elfu_mDumpElf(me);
81         }
82         break;
83       case 'i':
84         printf("Opening input file %s.\n", optarg);
85         openElf(&hIn, optarg, ELF_C_READ);
86         if (!hIn.e) {
87           printf("Error: Failed to open input file. Aborting.\n");
88           exitval = EXIT_FAILURE;
89           goto EXIT;
90         }
91
92         me = elfu_mFromElf(hIn.e);
93         closeElf(&hIn);
94
95         if (!me) {
96           printf("Error: Failed to load model, aborting.\n");
97           goto EXIT;
98         }
99         break;
100       case 'o':
101         if (!me) {
102           goto ERR_NO_INPUT;
103         } else {
104           ELFHandles hOut = { 0 };
105
106           printf("Writing modified file to %s.\n", optarg);
107
108           openElf(&hOut, optarg, ELF_C_WRITE);
109           if (!hOut.e) {
110             printf("Failed to open output file. Aborting.\n");
111             closeElf(&hOut);
112             exitval = EXIT_FAILURE;
113             goto EXIT;
114           }
115
116           elfu_mToElf(me, hOut.e);
117
118           if (elf_update(hOut.e, ELF_C_WRITE) < 0) {
119             fprintf(stderr, "elf_update() failed: %s\n", elf_errmsg(-1));
120           }
121           closeElf(&hOut);
122         }
123         break;
124       case 10001:
125         if (!me) {
126           goto ERR_NO_INPUT;
127         } else {
128           ELFHandles hRel = { 0 };
129           ElfuElf *mrel = NULL;
130
131           openElf(&hRel, optarg, ELF_C_READ);
132           if (!hRel.e) {
133             printf("--reladd: Failed to open file for --reladd, aborting.\n");
134             closeElf(&hRel);
135             goto ERR;
136           }
137
138           mrel = elfu_mFromElf(hRel.e);
139           closeElf(&hRel);
140           if (!mrel) {
141             printf("--reladd: Failed to load model for --reladd, aborting.\n");
142             goto ERR;
143           } else {
144             printf("--reladd: Injecting %s...\n", optarg);
145             elfu_mCheck(mrel);
146             elfu_mReladd(me, mrel);
147             printf("--reladd: Injected %s.\n", optarg);
148           }
149         }
150         break;
151       case '?':
152       default:
153         printUsage(progname);
154         goto EXIT;
155     }
156   }
157
158   while (optind < argc) {
159     optind++;
160   }
161
162
163
164 EXIT:
165   if (hIn.e) {
166     closeElf(&hIn);
167   }
168
169   return (exitval);
170
171
172 ERR_NO_INPUT:
173   printf("Error: No input file opened. Aborting.\n");
174
175 ERR:
176   exitval = EXIT_FAILURE;
177   goto EXIT;
178 }