1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - tools - makelcf
3 File: createlcf.c
4
5 Copyright 2003-2009 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2009-11-11#$
14 $Rev: 11140 $
15 $Author: kitase_hirotake $
16 *---------------------------------------------------------------------------*/
17 #include <stdio.h>
18 #include <strings.h>
19 #include <io.h> // setmode()
20 #include <fcntl.h> // setmode()
21 #include <stdarg.h> // va_start(),va_end()
22 #ifdef SDK_TWL
23 #include <twl/hw/common/mmap_shared.h>
24 #include <twl/hw/ARM9/mmap_global.h>
25 #include <twl/hw/ARM9/mmap_main.h>
26 #else
27 #include <nitro_win32.h>
28 #endif
29 #include "makelcf.h"
30 #include "defval.h"
31 #include "tlcf.tab.h"
32
33 static void PutString(const char *str);
34 static void PutAddress(u32 address);
35 static BOOL PutObject(const tObject * object, const char *secName);
36 static void PutStaticCrt0Object(const char *secName);
37 static void PutStaticObject(const char *secName);
38 static void PutOverlayName(void);
39 static void PutOverlayGroup(void);
40 static void PutOverlayObject(const char *secName);
41 static void PutOverlayAddress(void);
42 static void PutOverlayCompress(void);
43 static BOOL isObjectOK(const tObject * obj, const char *section, char filter_type);
44 static BOOL isSectionWildcard(const char *section);
45 static BOOL isSectionRegular(const char *section);
46 static int ForeachObjects(tObject ** ptrObject, tObject * start, int n);
47 static int ForeachStaticObjects(int n);
48 static int ForeachOverlayObjects(int n);
49 static int ForeachOverlays(int n);
50 static int PutToken(int n);
51 static void PutTokenBuffer(int start, int end);
52 static void PutTokenBufferAll(void);
53
54 FILE *fp_out;
55 tObject *StaticObject = NULL;
56 tObject *StaticLibrary = NULL;
57 tObject *StaticSearchSymbol = NULL;
58 tObject *StaticForce = NULL;
59 tOverlay *Autoload = NULL;
60 tObject *AutoloadObject = NULL;
61 tObject *AutoloadLibrary = NULL;
62 tObject *AutoloadSearchSymbol = NULL;
63 tObject *AutoloadForce = NULL;
64 tOverlay *Overlay = NULL;
65 tObject *OverlayObject = NULL;
66 tObject *OverlayLibrary = NULL;
67 tObject *OverlaySearchSymbol = NULL;
68 tObject *OverlayForce = NULL;
69 tOverlay *Ltdautoload = NULL;
70 tObject *LtdautoloadObject = NULL;
71 tObject *LtdautoloadLibrary = NULL;
72 tObject *LtdautoloadSearchSymbol = NULL;
73 tObject *LtdautoloadForce = NULL;
74 tOverlay *Ltdoverlay = NULL;
75 tObject *LtdoverlayObject = NULL;
76 tObject *LtdoverlayLibrary = NULL;
77 tObject *LtdoverlaySearchSymbol = NULL;
78 tObject *LtdoverlayForce = NULL;
79
lcf_error(const char * fmt,...)80 void lcf_error(const char *fmt, ...)
81 {
82 va_list va;
83 va_start(va, fmt);
84 vfprintf(stderr, fmt, va);
85 va_end(va);
86 fprintf(stderr, "\n");
87 }
88
89 /*============================================================================
90 * Put Tokens
91 */
PutString(const char * str)92 static void PutString(const char *str)
93 {
94 if (str)
95 fprintf(fp_out, "%s", str);
96 }
97
PutAddress(u32 address)98 static void PutAddress(u32 address)
99 {
100 fprintf(fp_out, "0x%08lx", address);
101 }
102
PutNumber(u32 num)103 static void PutNumber(u32 num)
104 {
105 fprintf(fp_out, "%ld", num);
106 }
107
108
GetCharPos(const char * str,char target)109 static int GetCharPos(const char *str, char target)
110 {
111 int n = 0;
112
113 if (str)
114 {
115 while ('\0' != str[n] && target != str[n])
116 {
117 n++;
118 }
119 }
120 return n;
121 }
122
GetObjectParam(const char * str,char start,char end)123 static char *GetObjectParam(const char *str, char start, char end)
124 {
125 int pos_start = GetCharPos(str, start);
126 int pos_end = GetCharPos(str, end);
127 int len = pos_end - pos_start;
128 char *buffer;
129
130 if (len > 0)
131 {
132 buffer = Alloc(len);
133 strncpy(buffer, str + pos_start + 1, len - 1);
134 buffer[len - 1] = '\0';
135 return buffer;
136 }
137 return NULL;
138 }
139
GetObjectSection(const char * str)140 static char *GetObjectSection(const char *str)
141 {
142 return GetObjectParam(str, '=', ':'); // return NULL if no section
143 }
144
GetObjectModifier(const char * str)145 static char GetObjectModifier(const char *str)
146 {
147 char *mod = GetObjectParam(str, ':', '\0');
148 char ret;
149
150 ret = mod ? mod[0] : '\0';
151 Free(&mod);
152
153 return ret;
154
155 }
156
GetMemTypeParam(const char * str)157 static tMemType GetMemTypeParam(const char *str)
158 {
159 char *mod = GetObjectParam(str, '=', ':');
160 int i;
161
162 static struct
163 {
164 tMemType type;
165 char *name;
166 }
167 table[] =
168 {
169 {
170 MEMTYPE_MAIN, "MAIN"}
171 ,
172 {
173 MEMTYPE_MAINEX, "MAINEX"}
174 ,
175 {
176 MEMTYPE_ITCM, "ITCM"}
177 ,
178 {
179 MEMTYPE_DTCM, "DTCM"}
180 ,
181 {
182 MEMTYPE_ITCM_BSS, "ITCM.BSS"}
183 ,
184 {
185 MEMTYPE_DTCM_BSS, "DTCM.BSS"}
186 ,
187 {
188 MEMTYPE_SHARED, "SHARED"}
189 ,
190 {
191 MEMTYPE_WRAM, "WRAM"}
192 ,
193 {
194 MEMTYPE_WRAM_BSS, "WRAM.BSS"}
195 ,
196 {
197 MEMTYPE_VRAM, "VRAM"}
198 ,
199 {
200 MEMTYPE_NONE, "*"}
201 ,};
202
203 for (i = 0; table[i].type != MEMTYPE_NONE; i++)
204 {
205 if (isSame(mod, table[i].name))
206 {
207 break;
208 }
209 }
210 Free(&mod);
211
212 return table[i].type;
213 }
214
215 //
216 // Decides to which memory region the section specified by name, address belongs
217 //
GetSectionMemType(const char * name,u32 address)218 static tMemType GetSectionMemType(const char *name, u32 address)
219 {
220 BOOL isARM9 = (Static.address < 0x02300000); // Actual decision value
221 tMemType memtype = MEMTYPE_NONE;
222
223 if (isARM9)
224 {
225 if (isSame(name, "ITCM"))
226 memtype = MEMTYPE_ITCM;
227 else if (isSame(name, "DTCM"))
228 memtype = MEMTYPE_DTCM;
229 else if (isSame(name, "WRAM"))
230 memtype = MEMTYPE_WRAM;
231 else if (isSame(name, "ITCM.BSS"))
232 memtype = MEMTYPE_ITCM_BSS;
233 else if (isSame(name, "DTCM.BSS"))
234 memtype = MEMTYPE_DTCM_BSS;
235 else if (isSame(name, "WRAM.BSS"))
236 memtype = MEMTYPE_WRAM_BSS;
237 else if (HW_ITCM_IMAGE <= address && address < HW_ITCM_END)
238 memtype = MEMTYPE_ITCM;
239 else if (HW_MAIN_MEM_SUB <= address && address < HW_MAIN_MEM_SUB_END)
240 memtype = MEMTYPE_DTCM;
241 else if (HW_MAIN_MEM_MAIN <= address && address < HW_MAIN_MEM_MAIN_END)
242 memtype = MEMTYPE_MAIN;
243 else if (HW_MAIN_MEM_MAIN_END <= address && address < HW_MAIN_MEM_DEBUGGER)
244 memtype = MEMTYPE_MAINEX;
245 else if (HW_MAIN_MEM_SHARED <= address && address < HW_MAIN_MEM_SHARED_END)
246 memtype = MEMTYPE_SHARED;
247 else if (HW_WRAM <= address && address < HW_WRAM_END)
248 memtype = MEMTYPE_WRAM;
249 else if (HW_BG_PLTT <= address && address < HW_CTRDG_ROM)
250 memtype = MEMTYPE_VRAM;
251 }
252 else
253 {
254 if (isSame(name, "WRAM"))
255 memtype = MEMTYPE_WRAM;
256 else if (HW_MAIN_MEM_MAIN <= address && address < HW_MAIN_MEM_SUB_END)
257 memtype = MEMTYPE_MAIN;
258 else if (HW_MAIN_MEM_SHARED <= address && address < HW_MAIN_MEM_SHARED_END)
259 memtype = MEMTYPE_SHARED;
260 else if (HW_WRAM <= address && address < HW_WRAM_END)
261 memtype = MEMTYPE_WRAM;
262 else if (HW_BG_PLTT <= address && address < HW_CTRDG_ROM)
263 memtype = MEMTYPE_VRAM;
264 }
265 return memtype;
266 }
267
268 //
269 // Return overlay that corresponds to the section specified by name
270 //
GetOverlayByName(const char * name)271 static tOverlay *GetOverlayByName(const char *name)
272 {
273 tOverlay *t;
274
275 for (t = OverlayList.head; t; t = t->next)
276 {
277 if (isSame(t->name, name))
278 return t;
279 }
280 for (t = AutoloadList.head; t; t = t->next)
281 {
282 if (isSame(t->name, name))
283 return t;
284 }
285 for (t = LtdoverlayList.head; t; t = t->next)
286 {
287 if (isSame(t->name, name))
288 return t;
289 }
290 for (t = LtdautoloadList.head; t; t = t->next)
291 {
292 if (isSame(t->name, name))
293 return t;
294 }
295 return NULL;
296 }
297
298 //
299 // Decides to which memory region the section specified by name belongs
300 //
RecgSectionMemTypeByName(const char * name)301 static tMemType RecgSectionMemTypeByName(const char *name)
302 {
303 tOverlay *overlay;
304 tMemType memtype, mt;
305 tAfter *after;
306
307 if (isSame(name, Static.name))
308 {
309 Static.memtype = GetSectionMemType(Static.name, Static.address);
310 return Static.memtype;
311 }
312
313 overlay = GetOverlayByName(name);
314 if (!overlay)
315 {
316 lcf_error("Unknown section %s, Ignored.", name);
317 return MEMTYPE_NONE;
318 }
319
320 if (overlay->memtype == MEMTYPE_NONE)
321 {
322 memtype = GetSectionMemType(overlay->name, overlay->address);
323
324 if (memtype == MEMTYPE_NONE)
325 {
326 overlay->memtype = MEMTYPE_DUMMY;
327
328 for (after = overlay->afters.head; after; after = after->next)
329 {
330 mt = RecgSectionMemTypeByName(after->name);
331
332 if (mt == MEMTYPE_DUMMY)
333 {
334 // Looping
335 lcf_error("Recursive AFTER reference in section %s, Ignored.", name);
336 overlay->memtype = MEMTYPE_NONE;
337 return MEMTYPE_NONE;
338 }
339 else if (memtype == MEMTYPE_NONE)
340 {
341 memtype = mt;
342 }
343 else if (memtype != mt)
344 {
345 // Different memtype sections are collected in AFTER
346 lcf_error("Bad address mapping in section %s, Ignored.", name);
347 overlay->memtype = MEMTYPE_NONE;
348 return MEMTYPE_NONE;
349 }
350 }
351 }
352 overlay->memtype = memtype;
353 }
354 return overlay->memtype;
355 }
356
357
358 //====== COMMONS ======
359
360 /*---------------------------------------------------------------------------*
361 Name: isObjectOK
362
363 Description: Determines whether the designated object matches the conditions designated by the section or the filter_type.
364
365
366 Arguments: obj : object
367 (What is actually determined is
368 obj->sectionName, obj->objextType )
369 section : Designated section name
370 filter_type : Qualifying options
371
372 Returns: None.
373 *---------------------------------------------------------------------------*/
374
isObjectOK(const tObject * obj,const char * section,char filter_type)375 static BOOL isObjectOK(const tObject * obj, const char *section, char filter_type)
376 {
377 //
378 // Checks pertaining to section naming
379 // A "*" can be used as the section wildcard.
380 // When the section is "*", all obj will pass
381 // When obj->section is "*", the section designation is a general section
382 // Pass for general sections (.text, .data, .bss, .init, and the like)
383 //
384 if (isSectionWildcard(section) ||
385 (isSectionWildcard(obj->sectionName) && isSectionRegular(section)) ||
386 isSame(obj->sectionName, section))
387 {
388 switch (filter_type)
389 {
390 case 'f': // only regular file
391 if (obj->objectType == OBJTYPE_FILE)
392 return TRUE;
393 break;
394
395 case '\0': // OK if NULL
396 return TRUE;
397
398 default:
399 lcf_error("Unknown type setting Ignored.");
400 break;
401 }
402 }
403 return FALSE;
404 }
405
isSectionWildcard(const char * section)406 static BOOL isSectionWildcard(const char *section)
407 {
408 return !section || isSame(section, "*");
409 }
410
isSectionRegular(const char * section)411 static BOOL isSectionRegular(const char *section)
412 {
413 return (isSame(section, ".text") ||
414 isSame(section, ".rodata") ||
415 isSame(section, ".sdata") ||
416 isSame(section, ".data") ||
417 isSame(section, ".sbss") ||
418 isSame(section, ".bss") ||
419 isSame(section, ".init") ||
420 isSame(section, ".exception") || isSame(section, ".ctor") || isSame(section, ".sinit"));
421 }
422
423 // Foreach Objects
ForeachObjects(tObject ** ptrObject,tObject * start,int n)424 static int ForeachObjects(tObject ** ptrObject, tObject * start, int n)
425 {
426 tTokenBuffer *token;
427 char *section;
428 char filter;
429
430 token = &tokenBuffer[n];
431 section = GetObjectSection(token->string);
432 filter = GetObjectModifier(token->string);
433
434 debug_printf("section =[%s]\n", section ? section : "");
435 debug_printf("filter =[%c]\n", filter ? filter : ' ');
436
437 while (start)
438 {
439 if (isObjectOK(start, section, filter))
440 {
441 *ptrObject = start;
442 PutTokenBuffer(n + 1, token->loop_end);
443 }
444
445 start = start->next;
446 }
447
448 Free(§ion);
449
450 *ptrObject = NULL;
451 return token->loop_end;
452 }
453
454 // Foreach Objects Force
ForeachObjectsForce(tObject ** ptrObject,tObject * start,int n)455 static int ForeachObjectsForce(tObject ** ptrObject, tObject * start, int n)
456 {
457 tTokenBuffer *token;
458 char *section;
459 char filter;
460
461 token = &tokenBuffer[n];
462 section = GetObjectSection(token->string);
463 filter = GetObjectModifier(token->string);
464
465 debug_printf("section =[%s]\n", section ? section : "");
466 debug_printf("filter =[%c]\n", filter ? filter : ' ');
467
468 while (start)
469 {
470 *ptrObject = start;
471 PutTokenBuffer(n + 1, token->loop_end);
472
473 start = start->next;
474 }
475
476 Free(§ion);
477
478 *ptrObject = NULL;
479 return token->loop_end;
480 }
481
482 // Object
PutObject(const tObject * object,const char * sectionName)483 static BOOL PutObject(const tObject * object, const char *sectionName)
484 {
485 if (object)
486 {
487 char modifier = GetObjectModifier(sectionName);
488
489 PutString(ResolveStringModifier(object->objectName, modifier));
490
491 if (isNeedSection(object))
492 {
493 char *section = GetObjectSection(sectionName);
494
495 if (section)
496 {
497 PutString(" (");
498 PutString(section);
499 PutString(")");
500 Free(§ion);
501 }
502 }
503 return TRUE;
504 }
505 return FALSE;
506 }
507
508 // Address
PutSectionAddress(tOverlay * overlay)509 static void PutSectionAddress(tOverlay * overlay)
510 {
511 if (overlay->address)
512 {
513 PutAddress(overlay->address);
514 }
515 else
516 {
517 tAfter *t = overlay->afters.head;
518 if (t)
519 {
520 fprintf(fp_out, "AFTER(%s", t->name);
521 while (NULL != (t = t->next))
522 {
523 fprintf(fp_out, ",%s", t->name);
524 }
525 fprintf(fp_out, ")");
526 }
527 }
528 }
529
530
531 //======== STATIC ========//
532
533 // Crt0 Object
PutStaticCrt0Object(const char * sectionName)534 static void PutStaticCrt0Object(const char *sectionName)
535 {
536 const char *objectName = SearchDefVal("CRT0_O");
537
538 if(objectName)
539 {
540 char* section = GetObjectSection(sectionName);
541
542 PutString(objectName);
543
544 if (section)
545 {
546 PutString(" (");
547 PutString(section);
548 PutString(")");
549 Free(§ion);
550 }
551 }
552 else
553 {
554 lcf_error("No <STATIC.CRT0.OBJECT> Ignored.");
555 }
556 }
557
558 // Object
PutStaticObject(const char * sectionName)559 static void PutStaticObject(const char *sectionName)
560 {
561 if (!PutObject(StaticObject, sectionName))
562 {
563 lcf_error("No <FOREACH.STATIC.OBJECTS> Ignored.");
564 }
565 }
566
567 // Foreach Objects
ForeachStaticObjects(int n)568 static int ForeachStaticObjects(int n)
569 {
570 return ForeachObjects(&StaticObject, Static.objects.head, n);
571 }
572
573 // Library
PutStaticLibrary(const char * sectionName)574 static void PutStaticLibrary(const char *sectionName)
575 {
576 if (!PutObject(StaticLibrary, sectionName))
577 {
578 lcf_error("No <FOREACH.STATIC.LIBRARIES> Ignored.");
579 }
580 }
581
582 // Foreach Libraries
ForeachStaticLibraries(int n)583 static int ForeachStaticLibraries(int n)
584 {
585 return ForeachObjects(&StaticLibrary, Static.libraries.head, n);
586 }
587
588 // SearchSymbol
PutStaticSearchSymbol(const char * dummy)589 static void PutStaticSearchSymbol(const char *dummy)
590 {
591 if (!PutObject(StaticSearchSymbol, NULL))
592 {
593 lcf_error("No <FOREACH.STATIC.SEARCHSYMBOLS> Ignored.");
594 }
595 }
596
597 // Foreach SearchSymbols
ForeachStaticSearchSymbols(int n)598 static int ForeachStaticSearchSymbols(int n)
599 {
600 return ForeachObjects(&StaticSearchSymbol, Static.searchSymbols.head, n);
601 }
602
603 // Force
PutStaticForce(const char * dummy)604 static void PutStaticForce(const char *dummy)
605 {
606 if (!PutObject(StaticForce, NULL))
607 {
608 lcf_error("No <FOREACH.STATIC.FORCES> Ignored.");
609 }
610 }
611
612 // Foreach Forces
ForeachStaticForces(int n)613 static int ForeachStaticForces(int n)
614 {
615 return ForeachObjectsForce(&StaticForce, Static.forces.head, n);
616 }
617
618
619 //======== AUTOLOAD ========//
620
621 // Id
PutAutoloadId(void)622 static void PutAutoloadId(void)
623 {
624 if (Autoload)
625 PutNumber(Autoload->id);
626 else
627 lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
628 }
629
630 // Name
PutAutoloadName(void)631 static void PutAutoloadName(void)
632 {
633 if (Autoload)
634 PutString(Autoload->name);
635 else
636 lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
637 }
638
639 // Address
PutAutoloadAddress(void)640 static void PutAutoloadAddress(void)
641 {
642 if (Autoload)
643 PutSectionAddress(Autoload);
644 else
645 lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
646 }
647
648 // Object
PutAutoloadObject(const char * sectionName)649 static void PutAutoloadObject(const char *sectionName)
650 {
651 if (!PutObject(AutoloadObject, sectionName))
652 {
653 lcf_error("No <FOREACH.AUTOLOAD.OBJECTS> Ignored.");
654 }
655 }
656
657 // Foreach Objects
ForeachAutoloadObjects(int n)658 static int ForeachAutoloadObjects(int n)
659 {
660 return ForeachObjects(&AutoloadObject, Autoload->objects.head, n);
661 }
662
663 // Library
PutAutoloadLibrary(const char * sectionName)664 static void PutAutoloadLibrary(const char *sectionName)
665 {
666 if (!PutObject(AutoloadLibrary, sectionName))
667 {
668 lcf_error("No <FOREACH.AUTOLOAD.LIBRARIES> Ignored.");
669 }
670 }
671
672 // Foreach Libraries
ForeachAutoloadLibraries(int n)673 static int ForeachAutoloadLibraries(int n)
674 {
675 return ForeachObjects(&AutoloadLibrary, Autoload->libraries.head, n);
676 }
677
678 // SearchSymbol
PutAutoloadSearchSymbol(const char * dummy)679 static void PutAutoloadSearchSymbol(const char *dummy)
680 {
681 if (!PutObject(AutoloadSearchSymbol, NULL))
682 {
683 lcf_error("No <FOREACH.AUTOLOAD.SEARCHSYMBOLS> Ignored.");
684 }
685 }
686
687 // Foreach SearchSymbols
ForeachAutoloadSearchSymbols(int n)688 static int ForeachAutoloadSearchSymbols(int n)
689 {
690 return ForeachObjects(&AutoloadSearchSymbol, Autoload->searchSymbols.head, n);
691 }
692
693 // Force
PutAutoloadForce(const char * dummy)694 static void PutAutoloadForce(const char *dummy)
695 {
696 if (!PutObject(AutoloadForce, NULL))
697 {
698 lcf_error("No <FOREACH.AUTOLOAD.FORCES> Ignored.");
699 }
700 }
701
702 // Foreach Forces
ForeachAutoloadForces(int n)703 static int ForeachAutoloadForces(int n)
704 {
705 return ForeachObjectsForce(&AutoloadForce, Autoload->forces.head, n);
706 }
707
708 // Foreach Autoloads
ForeachAutoloads(int n)709 static int ForeachAutoloads(int n)
710 {
711 tOverlay *start = AutoloadList.head;
712
713 while (start)
714 {
715 Autoload = start;
716 PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
717 start = start->next;
718 }
719 Autoload = NULL;
720 return tokenBuffer[n].loop_end;
721 }
722
723
724 //======== OVERLAY ========//
725
726 // Id
PutOverlayId(void)727 static void PutOverlayId(void)
728 {
729 if (Overlay)
730 PutNumber(Overlay->id);
731 else
732 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
733 }
734
735 // Name
PutOverlayName(void)736 static void PutOverlayName(void)
737 {
738 if (Overlay)
739 PutString(Overlay->name);
740 else
741 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
742 }
743
744 // Group
PutOverlayGroup(void)745 static void PutOverlayGroup(void)
746 {
747 if (Overlay)
748 {
749 // If a group has not been set, use the name of the overlay as a group
750 PutString(Overlay->group ? Overlay->group : Overlay->name);
751 }
752 else
753 {
754 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
755 }
756 }
757
758 // Address
PutOverlayAddress(void)759 static void PutOverlayAddress(void)
760 {
761 if (Overlay)
762 PutSectionAddress(Overlay);
763 else
764 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
765 }
766
767 // Compression spec
PutOverlayCompress(void)768 static void PutOverlayCompress(void)
769 {
770 if (Overlay)
771 {
772 fprintf(fp_out, "%c", Overlay->compressSpec);
773 }
774 else
775 {
776 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
777 }
778 }
779
780 // Object
PutOverlayObject(const char * sectionName)781 static void PutOverlayObject(const char *sectionName)
782 {
783 if (!PutObject(OverlayObject, sectionName))
784 {
785 lcf_error("No <FOREACH.OVERLAY.OBJECTS> Ignored.");
786 }
787 }
788
789 // Foreach Objects
ForeachOverlayObjects(int n)790 static int ForeachOverlayObjects(int n)
791 {
792 return ForeachObjects(&OverlayObject, Overlay->objects.head, n);
793 }
794
795 // Library
PutOverlayLibrary(const char * sectionName)796 static void PutOverlayLibrary(const char *sectionName)
797 {
798 if (!PutObject(OverlayLibrary, sectionName))
799 {
800 lcf_error("No <FOREACH.OVERLAY.LIBRARIES> Ignored.");
801 }
802 }
803
804 // Foreach Libraries
ForeachOverlayLibraries(int n)805 static int ForeachOverlayLibraries(int n)
806 {
807 return ForeachObjects(&OverlayLibrary, Overlay->libraries.head, n);
808 }
809
810 // SearchSymbol
PutOverlaySearchSymbol(const char * dummy)811 static void PutOverlaySearchSymbol(const char *dummy)
812 {
813 if (!PutObject(OverlaySearchSymbol, NULL))
814 {
815 lcf_error("No <FOREACH.OVERLAY.SEARCHSYMBOLS> Ignored.");
816 }
817 }
818
819 // Foreach SearchSymbols
ForeachOverlaySearchSymbols(int n)820 static int ForeachOverlaySearchSymbols(int n)
821 {
822 return ForeachObjects(&OverlaySearchSymbol, Overlay->searchSymbols.head, n);
823 }
824
825 // Force
PutOverlayForce(const char * dummy)826 static void PutOverlayForce(const char *dummy)
827 {
828 if (!PutObject(OverlayForce, NULL))
829 {
830 lcf_error("No <FOREACH.OVERLAY.FORCES> Ignored.");
831 }
832 }
833
834 // Foreach Forces
ForeachOverlayForces(int n)835 static int ForeachOverlayForces(int n)
836 {
837 return ForeachObjectsForce(&OverlayForce, Overlay->forces.head, n);
838 }
839
840 // Foreach Overlays
ForeachOverlays(int n)841 static int ForeachOverlays(int n)
842 {
843 tOverlay *start = OverlayList.head;
844 tTokenBuffer *token = &tokenBuffer[n];
845 tMemType memtype = GetMemTypeParam(token->string);
846
847 while (start)
848 {
849 if (memtype == MEMTYPE_NONE || memtype == RecgSectionMemTypeByName(start->name))
850 {
851 Overlay = start;
852 PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
853 }
854 start = start->next;
855 }
856 Overlay = NULL;
857 return tokenBuffer[n].loop_end;
858 }
859
860 //======== LTDAUTOLOAD ========//
861
862 // Id
PutLtdautoloadId(void)863 static void PutLtdautoloadId(void)
864 {
865 if (Ltdautoload)
866 PutNumber(Ltdautoload->id);
867 else
868 lcf_error("No <FOREACH.LTDAUTOLOADS> Ignored.");
869 }
870
871 // Name
PutLtdautoloadName(void)872 static void PutLtdautoloadName(void)
873 {
874 if (Ltdautoload)
875 PutString(Ltdautoload->name);
876 else
877 lcf_error("No <FOREACH.LTDAUTOLOADS> Ignored.");
878 }
879
880 // Address
PutLtdautoloadAddress(void)881 static void PutLtdautoloadAddress(void)
882 {
883 if (Ltdautoload)
884 PutSectionAddress(Ltdautoload);
885 else
886 lcf_error("No <FOREACH.LTDAUTOLOADS> Ignored.");
887 }
888
889 // Object
PutLtdautoloadObject(const char * sectionName)890 static void PutLtdautoloadObject(const char *sectionName)
891 {
892 if (!PutObject(LtdautoloadObject, sectionName))
893 {
894 lcf_error("No <FOREACH.LTDAUTOLOAD.OBJECTS> Ignored.");
895 }
896 }
897
898 // Foreach Objects
ForeachLtdautoloadObjects(int n)899 static int ForeachLtdautoloadObjects(int n)
900 {
901 return ForeachObjects(&LtdautoloadObject, Ltdautoload->objects.head, n);
902 }
903
904 // Library
PutLtdautoloadLibrary(const char * sectionName)905 static void PutLtdautoloadLibrary(const char *sectionName)
906 {
907 if (!PutObject(LtdautoloadLibrary, sectionName))
908 {
909 lcf_error("No <FOREACH.LTDAUTOLOAD.LIBRARIES> Ignored.");
910 }
911 }
912
913 // Foreach Libraries
ForeachLtdautoloadLibraries(int n)914 static int ForeachLtdautoloadLibraries(int n)
915 {
916 return ForeachObjects(&LtdautoloadLibrary, Ltdautoload->libraries.head, n);
917 }
918
919 // SearchSymbol
PutLtdautoloadSearchSymbol(const char * dummy)920 static void PutLtdautoloadSearchSymbol(const char *dummy)
921 {
922 if (!PutObject(LtdautoloadSearchSymbol, NULL))
923 {
924 lcf_error("No <FOREACH.LTDAUTOLOAD.SEARCHSYMBOLS> Ignored.");
925 }
926 }
927
928 // Foreach SearchSymbols
ForeachLtdautoloadSearchSymbols(int n)929 static int ForeachLtdautoloadSearchSymbols(int n)
930 {
931 return ForeachObjects(&LtdautoloadSearchSymbol, Ltdautoload->searchSymbols.head, n);
932 }
933
934 // Force
PutLtdautoloadForce(const char * dummy)935 static void PutLtdautoloadForce(const char *dummy)
936 {
937 if (!PutObject(LtdautoloadForce, NULL))
938 {
939 lcf_error("No <FOREACH.LTDAUTOLOAD.FORCES> Ignored.");
940 }
941 }
942
943 // Foreach Forces
ForeachLtdautoloadForces(int n)944 static int ForeachLtdautoloadForces(int n)
945 {
946 return ForeachObjectsForce(&LtdautoloadForce, Ltdautoload->forces.head, n);
947 }
948
949 // Foreach Ltdautoloads
ForeachLtdautoloads(int n)950 static int ForeachLtdautoloads(int n)
951 {
952 tOverlay *start = LtdautoloadList.head;
953
954 while (start)
955 {
956 Ltdautoload = start;
957 PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
958 start = start->next;
959 }
960 Ltdautoload = NULL;
961 return tokenBuffer[n].loop_end;
962 }
963
964 //======== LTDOVERLAY ========//
965
966 // Id
PutLtdoverlayId(void)967 static void PutLtdoverlayId(void)
968 {
969 if (Ltdoverlay)
970 PutNumber(Ltdoverlay->id);
971 else
972 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
973 }
974
975 // Name
PutLtdoverlayName(void)976 static void PutLtdoverlayName(void)
977 {
978 if (Ltdoverlay)
979 PutString(Ltdoverlay->name);
980 else
981 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
982 }
983
984 // Group
PutLtdoverlayGroup(void)985 static void PutLtdoverlayGroup(void)
986 {
987 if (Ltdoverlay)
988 {
989 // If a group has not been set, use the name of the overlay as a group
990 PutString(Ltdoverlay->group ? Ltdoverlay->group : Ltdoverlay->name);
991 }
992 else
993 {
994 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
995 }
996 }
997
998 // Address
PutLtdoverlayAddress(void)999 static void PutLtdoverlayAddress(void)
1000 {
1001 if (Ltdoverlay)
1002 PutSectionAddress(Ltdoverlay);
1003 else
1004 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
1005 }
1006
1007 // Compression spec
PutLtdoverlayCompress(void)1008 static void PutLtdoverlayCompress(void)
1009 {
1010 if (Ltdoverlay)
1011 {
1012 fprintf(fp_out, "%c", Ltdoverlay->compressSpec);
1013 }
1014 else
1015 {
1016 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
1017 }
1018 }
1019
1020 // Object
PutLtdoverlayObject(const char * sectionName)1021 static void PutLtdoverlayObject(const char *sectionName)
1022 {
1023 if (!PutObject(LtdoverlayObject, sectionName))
1024 {
1025 lcf_error("No <FOREACH.LTDOVERLAY.OBJECTS> Ignored.");
1026 }
1027 }
1028
1029 // Foreach Objects
ForeachLtdoverlayObjects(int n)1030 static int ForeachLtdoverlayObjects(int n)
1031 {
1032 return ForeachObjects(&LtdoverlayObject, Ltdoverlay->objects.head, n);
1033 }
1034
1035 // Library
PutLtdoverlayLibrary(const char * sectionName)1036 static void PutLtdoverlayLibrary(const char *sectionName)
1037 {
1038 if (!PutObject(LtdoverlayLibrary, sectionName))
1039 {
1040 lcf_error("No <FOREACH.LTDOVERLAY.LIBRARIES> Ignored.");
1041 }
1042 }
1043
1044 // Foreach Libraries
ForeachLtdoverlayLibraries(int n)1045 static int ForeachLtdoverlayLibraries(int n)
1046 {
1047 return ForeachObjects(&LtdoverlayLibrary, Ltdoverlay->libraries.head, n);
1048 }
1049
1050 // SearchSymbol
PutLtdoverlaySearchSymbol(const char * dummy)1051 static void PutLtdoverlaySearchSymbol(const char *dummy)
1052 {
1053 if (!PutObject(LtdoverlaySearchSymbol, NULL))
1054 {
1055 lcf_error("No <FOREACH.LTDOVERLAY.SEARCHSYMBOLS> Ignored.");
1056 }
1057 }
1058
1059 // Foreach SearchSymbols
ForeachLtdoverlaySearchSymbols(int n)1060 static int ForeachLtdoverlaySearchSymbols(int n)
1061 {
1062 return ForeachObjects(&LtdoverlaySearchSymbol, Ltdoverlay->searchSymbols.head, n);
1063 }
1064
1065 // Force
PutLtdoverlayForce(const char * dummy)1066 static void PutLtdoverlayForce(const char *dummy)
1067 {
1068 if (!PutObject(LtdoverlayForce, NULL))
1069 {
1070 lcf_error("No <FOREACH.LTDOVERLAY.FORCES> Ignored.");
1071 }
1072 }
1073
1074 // Foreach Forces
ForeachLtdoverlayForces(int n)1075 static int ForeachLtdoverlayForces(int n)
1076 {
1077 return ForeachObjectsForce(&LtdoverlayForce, Ltdoverlay->forces.head, n);
1078 }
1079
1080 // Foreach Ltdoverlays
ForeachLtdoverlays(int n)1081 static int ForeachLtdoverlays(int n)
1082 {
1083 tOverlay *start = LtdoverlayList.head;
1084 tTokenBuffer *token = &tokenBuffer[n];
1085 tMemType memtype = GetMemTypeParam(token->string);
1086
1087 while (start)
1088 {
1089 if (memtype == MEMTYPE_NONE || memtype == RecgSectionMemTypeByName(start->name))
1090 {
1091 Ltdoverlay = start;
1092 PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
1093 }
1094 start = start->next;
1095 }
1096 Ltdoverlay = NULL;
1097 return tokenBuffer[n].loop_end;
1098 }
1099
1100 /*============================================================================
1101 * Put Token List
1102 */
PutToken(int n)1103 static int PutToken(int n)
1104 {
1105 switch (tokenBuffer[n].id)
1106 {
1107 case tSTRING:
1108 PutString(tokenBuffer[n].string);
1109 break;
1110
1111 case tSTATIC_NAME:
1112 PutString(Static.name);
1113 break;
1114
1115 case tSTATIC_ADDRESS:
1116 PutAddress(Static.address);
1117 break;
1118
1119 case tSTATIC_CRT0_OBJECT:
1120 PutStaticCrt0Object(tokenBuffer[n].string);
1121 break;
1122
1123 case tSTATIC_OBJECT:
1124 PutStaticObject(tokenBuffer[n].string);
1125 break;
1126
1127 case tSTATIC_LIBRARY:
1128 PutStaticLibrary(tokenBuffer[n].string);
1129 break;
1130
1131 case tSTATIC_SEARCHSYMBOL:
1132 PutStaticSearchSymbol(tokenBuffer[n].string);
1133 break;
1134
1135 case tSTATIC_FORCE:
1136 PutStaticForce(tokenBuffer[n].string);
1137 break;
1138
1139 case tSTATIC_STACKSIZE:
1140 PutNumber(Static.stacksize);
1141 break;
1142
1143 case tSTATIC_IRQSTACKSIZE:
1144 PutNumber(Static.stacksize_irq);
1145 break;
1146
1147 case tFOREACH_STATIC_OBJECTS:
1148 n = ForeachStaticObjects(n);
1149 break;
1150
1151 case tFOREACH_STATIC_LIBRARIES:
1152 n = ForeachStaticLibraries(n);
1153 break;
1154
1155 case tFOREACH_STATIC_SEARCHSYMBOLS:
1156 n = ForeachStaticSearchSymbols(n);
1157 break;
1158
1159 case tFOREACH_STATIC_FORCES:
1160 n = ForeachStaticForces(n);
1161 break;
1162
1163 case tAUTOLOAD_ID:
1164 PutAutoloadId();
1165 break;
1166
1167 case tAUTOLOAD_NAME:
1168 PutAutoloadName();
1169 break;
1170
1171 case tAUTOLOAD_ADDRESS:
1172 PutAutoloadAddress();
1173 break;
1174
1175 case tAUTOLOAD_OBJECT:
1176 PutAutoloadObject(tokenBuffer[n].string);
1177 break;
1178
1179 case tAUTOLOAD_LIBRARY:
1180 PutAutoloadLibrary(tokenBuffer[n].string);
1181 break;
1182
1183 case tAUTOLOAD_SEARCHSYMBOL:
1184 PutAutoloadSearchSymbol(tokenBuffer[n].string);
1185 break;
1186
1187 case tAUTOLOAD_FORCE:
1188 PutAutoloadForce(tokenBuffer[n].string);
1189 break;
1190
1191 case tNUMBER_AUTOLOADS:
1192 PutNumber(AutoloadList.num);
1193 break;
1194
1195 case tFOREACH_AUTOLOADS:
1196 n = ForeachAutoloads(n);
1197 break;
1198
1199 case tFOREACH_AUTOLOAD_OBJECTS:
1200 n = ForeachAutoloadObjects(n);
1201 break;
1202
1203 case tFOREACH_AUTOLOAD_LIBRARIES:
1204 n = ForeachAutoloadLibraries(n);
1205 break;
1206
1207 case tFOREACH_AUTOLOAD_SEARCHSYMBOLS:
1208 n = ForeachAutoloadSearchSymbols(n);
1209 break;
1210
1211 case tFOREACH_AUTOLOAD_FORCES:
1212 n = ForeachAutoloadForces(n);
1213 break;
1214
1215 case tOVERLAY_ID:
1216 PutOverlayId();
1217 break;
1218
1219 case tOVERLAY_NAME:
1220 PutOverlayName();
1221 break;
1222
1223 case tOVERLAY_GROUP:
1224 PutOverlayGroup();
1225 break;
1226
1227 case tOVERLAY_ADDRESS:
1228 PutOverlayAddress();
1229 break;
1230
1231 case tOVERLAY_COMPRESS:
1232 PutOverlayCompress();
1233 break;
1234
1235 case tOVERLAY_OBJECT:
1236 PutOverlayObject(tokenBuffer[n].string);
1237 break;
1238
1239 case tOVERLAY_LIBRARY:
1240 PutOverlayLibrary(tokenBuffer[n].string);
1241 break;
1242
1243 case tOVERLAY_SEARCHSYMBOL:
1244 PutOverlaySearchSymbol(tokenBuffer[n].string);
1245 break;
1246
1247 case tOVERLAY_FORCE:
1248 PutOverlayForce(tokenBuffer[n].string);
1249 break;
1250
1251 case tNUMBER_OVERLAYS:
1252 PutNumber(OverlayList.num);
1253 break;
1254
1255 case tFOREACH_OVERLAYS:
1256 n = ForeachOverlays(n);
1257 break;
1258
1259 case tFOREACH_OVERLAY_OBJECTS:
1260 n = ForeachOverlayObjects(n);
1261 break;
1262
1263 case tFOREACH_OVERLAY_LIBRARIES:
1264 n = ForeachOverlayLibraries(n);
1265 break;
1266
1267 case tFOREACH_OVERLAY_SEARCHSYMBOLS:
1268 n = ForeachOverlaySearchSymbols(n);
1269 break;
1270
1271 case tFOREACH_OVERLAY_FORCES:
1272 n = ForeachOverlayForces(n);
1273 break;
1274
1275 case tLTDAUTOLOAD_ID:
1276 PutLtdautoloadId();
1277 break;
1278
1279 case tLTDAUTOLOAD_NAME:
1280 PutLtdautoloadName();
1281 break;
1282
1283 case tLTDAUTOLOAD_ADDRESS:
1284 PutLtdautoloadAddress();
1285 break;
1286
1287 case tLTDAUTOLOAD_OBJECT:
1288 PutLtdautoloadObject(tokenBuffer[n].string);
1289 break;
1290
1291 case tLTDAUTOLOAD_LIBRARY:
1292 PutLtdautoloadLibrary(tokenBuffer[n].string);
1293 break;
1294
1295 case tLTDAUTOLOAD_SEARCHSYMBOL:
1296 PutLtdautoloadSearchSymbol(tokenBuffer[n].string);
1297 break;
1298
1299 case tLTDAUTOLOAD_FORCE:
1300 PutLtdautoloadForce(tokenBuffer[n].string);
1301 break;
1302
1303 case tNUMBER_LTDAUTOLOADS:
1304 PutNumber(LtdautoloadList.num);
1305 break;
1306
1307 case tFOREACH_LTDAUTOLOADS:
1308 n = ForeachLtdautoloads(n);
1309 break;
1310
1311 case tFOREACH_LTDAUTOLOAD_OBJECTS:
1312 n = ForeachLtdautoloadObjects(n);
1313 break;
1314
1315 case tFOREACH_LTDAUTOLOAD_LIBRARIES:
1316 n = ForeachLtdautoloadLibraries(n);
1317 break;
1318
1319 case tFOREACH_LTDAUTOLOAD_SEARCHSYMBOLS:
1320 n = ForeachLtdautoloadSearchSymbols(n);
1321 break;
1322
1323 case tFOREACH_LTDAUTOLOAD_FORCES:
1324 n = ForeachLtdautoloadForces(n);
1325 break;
1326
1327 case tLTDOVERLAY_ID:
1328 PutLtdoverlayId();
1329 break;
1330
1331 case tLTDOVERLAY_NAME:
1332 PutLtdoverlayName();
1333 break;
1334
1335 case tLTDOVERLAY_GROUP:
1336 PutLtdoverlayGroup();
1337 break;
1338
1339 case tLTDOVERLAY_ADDRESS:
1340 PutLtdoverlayAddress();
1341 break;
1342
1343 case tLTDOVERLAY_COMPRESS:
1344 PutLtdoverlayCompress();
1345 break;
1346
1347 case tLTDOVERLAY_OBJECT:
1348 PutLtdoverlayObject(tokenBuffer[n].string);
1349 break;
1350
1351 case tLTDOVERLAY_LIBRARY:
1352 PutLtdoverlayLibrary(tokenBuffer[n].string);
1353 break;
1354
1355 case tLTDOVERLAY_SEARCHSYMBOL:
1356 PutLtdoverlaySearchSymbol(tokenBuffer[n].string);
1357 break;
1358
1359 case tLTDOVERLAY_FORCE:
1360 PutLtdoverlayForce(tokenBuffer[n].string);
1361 break;
1362
1363 case tNUMBER_LTDOVERLAYS:
1364 PutNumber(LtdoverlayList.num);
1365 break;
1366
1367 case tFOREACH_LTDOVERLAYS:
1368 n = ForeachLtdoverlays(n);
1369 break;
1370
1371 case tFOREACH_LTDOVERLAY_OBJECTS:
1372 n = ForeachLtdoverlayObjects(n);
1373 break;
1374
1375 case tFOREACH_LTDOVERLAY_LIBRARIES:
1376 n = ForeachLtdoverlayLibraries(n);
1377 break;
1378
1379 case tFOREACH_LTDOVERLAY_SEARCHSYMBOLS:
1380 n = ForeachLtdoverlaySearchSymbols(n);
1381 break;
1382
1383 case tFOREACH_LTDOVERLAY_FORCES:
1384 n = ForeachLtdoverlayForces(n);
1385 break;
1386
1387 case tPROPERTY_OVERLAYDEFS:
1388 PutString(Property.overlaydefs);
1389 break;
1390
1391 case tPROPERTY_OVERLAYTABLE:
1392 PutString(Property.overlaytable);
1393 break;
1394
1395 case tPROPERTY_LTDOVERLAYDEFS:
1396 PutString(Property.ltdoverlaydefs);
1397 break;
1398
1399 case tPROPERTY_LTDOVERLAYTABLE:
1400 PutString(Property.ltdoverlaytable);
1401 break;
1402
1403 case tPROPERTY_SUFFIX:
1404 PutString(Property.suffix);
1405 break;
1406
1407 case tPROPERTY_FLXSUFFIX:
1408 PutString(Property.flxsuffix);
1409 break;
1410
1411 case tPROPERTY_LTDSUFFIX:
1412 PutString(Property.ltdsuffix);
1413 break;
1414
1415 default:
1416 lcf_error("Unknown token\n");
1417 }
1418 return n;
1419 }
1420
PutTokenBuffer(int start,int end)1421 static void PutTokenBuffer(int start, int end)
1422 {
1423 int i;
1424
1425 for (i = start; i <= end; i++)
1426 {
1427 i = PutToken(i);
1428 }
1429 }
1430
PutTokenBufferAll(void)1431 static void PutTokenBufferAll(void)
1432 {
1433 PutTokenBuffer(0, tokenBufferEnd - 1);
1434 }
1435
1436
1437 /*============================================================================
1438 * Create LCF file
1439 */
CreateLcfFile(const char * filename)1440 int CreateLcfFile(const char *filename)
1441 {
1442 if (filename)
1443 {
1444 if (NULL == (fp_out = fopen(filename, "wb")))
1445 {
1446 fprintf(stderr, "makelcf: Cannot write %s\n", filename);
1447 return 2;
1448 }
1449 PutTokenBufferAll();
1450 fclose(fp_out);
1451 }
1452 else
1453 {
1454 setmode(1, O_BINARY);
1455 fp_out = stdout;
1456 PutTokenBufferAll();
1457 }
1458
1459 return 0;
1460 }
1461