PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
readconf.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "srxfixup_internal.h"
12#include <ctype.h>
13#include <errno.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17
18typedef struct lowtoken_
19{
20 const char *str;
21 int line;
22 int col;
23} LowToken;
24enum TokenCode
25{
26 TC_NULL = 0,
27 TC_STRING = 1,
28 TC_VECTOR = 2,
29 TC_IOP = 3,
30 TC_EE = 4,
31 TC_Define = 5,
32 TC_Segments_name = 6,
33 TC_Memory_segment = 7,
34 TC_remove = 8,
35 TC_Program_header_order = 9,
36 TC_Program_header_data = 10,
37 TC_Segment_data = 11,
38 TC_segment = 12,
39 TC_createinfo = 13,
40 TC_Section_header_table = 14,
41 TC_CreateSymbols = 15,
42 TC_MAX_NUMBER = 16
43};
44typedef struct TokenTree_
45{
46 enum TokenCode tkcode;
48 {
49 struct TokenTree_ *subtree;
50 LowToken *lowtoken;
51 } value;
52} TokenTree;
53struct fstrbuf
54{
55 int line;
56 int col;
57 const char *cp;
58 const char *ep;
59 char buf[];
60};
61
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);
68static TokenTree *make_conf_vector(LowToken **lowtokens);
69static TokenTree *make_conf_tree(LowToken *lowtokens);
70static int get_vector_len(TokenTree *ttp);
71static int get_stringvector_len(const char **str);
72static const char **add_stringvector(const char **str, const char *newstr);
73static int setup_reserved_symbol_table(CreateSymbolConf *result, TokenTree *ttp, Srx_gen_table *conf);
74static int gen_define(TokenTree *ttp, Srx_gen_table *result);
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);
77static Srx_gen_table *make_srx_gen_table(TokenTree *tokentree);
78static void check_change_bit(unsigned int oldbit, unsigned int newbit, unsigned int *up, unsigned int *down);
79static int check_srx_gen_table(Srx_gen_table *tp);
80
81Srx_gen_table *read_conf(const char *indata, const char *infile, int dumpopt)
82{
83 LowToken *lowtokens;
84 struct fstrbuf *fbuf;
85 unsigned int fsize;
86 FILE *fp;
87
88 fp = 0;
89 if ( !indata )
90 {
91 fprintf(stderr, "internal error read_conf()\n");
92 return 0;
93 }
94 if ( infile )
95 {
96 fp = fopen(infile, "r");
97 if ( !fp )
98 {
99 fprintf(stderr, "\"%s\" can't open (errno=%d)\n", infile, errno);
100 return 0;
101 }
102 fseek(fp, 0, SEEK_END);
103 fsize = ftell(fp) + 4;
104 fseek(fp, 0, SEEK_SET);
105 }
106 else
107 {
108 fsize = strlen(indata);
109 }
110 lowtokens = (LowToken *)calloc(
111 ((sizeof(LowToken) + 2) * (fsize + 1) + (sizeof(LowToken) - 1)) / sizeof(LowToken), sizeof(LowToken));
112 fbuf = (struct fstrbuf *)malloc(fsize + sizeof(struct fstrbuf) + 1);
113 fbuf->cp = fbuf->buf;
114 fbuf->line = 1;
115 fbuf->col = 1;
116 if ( infile )
117 {
118 fbuf->ep = &fbuf->cp[fread(fbuf->buf, 1, fsize, fp)];
119 fclose(fp);
120 }
121 else
122 {
123 strcpy(fbuf->buf, indata);
124 fbuf->ep = &fbuf->cp[fsize];
125 }
126 if ( dumpopt == 1 )
127 {
128 for ( ;; )
129 {
130 int ch_;
131
132 ch_ = bgetc(fbuf);
133 if ( ch_ == -1 )
134 {
135 break;
136 }
137 fputc(ch_, stdout);
138 }
139 free(lowtokens);
140 free(fbuf);
141 return 0;
142 }
143 TokenTree *tokentree;
144 Srx_gen_table *srx_gen_table;
145
146 split_conf(lowtokens, (char *)&lowtokens[fsize + 1], fbuf);
147 free(fbuf);
148 tokentree = make_conf_tree(lowtokens);
149 srx_gen_table = make_srx_gen_table(tokentree);
150 free(tokentree);
151 if ( check_srx_gen_table(srx_gen_table) )
152 {
153 free(srx_gen_table);
154 return 0;
155 }
156 return srx_gen_table;
157}
158
159static int bgetc(struct fstrbuf *fb)
160{
161 int ret;
162
163 if ( fb->ep <= fb->cp )
164 {
165 return -1;
166 }
167 if ( *fb->cp == '\n' )
168 {
169 fb->line += 1;
170 fb->col = 0;
171 }
172 else
173 {
174 fb->col += 1;
175 }
176 ret = (unsigned char)(*fb->cp);
177 fb->cp += 1;
178 return ret;
179}
180
181static void bungetc(struct fstrbuf *fb)
182{
183 if ( fb->cp > fb->buf )
184 {
185 fb->cp -= 1;
186 fb->col -= 1;
187 if ( *fb->cp == '\n' )
188 {
189 fb->line -= 1;
190 }
191 }
192}
193
194static int skipsp(struct fstrbuf *fb)
195{
196 int ch_;
197
198 do
199 {
200 ch_ = bgetc(fb);
201 } while ( ch_ != -1 && isspace(ch_) != 0 );
202 if ( ch_ != -1 )
203 {
204 bungetc(fb);
205 }
206 return ch_ != -1;
207}
208
209static int skip_to_eol(struct fstrbuf *fb)
210{
211 int ch_;
212
213 do
214 {
215 ch_ = bgetc(fb);
216 } while ( ch_ != -1 && ch_ != '\n' && ch_ != '\r' );
217 return ch_ != -1;
218}
219
220static int gettoken(char **strbuf, struct fstrbuf *fb)
221{
222 int ch_;
223 char *cp;
224
225 for ( cp = *strbuf;; *cp = 0 )
226 {
227 ch_ = bgetc(fb);
228 if ( ch_ == -1 || (ch_ != '.' && ch_ != '_' && ch_ != '*' && isalnum(ch_) == 0) )
229 {
230 break;
231 }
232 *cp = (char)(ch_ & 0xFF);
233 cp += 1;
234 }
235 if ( ch_ != -1 )
236 {
237 bungetc(fb);
238 }
239 *strbuf = cp + 1;
240 return ch_ != -1;
241}
242
243static void split_conf(LowToken *result, char *strbuf, struct fstrbuf *fb)
244{
245 char *cp;
246
247 cp = strbuf;
248 for ( ; skipsp(fb); )
249 {
250 int cuchar;
251
252 cuchar = bgetc(fb);
253 if ( cuchar == '@' || cuchar == '.' || cuchar == '_' || cuchar == '*' || isalnum(cuchar) != 0 )
254 {
255 result->str = cp;
256 result->line = fb->line;
257 result->col = fb->col;
258 result += 1;
259 result->str = 0;
260 *cp = (char)(cuchar & 0xFF);
261 cp += 1;
262 gettoken(&cp, fb);
263 }
264 else if ( cuchar == '#' )
265 {
266 skip_to_eol(fb);
267 }
268 else if ( isprint(cuchar) != 0 )
269 {
270 result->str = cp;
271 result->line = fb->line;
272 result->col = fb->col;
273 result += 1;
274 result->str = 0;
275 *cp = (char)(cuchar & 0xFF);
276 cp += 1;
277 *cp = 0;
278 cp += 1;
279 }
280 }
281}
282
283// clang-format off
285{
286 int code;
287 const char * name;
288} keyword_table[] =
289{
290 { 3, "IOP" },
291 { 4, "EE" },
292 { 5, "Define" },
293 { 6, "Segments_name" },
294 { 7, "Memory_segment" },
295 { 8, "remove" },
296 { 9, "Program_header_order" },
297 { 10, "Program_header_data" },
298 { 11, "Segment_data" },
299 { 12, "segment" },
300 { 13, "createinfo" },
301 { 14, "Section_header_table" },
302 { 15, "CreateSymbols" },
303 { -1, NULL }
304};
305// clang-format on
306
307static TokenTree *make_conf_vector(LowToken **lowtokens)
308{
309 struct keyword_table_ *kt;
310 const LowToken *sltp;
311 LowToken *ltp;
312 int entries;
313 TokenTree *v14;
314
315 entries = 0;
316 ltp = *lowtokens;
317 v14 = (TokenTree *)calloc(1, sizeof(TokenTree));
318 v14->tkcode = TC_NULL;
319 for ( ; ltp->str && strcmp(ltp->str, "}") != 0; )
320 {
321 {
322 TokenTree *realloc_tmp = (TokenTree *)realloc(v14, (entries + 2) * sizeof(TokenTree));
323 if ( realloc_tmp == NULL )
324 {
325 fprintf(stderr, "Failure to allocate token tree\n");
326 exit(1);
327 }
328 v14 = realloc_tmp;
329 }
330
331 if ( !strcmp(ltp->str, "{") )
332 {
333 sltp = ltp;
334 ltp += 1;
335 v14[entries].tkcode = TC_VECTOR;
336 v14[entries].value.subtree = make_conf_vector(&ltp);
337 if ( !ltp->str || strcmp(ltp->str, "}") != 0 )
338 {
339 fprintf(stderr, "make_conf_vector(): missing '}' line:%d col=%d\n", sltp->line, sltp->col);
340 exit(1);
341 }
342 ltp += 1;
343 }
344 else
345 {
346 if ( *ltp->str != '@' && *ltp->str != '.' && *ltp->str != '_' && *ltp->str != '*' && isalnum(*ltp->str) == 0 )
347 {
348 fprintf(stderr, "make_conf_vector(): unexcepted data '%s' line:%d col=%d\n", ltp->str, ltp->line, ltp->col);
349 exit(1);
350 }
351 if ( *ltp->str == '@' )
352 {
353 for ( kt = keyword_table; kt->code >= 0 && strcmp(kt->name, ltp->str + 1) != 0; kt += 1 )
354 {
355 ;
356 }
357 if ( kt->code < 0 )
358 {
359 fprintf(stderr, "make_conf_vector(): unknown keyword '%s' line:%d col=%d\n", ltp->str, ltp->line, ltp->col);
360 exit(1);
361 }
362 v14[entries].tkcode = kt->code;
363 }
364 else
365 {
366 v14[entries].tkcode = TC_STRING;
367 }
368 v14[entries].value.subtree = (TokenTree *)ltp;
369 ltp += 1;
370 }
371 entries += 1;
372 v14[entries].tkcode = TC_NULL;
373 }
374 *lowtokens = ltp;
375 return v14;
376}
377
378static TokenTree *make_conf_tree(LowToken *lowtokens)
379{
380 TokenTree *v4;
381
382 v4 = (TokenTree *)calloc(1, sizeof(TokenTree));
383 v4->tkcode = TC_VECTOR;
384 v4->value.subtree = make_conf_vector(&lowtokens);
385 if ( lowtokens->str )
386 {
387 fprintf(
388 stderr,
389 "make_conf_tree(): unexcepted data '%s' line:%d col=%d\n",
390 lowtokens->str,
391 lowtokens->line,
392 lowtokens->col);
393 exit(1);
394 }
395 return v4;
396}
397
398static int get_vector_len(TokenTree *ttp)
399{
400 int v2;
401
402 for ( v2 = 0; ttp->tkcode; v2 += 1, ttp += 1 )
403 {
404 ;
405 }
406 return v2;
407}
408
409static int get_stringvector_len(const char **str)
410{
411 int v2;
412
413 for ( v2 = 0; *str; v2 += 1, str += 1 )
414 {
415 ;
416 }
417 return v2;
418}
419
420static const char **add_stringvector(const char **str, const char *newstr)
421{
422 int stringvector_len;
423 const char **result;
424 int nstr;
425
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;
430 result[nstr] = 0;
431 return result;
432}
433
434static int setup_reserved_symbol_table(CreateSymbolConf *result, TokenTree *ttp, Srx_gen_table *conf)
435{
436 if ( !strcmp("GLOBAL", ttp[1].value.lowtoken->str) )
437 {
438 result->bind = STB_GLOBAL;
439 }
440 else if ( !strcmp("LOCAL", ttp[1].value.lowtoken->str) )
441 {
442 result->bind = STB_LOCAL;
443 }
444 else if ( !strcmp("WEAK", ttp[1].value.lowtoken->str) )
445 {
446 result->bind = STB_WEAK;
447 }
448 else
449 {
450 fprintf(stderr, "Unsupported bind '%s' for '%s'\n", ttp[1].value.lowtoken->str, ttp->value.lowtoken->str);
451 return 1;
452 }
453 if ( strcmp("OBJECT", ttp[2].value.lowtoken->str) != 0 )
454 {
455 fprintf(stderr, "Unsupported type '%s' for '%s'\n", ttp[2].value.lowtoken->str, ttp->value.lowtoken->str);
456 return 1;
457 }
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] == '.' )
461 {
462 result->sectname = ttp[3].value.lowtoken->str;
463 }
464 else
465 {
466 result->sectname = 0;
467 if ( !result->segment )
468 {
469 fprintf(stderr, "Unknown segment '%s' for '%s'\n", ttp[3].value.lowtoken->str, ttp->value.lowtoken->str);
470 return 1;
471 }
472 }
473 if ( !strcmp("SHN_RADDR", ttp[4].value.lowtoken->str) )
474 {
475 result->shindex = 65311;
476 }
477 else if ( !strcmp("0", ttp[4].value.lowtoken->str) )
478 {
479 result->shindex = 0;
480 }
481 else
482 {
483 fprintf(stderr, "Unknown shindex '%s' for '%s'\n", ttp[4].value.lowtoken->str, ttp->value.lowtoken->str);
484 return 1;
485 }
486 if ( !strcmp("start", ttp[5].value.lowtoken->str) )
487 {
488 result->seflag = 0;
489 }
490 else if ( !strcmp("end", ttp[5].value.lowtoken->str) )
491 {
492 result->seflag = 1;
493 }
494 else if ( !strcmp("gpbase", ttp[5].value.lowtoken->str) )
495 {
496 result->seflag = 2;
497 }
498 else
499 {
500 fprintf(stderr, "Unknown base '%s' for '%s'\n", ttp[5].value.lowtoken->str, ttp->value.lowtoken->str);
501 return 1;
502 }
503 result->name = ttp->value.lowtoken->str;
504 return 0;
505}
506
507static int gen_define(TokenTree *ttp, Srx_gen_table *result)
508{
509 PheaderInfo *phrlist;
510 SegConf *segp;
511 SegConf *seglist;
512 TokenTree *subarg;
513 TokenTree *arg;
514 int n;
515 int nseg;
516 int m;
517 int j;
518 int k;
519 int i;
520 int entries_1;
521 int entries_2;
522 int entries_3;
523 int entries_4;
524
525 for ( ; ttp->tkcode; ttp += 2 )
526 {
527 if ( ttp[1].tkcode != TC_VECTOR )
528 {
529 fprintf(
530 stderr,
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);
535 return 1;
536 }
537 arg = ttp[1].value.subtree;
538 switch ( ttp->tkcode )
539 {
540 case TC_Segments_name:
541 entries_1 = get_vector_len(arg);
542 seglist = (SegConf *)calloc(entries_1 + 1, sizeof(SegConf));
543 result->segment_list = seglist;
544 for ( m = 0; m < entries_1; m += 1 )
545 {
546 seglist[m].name = arg[m].value.lowtoken->str;
547 seglist[m].sect_name_patterns = (const char **)calloc(1, sizeof(const char *));
548 }
549 break;
550 case TC_Memory_segment:
551 entries_4 = get_vector_len(arg);
552 for ( i = 0; i < entries_4; i += 1 )
553 {
554 segp = lookup_segment(result, arg[i].value.lowtoken->str, 1);
555 if ( !segp )
556 {
557 return 1;
558 }
559 segp->bitid = 1 << (segp - result->segment_list);
560 }
561 break;
562 case TC_Program_header_order:
563 entries_2 = get_vector_len(arg);
564 phrlist = (PheaderInfo *)calloc(entries_2 + 1, sizeof(PheaderInfo));
565 result->program_header_order = phrlist;
566 for ( j = 0; j < entries_2; j += 1 )
567 {
568 switch ( arg[j].tkcode )
569 {
570 case TC_STRING:
571 phrlist[j].sw = SRX_PH_TYPE_MOD;
572 phrlist[j].d.section_name = arg[j].value.lowtoken->str;
573 break;
574 case TC_VECTOR:
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 )
580 {
581 phrlist[j].d.segment_list[n] = lookup_segment(result, subarg[n].value.lowtoken->str, 1);
582 if ( !phrlist[j].d.segment_list[n] )
583 {
584 return 1;
585 }
586 }
587 break;
588 default:
589 break;
590 }
591 }
592 break;
593 case TC_CreateSymbols:
594 entries_3 = get_vector_len(arg);
595 result->create_symbols = (CreateSymbolConf *)calloc(entries_3 + 1, sizeof(CreateSymbolConf));
596 for ( k = 0; k < entries_3; k += 1 )
597 {
598 if ( arg[k].tkcode != TC_VECTOR || get_vector_len(arg[k].value.subtree) != 6 )
599 {
600 fprintf(stderr, "unexcepted data in @CreateSymbols\n");
601 return 1;
602 }
603 if ( setup_reserved_symbol_table(&result->create_symbols[k], arg[k].value.subtree, result) )
604 {
605 return 1;
606 }
607 }
608 break;
609 default:
610 fprintf(
611 stderr,
612 "unexcepted data '%s' line:%d col=%d\n",
613 ttp->value.lowtoken->str,
614 ttp->value.lowtoken->line,
615 ttp->value.lowtoken->col);
616 return 1;
617 }
618 }
619 return 0;
620}
621
622static void get_section_type_flag(TokenTree *ttp, int *rtype, int *rflag)
623{
624 int flag;
625 int type;
626
627 type = 0;
628 flag = 0;
629 for ( ; ttp->tkcode; ttp += 1 )
630 {
631 const char *info;
632
633 info = ttp->value.lowtoken->str;
634 if ( !strcmp(info, "PROGBITS") )
635 {
636 type = SHT_PROGBITS;
637 }
638 else if ( !strcmp(info, "NOBITS") )
639 {
640 type = SHT_NOBITS;
641 }
642 else if ( !strcmp(info, "WRITE") )
643 {
644 flag |= SHF_WRITE;
645 }
646 else if ( !strcmp(info, "ALLOC") )
647 {
648 flag |= SHF_ALLOC;
649 }
650 else if ( !strcmp(info, "EXECINSTR") )
651 {
652 flag |= SHF_EXECINSTR;
653 }
654 }
655 *rtype = type;
656 *rflag = flag;
657}
658
659static elf_section *make_empty_section(const char *name, int type, int flag)
660{
661 elf_section *result;
662
663 result = (elf_section *)calloc(1, sizeof(elf_section));
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;
670 return result;
671}
672
673static Srx_gen_table *make_srx_gen_table(TokenTree *tokentree)
674{
675 SegConf *seg_1;
676 SegConf *seg_2;
677 const SegConf *seg_3;
678 TokenTree *nttp;
679 TokenTree *ttp2_1;
680 TokenTree *ttp2_2;
681 TokenTree *ttp1;
682 TokenTree *ttp;
683 Srx_gen_table *result;
684 int sectflag;
685 int secttype;
686 unsigned int bitid;
687 int nsect;
688 const char **strp;
689 const char *str;
690 char *str2;
691
692 result = (Srx_gen_table *)calloc(1, sizeof(Srx_gen_table));
693 if ( tokentree->tkcode != TC_VECTOR )
694 {
695 fprintf(stderr, "Internal error:make_srx_gen_table();\n");
696 free(result);
697 return 0;
698 }
699 ttp = tokentree->value.subtree;
700 nsect = 0;
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 *));
704 result->section_list = (SectConf *)calloc(1, sizeof(SectConf));
705 for ( ; ttp->tkcode; )
706 {
707 if ( ttp[1].tkcode == TC_VECTOR )
708 {
709 ttp1 = ttp[1].value.subtree;
710 nttp = ttp + 2;
711 }
712 else
713 {
714 ttp1 = 0;
715 nttp = ttp + 1;
716 }
717 switch ( ttp->tkcode )
718 {
719 case TC_STRING:
720 str = ttp->value.lowtoken->str;
721 result->section_table_order = add_stringvector(result->section_table_order, str);
722 if ( !ttp1 )
723 {
724 result->file_layout_order = add_stringvector(result->file_layout_order, str);
725 ttp = nttp;
726 break;
727 }
728 if ( ttp1->tkcode == TC_remove )
729 {
730 result->removesection_list = add_stringvector(result->removesection_list, str);
731 ttp = nttp;
732 break;
733 }
734 if ( ttp1->tkcode == TC_segment && ttp1[1].tkcode == TC_VECTOR )
735 {
736 bitid = 0;
737 for ( ttp2_1 = ttp1[1].value.subtree; ttp2_1->tkcode; ttp2_1 += 1 )
738 {
739 seg_1 = lookup_segment(result, ttp2_1->value.lowtoken->str, 1);
740 if ( !seg_1 )
741 {
742 return 0;
743 }
744 seg_1->sect_name_patterns = add_stringvector(seg_1->sect_name_patterns, str);
745 bitid |= seg_1->bitid;
746 }
747 if ( bitid )
748 {
749 result->section_list[nsect].sect_name_pattern = str;
750 result->section_list[nsect].flag = bitid;
751 nsect += 1;
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;
757 }
758 if ( ttp1[2].tkcode != TC_createinfo || ttp1[3].tkcode != TC_VECTOR )
759 {
760 ttp = nttp;
761 break;
762 }
763 get_section_type_flag(ttp1[3].value.subtree, &secttype, &sectflag);
764 if ( secttype && sectflag )
765 {
766 if ( bitid )
767 {
768 result->section_list[nsect - 1].secttype = secttype;
769 result->section_list[nsect - 1].sectflag = sectflag;
770 }
771 seg_2 = NULL;
772 for ( ttp2_2 = ttp1[1].value.subtree;; ttp2_2 += 1 )
773 {
774 if ( ttp2_2->tkcode == TC_NULL )
775 {
776 ttp = nttp;
777 break;
778 }
779 seg_2 = lookup_segment(result, ttp2_2->value.lowtoken->str, 1);
780 if ( !seg_2 )
781 {
782 break;
783 }
784 if ( !seg_2->empty_section )
785 {
786 seg_2->empty_section = make_empty_section(str, secttype, sectflag);
787 }
788 }
789 if ( !seg_2 )
790 {
791 free(result);
792 return 0;
793 }
794 }
795 else
796 {
797 fprintf(
798 stderr, "Illegal @createinfo line:%d col=%d\n", ttp1->value.lowtoken->line, ttp1->value.lowtoken->col);
799 free(result);
800 return 0;
801 }
802 }
803 else
804 {
805 fprintf(
806 stderr,
807 "unexcepted data '%s' line:%d col=%d\n",
808 ttp1->value.lowtoken->str,
809 ttp1->value.lowtoken->line,
810 ttp1->value.lowtoken->col);
811 free(result);
812 return 0;
813 }
814 break;
815 case TC_IOP:
816 result->target = SRX_TARGET_IOP;
817 ttp = nttp;
818 break;
819 case TC_EE:
820 result->target = SRX_TARGET_EE;
821 ttp = nttp;
822 break;
823 case TC_Define:
824 if ( !ttp1 )
825 {
826 fprintf(
827 stderr,
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);
832 free(result);
833 return 0;
834 }
835 if ( !gen_define(ttp1, result) )
836 {
837 ttp = nttp;
838 break;
839 }
840 free(result);
841 return 0;
842 case TC_Program_header_data:
843 if ( !ttp1 || ttp1->tkcode != TC_STRING )
844 {
845 if ( ttp1 )
846 {
847 fprintf(
848 stderr,
849 "unexcepted data '%s' line:%d col=%d\n",
850 ttp1->value.lowtoken->str,
851 ttp1->value.lowtoken->line,
852 ttp1->value.lowtoken->col);
853 }
854 else
855 {
856 fprintf(
857 stderr,
858 "%s missing '{ <n> }' line:%d col=%d\n",
859 ttp->value.lowtoken->str,
860 ttp->value.lowtoken->line,
861 ttp->value.lowtoken->col);
862 }
863 free(result);
864 return 0;
865 }
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);
869 ttp = nttp;
870 break;
871 case TC_Segment_data:
872 for ( ;; )
873 {
874 if ( ttp1 != NULL && ttp1->tkcode == TC_NULL )
875 {
876 ttp = nttp;
877 break;
878 }
879 if ( ttp1 != NULL )
880 {
881 seg_3 = lookup_segment(result, ttp1->value.lowtoken->str, 1);
882 if ( seg_3 )
883 {
884 for ( strp = seg_3->sect_name_patterns; *strp; strp += 1 )
885 {
886 result->file_layout_order = add_stringvector(result->file_layout_order, *strp);
887 }
888 ttp1 += 1;
889 continue;
890 }
891 }
892 free(result);
893 return 0;
894 }
895 break;
896 case TC_Section_header_table:
897 result->file_layout_order = add_stringvector(result->file_layout_order, "@Section_header_table");
898 ttp = nttp;
899 break;
900#pragma GCC diagnostic push
901#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
902 case TC_VECTOR:
903 ttp = ttp->value.subtree;
904 default:
905 if ( ttp->value.lowtoken != NULL )
906 {
907 fprintf(
908 stderr,
909 "unexcepted data '%s' line:%d col=%d\n",
910 ttp->value.lowtoken->str,
911 ttp->value.lowtoken->line,
912 ttp->value.lowtoken->col);
913 }
914 free(result);
915 return 0;
916#pragma GCC diagnostic pop
917 }
918 }
919 switch ( result->target )
920 {
921 case 1:
922 case 2:
923 return result;
924 default:
925 fprintf(stderr, "@IOP or @EE not found error !\n");
926 free(result);
927 return 0;
928 }
929}
930
931static void check_change_bit(unsigned int oldbit, unsigned int newbit, unsigned int *up, unsigned int *down)
932{
933 *up = ~oldbit & newbit & (newbit ^ oldbit);
934 *down = ~newbit & oldbit & (newbit ^ oldbit);
935}
936
937static int check_srx_gen_table(Srx_gen_table *tp)
938{
939 SegConf *scnfp;
940 SectConf *sctp;
941 int nsegment;
942 int b;
943 int error;
944 unsigned int defbitid;
945 unsigned int downdelta;
946 unsigned int updelta;
947 unsigned int oldbitid;
948
949 nsegment = 0;
950 for ( scnfp = tp->segment_list; scnfp && scnfp->name; scnfp += 1 )
951 {
952 nsegment += 1;
953 }
954 defbitid = 0;
955 oldbitid = 0;
956 error = 0;
957 for ( sctp = tp->section_list; sctp->sect_name_pattern; sctp += 1 )
958 {
959 check_change_bit(oldbitid, sctp->flag, &updelta, &downdelta);
960 if ( (defbitid & updelta) != 0 )
961 {
962 error += 1;
963 for ( b = 0; b < nsegment; b += 1 )
964 {
965 if ( (sctp->flag & (1 << b)) != 0 )
966 {
967 fprintf(stderr, "Segment '%s' restart by section `%s`\n", tp->segment_list[b].name, sctp->sect_name_pattern);
968 break;
969 }
970 }
971 }
972 oldbitid = sctp->flag;
973 check_change_bit(oldbitid, sctp[1].flag, &updelta, &downdelta);
974 defbitid |= downdelta;
975 }
976 return error;
977}