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-06-04#$
14 $Rev: 10698 $
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 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 BOOL isObjectOK(const tObject * obj, const char *section, char filter_type);
43 static BOOL isSectionWildcard(const char *section);
44 static BOOL isSectionRegular(const char *section);
45 static int ForeachObjects(tObject ** ptrObject, tObject * start, int n);
46 static int ForeachStaticObjects(int n);
47 static int ForeachOverlayObjects(int n);
48 static int ForeachOverlays(int n);
49 static int PutToken(int n);
50 static void PutTokenBuffer(int start, int end);
51 static void PutTokenBufferAll(void);
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 // Crt0 Object
PutStaticCrt0Object(const char * sectionName)500 static void PutStaticCrt0Object(const char *sectionName)
501 {
502 const char *objectName = SearchDefVal("CRT0_O");
503
504 if(objectName)
505 {
506 char* section = GetObjectSection(sectionName);
507
508 PutString(objectName);
509
510 if (section)
511 {
512 PutString(" (");
513 PutString(section);
514 PutString(")");
515 Free(§ion);
516 }
517 }
518 else
519 {
520 lcf_error("No <STATIC.CRT0.OBJECT> Ignored.");
521 }
522 }
523
524 // Object
PutStaticObject(const char * sectionName)525 static void PutStaticObject(const char *sectionName)
526 {
527 if (!PutObject(StaticObject, sectionName))
528 {
529 lcf_error("No <FOREACH.STATIC.OBJECTS> Ignored.");
530 }
531 }
532
533 // Foreach Objects
ForeachStaticObjects(int n)534 static int ForeachStaticObjects(int n)
535 {
536 return ForeachObjects(&StaticObject, Static.objects.head, n);
537 }
538
539 // Library
PutStaticLibrary(const char * sectionName)540 static void PutStaticLibrary(const char *sectionName)
541 {
542 if (!PutObject(StaticLibrary, sectionName))
543 {
544 lcf_error("No <FOREACH.STATIC.LIBRARIES> Ignored.");
545 }
546 }
547
548 // Foreach Libraries
ForeachStaticLibraries(int n)549 static int ForeachStaticLibraries(int n)
550 {
551 return ForeachObjects(&StaticLibrary, Static.libraries.head, n);
552 }
553
554 // SearchSymbol
PutStaticSearchSymbol(const char * dummy)555 static void PutStaticSearchSymbol(const char *dummy)
556 {
557 if (!PutObject(StaticSearchSymbol, NULL))
558 {
559 lcf_error("No <FOREACH.STATIC.SEARCHSYMBOLS> Ignored.");
560 }
561 }
562
563 // Foreach SearchSymbols
ForeachStaticSearchSymbols(int n)564 static int ForeachStaticSearchSymbols(int n)
565 {
566 return ForeachObjects(&StaticSearchSymbol, Static.searchSymbols.head, n);
567 }
568
569
570 //======== AUTOLOAD ========//
571
572 // Id
PutAutoloadId(void)573 static void PutAutoloadId(void)
574 {
575 if (Autoload)
576 PutNumber(Autoload->id);
577 else
578 lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
579 }
580
581 // Name
PutAutoloadName(void)582 static void PutAutoloadName(void)
583 {
584 if (Autoload)
585 PutString(Autoload->name);
586 else
587 lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
588 }
589
590 // Address
PutAutoloadAddress(void)591 static void PutAutoloadAddress(void)
592 {
593 if (Autoload)
594 PutSectionAddress(Autoload);
595 else
596 lcf_error("No <FOREACH.AUTOLOADS> Ignored.");
597 }
598
599 // Object
PutAutoloadObject(const char * sectionName)600 static void PutAutoloadObject(const char *sectionName)
601 {
602 if (!PutObject(AutoloadObject, sectionName))
603 {
604 lcf_error("No <FOREACH.AUTOLOAD.OBJECTS> Ignored.");
605 }
606 }
607
608 // Foreach Objects
ForeachAutoloadObjects(int n)609 static int ForeachAutoloadObjects(int n)
610 {
611 return ForeachObjects(&AutoloadObject, Autoload->objects.head, n);
612 }
613
614 // Library
PutAutoloadLibrary(const char * sectionName)615 static void PutAutoloadLibrary(const char *sectionName)
616 {
617 if (!PutObject(AutoloadLibrary, sectionName))
618 {
619 lcf_error("No <FOREACH.AUTOLOAD.LIBRARIES> Ignored.");
620 }
621 }
622
623 // Foreach Libraries
ForeachAutoloadLibraries(int n)624 static int ForeachAutoloadLibraries(int n)
625 {
626 return ForeachObjects(&AutoloadLibrary, Autoload->libraries.head, n);
627 }
628
629 // SearchSymbol
PutAutoloadSearchSymbol(const char * dummy)630 static void PutAutoloadSearchSymbol(const char *dummy)
631 {
632 if (!PutObject(AutoloadSearchSymbol, NULL))
633 {
634 lcf_error("No <FOREACH.AUTOLOAD.SEARCHSYMBOLS> Ignored.");
635 }
636 }
637
638 // Foreach SearchSymbols
ForeachAutoloadSearchSymbols(int n)639 static int ForeachAutoloadSearchSymbols(int n)
640 {
641 return ForeachObjects(&AutoloadSearchSymbol, Autoload->searchSymbols.head, n);
642 }
643
644 // Foreach Autoloads
ForeachAutoloads(int n)645 static int ForeachAutoloads(int n)
646 {
647 tOverlay *start = AutoloadList.head;
648
649 while (start)
650 {
651 Autoload = start;
652 PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
653 start = start->next;
654 }
655 Autoload = NULL;
656 return tokenBuffer[n].loop_end;
657 }
658
659
660 //======== OVERLAY ========//
661
662 // Id
PutOverlayId(void)663 static void PutOverlayId(void)
664 {
665 if (Overlay)
666 PutNumber(Overlay->id);
667 else
668 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
669 }
670
671 // Name
PutOverlayName(void)672 static void PutOverlayName(void)
673 {
674 if (Overlay)
675 PutString(Overlay->name);
676 else
677 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
678 }
679
680 // Group
PutOverlayGroup(void)681 static void PutOverlayGroup(void)
682 {
683 if (Overlay)
684 {
685 // If a group has not been set, use the name of the overlay as a group
686 PutString(Overlay->group ? Overlay->group : Overlay->name);
687 }
688 else
689 {
690 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
691 }
692 }
693
694 // Address
PutOverlayAddress(void)695 static void PutOverlayAddress(void)
696 {
697 if (Overlay)
698 PutSectionAddress(Overlay);
699 else
700 lcf_error("No <FOREACH.OVERLAYS> Ignored.");
701 }
702
703 // Object
PutOverlayObject(const char * sectionName)704 static void PutOverlayObject(const char *sectionName)
705 {
706 if (!PutObject(OverlayObject, sectionName))
707 {
708 lcf_error("No <FOREACH.OVERLAY.OBJECTS> Ignored.");
709 }
710 }
711
712 // Foreach Objects
ForeachOverlayObjects(int n)713 static int ForeachOverlayObjects(int n)
714 {
715 return ForeachObjects(&OverlayObject, Overlay->objects.head, n);
716 }
717
718 // Library
PutOverlayLibrary(const char * sectionName)719 static void PutOverlayLibrary(const char *sectionName)
720 {
721 if (!PutObject(OverlayLibrary, sectionName))
722 {
723 lcf_error("No <FOREACH.OVERLAY.LIBRARIES> Ignored.");
724 }
725 }
726
727 // Foreach Libraries
ForeachOverlayLibraries(int n)728 static int ForeachOverlayLibraries(int n)
729 {
730 return ForeachObjects(&OverlayLibrary, Overlay->libraries.head, n);
731 }
732
733 // SearchSymbol
PutOverlaySearchSymbol(const char * dummy)734 static void PutOverlaySearchSymbol(const char *dummy)
735 {
736 if (!PutObject(OverlaySearchSymbol, NULL))
737 {
738 lcf_error("No <FOREACH.OVERLAY.SEARCHSYMBOLS> Ignored.");
739 }
740 }
741
742 // Foreach SearchSymbols
ForeachOverlaySearchSymbols(int n)743 static int ForeachOverlaySearchSymbols(int n)
744 {
745 return ForeachObjects(&OverlaySearchSymbol, Overlay->searchSymbols.head, n);
746 }
747
748 // Foreach Overlays
ForeachOverlays(int n)749 static int ForeachOverlays(int n)
750 {
751 tOverlay *start = OverlayList.head;
752 tTokenBuffer *token = &tokenBuffer[n];
753 tMemType memtype = GetMemTypeParam(token->string);
754
755 while (start)
756 {
757 if (memtype == MEMTYPE_NONE || memtype == RecgSectionMemTypeByName(start->name))
758 {
759 Overlay = start;
760 PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
761 }
762 start = start->next;
763 }
764 Overlay = NULL;
765 return tokenBuffer[n].loop_end;
766 }
767
768 //======== LTDAUTOLOAD ========//
769
770 // Id
PutLtdautoloadId(void)771 static void PutLtdautoloadId(void)
772 {
773 if (Ltdautoload)
774 PutNumber(Ltdautoload->id);
775 else
776 lcf_error("No <FOREACH.LTDAUTOLOADS> Ignored.");
777 }
778
779 // Name
PutLtdautoloadName(void)780 static void PutLtdautoloadName(void)
781 {
782 if (Ltdautoload)
783 PutString(Ltdautoload->name);
784 else
785 lcf_error("No <FOREACH.LTDAUTOLOADS> Ignored.");
786 }
787
788 // Address
PutLtdautoloadAddress(void)789 static void PutLtdautoloadAddress(void)
790 {
791 if (Ltdautoload)
792 PutSectionAddress(Ltdautoload);
793 else
794 lcf_error("No <FOREACH.LTDAUTOLOADS> Ignored.");
795 }
796
797 // Object
PutLtdautoloadObject(const char * sectionName)798 static void PutLtdautoloadObject(const char *sectionName)
799 {
800 if (!PutObject(LtdautoloadObject, sectionName))
801 {
802 lcf_error("No <FOREACH.LTDAUTOLOAD.OBJECTS> Ignored.");
803 }
804 }
805
806 // Foreach Objects
ForeachLtdautoloadObjects(int n)807 static int ForeachLtdautoloadObjects(int n)
808 {
809 return ForeachObjects(&LtdautoloadObject, Ltdautoload->objects.head, n);
810 }
811
812 // Library
PutLtdautoloadLibrary(const char * sectionName)813 static void PutLtdautoloadLibrary(const char *sectionName)
814 {
815 if (!PutObject(LtdautoloadLibrary, sectionName))
816 {
817 lcf_error("No <FOREACH.LTDAUTOLOAD.LIBRARIES> Ignored.");
818 }
819 }
820
821 // Foreach Libraries
ForeachLtdautoloadLibraries(int n)822 static int ForeachLtdautoloadLibraries(int n)
823 {
824 return ForeachObjects(&LtdautoloadLibrary, Ltdautoload->libraries.head, n);
825 }
826
827 // SearchSymbol
PutLtdautoloadSearchSymbol(const char * dummy)828 static void PutLtdautoloadSearchSymbol(const char *dummy)
829 {
830 if (!PutObject(LtdautoloadSearchSymbol, NULL))
831 {
832 lcf_error("No <FOREACH.LTDAUTOLOAD.SEARCHSYMBOLS> Ignored.");
833 }
834 }
835
836 // Foreach SearchSymbols
ForeachLtdautoloadSearchSymbols(int n)837 static int ForeachLtdautoloadSearchSymbols(int n)
838 {
839 return ForeachObjects(&LtdautoloadSearchSymbol, Ltdautoload->searchSymbols.head, n);
840 }
841
842 // Foreach Ltdautoloads
ForeachLtdautoloads(int n)843 static int ForeachLtdautoloads(int n)
844 {
845 tOverlay *start = LtdautoloadList.head;
846
847 while (start)
848 {
849 Ltdautoload = start;
850 PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
851 start = start->next;
852 }
853 Ltdautoload = NULL;
854 return tokenBuffer[n].loop_end;
855 }
856
857 //======== LTDOVERLAY ========//
858
859 // Id
PutLtdoverlayId(void)860 static void PutLtdoverlayId(void)
861 {
862 if (Ltdoverlay)
863 PutNumber(Ltdoverlay->id);
864 else
865 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
866 }
867
868 // Name
PutLtdoverlayName(void)869 static void PutLtdoverlayName(void)
870 {
871 if (Ltdoverlay)
872 PutString(Ltdoverlay->name);
873 else
874 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
875 }
876
877 // Group
PutLtdoverlayGroup(void)878 static void PutLtdoverlayGroup(void)
879 {
880 if (Ltdoverlay)
881 {
882 // If a group has not been set, use the name of the overlay as a group
883 PutString(Ltdoverlay->group ? Ltdoverlay->group : Ltdoverlay->name);
884 }
885 else
886 {
887 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
888 }
889 }
890
891 // Address
PutLtdoverlayAddress(void)892 static void PutLtdoverlayAddress(void)
893 {
894 if (Ltdoverlay)
895 PutSectionAddress(Ltdoverlay);
896 else
897 lcf_error("No <FOREACH.LTDOVERLAYS> Ignored.");
898 }
899
900 // Object
PutLtdoverlayObject(const char * sectionName)901 static void PutLtdoverlayObject(const char *sectionName)
902 {
903 if (!PutObject(LtdoverlayObject, sectionName))
904 {
905 lcf_error("No <FOREACH.LTDOVERLAY.OBJECTS> Ignored.");
906 }
907 }
908
909 // Foreach Objects
ForeachLtdoverlayObjects(int n)910 static int ForeachLtdoverlayObjects(int n)
911 {
912 return ForeachObjects(&LtdoverlayObject, Ltdoverlay->objects.head, n);
913 }
914
915 // Library
PutLtdoverlayLibrary(const char * sectionName)916 static void PutLtdoverlayLibrary(const char *sectionName)
917 {
918 if (!PutObject(LtdoverlayLibrary, sectionName))
919 {
920 lcf_error("No <FOREACH.LTDOVERLAY.LIBRARIES> Ignored.");
921 }
922 }
923
924 // Foreach Libraries
ForeachLtdoverlayLibraries(int n)925 static int ForeachLtdoverlayLibraries(int n)
926 {
927 return ForeachObjects(&LtdoverlayLibrary, Ltdoverlay->libraries.head, n);
928 }
929
930 // SearchSymbol
PutLtdoverlaySearchSymbol(const char * dummy)931 static void PutLtdoverlaySearchSymbol(const char *dummy)
932 {
933 if (!PutObject(LtdoverlaySearchSymbol, NULL))
934 {
935 lcf_error("No <FOREACH.LTDOVERLAY.SEARCHSYMBOLS> Ignored.");
936 }
937 }
938
939 // Foreach SearchSymbols
ForeachLtdoverlaySearchSymbols(int n)940 static int ForeachLtdoverlaySearchSymbols(int n)
941 {
942 return ForeachObjects(&LtdoverlaySearchSymbol, Ltdoverlay->searchSymbols.head, n);
943 }
944
945 // Foreach Ltdoverlays
ForeachLtdoverlays(int n)946 static int ForeachLtdoverlays(int n)
947 {
948 tOverlay *start = LtdoverlayList.head;
949 tTokenBuffer *token = &tokenBuffer[n];
950 tMemType memtype = GetMemTypeParam(token->string);
951
952 while (start)
953 {
954 if (memtype == MEMTYPE_NONE || memtype == RecgSectionMemTypeByName(start->name))
955 {
956 Ltdoverlay = start;
957 PutTokenBuffer(n + 1, tokenBuffer[n].loop_end);
958 }
959 start = start->next;
960 }
961 Ltdoverlay = NULL;
962 return tokenBuffer[n].loop_end;
963 }
964
965 /*============================================================================
966 * Put Token List
967 */
PutToken(int n)968 static int PutToken(int n)
969 {
970 switch (tokenBuffer[n].id)
971 {
972 case tSTRING:
973 PutString(tokenBuffer[n].string);
974 break;
975
976 case tSTATIC_NAME:
977 PutString(Static.name);
978 break;
979
980 case tSTATIC_ADDRESS:
981 PutAddress(Static.address);
982 break;
983
984 case tSTATIC_CRT0_OBJECT:
985 PutStaticCrt0Object(tokenBuffer[n].string);
986 break;
987
988 case tSTATIC_OBJECT:
989 PutStaticObject(tokenBuffer[n].string);
990 break;
991
992 case tSTATIC_LIBRARY:
993 PutStaticLibrary(tokenBuffer[n].string);
994 break;
995
996 case tSTATIC_SEARCHSYMBOL:
997 PutStaticSearchSymbol(tokenBuffer[n].string);
998 break;
999
1000 case tSTATIC_STACKSIZE:
1001 PutNumber(Static.stacksize);
1002 break;
1003
1004 case tSTATIC_IRQSTACKSIZE:
1005 PutNumber(Static.stacksize_irq);
1006 break;
1007
1008 case tFOREACH_STATIC_OBJECTS:
1009 n = ForeachStaticObjects(n);
1010 break;
1011
1012 case tFOREACH_STATIC_LIBRARIES:
1013 n = ForeachStaticLibraries(n);
1014 break;
1015
1016 case tFOREACH_STATIC_SEARCHSYMBOLS:
1017 n = ForeachStaticSearchSymbols(n);
1018 break;
1019
1020 case tAUTOLOAD_ID:
1021 PutAutoloadId();
1022 break;
1023
1024 case tAUTOLOAD_NAME:
1025 PutAutoloadName();
1026 break;
1027
1028 case tAUTOLOAD_ADDRESS:
1029 PutAutoloadAddress();
1030 break;
1031
1032 case tAUTOLOAD_OBJECT:
1033 PutAutoloadObject(tokenBuffer[n].string);
1034 break;
1035
1036 case tAUTOLOAD_LIBRARY:
1037 PutAutoloadLibrary(tokenBuffer[n].string);
1038 break;
1039
1040 case tAUTOLOAD_SEARCHSYMBOL:
1041 PutAutoloadSearchSymbol(tokenBuffer[n].string);
1042 break;
1043
1044 case tNUMBER_AUTOLOADS:
1045 PutNumber(AutoloadList.num);
1046 break;
1047
1048 case tFOREACH_AUTOLOADS:
1049 n = ForeachAutoloads(n);
1050 break;
1051
1052 case tFOREACH_AUTOLOAD_OBJECTS:
1053 n = ForeachAutoloadObjects(n);
1054 break;
1055
1056 case tFOREACH_AUTOLOAD_LIBRARIES:
1057 n = ForeachAutoloadLibraries(n);
1058 break;
1059
1060 case tFOREACH_AUTOLOAD_SEARCHSYMBOLS:
1061 n = ForeachAutoloadSearchSymbols(n);
1062 break;
1063
1064 case tOVERLAY_ID:
1065 PutOverlayId();
1066 break;
1067
1068 case tOVERLAY_NAME:
1069 PutOverlayName();
1070 break;
1071
1072 case tOVERLAY_GROUP:
1073 PutOverlayGroup();
1074 break;
1075
1076 case tOVERLAY_ADDRESS:
1077 PutOverlayAddress();
1078 break;
1079
1080 case tOVERLAY_OBJECT:
1081 PutOverlayObject(tokenBuffer[n].string);
1082 break;
1083
1084 case tOVERLAY_LIBRARY:
1085 PutOverlayLibrary(tokenBuffer[n].string);
1086 break;
1087
1088 case tOVERLAY_SEARCHSYMBOL:
1089 PutOverlaySearchSymbol(tokenBuffer[n].string);
1090 break;
1091
1092 case tNUMBER_OVERLAYS:
1093 PutNumber(OverlayList.num);
1094 break;
1095
1096 case tFOREACH_OVERLAYS:
1097 n = ForeachOverlays(n);
1098 break;
1099
1100 case tFOREACH_OVERLAY_OBJECTS:
1101 n = ForeachOverlayObjects(n);
1102 break;
1103
1104 case tFOREACH_OVERLAY_LIBRARIES:
1105 n = ForeachOverlayLibraries(n);
1106 break;
1107
1108 case tFOREACH_OVERLAY_SEARCHSYMBOLS:
1109 n = ForeachOverlaySearchSymbols(n);
1110 break;
1111
1112 case tLTDAUTOLOAD_ID:
1113 PutLtdautoloadId();
1114 break;
1115
1116 case tLTDAUTOLOAD_NAME:
1117 PutLtdautoloadName();
1118 break;
1119
1120 case tLTDAUTOLOAD_ADDRESS:
1121 PutLtdautoloadAddress();
1122 break;
1123
1124 case tLTDAUTOLOAD_OBJECT:
1125 PutLtdautoloadObject(tokenBuffer[n].string);
1126 break;
1127
1128 case tLTDAUTOLOAD_LIBRARY:
1129 PutLtdautoloadLibrary(tokenBuffer[n].string);
1130 break;
1131
1132 case tLTDAUTOLOAD_SEARCHSYMBOL:
1133 PutLtdautoloadSearchSymbol(tokenBuffer[n].string);
1134 break;
1135
1136 case tNUMBER_LTDAUTOLOADS:
1137 PutNumber(LtdautoloadList.num);
1138 break;
1139
1140 case tFOREACH_LTDAUTOLOADS:
1141 n = ForeachLtdautoloads(n);
1142 break;
1143
1144 case tFOREACH_LTDAUTOLOAD_OBJECTS:
1145 n = ForeachLtdautoloadObjects(n);
1146 break;
1147
1148 case tFOREACH_LTDAUTOLOAD_LIBRARIES:
1149 n = ForeachLtdautoloadLibraries(n);
1150 break;
1151
1152 case tFOREACH_LTDAUTOLOAD_SEARCHSYMBOLS:
1153 n = ForeachLtdautoloadSearchSymbols(n);
1154 break;
1155
1156 case tLTDOVERLAY_ID:
1157 PutLtdoverlayId();
1158 break;
1159
1160 case tLTDOVERLAY_NAME:
1161 PutLtdoverlayName();
1162 break;
1163
1164 case tLTDOVERLAY_GROUP:
1165 PutLtdoverlayGroup();
1166 break;
1167
1168 case tLTDOVERLAY_ADDRESS:
1169 PutLtdoverlayAddress();
1170 break;
1171
1172 case tLTDOVERLAY_OBJECT:
1173 PutLtdoverlayObject(tokenBuffer[n].string);
1174 break;
1175
1176 case tLTDOVERLAY_LIBRARY:
1177 PutLtdoverlayLibrary(tokenBuffer[n].string);
1178 break;
1179
1180 case tLTDOVERLAY_SEARCHSYMBOL:
1181 PutLtdoverlaySearchSymbol(tokenBuffer[n].string);
1182 break;
1183
1184 case tNUMBER_LTDOVERLAYS:
1185 PutNumber(LtdoverlayList.num);
1186 break;
1187
1188 case tFOREACH_LTDOVERLAYS:
1189 n = ForeachLtdoverlays(n);
1190 break;
1191
1192 case tFOREACH_LTDOVERLAY_OBJECTS:
1193 n = ForeachLtdoverlayObjects(n);
1194 break;
1195
1196 case tFOREACH_LTDOVERLAY_LIBRARIES:
1197 n = ForeachLtdoverlayLibraries(n);
1198 break;
1199
1200 case tFOREACH_LTDOVERLAY_SEARCHSYMBOLS:
1201 n = ForeachLtdoverlaySearchSymbols(n);
1202 break;
1203
1204 case tPROPERTY_OVERLAYDEFS:
1205 PutString(Property.overlaydefs);
1206 break;
1207
1208 case tPROPERTY_OVERLAYTABLE:
1209 PutString(Property.overlaytable);
1210 break;
1211
1212 case tPROPERTY_LTDOVERLAYDEFS:
1213 PutString(Property.ltdoverlaydefs);
1214 break;
1215
1216 case tPROPERTY_LTDOVERLAYTABLE:
1217 PutString(Property.ltdoverlaytable);
1218 break;
1219
1220 case tPROPERTY_SUFFIX:
1221 PutString(Property.suffix);
1222 break;
1223
1224 case tPROPERTY_FLXSUFFIX:
1225 PutString(Property.flxsuffix);
1226 break;
1227
1228 case tPROPERTY_LTDSUFFIX:
1229 PutString(Property.ltdsuffix);
1230 break;
1231
1232 default:
1233 lcf_error("Unknown token\n");
1234 }
1235 return n;
1236 }
1237
PutTokenBuffer(int start,int end)1238 static void PutTokenBuffer(int start, int end)
1239 {
1240 int i;
1241
1242 for (i = start; i <= end; i++)
1243 {
1244 i = PutToken(i);
1245 }
1246 }
1247
PutTokenBufferAll(void)1248 static void PutTokenBufferAll(void)
1249 {
1250 PutTokenBuffer(0, tokenBufferEnd - 1);
1251 }
1252
1253
1254 /*============================================================================
1255 * Create LCF file
1256 */
CreateLcfFile(const char * filename)1257 int CreateLcfFile(const char *filename)
1258 {
1259 if (filename)
1260 {
1261 if (NULL == (fp_out = fopen(filename, "wb")))
1262 {
1263 fprintf(stderr, "makelcf: Cannot write %s\n", filename);
1264 return 2;
1265 }
1266 PutTokenBufferAll();
1267 fclose(fp_out);
1268 }
1269 else
1270 {
1271 setmode(1, O_BINARY);
1272 fp_out = stdout;
1273 PutTokenBufferAll();
1274 }
1275
1276 return 0;
1277 }
1278