summaryrefslogtreecommitdiffstats
path: root/utils/sbtools
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-09-15 16:10:31 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-09-15 16:10:31 +0000
commit9d7df9ae4d829204856a19fc14fae166631389bf (patch)
treeb82178fd2b0c7b4f75735599d99ce7fabbd53261 /utils/sbtools
parent64b46723591adc8b563a692c0e91681d2fcd4ad4 (diff)
downloadrockbox-9d7df9ae4d829204856a19fc14fae166631389bf.tar.gz
rockbox-9d7df9ae4d829204856a19fc14fae166631389bf.zip
sbtools: move the db parse to its own file and improve error messages
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30557 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils/sbtools')
-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
sbtoelf: sbtoelf.c crc.c crypto.h aes128.c sha1.c elf.c sb.h
gcc -g -std=c99 -o $@ -W -Wall $^
-elftosb: elftosb.c crc.c crypto.h aes128.c sha1.c elf.c sb.h
+elftosb: elftosb.c crc.c crypto.h aes128.c sha1.c elf.c sb.h dbparser.h dbparser.c
gcc -g -std=c99 -o $@ -W -Wall $^
clean:
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdint.h>
+#include "dbparser.h"
+
+typedef uint8_t byte;
+
+extern bool g_debug;
+extern void *xmalloc(size_t s);
+extern int convxdigit(char digit, byte *val);
+
+#define bug(...) do { fprintf(stderr, __VA_ARGS__); exit(1); } while(0)
+#define bugp(...) do { fprintf(stderr, __VA_ARGS__); perror(" "); exit(1); } while(0)
+
+enum lexem_type_t
+{
+ LEX_IDENTIFIER,
+ LEX_LPAREN,
+ LEX_RPAREN,
+ LEX_NUMBER,
+ LEX_STRING, /* double-quoted string */
+ LEX_EQUAL,
+ LEX_SEMICOLON,
+ LEX_LBRACE,
+ LEX_RBRACE,
+ LEX_RANGLE,
+ LEX_EOF
+};
+
+struct lexem_t
+{
+ enum lexem_type_t type;
+ char *str;
+ uint32_t num;
+ int line;
+ const char *file;
+};
+
+struct context_t
+{
+ const char *file;
+ char *begin;
+ char *end;
+ char *ptr;
+ int line;
+};
+
+#define parse_error(ctx, ...) \
+ do { fprintf(stderr, "%s:%d: ", ctx->file, ctx->line); \
+ fprintf(stderr, __VA_ARGS__); exit(2); } while(0)
+
+static void advance(struct context_t *ctx, int nr_chars)
+{
+ while(nr_chars--)
+ {
+ if(*(ctx->ptr++) == '\n')
+ ctx->line++;
+ }
+}
+
+static inline bool eof(struct context_t *ctx)
+{
+ return ctx->ptr == ctx->end;
+}
+
+static inline bool next_valid(struct context_t *ctx, int nr)
+{
+ return ctx->ptr + nr < ctx->end;
+}
+
+static inline char cur_char(struct context_t *ctx)
+{
+ return *ctx->ptr;
+}
+
+static inline char next_char(struct context_t *ctx, int nr)
+{
+ return ctx->ptr[nr];
+}
+
+static inline void locate_lexem(struct lexem_t *lex, struct context_t *ctx)
+{
+ lex->file = ctx->file;
+ lex->line = ctx->line;
+}
+
+static void __parse_string(struct context_t *ctx, void *user, void (*emit_fn)(void *user, char c))
+{
+ while(!eof(ctx))
+ {
+ if(cur_char(ctx) == '"')
+ break;
+ else if(cur_char(ctx) == '\\')
+ {
+ advance(ctx, 1);
+ if(eof(ctx))
+ parse_error(ctx, "Unfinished string\n");
+ if(cur_char(ctx) == '\\') emit_fn(user, '\\');
+ else if(cur_char(ctx) == '\'') emit_fn(user, '\'');
+ else if(cur_char(ctx) == '\"') emit_fn(user, '\"');
+ else parse_error(ctx, "Unknown escape sequence \\%c\n", cur_char(ctx));
+ advance(ctx, 1);
+ }
+ else
+ {
+ emit_fn(user, cur_char(ctx));
+ advance(ctx, 1);
+ }
+ }
+ if(eof(ctx) || cur_char(ctx) != '"')
+ parse_error(ctx, "Unfinished string\n");
+ advance(ctx, 1);
+}
+
+static void __parse_string_emit(void *user, char c)
+{
+ char **pstr = (char **)user;
+ *(*pstr)++ = c;
+}
+
+static void __parse_string_count(void *user, char c)
+{
+ (void) c;
+ (*(int *)user)++;
+}
+
+static void parse_string(struct context_t *ctx, struct lexem_t *lexem)
+{
+ locate_lexem(lexem, ctx);
+ /* skip " */
+ advance(ctx, 1);
+ /* compute length */
+ struct context_t cpy_ctx = *ctx;
+ int length = 0;
+ __parse_string(&cpy_ctx, (void *)&length, __parse_string_count);
+ /* parse again */
+ lexem->type = LEX_STRING;
+ lexem->str = xmalloc(length + 1);
+ lexem->str[length] = 0;
+ char *pstr = lexem->str;
+ __parse_string(ctx, (void *)&pstr, __parse_string_emit);
+}
+
+static void parse_ascii_number(struct context_t *ctx, struct lexem_t *lexem)
+{
+ locate_lexem(lexem, ctx);
+ /* skip ' */
+ advance(ctx, 1);
+ /* we expect n<=4 character and then ' */
+ int len = 0;
+ uint32_t value = 0;
+ while(!eof(ctx))
+ {
+ if(cur_char(ctx) != '\'')
+ {
+ value = value << 8 | cur_char(ctx);
+ len++;
+ advance(ctx, 1);
+ }
+ else
+ break;
+ }
+ if(eof(ctx) || cur_char(ctx) != '\'')
+ parse_error(ctx, "Unterminated ascii number literal\n");
+ if(len == 0 || len > 4)
+ parse_error(ctx, "Invalid ascii number literal length: only 1 to 4 characters allowed\n");
+ /* skip ' */
+ advance(ctx, 1);
+ lexem->type = LEX_NUMBER;
+ lexem->num = value;
+}
+
+static void parse_number(struct context_t *ctx, struct lexem_t *lexem)
+{
+ locate_lexem(lexem, ctx);
+ /* check base */
+ int base = 10;
+ if(cur_char(ctx) == '0' && next_valid(ctx, 1) && next_char(ctx, 1) == 'x')
+ {
+ advance(ctx, 2);
+ base = 16;
+ }
+
+ lexem->type = LEX_NUMBER;
+ lexem->num = 0;
+ while(!eof(ctx) && isxdigit(cur_char(ctx)))
+ {
+ if(base == 10 && !isdigit(cur_char(ctx)))
+ break;
+ byte v;
+ if(convxdigit(cur_char(ctx), &v))
+ break;
+ lexem->num = base * lexem->num + v;
+ advance(ctx, 1);
+ }
+}
+
+static void parse_identifier(struct context_t *ctx, struct lexem_t *lexem)
+{
+ locate_lexem(lexem, ctx);
+ /* remember position */
+ char *old = ctx->ptr;
+ while(!eof(ctx) && (isalnum(cur_char(ctx)) || cur_char(ctx) == '_'))
+ advance(ctx, 1);
+ lexem->type = LEX_IDENTIFIER;
+ int len = ctx->ptr - old;
+ lexem->str = xmalloc(len + 1);
+ lexem->str[len] = 0;
+ memcpy(lexem->str, old, len);
+}
+
+static void next_lexem(struct context_t *ctx, struct lexem_t *lexem)
+{
+ #define ret_simple(t, adv) \
+ do {locate_lexem(lexem, ctx); \
+ lexem->type = t; \
+ advance(ctx, adv); \
+ return;} while(0)
+ while(!eof(ctx))
+ {
+ char c = cur_char(ctx);
+ /* skip whitespace */
+ if(c == ' ' || c == '\t' || c == '\n' || c == '\r')
+ {
+ advance(ctx, 1);
+ continue;
+ }
+ /* skip C++ style comments */
+ if(c == '/' && next_valid(ctx, 1) && next_char(ctx, 1) == '/')
+ {
+ while(!eof(ctx) && cur_char(ctx) != '\n')
+ advance(ctx, 1);
+ continue;
+ }
+ /* skip C-style comments */
+ if(c == '/' && next_valid(ctx, 1) && next_char(ctx, 1) == '*')
+ {
+ advance(ctx, 2);
+ while(true)
+ {
+ if(!next_valid(ctx, 1))
+ parse_error(ctx, "Unterminated comment");
+ if(cur_char(ctx) == '*' && next_char(ctx, 1) == '/')
+ {
+ advance(ctx, 2);
+ break;
+ }
+ advance(ctx, 1);
+ }
+ continue;
+ }
+ break;
+ }
+ if(eof(ctx)) ret_simple(LEX_EOF, 0);
+ char c = cur_char(ctx);
+ if(c == '(') ret_simple(LEX_LPAREN, 1);
+ if(c == ')') ret_simple(LEX_RPAREN, 1);
+ if(c == '{') ret_simple(LEX_LBRACE, 1);
+ if(c == '}') ret_simple(LEX_RBRACE, 1);
+ if(c == '>') ret_simple(LEX_RANGLE, 1);
+ if(c == '=') ret_simple(LEX_EQUAL, 1);
+ if(c == ';') ret_simple(LEX_SEMICOLON, 1);
+ if(c == '"') return parse_string(ctx, lexem);
+ if(c == '\'') return parse_ascii_number(ctx, lexem);
+ if(isdigit(c)) return parse_number(ctx, lexem);
+ if(isalpha(c) || c == '_') return parse_identifier(ctx, lexem);
+ parse_error(ctx, "Unexpected character '%c'\n", c);
+ #undef ret_simple
+}
+
+#if 0
+static void log_lexem(struct lexem_t *lexem)
+{
+ switch(lexem->type)
+ {
+ case LEX_EOF: printf("<eof>"); break;
+ case LEX_EQUAL: printf("="); break;
+ case LEX_IDENTIFIER: printf("id(%s)", lexem->str); break;
+ case LEX_LPAREN: printf("("); break;
+ case LEX_RPAREN: printf(")"); break;
+ case LEX_LBRACE: printf("{"); break;
+ case LEX_RBRACE: printf("}"); break;
+ case LEX_SEMICOLON: printf(";"); break;
+ case LEX_NUMBER: printf("num(%d)", lexem->num); break;
+ case LEX_STRING: printf("str(%s)", lexem->str); break;
+ default: printf("<unk>");
+ }
+}
+#endif
+
+struct cmd_source_t *db_find_source_by_id(struct cmd_file_t *cmd_file, const char *id)
+{
+ struct cmd_source_t *src = cmd_file->source_list;
+ while(src)
+ {
+ if(strcmp(src->identifier, id) == 0)
+ return src;
+ src = src->next;
+ }
+ return NULL;
+}
+
+static void generate_default_version(struct sb_version_t *ver)
+{
+ ver->major = 0x999;
+ ver->minor = 0x999;
+ ver->revision = 0x999;
+}
+
+#define INVALID_SB_SUBVERSION 0xffff
+
+static uint16_t parse_sb_subversion(char *str)
+{
+ int len = strlen(str);
+ uint16_t n = 0;
+ if(len == 0 || len > 4)
+ return INVALID_SB_SUBVERSION;
+ for(int i = 0; i < len; i++)
+ {
+ if(!isdigit(str[i]))
+ return INVALID_SB_SUBVERSION;
+ n = n << 4 | (str[i] - '0');
+ }
+ return n;
+}
+
+bool db_parse_sb_version(struct sb_version_t *ver, char *str)
+{
+ int len = strlen(str);
+ int cnt = 0;
+ int pos[2];
+
+ for(int i = 0; i < len; i++)
+ {
+ if(str[i] != '.')
+ continue;
+ if(cnt == 2)
+ return false;
+ pos[cnt++] = i + 1;
+ str[i] = 0;
+ }
+ if(cnt != 2)
+ return false;
+ ver->major = parse_sb_subversion(str);
+ ver->minor = parse_sb_subversion(str + pos[0]);
+ ver->revision = parse_sb_subversion(str + pos[1]);
+ return ver->major != INVALID_SB_SUBVERSION &&
+ ver->minor != INVALID_SB_SUBVERSION &&
+ ver->revision != INVALID_SB_SUBVERSION;
+}
+
+#undef parse_error
+#define parse_error(lexem, ...) \
+ do { fprintf(stderr, "%s:%d: ", lexem.file, lexem.line); \
+ fprintf(stderr, __VA_ARGS__); exit(2); } while(0)
+
+struct cmd_file_t *db_parse_file(const char *file)
+{
+ size_t size;
+ FILE *f = fopen(file, "r");
+ if(f == NULL)
+ bugp("Cannot open file '%s'", file);
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ char *buf = xmalloc(size);
+ if(fread(buf, size, 1, f) != 1)
+ bugp("Cannot read file '%s'", file);
+ fclose(f);
+
+ if(g_debug)
+ printf("Parsing db file '%s'\n", file);
+ struct cmd_file_t *cmd_file = xmalloc(sizeof(struct cmd_file_t));
+ memset(cmd_file, 0, sizeof(struct cmd_file_t));
+
+ generate_default_version(&cmd_file->product_ver);
+ generate_default_version(&cmd_file->component_ver);
+
+ struct lexem_t lexem;
+ struct context_t ctx;
+ ctx.file = file;
+ ctx.line = 1;
+ ctx.begin = buf;
+ ctx.ptr = buf;
+ ctx.end = buf + size;
+ #define next() next_lexem(&ctx, &lexem)
+ /* init lexer */
+ next();
+ /* options ? */
+ if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "options"))
+ {
+ next();
+ if(lexem.type != LEX_LBRACE)
+ parse_error(lexem, "'{' expected after 'options'\n");
+
+ while(true)
+ {
+ next();
+ if(lexem.type == LEX_RBRACE)
+ break;
+ if(lexem.type != LEX_IDENTIFIER)
+ parse_error(lexem, "Identifier expected in options\n");
+ char *opt = lexem.str;
+ next();
+ if(lexem.type != LEX_EQUAL)
+ parse_error(lexem, "'=' expected after identifier\n");
+ next();
+ if(!strcmp(opt, "productVersion") || !strcmp(opt, "componentVersion"))
+ {
+ if(lexem.type != LEX_STRING)
+ parse_error(lexem, "String expected after '='\n");
+ bool ret;
+ if(!strcmp(opt, "productVersion"))
+ ret = db_parse_sb_version(&cmd_file->product_ver, lexem.str);
+ else
+ ret = db_parse_sb_version(&cmd_file->component_ver, lexem.str);
+ if(!ret)
+ parse_error(lexem, "Invalid product/component version");
+ }
+ else
+ parse_error(lexem, "Unknown option '%s'\n", opt);
+ next();
+ if(lexem.type != LEX_SEMICOLON)
+ parse_error(lexem, "';' expected after string\n");
+ }
+ next();
+ }
+ /* sources */
+ if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources"))
+ parse_error(lexem, "'sources' expected\n");
+ next();
+ if(lexem.type != LEX_LBRACE)
+ parse_error(lexem, "'{' expected after 'sources'\n");
+
+ while(true)
+ {
+ next();
+ if(lexem.type == LEX_RBRACE)
+ break;
+ struct cmd_source_t *src = xmalloc(sizeof(struct cmd_source_t));
+ memset(src, 0, sizeof(struct cmd_source_t));
+ src->next = cmd_file->source_list;
+ if(lexem.type != LEX_IDENTIFIER)
+ parse_error(lexem, "identifier expected in sources\n");
+ src->identifier = lexem.str;
+ next();
+ if(lexem.type != LEX_EQUAL)
+ parse_error(lexem, "'=' expected after identifier\n");
+ next();
+ if(lexem.type != LEX_STRING)
+ parse_error(lexem, "String expected after '='\n");
+ src->filename = lexem.str;
+ next();
+ if(lexem.type != LEX_SEMICOLON)
+ parse_error(lexem, "';' expected after string\n");
+ if(db_find_source_by_id(cmd_file, src->identifier) != NULL)
+ parse_error(lexem, "Duplicate source identifier\n");
+ /* type filled later */
+ src->type = CMD_SRC_UNK;
+ cmd_file->source_list = src;
+ }
+
+ /* sections */
+ struct cmd_section_t *end_sec = NULL;
+ while(true)
+ {
+ struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t));
+ struct cmd_inst_t *end_list = NULL;
+ memset(sec, 0, sizeof(struct cmd_section_t));
+ next();
+ if(lexem.type == LEX_EOF)
+ break;
+ if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0)
+ parse_error(lexem, "'section' expected\n");
+ next();
+ if(lexem.type != LEX_LPAREN)
+ parse_error(lexem, "'(' expected after 'section'\n");
+ next();
+ /* can be a number or a 4 character long string */
+ if(lexem.type == LEX_NUMBER)
+ {
+ sec->identifier = lexem.num;
+ }
+ else
+ parse_error(lexem, "Number expected as section identifier\n");
+
+ next();
+ if(lexem.type != LEX_RPAREN)
+ parse_error(lexem, "')' expected after section identifier\n");
+ next();
+ if(lexem.type != LEX_LBRACE)
+ parse_error(lexem, "'{' expected after section directive\n");
+ /* commands */
+ while(true)
+ {
+ struct cmd_inst_t *inst = xmalloc(sizeof(struct cmd_inst_t));
+ memset(inst, 0, sizeof(struct cmd_inst_t));
+ next();
+ if(lexem.type == LEX_RBRACE)
+ break;
+ if(lexem.type != LEX_IDENTIFIER)
+ parse_error(lexem, "Instruction expected in section\n");
+ if(strcmp(lexem.str, "load") == 0)
+ inst->type = CMD_LOAD;
+ else if(strcmp(lexem.str, "call") == 0)
+ inst->type = CMD_CALL;
+ else if(strcmp(lexem.str, "jump") == 0)
+ inst->type = CMD_JUMP;
+ else if(strcmp(lexem.str, "mode") == 0)
+ inst->type = CMD_MODE;
+ else
+ parse_error(lexem, "Instruction expected in section\n");
+ next();
+
+ if(inst->type == CMD_LOAD)
+ {
+ if(lexem.type != LEX_IDENTIFIER)
+ parse_error(lexem, "Identifier expected after instruction\n");
+ inst->identifier = lexem.str;
+ if(db_find_source_by_id(cmd_file, inst->identifier) == NULL)
+ parse_error(lexem, "Undefined reference to source '%s'\n", inst->identifier);
+ next();
+ if(lexem.type == LEX_RANGLE)
+ {
+ // load at
+ inst->type = CMD_LOAD_AT;
+ next();
+ if(lexem.type != LEX_NUMBER)
+ parse_error(lexem, "Number expected for loading address\n");
+ inst->addr = lexem.num;
+ next();
+ }
+ if(lexem.type != LEX_SEMICOLON)
+ parse_error(lexem, "';' expected after command\n");
+ }
+ else if(inst->type == CMD_CALL || inst->type == CMD_JUMP)
+ {
+ if(lexem.type == LEX_IDENTIFIER)
+ {
+ inst->identifier = lexem.str;
+ if(db_find_source_by_id(cmd_file, inst->identifier) == NULL)
+ parse_error(lexem, "Undefined reference to source '%s'\n", inst->identifier);
+ next();
+ }
+ else if(lexem.type == LEX_NUMBER)
+ {
+ inst->type = (inst->type == CMD_CALL) ? CMD_CALL_AT : CMD_JUMP_AT;
+ inst->addr = lexem.num;
+ next();
+ }
+ else
+ parse_error(lexem, "Identifier or number expected after jump/load\n");
+
+ if(lexem.type == LEX_LPAREN)
+ {
+ next();
+ if(lexem.type != LEX_NUMBER)
+ parse_error(lexem, "Expected numeral expression after (\n");
+ inst->argument = lexem.num;
+ next();
+ if(lexem.type != LEX_RPAREN)
+ parse_error(lexem, "Expected closing brace\n");
+ next();
+ }
+ if(lexem.type != LEX_SEMICOLON)
+ parse_error(lexem, "Expected ';' after command\n");
+ }
+ else if(inst->type == CMD_MODE)
+ {
+ if(lexem.type != LEX_NUMBER)
+ parse_error(lexem, "Number expected after 'mode'\n");
+ inst->argument = lexem.num;
+ next();
+ if(lexem.type != LEX_SEMICOLON)
+ parse_error(lexem, "Expected ';' after command\n");
+ }
+ else
+ parse_error(lexem, "Internal error");
+ if(end_list == NULL)
+ {
+ sec->inst_list = inst;
+ end_list = inst;
+ }
+ else
+ {
+ end_list->next = inst;
+ end_list = inst;
+ }
+ }
+
+ if(end_sec == NULL)
+ {
+ cmd_file->section_list = sec;
+ end_sec = sec;
+ }
+ else
+ {
+ end_sec->next = sec;
+ end_sec = sec;
+ }
+ }
+ #undef next
+
+ return cmd_file;
+}
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __DBPARSER__
+#define __DBPARSER__
+
+/**
+ * Command file parsing
+ */
+#include "sb.h"
+#include "elf.h"
+
+enum cmd_source_type_t
+{
+ CMD_SRC_UNK,
+ CMD_SRC_ELF,
+ CMD_SRC_BIN
+};
+
+struct bin_param_t
+{
+ uint32_t size;
+ void *data;
+};
+
+struct cmd_source_t
+{
+ char *identifier;
+ char *filename;
+ struct cmd_source_t *next;
+ /* for later use */
+ enum cmd_source_type_t type;
+ bool loaded;
+ struct elf_params_t elf;
+ struct bin_param_t bin;
+};
+
+enum cmd_inst_type_t
+{
+ CMD_LOAD, /* load image */
+ CMD_JUMP, /* jump at image */
+ CMD_CALL, /* call image */
+ CMD_LOAD_AT, /* load binary at */
+ CMD_CALL_AT, /* call at address */
+ CMD_JUMP_AT, /* jump at address */
+ CMD_MODE, /* change boot mode */
+};
+
+struct cmd_inst_t
+{
+ enum cmd_inst_type_t type;
+ char *identifier;
+ uint32_t argument; // for jump, call, mode
+ uint32_t addr; // for 'at'
+ struct cmd_inst_t *next;
+};
+
+struct cmd_section_t
+{
+ uint32_t identifier;
+ struct cmd_inst_t *inst_list;
+ struct cmd_section_t *next;
+};
+
+struct cmd_file_t
+{
+ struct sb_version_t product_ver;
+ struct sb_version_t component_ver;
+ struct cmd_source_t *source_list;
+ struct cmd_section_t *section_list;
+};
+
+struct cmd_source_t *db_find_source_by_id(struct cmd_file_t *cmd_file, const char *id);
+bool db_parse_sb_version(struct sb_version_t *ver, char *str);
+struct cmd_file_t *db_parse_file(const char *file);
+
+#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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
#include "elf.h"
/**
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 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __ELF_H__
+#define __ELF_H__
+
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -67,3 +90,5 @@ void elf_set_start_addr(struct elf_params_t *params, uint32_t addr);
bool elf_get_start_addr(struct elf_params_t *params, uint32_t *addr);
int elf_get_nr_sections(struct elf_params_t *params);
void elf_release(struct elf_params_t *params);
+
+#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 @@
#include "crypto.h"
#include "elf.h"
#include "sb.h"
+#include "dbparser.h"
#define _STR(a) #a
#define STR(a) _STR(a)
@@ -76,7 +77,7 @@ void *xmalloc(size_t s) /* malloc helper, used in elf.c */
return r;
}
-static int convxdigit(char digit, byte *val)
+int convxdigit(char digit, byte *val)
{
if(digit >= '0' && digit <= '9')
{
@@ -164,582 +165,6 @@ static key_array_t read_keys(const char *key_file, int *num_keys)
}
/**
- * Command file parsing
- */
-
-enum cmd_source_type_t
-{
- CMD_SRC_UNK,
- CMD_SRC_ELF,
- CMD_SRC_BIN
-};
-
-struct bin_param_t
-{
- uint32_t size;
- void *data;
-};
-
-struct cmd_source_t
-{
- char *identifier;
- char *filename;
- struct cmd_source_t *next;
- /* for later use */
- enum cmd_source_type_t type;
- bool loaded;
- struct elf_params_t elf;
- struct bin_param_t bin;
-};
-
-enum cmd_inst_type_t
-{
- CMD_LOAD, /* load image */
- CMD_JUMP, /* jump at image */
- CMD_CALL, /* call image */
- CMD_LOAD_AT, /* load binary at */
- CMD_CALL_AT, /* call at address */
- CMD_JUMP_AT, /* jump at address */
- CMD_MODE, /* change boot mode */
-};
-
-struct cmd_inst_t
-{
- enum cmd_inst_type_t type;
- char *identifier;
- uint32_t argument; // for jump, call, mode
- uint32_t addr; // for 'at'
- struct cmd_inst_t *next;
-};
-
-struct cmd_section_t
-{
- uint32_t identifier;
- struct cmd_inst_t *inst_list;
- struct cmd_section_t *next;
-};
-
-struct cmd_file_t
-{
- struct sb_version_t product_ver;
- struct sb_version_t component_ver;
- struct cmd_source_t *source_list;
- struct cmd_section_t *section_list;
-};
-
-enum lexem_type_t
-{
- LEX_IDENTIFIER,
- LEX_LPAREN,
- LEX_RPAREN,
- LEX_NUMBER,
- LEX_STRING, /* double-quoted string */
- LEX_EQUAL,
- LEX_SEMICOLON,
- LEX_LBRACE,
- LEX_RBRACE,
- LEX_RANGLE,
- LEX_EOF
-};
-
-struct lexem_t
-{
- enum lexem_type_t type;
- char *str;
- uint32_t num;
-};
-
-static void __parse_string(char **ptr, char *end, void *user, void (*emit_fn)(void *user, char c))
-{
- while(*ptr != end)
- {
- if(**ptr == '"')
- break;
- else if(**ptr == '\\')
- {
- (*ptr)++;
- if(*ptr == end)
- bug("Unfinished string\n");
- if(**ptr == '\\') emit_fn(user, '\\');
- else if(**ptr == '\'') emit_fn(user, '\'');
- else if(**ptr == '\"') emit_fn(user, '\"');
- else bug("Unknown escape sequence \\%c\n", **ptr);
- (*ptr)++;
- }
- else
- emit_fn(user, *(*ptr)++);
- }
- if(*ptr == end || **ptr != '"')
- bug("unfinished string\n");
- (*ptr)++;
-}
-
-static void __parse_string_emit(void *user, char c)
-{
- char **pstr = (char **)user;
- *(*pstr)++ = c;
-}
-
-static void __parse_string_count(void *user, char c)
-{
- (void) c;
- (*(int *)user)++;
-}
-
-static void parse_string(char **ptr, char *end, struct lexem_t *lexem)
-{
- /* skip " */
- (*ptr)++;
- char *p = *ptr;
- /* compute length */
- int length = 0;
- __parse_string(&p, end, (void *)&length, __parse_string_count);
- /* parse again */
- lexem->type = LEX_STRING;
- lexem->str = xmalloc(length + 1);
- lexem->str[length] = 0;
- char *pstr = lexem->str;
- __parse_string(ptr, end, (void *)&pstr, __parse_string_emit);
-}
-
-static void parse_ascii_number(char **ptr, char *end, struct lexem_t *lexem)
-{
- /* skip ' */
- (*ptr)++;
- /* we expect 4 character and then ' */
- int len = 0;
- uint32_t value = 0;
- while(*ptr != end)
- {
- if(**ptr != '\'')
- {
- value = value << 8 | **ptr;
- len++;
- (*ptr)++;
- }
- else
- break;
- }
- if(*ptr == end || **ptr != '\'')
- bug("Unterminated ascii number literal\n");
- if(len != 1 && len != 2 && len != 4)
- bug("Invalid ascii number literal length: only 1, 2 or 4 are valid\n");
- /* skip ' */
- (*ptr)++;
- lexem->type = LEX_NUMBER;
- lexem->num = value;
-}
-
-static void parse_number(char **ptr, char *end, struct lexem_t *lexem)
-{
- int base = 10;
- if(**ptr == '0' && (*ptr) + 1 != end && (*ptr)[1] == 'x')
- {
- (*ptr) += 2;
- base = 16;
- }
-
- lexem->type = LEX_NUMBER;
- lexem->num = 0;
- while(*ptr != end && isxdigit(**ptr))
- {
- if(base == 10 && !isdigit(**ptr))
- break;
- byte v;
- if(convxdigit(**ptr, &v))
- break;
- lexem->num = base * lexem->num + v;
- (*ptr)++;
- }
-}
-
-static void parse_identifier(char **ptr, char *end, struct lexem_t *lexem)
-{
- /* remember position */
- char *old = *ptr;
- while(*ptr != end && (isalnum(**ptr) || **ptr == '_'))
- (*ptr)++;
- lexem->type = LEX_IDENTIFIER;
- int len = *ptr - old;
- lexem->str = xmalloc(len + 1);
- lexem->str[len] = 0;
- memcpy(lexem->str, old, len);
-}
-
-static void next_lexem(char **ptr, char *end, struct lexem_t *lexem)
-{
- #define ret_simple(t, advance) ({(*ptr) += advance; lexem->type = t; return;})
- while(*ptr != end)
- {
- /* skip whitespace */
- if(**ptr == ' ' || **ptr == '\t' || **ptr == '\n' || **ptr == '\r')
- {
- (*ptr)++;
- continue;
- }
- /* skip C++ style comments */
- if(**ptr == '/' && (*ptr) + 1 != end && (*ptr)[1] == '/')
- {
- while(*ptr != end && **ptr != '\n')
- (*ptr)++;
- continue;
- }
- /* skip C-style comments */
- if(**ptr == '/' && (*ptr) + 1 != end && (*ptr)[1] == '*')
- {
- (*ptr) += 2;
- if(*ptr == end)
- bug("invalid command file: unterminated comment");
- while(true)
- {
- if(**ptr == '*' && (*ptr) + 1 != end && (*ptr)[1] == '/')
- {
- (*ptr) += 2;
- break;
- }
- (*ptr)++;
- }
- continue;
- }
- break;
- }
- if(*ptr == end) ret_simple(LEX_EOF, 0);
- if(**ptr == '(') ret_simple(LEX_LPAREN, 1);
- if(**ptr == ')') ret_simple(LEX_RPAREN, 1);
- if(**ptr == '{') ret_simple(LEX_LBRACE, 1);
- if(**ptr == '}') ret_simple(LEX_RBRACE, 1);
- if(**ptr == '>') ret_simple(LEX_RANGLE, 1);
- if(**ptr == '=') ret_simple(LEX_EQUAL, 1);
- if(**ptr == ';') ret_simple(LEX_SEMICOLON, 1);
- if(**ptr == '"') return parse_string(ptr, end, lexem);
- if(**ptr == '\'') return parse_ascii_number(ptr, end, lexem);
- if(isdigit(**ptr)) return parse_number(ptr, end, lexem);
- if(isalpha(**ptr) || **ptr == '_') return parse_identifier(ptr, end, lexem);
- bug("Unexpected character '%c' in command file\n", **ptr);
- #undef ret_simple
-}
-
-#if 0
-static void log_lexem(struct lexem_t *lexem)
-{
- switch(lexem->type)
- {
- case LEX_EOF: printf("<eof>"); break;
- case LEX_EQUAL: printf("="); break;
- case LEX_IDENTIFIER: printf("id(%s)", lexem->str); break;
- case LEX_LPAREN: printf("("); break;
- case LEX_RPAREN: printf(")"); break;
- case LEX_LBRACE: printf("{"); break;
- case LEX_RBRACE: printf("}"); break;
- case LEX_SEMICOLON: printf(";"); break;
- case LEX_NUMBER: printf("num(%d)", lexem->num); break;
- case LEX_STRING: printf("str(%s)", lexem->str); break;
- default: printf("<unk>");
- }
-}
-#endif
-
-static struct cmd_source_t *find_source_by_id(struct cmd_file_t *cmd_file, const char *id)
-{
- struct cmd_source_t *src = cmd_file->source_list;
- while(src)
- {
- if(strcmp(src->identifier, id) == 0)
- return src;
- src = src->next;
- }
- return NULL;
-}
-
-static void generate_default_version(struct sb_version_t *ver)
-{
- ver->major = 0x999;
- ver->minor = 0x999;
- ver->revision = 0x999;
-}
-
-static uint16_t parse_sb_subversion(char *str)
-{
- int len = strlen(str);
- uint16_t n = 0;
- if(len == 0 || len > 4)
- bug("invalid command file: invalid version string");
- for(int i = 0; i < len; i++)
- {
- if(!isdigit(str[i]))
- bug("invalid command file: invalid version string");
- n = n << 4 | (str[i] - '0');
- }
- return n;
-}
-
-static void parse_sb_version(struct sb_version_t *ver, char *str)
-{
- int len = strlen(str);
- int cnt = 0;
- int pos[2];
-
- for(int i = 0; i < len; i++)
- {
- if(str[i] != '.')
- continue;
- if(cnt == 2)
- bug("invalid command file: invalid version string");
- pos[cnt++] = i + 1;
- str[i] = 0;
- }
- if(cnt != 2)
- bug("invalid command file: invalid version string");
- ver->major = parse_sb_subversion(str);
- ver->minor = parse_sb_subversion(str + pos[0]);
- ver->revision = parse_sb_subversion(str + pos[1]);
-}
-
-static struct cmd_file_t *read_command_file(const char *file)
-{
- int size;
- struct stat st;
- int fd = open(file,O_RDONLY);
- if(fd == -1)
- bugp("opening command file failed");
- if(fstat(fd,&st) == -1)
- bugp("command file stat() failed");
- size = st.st_size;
- char *buf = xmalloc(size);
- if(read(fd, buf, size) != (ssize_t)size)
- bugp("reading command file");
- close(fd);
-
- if(g_debug)
- printf("Parsing command file '%s'...\n", file);
- struct cmd_file_t *cmd_file = xmalloc(sizeof(struct cmd_file_t));
- memset(cmd_file, 0, sizeof(struct cmd_file_t));
-
- generate_default_version(&cmd_file->product_ver);
- generate_default_version(&cmd_file->component_ver);
-
- struct lexem_t lexem;
- char *p = buf;
- char *end = buf + size;
- #define next() next_lexem(&p, end, &lexem)
- /* init lexer */
- next();
- /* options ? */
- if(lexem.type == LEX_IDENTIFIER && !strcmp(lexem.str, "options"))
- {
- next();
- if(lexem.type != LEX_LBRACE)
- bug("invalid command file: '{' expected after 'options'\n");
-
- while(true)
- {
- next();
- if(lexem.type == LEX_RBRACE)
- break;
- if(lexem.type != LEX_IDENTIFIER)
- bug("invalid command file: identifier expected in options\n");
- char *opt = lexem.str;
- next();
- if(lexem.type != LEX_EQUAL)
- bug("invalid command file: '=' expected after identifier\n");
- next();
- if(!strcmp(opt, "productVersion") || !strcmp(opt, "componentVersion"))
- {
- if(lexem.type != LEX_STRING)
- bug("invalid command file: string expected after '='\n");
- if(!strcmp(opt, "productVersion"))
- parse_sb_version(&cmd_file->product_ver, lexem.str);
- else
- parse_sb_version(&cmd_file->component_ver, lexem.str);
- }
- else
- bug("invalid command file: unknown option '%s'\n", opt);
- next();
- if(lexem.type != LEX_SEMICOLON)
- bug("invalid command file: ';' expected after string\n");
- }
- next();
- }
- /* sources */
- if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources") != 0)
- bug("invalid command file: 'sources' expected\n");
- next();
- if(lexem.type != LEX_LBRACE)
- bug("invalid command file: '{' expected after 'sources'\n");
-
- while(true)
- {
- next();
- if(lexem.type == LEX_RBRACE)
- break;
- struct cmd_source_t *src = xmalloc(sizeof(struct cmd_source_t));
- memset(src, 0, sizeof(struct cmd_source_t));
- src->next = cmd_file->source_list;
- if(lexem.type != LEX_IDENTIFIER)
- bug("invalid command file: identifier expected in sources\n");
- src->identifier = lexem.str;
- next();
- if(lexem.type != LEX_EQUAL)
- bug("invalid command file: '=' expected after identifier\n");
- next();
- if(lexem.type != LEX_STRING)
- bug("invalid command file: string expected after '='\n");
- src->filename = lexem.str;
- next();
- if(lexem.type != LEX_SEMICOLON)
- bug("invalid command file: ';' expected after string\n");
- if(find_source_by_id(cmd_file, src->identifier) != NULL)
- bug("invalid command file: duplicated source identifier\n");
- /* type filled later */
- src->type = CMD_SRC_UNK;
- cmd_file->source_list = src;
- }
-
- /* sections */
- struct cmd_section_t *end_sec = NULL;
- while(true)
- {
- struct cmd_section_t *sec = xmalloc(sizeof(struct cmd_section_t));
- struct cmd_inst_t *end_list = NULL;
- memset(sec, 0, sizeof(struct cmd_section_t));
- next();
- if(lexem.type == LEX_EOF)
- break;
- if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0)
- bug("invalid command file: 'section' expected\n");
- next();
- if(lexem.type != LEX_LPAREN)
- bug("invalid command file: '(' expected after 'section'\n");
- next();
- /* can be a number or a 4 character long string */
- if(lexem.type == LEX_NUMBER)
- {
- sec->identifier = lexem.num;
- }
- else
- bug("invalid command file: number expected as section identifier\n");
-
- next();
- if(lexem.type != LEX_RPAREN)
- bug("invalid command file: ')' expected after section identifier\n");
- next();
- if(lexem.type != LEX_LBRACE)
- bug("invalid command file: '{' expected after section directive\n");
- /* commands */
- while(true)
- {
- struct cmd_inst_t *inst = xmalloc(sizeof(struct cmd_inst_t));
- memset(inst, 0, sizeof(struct cmd_inst_t));
- next();
- if(lexem.type == LEX_RBRACE)
- break;
- if(lexem.type != LEX_IDENTIFIER)
- bug("invalid command file: instruction expected in section\n");
- if(strcmp(lexem.str, "load") == 0)
- inst->type = CMD_LOAD;
- else if(strcmp(lexem.str, "call") == 0)
- inst->type = CMD_CALL;
- else if(strcmp(lexem.str, "jump") == 0)
- inst->type = CMD_JUMP;
- else if(strcmp(lexem.str, "mode") == 0)
- inst->type = CMD_MODE;
- else
- bug("invalid command file: instruction expected in section\n");
- next();
-
- if(inst->type == CMD_LOAD)
- {
- if(lexem.type != LEX_IDENTIFIER)
- bug("invalid command file: identifier expected after instruction\n");
- inst->identifier = lexem.str;
- if(find_source_by_id(cmd_file, inst->identifier) == NULL)
- bug("invalid command file: undefined reference to source '%s'\n", inst->identifier);
- next();
- if(lexem.type == LEX_RANGLE)
- {
- // load at
- inst->type = CMD_LOAD_AT;
- next();
- if(lexem.type != LEX_NUMBER)
- bug("invalid command file: number expected for loading address\n");
- inst->addr = lexem.num;
- next();
- }
- if(lexem.type != LEX_SEMICOLON)
- bug("invalid command file: expected ';' after command\n");
- }
- else if(inst->type == CMD_CALL || inst->type == CMD_JUMP)
- {
- if(lexem.type == LEX_IDENTIFIER)
- {
- inst->identifier = lexem.str;
- if(find_source_by_id(cmd_file, inst->identifier) == NULL)
- bug("invalid command file: undefined reference to source '%s'\n", inst->identifier);
- next();
- }
- else if(lexem.type == LEX_NUMBER)
- {
- inst->type = (inst->type == CMD_CALL) ? CMD_CALL_AT : CMD_JUMP_AT;
- inst->addr = lexem.num;
- next();
- }
- else
- bug("invalid command file: identifier or number expected after jump/load\n");
-
- if(lexem.type == LEX_LPAREN)
- {
- next();
- if(lexem.type != LEX_NUMBER)
- bug("invalid command file: expected numeral expression after (\n");
- inst->argument = lexem.num;
- next();
- if(lexem.type != LEX_RPAREN)
- bug("invalid command file: expected closing brace\n");
- next();
- }
- if(lexem.type != LEX_SEMICOLON)
- bug("invalid command file: expected ';' after command\n");
- }
- else if(inst->type == CMD_MODE)
- {
- if(lexem.type != LEX_NUMBER)
- bug("invalid command file: number expected after 'mode'\n");
- inst->argument = lexem.num;
- next();
- if(lexem.type != LEX_SEMICOLON)
- bug("invalid command file: expected ';' after command\n");
- }
- else
- bug("die\n");
- if(end_list == NULL)
- {
- sec->inst_list = inst;
- end_list = inst;
- }
- else
- {
- end_list->next = inst;
- end_list = inst;
- }
- }
-
- if(end_sec == NULL)
- {
- cmd_file->section_list = sec;
- end_sec = sec;
- }
- else
- {
- end_sec->next = sec;
- end_sec = sec;
- }
- }
- #undef next
-
- return cmd_file;
-}
-
-/**
* command file to sb conversion
*/
@@ -798,7 +223,7 @@ static void elf_printf(void *user, bool error, const char *fmt, ...)
static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
{
- struct cmd_source_t *src = find_source_by_id(cmd_file, id);
+ struct cmd_source_t *src = db_find_source_by_id(cmd_file, id);
if(src == NULL)
bug("undefined reference to source '%s'\n", id);
/* avoid reloading */
@@ -822,7 +247,7 @@ static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
static void load_bin_by_id(struct cmd_file_t *cmd_file, const char *id)
{
- struct cmd_source_t *src = find_source_by_id(cmd_file, id);
+ struct cmd_source_t *src = db_find_source_by_id(cmd_file, id);
if(src == NULL)
bug("undefined reference to source '%s'\n", id);
/* avoid reloading */
@@ -877,13 +302,13 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
if(cinst->type == CMD_LOAD)
{
load_elf_by_id(cmd_file, cinst->identifier);
- struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf;
+ struct elf_params_t *elf = &db_find_source_by_id(cmd_file, cinst->identifier)->elf;
sec->nr_insts += elf_get_nr_sections(elf);
}
else if(cinst->type == CMD_JUMP || cinst->type == CMD_CALL)
{
load_elf_by_id(cmd_file, cinst->identifier);
- struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf;
+ struct elf_params_t *elf = &db_find_source_by_id(cmd_file, cinst->identifier)->elf;
if(!elf_get_start_addr(elf, NULL))
bug("cannot jump/call '%s' because it has no starting point !\n", cinst->identifier);
sec->nr_insts++;
@@ -916,7 +341,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
{
if(cinst->type == CMD_LOAD)
{
- struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf;
+ struct elf_params_t *elf = &db_find_source_by_id(cmd_file, cinst->identifier)->elf;
struct elf_section_t *esec = elf->first_section;
while(esec)
{
@@ -939,7 +364,7 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
}
else if(cinst->type == CMD_JUMP || cinst->type == CMD_CALL)
{
- struct elf_params_t *elf = &find_source_by_id(cmd_file, cinst->identifier)->elf;
+ struct elf_params_t *elf = &db_find_source_by_id(cmd_file, cinst->identifier)->elf;
sec->insts[idx].argument = cinst->argument;
sec->insts[idx].inst = (cinst->type == CMD_JUMP) ? SB_INST_JUMP : SB_INST_CALL;
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)
}
else if(cinst->type == CMD_LOAD_AT)
{
- struct bin_param_t *bin = &find_source_by_id(cmd_file, cinst->identifier)->bin;
+ struct bin_param_t *bin = &db_find_source_by_id(cmd_file, cinst->identifier)->bin;
sec->insts[idx].inst = SB_INST_LOAD;
sec->insts[idx].addr = cinst->addr;
sec->insts[idx].data = bin->data;
@@ -1294,7 +719,7 @@ int main(int argc, const char **argv)
g_debug = true;
g_key_array = read_keys(argv[2], &g_nr_keys);
- struct cmd_file_t *cmd_file = read_command_file(argv[1]);
+ struct cmd_file_t *cmd_file = db_parse_file(argv[1]);
struct sb_file_t *sb_file = apply_cmd_file(cmd_file);
produce_sb_file(sb_file, argv[3]);
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 @@
* KIND, either express or implied.
*
****************************************************************************/
+#ifndef __SB_H__
+#define __SB_H__
#include <stdint.h>
@@ -147,3 +149,5 @@ struct sb_instruction_tag_t
uint32_t len; /* length of the section */
uint32_t flags; /* section flags */
} __attribute__((packed));
+
+#endif /* __SB_H__ */