1 /*****************************************************************************/
5 /* Symbol table for the ca65 macroassembler */
9 /* (C) 1998-2000 Ullrich von Bassewitz */
11 /* D-70597 Stuttgart */
12 /* EMail: uz@musoftware.de */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
54 /*****************************************************************************/
56 /*****************************************************************************/
60 /* Bits for the Flags value in SymEntry */
61 #define SF_USER 0x0001 /* User bit */
62 #define SF_TRAMPOLINE 0x0002 /* Trampoline entry */
63 #define SF_EXPORT 0x0004 /* Export this symbol */
64 #define SF_IMPORT 0x0008 /* Import this symbol */
65 #define SF_GLOBAL 0x0010 /* Global symbol */
66 #define SF_INITIALIZER 0x0020 /* Exported initializer */
67 #define SF_ZP 0x0040 /* Declared as zeropage symbol */
68 #define SF_ABS 0x0080 /* Declared as absolute symbol */
69 #define SF_INDEXED 0x0800 /* Index is valid */
70 #define SF_CONST 0x1000 /* The symbol has a constant value */
71 #define SF_MULTDEF 0x2000 /* Multiply defined symbol */
72 #define SF_DEFINED 0x4000 /* Defined */
73 #define SF_REFERENCED 0x8000 /* Referenced */
76 #define SF_UNDEFMASK (SF_REFERENCED | SF_DEFINED | SF_IMPORT)
77 #define SF_UNDEFVAL (SF_REFERENCED)
78 #define SF_IMPMASK (SF_TRAMPOLINE | SF_IMPORT | SF_REFERENCED)
79 #define SF_IMPVAL (SF_IMPORT | SF_REFERENCED)
80 #define SF_EXPMASK (SF_TRAMPOLINE | SF_EXPORT)
81 #define SF_EXPVAL (SF_EXPORT)
82 #define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
83 #define SF_DBGINFOVAL (SF_DEFINED)
85 /* Structure of a symbol table entry */
87 SymEntry* Left; /* Lexically smaller entry */
88 SymEntry* Right; /* Lexically larger entry */
89 SymEntry* List; /* List of all entries */
90 SymEntry* Locals; /* Root of subtree for local symbols */
91 struct SymTable_* SymTab; /* Table this symbol is in, 0 for locals */
92 FilePos Pos; /* File position for this symbol */
93 unsigned Flags; /* Symbol flags */
94 unsigned Index; /* Index of import/export entries */
96 struct ExprNode_* Expr; /* Expression if CONST not set */
97 long Val; /* Value (if CONST set) */
98 SymEntry* Sym; /* Symbol (if trampoline entry) */
100 unsigned char InitVal; /* Initializer value */
101 char Name [1]; /* Dynamic allocation */
106 /* Definitions for the hash table */
107 #define MAIN_HASHTAB_SIZE 213
108 #define SUB_HASHTAB_SIZE 53
109 typedef struct SymTable_ SymTable;
111 unsigned TableSlots; /* Number of hash table slots */
112 unsigned TableEntries; /* Number of entries in the table */
113 SymTable* BackLink; /* Link to enclosing scope if any */
114 SymEntry* Table [1]; /* Dynamic allocation */
119 /* Arguments for SymFind */
120 #define SF_FIND_EXISTING 0
121 #define SF_ALLOC_NEW 1
125 /* Symbol table variables */
126 static SymEntry* SymList = 0; /* List of all symbol table entries */
127 static SymEntry* SymLast = 0; /* Pointer to last defined symbol */
128 static SymTable* SymTab = 0; /* Pointer to current symbol table */
129 static SymTable* RootTab = 0; /* Root symbol table */
130 static unsigned ImportCount = 0;/* Counter for import symbols */
131 static unsigned ExportCount = 0;/* Counter for export symbols */
135 /*****************************************************************************/
136 /* Internally used functions */
137 /*****************************************************************************/
141 static int IsLocal (const char* Name)
142 /* Return true if Name is the name of a local symbol */
144 return (*Name == LocalStart);
149 static SymEntry* NewSymEntry (const char* Name)
150 /* Allocate a symbol table entry, initialize and return it */
155 /* Get the length of the name */
158 /* Allocate memory */
159 S = xmalloc (sizeof (SymEntry) + Len);
161 /* Initialize the entry */
170 memcpy (S->Name, Name, Len+1);
172 /* Insert it into the list of all entries */
176 /* Return the initialized entry */
182 static SymTable* NewSymTable (unsigned Size)
183 /* Allocate a symbol table on the heap and return it */
187 /* Allocate memory */
188 S = xmalloc (sizeof (SymTable) + (Size-1) * sizeof (SymEntry*));
190 /* Set variables and clear hash table entries */
191 S->TableSlots = Size;
198 /* Return the prepared struct */
204 static int SearchSymTab (SymEntry* T, const char* Name, SymEntry** E)
205 /* Search in the given table for a name (Hash is the hash value of Name and
206 * is given as parameter so that it will not get calculated twice if we search
207 * in more than one table). If we find the symbol, the function will return 0
208 * and put the entry pointer into E. If we did not find the symbol, and the
209 * tree is empty, E is set to NULL. If the tree is not empty, E will be set to
210 * the last entry, and the result of the function is <0 if the entry should
211 * be inserted on the left side, and >0 if it should get inserted on the right
217 /* Is there a tree? */
223 /* We have a table, search it */
225 /* Choose next entry */
226 Cmp = strcmp (Name, T->Name);
227 if (Cmp < 0 && T->Left) {
229 } else if (Cmp > 0 && T->Right) {
232 /* Found or end of search */
237 /* Return the search result */
244 /*****************************************************************************/
246 /*****************************************************************************/
250 static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew)
251 /* Find a new symbol table entry in the given table. If AllocNew is given and
252 * the entry is not found, create a new one. Return the entry found, or the
253 * new entry created, or - in case AllocNew is zero - return 0.
260 if (IsLocal (Name)) {
262 /* Local symbol, get the table */
264 /* No last global, so there's no local table */
265 Error (ERR_ILLEGAL_LOCAL_USE);
267 return NewSymEntry (Name);
273 /* Search for the symbol if we have a table */
274 Cmp = SearchSymTab (SymLast->Locals, Name, &S);
276 /* If we found an entry, return it */
283 /* Otherwise create a new entry, insert and return it */
284 SymEntry* N = NewSymEntry (Name);
287 } else if (Cmp < 0) {
297 /* Global symbol: Get the hash value for the name */
298 Hash = HashStr (Name) % Tab->TableSlots;
300 /* Search for the entry */
301 Cmp = SearchSymTab (Tab->Table [Hash], Name, &S);
303 /* If we found an entry, return it */
305 /* Check for a trampoline entry, in this case return the real
308 if (S->Flags & SF_TRAMPOLINE) {
317 /* Otherwise create a new entry, insert and return it */
318 SymEntry* N = NewSymEntry (Name);
320 Tab->Table [Hash] = N;
321 } else if (Cmp < 0) {
333 /* We did not find the entry and AllocNew is false. */
339 static SymEntry* SymFindAny (SymTable* Tab, const char* Name)
340 /* Find a symbol in any table */
344 /* Search in the current table */
345 Sym = SymFind (Tab, Name, 0);
347 /* Found, return it */
350 /* Not found, search in the backlink, if we have one */
353 } while (Sym == 0 && Tab != 0);
361 static SymEntry* SymRefInternal (SymTable* Table, const char* Name)
362 /* Search for the symbol in the given table and return it */
364 /* Try to find the symbol, create a new one if the symbol does not exist */
365 SymEntry* S = SymFind (Table, Name, SF_ALLOC_NEW);
367 /* Mark the symbol as referenced */
368 S->Flags |= SF_REFERENCED;
376 void SymEnterLevel (void)
377 /* Enter a new lexical level */
380 /* Create the main symbol table */
381 RootTab = SymTab = NewSymTable (MAIN_HASHTAB_SIZE);
383 /* Create a local symbol table */
385 LocalSyms = NewSymTable (SUB_HASHTAB_SIZE);
386 LocalSyms->BackLink = SymTab;
393 void SymLeaveLevel (void)
394 /* Leave the current lexical level */
396 SymTab = SymTab->BackLink;
401 void SymDef (const char* Name, ExprNode* Expr, int ZP)
402 /* Define a new symbol */
404 /* Do we have such a symbol? */
405 SymEntry* S = SymFind (SymTab, Name, SF_ALLOC_NEW);
406 if (S->Flags & SF_IMPORT) {
407 /* Defined symbol is marked as imported external symbol */
408 Error (ERR_SYM_ALREADY_IMPORT, Name);
411 if (S->Flags & SF_DEFINED) {
412 /* Multiple definition */
413 Error (ERR_SYM_ALREADY_DEFINED, Name);
414 S->Flags |= SF_MULTDEF;
418 /* Set the symbol data */
419 if (IsConstExpr (Expr)) {
420 /* Expression is const, store the value */
421 S->Flags |= SF_CONST;
422 S->V.Val = GetExprVal (Expr);
425 /* Not const, store the expression */
428 S->Flags |= SF_DEFINED;
433 /* If the symbol is a ZP symbol, check if the value is in correct range */
434 if (S->Flags & SF_ZP) {
435 /* Already marked as ZP symbol by some means */
436 if (!IsByteExpr (Expr)) {
441 /* If this is not a local symbol, remember it as the last global one */
442 if (!IsLocal (Name)) {
449 SymEntry* SymRef (const char* Name)
450 /* Search for the symbol and return it */
452 /* Reference the symbol in the current table */
453 return SymRefInternal (SymTab, Name);
458 SymEntry* SymRefGlobal (const char* Name)
459 /* Search for the symbol in the global namespace and return it */
461 /* Reference the symbol in the current table */
462 return SymRefInternal (RootTab, Name);
467 void SymImport (const char* Name, int ZP)
468 /* Mark the given symbol as an imported symbol */
472 /* Don't accept local symbols */
473 if (IsLocal (Name)) {
474 Error (ERR_ILLEGAL_LOCAL_USE);
478 /* Do we have such a symbol? */
479 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
480 if (S->Flags & SF_DEFINED) {
481 Error (ERR_SYM_ALREADY_DEFINED, Name);
482 S->Flags |= SF_MULTDEF;
485 if (S->Flags & SF_EXPORT) {
486 /* The symbol is already marked as exported symbol */
487 Error (ERR_SYM_ALREADY_EXPORT, Name);
491 /* If the symbol is marked as global, check the symbol size, then do
492 * silently remove the global flag
494 if (S->Flags & SF_GLOBAL) {
495 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
496 Error (ERR_SYM_REDECL_MISMATCH);
498 S->Flags &= ~SF_GLOBAL;
501 /* Set the symbol data */
502 S->Flags |= SF_IMPORT;
510 void SymExport (const char* Name, int ZP)
511 /* Mark the given symbol as an exported symbol */
515 /* Don't accept local symbols */
516 if (IsLocal (Name)) {
517 Error (ERR_ILLEGAL_LOCAL_USE);
521 /* Do we have such a symbol? */
522 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
523 if (S->Flags & SF_IMPORT) {
524 /* The symbol is already marked as imported external symbol */
525 Error (ERR_SYM_ALREADY_IMPORT, Name);
529 /* If the symbol is marked as global, check the symbol size, then do
530 * silently remove the global flag
532 if (S->Flags & SF_GLOBAL) {
533 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
534 Error (ERR_SYM_REDECL_MISMATCH);
536 S->Flags &= ~SF_GLOBAL;
539 /* Set the symbol data */
540 S->Flags |= SF_EXPORT | SF_REFERENCED;
548 void SymGlobal (const char* Name, int ZP)
549 /* Mark the given symbol as a global symbol, that is, as a symbol that is
550 * either imported or exported.
555 /* Don't accept local symbols */
556 if (IsLocal (Name)) {
557 Error (ERR_ILLEGAL_LOCAL_USE);
561 /* Search for this symbol, create a new entry if needed */
562 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
564 /* If the symbol is already marked as import or export, check the
565 * size of the definition, then bail out. */
566 if (S->Flags & SF_IMPORT || S->Flags & SF_EXPORT) {
567 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
568 Error (ERR_SYM_REDECL_MISMATCH);
573 /* Mark the symbol */
574 S->Flags |= SF_GLOBAL;
582 void SymInitializer (const char* Name, unsigned InitVal)
583 /* Mark the given symbol as an initializer. This will also mark the symbol as
584 * an export. Initializers may never be zero page symbols.
589 /* Check the InitVal parameter */
590 CHECK (InitVal >= EXP_INIT_MIN && InitVal <= EXP_INIT_MAX);
592 /* Don't accept local symbols */
593 if (IsLocal (Name)) {
594 Error (ERR_ILLEGAL_LOCAL_USE);
598 /* Do we have such a symbol? */
599 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
600 if (S->Flags & SF_IMPORT) {
601 /* The symbol is already marked as imported external symbol */
602 Error (ERR_SYM_ALREADY_IMPORT, Name);
606 /* If the symbol is marked as global, silently remove the global flag */
607 if (S->Flags & SF_GLOBAL) {
608 S->Flags &= ~SF_GLOBAL;
611 /* Check if the symbol was not already defined as ZP symbol */
612 if ((S->Flags & SF_ZP) != 0) {
613 Error (ERR_SYM_REDECL_MISMATCH);
616 /* If the symbol was already declared as an initializer, check if the new
617 * initializer value is the same as the old one.
619 if (S->Flags & SF_INITIALIZER) {
620 if (S->InitVal != InitVal) {
621 Error (ERR_SYM_REDECL_MISMATCH);
624 S->InitVal = InitVal;
626 /* Set the symbol data */
627 S->Flags |= SF_EXPORT | SF_INITIALIZER | SF_REFERENCED;
632 int SymIsDef (const char* Name)
633 /* Return true if the given symbol is already defined */
635 SymEntry* S = SymFindAny (SymTab, Name);
636 return S != 0 && (S->Flags & (SF_DEFINED | SF_IMPORT)) != 0;
641 int SymIsRef (const char* Name)
642 /* Return true if the given symbol has been referenced */
644 SymEntry* S = SymFindAny (SymTab, Name);
645 return S != 0 && (S->Flags & SF_REFERENCED) != 0;
650 int SymIsConst (SymEntry* S)
651 /* Return true if the given symbol has a constant value */
653 /* Resolve trampoline entries */
654 if (S->Flags & SF_TRAMPOLINE) {
658 /* Check for constness */
659 if (S->Flags & SF_CONST) {
661 } else if ((S->Flags & SF_DEFINED) && IsConstExpr (S->V.Expr)) {
662 /* Constant expression, remember the value */
663 ExprNode* Expr = S->V.Expr;
664 S->Flags |= SF_CONST;
665 S->V.Val = GetExprVal (Expr);
674 int SymIsZP (SymEntry* S)
675 /* Return true if the symbol is explicitly marked as zeropage symbol */
677 /* Resolve trampoline entries */
678 if (S->Flags & SF_TRAMPOLINE) {
682 /* If the symbol is not a global symbol, was not defined before, check the
683 * enclosing scope for a symbol with the same name, and return the ZP
684 * attribute of this symbol if we find one.
686 if (!IsLocal (S->Name) &&
687 (S->Flags & (SF_ZP | SF_ABS | SF_DEFINED | SF_IMPORT)) == 0 &&
688 S->SymTab->BackLink != 0) {
690 /* Try to find a symbol with the same name in the enclosing scope */
691 SymEntry* E = SymFindAny (S->SymTab->BackLink, S->Name);
693 /* If we found one, use the ZP flag */
694 if (E && (E->Flags & SF_ZP) != 0) {
699 /* Check the ZP flag */
700 return (S->Flags & SF_ZP) != 0;
705 int SymIsImport (SymEntry* S)
706 /* Return true if the given symbol is marked as import */
708 /* Resolve trampoline entries */
709 if (S->Flags & SF_TRAMPOLINE) {
713 /* Check the import flag */
714 return (S->Flags & SF_IMPORT) != 0;
719 int SymHasExpr (SymEntry* S)
720 /* Return true if the given symbol has an associated expression */
722 /* Resolve trampoline entries */
723 if (S->Flags & SF_TRAMPOLINE) {
727 /* Check the expression */
728 return ((S->Flags & SF_DEFINED) != 0 &&
729 (S->Flags & SF_IMPORT) == 0 &&
730 (S->Flags & SF_CONST) == 0);
735 void SymFinalize (SymEntry* S)
736 /* Finalize a symbol expression if there is one */
738 /* Resolve trampoline entries */
739 if (S->Flags & SF_TRAMPOLINE) {
743 /* Check if we have an expression */
744 if (SymHasExpr (S)) {
745 S->V.Expr = FinalizeExpr (S->V.Expr);
751 void SymMarkUser (SymEntry* S)
752 /* Set a user mark on the specified symbol */
754 /* Resolve trampoline entries */
755 if (S->Flags & SF_TRAMPOLINE) {
765 void SymUnmarkUser (SymEntry* S)
766 /* Remove a user mark from the specified symbol */
768 /* Resolve trampoline entries */
769 if (S->Flags & SF_TRAMPOLINE) {
774 S->Flags &= ~SF_USER;
779 int SymHasUserMark (SymEntry* S)
780 /* Return the state of the user mark for the specified symbol */
782 /* Resolve trampoline entries */
783 if (S->Flags & SF_TRAMPOLINE) {
788 return (S->Flags & SF_USER) != 0;
793 long GetSymVal (SymEntry* S)
794 /* Return the symbol value */
796 /* Resolve trampoline entries */
797 if (S->Flags & SF_TRAMPOLINE) {
801 PRECONDITION ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_CONST) != 0);
807 ExprNode* GetSymExpr (SymEntry* S)
808 /* Get the expression for a non-const symbol */
810 /* Resolve trampoline entries */
811 if (S->Flags & SF_TRAMPOLINE) {
815 PRECONDITION (S != 0 && (S->Flags & SF_CONST) == 0);
821 const char* GetSymName (SymEntry* S)
822 /* Return the name of the symbol */
824 /* Resolve trampoline entries */
825 if (S->Flags & SF_TRAMPOLINE) {
833 unsigned GetSymIndex (SymEntry* S)
834 /* Return the symbol index for the given symbol */
836 /* Resolve trampoline entries */
837 if (S->Flags & SF_TRAMPOLINE) {
840 PRECONDITION (S != 0 && (S->Flags & SF_INDEXED));
846 const FilePos* GetSymPos (SymEntry* S)
847 /* Return the position of first occurence in the source for the given symbol */
849 /* Resolve trampoline entries */
850 if (S->Flags & SF_TRAMPOLINE) {
853 PRECONDITION (S != 0);
859 static void SymCheckUndefined (SymEntry* S)
860 /* Handle an undefined symbol */
862 /* Undefined symbol. It may be...
864 * - An undefined symbol in a nested lexical level. In this
865 * case, search for the symbol in the higher levels and
866 * make the entry a trampoline entry if we find one.
868 * - If the symbol is not found, it is a real undefined symbol.
869 * If the AutoImport flag is set, make it an import. If the
870 * AutoImport flag is not set, it's an error.
874 /* It's a global symbol, get the higher level table */
875 SymTable* Tab = S->SymTab->BackLink;
877 Sym = SymFindAny (Tab, S->Name);
879 if (Sym->Flags & (SF_DEFINED | SF_IMPORT)) {
880 /* We've found a symbol in a higher level that is
881 * either defined in the source, or an import.
885 /* The symbol found is undefined itself. Look further */
886 Tab = Sym->SymTab->BackLink;
889 /* No symbol found */
895 /* We found the symbol in a higher level. Make S a trampoline
896 * symbol. Beware: We have to transfer the symbol attributes to
897 * the real symbol and check for any conflicts.
899 S->Flags |= SF_TRAMPOLINE;
902 /* Transfer the flags. Note: S may not be imported, since in that
903 * case it wouldn't be undefined.
905 if (S->Flags & SF_EXPORT) {
906 if (Sym->Flags & SF_IMPORT) {
907 /* The symbol is already marked as imported external symbol */
908 PError (&S->Pos, ERR_SYM_ALREADY_IMPORT, S->Name);
910 Sym->Flags |= S->Flags & (SF_EXPORT | SF_ZP);
913 /* Transfer the referenced flag */
914 Sym->Flags |= (S->Flags & SF_REFERENCED);
917 /* The symbol is definitely undefined */
918 if (S->Flags & SF_EXPORT) {
919 /* We will not auto-import an export */
920 PError (&S->Pos, ERR_EXPORT_UNDEFINED, S->Name);
923 /* Mark as import, will be indexed later */
924 S->Flags |= SF_IMPORT;
927 PError (&S->Pos, ERR_SYM_UNDEFINED, S->Name);
936 /* Run through all symbols and check for anomalies and errors */
940 /* Check for open lexical levels */
941 if (SymTab->BackLink != 0) {
942 Error (ERR_OPEN_PROC);
945 /* First pass: Walk through all symbols, checking for undefined's and
946 * changing them to trampoline symbols or make them imports.
950 /* If the symbol is marked as global, mark it as export, if it is
951 * already defined, otherwise mark it as import.
953 if (S->Flags & SF_GLOBAL) {
954 S->Flags &= ~SF_GLOBAL;
955 if (S->Flags & SF_DEFINED) {
956 S->Flags |= SF_EXPORT;
958 S->Flags |= SF_IMPORT;
962 /* Handle undefined symbols */
963 if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
964 /* This is an undefined symbol. Handle it. */
965 SymCheckUndefined (S);
972 /* Second pass: Walk again through the symbols. Ignore undefined's, since
973 * we handled them in the last pass, and ignore trampoline symbols, since
974 * we handled them in the last pass, too.
978 if ((S->Flags & SF_TRAMPOLINE) == 0 &&
979 (S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
980 if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
981 /* Symbol was defined but never referenced */
982 PWarning (&S->Pos, WARN_SYM_NOT_REFERENCED, S->Name);
984 if (S->Flags & SF_IMPORT) {
985 if ((S->Flags & SF_REFERENCED) == 0) {
986 /* Imported symbol is not referenced */
987 PWarning (&S->Pos, WARN_IMPORT_NOT_REFERENCED, S->Name);
989 /* Give the import an index, count imports */
990 S->Index = ImportCount++;
991 S->Flags |= SF_INDEXED;
994 if (S->Flags & SF_EXPORT) {
995 /* Give the export an index, count exports */
996 S->Index = ExportCount++;
997 S->Flags |= SF_INDEXED;
1008 void SymDump (FILE* F)
1009 /* Dump the symbol table */
1011 SymEntry* S = SymList;
1014 /* Ignore trampoline symbols */
1015 if ((S->Flags & SF_TRAMPOLINE) != 0) {
1016 printf ("%-24s %s %s %s %s %s\n",
1018 (S->Flags & SF_DEFINED)? "DEF" : "---",
1019 (S->Flags & SF_REFERENCED)? "REF" : "---",
1020 (S->Flags & SF_IMPORT)? "IMP" : "---",
1021 (S->Flags & SF_EXPORT)? "EXP" : "---",
1022 (S->Flags & SF_ZP)? "ZP" : "--");
1031 void WriteImports (void)
1032 /* Write the imports list to the object file */
1036 /* Tell the object file module that we're about to start the imports */
1039 /* Write the import count to the list */
1040 ObjWriteVar (ImportCount);
1042 /* Walk throught list and write all imports to the file */
1045 if ((S->Flags & SF_IMPMASK) == SF_IMPVAL) {
1046 if (S->Flags & SF_ZP) {
1049 ObjWrite8 (IMP_ABS);
1051 ObjWriteStr (S->Name);
1052 ObjWritePos (&S->Pos);
1057 /* Done writing imports */
1063 void WriteExports (void)
1064 /* Write the exports list to the object file */
1068 /* Tell the object file module that we're about to start the exports */
1071 /* Write the export count to the list */
1072 ObjWriteVar (ExportCount);
1074 /* Walk throught list and write all exports to the file */
1077 if ((S->Flags & SF_EXPMASK) == SF_EXPVAL) {
1078 unsigned char ExprMask;
1080 /* Finalize an associated expression if we have one */
1083 /* Check if the symbol is const */
1084 ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
1086 /* Add zeropage/abs bits */
1087 ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
1089 /* Add the initializer bits */
1090 if (S->Flags & SF_INITIALIZER) {
1091 ExprMask |= S->InitVal;
1094 /* Write the type */
1095 ObjWrite8 (ExprMask);
1097 /* Write the name */
1098 ObjWriteStr (S->Name);
1100 /* Write the value */
1101 if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
1102 /* Constant value */
1103 ObjWrite32 (S->V.Val);
1105 /* Expression involved */
1106 WriteExpr (S->V.Expr);
1109 /* Write the source file position */
1110 ObjWritePos (&S->Pos);
1115 /* Done writing exports */
1121 void WriteDbgSyms (void)
1122 /* Write a list of all symbols to the object file */
1127 /* Tell the object file module that we're about to start the debug info */
1130 /* Check if debug info is requested */
1133 /* Walk through the list and count the symbols */
1137 if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
1143 /* Write the symbol count to the list */
1144 ObjWriteVar (Count);
1146 /* Walk through list and write all symbols to the file */
1149 if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
1150 unsigned char ExprMask;
1152 /* Finalize an associated expression if we have one */
1155 /* Check if the symbol is const */
1156 ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
1158 /* Add zeropage/abs bits */
1159 ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
1161 /* Add the initializer bits */
1162 if (S->Flags & SF_INITIALIZER) {
1163 ExprMask |= S->InitVal;
1166 /* Write the type */
1167 ObjWrite8 (ExprMask);
1169 /* Write the name */
1170 ObjWriteStr (S->Name);
1172 /* Write the value */
1173 if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
1174 /* Constant value */
1175 ObjWrite32 (S->V.Val);
1177 /* Expression involved */
1178 WriteExpr (S->V.Expr);
1181 /* Write the source file position */
1182 ObjWritePos (&S->Pos);
1189 /* No debug symbols */
1194 /* Done writing debug symbols */