summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/sbtools/elftosb.c137
-rw-r--r--utils/sbtools/sbtoelf.c20
2 files changed, 114 insertions, 43 deletions
diff --git a/utils/sbtools/elftosb.c b/utils/sbtools/elftosb.c
index 7a0c67e53b..601321d9c0 100644
--- a/utils/sbtools/elftosb.c
+++ b/utils/sbtools/elftosb.c
@@ -38,7 +38,10 @@
38#include "elf.h" 38#include "elf.h"
39#include "sb.h" 39#include "sb.h"
40 40
41#define bug(...) do { fprintf(stderr,"ERROR: "__VA_ARGS__); exit(1); } while(0) 41#define _STR(a) #a
42#define STR(a) _STR(a)
43
44#define bug(...) do { fprintf(stderr,"["__FILE__":"STR(__LINE__)"]ERROR: "__VA_ARGS__); exit(1); } while(0)
42#define bugp(a) do { perror("ERROR: "a); exit(1); } while(0) 45#define bugp(a) do { perror("ERROR: "a); exit(1); } while(0)
43 46
44bool g_debug = false; 47bool g_debug = false;
@@ -197,13 +200,14 @@ enum cmd_inst_type_t
197 CMD_LOAD_AT, /* load binary at */ 200 CMD_LOAD_AT, /* load binary at */
198 CMD_CALL_AT, /* call at address */ 201 CMD_CALL_AT, /* call at address */
199 CMD_JUMP_AT, /* jump at address */ 202 CMD_JUMP_AT, /* jump at address */
203 CMD_MODE, /* change boot mode */
200}; 204};
201 205
202struct cmd_inst_t 206struct cmd_inst_t
203{ 207{
204 enum cmd_inst_type_t type; 208 enum cmd_inst_type_t type;
205 char *identifier; 209 char *identifier;
206 uint32_t argument; // for jump, call 210 uint32_t argument; // for jump, call, mode
207 uint32_t addr; // for 'at' 211 uint32_t addr; // for 'at'
208 struct cmd_inst_t *next; 212 struct cmd_inst_t *next;
209}; 213};
@@ -253,18 +257,18 @@ static void __parse_string(char **ptr, char *end, void *user, void (*emit_fn)(vo
253 { 257 {
254 (*ptr)++; 258 (*ptr)++;
255 if(*ptr == end) 259 if(*ptr == end)
256 bug("Unfinished string"); 260 bug("Unfinished string\n");
257 if(**ptr == '\\') emit_fn(user, '\\'); 261 if(**ptr == '\\') emit_fn(user, '\\');
258 else if(**ptr == '\'') emit_fn(user, '\''); 262 else if(**ptr == '\'') emit_fn(user, '\'');
259 else if(**ptr == '\"') emit_fn(user, '\"'); 263 else if(**ptr == '\"') emit_fn(user, '\"');
260 else bug("Unknown escape sequence \\%c", **ptr); 264 else bug("Unknown escape sequence \\%c\n", **ptr);
261 (*ptr)++; 265 (*ptr)++;
262 } 266 }
263 else 267 else
264 emit_fn(user, *(*ptr)++); 268 emit_fn(user, *(*ptr)++);
265 } 269 }
266 if(*ptr == end || **ptr != '"') 270 if(*ptr == end || **ptr != '"')
267 bug("unfinished string"); 271 bug("unfinished string\n");
268 (*ptr)++; 272 (*ptr)++;
269} 273}
270 274
@@ -315,9 +319,9 @@ static void parse_ascii_number(char **ptr, char *end, struct lexem_t *lexem)
315 break; 319 break;
316 } 320 }
317 if(*ptr == end || **ptr != '\'') 321 if(*ptr == end || **ptr != '\'')
318 bug("Unterminated ascii number literal"); 322 bug("Unterminated ascii number literal\n");
319 if(len != 1 && len != 2 && len != 4) 323 if(len != 1 && len != 2 && len != 4)
320 bug("Invalid ascii number literal length: only 1, 2 or 4 are valid"); 324 bug("Invalid ascii number literal length: only 1, 2 or 4 are valid\n");
321 /* skip ' */ 325 /* skip ' */
322 (*ptr)++; 326 (*ptr)++;
323 lexem->type = LEX_NUMBER; 327 lexem->type = LEX_NUMBER;
@@ -371,13 +375,30 @@ static void next_lexem(char **ptr, char *end, struct lexem_t *lexem)
371 (*ptr)++; 375 (*ptr)++;
372 continue; 376 continue;
373 } 377 }
374 /* skip comments */ 378 /* skip C++ style comments */
375 if(**ptr == '/' && (*ptr) + 1 != end && (*ptr)[1] == '/') 379 if(**ptr == '/' && (*ptr) + 1 != end && (*ptr)[1] == '/')
376 { 380 {
377 while(*ptr != end && **ptr != '\n') 381 while(*ptr != end && **ptr != '\n')
378 (*ptr)++; 382 (*ptr)++;
379 continue; 383 continue;
380 } 384 }
385 /* skip C-style comments */
386 if(**ptr == '/' && (*ptr) + 1 != end && (*ptr)[1] == '*')
387 {
388 (*ptr) += 2;
389 if(*ptr == end)
390 bug("invalid command file: unterminated comment");
391 while(true)
392 {
393 if(**ptr == '*' && (*ptr) + 1 != end && (*ptr)[1] == '/')
394 {
395 (*ptr) += 2;
396 break;
397 }
398 (*ptr)++;
399 }
400 continue;
401 }
381 break; 402 break;
382 } 403 }
383 if(*ptr == end) ret_simple(LEX_EOF, 0); 404 if(*ptr == end) ret_simple(LEX_EOF, 0);
@@ -455,10 +476,10 @@ static struct cmd_file_t *read_command_file(const char *file)
455 /* sources */ 476 /* sources */
456 next(); 477 next();
457 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources") != 0) 478 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "sources") != 0)
458 bug("invalid command file: 'sources' expected"); 479 bug("invalid command file: 'sources' expected\n");
459 next(); 480 next();
460 if(lexem.type != LEX_LBRACE) 481 if(lexem.type != LEX_LBRACE)
461 bug("invalid command file: '{' expected after 'sources'"); 482 bug("invalid command file: '{' expected after 'sources'\n");
462 483
463 while(true) 484 while(true)
464 { 485 {
@@ -469,20 +490,20 @@ static struct cmd_file_t *read_command_file(const char *file)
469 memset(src, 0, sizeof(struct cmd_source_t)); 490 memset(src, 0, sizeof(struct cmd_source_t));
470 src->next = cmd_file->source_list; 491 src->next = cmd_file->source_list;
471 if(lexem.type != LEX_IDENTIFIER) 492 if(lexem.type != LEX_IDENTIFIER)
472 bug("invalid command file: identifier expected in sources"); 493 bug("invalid command file: identifier expected in sources\n");
473 src->identifier = lexem.str; 494 src->identifier = lexem.str;
474 next(); 495 next();
475 if(lexem.type != LEX_EQUAL) 496 if(lexem.type != LEX_EQUAL)
476 bug("invalid command file: '=' expected after identifier"); 497 bug("invalid command file: '=' expected after identifier\n");
477 next(); 498 next();
478 if(lexem.type != LEX_STRING) 499 if(lexem.type != LEX_STRING)
479 bug("invalid command file: string expected after '='"); 500 bug("invalid command file: string expected after '='\n");
480 src->filename = lexem.str; 501 src->filename = lexem.str;
481 next(); 502 next();
482 if(lexem.type != LEX_SEMICOLON) 503 if(lexem.type != LEX_SEMICOLON)
483 bug("invalid command file: ';' expected after string"); 504 bug("invalid command file: ';' expected after string\n");
484 if(find_source_by_id(cmd_file, src->identifier) != NULL) 505 if(find_source_by_id(cmd_file, src->identifier) != NULL)
485 bug("invalid command file: duplicated source identifier"); 506 bug("invalid command file: duplicated source identifier\n");
486 /* type filled later */ 507 /* type filled later */
487 src->type = CMD_SRC_UNK; 508 src->type = CMD_SRC_UNK;
488 cmd_file->source_list = src; 509 cmd_file->source_list = src;
@@ -499,10 +520,10 @@ static struct cmd_file_t *read_command_file(const char *file)
499 if(lexem.type == LEX_EOF) 520 if(lexem.type == LEX_EOF)
500 break; 521 break;
501 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0) 522 if(lexem.type != LEX_IDENTIFIER || strcmp(lexem.str, "section") != 0)
502 bug("invalid command file: 'section' expected"); 523 bug("invalid command file: 'section' expected\n");
503 next(); 524 next();
504 if(lexem.type != LEX_LPAREN) 525 if(lexem.type != LEX_LPAREN)
505 bug("invalid command file: '(' expected after 'section'"); 526 bug("invalid command file: '(' expected after 'section'\n");
506 next(); 527 next();
507 /* can be a number or a 4 character long string */ 528 /* can be a number or a 4 character long string */
508 if(lexem.type == LEX_NUMBER) 529 if(lexem.type == LEX_NUMBER)
@@ -510,14 +531,14 @@ static struct cmd_file_t *read_command_file(const char *file)
510 sec->identifier = lexem.num; 531 sec->identifier = lexem.num;
511 } 532 }
512 else 533 else
513 bug("invalid command file: number expected as section identifier"); 534 bug("invalid command file: number expected as section identifier\n");
514 535
515 next(); 536 next();
516 if(lexem.type != LEX_RPAREN) 537 if(lexem.type != LEX_RPAREN)
517 bug("invalid command file: ')' expected after section identifier"); 538 bug("invalid command file: ')' expected after section identifier\n");
518 next(); 539 next();
519 if(lexem.type != LEX_LBRACE) 540 if(lexem.type != LEX_LBRACE)
520 bug("invalid command file: '{' expected after section directive"); 541 bug("invalid command file: '{' expected after section directive\n");
521 /* commands */ 542 /* commands */
522 while(true) 543 while(true)
523 { 544 {
@@ -527,24 +548,26 @@ static struct cmd_file_t *read_command_file(const char *file)
527 if(lexem.type == LEX_RBRACE) 548 if(lexem.type == LEX_RBRACE)
528 break; 549 break;
529 if(lexem.type != LEX_IDENTIFIER) 550 if(lexem.type != LEX_IDENTIFIER)
530 bug("invalid command file: instruction expected in section"); 551 bug("invalid command file: instruction expected in section\n");
531 if(strcmp(lexem.str, "load") == 0) 552 if(strcmp(lexem.str, "load") == 0)
532 inst->type = CMD_LOAD; 553 inst->type = CMD_LOAD;
533 else if(strcmp(lexem.str, "call") == 0) 554 else if(strcmp(lexem.str, "call") == 0)
534 inst->type = CMD_CALL; 555 inst->type = CMD_CALL;
535 else if(strcmp(lexem.str, "jump") == 0) 556 else if(strcmp(lexem.str, "jump") == 0)
536 inst->type = CMD_JUMP; 557 inst->type = CMD_JUMP;
558 else if(strcmp(lexem.str, "mode") == 0)
559 inst->type = CMD_MODE;
537 else 560 else
538 bug("invalid command file: instruction expected in section"); 561 bug("invalid command file: instruction expected in section\n");
539 next(); 562 next();
540 563
541 if(inst->type == CMD_LOAD) 564 if(inst->type == CMD_LOAD)
542 { 565 {
543 if(lexem.type != LEX_IDENTIFIER) 566 if(lexem.type != LEX_IDENTIFIER)
544 bug("invalid command file: identifier expected after instruction"); 567 bug("invalid command file: identifier expected after instruction\n");
545 inst->identifier = lexem.str; 568 inst->identifier = lexem.str;
546 if(find_source_by_id(cmd_file, inst->identifier) == NULL) 569 if(find_source_by_id(cmd_file, inst->identifier) == NULL)
547 bug("invalid command file: undefined reference to source '%s'", inst->identifier); 570 bug("invalid command file: undefined reference to source '%s'\n", inst->identifier);
548 next(); 571 next();
549 if(lexem.type == LEX_RANGLE) 572 if(lexem.type == LEX_RANGLE)
550 { 573 {
@@ -552,12 +575,12 @@ static struct cmd_file_t *read_command_file(const char *file)
552 inst->type = CMD_LOAD_AT; 575 inst->type = CMD_LOAD_AT;
553 next(); 576 next();
554 if(lexem.type != LEX_NUMBER) 577 if(lexem.type != LEX_NUMBER)
555 bug("invalid command file: number expected for loading address"); 578 bug("invalid command file: number expected for loading address\n");
556 inst->addr = lexem.num; 579 inst->addr = lexem.num;
557 next(); 580 next();
558 } 581 }
559 if(lexem.type != LEX_SEMICOLON) 582 if(lexem.type != LEX_SEMICOLON)
560 bug("invalid command file: expected ';' after command"); 583 bug("invalid command file: expected ';' after command\n");
561 } 584 }
562 else if(inst->type == CMD_CALL || inst->type == CMD_JUMP) 585 else if(inst->type == CMD_CALL || inst->type == CMD_JUMP)
563 { 586 {
@@ -565,7 +588,7 @@ static struct cmd_file_t *read_command_file(const char *file)
565 { 588 {
566 inst->identifier = lexem.str; 589 inst->identifier = lexem.str;
567 if(find_source_by_id(cmd_file, inst->identifier) == NULL) 590 if(find_source_by_id(cmd_file, inst->identifier) == NULL)
568 bug("invalid command file: undefined reference to source '%s'", inst->identifier); 591 bug("invalid command file: undefined reference to source '%s'\n", inst->identifier);
569 next(); 592 next();
570 } 593 }
571 else if(lexem.type == LEX_NUMBER) 594 else if(lexem.type == LEX_NUMBER)
@@ -575,24 +598,33 @@ static struct cmd_file_t *read_command_file(const char *file)
575 next(); 598 next();
576 } 599 }
577 else 600 else
578 bug("invalid command file: identifier or number expected after jump/load"); 601 bug("invalid command file: identifier or number expected after jump/load\n");
579 602
580 if(lexem.type == LEX_LPAREN) 603 if(lexem.type == LEX_LPAREN)
581 { 604 {
582 next(); 605 next();
583 if(lexem.type != LEX_NUMBER) 606 if(lexem.type != LEX_NUMBER)
584 bug("invalid command file: expected numeral expression after ("); 607 bug("invalid command file: expected numeral expression after (\n");
585 inst->argument = lexem.num; 608 inst->argument = lexem.num;
586 next(); 609 next();
587 if(lexem.type != LEX_RPAREN) 610 if(lexem.type != LEX_RPAREN)
588 bug("invalid command file: expected closing brace"); 611 bug("invalid command file: expected closing brace\n");
589 next(); 612 next();
590 } 613 }
591 if(lexem.type != LEX_SEMICOLON) 614 if(lexem.type != LEX_SEMICOLON)
592 bug("invalid command file: expected ';' after command"); 615 bug("invalid command file: expected ';' after command\n");
616 }
617 else if(inst->type == CMD_MODE)
618 {
619 if(lexem.type != LEX_NUMBER)
620 bug("invalid command file: number expected after 'mode'\n");
621 inst->argument = lexem.num;
622 next();
623 if(lexem.type != LEX_SEMICOLON)
624 bug("invalid command file: expected ';' after command\n");
593 } 625 }
594 else 626 else
595 bug("die"); 627 bug("die\n");
596 if(end_list == NULL) 628 if(end_list == NULL)
597 { 629 {
598 sec->inst_list = inst; 630 sec->inst_list = inst;
@@ -685,7 +717,7 @@ static void load_elf_by_id(struct cmd_file_t *cmd_file, const char *id)
685 if(src->type == CMD_SRC_ELF && src->loaded) 717 if(src->type == CMD_SRC_ELF && src->loaded)
686 return; 718 return;
687 if(src->type != CMD_SRC_UNK) 719 if(src->type != CMD_SRC_UNK)
688 bug("source '%s' seen both as elf and binary file", id); 720 bug("source '%s' seen both as elf and binary file\n", id);
689 src->type = CMD_SRC_ELF; 721 src->type = CMD_SRC_ELF;
690 int fd = open(src->filename, O_RDONLY); 722 int fd = open(src->filename, O_RDONLY);
691 if(fd < 0) 723 if(fd < 0)
@@ -708,7 +740,7 @@ static void load_bin_by_id(struct cmd_file_t *cmd_file, const char *id)
708 if(src->type == CMD_SRC_BIN && src->loaded) 740 if(src->type == CMD_SRC_BIN && src->loaded)
709 return; 741 return;
710 if(src->type != CMD_SRC_UNK) 742 if(src->type != CMD_SRC_UNK)
711 bug("source '%s' seen both as elf and binary file", id); 743 bug("source '%s' seen both as elf and binary file\n", id);
712 src->type = CMD_SRC_BIN; 744 src->type = CMD_SRC_BIN;
713 int fd = open(src->filename, O_RDONLY); 745 int fd = open(src->filename, O_RDONLY);
714 if(fd < 0) 746 if(fd < 0)
@@ -773,8 +805,12 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
773 load_bin_by_id(cmd_file, cinst->identifier); 805 load_bin_by_id(cmd_file, cinst->identifier);
774 sec->nr_insts++; 806 sec->nr_insts++;
775 } 807 }
808 else if(cinst->type == CMD_MODE)
809 {
810 sec->nr_insts++;
811 }
776 else 812 else
777 bug("die"); 813 bug("die\n");
778 814
779 cinst = cinst->next; 815 cinst = cinst->next;
780 } 816 }
@@ -830,8 +866,13 @@ static struct sb_file_t *apply_cmd_file(struct cmd_file_t *cmd_file)
830 sec->insts[idx].data = bin->data; 866 sec->insts[idx].data = bin->data;
831 sec->insts[idx++].size = bin->size; 867 sec->insts[idx++].size = bin->size;
832 } 868 }
869 else if(cinst->type == CMD_MODE)
870 {
871 sec->insts[idx].inst = SB_INST_MODE;
872 sec->insts[idx++].addr = cinst->argument;
873 }
833 else 874 else
834 bug("die"); 875 bug("die\n");
835 876
836 cinst = cinst->next; 877 cinst = cinst->next;
837 } 878 }
@@ -909,6 +950,15 @@ static void compute_sb_offsets(struct sb_file_t *sb)
909 sb->image_size += (inst->size + inst->padding_size) / BLOCK_SIZE; 950 sb->image_size += (inst->size + inst->padding_size) / BLOCK_SIZE;
910 sec->sec_size += (inst->size + inst->padding_size) / BLOCK_SIZE; 951 sec->sec_size += (inst->size + inst->padding_size) / BLOCK_SIZE;
911 } 952 }
953 else if(inst->inst == SB_INST_MODE)
954 {
955 if(g_debug)
956 printf("MODE | mod=0x%08x", inst->addr);
957 sb->image_size += sizeof(struct sb_instruction_mode_t) / BLOCK_SIZE;
958 sec->sec_size += sizeof(struct sb_instruction_mode_t) / BLOCK_SIZE;
959 }
960 else
961 bug("die on inst %d\n", inst->inst);
912 } 962 }
913 } 963 }
914 /* final signature */ 964 /* final signature */
@@ -999,26 +1049,31 @@ static void produce_section_tag_cmd(struct sb_section_t *sec,
999void produce_sb_instruction(struct sb_inst_t *inst, 1049void produce_sb_instruction(struct sb_inst_t *inst,
1000 struct sb_instruction_common_t *cmd) 1050 struct sb_instruction_common_t *cmd)
1001{ 1051{
1002 cmd->hdr.flags = 0; 1052 memset(cmd, 0, sizeof(struct sb_instruction_common_t));
1003 cmd->hdr.opcode = inst->inst; 1053 cmd->hdr.opcode = inst->inst;
1004 cmd->addr = inst->addr;
1005 cmd->len = inst->size;
1006 switch(inst->inst) 1054 switch(inst->inst)
1007 { 1055 {
1008 case SB_INST_CALL: 1056 case SB_INST_CALL:
1009 case SB_INST_JUMP: 1057 case SB_INST_JUMP:
1010 cmd->len = 0; 1058 cmd->addr = inst->addr;
1011 cmd->data = inst->argument; 1059 cmd->data = inst->argument;
1012 break; 1060 break;
1013 case SB_INST_FILL: 1061 case SB_INST_FILL:
1062 cmd->addr = inst->addr;
1063 cmd->len = inst->size;
1014 cmd->data = inst->pattern; 1064 cmd->data = inst->pattern;
1015 break; 1065 break;
1016 case SB_INST_LOAD: 1066 case SB_INST_LOAD:
1067 cmd->addr = inst->addr;
1068 cmd->len = inst->size;
1017 cmd->data = crc_continue(crc(inst->data, inst->size), 1069 cmd->data = crc_continue(crc(inst->data, inst->size),
1018 inst->padding, inst->padding_size); 1070 inst->padding, inst->padding_size);
1019 break; 1071 break;
1020 default: 1072 case SB_INST_MODE:
1073 cmd->data = inst->addr;
1021 break; 1074 break;
1075 default:
1076 bug("die\n");
1022 } 1077 }
1023 cmd->hdr.checksum = instruction_checksum(&cmd->hdr); 1078 cmd->hdr.checksum = instruction_checksum(&cmd->hdr);
1024} 1079}
diff --git a/utils/sbtools/sbtoelf.c b/utils/sbtools/sbtoelf.c
index 851189f05e..f421f83848 100644
--- a/utils/sbtools/sbtoelf.c
+++ b/utils/sbtools/sbtoelf.c
@@ -224,7 +224,15 @@ static void extract_section(int data_sec, char name[5], byte *buf, int size, con
224 color(GREY); 224 color(GREY);
225 printf("[Bad checksum]"); 225 printf("[Bad checksum]");
226 } 226 }
227 227 if(hdr->flags != 0)
228 {
229 color(GREY);
230 printf("[");
231 color(BLUE);
232 printf("f=%x", hdr->flags);
233 color(GREY);
234 printf("] ");
235 }
228 if(hdr->opcode == SB_INST_LOAD) 236 if(hdr->opcode == SB_INST_LOAD)
229 { 237 {
230 struct sb_instruction_load_t *load = (struct sb_instruction_load_t *)&buf[pos]; 238 struct sb_instruction_load_t *load = (struct sb_instruction_load_t *)&buf[pos];
@@ -612,8 +620,16 @@ static void extract(unsigned long filesize)
612 printf("cnt=0x%08x", tag->len); 620 printf("cnt=0x%08x", tag->len);
613 color(OFF);printf(" | "); 621 color(OFF);printf(" | ");
614 color(YELLOW); 622 color(YELLOW);
615 printf("flg=0x%08x\n", tag->flags); 623 printf("flg=0x%08x", tag->flags);
616 color(OFF); 624 color(OFF);
625 if(tag->hdr.flags & SB_INST_LAST_TAG)
626 {
627 printf(" | ");
628 color(RED);
629 printf(" Last section");
630 color(OFF);
631 }
632 printf("\n");
617 offset += sizeof(struct sb_instruction_tag_t); 633 offset += sizeof(struct sb_instruction_tag_t);
618 634
619 char name[5]; 635 char name[5];