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