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