blob: 43b3a00e0df270d22adec0213fdd26b25a533fc8 [file] [log] [blame]
Patrick Georgiea063cb2020-05-08 19:28:13 +02001/* bincfg - Compiler/Decompiler for data blobs with specs */
Patrick Georgi7333a112020-05-08 20:48:04 +02002/* SPDX-License-Identifier: GPL-3.0-or-later */
Damien Zammit06853222016-11-16 21:06:54 +11003
4%{
5#include <stdio.h>
6#include <inttypes.h>
7#include <stdlib.h>
8#include <string.h>
Denis 'GNUtoo' Cariklifa0bdfc2018-01-12 04:04:30 +01009#include "bincfg.h"
Damien Zammit06853222016-11-16 21:06:54 +110010//#define YYDEBUG 1
Damien Zammit06853222016-11-16 21:06:54 +110011
Martin Roth63381892017-04-09 13:30:17 -060012static void check_pointer (void *ptr)
13{
14 if (ptr == NULL) {
15 printf("Error: Out of memory\n");
16 exit(1);
17 }
18}
19
20static unsigned char* value_to_bits (unsigned int v, unsigned int w)
Damien Zammit06853222016-11-16 21:06:54 +110021{
22 unsigned int i;
23 unsigned char* bitarr;
24
25 if (w > MAX_WIDTH) w = MAX_WIDTH;
26 bitarr = (unsigned char *) malloc (w * sizeof (unsigned char));
Martin Roth63381892017-04-09 13:30:17 -060027 check_pointer(bitarr);
Damien Zammit06853222016-11-16 21:06:54 +110028 memset (bitarr, 0, w);
29
30 for (i = 0; i < w; i++) {
31 bitarr[i] = VALID_BIT | ((v & (1 << i)) >> i);
32 }
33 return bitarr;
34}
35
36/* Store each bit of a bitfield in a new byte sequentially 0x80 or 0x81 */
Martin Roth63381892017-04-09 13:30:17 -060037static void append_field_to_blob (unsigned char b[], unsigned int w)
Damien Zammit06853222016-11-16 21:06:54 +110038{
39 unsigned int i, j;
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +010040 binary->blb = (unsigned char *) realloc (binary->blb,
41 binary->bloblen + w);
Martin Roth63381892017-04-09 13:30:17 -060042 check_pointer(binary->blb);
Damien Zammit06853222016-11-16 21:06:54 +110043 for (j = 0, i = binary->bloblen; i < binary->bloblen + w; i++, j++) {
44 binary->blb[i] = VALID_BIT | (b[j] & 1);
45 //fprintf (stderr, "blob[%d] = %d\n", i, binary->blb[i] & 1);
46 }
47 binary->bloblen += w;
48}
49
Angel Pons175778f2019-01-26 10:09:13 +000050static void set_bitfield(char *name, unsigned int value)
Damien Zammit06853222016-11-16 21:06:54 +110051{
52 unsigned long long i;
Angel Pons175778f2019-01-26 10:09:13 +000053 struct field *bf = getsym (name);
Damien Zammit06853222016-11-16 21:06:54 +110054 if (bf) {
55 bf->value = value & 0xffffffff;
56 i = (1 << bf->width) - 1;
57 if (bf->width > 8 * sizeof (unsigned int)) {
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +010058 fprintf(stderr,
59 "Overflow in bitfield, truncating bits to"
60 " fit\n");
Damien Zammit06853222016-11-16 21:06:54 +110061 bf->value = value & i;
62 }
63 //fprintf(stderr, "Setting `%s` = %d\n", bf->name, bf->value);
64 } else {
65 fprintf(stderr, "Can't find bitfield `%s` in spec\n", name);
66 }
67}
68
Angel Pons175778f2019-01-26 10:09:13 +000069static void set_bitfield_array(char *name, unsigned int n, unsigned int value)
Damien Zammit06853222016-11-16 21:06:54 +110070{
71 unsigned int i;
Martin Roth63381892017-04-09 13:30:17 -060072 unsigned long len = strlen (name);
Damien Zammit06853222016-11-16 21:06:54 +110073 char *namen = (char *) malloc ((len + 9) * sizeof (char));
Martin Roth63381892017-04-09 13:30:17 -060074 check_pointer(namen);
Damien Zammit06853222016-11-16 21:06:54 +110075 for (i = 0; i < n; i++) {
76 snprintf (namen, len + 8, "%s%x", name, i);
Angel Pons175778f2019-01-26 10:09:13 +000077 set_bitfield (namen, value);
Damien Zammit06853222016-11-16 21:06:54 +110078 }
79 free(namen);
80}
81
Angel Pons175778f2019-01-26 10:09:13 +000082static void create_new_bitfield(char *name, unsigned int width)
Damien Zammit06853222016-11-16 21:06:54 +110083{
84 struct field *bf;
85
Angel Pons175778f2019-01-26 10:09:13 +000086 if (!(bf = putsym (name, width))) return;
Damien Zammit06853222016-11-16 21:06:54 +110087 //fprintf(stderr, "Added bitfield `%s` : %d\n", bf->name, width);
88}
89
Angel Pons175778f2019-01-26 10:09:13 +000090static void create_new_bitfields(char *name, unsigned int n, unsigned int width)
Damien Zammit06853222016-11-16 21:06:54 +110091{
92 unsigned int i;
Martin Roth63381892017-04-09 13:30:17 -060093 unsigned long len = strlen (name);
Damien Zammit06853222016-11-16 21:06:54 +110094 char *namen = (char *) malloc ((len + 9) * sizeof (char));
Martin Roth63381892017-04-09 13:30:17 -060095 check_pointer(namen);
Damien Zammit06853222016-11-16 21:06:54 +110096 for (i = 0; i < n; i++) {
97 snprintf (namen, len + 8, "%s%x", name, i);
Angel Pons175778f2019-01-26 10:09:13 +000098 create_new_bitfield (namen, width);
Damien Zammit06853222016-11-16 21:06:54 +110099 }
100 free(namen);
101}
102
Angel Pons175778f2019-01-26 10:09:13 +0000103static struct field *putsym (char const *sym_name, unsigned int w)
Damien Zammit06853222016-11-16 21:06:54 +1100104{
Angel Pons175778f2019-01-26 10:09:13 +0000105 if (getsym(sym_name)) {
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +0100106 fprintf(stderr, "Cannot add duplicate named bitfield `%s`\n",
107 sym_name);
Damien Zammit06853222016-11-16 21:06:54 +1100108 return 0;
109 }
Angel Pons175778f2019-01-26 10:09:13 +0000110 struct field *ptr = (struct field *) malloc (sizeof (struct field));
Martin Roth63381892017-04-09 13:30:17 -0600111 check_pointer(ptr);
Damien Zammit06853222016-11-16 21:06:54 +1100112 ptr->name = (char *) malloc (strlen (sym_name) + 1);
Martin Roth63381892017-04-09 13:30:17 -0600113 check_pointer(ptr->name);
Damien Zammit06853222016-11-16 21:06:54 +1100114 strcpy (ptr->name, sym_name);
115 ptr->width = w;
116 ptr->value = 0;
Angel Pons175778f2019-01-26 10:09:13 +0000117 ptr->next = (struct field *)0;
Damien Zammit06853222016-11-16 21:06:54 +1100118 if (sym_table_tail) {
119 sym_table_tail->next = ptr;
120 } else {
Angel Pons175778f2019-01-26 10:09:13 +0000121 sym_table = ptr;
Damien Zammit06853222016-11-16 21:06:54 +1100122 }
123 sym_table_tail = ptr;
124 return ptr;
125}
126
Angel Pons175778f2019-01-26 10:09:13 +0000127static struct field *getsym (char const *sym_name)
Damien Zammit06853222016-11-16 21:06:54 +1100128{
129 struct field *ptr;
130 for (ptr = sym_table; ptr != (struct field *) 0;
131 ptr = (struct field *)ptr->next) {
132 if (strcmp (ptr->name, sym_name) == 0)
133 return ptr;
134 }
135 return 0;
136}
137
Angel Pons175778f2019-01-26 10:09:13 +0000138static void dump_all_values (void)
Damien Zammit06853222016-11-16 21:06:54 +1100139{
140 struct field *ptr;
141 for (ptr = sym_table; ptr != (struct field *) 0;
142 ptr = (struct field *)ptr->next) {
143 fprintf(stderr, "%s = %d (%d bits)\n",
144 ptr->name,
145 ptr->value,
146 ptr->width);
147 }
148}
149
Angel Pons175778f2019-01-26 10:09:13 +0000150static void empty_field_table(void)
Damien Zammit06853222016-11-16 21:06:54 +1100151{
152 struct field *ptr;
153 struct field *ptrnext;
154
155 for (ptr = sym_table; ptr != (struct field *) 0; ptr = ptrnext) {
156 if (ptr) {
157 ptrnext = ptr->next;
158 free(ptr);
159 } else {
160 ptrnext = (struct field *) 0;
161 }
162 }
163 sym_table = 0;
164 sym_table_tail = 0;
165}
166
Martin Roth63381892017-04-09 13:30:17 -0600167static void create_binary_blob (void)
Damien Zammit06853222016-11-16 21:06:54 +1100168{
169 if (binary && binary->blb) {
170 free(binary->blb);
171 free(binary);
172 }
173 binary = (struct blob *) malloc (sizeof (struct blob));
Martin Roth63381892017-04-09 13:30:17 -0600174 check_pointer(binary);
Damien Zammit06853222016-11-16 21:06:54 +1100175 binary->blb = (unsigned char *) malloc (sizeof (unsigned char));
Martin Roth63381892017-04-09 13:30:17 -0600176 check_pointer(binary->blb);
Damien Zammit06853222016-11-16 21:06:54 +1100177 binary->bloblen = 0;
178 binary->blb[0] = VALID_BIT;
179}
180
Martin Roth63381892017-04-09 13:30:17 -0600181static void interpret_next_blob_value (struct field *f)
Damien Zammit06853222016-11-16 21:06:54 +1100182{
Martin Roth63381892017-04-09 13:30:17 -0600183 unsigned int i;
Damien Zammit06853222016-11-16 21:06:54 +1100184 unsigned int v = 0;
185
186 if (binary->bloblen >= binary->lenactualblob * 8) {
187 f->value = 0;
188 return;
189 }
190
191 for (i = 0; i < f->width; i++) {
192 v |= (binary->blb[binary->bloblen++] & 1) << i;
193 }
194
195 f->value = v;
196}
197
198/* {}%BIN -> {} */
Angel Pons175778f2019-01-26 10:09:13 +0000199static void generate_setter_bitfields(FILE* fp, unsigned char *bin)
Damien Zammit06853222016-11-16 21:06:54 +1100200{
201 unsigned int i;
202 struct field *ptr;
203
204 /* Convert bytes to bit array */
205 for (i = 0; i < binary->lenactualblob; i++) {
206 append_field_to_blob (value_to_bits(bin[i], 8), 8);
207 }
208
209 /* Reset blob position to zero */
210 binary->bloblen = 0;
211
Denis 'GNUtoo' Carikli780e9312018-01-10 14:35:55 +0100212 fprintf (fp, "# AUTOGENERATED SETTER BY BINCFG\n{\n");
Damien Zammit06853222016-11-16 21:06:54 +1100213
214 /* Traverse spec and output bitfield setters based on blob values */
215 for (ptr = sym_table; ptr != (struct field *) 0; ptr = ptr->next) {
216
217 interpret_next_blob_value(ptr);
218 fprintf (fp, "\t\"%s\" = 0x%x,\n", ptr->name, ptr->value);
219 }
220 fseek(fp, -2, SEEK_CUR);
221 fprintf (fp, "\n}\n");
222}
223
Angel Pons175778f2019-01-26 10:09:13 +0000224static void generate_binary_with_gbe_checksum(FILE* fp)
Damien Zammit06853222016-11-16 21:06:54 +1100225{
Martin Rothdb4719f2021-02-13 23:19:51 -0700226 unsigned int i;
Damien Zammit06853222016-11-16 21:06:54 +1100227 unsigned short checksum;
228
229 /* traverse spec, push to blob and add up for checksum */
230 struct field *ptr;
231 unsigned int uptochksum = 0;
232 for (ptr = sym_table; ptr != (struct field *) 0; ptr = ptr->next) {
233 if (strcmp (ptr->name, "checksum_gbe") == 0) {
234 /* Stop traversing because we hit checksum */
235 ptr = ptr->next;
236 break;
237 }
238 append_field_to_blob (
239 value_to_bits(ptr->value, ptr->width),
240 ptr->width);
241 uptochksum += ptr->width;
242 }
243
244 /* deserialize bits of blob up to checksum */
245 for (i = 0; i < uptochksum; i += 8) {
246 unsigned char byte = (((binary->blb[i+0] & 1) << 0)
247 | ((binary->blb[i+1] & 1) << 1)
248 | ((binary->blb[i+2] & 1) << 2)
249 | ((binary->blb[i+3] & 1) << 3)
250 | ((binary->blb[i+4] & 1) << 4)
251 | ((binary->blb[i+5] & 1) << 5)
252 | ((binary->blb[i+6] & 1) << 6)
253 | ((binary->blb[i+7] & 1) << 7)
254 );
255 fprintf(fp, "%c", byte);
256
257 /* incremental 16 bit checksum */
258 if ((i % 16) < 8) {
259 binary->checksum += byte;
260 } else {
261 binary->checksum += byte << 8;
262 }
263 }
264
265 checksum = (0xbaba - binary->checksum) & 0xffff;
266
267 /* Now write checksum */
Angel Pons175778f2019-01-26 10:09:13 +0000268 set_bitfield ("checksum_gbe", checksum);
Damien Zammit06853222016-11-16 21:06:54 +1100269
270 fprintf(fp, "%c", checksum & 0xff);
271 fprintf(fp, "%c", (checksum & 0xff00) >> 8);
272
273 append_field_to_blob (value_to_bits(checksum, 16), 16);
274
275 for (; ptr != (struct field *) 0; ptr = ptr->next) {
276 append_field_to_blob (
277 value_to_bits(ptr->value, ptr->width), ptr->width);
278 }
279
280 /* deserialize rest of blob past checksum */
281 for (i = uptochksum + CHECKSUM_SIZE; i < binary->bloblen; i += 8) {
282 unsigned char byte = (((binary->blb[i+0] & 1) << 0)
283 | ((binary->blb[i+1] & 1) << 1)
284 | ((binary->blb[i+2] & 1) << 2)
285 | ((binary->blb[i+3] & 1) << 3)
286 | ((binary->blb[i+4] & 1) << 4)
287 | ((binary->blb[i+5] & 1) << 5)
288 | ((binary->blb[i+6] & 1) << 6)
289 | ((binary->blb[i+7] & 1) << 7)
290 );
291 fprintf(fp, "%c", byte);
292 }
293}
294
295/* {}{} -> BIN */
Angel Pons175778f2019-01-26 10:09:13 +0000296static void generate_binary(FILE* fp)
Damien Zammit06853222016-11-16 21:06:54 +1100297{
298 unsigned int i;
299 struct field *ptr;
300
301 if (binary->bloblen % 8) {
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +0100302 fprintf (stderr,
303 "ERROR: Spec must be multiple of 8 bits wide\n");
Damien Zammit06853222016-11-16 21:06:54 +1100304 exit (1);
305 }
306
Angel Pons175778f2019-01-26 10:09:13 +0000307 if (getsym ("checksum_gbe")) {
308 generate_binary_with_gbe_checksum(fp);
Damien Zammit06853222016-11-16 21:06:54 +1100309 return;
310 }
311
312 /* traverse spec, push to blob */
313 for (ptr = sym_table; ptr != (struct field *) 0; ptr = ptr->next) {
314 append_field_to_blob (
315 value_to_bits(ptr->value, ptr->width),
316 ptr->width);
317 }
318
319 /* deserialize bits of blob */
320 for (i = 0; i < binary->bloblen; i += 8) {
321 unsigned char byte = (((binary->blb[i+0] & 1) << 0)
322 | ((binary->blb[i+1] & 1) << 1)
323 | ((binary->blb[i+2] & 1) << 2)
324 | ((binary->blb[i+3] & 1) << 3)
325 | ((binary->blb[i+4] & 1) << 4)
326 | ((binary->blb[i+5] & 1) << 5)
327 | ((binary->blb[i+6] & 1) << 6)
328 | ((binary->blb[i+7] & 1) << 7)
329 );
330 fprintf(fp, "%c", byte);
331 }
332}
333
334%}
335
336%union
337{
338 char *str;
339 unsigned int u32;
340 unsigned int *u32array;
341 unsigned char u8;
342 unsigned char *u8array;
343}
Angel Pons175778f2019-01-26 10:09:13 +0000344%parse-param {FILE* fp}
Damien Zammit06853222016-11-16 21:06:54 +1100345
346%token <str> name
347%token <u32> val
348%token <u32array> vals
349%token <u8> hexbyte
350%token <u8array> binblob
351%token <u8> eof
352
353%left '%'
354%left '{' '}'
355%left ','
356%left ':'
357%left '='
358
359%%
360
361input:
362 /* empty */
Angel Pons175778f2019-01-26 10:09:13 +0000363| input spec setter eof { empty_field_table(); YYACCEPT;}
Damien Zammit06853222016-11-16 21:06:54 +1100364| input spec blob { fprintf (stderr, "Parsed all bytes\n");
Angel Pons175778f2019-01-26 10:09:13 +0000365 empty_field_table(); YYACCEPT;}
Damien Zammit06853222016-11-16 21:06:54 +1100366;
367
368blob:
Angel Pons175778f2019-01-26 10:09:13 +0000369 '%' eof { generate_setter_bitfields(fp,
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +0100370 binary->actualblob); }
Damien Zammit06853222016-11-16 21:06:54 +1100371;
372
373spec:
374 '{' '}' { fprintf (stderr, "No spec\n"); }
375| '{' specmembers '}' { fprintf (stderr, "Parsed all spec\n");
376 create_binary_blob(); }
377;
378
379specmembers:
380 specpair
381| specpair ',' specmembers
382;
383
384specpair:
Angel Pons175778f2019-01-26 10:09:13 +0000385 name ':' val { create_new_bitfield($1, $3); }
386| name '[' val ']' ':' val { create_new_bitfields($1, $3, $6); }
Damien Zammit06853222016-11-16 21:06:54 +1100387;
388
389setter:
390 '{' '}' { fprintf (stderr, "No values\n"); }
391| '{' valuemembers '}' { fprintf (stderr, "Parsed all values\n");
Angel Pons175778f2019-01-26 10:09:13 +0000392 generate_binary(fp); }
Damien Zammit06853222016-11-16 21:06:54 +1100393;
394
395valuemembers:
396 setpair
397| setpair ',' valuemembers
398;
399
400setpair:
Angel Pons175778f2019-01-26 10:09:13 +0000401 name '=' val { set_bitfield($1, $3); }
402| name '[' val ']' '=' val { set_bitfield_array($1, $3, $6); }
Damien Zammit06853222016-11-16 21:06:54 +1100403;
404
405%%
406
407/* Called by yyparse on error. */
Angel Pons175778f2019-01-26 10:09:13 +0000408static void yyerror (FILE* fp, char const *s)
Damien Zammit06853222016-11-16 21:06:54 +1100409{
Martin Rothdb4719f2021-02-13 23:19:51 -0700410 (void)fp;
Damien Zammit06853222016-11-16 21:06:54 +1100411 fprintf (stderr, "yyerror: %s\n", s);
412}
413
414/* Declarations */
415void set_input_string(char* in);
416
417/* This function parses a string */
Angel Pons175778f2019-01-26 10:09:13 +0000418static int parse_string(FILE* fp, unsigned char* in) {
Damien Zammit06853222016-11-16 21:06:54 +1100419 set_input_string ((char *)in);
Angel Pons175778f2019-01-26 10:09:13 +0000420 return yyparse (fp);
Damien Zammit06853222016-11-16 21:06:54 +1100421}
422
Denis 'GNUtoo' Cariklid5dee1e2018-01-12 04:21:14 +0100423static unsigned int loadfile (FILE* fp, char *file, char *filetype,
Martin Roth63381892017-04-09 13:30:17 -0600424 unsigned char **parsestring, unsigned int lenstr)
425{
426 unsigned int lenfile;
427
428 if ((fp = fopen(file, "r")) == NULL) {
429 printf("Error: Could not open %s file: %s\n",filetype,file);
430 exit(1);
431 }
432 fseek(fp, 0, SEEK_END);
433 lenfile = ftell(fp);
434 fseek(fp, 0, SEEK_SET);
435
436 if (lenstr == 0)
437 *parsestring = (unsigned char *) malloc (lenfile + 2);
438 else
439 *parsestring = (unsigned char *) realloc (*parsestring,
440 lenfile + lenstr);
441
442 check_pointer(*parsestring);
443 fread(*parsestring + lenstr, 1, lenfile, fp);
444 fclose(fp);
445 return lenfile;
446}
447
Damien Zammit06853222016-11-16 21:06:54 +1100448int main (int argc, char *argv[])
449{
Martin Roth63381892017-04-09 13:30:17 -0600450 unsigned int lenspec;
Damien Zammit06853222016-11-16 21:06:54 +1100451 unsigned char *parsestring;
Damien Zammit06853222016-11-16 21:06:54 +1100452 int ret = 0;
Denis 'GNUtoo' Cariklid5dee1e2018-01-12 04:21:14 +0100453 FILE* fp;
Damien Zammit06853222016-11-16 21:06:54 +1100454
455#if YYDEBUG == 1
456 yydebug = 1;
457#endif
458 create_binary_blob();
459 binary->lenactualblob = 0;
460
461 if (argc == 4 && strcmp(argv[1], "-d") != 0) {
462 /* Compile mode */
463
464 /* Load Spec */
Denis 'GNUtoo' Cariklid5dee1e2018-01-12 04:21:14 +0100465 lenspec = loadfile(fp, argv[1], "spec", &parsestring, 0);
466 loadfile(fp, argv[2], "setter", &parsestring, lenspec);
Damien Zammit06853222016-11-16 21:06:54 +1100467
468 /* Open output and parse string - output to fp */
Martin Roth63381892017-04-09 13:30:17 -0600469 if ((fp = fopen(argv[3], "wb")) == NULL) {
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +0100470 printf("Error: Could not open output file: %s\n",
471 argv[3]);
Martin Roth63381892017-04-09 13:30:17 -0600472 exit(1);
473 }
Angel Pons175778f2019-01-26 10:09:13 +0000474 ret = parse_string(fp, parsestring);
Damien Zammit06853222016-11-16 21:06:54 +1100475 free(parsestring);
476 } else if (argc == 5 && strcmp (argv[1], "-d") == 0) {
477 /* Decompile mode */
478
479 /* Load Spec */
Denis 'GNUtoo' Cariklid5dee1e2018-01-12 04:21:14 +0100480 lenspec = loadfile(fp, argv[2], "spec", &parsestring, 0);
Damien Zammit06853222016-11-16 21:06:54 +1100481
Damien Zammit06853222016-11-16 21:06:54 +1100482 parsestring[lenspec] = '%';
Martin Roth63381892017-04-09 13:30:17 -0600483 parsestring[lenspec + 1] = '\0';
Damien Zammit06853222016-11-16 21:06:54 +1100484
485 /* Load Actual Binary */
Martin Roth63381892017-04-09 13:30:17 -0600486 if ((fp = fopen(argv[3], "rb")) == NULL) {
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +0100487 printf("Error: Could not open binary file: %s\n",
488 argv[3]);
Martin Roth63381892017-04-09 13:30:17 -0600489 exit(1);
490 }
Damien Zammit06853222016-11-16 21:06:54 +1100491 fseek(fp, 0, SEEK_END);
492 binary->lenactualblob = ftell(fp);
493 fseek(fp, 0, SEEK_SET);
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +0100494 binary->actualblob = (unsigned char *)malloc(
495 binary->lenactualblob);
Martin Roth63381892017-04-09 13:30:17 -0600496 check_pointer(binary->actualblob);
Damien Zammit06853222016-11-16 21:06:54 +1100497 fread(binary->actualblob, 1, binary->lenactualblob, fp);
498 fclose(fp);
499
500 /* Open output and parse - output to fp */
Martin Roth63381892017-04-09 13:30:17 -0600501 if ((fp = fopen(argv[4], "w")) == NULL) {
Denis 'GNUtoo' Cariklif73914d2018-01-12 05:24:23 +0100502 printf("Error: Could not open output file: %s\n",
503 argv[4]);
Martin Roth63381892017-04-09 13:30:17 -0600504 exit(1);
505 }
Angel Pons175778f2019-01-26 10:09:13 +0000506 ret = parse_string(fp, parsestring);
Damien Zammit06853222016-11-16 21:06:54 +1100507 free(parsestring);
508 free(binary->actualblob);
509 fclose(fp);
510 } else {
511 printf("Usage: Compile mode\n\n");
Denis 'GNUtoo' Carikli780e9312018-01-10 14:35:55 +0100512 printf(" bincfg spec setter binaryoutput\n");
Damien Zammit06853222016-11-16 21:06:54 +1100513 printf(" (file) (file) (file)\n");
514 printf(" OR : Decompile mode\n\n");
Denis 'GNUtoo' Carikli780e9312018-01-10 14:35:55 +0100515 printf(" bincfg -d spec binary setteroutput\n");
Damien Zammit06853222016-11-16 21:06:54 +1100516 }
517 return ret;
518}