1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - tools - makelcf
3 File: container.c
4
5 Copyright 2003-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17 #include <stdio.h>
18 #include <stdlib.h> // exit()
19 #include <string.h> // strcpy(), strcat()
20 #include <malloc.h>
21 #include "misc.h"
22 #include "makelcf.h"
23
24
25 /*============================================================================
26 * MISC
27 */
28 tStatic Static = { 0 };
29 tProperty Property = { 0 };
30
31 tOverlayList OverlayList = { 0, 0, 0 };
32 tOverlayList AutoloadList = { 0, 0, 0 };
33 tOverlayList LtdoverlayList = { 0, 0, 0 };
34 tOverlayList LtdautoloadList = { 0, 0, 0 };
35
36 static tOverlayList *CurrentOverlay = &OverlayList;
37
isSame(const char * s1,const char * s2)38 BOOL isSame(const char *s1, const char *s2)
39 {
40 if (s1 == s2)
41 {
42 return TRUE;
43 }
44
45 if (!s1 || !s2)
46 {
47 return FALSE;
48 }
49
50 while (*s1 == *s2)
51 {
52 if (!*s1)
53 {
54 return TRUE;
55 }
56 s1++;
57 s2++;
58 }
59 return FALSE;
60 }
61
62
63 /*============================================================================
64 * OVERLAY
65 */
66
GetNextOverlayID(void)67 static u32 GetNextOverlayID(void)
68 {
69 return (u32)(OverlayList.num + LtdoverlayList.num);
70 }
71
NewOverlay(tOverlayList * list)72 static tOverlay *NewOverlay(tOverlayList * list)
73 {
74 tOverlay *t = Alloc(sizeof(tOverlay));
75
76 if (list->tail)
77 list->tail->next = t;
78 else
79 list->head = t;
80 list->tail = t;
81
82 return t;
83 }
84
GetOverlay(tOverlayList * list,const char * overlayName)85 static tOverlay *GetOverlay(tOverlayList * list, const char *overlayName)
86 {
87 tOverlay *t = list->head;
88
89 while (t)
90 {
91 if (isSame(t->name, overlayName))
92 {
93 return t;
94 }
95 t = t->next;
96 }
97 return NULL;
98 }
99
100
s_AddOverlay(tOverlayList * list,const char * overlayName)101 static BOOL s_AddOverlay(tOverlayList * list, const char *overlayName)
102 {
103 if (isSame(Static.name, overlayName) || GetOverlay(&OverlayList, overlayName)
104 || GetOverlay(&AutoloadList, overlayName)
105 || GetOverlay(&LtdoverlayList, overlayName)
106 || GetOverlay(&LtdautoloadList, overlayName))
107 {
108 spec_yyerror("Same named MAIN/OVERLAY already existed. Aborted.");
109 return FALSE;
110 }
111 else
112 {
113 tOverlay *t = NewOverlay(list);
114 // t->id = list->num++;
115 t->id = GetNextOverlayID();
116 list->num++;
117 t->name = overlayName;
118 CurrentOverlay = list;
119 }
120 return TRUE;
121 }
122
AddOverlay(const char * overlayName)123 BOOL AddOverlay(const char *overlayName)
124 {
125 return s_AddOverlay(&OverlayList, overlayName);
126 }
127
AddLtdoverlay(const char * overlayName)128 BOOL AddLtdoverlay(const char *overlayName)
129 {
130 return s_AddOverlay(&LtdoverlayList, overlayName);
131 }
132
AddAutoload(const char * overlayName)133 BOOL AddAutoload(const char *overlayName)
134 {
135 return s_AddOverlay(&AutoloadList, overlayName);
136 }
137
AddLtdautoload(const char * overlayName)138 BOOL AddLtdautoload(const char *overlayName)
139 {
140 return s_AddOverlay(&LtdautoloadList, overlayName);
141 }
142
143 /*============================================================================
144 * OVERLAY - id
145 */
146
OverlaySetId(u32 id)147 BOOL OverlaySetId(u32 id)
148 {
149 tOverlay *t = CurrentOverlay->tail;
150
151 if (t->id)
152 {
153 spec_yyerror("OVERLAY ID already set. Ignored.");
154 }
155 else
156 {
157 t->id = id;
158 }
159 return TRUE;
160 }
161
162
163 /*============================================================================
164 * OVERLAY - group
165 */
166
OverlaySetGroup(const char * group)167 BOOL OverlaySetGroup(const char *group)
168 {
169 tOverlay *t = CurrentOverlay->tail;
170
171 if (t->group)
172 {
173 spec_yyerror("overlay GROUP already set. Ignored.");
174 }
175 else
176 {
177 t->group = group;
178 }
179 return TRUE;
180 }
181
182
183 /*============================================================================
184 * OVERLAY - address
185 */
186
OverlaySetAddress(u32 address)187 BOOL OverlaySetAddress(u32 address)
188 {
189 tOverlay *t = CurrentOverlay->tail;
190
191 if (t->afters.tail || t->address)
192 {
193 spec_yyerror("ADDRESS/AFTER already set. Ignored.");
194 }
195 else
196 {
197 t->address = address;
198 }
199 return TRUE;
200 }
201
202
203 /*============================================================================
204 * OVERLAY - after
205 */
206
NewAfter(tAfterList * list)207 static tAfter *NewAfter(tAfterList * list)
208 {
209 tAfter *t = Alloc(sizeof(tAfter));
210
211 if (list->tail)
212 list->tail->next = t;
213 else
214 list->head = t;
215 list->tail = t;
216
217 return t;
218 }
219
220
GetAfter(tAfterList * list,const char * name)221 static tAfter *GetAfter(tAfterList * list, const char *name)
222 {
223 tAfter *t = list->head;
224
225 while (t)
226 {
227 if (isSame(t->name, name))
228 {
229 return t;
230 }
231 t = t->next;
232 }
233 return NULL;
234 }
235
236
AddAfter(tAfterList * list,const char * name)237 BOOL AddAfter(tAfterList * list, const char *name)
238 {
239 if (GetAfter(list, name))
240 {
241 spec_yyerror("Same AFTER already existed. Ignored.");
242 }
243 else
244 {
245 tAfter *t = NewAfter(list);
246 t->name = name;
247 }
248 return TRUE;
249 }
250
251
OverlayAddAfter(const char * overlayName)252 BOOL OverlayAddAfter(const char *overlayName)
253 {
254 if (CurrentOverlay->tail->address)
255 {
256 spec_yyerror("ADDRESS already set. Ignored.");
257 return TRUE;
258 }
259 return AddAfter(&CurrentOverlay->tail->afters, overlayName);
260 }
261
262
263 /*============================================================================
264 * Object/Library - common
265 */
266
NewObject(tObjectList * list)267 tObject *NewObject(tObjectList * list)
268 {
269 tObject *t = Alloc(sizeof(tObject));
270
271 if (list->tail)
272 list->tail->next = t;
273 else
274 list->head = t;
275 list->tail = t;
276
277 return t;
278 }
279
280
GetObject(tObjectList * list,const char * objectName,const char * sectionName)281 tObject *GetObject(tObjectList * list, const char *objectName, const char *sectionName)
282 {
283 tObject *t = list->head;
284
285 while (t)
286 {
287 if (isSame(t->objectName, objectName) && isSame(t->sectionName, sectionName))
288 {
289 return t;
290 }
291 t = t->next;
292 }
293 return NULL;
294 }
295
296
AddObject(tObjectList * list,const char * objectName,tObjectType objectType)297 BOOL AddObject(tObjectList * list, const char *objectName, tObjectType objectType)
298 {
299 tObject *t = NewObject(list);
300 t->objectName = objectName;
301 t->sectionName = NULL;
302 t->objectType = objectType;
303 return TRUE;
304 }
305
306
SetObjectSection(tObjectList * list,const char * sectionName)307 BOOL SetObjectSection(tObjectList * list, const char *sectionName)
308 {
309 tObject *t = list->head;
310
311 debug_printf("sectionName=[%s]\n", sectionName);
312
313 while (t)
314 {
315 if (!t->sectionName)
316 {
317 debug_printf("list=%08x\n", list);
318
319 if (!isNeedSection(t) && sectionName[0] == '*')
320 {
321 spec_yyerror("OBJECT() must be with section option like as (.text),(.data),..");
322 return FALSE;
323 }
324
325 debug_printf("t->objectName=[%s]\n", t->objectName);
326
327 if (GetObject(list, t->objectName, sectionName))
328 {
329 char *s = Alloc(strlen(t->objectName) + strlen(sectionName) + 80);
330 sprintf(s, "OBJECT '%s (%s)' already existed. Ignored.", t->objectName,
331 sectionName);
332 spec_yyerror(s);
333 Free(&s);
334 }
335
336 t->sectionName = strdup(sectionName);
337 }
338 t = t->next;
339 }
340 return TRUE;
341 }
342
343
344 /*============================================================================
345 * OVERLAY - object
346 */
347
OverlayAddObject(const char * objectName,tObjectType objectType)348 BOOL OverlayAddObject(const char *objectName, tObjectType objectType)
349 {
350 return AddObject(&CurrentOverlay->tail->objects, objectName, objectType);
351 }
352
353
OverlaySetObjectSection(const char * sectionName)354 BOOL OverlaySetObjectSection(const char *sectionName)
355 {
356 return SetObjectSection(&CurrentOverlay->tail->objects, sectionName);
357 }
358
359
360 /*============================================================================
361 * OVERLAY - library
362 */
363
OverlayAddLibrary(const char * objectName,tObjectType objectType)364 BOOL OverlayAddLibrary(const char *objectName, tObjectType objectType)
365 {
366 return AddObject(&CurrentOverlay->tail->libraries, objectName, objectType);
367 }
368
369
OverlaySetLibrarySection(const char * sectionName)370 BOOL OverlaySetLibrarySection(const char *sectionName)
371 {
372 return SetObjectSection(&CurrentOverlay->tail->libraries, sectionName);
373 }
374
375
376 /*============================================================================
377 * OVERLAY - searchsymbol
378 */
379
OverlayAddSearchSymbol(const char * searchName)380 BOOL OverlayAddSearchSymbol(const char *searchName)
381 {
382 return AddObject(&CurrentOverlay->tail->searchSymbols, searchName, OBJTYPE_NONE);
383 }
384
385
386 /*============================================================================
387 * STATIC - name
388 */
389
StaticSetName(const char * staticName)390 BOOL StaticSetName(const char *staticName)
391 {
392 tStatic *t = &Static;
393
394 if (t->name)
395 {
396 spec_yyerror("'Static' section already existed. Aborted.");
397 return FALSE;
398 }
399 else if (GetOverlay(&OverlayList, staticName) || GetOverlay(&AutoloadList, staticName)
400 || GetOverlay(&LtdoverlayList, staticName) || GetOverlay(&LtdautoloadList, staticName))
401 {
402 spec_yyerror("Same named 'Overlay' or 'Autoload' or 'Ltdoverlay' or 'Ltdautoload' already existed. Aborted.");
403 return FALSE;
404 }
405 else
406 {
407 t->name = staticName;
408 }
409 return TRUE;
410 }
411
412
413 /*============================================================================
414 * STATIC - address
415 */
416
StaticSetAddress(u32 address)417 BOOL StaticSetAddress(u32 address)
418 {
419 tStatic *t = &Static;
420
421 if (t->address)
422 {
423 spec_yyerror("'Address' already set. Ignored.");
424 }
425 else
426 {
427 t->address = address;
428 }
429 return TRUE;
430 }
431
432
433 /*============================================================================
434 * STATIC - object
435 */
436
StaticAddObject(const char * objectName,tObjectType objectType)437 BOOL StaticAddObject(const char *objectName, tObjectType objectType)
438 {
439 return AddObject(&Static.objects, objectName, objectType);
440 }
441
442
StaticSetObjectSection(const char * sectionName)443 BOOL StaticSetObjectSection(const char *sectionName)
444 {
445 return SetObjectSection(&Static.objects, sectionName);
446 }
447
448
449 /*============================================================================
450 * STATIC - library
451 */
452
StaticAddLibrary(const char * objectName,tObjectType objectType)453 BOOL StaticAddLibrary(const char *objectName, tObjectType objectType)
454 {
455 return AddObject(&Static.libraries, objectName, objectType);
456 }
457
458
StaticSetLibrarySection(const char * sectionName)459 BOOL StaticSetLibrarySection(const char *sectionName)
460 {
461 return SetObjectSection(&Static.libraries, sectionName);
462 }
463
464
465 /*============================================================================
466 * STATIC - searchsymbol
467 */
468
StaticAddSearchSymbol(const char * searchName)469 BOOL StaticAddSearchSymbol(const char *searchName)
470 {
471 return AddObject(&Static.searchSymbols, searchName, OBJTYPE_NONE);
472 }
473
474
475 /*============================================================================
476 * STATIC - address
477 */
478
StaticSetStackSize(u32 stacksize)479 BOOL StaticSetStackSize(u32 stacksize)
480 {
481 tStatic *t = &Static;
482
483 if (t->stacksize)
484 {
485 spec_yyerror("'StackSize' already set. Ignored.");
486 }
487 else
488 {
489 t->stacksize = stacksize;
490 }
491 return TRUE;
492 }
493
494
StaticSetStackSizeIrq(u32 stacksize_irq)495 BOOL StaticSetStackSizeIrq(u32 stacksize_irq)
496 {
497 tStatic *t = &Static;
498
499 if (t->stacksize_irq)
500 {
501 spec_yyerror("'IrqStackSize' already set. Ignored.");
502 }
503 else
504 {
505 t->stacksize_irq = stacksize_irq;
506 }
507 return TRUE;
508 }
509
510
511 /*============================================================================
512 * PROPERTY - OverlayTable
513 * PROPERTY - OverlayTable
514 * PROPERTY - Suffix
515 */
516
517 #define SET_PROPERTY( func, member, token ) \
518 BOOL func( const char* val ) \
519 { \
520 tProperty* t = &Property; \
521 \
522 if ( t->member ) \
523 { \
524 spec_yyerror( "'" #token "' already set. Ignored." );\
525 } \
526 else \
527 { \
528 t->member = val; \
529 } \
530 return TRUE; \
531 }
532
SET_PROPERTY(PropertySetOverlayDefs,overlaydefs,OverlayDefs)533 SET_PROPERTY(PropertySetOverlayDefs, overlaydefs, OverlayDefs)
534 SET_PROPERTY(PropertySetOverlayTable, overlaytable, OverlayTable)
535 SET_PROPERTY(PropertySetLtdoverlayDefs, ltdoverlaydefs, LtdoverlayDefs)
536 SET_PROPERTY(PropertySetLtdoverlayTable, ltdoverlaytable, LtdoverlayTable)
537 SET_PROPERTY(PropertySetSuffix, suffix, Suffix)
538 SET_PROPERTY(PropertySetFlxsuffix, flxsuffix, Flxsuffix)
539 SET_PROPERTY(PropertySetLtdsuffix, ltdsuffix, Ltdsuffix)
540 /*============================================================================
541 * CHECK SPECS
542 */
543 static BOOL CheckAfters(const char *name, tAfterList * list)
544 {
545 tAfter *t = list->head;
546
547 while (t)
548 {
549 if (!isSame(t->name, Static.name) && !GetOverlay(&OverlayList, t->name)
550 && !GetOverlay(&AutoloadList, t->name)
551 && !GetOverlay(&LtdoverlayList, t->name)
552 && !GetOverlay(&LtdautoloadList, t->name))
553 {
554 fprintf(stderr, "No such static/autoload/overlay/ltdautoload/ltdoverlay %s referred in overlay %s", t->name,
555 name);
556 return FALSE;
557 }
558 t = t->next;
559 }
560 return TRUE;
561 }
562
563
s_CheckOverlay(tOverlayList * list)564 static BOOL s_CheckOverlay(tOverlayList * list)
565 {
566 tOverlay *t = list->head;
567
568 while (t)
569 {
570 if (t->address)
571 {
572 if (t->afters.tail)
573 {
574 fprintf(stderr, "Set both of 'Address' and 'After' in overlay %s", t->name);
575 return FALSE;
576 }
577 }
578 else
579 {
580 if (t->afters.tail)
581 {
582 if (!CheckAfters(t->name, &t->afters))
583 {
584 return FALSE;
585 }
586 }
587 else
588 {
589 fprintf(stderr, "No addressing commands 'Address'/ 'After' in overlay %s", t->name);
590 return FALSE;
591 }
592 }
593 t = t->next;
594 }
595 return TRUE;
596 }
597
CheckOverlay(void)598 static BOOL CheckOverlay(void)
599 {
600 return s_CheckOverlay(&AutoloadList) && s_CheckOverlay(&OverlayList) && s_CheckOverlay(&LtdautoloadList) && s_CheckOverlay(&LtdoverlayList);
601 }
602
CheckStatic(void)603 static BOOL CheckStatic(void)
604 {
605 tStatic *t = &Static;
606
607 if (!t->address)
608 {
609 fprintf(stderr, "No addressing commands 'After' in static %s", t->name);
610 return FALSE;
611 }
612
613 if (!t->stacksize_irq)
614 {
615 t->stacksize_irq = DEFAULT_IRQSTACKSIZE;
616 }
617
618 return TRUE;
619 }
620
621
CheckProperty(void)622 static BOOL CheckProperty(void)
623 {
624 tProperty *t = &Property;
625
626 // Set default values
627 if (!t->overlaydefs)
628 {
629 t->overlaydefs = strdup(DEFAULT_OVERLAYDEFS);
630 }
631 if (t->overlaydefs[0] == '%')
632 {
633 char *name = Alloc(strlen(Static.name) + strlen(t->overlaydefs + 1) + 1);
634 strcpy(name, Static.name);
635 strcat(name, t->overlaydefs + 1);
636 Free(&t->overlaydefs);
637 t->overlaydefs = name;
638 }
639
640 if (!t->overlaytable)
641 {
642 t->overlaytable = strdup(DEFAULT_OVERLAYTABLE);
643 }
644 if (t->overlaytable[0] == '%')
645 {
646 char *name = Alloc(strlen(Static.name) + strlen(t->overlaytable + 1) + 1);
647 strcpy(name, Static.name);
648 strcat(name, t->overlaytable + 1);
649 Free(&t->overlaytable);
650 t->overlaytable = name;
651 }
652
653 if (!t->ltdoverlaydefs)
654 {
655 t->ltdoverlaydefs = strdup(DEFAULT_LTDOVERLAYDEFS);
656 }
657 if (t->ltdoverlaydefs[0] == '%')
658 {
659 char *name = Alloc(strlen(Static.name) + strlen(t->ltdoverlaydefs + 1) + 1);
660 strcpy(name, Static.name);
661 strcat(name, t->ltdoverlaydefs + 1);
662 Free(&t->ltdoverlaydefs);
663 t->ltdoverlaydefs = name;
664 }
665
666 if (!t->ltdoverlaytable)
667 {
668 t->ltdoverlaytable = strdup(DEFAULT_LTDOVERLAYTABLE);
669 }
670 if (t->ltdoverlaytable[0] == '%')
671 {
672 char *name = Alloc(strlen(Static.name) + strlen(t->ltdoverlaytable + 1) + 1);
673 strcpy(name, Static.name);
674 strcat(name, t->ltdoverlaytable + 1);
675 Free(&t->ltdoverlaytable);
676 t->ltdoverlaytable = name;
677 }
678
679 if (!t->suffix)
680 {
681 t->suffix = strdup(DEFAULT_SUFFIX);
682 }
683
684 if (!t->flxsuffix)
685 {
686 t->flxsuffix = strdup(DEFAULT_FLXSUFFIX);
687 }
688
689 if (!t->ltdsuffix)
690 {
691 t->ltdsuffix = strdup(DEFAULT_LTDSUFFIX);
692 }
693 return TRUE;
694 }
695
696
CheckSpec(void)697 BOOL CheckSpec(void)
698 {
699 return (CheckStatic() && CheckOverlay() && CheckProperty());
700 }
701
702
703 /*============================================================================
704 * DUMP UTILITIES
705 */
706
DumpAfters(tAfterList * list)707 static void DumpAfters(tAfterList * list)
708 {
709 tAfter *t = list->head;
710
711 while (t)
712 {
713 printf(" After : %s\n", t->name);
714 t = t->next;
715 }
716 }
717
718
DumpObjects(tObjectList * list)719 static void DumpObjects(tObjectList * list)
720 {
721 tObject *t = list->head;
722
723 while (t)
724 {
725 printf(" Object : %s %s\n", t->objectName, t->sectionName);
726 t = t->next;
727 }
728 }
729
730
DumpAutoload(void)731 static void DumpAutoload(void)
732 {
733 tOverlay *t = AutoloadList.head;
734
735 while (t)
736 {
737 printf("Autoload : %s\n", t->name);
738 printf(" Address : %08lx\n", t->address);
739 DumpAfters(&t->afters);
740 DumpObjects(&t->objects);
741 printf("\n");
742 t = t->next;
743 }
744 }
745
746
DumpOverlay(void)747 static void DumpOverlay(void)
748 {
749 tOverlay *t = OverlayList.head;
750
751 while (t)
752 {
753 printf("Overlay : %s\n", t->name);
754 printf(" Address : %08lx\n", t->address);
755 DumpAfters(&t->afters);
756 DumpObjects(&t->objects);
757 printf("\n");
758 t = t->next;
759 }
760 }
761
762
DumpLtdautoload(void)763 static void DumpLtdautoload(void)
764 {
765 tOverlay *t = LtdautoloadList.head;
766
767 while (t)
768 {
769 printf("Ltdautoload : %s\n", t->name);
770 printf(" Address : %08lx\n", t->address);
771 DumpAfters(&t->afters);
772 DumpObjects(&t->objects);
773 printf("\n");
774 t = t->next;
775 }
776 }
777
778
DumpLtdoverlay(void)779 static void DumpLtdoverlay(void)
780 {
781 tOverlay *t = LtdoverlayList.head;
782
783 while (t)
784 {
785 printf("Ltdoverlay : %s\n", t->name);
786 printf(" Address : %08lx\n", t->address);
787 DumpAfters(&t->afters);
788 DumpObjects(&t->objects);
789 printf("\n");
790 t = t->next;
791 }
792 }
793
794
DumpStatic(void)795 static void DumpStatic(void)
796 {
797 tStatic *t = &Static;
798
799 printf("Static : %s\n", t->name);
800 printf(" Address : %08lx\n", t->address);
801 DumpObjects(&t->objects);
802 printf(" StackSize : %08lx\n", t->stacksize);
803 printf("\n");
804 }
805
806
DumpProperty(void)807 static void DumpProperty(void)
808 {
809 tProperty *t = &Property;
810
811 printf("Property :\n");
812 printf(" OverlayDefs : %s\n", t->overlaydefs);
813 printf(" OverlayTable : %s\n", t->overlaytable);
814 printf(" LtdoverlayDefs : %s\n", t->ltdoverlaydefs);
815 printf(" LtdoverlayTable : %s\n", t->ltdoverlaytable);
816 printf(" Suffix : %s\n", t->suffix);
817 printf(" Flxsuffix : %s\n", t->flxsuffix);
818 printf(" Ltdsuffix : %s\n", t->ltdsuffix);
819 printf("\n");
820 }
821
822
DumpSpec(void)823 void DumpSpec(void)
824 {
825 DumpStatic();
826 DumpAutoload();
827 DumpOverlay();
828 DumpLtdautoload();
829 DumpLtdoverlay();
830 DumpProperty();
831 }
832