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 t->compressSpec = 'S';
173 CurrentOverlay = list;
174 }
175 return TRUE;
176 }
177
AddOverlay(const char * overlayName)178 BOOL AddOverlay(const char *overlayName)
179 {
180 return s_AddOverlay(&OverlayList, overlayName);
181 }
182
AddAutoload(const char * overlayName)183 BOOL AddAutoload(const char *overlayName)
184 {
185 return s_AddOverlay(&AutoloadList, overlayName);
186 }
187
188 /*============================================================================
189 * OVERLAY - id
190 */
191
OverlaySetId(u32 id)192 BOOL OverlaySetId(u32 id)
193 {
194 tOverlay *t = CurrentOverlay->tail;
195
196 if (t->id)
197 {
198 spec_yyerror("OVERLAY ID already set. Ignored.");
199 }
200 else
201 {
202 t->id = id;
203 }
204 return TRUE;
205 }
206
207
208 /*============================================================================
209 * OVERLAY - group
210 */
211
OverlaySetGroup(const char * group)212 BOOL OverlaySetGroup(const char *group)
213 {
214 tOverlay *t = CurrentOverlay->tail;
215
216 if (t->group)
217 {
218 spec_yyerror("overlay GROUP already set. Ignored.");
219 }
220 else
221 {
222 t->group = group;
223 }
224 return TRUE;
225 }
226
227
228 /*============================================================================
229 * OVERLAY - address
230 */
231
OverlaySetAddress(u32 address)232 BOOL OverlaySetAddress(u32 address)
233 {
234 tOverlay *t = CurrentOverlay->tail;
235
236 if (t->afters.tail || t->address)
237 {
238 spec_yyerror("ADDRESS/AFTER already set. Ignored.");
239 }
240 else
241 {
242 t->address = address;
243 }
244 return TRUE;
245 }
246
247
248 /*============================================================================
249 * OVERLAY - after
250 */
251
NewAfter(tAfterList * list)252 static tAfter *NewAfter(tAfterList * list)
253 {
254 tAfter *t = Alloc(sizeof(tAfter));
255
256 if (list->tail)
257 list->tail->next = t;
258 else
259 list->head = t;
260 list->tail = t;
261
262 return t;
263 }
264
265
GetAfter(tAfterList * list,const char * name)266 static tAfter *GetAfter(tAfterList * list, const char *name)
267 {
268 tAfter *t = list->head;
269
270 while (t)
271 {
272 if (isSame(t->name, name))
273 {
274 return t;
275 }
276 t = t->next;
277 }
278 return NULL;
279 }
280
281
AddAfter(tAfterList * list,const char * name)282 BOOL AddAfter(tAfterList * list, const char *name)
283 {
284 if (GetAfter(list, name))
285 {
286 spec_yyerror("Same AFTER already existed. Ignored.");
287 }
288 else
289 {
290 tAfter *t = NewAfter(list);
291 t->name = name;
292 }
293 return TRUE;
294 }
295
296
OverlayAddAfter(const char * overlayName)297 BOOL OverlayAddAfter(const char *overlayName)
298 {
299 if (CurrentOverlay->tail->address)
300 {
301 spec_yyerror("ADDRESS already set. Ignored.");
302 return TRUE;
303 }
304 return AddAfter(&CurrentOverlay->tail->afters, overlayName);
305 }
306
307
308 /*============================================================================
309 * Object/Library - common
310 */
311
NewObject(tObjectList * list)312 tObject *NewObject(tObjectList * list)
313 {
314 tObject *t = Alloc(sizeof(tObject));
315
316 if (list->tail)
317 list->tail->next = t;
318 else
319 list->head = t;
320 list->tail = t;
321
322 return t;
323 }
324
325
GetObject(tObjectList * list,const char * objectName,const char * sectionName)326 tObject *GetObject(tObjectList * list, const char *objectName, const char *sectionName)
327 {
328 tObject *t = list->head;
329
330 while (t)
331 {
332 if (isSame(t->objectName, objectName) && isSame(t->sectionName, sectionName))
333 {
334 return t;
335 }
336 t = t->next;
337 }
338 return NULL;
339 }
340
341
AddObject(tObjectList * list,const char * objectName,tObjectType objectType)342 BOOL AddObject(tObjectList * list, const char *objectName, tObjectType objectType)
343 {
344 tObject *t = NewObject(list);
345 t->objectName = objectName;
346 t->sectionName = NULL;
347 t->objectType = objectType;
348 return TRUE;
349 }
350
351
SetObjectSection(tObjectList * list,const char * sectionName)352 BOOL SetObjectSection(tObjectList * list, const char *sectionName)
353 {
354 tObject *t = list->head;
355
356 debug_printf("sectionName=[%s]\n", sectionName);
357
358 while (t)
359 {
360 if (!t->sectionName)
361 {
362 debug_printf("list=%08x\n", list);
363
364 if (!isNeedSection(t) && sectionName[0] == '*')
365 {
366 spec_yyerror("OBJECT() must be with section option like as (.text),(.data),..");
367 return FALSE;
368 }
369
370 debug_printf("t->objectName=[%s]\n", t->objectName);
371
372 if (GetObject(list, t->objectName, sectionName))
373 {
374 char *s = Alloc(strlen(t->objectName) + strlen(sectionName) + 80);
375 sprintf(s, "OBJECT '%s (%s)' already existed. Ignored.", t->objectName,
376 sectionName);
377 spec_yyerror(s);
378 Free(&s);
379 }
380
381 t->sectionName = strdup(sectionName);
382 }
383 t = t->next;
384 }
385 return TRUE;
386 }
387
388
389 /*============================================================================
390 * OVERLAY - object
391 */
392
OverlayAddObject(const char * objectName,tObjectType objectType)393 BOOL OverlayAddObject(const char *objectName, tObjectType objectType)
394 {
395 return AddObject(&CurrentOverlay->tail->objects, objectName, objectType);
396 }
397
398
OverlaySetObjectSection(const char * sectionName)399 BOOL OverlaySetObjectSection(const char *sectionName)
400 {
401 return SetObjectSection(&CurrentOverlay->tail->objects, sectionName);
402 }
403
404
405 /*============================================================================
406 * OVERLAY - library
407 */
408
OverlayAddLibrary(const char * objectName,tObjectType objectType)409 BOOL OverlayAddLibrary(const char *objectName, tObjectType objectType)
410 {
411 return AddObject(&CurrentOverlay->tail->libraries, objectName, objectType);
412 }
413
414
OverlaySetLibrarySection(const char * sectionName)415 BOOL OverlaySetLibrarySection(const char *sectionName)
416 {
417 return SetObjectSection(&CurrentOverlay->tail->libraries, sectionName);
418 }
419
420
421 /*============================================================================
422 * OVERLAY - searchsymbol
423 */
424
OverlayAddSearchSymbol(const char * searchName)425 BOOL OverlayAddSearchSymbol(const char *searchName)
426 {
427 return AddObject(&CurrentOverlay->tail->searchSymbols, searchName, OBJTYPE_NONE);
428 }
429
430
431 /*============================================================================
432 * OVERLAY - force
433 */
434
OverlayAddForce(const char * forceName)435 BOOL OverlayAddForce(const char *forceName)
436 {
437 return AddObject(&CurrentOverlay->tail->forces, forceName, OBJTYPE_NONE);
438 }
439
440
441 /*============================================================================
442 * OVERLAY - compress
443 */
444
OverlaySetCompress(const char * compressSpec)445 BOOL OverlaySetCompress(const char *compressSpec)
446 {
447 char c;
448
449 if(!strcmp(compressSpec, "SMART")) c = 'S';
450 else if(!strcmp(compressSpec, "EXCLUSION")) c = 'E';
451 else return FALSE;
452
453 CurrentOverlay->tail->compressSpec = c;
454 return TRUE;
455 }
456
457
458 /*============================================================================
459 * STATIC - name
460 */
461
StaticSetTargetName(const char * staticTargetName)462 BOOL StaticSetTargetName(const char *staticTargetName)
463 {
464 tStatic *t = &Static;
465
466 if (t->targetName)
467 {
468 return FALSE;
469 }
470 t->targetName = strdup(staticTargetName);
471 return TRUE;
472 }
473
StaticSetName(const char * staticName)474 BOOL StaticSetName(const char *staticName)
475 {
476 tStatic *t = &Static;
477
478 if (t->name)
479 {
480 spec_yyerror("'Static' section already existed. Aborted.");
481 return FALSE;
482 }
483 else if (GetOverlay(&OverlayList, staticName) || GetOverlay(&AutoloadList, staticName))
484 {
485 spec_yyerror("Same named 'Overlay' or 'Autoload' already existed. Aborted.");
486 return FALSE;
487 }
488 else
489 {
490 t->name = staticName;
491 }
492 return TRUE;
493 }
494
495
496 /*============================================================================
497 * STATIC - address
498 */
499
StaticSetAddress(u32 address)500 BOOL StaticSetAddress(u32 address)
501 {
502 tStatic *t = &Static;
503
504 if (t->address)
505 {
506 spec_yyerror("'Address' already set. Ignored.");
507 }
508 else
509 {
510 t->address = address;
511 }
512 return TRUE;
513 }
514
515
516 /*============================================================================
517 * STATIC - object
518 */
519
StaticAddObject(const char * objectName,tObjectType objectType)520 BOOL StaticAddObject(const char *objectName, tObjectType objectType)
521 {
522 return AddObject(&Static.objects, objectName, objectType);
523 }
524
525
StaticSetObjectSection(const char * sectionName)526 BOOL StaticSetObjectSection(const char *sectionName)
527 {
528 return SetObjectSection(&Static.objects, sectionName);
529 }
530
531
532 /*============================================================================
533 * STATIC - library
534 */
535
StaticAddLibrary(const char * objectName,tObjectType objectType)536 BOOL StaticAddLibrary(const char *objectName, tObjectType objectType)
537 {
538 return AddObject(&Static.libraries, objectName, objectType);
539 }
540
541
StaticSetLibrarySection(const char * sectionName)542 BOOL StaticSetLibrarySection(const char *sectionName)
543 {
544 return SetObjectSection(&Static.libraries, sectionName);
545 }
546
547
548 /*============================================================================
549 * STATIC - searchsymbol
550 */
551
StaticAddSearchSymbol(const char * searchName)552 BOOL StaticAddSearchSymbol(const char *searchName)
553 {
554 return AddObject(&Static.searchSymbols, searchName, OBJTYPE_NONE);
555 }
556
557
558 /*============================================================================
559 * STATIC - force
560 */
561
StaticAddForce(const char * forceName)562 BOOL StaticAddForce(const char *forceName)
563 {
564 return AddObject(&Static.forces, forceName, OBJTYPE_NONE);
565 }
566
567
568 /*============================================================================
569 * STATIC - address
570 */
571
StaticSetStackSize(u32 stacksize)572 BOOL StaticSetStackSize(u32 stacksize)
573 {
574 tStatic *t = &Static;
575
576 if (t->stacksize)
577 {
578 spec_yyerror("'StackSize' already set. Ignored.");
579 }
580 else
581 {
582 t->stacksize = stacksize;
583 }
584 return TRUE;
585 }
586
587
StaticSetStackSizeIrq(u32 stacksize_irq)588 BOOL StaticSetStackSizeIrq(u32 stacksize_irq)
589 {
590 tStatic *t = &Static;
591
592 if (t->stacksize_irq)
593 {
594 spec_yyerror("'IrqStackSize' already set. Ignored.");
595 }
596 else
597 {
598 t->stacksize_irq = stacksize_irq;
599 }
600 return TRUE;
601 }
602
603
604 /*============================================================================
605 * PROPERTY - OverlayTable
606 * PROPERTY - OverlayTable
607 * PROPERTY - Suffix
608 */
609
610 #define SET_PROPERTY( func, member, token ) \
611 BOOL func( const char* val ) \
612 { \
613 tProperty* t = &Property; \
614 \
615 if ( t->member ) \
616 { \
617 spec_yyerror( "'" #token "' already set. Ignored." );\
618 } \
619 else \
620 { \
621 t->member = val; \
622 } \
623 return TRUE; \
624 }
625
SET_PROPERTY(PropertySetOverlayDefs,overlaydefs,OverlayDefs)626 SET_PROPERTY(PropertySetOverlayDefs, overlaydefs, OverlayDefs)
627 SET_PROPERTY(PropertySetOverlayTable, overlaytable, OverlayTable)
628 SET_PROPERTY(PropertySetSuffix, suffix, Suffix)
629 /*============================================================================
630 * CHECK SPECS
631 */
632 static BOOL CheckAfters(const char *name, tAfterList * list)
633 {
634 tAfter *t = list->head;
635
636 while (t)
637 {
638 if (!isSame(t->name, Static.name) && !GetOverlay(&OverlayList, t->name)
639 && !GetOverlay(&AutoloadList, t->name))
640 {
641 fprintf(stderr, "No such static/autoload/overlay %s referred in overlay %s", t->name,
642 name);
643 return FALSE;
644 }
645 t = t->next;
646 }
647 return TRUE;
648 }
649
650
s_CheckOverlay(tOverlayList * list)651 static BOOL s_CheckOverlay(tOverlayList * list)
652 {
653 tOverlay *t = list->head;
654
655 while (t)
656 {
657 if (t->address)
658 {
659 if (t->afters.tail)
660 {
661 fprintf(stderr, "Set both of 'Address' and 'After' in overlay %s", t->name);
662 return FALSE;
663 }
664 }
665 else
666 {
667 if (t->afters.tail)
668 {
669 if (!CheckAfters(t->name, &t->afters))
670 {
671 return FALSE;
672 }
673 }
674 else
675 {
676 fprintf(stderr, "No addressing commands 'Address'/ 'After' in overlay %s", t->name);
677 return FALSE;
678 }
679 }
680 t = t->next;
681 }
682 return TRUE;
683 }
684
CheckOverlay(void)685 static BOOL CheckOverlay(void)
686 {
687 return s_CheckOverlay(&AutoloadList) && s_CheckOverlay(&OverlayList);
688 }
689
CheckStatic(void)690 static BOOL CheckStatic(void)
691 {
692 tStatic *t = &Static;
693
694 if (!t->address)
695 {
696 fprintf(stderr, "No addressing commands 'After' in static %s", t->name);
697 return FALSE;
698 }
699
700 if (!t->stacksize_irq)
701 {
702 t->stacksize_irq = DEFAULT_IRQSTACKSIZE;
703 }
704
705 return TRUE;
706 }
707
708
CheckProperty(void)709 static BOOL CheckProperty(void)
710 {
711 tProperty *t = &Property;
712 const char *target = Static.targetName ? Static.targetName : Static.name;
713
714 // Set default values
715 if (!t->overlaydefs)
716 {
717 t->overlaydefs = strdup(DEFAULT_OVERLAYDEFS);
718 }
719 if (t->overlaydefs[0] == '%')
720 {
721 char *name = Alloc(strlen(target) + strlen(t->overlaydefs + 1) + 1);
722 strcpy(name, target);
723 strcat(name, t->overlaydefs + 1);
724 Free(&t->overlaydefs);
725 t->overlaydefs = name;
726 }
727
728 if (!t->overlaytable)
729 {
730 t->overlaytable = strdup(DEFAULT_OVERLAYTABLE);
731 }
732 if (t->overlaytable[0] == '%')
733 {
734 char *name = Alloc(strlen(target) + strlen(t->overlaytable + 1) + 1);
735 strcpy(name, target);
736 strcat(name, t->overlaytable + 1);
737 Free(&t->overlaytable);
738 t->overlaytable = name;
739 }
740
741 if (!t->suffix)
742 {
743 t->suffix = strdup(DEFAULT_SUFFIX);
744 }
745 return TRUE;
746 }
747
748
CheckSpec(void)749 BOOL CheckSpec(void)
750 {
751 return (CheckStatic() && CheckOverlay() && CheckProperty());
752 }
753
754
755 /*============================================================================
756 * DUMP UTILITIES
757 */
758
DumpAfters(tAfterList * list)759 static void DumpAfters(tAfterList * list)
760 {
761 tAfter *t = list->head;
762
763 while (t)
764 {
765 printf(" After : %s\n", t->name);
766 t = t->next;
767 }
768 }
769
770
DumpObjects(tObjectList * list)771 static void DumpObjects(tObjectList * list)
772 {
773 tObject *t = list->head;
774
775 while (t)
776 {
777 printf(" Object : %s %s\n", t->objectName, t->sectionName);
778 t = t->next;
779 }
780 }
781
782
DumpAutoload(void)783 static void DumpAutoload(void)
784 {
785 tOverlay *t = AutoloadList.head;
786
787 while (t)
788 {
789 printf("Autoload : %s\n", t->name);
790 printf(" Address : %08lx\n", t->address);
791 DumpAfters(&t->afters);
792 DumpObjects(&t->objects);
793 printf("\n");
794 t = t->next;
795 }
796 }
797
798
DumpOverlay(void)799 static void DumpOverlay(void)
800 {
801 tOverlay *t = OverlayList.head;
802
803 while (t)
804 {
805 printf("Overlay : %s\n", t->name);
806 printf(" Address : %08lx\n", t->address);
807 DumpAfters(&t->afters);
808 DumpObjects(&t->objects);
809 printf("\n");
810 t = t->next;
811 }
812 }
813
814
DumpStatic(void)815 static void DumpStatic(void)
816 {
817 tStatic *t = &Static;
818
819 printf("Static : %s\n", t->name);
820 printf(" Address : %08lx\n", t->address);
821 DumpObjects(&t->objects);
822 printf(" StackSize : %08lx\n", t->stacksize);
823 printf("\n");
824 }
825
826
DumpProperty(void)827 static void DumpProperty(void)
828 {
829 tProperty *t = &Property;
830
831 printf("Property :\n");
832 printf(" OverlayDefs : %s\n", t->overlaydefs);
833 printf(" OverlayTable : %s\n", t->overlaytable);
834 printf(" Suffix : %s\n", t->suffix);
835 printf("\n");
836 }
837
838
DumpSpec(void)839 void DumpSpec(void)
840 {
841 DumpStatic();
842 DumpAutoload();
843 DumpOverlay();
844 DumpProperty();
845 }
846