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