11#include "srxfixup_internal.h"
33 TC_Memory_segment = 7,
35 TC_Program_header_order = 9,
36 TC_Program_header_data = 10,
40 TC_Section_header_table = 14,
41 TC_CreateSymbols = 15,
46 enum TokenCode tkcode;
62static int bgetc(
struct fstrbuf *fb);
63static void bungetc(
struct fstrbuf *fb);
64static int skipsp(
struct fstrbuf *fb);
65static int skip_to_eol(
struct fstrbuf *fb);
66static int gettoken(
char **strbuf,
struct fstrbuf *fb);
67static void split_conf(
LowToken *result,
char *strbuf,
struct fstrbuf *fb);
71static int get_stringvector_len(
const char **str);
72static const char **add_stringvector(
const char **str,
const char *newstr);
75static void get_section_type_flag(
TokenTree *ttp,
int *rtype,
int *rflag);
76static elf_section *make_empty_section(
const char *name,
int type,
int flag);
78static void check_change_bit(
unsigned int oldbit,
unsigned int newbit,
unsigned int *up,
unsigned int *down);
81Srx_gen_table *read_conf(
const char *indata,
const char *infile,
int dumpopt)
91 fprintf(stderr,
"internal error read_conf()\n");
96 fp = fopen(infile,
"r");
99 fprintf(stderr,
"\"%s\" can't open (errno=%d)\n", infile, errno);
102 fseek(fp, 0, SEEK_END);
103 fsize = ftell(fp) + 4;
104 fseek(fp, 0, SEEK_SET);
108 fsize = strlen(indata);
112 fbuf = (
struct fstrbuf *)malloc(fsize +
sizeof(
struct fstrbuf) + 1);
113 fbuf->cp = fbuf->buf;
118 fbuf->ep = &fbuf->cp[fread(fbuf->buf, 1, fsize, fp)];
123 strcpy(fbuf->buf, indata);
124 fbuf->ep = &fbuf->cp[fsize];
146 split_conf(lowtokens, (
char *)&lowtokens[fsize + 1], fbuf);
148 tokentree = make_conf_tree(lowtokens);
149 srx_gen_table = make_srx_gen_table(tokentree);
151 if ( check_srx_gen_table(srx_gen_table) )
156 return srx_gen_table;
159static int bgetc(
struct fstrbuf *fb)
163 if ( fb->ep <= fb->cp )
167 if ( *fb->cp ==
'\n' )
176 ret = (
unsigned char)(*fb->cp);
181static void bungetc(
struct fstrbuf *fb)
183 if ( fb->cp > fb->buf )
187 if ( *fb->cp ==
'\n' )
194static int skipsp(
struct fstrbuf *fb)
201 }
while ( ch_ != -1 && isspace(ch_) != 0 );
209static int skip_to_eol(
struct fstrbuf *fb)
216 }
while ( ch_ != -1 && ch_ !=
'\n' && ch_ !=
'\r' );
220static int gettoken(
char **strbuf,
struct fstrbuf *fb)
225 for ( cp = *strbuf;; *cp = 0 )
228 if ( ch_ == -1 || (ch_ !=
'.' && ch_ !=
'_' && ch_ !=
'*' && isalnum(ch_) == 0) )
232 *cp = (char)(ch_ & 0xFF);
243static void split_conf(
LowToken *result,
char *strbuf,
struct fstrbuf *fb)
248 for ( ; skipsp(fb); )
253 if ( cuchar ==
'@' || cuchar ==
'.' || cuchar ==
'_' || cuchar ==
'*' || isalnum(cuchar) != 0 )
256 result->line = fb->line;
257 result->col = fb->col;
260 *cp = (char)(cuchar & 0xFF);
264 else if ( cuchar ==
'#' )
268 else if ( isprint(cuchar) != 0 )
271 result->line = fb->line;
272 result->col = fb->col;
275 *cp = (char)(cuchar & 0xFF);
293 { 6,
"Segments_name" },
294 { 7,
"Memory_segment" },
296 { 9,
"Program_header_order" },
297 { 10,
"Program_header_data" },
298 { 11,
"Segment_data" },
300 { 13,
"createinfo" },
301 { 14,
"Section_header_table" },
302 { 15,
"CreateSymbols" },
318 v14->tkcode = TC_NULL;
319 for ( ; ltp->str && strcmp(ltp->str,
"}") != 0; )
323 if ( realloc_tmp == NULL )
325 fprintf(stderr,
"Failure to allocate token tree\n");
331 if ( !strcmp(ltp->str,
"{") )
335 v14[entries].tkcode = TC_VECTOR;
336 v14[entries].value.subtree = make_conf_vector(<p);
337 if ( !ltp->str || strcmp(ltp->str,
"}") != 0 )
339 fprintf(stderr,
"make_conf_vector(): missing '}' line:%d col=%d\n", sltp->line, sltp->col);
346 if ( *ltp->str !=
'@' && *ltp->str !=
'.' && *ltp->str !=
'_' && *ltp->str !=
'*' && isalnum(*ltp->str) == 0 )
348 fprintf(stderr,
"make_conf_vector(): unexcepted data '%s' line:%d col=%d\n", ltp->str, ltp->line, ltp->col);
351 if ( *ltp->str ==
'@' )
353 for ( kt = keyword_table; kt->code >= 0 && strcmp(kt->name, ltp->str + 1) != 0; kt += 1 )
359 fprintf(stderr,
"make_conf_vector(): unknown keyword '%s' line:%d col=%d\n", ltp->str, ltp->line, ltp->col);
362 v14[entries].tkcode = kt->code;
366 v14[entries].tkcode = TC_STRING;
368 v14[entries].value.subtree = (
TokenTree *)ltp;
372 v14[entries].tkcode = TC_NULL;
383 v4->tkcode = TC_VECTOR;
384 v4->value.subtree = make_conf_vector(&lowtokens);
385 if ( lowtokens->str )
389 "make_conf_tree(): unexcepted data '%s' line:%d col=%d\n",
402 for ( v2 = 0; ttp->tkcode; v2 += 1, ttp += 1 )
409static int get_stringvector_len(
const char **str)
413 for ( v2 = 0; *str; v2 += 1, str += 1 )
420static const char **add_stringvector(
const char **str,
const char *newstr)
422 int stringvector_len;
426 stringvector_len = get_stringvector_len(str);
427 nstr = stringvector_len + 1;
428 result = (
const char **)realloc(str, (stringvector_len + 2) *
sizeof(
const char *));
429 result[nstr - 1] = newstr;
436 if ( !strcmp(
"GLOBAL", ttp[1].value.lowtoken->str) )
438 result->bind = STB_GLOBAL;
440 else if ( !strcmp(
"LOCAL", ttp[1].value.lowtoken->str) )
442 result->bind = STB_LOCAL;
444 else if ( !strcmp(
"WEAK", ttp[1].value.lowtoken->str) )
446 result->bind = STB_WEAK;
450 fprintf(stderr,
"Unsupported bind '%s' for '%s'\n", ttp[1].value.lowtoken->str, ttp->value.lowtoken->str);
453 if ( strcmp(
"OBJECT", ttp[2].value.lowtoken->str) != 0 )
455 fprintf(stderr,
"Unsupported type '%s' for '%s'\n", ttp[2].value.lowtoken->str, ttp->value.lowtoken->str);
458 result->type = STT_OBJECT;
459 result->segment = lookup_segment(conf, ttp[3].value.lowtoken->str, 0);
460 if ( !result->segment && ttp[3].value.lowtoken->str[0] ==
'.' )
462 result->sectname = ttp[3].value.lowtoken->str;
466 result->sectname = 0;
467 if ( !result->segment )
469 fprintf(stderr,
"Unknown segment '%s' for '%s'\n", ttp[3].value.lowtoken->str, ttp->value.lowtoken->str);
473 if ( !strcmp(
"SHN_RADDR", ttp[4].value.lowtoken->str) )
475 result->shindex = 65311;
477 else if ( !strcmp(
"0", ttp[4].value.lowtoken->str) )
483 fprintf(stderr,
"Unknown shindex '%s' for '%s'\n", ttp[4].value.lowtoken->str, ttp->value.lowtoken->str);
486 if ( !strcmp(
"start", ttp[5].value.lowtoken->str) )
490 else if ( !strcmp(
"end", ttp[5].value.lowtoken->str) )
494 else if ( !strcmp(
"gpbase", ttp[5].value.lowtoken->str) )
500 fprintf(stderr,
"Unknown base '%s' for '%s'\n", ttp[5].value.lowtoken->str, ttp->value.lowtoken->str);
503 result->name = ttp->value.lowtoken->str;
525 for ( ; ttp->tkcode; ttp += 2 )
527 if ( ttp[1].tkcode != TC_VECTOR )
531 "argument not found for '%s' line:%d col=%d\n",
532 ttp->value.lowtoken->str,
533 ttp->value.lowtoken->line,
534 ttp->value.lowtoken->col);
537 arg = ttp[1].value.subtree;
538 switch ( ttp->tkcode )
540 case TC_Segments_name:
541 entries_1 = get_vector_len(arg);
543 result->segment_list = seglist;
544 for ( m = 0; m < entries_1; m += 1 )
546 seglist[m].name = arg[m].value.lowtoken->str;
547 seglist[m].sect_name_patterns = (
const char **)calloc(1,
sizeof(
const char *));
550 case TC_Memory_segment:
551 entries_4 = get_vector_len(arg);
552 for ( i = 0; i < entries_4; i += 1 )
554 segp = lookup_segment(result, arg[i].value.lowtoken->str, 1);
559 segp->bitid = 1 << (segp - result->segment_list);
562 case TC_Program_header_order:
563 entries_2 = get_vector_len(arg);
565 result->program_header_order = phrlist;
566 for ( j = 0; j < entries_2; j += 1 )
568 switch ( arg[j].tkcode )
571 phrlist[j].sw = SRX_PH_TYPE_MOD;
572 phrlist[j].d.section_name = arg[j].value.lowtoken->str;
575 subarg = arg[j].value.subtree;
576 nseg = get_vector_len(subarg);
577 phrlist[j].sw = SRX_PH_TYPE_TEXT;
578 phrlist[j].d.segment_list = (
SegConf **)calloc(nseg + 1,
sizeof(
SegConf *));
579 for ( n = 0; n < nseg; n += 1 )
581 phrlist[j].d.segment_list[n] = lookup_segment(result, subarg[n].value.lowtoken->str, 1);
582 if ( !phrlist[j].d.segment_list[n] )
593 case TC_CreateSymbols:
594 entries_3 = get_vector_len(arg);
596 for ( k = 0; k < entries_3; k += 1 )
598 if ( arg[k].tkcode != TC_VECTOR || get_vector_len(arg[k].value.subtree) != 6 )
600 fprintf(stderr,
"unexcepted data in @CreateSymbols\n");
603 if ( setup_reserved_symbol_table(&result->create_symbols[k], arg[k].value.subtree, result) )
612 "unexcepted data '%s' line:%d col=%d\n",
613 ttp->value.lowtoken->str,
614 ttp->value.lowtoken->line,
615 ttp->value.lowtoken->col);
622static void get_section_type_flag(
TokenTree *ttp,
int *rtype,
int *rflag)
629 for ( ; ttp->tkcode; ttp += 1 )
633 info = ttp->value.lowtoken->str;
634 if ( !strcmp(
info,
"PROGBITS") )
638 else if ( !strcmp(
info,
"NOBITS") )
642 else if ( !strcmp(
info,
"WRITE") )
646 else if ( !strcmp(
info,
"ALLOC") )
650 else if ( !strcmp(
info,
"EXECINSTR") )
652 flag |= SHF_EXECINSTR;
659static elf_section *make_empty_section(
const char *name,
int type,
int flag)
664 result->name = strdup(name);
665 result->shr.sh_type = type;
666 result->shr.sh_flags = flag;
667 result->shr.sh_size = 0;
668 result->shr.sh_addralign = 4;
669 result->shr.sh_entsize = 0;
693 if ( tokentree->tkcode != TC_VECTOR )
695 fprintf(stderr,
"Internal error:make_srx_gen_table();\n");
699 ttp = tokentree->value.subtree;
701 result->section_table_order = (
const char **)calloc(1,
sizeof(
const char *));
702 result->file_layout_order = (
const char **)calloc(1,
sizeof(
const char *));
703 result->removesection_list = (
const char **)calloc(1,
sizeof(
const char *));
705 for ( ; ttp->tkcode; )
707 if ( ttp[1].tkcode == TC_VECTOR )
709 ttp1 = ttp[1].value.subtree;
717 switch ( ttp->tkcode )
720 str = ttp->value.lowtoken->str;
721 result->section_table_order = add_stringvector(result->section_table_order, str);
724 result->file_layout_order = add_stringvector(result->file_layout_order, str);
728 if ( ttp1->tkcode == TC_remove )
730 result->removesection_list = add_stringvector(result->removesection_list, str);
734 if ( ttp1->tkcode == TC_segment && ttp1[1].tkcode == TC_VECTOR )
737 for ( ttp2_1 = ttp1[1].value.subtree; ttp2_1->tkcode; ttp2_1 += 1 )
739 seg_1 = lookup_segment(result, ttp2_1->value.lowtoken->str, 1);
744 seg_1->sect_name_patterns = add_stringvector(seg_1->sect_name_patterns, str);
745 bitid |= seg_1->bitid;
749 result->section_list[nsect].sect_name_pattern = str;
750 result->section_list[nsect].flag = bitid;
752 result->section_list = (
SectConf *)realloc(result->section_list, (nsect + 1) *
sizeof(
SectConf));
753 result->section_list[nsect].sect_name_pattern = 0;
754 result->section_list[nsect].flag = 0;
755 result->section_list[nsect].secttype = 0;
756 result->section_list[nsect].sectflag = 0;
758 if ( ttp1[2].tkcode != TC_createinfo || ttp1[3].tkcode != TC_VECTOR )
763 get_section_type_flag(ttp1[3].value.subtree, §type, §flag);
764 if ( secttype && sectflag )
768 result->section_list[nsect - 1].secttype = secttype;
769 result->section_list[nsect - 1].sectflag = sectflag;
772 for ( ttp2_2 = ttp1[1].value.subtree;; ttp2_2 += 1 )
774 if ( ttp2_2->tkcode == TC_NULL )
779 seg_2 = lookup_segment(result, ttp2_2->value.lowtoken->str, 1);
784 if ( !seg_2->empty_section )
786 seg_2->empty_section = make_empty_section(str, secttype, sectflag);
798 stderr,
"Illegal @createinfo line:%d col=%d\n", ttp1->value.lowtoken->line, ttp1->value.lowtoken->col);
807 "unexcepted data '%s' line:%d col=%d\n",
808 ttp1->value.lowtoken->str,
809 ttp1->value.lowtoken->line,
810 ttp1->value.lowtoken->col);
816 result->target = SRX_TARGET_IOP;
820 result->target = SRX_TARGET_EE;
828 "argument not found for '%s' line:%d col=%d\n",
829 ttp->value.lowtoken->str,
830 ttp->value.lowtoken->line,
831 ttp->value.lowtoken->col);
835 if ( !gen_define(ttp1, result) )
842 case TC_Program_header_data:
843 if ( !ttp1 || ttp1->tkcode != TC_STRING )
849 "unexcepted data '%s' line:%d col=%d\n",
850 ttp1->value.lowtoken->str,
851 ttp1->value.lowtoken->line,
852 ttp1->value.lowtoken->col);
858 "%s missing '{ <n> }' line:%d col=%d\n",
859 ttp->value.lowtoken->str,
860 ttp->value.lowtoken->line,
861 ttp->value.lowtoken->col);
866 str2 = (
char *)malloc(0x32);
867 sprintf(str2,
"@Program_header_data %s", ttp1->value.lowtoken->str);
868 result->file_layout_order = add_stringvector(result->file_layout_order, str2);
871 case TC_Segment_data:
874 if ( ttp1 != NULL && ttp1->tkcode == TC_NULL )
881 seg_3 = lookup_segment(result, ttp1->value.lowtoken->str, 1);
884 for ( strp = seg_3->sect_name_patterns; *strp; strp += 1 )
886 result->file_layout_order = add_stringvector(result->file_layout_order, *strp);
896 case TC_Section_header_table:
897 result->file_layout_order = add_stringvector(result->file_layout_order,
"@Section_header_table");
900#pragma GCC diagnostic push
901#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
903 ttp = ttp->value.subtree;
905 if ( ttp->value.lowtoken != NULL )
909 "unexcepted data '%s' line:%d col=%d\n",
910 ttp->value.lowtoken->str,
911 ttp->value.lowtoken->line,
912 ttp->value.lowtoken->col);
916#pragma GCC diagnostic pop
919 switch ( result->target )
925 fprintf(stderr,
"@IOP or @EE not found error !\n");
931static void check_change_bit(
unsigned int oldbit,
unsigned int newbit,
unsigned int *up,
unsigned int *down)
933 *up = ~oldbit & newbit & (newbit ^ oldbit);
934 *down = ~newbit & oldbit & (newbit ^ oldbit);
944 unsigned int defbitid;
945 unsigned int downdelta;
946 unsigned int updelta;
947 unsigned int oldbitid;
950 for ( scnfp = tp->segment_list; scnfp && scnfp->name; scnfp += 1 )
957 for ( sctp = tp->section_list; sctp->sect_name_pattern; sctp += 1 )
959 check_change_bit(oldbitid, sctp->flag, &updelta, &downdelta);
960 if ( (defbitid & updelta) != 0 )
963 for ( b = 0; b < nsegment; b += 1 )
965 if ( (sctp->flag & (1 << b)) != 0 )
967 fprintf(stderr,
"Segment '%s' restart by section `%s`\n", tp->segment_list[b].name, sctp->sect_name_pattern);
972 oldbitid = sctp->flag;
973 check_change_bit(oldbitid, sctp[1].flag, &updelta, &downdelta);
974 defbitid |= downdelta;