1 /*---------------------------------------------------------------------------*
2   Project:  NitroSDK - tools - makelcf
3   File:     createlcf.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: createlcf.c,v $
14   Revision 1.25  2007/07/09 12:17:54  yasu
15   Support for TARGET_NAME.
16 
17   Revision 1.24  2007/07/09 07:02:00  yasu
18   Support for IF.EXIST
19 
20   Revision 1.23  2007/06/21 00:19:05  yasu
21   Support for FOREACH.AUTOLOADS=XXX notation
22 
23   Revision 1.22  2007/04/12 03:29:45  yasu
24   Revised such that IF FIRST/LAST can also support FOREACH OBJECT/LIBRARY
25 
26   Revision 1.21  2007/04/10 14:13:20  yasu
27   Support for multiple uses of SEARCH_SYMBOL.
28 
29   Revision 1.20  2006/05/10 02:06:00  yasu
30   Added support for CodeWarrior 2.x
31 
32   Revision 1.19  2006/04/06 09:05:56  kitase_hirotake
33   Support for .itcm.bss, .dtcm.bss, and .wram.bss
34 
35   Revision 1.18  2006/01/18 02:11:19  kitase_hirotake
36   do-indent.
37 
38   Revision 1.17  2005/09/01 04:30:52  yasu
39   Support for Overlay Group
40 
41   Revision 1.16  2005/08/26 11:23:11  yasu
42   Overlay support for ITCM/DTCM.
43 
44   Revision 1.15  2005/06/20 12:21:48  yasu
45   Changed Surffix to Suffix.
46 
47   Revision 1.14  2005/02/28 05:26:03  yosizaki
48   do-indent.
49 
50   Revision 1.13  2004/09/24 13:24:04  yasu
51   Support for NitroStaticInit
52 
53   Revision 1.12  2004/08/25 04:01:34  yasu
54   Changes in handling when the object is aaa.o (*)
55 
56   Revision 1.11  2004/07/10 04:06:17  yasu
57   Added support for command 'Library'.
58   Support for modifier ':x' in template
59   Fixed line continue '\' issue
60 
61   Revision 1.10  2004/07/02 07:34:53  yasu
62   Added support for OBJECT( ).
63 
64   Revision 1.9  2004/06/24 07:18:54  yasu
65   Support for keyword "Autoload"
66 
67   Revision 1.8  2004/06/14 11:28:45  yasu
68   Support for section filter "FOREACH.STATIC.OBJECTS=.sectionName"
69 
70   Revision 1.7  2004/03/26 05:07:11  yasu
71   Support for variables like as -DNAME=VALUE
72 
73   Revision 1.6  2004/02/13 07:13:03  yasu
74   Support for SDK_IRQ_STACKSIZE
75 
76   Revision 1.5  2004/02/05 07:09:03  yasu
77   Changed SDK prefix iris to nitro.
78 
79   Revision 1.4  2004/01/15 10:51:45  yasu
80   Implementation of a static StackSize
81 
82   Revision 1.3  2004/01/14 12:38:08  yasu
83   Changed OverlayName to OverlayDefs
84 
85   Revision 1.2  2004/01/07 13:10:17  yasu
86   Fixed all warnings at compile -Wall
87 
88   Revision 1.1  2004/01/05 02:32:59  yasu
89   Initial version
90 
91   $NoKeywords: $
92  *---------------------------------------------------------------------------*/
93 #include	<stdio.h>
94 #include	<strings.h>
95 #include	<io.h>                 // setmode()
96 #include	<fcntl.h>              // setmode()
97 #include	<stdarg.h>             // va_start(),va_end()
98 #include	<nitro_win32.h>
99 #include	"makelcf.h"
100 #include	"defval.h"
101 #include	"tlcf.tab.h"
102 
103 static void PutString(const char *str);
104 static void PutAddress(u32 address);
105 static BOOL PutObject(const tObject * object, const char *secName);
106 static void PutStaticObject(const char *secName);
107 static void PutOverlayName(void);
108 static void PutOverlayGroup(void);
109 static void PutOverlayObject(const char *secName);
110 static void PutOverlayAddress(void);
111 static void PutOverlayCompress(void);
112 static BOOL isObjectOK(const tObject * obj, const char *section, char filter_type);
113 static BOOL isSectionWildcard(const char *section);
114 static BOOL isSectionRegular(const char *section);
115 static int ForeachObjects(tObject ** ptrObject, tObject * start, tForeachStatus * fep, int n);
116 static int ForeachStaticObjects(int n);
117 static int ForeachOverlayObjects(int n);
118 static int ForeachOverlays(int n);
119 static int PutToken(int n);
120 static void PutTokenBuffer(int start, int end);
121 static void PutTokenBufferAll(void);
122 
123 
124 FILE   *fp_out;
125 tObject *StaticObject = NULL;
126 tObject *StaticLibrary = NULL;
127 tObject *StaticSearchSymbol = NULL;
128 tObject *StaticForce = NULL;
129 tOverlay *Autoload = NULL;
130 tObject *AutoloadObject = NULL;
131 tObject *AutoloadLibrary = NULL;
132 tObject *AutoloadSearchSymbol = NULL;
133 tObject *AutoloadForce = NULL;
134 tOverlay *Overlay = NULL;
135 tObject *OverlayObject = NULL;
136 tObject *OverlayLibrary = NULL;
137 tObject *OverlaySearchSymbol = NULL;
138 tObject *OverlayForce = NULL;
139 
lcf_error(const char * fmt,...)140 void lcf_error(const char *fmt, ...)
141 {
142     va_list va;
143     va_start(va, fmt);
144     vfprintf(stderr, fmt, va);
145     va_end(va);
146     fprintf(stderr, "\n");
147 }
148 
149 /*============================================================================
150  *  Put Tokens
151  */
PutString(const char * str)152 static void PutString(const char *str)
153 {
154     if (str)
155         fprintf(fp_out, "%s", str);
156 }
157 
PutAddress(u32 address)158 static void PutAddress(u32 address)
159 {
160     fprintf(fp_out, "0x%08lx", address);
161 }
162 
PutNumber(u32 num)163 static void PutNumber(u32 num)
164 {
165     fprintf(fp_out, "%ld", num);
166 }
167 
168 
GetCharPos(const char * str,char target)169 static int GetCharPos(const char *str, char target)
170 {
171     int     n = 0;
172 
173     if (str)
174     {
175         while ('\0' != str[n] && target != str[n])
176         {
177             n++;
178         }
179     }
180     return n;
181 }
182 
GetObjectParam(const char * str,char start,char end)183 static char *GetObjectParam(const char *str, char start, char end)
184 {
185     int     pos_start = GetCharPos(str, start);
186     int     pos_end = GetCharPos(str, end);
187     int     len = pos_end - pos_start;
188     char   *buffer;
189 
190     if (len > 0)
191     {
192         buffer = Alloc(len);
193         strncpy(buffer, str + pos_start + 1, len - 1);
194         buffer[len - 1] = '\0';
195         return buffer;
196     }
197     return NULL;
198 }
199 
GetObjectSection(const char * str)200 static char *GetObjectSection(const char *str)
201 {
202     return GetObjectParam(str, '=', ':');       // return NULL if no section
203 }
204 
GetObjectModifier(const char * str)205 static char GetObjectModifier(const char *str)
206 {
207     char   *mod = GetObjectParam(str, ':', '\0');
208     char    ret;
209 
210     ret = mod ? mod[0] : '\0';
211     Free(&mod);
212 
213     return ret;
214 
215 }
216 
GetMemTypeParam(const char * str)217 static tMemType GetMemTypeParam(const char *str)
218 {
219     char   *mod = GetObjectParam(str, '=', ':');
220     int     i;
221 
222     static struct
223     {
224         tMemType type;
225         char   *name;
226     }
227     table[] =
228     {
229         {
230         MEMTYPE_MAIN, "MAIN"}
231         ,
232         {
233         MEMTYPE_MAINEX, "MAINEX"}
234         ,
235         {
236         MEMTYPE_ITCM, "ITCM"}
237         ,
238         {
239         MEMTYPE_DTCM, "DTCM"}
240         ,
241         {
242         MEMTYPE_ITCM_BSS, "ITCM.BSS"}
243         ,
244         {
245         MEMTYPE_DTCM_BSS, "DTCM.BSS"}
246         ,
247         {
248         MEMTYPE_SHARED, "SHARED"}
249         ,
250         {
251         MEMTYPE_WRAM, "WRAM"}
252         ,
253         {
254         MEMTYPE_WRAM_BSS, "WRAM.BSS"}
255         ,
256         {
257         MEMTYPE_VRAM, "VRAM"}
258         ,
259         {
260         MEMTYPE_NONE, "*"}
261     ,};
262 
263     for (i = 0; table[i].type != MEMTYPE_NONE; i++)
264     {
265         if (isSame(mod, table[i].name))
266         {
267             break;
268         }
269     }
270     Free(&mod);
271 
272     return table[i].type;
273 }
274 
275 //
276 // Decides to which memory region the section specified by name, address belongs
277 //
GetSectionMemType(const char * name,u32 address)278 static tMemType GetSectionMemType(const char *name, u32 address)
279 {
280     BOOL    isARM9 = (Static.address < 0x02300000);     // Actual decision value
281     tMemType memtype = MEMTYPE_NONE;
282 
283     if (isARM9)
284     {
285         if (isSame(name, "ITCM"))
286             memtype = MEMTYPE_ITCM;
287         else if (isSame(name, "DTCM"))
288             memtype = MEMTYPE_DTCM;
289         else if (isSame(name, "WRAM"))
290             memtype = MEMTYPE_WRAM;
291         else if (isSame(name, "ITCM.BSS"))
292             memtype = MEMTYPE_ITCM_BSS;
293         else if (isSame(name, "DTCM.BSS"))
294             memtype = MEMTYPE_DTCM_BSS;
295         else if (isSame(name, "WRAM.BSS"))
296             memtype = MEMTYPE_WRAM_BSS;
297         else if (HW_ITCM_IMAGE <= address && address < HW_ITCM_END)
298             memtype = MEMTYPE_ITCM;
299         else if (HW_MAIN_MEM_SUB <= address && address < HW_MAIN_MEM_SUB_END)
300             memtype = MEMTYPE_DTCM;
301         else if (HW_MAIN_MEM_MAIN <= address && address < HW_MAIN_MEM_MAIN_END)
302             memtype = MEMTYPE_MAIN;
303         else if (HW_MAIN_MEM_MAIN_END <= address && address < HW_MAIN_MEM_DEBUGGER)
304             memtype = MEMTYPE_MAINEX;
305         else if (HW_MAIN_MEM_SHARED <= address && address < HW_MAIN_MEM_SHARED_END)
306             memtype = MEMTYPE_SHARED;
307         else if (HW_WRAM <= address && address < HW_WRAM_END)
308             memtype = MEMTYPE_WRAM;
309         else if (HW_BG_PLTT <= address && address < HW_CTRDG_ROM)
310             memtype = MEMTYPE_VRAM;
311     }
312     else
313     {
314         if (isSame(name, "WRAM"))
315             memtype = MEMTYPE_WRAM;
316         else if (HW_MAIN_MEM_MAIN <= address && address < HW_MAIN_MEM_SUB_END)
317             memtype = MEMTYPE_MAIN;
318         else if (HW_MAIN_MEM_SHARED <= address && address < HW_MAIN_MEM_SHARED_END)
319             memtype = MEMTYPE_SHARED;
320         else if (HW_WRAM <= address && address < HW_WRAM_END)
321             memtype = MEMTYPE_WRAM;
322         else if (HW_BG_PLTT <= address && address < HW_CTRDG_ROM)
323             memtype = MEMTYPE_VRAM;
324     }
325     return memtype;
326 }
327 
328 //
329 // Return overlay that corresponds to the section specified by name
330 //
GetOverlayByName(const char * name)331 static tOverlay *GetOverlayByName(const char *name)
332 {
333     tOverlay *t;
334 
335     for (t = OverlayList.head; t; t = t->next)
336     {
337         if (isSame(t->name, name))
338             return t;
339     }
340     for (t = AutoloadList.head; t; t = t->next)
341     {
342         if (isSame(t->name, name))
343             return t;
344     }
345     return NULL;
346 }
347 
348 //
349 // Decides to which memory region the section specified by name belongs
350 //
RecgSectionMemTypeByName(const char * name)351 static tMemType RecgSectionMemTypeByName(const char *name)
352 {
353     tOverlay *overlay;
354     tMemType memtype, mt;
355     tAfter *after;
356 
357     if (isSame(name, Static.name))
358     {
359         Static.memtype = GetSectionMemType(Static.name, Static.address);
360         return Static.memtype;
361     }
362 
363     overlay = GetOverlayByName(name);
364     if (!overlay)
365     {
366         lcf_error("Unknown section %s, Ignored.", name);
367         return MEMTYPE_NONE;
368     }
369 
370     if (overlay->memtype == MEMTYPE_NONE)
371     {
372         memtype = GetSectionMemType(overlay->name, overlay->address);
373 
374         if (memtype == MEMTYPE_NONE)
375         {
376             overlay->memtype = MEMTYPE_DUMMY;
377 
378             for (after = overlay->afters.head; after; after = after->next)
379             {
380                 mt = RecgSectionMemTypeByName(after->name);
381 
382                 if (mt == MEMTYPE_DUMMY)
383                 {
384                     // Looping
385                     lcf_error("Recursive AFTER reference in section %s, Ignored.", name);
386                     overlay->memtype = MEMTYPE_NONE;
387                     return MEMTYPE_NONE;
388                 }
389                 else if (memtype == MEMTYPE_NONE)
390                 {
391                     memtype = mt;
392                 }
393                 else if (memtype != mt)
394                 {
395                     // Different memtype sections are collected in AFTER
396                     lcf_error("Bad address mapping in section %s, Ignored.", name);
397                     overlay->memtype = MEMTYPE_NONE;
398                     return MEMTYPE_NONE;
399                 }
400             }
401         }
402         overlay->memtype = memtype;
403     }
404     return overlay->memtype;
405 }
406 
407 
408 //====== COMMONS ======
409 
410 /*---------------------------------------------------------------------------*
411   Name:         isObjectOK
412 
413   Description:  Determines whether the designated object matches the conditions designated by the section or the filter_type.
414 
415 
416   Arguments:    obj         : object
417                               (What is actually determined is obj->sectionName, obj->objextType )
418 
419                 section     : Designated section name
420                 filter_type : Qualifying options
421 
422   Returns:      None.
423  *---------------------------------------------------------------------------*/
424 
isObjectOK(const tObject * obj,const char * section,char filter_type)425 static BOOL isObjectOK(const tObject * obj, const char *section, char filter_type)
426 {
427     //
428     //  Checks pertaining to section naming
429     //          A "*" can be used as the section wildcard.
430     //          When the section is "*", all obj will pass
431     //          When obj->section is  '*', the section specification will pass when general section (.text, .data, .bss, .init, etc.)
432     //
433     //
434     if (isSectionWildcard(section) ||
435         (isSectionWildcard(obj->sectionName) && isSectionRegular(section)) ||
436         isSame(obj->sectionName, section))
437     {
438         switch (filter_type)
439         {
440         case 'f':                     // only regular file
441             if (obj->objectType == OBJTYPE_FILE)
442                 return TRUE;
443             break;
444 
445         case '\0':                    // OK if NULL
446             return TRUE;
447 
448         default:
449             lcf_error("Unknown type setting Ignored.");
450             break;
451         }
452     }
453     return FALSE;
454 }
455 
isSectionWildcard(const char * section)456 static BOOL isSectionWildcard(const char *section)
457 {
458     return !section || isSame(section, "*");
459 }
460 
isSectionRegular(const char * section)461 static BOOL isSectionRegular(const char *section)
462 {
463     return (isSame(section, ".text") ||
464             isSame(section, ".rodata") ||
465             isSame(section, ".sdata") ||
466             isSame(section, ".data") ||
467             isSame(section, ".sbss") ||
468             isSame(section, ".bss") ||
469             isSame(section, ".init") ||
470             isSame(section, ".exception") || isSame(section, ".ctor") || isSame(section, ".sinit"));
471 }
472 
473 // Foreach Objects
ForeachObjects(tObject ** ptrObject,tObject * start,tForeachStatus * fep,int n)474 static int ForeachObjects(tObject ** ptrObject, tObject * start, tForeachStatus* fep, int n)
475 {
476     tTokenBuffer *token;
477     char   *section;
478     char    filter;
479     int     count;
480 
481     token = &tokenBuffer[n];
482     section = GetObjectSection(token->string);
483     filter = GetObjectModifier(token->string);
484 
485     debug_printf("section =[%s]\n", section ? section : "");
486     debug_printf("filter  =[%c]\n", filter ? filter : ' ');
487 
488     count = 0;	// The stack value is used as a counter as a recursive measure.
489     while (start)
490     {
491         if (isObjectOK(start, section, filter))
492         {
493             *ptrObject = start;
494             fep->isFirst = (count ? FALSE : TRUE);
495             fep->isLast  = (start->next ? FALSE : TRUE);
496             fep->count   = count;
497             PutTokenBuffer(n + 1, token->loop_end);
498             count ++;
499         }
500         start = start->next;
501     }
502 
503     Free(&section);
504 
505     *ptrObject = NULL;
506     return token->loop_end;
507 }
508 
509 // Foreach Objects Force
ForeachObjectsForce(tObject ** ptrObject,tObject * start,tForeachStatus * fep,int n)510 static int ForeachObjectsForce(tObject ** ptrObject, tObject * start, tForeachStatus* fep, int n)
511 {
512     tTokenBuffer *token;
513     char   *section;
514     char    filter;
515     int     count;
516 
517     token = &tokenBuffer[n];
518     section = GetObjectSection(token->string);
519     filter = GetObjectModifier(token->string);
520 
521     debug_printf("section =[%s]\n", section ? section : "");
522     debug_printf("filter  =[%c]\n", filter ? filter : ' ');
523 
524     count = 0;	// The stack value is used as a counter as a recursive measure.
525     while (start)
526     {
527         *ptrObject = start;
528         fep->isFirst = (count ? FALSE : TRUE);
529         fep->isLast  = (start->next ? FALSE : TRUE);
530         fep->count   = count;
531         PutTokenBuffer(n + 1, token->loop_end);
532         count ++;
533 
534         start = start->next;
535     }
536 
537     Free(&section);
538 
539     *ptrObject = NULL;
540     return token->loop_end;
541 }
542 
PutIfObject(BOOL flag,const char * str)543 static void PutIfObject(BOOL flag, const char *str)
544 {
545     char *p;
546 
547     debug_printf("str =[%s]\n", str ? str : "");
548 
549     if (flag)	// TRUE
550     {
551         p = GetObjectParam(str, '=', ':');
552 
553     }
554     else	// FALSE
555     {
556         p = GetObjectParam(str, ':', '\0');
557     }
558 
559     if (p)	// Displayed if gotten
560     {
561         PutString(p);
562         Free(&p);
563     }
564 }
565 
566 // Object
PutObject(const tObject * object,const char * sectionName)567 static BOOL PutObject(const tObject * object, const char *sectionName)
568 {
569     if (object)
570     {
571         char    modifier = GetObjectModifier(sectionName);
572 
573         PutString(ResolveStringModifier(object->objectName, modifier));
574 
575         if (isNeedSection(object))
576         {
577             char   *section = GetObjectSection(sectionName);
578 
579             if (section)
580             {
581                 PutString(" (");
582                 PutString(section);
583                 PutString(")");
584                 Free(&section);
585             }
586         }
587         return TRUE;
588     }
589     return FALSE;
590 }
591 
592 // Address
PutSectionAddress(tOverlay * overlay)593 static void PutSectionAddress(tOverlay * overlay)
594 {
595     if (overlay->address)
596     {
597         PutAddress(overlay->address);
598     }
599     else
600     {
601         tAfter *t = overlay->afters.head;
602         if (t)
603         {
604             fprintf(fp_out, "AFTER(%s", t->name);
605             while (NULL != (t = t->next))
606             {
607                 fprintf(fp_out, ",%s", t->name);
608             }
609             fprintf(fp_out, ")");
610         }
611     }
612 }
613 
614 
615 //======== STATIC ========//
616 
617 // TargetName
PutTargetName(const char * format)618 static void PutTargetName(const char *format)
619 {
620     char* str;
621     int   pos;
622 
623     if (format == NULL || format[0] == '\0')
624     {
625         PutString(Static.targetName ? Static.targetName : Static.name);
626     }
627     else if (Static.targetName && Static.targetName[0])
628     {
629         str = GetObjectParam(format, '=', '\0');
630         pos = GetCharPos(str, '%');
631         if (str[pos] == '%')
632         {
633             str[pos] = '\0';
634             PutString(str);
635             PutString(Static.targetName);
636             PutString(str+pos+1);
637         }
638         Free(&str);
639     }
640 }
641 
642 // Object
PutStaticObject(const char * sectionName)643 static void PutStaticObject(const char *sectionName)
644 {
645     if (!PutObject(StaticObject, sectionName))
646     {
647         lcf_error("No <FOREACH.STATIC.OBJECTS> Ignored.");
648     }
649 }
650 
651 // Foreach Objects
ForeachStaticObjects(int n)652 static int ForeachStaticObjects(int n)
653 {
654     return ForeachObjects(&StaticObject, Static.objects.head, &Foreach.static_object, n);
655 }
656 
657 // If Object First/Last
PutIfStaticObjectFirst(const char * str)658 static void PutIfStaticObjectFirst(const char *str)
659 {
660     PutIfObject(Foreach.static_object.isFirst, str);
661 }
662 
PutIfStaticObjectLast(const char * str)663 static void PutIfStaticObjectLast(const char *str)
664 {
665     PutIfObject(Foreach.static_object.isLast, str);
666 }
667 
668 // Library
PutStaticLibrary(const char * sectionName)669 static void PutStaticLibrary(const char *sectionName)
670 {
671     if (!PutObject(StaticLibrary, sectionName))
672     {
673         lcf_error("No <FOREACH.STATIC.LIBRARIES> Ignored.");
674     }
675 }
676 
677 // Foreach Libraries
ForeachStaticLibraries(int n)678 static int ForeachStaticLibraries(int n)
679 {
680     return ForeachObjects(&StaticLibrary, Static.libraries.head, &Foreach.static_library, n);
681 }
682 
683 // If Library First/Last
PutIfStaticLibraryFirst(const char * str)684 static void PutIfStaticLibraryFirst(const char *str)
685 {
686     PutIfObject(Foreach.static_library.isFirst, str);
687 }
688 
PutIfStaticLibraryLast(const char * str)689 static void PutIfStaticLibraryLast(const char *str)
690 {
691     PutIfObject(Foreach.static_library.isLast, str);
692 }
693 
694 // SearchSymbol
PutStaticSearchSymbol(const char * dummy)695 static void PutStaticSearchSymbol(const char *dummy)
696 {
697     if (!PutObject(StaticSearchSymbol, NULL))
698     {
699         lcf_error("No <FOREACH.STATIC.SEARCHSYMBOLS> Ignored.");
700     }
701 }
702 
703 // Foreach SearchSymbols
ForeachStaticSearchSymbols(int n)704 static int ForeachStaticSearchSymbols(int n)
705 {
706     return ForeachObjects(&StaticSearchSymbol, Static.searchSymbols.head, &Foreach.static_searchsymbol, n);
707 }
708 
709 // If SearchSymbol First/Last
PutIfStaticSearchSymbolFirst(const char * str)710 static void PutIfStaticSearchSymbolFirst(const char *str)
711 {
712     PutIfObject(Foreach.static_searchsymbol.isFirst, str);
713 }
714 
PutIfStaticSearchSymbolLast(const char * str)715 static void PutIfStaticSearchSymbolLast(const char *str)
716 {
717     PutIfObject(Foreach.static_searchsymbol.isLast, str);
718 }
719 
720 // Force
PutStaticForce(const char * dummy)721 static void PutStaticForce(const char *dummy)
722 {
723     if (!PutObject(StaticForce, NULL))
724     {
725         lcf_error("No <FOREACH.STATIC.FORCES> Ignored.");
726     }
727 }
728 
729 // Foreach Force
ForeachStaticForces(int n)730 static int ForeachStaticForces(int n)
731 {
732     return ForeachObjectsForce(&StaticForce, Static.forces.head, &Foreach.static_force, n);
733 }
734 
735 // If Force First/Last
PutIfStaticForceFirst(const char * str)736 static void PutIfStaticForceFirst(const char *str)
737 {
738     PutIfObject(Foreach.static_force.isFirst, str);
739 }
740 
PutIfStaticForceLast(const char * str)741 static void PutIfStaticForceLast(const char *str)
742 {
743     PutIfObject(Foreach.static_force.isLast, str);
744 }
745 
746 
747 //======== AUTOLOAD ========//
748 
749 // Id
PutAutoloadId(void)750 static void PutAutoloadId(void)
751 {
752     if (Autoload)
753         PutNumber(Autoload->id);
754     else
755         lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
756 }
757 
758 // Name
PutAutoloadName(void)759 static void PutAutoloadName(void)
760 {
761     if (Autoload)
762         PutString(Autoload->name);
763     else
764         lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
765 }
766 
767 // Address
PutAutoloadAddress(void)768 static void PutAutoloadAddress(void)
769 {
770     if (Autoload)
771         PutSectionAddress(Autoload);
772     else
773         lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
774 }
775 
776 // Object
PutAutoloadObject(const char * sectionName)777 static void PutAutoloadObject(const char *sectionName)
778 {
779     if (!PutObject(AutoloadObject, sectionName))
780     {
781         lcf_error("No <FOREACH.AUTOLOAD.OBJECTS> Ignored.");
782     }
783 }
784 
785 // Foreach Objects
ForeachAutoloadObjects(int n)786 static int ForeachAutoloadObjects(int n)
787 {
788     if (Autoload)
789     {
790         return ForeachObjects(&AutoloadObject, Autoload->objects.head, &Foreach.autoload_object, n);
791     }
792     else
793     {
794         lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
795         return tokenBuffer[n].loop_end;
796     }
797 }
798 
799 // If Object First/Last
PutIfAutoloadObjectFirst(const char * str)800 static void PutIfAutoloadObjectFirst(const char *str)
801 {
802     PutIfObject(Foreach.autoload_object.isFirst, str);
803 }
804 
PutIfAutoloadObjectLast(const char * str)805 static void PutIfAutoloadObjectLast(const char *str)
806 {
807     PutIfObject(Foreach.autoload_object.isLast, str);
808 }
809 
810 // Library
PutAutoloadLibrary(const char * sectionName)811 static void PutAutoloadLibrary(const char *sectionName)
812 {
813     if (!PutObject(AutoloadLibrary, sectionName))
814     {
815         lcf_error("No <FOREACH.AUTOLOAD.LIBRARIES> Ignored.");
816     }
817 }
818 
819 // Foreach Libraries
ForeachAutoloadLibraries(int n)820 static int ForeachAutoloadLibraries(int n)
821 {
822     if (Autoload)
823     {
824         return ForeachObjects(&AutoloadLibrary, Autoload->libraries.head, &Foreach.autoload_library, n);
825     }
826     else
827     {
828         lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
829         return tokenBuffer[n].loop_end;
830     }
831 }
832 
833 // If Library First/Last
PutIfAutoloadLibraryFirst(const char * str)834 static void PutIfAutoloadLibraryFirst(const char *str)
835 {
836     PutIfObject(Foreach.autoload_library.isFirst, str);
837 }
838 
PutIfAutoloadLibraryLast(const char * str)839 static void PutIfAutoloadLibraryLast(const char *str)
840 {
841     PutIfObject(Foreach.autoload_library.isLast, str);
842 }
843 
844 // SearchSymbol
PutAutoloadSearchSymbol(const char * dummy)845 static void PutAutoloadSearchSymbol(const char *dummy)
846 {
847     if (!PutObject(AutoloadSearchSymbol, NULL))
848     {
849         lcf_error("No <FOREACH.AUTOLOAD.SEARCHSYMBOLS> Ignored.");
850     }
851 }
852 
853 // Foreach SearchSymbols
ForeachAutoloadSearchSymbols(int n)854 static int ForeachAutoloadSearchSymbols(int n)
855 {
856     if (Autoload)
857     {
858         return ForeachObjects(&AutoloadSearchSymbol, Autoload->searchSymbols.head, &Foreach.autoload_searchsymbol, n);
859     }
860     else
861     {
862         lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
863         return tokenBuffer[n].loop_end;
864     }
865 }
866 
867 // If SearchSymbol First/Last
PutIfAutoloadSearchSymbolFirst(const char * str)868 static void PutIfAutoloadSearchSymbolFirst(const char *str)
869 {
870     PutIfObject(Foreach.autoload_searchsymbol.isFirst, str);
871 }
872 
PutIfAutoloadSearchSymbolLast(const char * str)873 static void PutIfAutoloadSearchSymbolLast(const char *str)
874 {
875     PutIfObject(Foreach.autoload_searchsymbol.isLast, str);
876 }
877 
878 // Force
PutAutoloadForce(const char * dummy)879 static void PutAutoloadForce(const char *dummy)
880 {
881     if (!PutObject(AutoloadForce, NULL))
882     {
883         lcf_error("No <FOREACH.AUTOLOAD.FORCES> Ignored.");
884     }
885 }
886 
887 // Foreach Forces
ForeachAutoloadForces(int n)888 static int ForeachAutoloadForces(int n)
889 {
890     if (Autoload)
891     {
892         return ForeachObjects(&AutoloadForce, Autoload->forces.head, &Foreach.autoload_force, n);
893     }
894     else
895     {
896         lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
897         return tokenBuffer[n].loop_end;
898     }
899 }
900 
901 // If Force First/Last
PutIfAutoloadForceFirst(const char * str)902 static void PutIfAutoloadForceFirst(const char *str)
903 {
904     PutIfObject(Foreach.autoload_force.isFirst, str);
905 }
906 
PutIfAutoloadForceLast(const char * str)907 static void PutIfAutoloadForceLast(const char *str)
908 {
909     PutIfObject(Foreach.autoload_force.isLast, str);
910 }
911 
912 // Foreach Autoloads
ForeachAutoloads(int n)913 static int ForeachAutoloads(int n)
914 {
915     tOverlay *start;
916     tTokenBuffer *token = &tokenBuffer[n];
917     tMemType memtype = GetMemTypeParam(token->string);
918     int count, num;
919 
920     start = AutoloadList.head;
921     num = 0;
922     while (start)
923     {
924         if (memtype == MEMTYPE_NONE || memtype == RecgSectionMemTypeByName(start->name))
925         {
926             num ++;
927         }
928         start = start->next;
929     }
930 
931     start = AutoloadList.head;
932     count = 0;
933     while (start)
934     {
935         if (memtype == MEMTYPE_NONE || memtype == RecgSectionMemTypeByName(start->name))
936         {
937             Autoload = start;
938             Foreach.autoload.isFirst = (count ? FALSE : TRUE);
939             Foreach.autoload.isLast  = (count == num - 1 ? TRUE : FALSE);
940             Foreach.autoload.count   = count;
941             PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
942             count ++;
943         }
944             start = start->next;
945     }
946     Autoload = NULL;
947     return tokenBuffer[n].loop_end;
948 }
949 
950 // If Autoload First/Last
PutIfAutoloadFirst(const char * str)951 static void PutIfAutoloadFirst(const char *str)
952 {
953     PutIfObject(Foreach.autoload.isFirst, str);
954 }
955 
PutIfAutoloadLast(const char * str)956 static void PutIfAutoloadLast(const char *str)
957 {
958     PutIfObject(Foreach.autoload.isLast, str);
959 }
960 
961 
962 //======== OVERLAY ========//
963 
964 // Id
PutOverlayId(void)965 static void PutOverlayId(void)
966 {
967     if (Overlay)
968         PutNumber(Overlay->id);
969     else
970         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
971 }
972 
973 // Name
PutOverlayName(void)974 static void PutOverlayName(void)
975 {
976     if (Overlay)
977         PutString(Overlay->name);
978     else
979         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
980 }
981 
982 // Group
PutOverlayGroup(void)983 static void PutOverlayGroup(void)
984 {
985     if (Overlay)
986     {
987         // If a group has not been set, use the name of the overlay as a group
988         PutString(Overlay->group ? Overlay->group : Overlay->name);
989     }
990     else
991     {
992         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
993     }
994 }
995 
996 // Address
PutOverlayAddress(void)997 static void PutOverlayAddress(void)
998 {
999     if (Overlay)
1000         PutSectionAddress(Overlay);
1001     else
1002         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
1003 }
1004 
1005 // Compression spec
PutOverlayCompress(void)1006 static void PutOverlayCompress(void)
1007 {
1008     if (Overlay)
1009     {
1010         fprintf(fp_out, "%c", Overlay->compressSpec);
1011     }
1012     else
1013     {
1014         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
1015     }
1016 }
1017 
1018 // Object
PutOverlayObject(const char * sectionName)1019 static void PutOverlayObject(const char *sectionName)
1020 {
1021     if (!PutObject(OverlayObject, sectionName))
1022     {
1023         lcf_error("No <FOREACH.OVERLAY.OBJECTS> Ignored.");
1024     }
1025 }
1026 
1027 // Foreach Objects
ForeachOverlayObjects(int n)1028 static int ForeachOverlayObjects(int n)
1029 {
1030     if (Overlay)
1031     {
1032         return ForeachObjects(&OverlayObject, Overlay->objects.head, &Foreach.overlay_object, n);
1033     }
1034     else
1035     {
1036         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
1037         return tokenBuffer[n].loop_end;
1038     }
1039 }
1040 
1041 // If Object First/Last
PutIfOverlayObjectFirst(const char * str)1042 static void PutIfOverlayObjectFirst(const char *str)
1043 {
1044     PutIfObject(Foreach.overlay_object.isFirst, str);
1045 }
1046 
PutIfOverlayObjectLast(const char * str)1047 static void PutIfOverlayObjectLast(const char *str)
1048 {
1049     PutIfObject(Foreach.overlay_object.isLast, str);
1050 }
1051 
1052 
1053 // Library
PutOverlayLibrary(const char * sectionName)1054 static void PutOverlayLibrary(const char *sectionName)
1055 {
1056     if (!PutObject(OverlayLibrary, sectionName))
1057     {
1058         lcf_error("No <FOREACH.OVERLAY.LIBRARIES> Ignored.");
1059     }
1060 }
1061 
1062 // Foreach Libraries
ForeachOverlayLibraries(int n)1063 static int ForeachOverlayLibraries(int n)
1064 {
1065     if (Overlay)
1066     {
1067         return ForeachObjects(&OverlayLibrary, Overlay->libraries.head, &Foreach.overlay_library, n);
1068     }
1069     else
1070     {
1071         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
1072         return tokenBuffer[n].loop_end;
1073     }
1074 }
1075 
1076 // If Library First/Last
PutIfOverlayLibraryFirst(const char * str)1077 static void PutIfOverlayLibraryFirst(const char *str)
1078 {
1079     PutIfObject(Foreach.overlay_library.isFirst, str);
1080 }
1081 
PutIfOverlayLibraryLast(const char * str)1082 static void PutIfOverlayLibraryLast(const char *str)
1083 {
1084     PutIfObject(Foreach.overlay_library.isLast, str);
1085 }
1086 
1087 
1088 // SearchSymbol
PutOverlaySearchSymbol(const char * dummy)1089 static void PutOverlaySearchSymbol(const char *dummy)
1090 {
1091     if (!PutObject(OverlaySearchSymbol, NULL))
1092     {
1093         lcf_error("No <FOREACH.OVERLAY.SEARCHSYMBOLS> Ignored.");
1094     }
1095 }
1096 
1097 // Foreach SearchSymbols
ForeachOverlaySearchSymbols(int n)1098 static int ForeachOverlaySearchSymbols(int n)
1099 {
1100     if (Overlay)
1101     {
1102         return ForeachObjects(&OverlaySearchSymbol, Overlay->searchSymbols.head, &Foreach.overlay_searchsymbol, n);
1103     }
1104     else
1105     {
1106         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
1107         return tokenBuffer[n].loop_end;
1108     }
1109 }
1110 
1111 // If SearchSymbol First/Last
PutIfOverlaySearchSymbolFirst(const char * str)1112 static void PutIfOverlaySearchSymbolFirst(const char *str)
1113 {
1114     PutIfObject(Foreach.overlay_searchsymbol.isFirst, str);
1115 }
1116 
PutIfOverlaySearchSymbolLast(const char * str)1117 static void PutIfOverlaySearchSymbolLast(const char *str)
1118 {
1119     PutIfObject(Foreach.overlay_searchsymbol.isLast, str);
1120 }
1121 
1122 // Force
PutOverlayForce(const char * dummy)1123 static void PutOverlayForce(const char *dummy)
1124 {
1125     if (!PutObject(OverlayForce, NULL))
1126     {
1127         lcf_error("No <FOREACH.OVERLAY.FORCES> Ignored.");
1128     }
1129 }
1130 
1131 // Foreach Forces
ForeachOverlayForces(int n)1132 static int ForeachOverlayForces(int n)
1133 {
1134     if (Overlay)
1135     {
1136         return ForeachObjects(&OverlayForce, Overlay->forces.head, &Foreach.overlay_force, n);
1137     }
1138     else
1139     {
1140         lcf_error("No <FOREACH.OVERLAYS> Ignored.");
1141         return tokenBuffer[n].loop_end;
1142     }
1143 }
1144 
1145 // If Force First/Last
PutIfOverlayForceFirst(const char * str)1146 static void PutIfOverlayForceFirst(const char *str)
1147 {
1148     PutIfObject(Foreach.overlay_force.isFirst, str);
1149 }
1150 
PutIfOverlayForceLast(const char * str)1151 static void PutIfOverlayForceLast(const char *str)
1152 {
1153     PutIfObject(Foreach.overlay_force.isLast, str);
1154 }
1155 
1156 // Foreach Overlays
ForeachOverlays(int n)1157 static int ForeachOverlays(int n)
1158 {
1159     tOverlay *start;
1160     tTokenBuffer *token = &tokenBuffer[n];
1161     tMemType memtype = GetMemTypeParam(token->string);
1162     int count, num;
1163 
1164     start = OverlayList.head;
1165     num = 0;
1166     while (start)
1167     {
1168         if (memtype == MEMTYPE_NONE || memtype == RecgSectionMemTypeByName(start->name))
1169         {
1170             num ++;
1171         }
1172         start = start->next;
1173     }
1174 
1175     start = OverlayList.head;
1176     count = 0;
1177     while (start)
1178     {
1179         if (memtype == MEMTYPE_NONE || memtype == RecgSectionMemTypeByName(start->name))
1180         {
1181             Overlay = start;
1182             Foreach.overlay.isFirst = (count ? FALSE : TRUE);
1183             Foreach.overlay.isLast  = (count == num - 1 ? TRUE : FALSE);
1184             Foreach.overlay.count   = count;
1185             PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
1186             count ++;
1187         }
1188         start = start->next;
1189     }
1190     Overlay = NULL;
1191     return tokenBuffer[n].loop_end;
1192 }
1193 
1194 // If Overlay First/Last
PutIfOverlayFirst(const char * str)1195 static void PutIfOverlayFirst(const char *str)
1196 {
1197     PutIfObject(Foreach.overlay.isFirst, str);
1198 }
1199 
PutIfOverlayLast(const char * str)1200 static void PutIfOverlayLast(const char *str)
1201 {
1202     PutIfObject(Foreach.overlay.isLast, str);
1203 }
1204 
1205 
1206 //======== MISC ========//
1207 
IsExistStatic(const char * str)1208 static BOOL IsExistStatic(const char *str)
1209 {
1210     return strcmp(Static.name, str) ? FALSE : TRUE;
1211 }
1212 
IsExistAutoload(const char * str)1213 static BOOL IsExistAutoload(const char *str)
1214 {
1215     tOverlay *t = AutoloadList.head;
1216     while (t)
1217     {
1218         if (!strcmp(t->name, str))
1219         {
1220             return TRUE;
1221         }
1222         t = t->next;
1223     }
1224     return FALSE;
1225 }
1226 
IsExistOverlay(const char * str)1227 static BOOL IsExistOverlay(const char *str)
1228 {
1229     tOverlay *t = OverlayList.head;
1230     while (t)
1231     {
1232         if (!strcmp(t->name, str))
1233         {
1234             return TRUE;
1235         }
1236         t = t->next;
1237     }
1238     return FALSE;
1239 }
1240 
PutIfExistSection(const char * str)1241 static void PutIfExistSection(const char *str)
1242 {
1243     char *name = GetObjectParam(str, '.', '=');
1244     debug_printf("ExistSection? name = %s\n", name ? name : "");
1245     if (name)
1246     {
1247         PutIfObject(IsExistStatic(name)||IsExistAutoload(name)||IsExistOverlay(name), str);
1248         Free(&name);
1249     }
1250     return;
1251 }
1252 
PutIfExistStatic(const char * str)1253 static void PutIfExistStatic(const char *str)
1254 {
1255     char *name = GetObjectParam(str, '.', '=');
1256     debug_printf("ExistStatic? name = %s\n", name ? name : "");
1257     if (name)
1258     {
1259         PutIfObject(IsExistStatic(name), str);
1260         Free(&name);
1261     }
1262     return;
1263 }
1264 
PutIfExistAutoload(const char * str)1265 static void PutIfExistAutoload(const char *str)
1266 {
1267     char *name = GetObjectParam(str, '.', '=');
1268     debug_printf("ExistAutoload? name = %s\n", name ? name : "");
1269     if (name)
1270     {
1271         PutIfObject(IsExistAutoload(name), str);
1272         Free(&name);
1273     }
1274     return;
1275 }
1276 
PutIfExistOverlay(const char * str)1277 static void PutIfExistOverlay(const char *str)
1278 {
1279     char *name = GetObjectParam(str, '.', '=');
1280     debug_printf("ExistOverlay? name = %s\n", name ? name : "");
1281     if (name)
1282     {
1283         PutIfObject(IsExistOverlay(name), str);
1284         Free(&name);
1285     }
1286     return;
1287 }
1288 
1289 
1290 /*============================================================================
1291  *  Put Token List
1292  */
PutToken(int n)1293 static int PutToken(int n)
1294 {
1295     switch (tokenBuffer[n].id)
1296     {
1297     case tSTRING:
1298         PutString(tokenBuffer[n].string);
1299         break;
1300 
1301     case tTARGET_NAME:
1302         PutTargetName(tokenBuffer[n].string);
1303         break;
1304 
1305     case tSTATIC_NAME:
1306         PutString(Static.name);
1307         break;
1308 
1309     case tSTATIC_ADDRESS:
1310         PutAddress(Static.address);
1311         break;
1312 
1313     case tSTATIC_OBJECT:
1314         PutStaticObject(tokenBuffer[n].string);
1315         break;
1316 
1317     case tSTATIC_LIBRARY:
1318         PutStaticLibrary(tokenBuffer[n].string);
1319         break;
1320 
1321     case tSTATIC_SEARCHSYMBOL:
1322         PutStaticSearchSymbol(tokenBuffer[n].string);
1323         break;
1324 
1325     case tSTATIC_FORCE:
1326         PutStaticForce(tokenBuffer[n].string);
1327         break;
1328 
1329     case tSTATIC_STACKSIZE:
1330         PutNumber(Static.stacksize);
1331         break;
1332 
1333     case tSTATIC_IRQSTACKSIZE:
1334         PutNumber(Static.stacksize_irq);
1335         break;
1336 
1337     case tFOREACH_STATIC_OBJECTS:
1338         n = ForeachStaticObjects(n);
1339         break;
1340 
1341     case tFOREACH_STATIC_LIBRARIES:
1342         n = ForeachStaticLibraries(n);
1343         break;
1344 
1345     case tFOREACH_STATIC_SEARCHSYMBOLS:
1346         n = ForeachStaticSearchSymbols(n);
1347         break;
1348 
1349     case tFOREACH_STATIC_FORCES:
1350         n = ForeachStaticForces(n);
1351         break;
1352 
1353     case tIF_STATIC_OBJECT_FIRST:
1354         PutIfStaticObjectFirst(tokenBuffer[n].string);
1355         break;
1356 
1357     case tIF_STATIC_OBJECT_LAST:
1358         PutIfStaticObjectLast(tokenBuffer[n].string);
1359         break;
1360 
1361     case tIF_STATIC_LIBRARY_FIRST:
1362         PutIfStaticLibraryFirst(tokenBuffer[n].string);
1363         break;
1364 
1365     case tIF_STATIC_LIBRARY_LAST:
1366         PutIfStaticLibraryLast(tokenBuffer[n].string);
1367         break;
1368 
1369     case tIF_STATIC_SEARCHSYMBOL_FIRST:
1370         PutIfStaticSearchSymbolFirst(tokenBuffer[n].string);
1371         break;
1372 
1373     case tIF_STATIC_SEARCHSYMBOL_LAST:
1374         PutIfStaticSearchSymbolLast(tokenBuffer[n].string);
1375         break;
1376 
1377     case tIF_STATIC_FORCE_FIRST:
1378         PutIfStaticForceFirst(tokenBuffer[n].string);
1379         break;
1380 
1381     case tIF_STATIC_FORCE_LAST:
1382         PutIfStaticForceLast(tokenBuffer[n].string);
1383         break;
1384 
1385     case tAUTOLOAD_ID:
1386         PutAutoloadId();
1387         break;
1388 
1389     case tAUTOLOAD_NAME:
1390         PutAutoloadName();
1391         break;
1392 
1393     case tAUTOLOAD_ADDRESS:
1394         PutAutoloadAddress();
1395         break;
1396 
1397     case tAUTOLOAD_OBJECT:
1398         PutAutoloadObject(tokenBuffer[n].string);
1399         break;
1400 
1401     case tAUTOLOAD_LIBRARY:
1402         PutAutoloadLibrary(tokenBuffer[n].string);
1403         break;
1404 
1405     case tAUTOLOAD_SEARCHSYMBOL:
1406         PutAutoloadSearchSymbol(tokenBuffer[n].string);
1407         break;
1408 
1409     case tAUTOLOAD_FORCE:
1410         PutAutoloadForce(tokenBuffer[n].string);
1411         break;
1412 
1413     case tNUMBER_AUTOLOADS:
1414         PutNumber(AutoloadList.num);
1415         break;
1416 
1417     case tFOREACH_AUTOLOADS:
1418         n = ForeachAutoloads(n);
1419         break;
1420 
1421     case tFOREACH_AUTOLOAD_OBJECTS:
1422         n = ForeachAutoloadObjects(n);
1423         break;
1424 
1425     case tFOREACH_AUTOLOAD_LIBRARIES:
1426         n = ForeachAutoloadLibraries(n);
1427         break;
1428 
1429     case tFOREACH_AUTOLOAD_SEARCHSYMBOLS:
1430         n = ForeachAutoloadSearchSymbols(n);
1431         break;
1432 
1433     case tFOREACH_AUTOLOAD_FORCES:
1434         n = ForeachAutoloadForces(n);
1435         break;
1436 
1437     case tIF_AUTOLOAD_FIRST:
1438         PutIfAutoloadFirst(tokenBuffer[n].string);
1439         break;
1440 
1441     case tIF_AUTOLOAD_LAST:
1442         PutIfAutoloadLast(tokenBuffer[n].string);
1443         break;
1444 
1445     case tIF_AUTOLOAD_OBJECT_FIRST:
1446         PutIfAutoloadObjectFirst(tokenBuffer[n].string);
1447         break;
1448 
1449     case tIF_AUTOLOAD_OBJECT_LAST:
1450         PutIfAutoloadObjectLast(tokenBuffer[n].string);
1451         break;
1452 
1453     case tIF_AUTOLOAD_LIBRARY_FIRST:
1454         PutIfAutoloadLibraryFirst(tokenBuffer[n].string);
1455         break;
1456 
1457     case tIF_AUTOLOAD_LIBRARY_LAST:
1458         PutIfAutoloadLibraryLast(tokenBuffer[n].string);
1459         break;
1460 
1461     case tIF_AUTOLOAD_SEARCHSYMBOL_FIRST:
1462         PutIfAutoloadSearchSymbolFirst(tokenBuffer[n].string);
1463         break;
1464 
1465     case tIF_AUTOLOAD_SEARCHSYMBOL_LAST:
1466         PutIfAutoloadSearchSymbolLast(tokenBuffer[n].string);
1467         break;
1468 
1469     case tIF_AUTOLOAD_FORCE_FIRST:
1470         PutIfAutoloadForceFirst(tokenBuffer[n].string);
1471         break;
1472 
1473     case tIF_AUTOLOAD_FORCE_LAST:
1474         PutIfAutoloadForceLast(tokenBuffer[n].string);
1475         break;
1476 
1477     case tOVERLAY_ID:
1478         PutOverlayId();
1479         break;
1480 
1481     case tOVERLAY_NAME:
1482         PutOverlayName();
1483         break;
1484 
1485     case tOVERLAY_GROUP:
1486         PutOverlayGroup();
1487         break;
1488 
1489     case tOVERLAY_ADDRESS:
1490         PutOverlayAddress();
1491         break;
1492 
1493     case tOVERLAY_COMPRESS:
1494         PutOverlayCompress();
1495         break;
1496 
1497     case tOVERLAY_OBJECT:
1498         PutOverlayObject(tokenBuffer[n].string);
1499         break;
1500 
1501     case tOVERLAY_LIBRARY:
1502         PutOverlayLibrary(tokenBuffer[n].string);
1503         break;
1504 
1505     case tOVERLAY_SEARCHSYMBOL:
1506         PutOverlaySearchSymbol(tokenBuffer[n].string);
1507         break;
1508 
1509     case tOVERLAY_FORCE:
1510         PutOverlayForce(tokenBuffer[n].string);
1511         break;
1512 
1513     case tNUMBER_OVERLAYS:
1514         PutNumber(OverlayList.num);
1515         break;
1516 
1517     case tFOREACH_OVERLAYS:
1518         n = ForeachOverlays(n);
1519         break;
1520 
1521     case tFOREACH_OVERLAY_OBJECTS:
1522         n = ForeachOverlayObjects(n);
1523         break;
1524 
1525     case tFOREACH_OVERLAY_LIBRARIES:
1526         n = ForeachOverlayLibraries(n);
1527         break;
1528 
1529     case tFOREACH_OVERLAY_SEARCHSYMBOLS:
1530         n = ForeachOverlaySearchSymbols(n);
1531         break;
1532 
1533     case tFOREACH_OVERLAY_FORCES:
1534         n = ForeachOverlayForces(n);
1535         break;
1536 
1537     case tIF_OVERLAY_FIRST:
1538         PutIfOverlayFirst(tokenBuffer[n].string);
1539         break;
1540 
1541     case tIF_OVERLAY_LAST:
1542         PutIfOverlayLast(tokenBuffer[n].string);
1543         break;
1544 
1545     case tIF_OVERLAY_OBJECT_FIRST:
1546         PutIfOverlayObjectFirst(tokenBuffer[n].string);
1547         break;
1548 
1549     case tIF_OVERLAY_OBJECT_LAST:
1550         PutIfOverlayObjectLast(tokenBuffer[n].string);
1551         break;
1552 
1553     case tIF_OVERLAY_LIBRARY_FIRST:
1554         PutIfOverlayLibraryFirst(tokenBuffer[n].string);
1555         break;
1556 
1557     case tIF_OVERLAY_LIBRARY_LAST:
1558         PutIfOverlayLibraryLast(tokenBuffer[n].string);
1559         break;
1560 
1561     case tIF_OVERLAY_SEARCHSYMBOL_FIRST:
1562         PutIfOverlaySearchSymbolFirst(tokenBuffer[n].string);
1563         break;
1564 
1565     case tIF_OVERLAY_SEARCHSYMBOL_LAST:
1566         PutIfOverlaySearchSymbolLast(tokenBuffer[n].string);
1567         break;
1568 
1569     case tIF_OVERLAY_FORCE_FIRST:
1570         PutIfOverlayForceFirst(tokenBuffer[n].string);
1571         break;
1572 
1573     case tIF_OVERLAY_FORCE_LAST:
1574         PutIfOverlayForceLast(tokenBuffer[n].string);
1575         break;
1576 
1577     case tPROPERTY_OVERLAYDEFS:
1578         PutString(Property.overlaydefs);
1579         break;
1580 
1581     case tPROPERTY_OVERLAYTABLE:
1582         PutString(Property.overlaytable);
1583         break;
1584 
1585     case tPROPERTY_SUFFIX:
1586         PutString(Property.suffix);
1587         break;
1588 
1589     case tIF_EXIST_SECTION:
1590         PutIfExistSection(tokenBuffer[n].string);
1591         break;
1592 
1593     case tIF_EXIST_STATIC:
1594         PutIfExistStatic(tokenBuffer[n].string);
1595         break;
1596 
1597     case tIF_EXIST_AUTOLOAD:
1598         PutIfExistAutoload(tokenBuffer[n].string);
1599         break;
1600 
1601     case tIF_EXIST_OVERLAY:
1602         PutIfExistOverlay(tokenBuffer[n].string);
1603         break;
1604 
1605     default:
1606         lcf_error("Unknown token\n");
1607     }
1608     return n;
1609 }
1610 
PutTokenBuffer(int start,int end)1611 static void PutTokenBuffer(int start, int end)
1612 {
1613     int     i;
1614 
1615     for (i = start; i <= end; i++)
1616     {
1617         i = PutToken(i);
1618     }
1619 }
1620 
PutTokenBufferAll(void)1621 static void PutTokenBufferAll(void)
1622 {
1623     PutTokenBuffer(0, tokenBufferEnd - 1);
1624 }
1625 
1626 
1627 /*============================================================================
1628  *  Create LCF file
1629  */
CreateLcfFile(const char * filename)1630 int CreateLcfFile(const char *filename)
1631 {
1632     if (filename)
1633     {
1634         if (NULL == (fp_out = fopen(filename, "wb")))
1635         {
1636             fprintf(stderr, "makelcf: Cannot write %s\n", filename);
1637             return 2;
1638         }
1639         PutTokenBufferAll();
1640         fclose(fp_out);
1641     }
1642     else
1643     {
1644         setmode(1, O_BINARY);
1645         fp_out = stdout;
1646         PutTokenBufferAll();
1647     }
1648 
1649     return 0;
1650 }
1651