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