summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/sbtools/Makefile2
-rw-r--r--utils/sbtools/dbparser.c626
-rw-r--r--utils/sbtools/dbparser.h94
-rw-r--r--utils/sbtools/elf.c20
-rw-r--r--utils/sbtools/elf.h25
-rw-r--r--utils/sbtools/elftosb.c595
-rw-r--r--utils/sbtools/sb.h4
7 files changed, 780 insertions, 586 deletions
diff --git a/utils/sbtools/Makefile b/utils/sbtools/Makefile
index e8bb68aadd..dc9c0966a7 100644
--- a/utils/sbtools/Makefile
+++ b/utils/sbtools/Makefile
@@ -3,7 +3,7 @@ all: elftosb sbtoelf
3sbtoelf: sbtoelf.c crc.c crypto.h aes128.c sha1.c elf.c sb.h 3sbtoelf: sbtoelf.c crc.c crypto.h aes128.c sha1.c elf.c sb.h
4 gcc -g -std=c99 -o $@ -W -Wall $^ 4 gcc -g -std=c99 -o $@ -W -Wall $^
5 5
6elftosb: elftosb.c crc.c crypto.h aes128.c sha1.c elf.c sb.h 6elftosb: elftosb.c crc.c crypto.h aes128.c sha1.c elf.c sb.h dbparser.h dbparser.c
7 gcc -g -std=c99 -o $@ -W -Wall $^ 7 gcc -g -std=c99 -o $@ -W -Wall $^
8 8
9clean: 9clean:
diff --git a/utils/sbtools/dbparser.c b/utils/sbtools/dbparser.c
new file mode 100644
index 0000000000..20f2d66c0e
--- /dev/null
+++ b/utils/sbtools/dbparser.c
@@ -0,0 +1,626 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <ctype.h>
24#include <stdint.h>
25#include "dbparser.h"
26
27typedef uint8_t byte;
28
29extern bool g_debug;
30extern void *xmalloc(size_t s);
31extern int convxdigit(char digit, byte *val);
32
33#define bug(...) do { fprintf(stderr, __VA_ARGS__); exit(1); } while(0)
34#define bugp(...) do { fprintf(stderr, __VA_ARGS__); perror(" "); exit(1); } while(0)
35
36enum lexem_type_t
37{
38 LEX_IDENTIFIER,
39 LEX_LPAREN,
40 LEX_RPAREN,
41 LEX_NUMBER,
42 LEX_STRING, /* double-quoted string */
43 LEX_EQUAL,
44 LEX_SEMICOLON,
45 LEX_LBRACE,
46 LEX_RBRACE,
47 LEX_RANGLE,
48 LEX_EOF
49};
50
51struct lexem_t
52{
53 enum lexem_type_t type;
54 char *str;
55 uint32_t num;
56 int line;
57 const char *file;
58};
59
60struct context_t
61{
62 const char *file;
63 char *begin;
64 char *end;
65 char *ptr;
66 int line;
67};
68
69#define parse_error(ctx, ...) \
70 do { fprintf(stderr, "%s:%d: ", ctx->file, ctx->line); \
71 fprintf(stderr, __VA_ARGS__); exit(2); } while(0)
72
73static void advance(struct context_t *ctx, int nr_chars)
74{
75 while(nr_chars--)
76 {
77 if(*(ctx->ptr++) == '\n')
78 ctx->line++;
79 }
80}
81
82static inline bool eof(struct context_t *ctx)
83{
84 return ctx->ptr == ctx->end;
85}
86
87static inline bool next_valid(struct context_t *ctx, int nr)
88{
89 return ctx->ptr + nr < ctx->end;
90}
91
92static inline char cur_char(struct context_t *ctx)
93{
94 return *ctx->ptr;
95}
96
97static inline char next_char(struct context_t *ctx, int nr)
98{
99 return ctx->ptr[nr];
100}
101
102static inline void locate_lexem(struct lexem_t *lex, struct context_t *ctx)
103{
104 lex->file = ctx->file;
105 lex->line = ctx->line;
106}
107
108static void __parse_string(struct context_t *ctx, void *user, void (*emit_fn)(void *user, char c))
109{
110 while(!eof(ctx))
111 {
112 if(cur_char(ctx) == '"')
113 break;
114 else if(cur_char(ctx) == '\\')
115 {
116 advance(ctx, 1);
117 if(eof(ctx))
118 parse_error(ctx, "Unfinished string\n");
119 if(cur_char(ctx) == '\\') emit_fn(user, '\\');
120 else if(cur_char(ctx) == '\'') emit_fn(user, '\'');
121 else if(cur_char(ctx) == '\"') emit_fn(user, '\"');
122 else parse_error(ctx, "Unknown escape sequence \\%c\n", cur_char(ctx));
123 advance(ctx, 1);
124 }
125 else
126 {
127 emit_fn(user, cur_char(ctx));
128 advance(ctx, 1);
129 }
130 }
131 if(eof(ctx) || cur_char(ctx) != '"')
132 parse_error(ctx, "Unfinished string\n");
133 advance(ctx, 1);
134}
135
136static void __parse_string_emit(void *user, char c)
137{
138 char **pstr = (char **)user;
139 *(*pstr)++ = c;
140}
141
142static void __parse_string_count(void *user, char c)
143{
144 (void) c;
145 (*(int *)user)++;
146}
147
148static void parse_string(struct context_t *ctx, struct lexem_t *lexem)
149{
150 locate_lexem(lexem, ctx);
151 /* skip " */
152 advance(ctx, 1);
153 /* compute length */
154 struct context_t cpy_ctx = *ctx;
155 int length = 0;
156 __parse_string(&cpy_ctx, (void *)&length, __parse_string_count);
157 /* parse again */
158 lexem->type = LEX_STRING;
159 lexem->str = xmalloc(length + 1);
160 lexem->str[length] = 0;
161 char *pstr = lexem->str;
162 __parse_string(ctx, (void *)&pstr, __parse_string_emit);
163}
164
165static void parse_ascii_number(struct context_t *ctx, struct lexem_t *lexem)
166{
167 locate_lexem(lexem, ctx);
168 /* skip ' */
169 advance(ctx, 1);
170 /* we expect n<=4 character and then ' */
171 int len = 0;
172 uint32_t value = 0;
173 while(!eof(ctx))
174 {
175 if(cur_char(ctx) != '\'')
176 {
177 value = value << 8 | cur_char(ctx);
178 len++;
179 advance(ctx, 1);
180 }
181 else
182 break;
183 }
184 if(eof(ctx) || cur_char(ctx) != '\'')
185 parse_error(ctx, "Unterminated ascii number literal\n");
186 if(len == 0 || len > 4)
187 parse_error(ctx, "Invalid ascii number literal length: only 1 to 4 characters allowed\n");
188 /* skip ' */
189 advance(ctx, 1);
190 lexem->type = LEX_NUMBER;
191 lexem->num = value;
192}
193
194static void parse_number(struct context_t *ctx, struct lexem_t *lexem)
195{
196 locate_lexem(lexem, ctx);
197 /* check base */
198 int base = 10;
199 if(cur_char(ctx) == '0' && next_valid(ctx, 1) && next_char(ctx, 1) == 'x')
200 {
201 advance(ctx, 2);
202 base = 16;
203 }
204
205 lexem->type = LEX_NUMBER;
206 lexem->num = 0;
207 while(!eof(ctx) && isxdigit(cur_char(ctx)))
208 {
209 if(base == 10 && !isdigit(cur_char(ctx)))
210 break;
211 byte v;
212 if(convxdigit(cur_char(ctx), &v))
213 break;
214 lexem->num = base * lexem->num + v;
215 advance(ctx, 1);
216 }
217}
218
219static void parse_identifier(struct context_t *ctx, struct lexem_t *lexem)
220{
221 locate_lexem(lexem, ctx);
222 /* remember position */
223 char *old = ctx->ptr;
224 while(!eof(ctx) && (isalnum(cur_char(ctx)) || cur_char(ctx) == '_'))
225 advance(ctx, 1);
226 lexem->type = LEX_IDENTIFIER;
227 int len = ctx->ptr - old;
228 lexem->str = xmalloc(len + 1);
229 lexem->str[len] = 0;
230 memcpy(lexem->str, old, len);
231}
232
233static void next_lexem(struct context_t *ctx, struct lexem_t *lexem)
234{
235 #define ret_simple(t, adv) \
236 do {locate_lexem(lexem, ctx); \
237 lexem->type = t; \
238 advance(ctx, adv); \
239 return;} while(0)
240 while(!eof(ctx))
241 {
242 char c = cur_char(ctx);
243 /* skip whitespace */
244 if(c == ' ' || c == '\t' || c == '\n' || c == '\r')
245 {
246 advance(ctx, 1);
247 continue;
248 }
249 /* skip C++ style comments */
250 if(c == '/' && next_valid(ctx, 1) && next_char(ctx, 1) == '/')
251 {
252 while(!eof(ctx) && cur_char(ctx) != '\n')
253 advance(ctx, 1);
254 continue;
255 }
256 /* skip C-style comments */
257 if(c == '/' && next_valid(ctx, 1) && next_char(ctx, 1) == '*')
258 {
259 advance(ctx, 2);
260 while(true)
261 {
262 if(!next_valid(ctx, 1))
263 parse_error(ctx, "Unterminated comment");
264 if(cur_char(ctx) == '*' && next_char(ctx, 1) == '/')
265 {
266 advance(ctx, 2);
267 break;
268 }
269 advance(ctx, 1);
270 }
271 continue;
272 }
273 break;
274 }
275 if(eof(ctx)) ret_simple(LEX_EOF, 0);
276 char c = cur_char(ctx);
277 if(c == '(') ret_simple(LEX_LPAREN, 1);
278 if(c == ')') ret_simple(LEX_RPAREN, 1);
279 if(c == '{') ret_simple(LEX_LBRACE, 1);
280 if(c == '}') ret_simple(LEX_RBRACE, 1);
281 if(c == '>') ret_simple(LEX_RANGLE, 1);
282 if(c == '=') ret_simple(LEX_EQUAL, 1);
283 if(c == ';') ret_simple(LEX_SEMICOLON, 1);
284 if(c == '"') return parse_string(ctx, lexem);
285 if(c == '\'') return parse_ascii_number(ctx, lexem);
286 if(isdigit(c)) return parse_number(ctx, lexem);
287 if(isalpha(c) || c == '_') return parse_identifier(ctx, lexem);
288 parse_error(ctx, "Unexpected character '%c'\n", c);
289 #undef ret_simple
290}
291
292#if 0
293static void log_lexem(struct lexem_t *lexem)
294{
295 switch(lexem->type)
296 {
297 case LEX_EOF: printf("<eof>"); break;
298 case LEX_EQUAL: printf("="); break;
299 case LEX_IDENTIFIER: printf("id(%s)", lexem->str); break;
300 case LEX_LPAREN: printf("("); break;
301 case LEX_RPAREN: printf(")"); break;
302 case LEX_LBRACE: printf("{"); break;
303 case LEX_RBRACE: printf("}"); break;
304 case LEX_SEMICOLON: printf(";"); break;
305 case LEX_NUMBER: printf("num(%d)", lexem->num); break;
306 case LEX_STRING: printf("str(%s)", lexem->str); break;
307 default: printf("<unk>");
308 }
309}
310#endif
311
312struct cmd_source_t *db_find_source_by_id(struct cmd_file_t *cmd_file, const char *id)
313{
314 struct cmd_source_t *src = cmd_file->source_list;
315 while(src)
316 {
317 if(strcmp(src->identifier, id) == 0)
318 return src;
319 src = src->next;
320 }
321 return NULL;
322}
323
324static void generate_default_version(struct sb_version_t *ver)
325{
326 ver->major = 0x999;
327 ver->minor = 0x999;
328 ver->revision = 0x999;
329}
330
331#define INVALID_SB_SUBVERSION 0xffff
332
333static uint16_t parse_sb_subversion(char *str)
334{
335 int len = strlen(str);
336 uint16_t n = 0;
337 if(len == 0 || len > 4)
338 return INVALID_SB_SUBVERSION;
339 for(int i = 0; i < len; i++)
340 {
341 if(!isdigit(str[i]))
342 return INVALID_SB_SUBVERSION;
343 n = n << 4 | (str[i] - '0');
344 }
345 return n;
346}
347
348bool db_parse_sb_version(struct sb_version_t *ver, char *str)
349{
350 int len = strlen(str);
351 int cnt = 0;
352 int pos[2];
353
354 for(int i = 0; i < len; i++)
355 {
356 if(str[i] != '.')
357 continue;
358 if(cnt == 2)
359 return false;
360 pos[cnt++] = i + 1;
361 str[i] = 0;
362 }
363 if(cnt != 2)
364 return false;
365 ver->major = parse_sb_subversion(str);
366 ver->minor = parse_sb_subversion(str + pos[0]);
367 ver->revision = parse_sb_subversion(str + pos[1]);
368 return ver->major != INVALID_SB_SUBVERSION &&
369 ver->minor != INVALID_SB_SUBVERSION &&
370 ver->revision != INVALID_SB_SUBVERSION;
371}
372
373#undef parse_error
374#define parse_error(lexem, ...) \
375 do { fprintf(stderr, "%s:%d: ", lexem.file, lexem.line); \
376 fprintf(stderr, __VA_ARGS__); exit(2); } while(0)
377
378struct cmd_file_t *db_parse_file(const char *file)
379{
380 size_t size;
381 FILE *f = fopen(file, "r");
382 if(f == NULL)
383 bugp("Cannot open file '%s'", file);
384 fseek(f, 0, SEEK_END);
385 size = ftell(f);
386 fseek(f, 0, SEEK_SET);
387 char *buf = xmalloc(size);
388 if(fread(buf, size, 1, f) != 1)
389 bugp("Cannot read file '%s'", file);
390 fclose(f);
391
392 if(g_debug)
393 printf("Parsing db file '%s'\n", file);
394 struct cmd_file_t *cmd_file = xmalloc(sizeof(struct cmd_file_t));
395 memset(cmd_file, 0, sizeof(struct cmd_file_t));
396
397 generate_default_version(&cmd_file->product_ver);
398 generate_default_version(&cmd_file->component_ver);
399
400 struct lexem_t lexem;
401 struct context_t ctx;
402 ctx.file = file;
403 ctx.line = 1;
404 ctx.begin = buf;
405 ctx.ptr = buf;
406 ctx.end = buf + size;
407 #define next() next_lexem(&ctx, &lexem)
408 /* init lexer */
409 next();
410 /* options ? */
411 if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "options"))
412 {
413 next();
414 if(lexem.type != LEX_LBRACE)
415 parse_error(lexem, "'{' expected after 'options'\n");
416
417 while(true)
418 {
419 next();
420 if(lexem.type == LEX_RBRACE)
421 break;
422 if(lexem.type != LEX_IDENTIFIER)
423 parse_error(lexem, "Identifier expected in options\n");
424 char *opt = lexem.str;
425 next();
426 if(lexem.type != LEX_EQUAL)
427 parse_error(lexem, "'=' expected after identifier\n");
428 next();
429 if(!strcmp(opt, "productVersion") || !strcmp(opt, "componentVersion"))
430 {
431 if(lexem.type != LEX_STRING)
432 parse_error(lexem, "String expected after '='\n");
433 bool ret;
434 if(!strcmp(opt, "productVersion"))
435 ret = db_parse_sb_version(&cmd_file->product_ver, lexem.str);
436 else
437 ret = db_parse_sb_version(&cmd_file->component_ver, lexem.str);
438 if(!ret)
439 parse_error(lexem, "Invalid product/component version");
440 }
441 else
442 parse_error(lexem, "Unknown option '%s'\n", opt);
443 next();
444 if(lexem.type != LEX_SEMICOLON)
445 parse_error(lexem, "';' expected after string\n");
446 }
447 next();
448 }
449 /* sources */
450 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources"))
451 parse_error(lexem, "'sources' expected\n");
452 next();
453 if(lexem.type != LEX_LBRACE)
454 parse_error(lexem, "'{' expected after 'sources'\n");
455
456 while(true)
457 {
458 next();
459 if(lexem.type == LEX_RBRACE)
460 break;
461 struct cmd_source_t *src = xmalloc(sizeof(struct cmd_source_t));
462 memset(src, 0, sizeof(struct cmd_source_t));
463 src->next = cmd_file->source_list;
464 if(lexem.type != LEX_IDENTIFIER)
465 parse_error(lexem, "identifier expected in sources\n");
466 src->identifier = lexem.str;
467 next();
468 if(lexem.type != LEX_EQUAL)
469 parse_error(lexem, "'=' expected after identifier\n");
470 next();
471 if(lexem.type != LEX_STRING)
472 parse_error(lexem, "String expected after '='\n");
473 src->filename = lexem.str;
474 next();
475 if(lexem.type != LEX_SEMICOLON)
476 parse_error(lexem, "';' expected after string\n");
477 if(db_find_source_by_id(cmd_file, src->identifier) != NULL)
478 parse_error(lexem, "Duplicate source identifier\n");
479 /* type filled later */
480 src->type = CMD_SRC_UNK;
481 cmd_file->source_list = src;
482 }
483
484 /* sections */
485 struct cmd_section_t *end_sec = NULL;
486 while(true)
487 {
488 struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t));
489 struct cmd_inst_t *end_list = NULL;
490 memset(sec, 0, sizeof(struct cmd_section_t));
491 next();
492 if(lexem.type == LEX_EOF)
493 break;
494 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0)
495 parse_error(lexem, "'section' expected\n");
496 next();
497 if(lexem.type != LEX_LPAREN)
498 parse_error(lexem, "'(' expected after 'section'\n");
499 next();
500 /* can be a number or a 4 character long string */
501 if(lexem.type == LEX_NUMBER)
502 {
503 sec->identifier = lexem.num;
504 }
505 else
506 parse_error(lexem, "Number expected as section identifier\n");
507
508 next();
509 if(lexem.type != LEX_RPAREN)
510 parse_error(lexem, "')' expected after section identifier\n");
511 next();
512 if(lexem.type != LEX_LBRACE)
513 parse_error(lexem, "'{' expected after section directive\n");
514 /* commands */
515 while(true)
516 {
517 struct cmd_inst_t *inst = xmalloc(sizeof(struct cmd_inst_t));
518 memset(inst, 0, sizeof(struct cmd_inst_t));
519 next();
520 if(lexem.type == LEX_RBRACE)
521 break;
522 if(lexem.type != LEX_IDENTIFIER)
523 parse_error(lexem, "Instruction expected in section\n");
524 if(strcmp(lexem.str, "load") == 0)
525 inst->type = CMD_LOAD;
526 else if(strcmp(lexem.str, "call") == 0)
527 inst->type = CMD_CALL;
528 else if(strcmp(lexem.str, "jump") == 0)
529 inst->type = CMD_JUMP;
530 else if(strcmp(lexem.str, "mode") == 0)
531 inst->type = CMD_MODE;
532 else
533 parse_error(lexem, "Instruction expected in section\n");
534 next();
535
536 if(inst->type == CMD_LOAD)
537 {
538 if(lexem.type != LEX_IDENTIFIER)
539 parse_error(lexem, "Identifier expected after instruction\n");
540 inst->identifier = lexem.str;
541 if(db_find_source_by_id(cmd_file, inst->identifier) == NULL)
542 parse_error(lexem, "Undefined reference to source '%s'\n", inst->identifier);
543 next();
544 if(lexem.type == LEX_RANGLE)
545 {
546 // load at
547 inst->type = CMD_LOAD_AT;
548 next();
549 if(lexem.type != LEX_NUMBER)
550 parse_error(lexem, "Number expected for loading address\n");
551 inst->addr = lexem.num;
552 next();
553 }
554 if(lexem.type != LEX_SEMICOLON)
555 parse_error(lexem, "';' expected after command\n");
556 }
557 else if(inst->type == CMD_CALL || inst->type == CMD_JUMP)
558 {
559 if(lexem.type == LEX_IDENTIFIER)
560 {
561 inst->identifier = lexem.str;
562 if(db_find_source_by_id(cmd_file, inst->identifier) == NULL)
563 parse_error(lexem, "Undefined reference to source '%s'\n", inst->identifier);
564 next();
565 }
566 else if(lexem.type == LEX_NUMBER)
567 {
568 inst->type = (inst->type == CMD_CALL) ? CMD_CALL_AT : CMD_JUMP_AT;
569 inst->addr = lexem.num;
570 next();
571 }
572 else
573 parse_error(lexem, "Identifier or number expected after jump/load\n");
574
575 if(lexem.type == LEX_LPAREN)
576 {
577 next();
578 if(lexem.type != LEX_NUMBER)
579 parse_error(lexem, "Expected numeral expression after (\n");
580 inst->argument = lexem.num;
581 next();
582 if(lexem.type != LEX_RPAREN)
583 parse_error(lexem, "Expected closing brace\n");
584 next();
585 }
586 if(lexem.type != LEX_SEMICOLON)
587 parse_error(lexem, "Expected ';' after command\n");
588 }
589 else if(inst->type == CMD_MODE)
590 {
591 if(lexem.type != LEX_NUMBER)
592 parse_error(lexem, "Number expected after 'mode'\n");
593 inst->argument = lexem.num;
594 next();
595 if(lexem.type != LEX_SEMICOLON)
596 parse_error(lexem, "Expected ';' after command\n");
597 }
598 else
599 parse_error(lexem, "Internal error");
600 if(end_list == NULL)
601 {
602 sec->inst_list = inst;
603 end_list = inst;
604 }
605 else
606 {
607 end_list->next = inst;
608 end_list = inst;
609 }
610 }
611
612 if(end_sec == NULL)
613 {
614 cmd_file->section_list = sec;
615 end_sec = sec;
616 }
617 else
618 {
619 end_sec->next = sec;
620 end_sec = sec;
621 }
622 }
623 #undef next
624
625 return cmd_file;
626}
diff --git a/utils/sbtools/dbparser.h b/utils/sbtools/dbparser.h
new file mode 100644
index 0000000000..f1b7ffd77e
--- /dev/null
+++ b/utils/sbtools/dbparser.h
@@ -0,0 +1,94 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __DBPARSER__
22#define __DBPARSER__
23
24/**
25 * Command file parsing
26 */
27#include "sb.h"
28#include "elf.h"
29
30enum cmd_source_type_t
31{
32 CMD_SRC_UNK,
33 CMD_SRC_ELF,
34 CMD_SRC_BIN
35};
36
37struct bin_param_t
38{
39 uint32_t size;
40 void *data;
41};
42
43struct cmd_source_t
44{
45 char *identifier;
46 char *filename;
47 struct cmd_source_t *next;
48 /* for later use */
49 enum cmd_source_type_t type;
50 bool loaded;
51 struct elf_params_t elf;
52 struct bin_param_t bin;
53};
54
55enum cmd_inst_type_t
56{
57 CMD_LOAD, /* load image */
58 CMD_JUMP, /* jump at image */
59 CMD_CALL, /* call image */
60 CMD_LOAD_AT, /* load binary at */
61 CMD_CALL_AT, /* call at address */
62 CMD_JUMP_AT, /* jump at address */
63 CMD_MODE, /* change boot mode */
64};
65
66struct cmd_inst_t
67{
68 enum cmd_inst_type_t type;
69 char *identifier;
70 uint32_t argument; // for jump, call, mode
71 uint32_t addr; // for 'at'
72 struct cmd_inst_t *next;
73};
74
75struct cmd_section_t
76{
77 uint32_t identifier;
78 struct cmd_inst_t *inst_list;
79 struct cmd_section_t *next;
80};
81
82struct cmd_file_t
83{
84 struct sb_version_t product_ver;
85 struct sb_version_t component_ver;
86 struct cmd_source_t *source_list;
87 struct cmd_section_t *section_list;
88};
89
90struct cmd_source_t *db_find_source_by_id(struct cmd_file_t *cmd_file, const char *id);
91bool db_parse_sb_version(struct sb_version_t *ver, char *str);
92struct cmd_file_t *db_parse_file(const char *file);
93
94#endif /* __DBPARSER__ */
diff --git a/utils/sbtools/elf.c b/utils/sbtools/elf.c
index 57f38b8016..80bff01c4c 100644
--- a/utils/sbtools/elf.c
+++ b/utils/sbtools/elf.c
@@ -1,3 +1,23 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
1#include "elf.h" 21#include "elf.h"
2 22
3/** 23/**
diff --git a/utils/sbtools/elf.h b/utils/sbtools/elf.h
index d63b9a93b7..f85595d784 100644
--- a/utils/sbtools/elf.h
+++ b/utils/sbtools/elf.h
@@ -1,3 +1,26 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __ELF_H__
22#define __ELF_H__
23
1#include <stdio.h> 24#include <stdio.h>
2#include <stdint.h> 25#include <stdint.h>
3#include <string.h> 26#include <string.h>
@@ -67,3 +90,5 @@ void elf_set_start_addr(struct elf_params_t *params, uint32_t addr);
67bool elf_get_start_addr(struct elf_params_t *params, uint32_t *addr); 90bool elf_get_start_addr(struct elf_params_t *params, uint32_t *addr);
68int elf_get_nr_sections(struct elf_params_t *params); 91int elf_get_nr_sections(struct elf_params_t *params);
69void elf_release(struct elf_params_t *params); 92void elf_release(struct elf_params_t *params);
93
94#endif /* __ELF_H__ */
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c
index cb5cc4c6db..0b659eaf26 100644
--- a/utils/sbtools/elftosb.c
+++ b/utils/sbtools/elftosb.c
@@ -37,6 +37,7 @@
37#include "crypto.h" 37#include "crypto.h"
38#include "elf.h" 38#include "elf.h"
39#include "sb.h" 39#include "sb.h"
40#include "dbparser.h"
40 41
41#define _STR(a) #a 42#define _STR(a) #a
42#define STR(a) _STR(a) 43#define STR(a) _STR(a)
@@ -76,7 +77,7 @@ void *xmalloc(size_t s) /* malloc helper, used in elf.c */
76 return r; 77 return r;
77} 78}
78 79
79static int convxdigit(char digit, byte *val) 80int convxdigit(char digit, byte *val)
80{ 81{
81 if(digit >= '0' && digit <= '9') 82 if(digit >= '0' && digit <= '9')
82 { 83 {
@@ -164,582 +165,6 @@ static key_array_t read_keys(const char *key_file, int *num_keys)
164} 165}
165 166
166/** 167/**
167 * Command file parsing
168 */
169
170enum cmd_source_type_t
171{
172 CMD_SRC_UNK,
173 CMD_SRC_ELF,
174 CMD_SRC_BIN
175};
176
177struct bin_param_t
178{
179 uint32_t size;
180 void *data;
181};
182
183struct cmd_source_t
184{
185 char *identifier;
186 char *filename;
187 struct cmd_source_t *next;
188 /* for later use */
189 enum cmd_source_type_t type;
190 bool loaded;
191 struct elf_params_t elf;
192 struct bin_param_t bin;
193};
194
195enum cmd_inst_type_t
196{
197 CMD_LOAD, /* load image */
198 CMD_JUMP, /* jump at image */
199 CMD_CALL, /* call image */
200 CMD_LOAD_AT, /* load binary at */
201 CMD_CALL_AT, /* call at address */
202 CMD_JUMP_AT, /* jump at address */
203 CMD_MODE, /* change boot mode */
204};
205
206struct cmd_inst_t
207{
208 enum cmd_inst_type_t type;
209 char *identifier;
210 uint32_t argument; // for jump, call, mode
211 uint32_t addr; // for 'at'
212 struct cmd_inst_t *next;
213};
214
215struct cmd_section_t
216{
217 uint32_t identifier;
218 struct cmd_inst_t *inst_list;
219 struct cmd_section_t *next;
220};
221
222struct cmd_file_t
223{
224 struct sb_version_t product_ver;
225 struct sb_version_t component_ver;
226 struct cmd_source_t *source_list;
227 struct cmd_section_t *section_list;
228};
229
230enum lexem_type_t
231{
232 LEX_IDENTIFIER,
233 LEX_LPAREN,
234 LEX_RPAREN,
235 LEX_NUMBER,
236 LEX_STRING, /* double-quoted string */
237 LEX_EQUAL,
238 LEX_SEMICOLON,
239 LEX_LBRACE,
240 LEX_RBRACE,
241 LEX_RANGLE,
242 LEX_EOF
243};
244
245struct lexem_t
246{
247 enum lexem_type_t type;
248 char *str;
249 uint32_t num;
250};
251
252static void __parse_string(char **ptr, char *end, void *user, void (*emit_fn)(void *user, char c))
253{
254 while(*ptr != end)
255 {
256 if(**ptr == '"')
257 break;
258 else if(**ptr == '\\')
259 {
260 (*ptr)++;
261 if(*ptr == end)
262 bug("Unfinished string\n");
263 if(**ptr == '\\') emit_fn(user, '\\');
264 else if(**ptr == '\'') emit_fn(user, '\'');
265 else if(**ptr == '\"') emit_fn(user, '\"');
266 else bug("Unknown escape sequence \\%c\n", **ptr);
267 (*ptr)++;
268 }
269 else
270 emit_fn(user, *(*ptr)++);
271 }
272 if(*ptr == end || **ptr != '"')
273 bug("unfinished string\n");
274 (*ptr)++;
275}
276
277static void __parse_string_emit(void *user, char c)
278{
279 char **pstr = (char **)user;
280 *(*pstr)++ = c;
281}
282
283static void __parse_string_count(void *user, char c)
284{
285 (void) c;
286 (*(int *)user)++;
287}
288
289static void parse_string(char **ptr, char *end, struct lexem_t *lexem)
290{
291 /* skip " */
292 (*ptr)++;
293 char *p = *ptr;
294 /* compute length */
295 int length = 0;
296 __parse_string(&p, end, (void *)&length, __parse_string_count);
297 /* parse again */
298 lexem->type = LEX_STRING;
299 lexem->str = xmalloc(length + 1);
300 lexem->str[length] = 0;
301 char *pstr = lexem->str;
302 __parse_string(ptr, end, (void *)&pstr, __parse_string_emit);
303}
304
305static void parse_ascii_number(char **ptr, char *end, struct lexem_t *lexem)
306{
307 /* skip ' */
308 (*ptr)++;
309 /* we expect 4 character and then ' */
310 int len = 0;
311 uint32_t value = 0;
312 while(*ptr != end)
313 {
314 if(**ptr != '\'')
315 {
316 value = value << 8 | **ptr;
317 len++;
318 (*ptr)++;
319 }
320 else
321 break;
322 }
323 if(*ptr == end || **ptr != '\'')
324 bug("Unterminated ascii number literal\n");
325 if(len != 1 && len != 2 && len != 4)
326 bug("Invalid ascii number literal length: only 1, 2 or 4 are valid\n");
327 /* skip ' */
328 (*ptr)++;
329 lexem->type = LEX_NUMBER;
330 lexem->num = value;
331}
332
333static void parse_number(char **ptr, char *end, struct lexem_t *lexem)
334{
335 int base = 10;
336 if(**ptr == '0' && (*ptr) + 1 != end && (*ptr)[1] == 'x')
337 {
338 (*ptr) += 2;
339 base = 16;
340 }
341
342 lexem->type = LEX_NUMBER;
343 lexem->num = 0;
344 while(*ptr != end && isxdigit(**ptr))
345 {
346 if(base == 10 && !isdigit(**ptr))
347 break;
348 byte v;
349 if(convxdigit(**ptr, &v))
350 break;
351 lexem->num = base * lexem->num + v;
352 (*ptr)++;
353 }
354}
355
356static void parse_identifier(char **ptr, char *end, struct lexem_t *lexem)
357{
358 /* remember position */
359 char *old = *ptr;
360 while(*ptr != end && (isalnum(**ptr) || **ptr == '_'))
361 (*ptr)++;
362 lexem->type = LEX_IDENTIFIER;
363 int len = *ptr - old;
364 lexem->str = xmalloc(len + 1);
365 lexem->str[len] = 0;
366 memcpy(lexem->str, old, len);
367}
368
369static void next_lexem(char **ptr, char *end, struct lexem_t *lexem)
370{
371 #define ret_simple(t, advance) ({(*ptr) += advance; lexem->type = t; return;})
372 while(*ptr != end)
373 {
374 /* skip whitespace */
375 if(**ptr == ' ' || **ptr == '\t' || **ptr == '\n' || **ptr == '\r')
376 {
377 (*ptr)++;
378 continue;
379 }
380 /* skip C++ style comments */
381 if(**ptr == '/' && (*ptr) + 1 != end && (*ptr)[1] == '/')
382 {
383 while(*ptr != end && **ptr != '\n')
384 (*ptr)++;
385 continue;
386 }
387 /* skip C-style comments */
388 if(**ptr == '/' && (*ptr) + 1 != end && (*ptr)[1] == '*')
389 {
390 (*ptr) += 2;
391 if(*ptr == end)
392 bug("invalid command file: unterminated comment");
393 while(true)
394 {
395 if(**ptr == '*' && (*ptr) + 1 != end && (*ptr)[1] == '/')
396 {
397 (*ptr) += 2;
398 break;
399 }
400 (*ptr)++;
401 }
402 continue;
403 }
404 break;
405 }
406 if(*ptr == end) ret_simple(LEX_EOF, 0);
407 if(**ptr == '(') ret_simple(LEX_LPAREN, 1);
408 if(**ptr == ')') ret_simple(LEX_RPAREN, 1);
409 if(**ptr == '{') ret_simple(LEX_LBRACE, 1);
410 if(**ptr == '}') ret_simple(LEX_RBRACE, 1);
411 if(**ptr == '>') ret_simple(LEX_RANGLE, 1);
412 if(**ptr == '=') ret_simple(LEX_EQUAL, 1);
413 if(**ptr == ';') ret_simple(LEX_SEMICOLON, 1);
414 if(**ptr == '"') return parse_string(ptr, end, lexem);
415 if(**ptr == '\'') return parse_ascii_number(ptr, end, lexem);
416 if(isdigit(**ptr)) return parse_number(ptr, end, lexem);
417 if(isalpha(**ptr) || **ptr == '_') return parse_identifier(ptr, end, lexem);
418 bug("Unexpected character '%c' in command file\n", **ptr);
419 #undef ret_simple
420}
421
422#if 0
423static void log_lexem(struct lexem_t *lexem)
424{
425 switch(lexem->type)
426 {
427 case LEX_EOF: printf("<eof>"); break;
428 case LEX_EQUAL: printf("="); break;
429 case LEX_IDENTIFIER: printf("id(%s)", lexem->str); break;
430 case LEX_LPAREN: printf("("); break;
431 case LEX_RPAREN: printf(")"); break;
432 case LEX_LBRACE: printf("{"); break;
433 case LEX_RBRACE: printf("}"); break;
434 case LEX_SEMICOLON: printf(";"); break;
435 case LEX_NUMBER: printf("num(%d)", lexem->num); break;
436 case LEX_STRING: printf("str(%s)", lexem->str); break;
437 default: printf("<unk>");
438 }
439}
440#endif
441
442static struct cmd_source_t *find_source_by_id(struct cmd_file_t *cmd_file, const char *id)
443{
444 struct cmd_source_t *src = cmd_file->source_list;
445 while(src)
446 {
447 if(strcmp(src->identifier, id) == 0)
448 return src;
449 src = src->next;
450 }
451 return NULL;
452}
453
454static void generate_default_version(struct sb_version_t *ver)
455{
456 ver->major = 0x999;
457 ver->minor = 0x999;
458 ver->revision = 0x999;
459}
460
461static uint16_t parse_sb_subversion(char *str)
462{
463 int len = strlen(str);
464 uint16_t n = 0;
465 if(len == 0 || len > 4)
466 bug("invalid command file: invalid version string");
467 for(int i = 0; i < len; i++)
468 {
469 if(!isdigit(str[i]))
470 bug("invalid command file: invalid version string");
471 n = n << 4 | (str[i] - '0');
472 }
473 return n;
474}
475
476static void parse_sb_version(struct sb_version_t *ver, char *str)
477{
478 int len = strlen(str);
479 int cnt = 0;
480 int pos[2];
481
482 for(int i = 0; i < len; i++)
483 {
484 if(str[i] != '.')
485 continue;
486 if(cnt == 2)
487 bug("invalid command file: invalid version string");
488 pos[cnt++] = i + 1;
489 str[i] = 0;
490 }
491 if(cnt != 2)
492 bug("invalid command file: invalid version string");
493 ver->major = parse_sb_subversion(str);
494 ver->minor = parse_sb_subversion(str + pos[0]);
495 ver->revision = parse_sb_subversion(str + pos[1]);
496}
497
498static struct cmd_file_t *read_command_file(const char *file)
499{
500 int size;
501 struct stat st;
502 int fd = open(file,O_RDONLY);
503 if(fd == -1)
504 bugp("opening command file failed");
505 if(fstat(fd,&st) == -1)
506 bugp("command file stat() failed");
507 size = st.st_size;
508 char *buf = xmalloc(size);
509 if(read(fd, buf, size) != (ssize_t)size)
510 bugp("reading command file");
511 close(fd);
512
513 if(g_debug)
514 printf("Parsing command file '%s'...\n", file);
515 struct cmd_file_t *cmd_file = xmalloc(sizeof(struct cmd_file_t));
516 memset(cmd_file, 0, sizeof(struct cmd_file_t));
517
518 generate_default_version(&cmd_file->product_ver);
519 generate_default_version(&cmd_file->component_ver);
520
521 struct lexem_t lexem;
522 char *p = buf;
523 char *end = buf + size;
524 #define next() next_lexem(&p, end, &lexem)
525 /* init lexer */
526 next();
527 /* options ? */
528 if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "options"))
529 {
530 next();
531 if(lexem.type != LEX_LBRACE)
532 bug("invalid command file: '{' expected after 'options'\n");
533
534 while(true)
535 {
536 next();
537 if(lexem.type == LEX_RBRACE)
538 break;
539 if(lexem.type != LEX_IDENTIFIER)
540 bug("invalid command file: identifier expected in options\n");
541 char *opt = lexem.str;
542 next();
543 if(lexem.type != LEX_EQUAL)
544 bug("invalid command file: '=' expected after identifier\n");
545 next();
546 if(!strcmp(opt, "productVersion") || !strcmp(opt, "componentVersion"))
547 {
548 if(lexem.type != LEX_STRING)
549 bug("invalid command file: string expected after '='\n");
550 if(!strcmp(opt, "productVersion"))
551 parse_sb_version(&cmd_file->product_ver, lexem.str);
552 else
553 parse_sb_version(&cmd_file->component_ver, lexem.str);
554 }
555 else
556 bug("invalid command file: unknown option '%s'\n", opt);
557 next();
558 if(lexem.type != LEX_SEMICOLON)
559 bug("invalid command file: ';' expected after string\n");
560 }
561 next();
562 }
563 /* sources */
564 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources") != 0)
565 bug("invalid command file: 'sources' expected\n");
566 next();
567 if(lexem.type != LEX_LBRACE)
568 bug("invalid command file: '{' expected after 'sources'\n");
569
570 while(true)
571 {
572 next();
573 if(lexem.type == LEX_RBRACE)
574 break;
575 struct cmd_source_t *src = xmalloc(sizeof(struct cmd_source_t));
576 memset(src, 0, sizeof(struct cmd_source_t));
577 src->next = cmd_file->source_list;
578 if(lexem.type != LEX_IDENTIFIER)
579 bug("invalid command file: identifier expected in sources\n");
580 src->identifier = lexem.str;
581 next();
582 if(lexem.type != LEX_EQUAL)
583 bug("invalid command file: '=' expected after identifier\n");
584 next();
585 if(lexem.type != LEX_STRING)
586 bug("invalid command file: string expected after '='\n");
587 src->filename = lexem.str;
588 next();
589 if(lexem.type != LEX_SEMICOLON)
590 bug("invalid command file: ';' expected after string\n");
591 if(find_source_by_id(cmd_file, src->identifier) != NULL)
592 bug("invalid command file: duplicated source identifier\n");
593 /* type filled later */
594 src->type = CMD_SRC_UNK;
595 cmd_file->source_list = src;
596 }
597
598 /* sections */
599 struct cmd_section_t *end_sec = NULL;
600 while(true)
601 {
602 struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t));
603 struct cmd_inst_t *end_list = NULL;
604 memset(sec, 0, sizeof(struct cmd_section_t));
605 next();
606 if(lexem.type == LEX_EOF)
607 break;
608 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0)
609 bug("invalid command file: 'section' expected\n");
610 next();
611 if(lexem.type != LEX_LPAREN)
612 bug("invalid command file: '(' expected after 'section'\n");
613 next();
614 /* can be a number or a 4 character long string */
615 if(lexem.type == LEX_NUMBER)
616 {
617 sec->identifier = lexem.num;
618 }
619 else
620 bug("invalid command file: number expected as section identifier\n");
621
622 next();
623 if(lexem.type != LEX_RPAREN)
624 bug("invalid command file: ')' expected after section identifier\n");
625 next();
626 if(lexem.type != LEX_LBRACE)
627 bug("invalid command file: '{' expected after section directive\n");
628 /* commands */
629 while(true)
630 {
631 struct cmd_inst_t *inst = xmalloc(sizeof(struct cmd_inst_t));
632 memset(inst, 0, sizeof(struct cmd_inst_t));
633 next();
634 if(lexem.type == LEX_RBRACE)
635 break;
636 if(lexem.type != LEX_IDENTIFIER)
637 bug("invalid command file: instruction expected in section\n");
638 if(strcmp(lexem.str, "load") == 0)
639 inst->type = CMD_LOAD;
640 else if(strcmp(lexem.str, "call") == 0)
641 inst->type = CMD_CALL;
642 else if(strcmp(lexem.str, "jump") == 0)
643 inst->type = CMD_JUMP;
644 else if(strcmp(lexem.str, "mode") == 0)
645 inst->type = CMD_MODE;
646 else
647 bug("invalid command file: instruction expected in section\n");
648 next();
649
650 if(inst->type == CMD_LOAD)
651 {
652 if(lexem.type != LEX_IDENTIFIER)
653 bug("invalid command file: identifier expected after instruction\n");
654 inst->identifier = lexem.str;
655 if(find_source_by_id(cmd_file, inst->identifier) == NULL)
656 bug("invalid command file: undefined reference to source '%s'\n", inst->identifier);
657 next();
658 if(lexem.type == LEX_RANGLE)
659 {
660 // load at
661 inst->type = CMD_LOAD_AT;
662 next();
663 if(lexem.type != LEX_NUMBER)
664 bug("invalid command file: number expected for loading address\n");
665 inst->addr = lexem.num;
666 next();
667 }
668 if(lexem.type != LEX_SEMICOLON)
669 bug("invalid command file: expected ';' after command\n");
670 }
671 else if(inst->type == CMD_CALL || inst->type == CMD_JUMP)
672 {
673 if(lexem.type == LEX_IDENTIFIER)
674 {
675 inst->identifier = lexem.str;
676 if(find_source_by_id(cmd_file, inst->identifier) == NULL)
677 bug("invalid command file: undefined reference to source '%s'\n", inst->identifier);
678 next();
679 }
680 else if(lexem.type == LEX_NUMBER)
681 {
682 inst->type = (inst->type == CMD_CALL) ? CMD_CALL_AT : CMD_JUMP_AT;
683 inst->addr = lexem.num;
684 next();
685 }
686 else
687 bug("invalid command file: identifier or number expected after jump/load\n");
688
689 if(lexem.type == LEX_LPAREN)
690 {
691 next();
692 if(lexem.type != LEX_NUMBER)
693 bug("invalid command file: expected numeral expression after (\n");
694 inst->argument = lexem.num;
695 next();
696 if(lexem.type != LEX_RPAREN)
697 bug("invalid command file: expected closing brace\n");
698 next();
699 }
700 if(lexem.type != LEX_SEMICOLON)
701 bug("invalid command file: expected ';' after command\n");
702 }
703 else if(inst->type == CMD_MODE)
704 {
705 if(lexem.type != LEX_NUMBER)
706 bug("invalid command file: number expected after 'mode'\n");
707 inst->argument = lexem.num;
708 next();
709 if(lexem.type != LEX_SEMICOLON)
710 bug("invalid command file: expected ';' after command\n");
711 }
712 else
713 bug("die\n");
714 if(end_list == NULL)
715 {
716 sec->inst_list = inst;
717 end_list = inst;
718 }
719 else
720 {
721 end_list->next = inst;
722 end_list = inst;
723 }
724 }
725
726 if(end_sec == NULL)
727 {
728 cmd_file->section_list = sec;
729 end_sec = sec;
730 }
731 else
732 {
733 end_sec->next = sec;
734 end_sec = sec;
735 }
736 }
737 #undef next
738
739 return cmd_file;
740}
741
742/**
743 * command file to sb conversion 168 * command file to sb conversion
744 */ 169 */
745 170
@@ -798,7 +223,7 @@ static void elf_printf(void *user, bool error, const char *fmt, ...)
798 223
799static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id) 224static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
800{ 225{
801 struct cmd_source_t *src = find_source_by_id(cmd_file, id); 226 struct cmd_source_t *src = db_find_source_by_id(cmd_file, id);
802 if(src == NULL) 227 if(src == NULL)
803 bug("undefined reference to source '%s'\n", id); 228 bug("undefined reference to source '%s'\n", id);
804 /* avoid reloading */ 229 /* avoid reloading */
@@ -822,7 +247,7 @@ static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
822 247
823static void load_bin_by_id(struct cmd_file_t *cmd_file, const char *id) 248static void load_bin_by_id(struct cmd_file_t *cmd_file, const char *id)
824{ 249{
825 struct cmd_source_t *src = find_source_by_id(cmd_file, id); 250 struct cmd_source_t *src = db_find_source_by_id(cmd_file, id);
826 if(src == NULL) 251 if(src == NULL)
827 bug("undefined reference to source '%s'\n", id); 252 bug("undefined reference to source '%s'\n", id);
828 /* avoid reloading */ 253 /* avoid reloading */
@@ -877,13 +302,13 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
877 if(cinst->type == CMD_LOAD) 302 if(cinst->type == CMD_LOAD)
878 { 303 {
879 load_elf_by_id(cmd_file, cinst->identifier); 304 load_elf_by_id(cmd_file, cinst->identifier);
880 struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf; 305 struct elf_params_t *elf = &db_find_source_by_id(cmd_file, cinst->identifier)->elf;
881 sec->nr_insts += elf_get_nr_sections(elf); 306 sec->nr_insts += elf_get_nr_sections(elf);
882 } 307 }
883 else if(cinst->type == CMD_JUMP || cinst->type == CMD_CALL) 308 else if(cinst->type == CMD_JUMP || cinst->type == CMD_CALL)
884 { 309 {
885 load_elf_by_id(cmd_file, cinst->identifier); 310 load_elf_by_id(cmd_file, cinst->identifier);
886 struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf; 311 struct elf_params_t *elf = &db_find_source_by_id(cmd_file, cinst->identifier)->elf;
887 if(!elf_get_start_addr(elf, NULL)) 312 if(!elf_get_start_addr(elf, NULL))
888 bug("cannot jump/call '%s' because it has no starting point !\n", cinst->identifier); 313 bug("cannot jump/call '%s' because it has no starting point !\n", cinst->identifier);
889 sec->nr_insts++; 314 sec->nr_insts++;
@@ -916,7 +341,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
916 { 341 {
917 if(cinst->type == CMD_LOAD) 342 if(cinst->type == CMD_LOAD)
918 { 343 {
919 struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf; 344 struct elf_params_t *elf = &db_find_source_by_id(cmd_file, cinst->identifier)->elf;
920 struct elf_section_t *esec = elf->first_section; 345 struct elf_section_t *esec = elf->first_section;
921 while(esec) 346 while(esec)
922 { 347 {
@@ -939,7 +364,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
939 } 364 }
940 else if(cinst->type == CMD_JUMP || cinst->type == CMD_CALL) 365 else if(cinst->type == CMD_JUMP || cinst->type == CMD_CALL)
941 { 366 {
942 struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf; 367 struct elf_params_t *elf = &db_find_source_by_id(cmd_file, cinst->identifier)->elf;
943 sec->insts[idx].argument = cinst->argument; 368 sec->insts[idx].argument = cinst->argument;
944 sec->insts[idx].inst = (cinst->type == CMD_JUMP) ? SB_INST_JUMP : SB_INST_CALL; 369 sec->insts[idx].inst = (cinst->type == CMD_JUMP) ? SB_INST_JUMP : SB_INST_CALL;
945 sec->insts[idx++].addr = elf->start_addr; 370 sec->insts[idx++].addr = elf->start_addr;
@@ -952,7 +377,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
952 } 377 }
953 else if(cinst->type == CMD_LOAD_AT) 378 else if(cinst->type == CMD_LOAD_AT)
954 { 379 {
955 struct bin_param_t *bin = &find_source_by_id(cmd_file, cinst->identifier)->bin; 380 struct bin_param_t *bin = &db_find_source_by_id(cmd_file, cinst->identifier)->bin;
956 sec->insts[idx].inst = SB_INST_LOAD; 381 sec->insts[idx].inst = SB_INST_LOAD;
957 sec->insts[idx].addr = cinst->addr; 382 sec->insts[idx].addr = cinst->addr;
958 sec->insts[idx].data = bin->data; 383 sec->insts[idx].data = bin->data;
@@ -1294,7 +719,7 @@ int main(int argc, const char **argv)
1294 g_debug = true; 719 g_debug = true;
1295 720
1296 g_key_array = read_keys(argv[2], &g_nr_keys); 721 g_key_array = read_keys(argv[2], &g_nr_keys);
1297 struct cmd_file_t *cmd_file = read_command_file(argv[1]); 722 struct cmd_file_t *cmd_file = db_parse_file(argv[1]);
1298 struct sb_file_t *sb_file = apply_cmd_file(cmd_file); 723 struct sb_file_t *sb_file = apply_cmd_file(cmd_file);
1299 produce_sb_file(sb_file, argv[3]); 724 produce_sb_file(sb_file, argv[3]);
1300 725
diff --git a/utils/sbtools/sb.h b/utils/sbtools/sb.h
index a1482691ce..0a8fad10af 100644
--- a/utils/sbtools/sb.h
+++ b/utils/sbtools/sb.h
@@ -18,6 +18,8 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#ifndef __SB_H__
22#define __SB_H__
21 23
22#include <stdint.h> 24#include <stdint.h>
23 25
@@ -147,3 +149,5 @@ struct sb_instruction_tag_t
147 uint32_t len; /* length of the section */ 149 uint32_t len; /* length of the section */
148 uint32_t flags; /* section flags */ 150 uint32_t flags; /* section flags */
149} __attribute__((packed)); 151} __attribute__((packed));
152
153#endif /* __SB_H__ */