1 /*****************************************************************************/
5 /* Symbol table for the ca65 macroassembler */
9 /* (C) 1998-2002 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 /*****************************************************************************/
55 /*****************************************************************************/
57 /*****************************************************************************/
61 /* Bits for the Flags value in SymEntry */
62 #define SF_USER 0x0001 /* User bit */
63 #define SF_TRAMPOLINE 0x0002 /* Trampoline entry */
64 #define SF_EXPORT 0x0004 /* Export this symbol */
65 #define SF_IMPORT 0x0008 /* Import this symbol */
66 #define SF_GLOBAL 0x0010 /* Global symbol */
67 #define SF_ZP 0x0020 /* Declared as zeropage symbol */
68 #define SF_ABS 0x0040 /* Declared as absolute symbol */
69 #define SF_LABEL 0x0080 /* Used as a label */
70 #define SF_INDEXED 0x0800 /* Index is valid */
71 #define SF_CONST 0x1000 /* The symbol has a constant value */
72 #define SF_MULTDEF 0x2000 /* Multiply defined symbol */
73 #define SF_DEFINED 0x4000 /* Defined */
74 #define SF_REFERENCED 0x8000 /* Referenced */
77 #define SF_UNDEFMASK (SF_REFERENCED | SF_DEFINED | SF_IMPORT)
78 #define SF_UNDEFVAL (SF_REFERENCED)
79 #define SF_IMPMASK (SF_TRAMPOLINE | SF_IMPORT | SF_REFERENCED)
80 #define SF_IMPVAL (SF_IMPORT | SF_REFERENCED)
81 #define SF_EXPMASK (SF_TRAMPOLINE | SF_EXPORT)
82 #define SF_EXPVAL (SF_EXPORT)
83 #define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
84 #define SF_DBGINFOVAL (SF_DEFINED)
86 /* Structure of a symbol table entry */
88 SymEntry* Left; /* Lexically smaller entry */
89 SymEntry* Right; /* Lexically larger entry */
90 SymEntry* List; /* List of all entries */
91 SymEntry* Locals; /* Root of subtree for local symbols */
92 struct SymTable* SymTab; /* Table this symbol is in, 0 for locals */
93 FilePos Pos; /* File position for this symbol */
94 unsigned Flags; /* Symbol flags */
95 unsigned Index; /* Index of import/export entries */
97 struct ExprNode* Expr; /* Expression if CONST not set */
98 long Val; /* Value (if CONST set) */
99 SymEntry* Sym; /* Symbol (if trampoline entry) */
101 unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
102 /* ...actually value+1 (used as flag) */
103 char Name [1]; /* Dynamic allocation */
108 /* Definitions for the hash table */
109 #define MAIN_HASHTAB_SIZE 213
110 #define SUB_HASHTAB_SIZE 53
111 typedef struct SymTable SymTable;
113 unsigned TableSlots; /* Number of hash table slots */
114 unsigned TableEntries; /* Number of entries in the table */
115 SymTable* BackLink; /* Link to enclosing scope if any */
116 SymEntry* Table [1]; /* Dynamic allocation */
121 /* Arguments for SymFind */
122 #define SF_FIND_EXISTING 0
123 #define SF_ALLOC_NEW 1
127 /* Symbol table variables */
128 static SymEntry* SymList = 0; /* List of all symbol table entries */
129 static SymEntry* SymLast = 0; /* Pointer to last defined symbol */
130 static SymTable* SymTab = 0; /* Pointer to current symbol table */
131 static SymTable* RootTab = 0; /* Root symbol table */
132 static unsigned ImportCount = 0;/* Counter for import symbols */
133 static unsigned ExportCount = 0;/* Counter for export symbols */
137 /*****************************************************************************/
138 /* Internally used functions */
139 /*****************************************************************************/
143 static int IsLocal (const char* Name)
144 /* Return true if Name is the name of a local symbol */
146 return (*Name == LocalStart);
151 static SymEntry* NewSymEntry (const char* Name)
152 /* Allocate a symbol table entry, initialize and return it */
157 /* Get the length of the name */
160 /* Allocate memory */
161 S = xmalloc (sizeof (SymEntry) + Len);
163 /* Initialize the entry */
171 memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
172 memcpy (S->Name, Name, Len+1);
174 /* Insert it into the list of all entries */
178 /* Return the initialized entry */
184 static SymTable* NewSymTable (unsigned Size)
185 /* Allocate a symbol table on the heap and return it */
189 /* Allocate memory */
190 S = xmalloc (sizeof (SymTable) + (Size-1) * sizeof (SymEntry*));
192 /* Set variables and clear hash table entries */
193 S->TableSlots = Size;
200 /* Return the prepared struct */
206 static int SearchSymTab (SymEntry* T, const char* Name, SymEntry** E)
207 /* Search in the given table for a name (Hash is the hash value of Name and
208 * is given as parameter so that it will not get calculated twice if we search
209 * in more than one table). If we find the symbol, the function will return 0
210 * and put the entry pointer into E. If we did not find the symbol, and the
211 * tree is empty, E is set to NULL. If the tree is not empty, E will be set to
212 * the last entry, and the result of the function is <0 if the entry should
213 * be inserted on the left side, and >0 if it should get inserted on the right
219 /* Is there a tree? */
225 /* We have a table, search it */
227 /* Choose next entry */
228 Cmp = strcmp (Name, T->Name);
229 if (Cmp < 0 && T->Left) {
231 } else if (Cmp > 0 && T->Right) {
234 /* Found or end of search */
239 /* Return the search result */
246 /*****************************************************************************/
248 /*****************************************************************************/
252 static SymEntry* SymFind (SymTable* Tab, const char* Name, int AllocNew)
253 /* Find a new symbol table entry in the given table. If AllocNew is given and
254 * the entry is not found, create a new one. Return the entry found, or the
255 * new entry created, or - in case AllocNew is zero - return 0.
262 if (IsLocal (Name)) {
264 /* Local symbol, get the table */
266 /* No last global, so there's no local table */
267 Error (ERR_ILLEGAL_LOCAL_USE);
269 return NewSymEntry (Name);
275 /* Search for the symbol if we have a table */
276 Cmp = SearchSymTab (SymLast->Locals, Name, &S);
278 /* If we found an entry, return it */
285 /* Otherwise create a new entry, insert and return it */
286 SymEntry* N = NewSymEntry (Name);
289 } else if (Cmp < 0) {
299 /* Global symbol: Get the hash value for the name */
300 Hash = HashStr (Name) % Tab->TableSlots;
302 /* Search for the entry */
303 Cmp = SearchSymTab (Tab->Table [Hash], Name, &S);
305 /* If we found an entry, return it */
307 /* Check for a trampoline entry, in this case return the real
310 if (S->Flags & SF_TRAMPOLINE) {
319 /* Otherwise create a new entry, insert and return it */
320 SymEntry* N = NewSymEntry (Name);
322 Tab->Table [Hash] = N;
323 } else if (Cmp < 0) {
335 /* We did not find the entry and AllocNew is false. */
341 static SymEntry* SymFindAny (SymTable* Tab, const char* Name)
342 /* Find a symbol in any table */
346 /* Search in the current table */
347 Sym = SymFind (Tab, Name, SF_FIND_EXISTING);
349 /* Found, return it */
352 /* Not found, search in the backlink, if we have one */
355 } while (Sym == 0 && Tab != 0);
363 void SymEnterLevel (void)
364 /* Enter a new lexical level */
367 /* Create the main symbol table */
368 RootTab = SymTab = NewSymTable (MAIN_HASHTAB_SIZE);
370 /* Create a local symbol table */
372 LocalSyms = NewSymTable (SUB_HASHTAB_SIZE);
373 LocalSyms->BackLink = SymTab;
380 void SymLeaveLevel (void)
381 /* Leave the current lexical level */
383 SymTab = SymTab->BackLink;
388 void SymDef (const char* Name, ExprNode* Expr, int ZP, int Label)
389 /* Define a new symbol */
391 /* Do we have such a symbol? */
392 SymEntry* S = SymFind (SymTab, Name, SF_ALLOC_NEW);
393 if (S->Flags & SF_IMPORT) {
394 /* Defined symbol is marked as imported external symbol */
395 Error (ERR_SYM_ALREADY_IMPORT, Name);
398 if (S->Flags & SF_DEFINED) {
399 /* Multiple definition */
400 Error (ERR_SYM_ALREADY_DEFINED, Name);
401 S->Flags |= SF_MULTDEF;
405 /* Set the symbol data */
406 if (IsConstExpr (Expr)) {
407 /* Expression is const, store the value */
408 S->Flags |= SF_CONST;
409 S->V.Val = GetExprVal (Expr);
412 /* Not const, store the expression */
415 S->Flags |= SF_DEFINED;
420 S->Flags |= SF_LABEL;
423 /* If the symbol is a ZP symbol, check if the value is in correct range */
424 if (S->Flags & SF_ZP) {
425 /* Already marked as ZP symbol by some means */
426 if (!IsByteExpr (Expr)) {
431 /* If this is not a local symbol, remember it as the last global one */
432 if (!IsLocal (Name)) {
439 SymEntry* SymRef (const char* Name, int Scope)
440 /* Search for the symbol and return it */
445 case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_ALLOC_NEW); break;
446 case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_ALLOC_NEW); break;
448 /* Others are not allowed */
451 Internal ("Invalid scope in SymRef: %d", Scope);
456 /* Mark the symbol as referenced */
457 S->Flags |= SF_REFERENCED;
465 void SymImport (const char* Name, int ZP)
466 /* Mark the given symbol as an imported symbol */
470 /* Don't accept local symbols */
471 if (IsLocal (Name)) {
472 Error (ERR_ILLEGAL_LOCAL_USE);
476 /* Do we have such a symbol? */
477 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
478 if (S->Flags & SF_DEFINED) {
479 Error (ERR_SYM_ALREADY_DEFINED, Name);
480 S->Flags |= SF_MULTDEF;
483 if (S->Flags & SF_EXPORT) {
484 /* The symbol is already marked as exported symbol */
485 Error (ERR_SYM_ALREADY_EXPORT, Name);
489 /* If the symbol is marked as global, check the symbol size, then do
490 * silently remove the global flag
492 if (S->Flags & SF_GLOBAL) {
493 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
494 Error (ERR_SYM_REDECL_MISMATCH, Name);
496 S->Flags &= ~SF_GLOBAL;
499 /* Set the symbol data */
500 S->Flags |= SF_IMPORT;
508 void SymExport (const char* Name, int ZP)
509 /* Mark the given symbol as an exported symbol */
513 /* Don't accept local symbols */
514 if (IsLocal (Name)) {
515 Error (ERR_ILLEGAL_LOCAL_USE);
519 /* Do we have such a symbol? */
520 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
521 if (S->Flags & SF_IMPORT) {
522 /* The symbol is already marked as imported external symbol */
523 Error (ERR_SYM_ALREADY_IMPORT, Name);
527 /* If the symbol is marked as global, check the symbol size, then do
528 * silently remove the global flag
530 if (S->Flags & SF_GLOBAL) {
531 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
532 Error (ERR_SYM_REDECL_MISMATCH, Name);
534 S->Flags &= ~SF_GLOBAL;
537 /* Set the symbol data */
538 S->Flags |= SF_EXPORT | SF_REFERENCED;
546 void SymGlobal (const char* Name, int ZP)
547 /* Mark the given symbol as a global symbol, that is, as a symbol that is
548 * either imported or exported.
553 /* Don't accept local symbols */
554 if (IsLocal (Name)) {
555 Error (ERR_ILLEGAL_LOCAL_USE);
559 /* Search for this symbol, create a new entry if needed */
560 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
562 /* If the symbol is already marked as import or export, check the
563 * size of the definition, then bail out. */
564 if (S->Flags & SF_IMPORT || S->Flags & SF_EXPORT) {
565 if ((ZP != 0) != ((S->Flags & SF_ZP) != 0)) {
566 Error (ERR_SYM_REDECL_MISMATCH, Name);
571 /* Mark the symbol */
572 S->Flags |= SF_GLOBAL;
580 void SymConDes (const char* Name, unsigned Type, unsigned Prio)
581 /* Mark the given symbol as a module constructor/destructor. This will also
582 * mark the symbol as an export. Initializers may never be zero page symbols.
587 /* Check the parameters */
588 #if (CD_TYPE_MIN != 0)
589 CHECK (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
591 CHECK (Type <= CD_TYPE_MAX);
593 CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX);
595 /* Don't accept local symbols */
596 if (IsLocal (Name)) {
597 Error (ERR_ILLEGAL_LOCAL_USE);
601 /* Do we have such a symbol? */
602 S = SymFind (SymTab, Name, SF_ALLOC_NEW);
603 if (S->Flags & SF_IMPORT) {
604 /* The symbol is already marked as imported external symbol */
605 Error (ERR_SYM_ALREADY_IMPORT, Name);
609 /* If the symbol is marked as global, silently remove the global flag */
610 if (S->Flags & SF_GLOBAL) {
611 S->Flags &= ~SF_GLOBAL;
614 /* Check if the symbol was not already defined as ZP symbol */
615 if ((S->Flags & SF_ZP) != 0) {
616 Error (ERR_SYM_REDECL_MISMATCH, Name);
619 /* If the symbol was already declared as a condes, check if the new
620 * priority value is the same as the old one.
622 if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
623 if (S->ConDesPrio[Type] != Prio) {
624 Error (ERR_SYM_REDECL_MISMATCH, Name);
627 S->ConDesPrio[Type] = Prio;
629 /* Set the symbol data */
630 S->Flags |= SF_EXPORT | SF_REFERENCED;
635 int SymIsDef (const char* Name, int Scope)
636 /* Return true if the given symbol is already defined */
640 /* Search for the symbol */
642 case SCOPE_ANY: S = SymFindAny (SymTab, Name); break;
643 case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_FIND_EXISTING); break;
644 case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_FIND_EXISTING); break;
645 default: Internal ("Invalid scope in SymIsDef: %d", Scope);
648 /* Check if it's defined */
649 return S != 0 && (S->Flags & SF_DEFINED) != 0;
654 int SymIsRef (const char* Name, int Scope)
655 /* Return true if the given symbol has been referenced */
659 /* Search for the symbol */
661 case SCOPE_ANY: S = SymFindAny (SymTab, Name); break;
662 case SCOPE_GLOBAL: S = SymFind (RootTab, Name, SF_FIND_EXISTING); break;
663 case SCOPE_LOCAL: S = SymFind (SymTab, Name, SF_FIND_EXISTING); break;
664 default: Internal ("Invalid scope in SymIsRef: %d", Scope);
667 /* Check if it's defined */
668 return S != 0 && (S->Flags & SF_REFERENCED) != 0;
673 int SymIsConst (SymEntry* S)
674 /* Return true if the given symbol has a constant value */
676 /* Resolve trampoline entries */
677 if (S->Flags & SF_TRAMPOLINE) {
681 /* Check for constness */
682 if (S->Flags & SF_CONST) {
684 } else if ((S->Flags & SF_DEFINED) && IsConstExpr (S->V.Expr)) {
685 /* Constant expression, remember the value */
686 ExprNode* Expr = S->V.Expr;
687 S->Flags |= SF_CONST;
688 S->V.Val = GetExprVal (Expr);
697 int SymIsZP (SymEntry* S)
698 /* Return true if the symbol is explicitly marked as zeropage symbol */
700 /* Resolve trampoline entries */
701 if (S->Flags & SF_TRAMPOLINE) {
705 /* If the symbol is not a global symbol, was not defined before, check the
706 * enclosing scope for a symbol with the same name, and return the ZP
707 * attribute of this symbol if we find one.
709 if (!IsLocal (S->Name) &&
710 (S->Flags & (SF_ZP | SF_ABS | SF_DEFINED | SF_IMPORT)) == 0 &&
711 S->SymTab->BackLink != 0) {
713 /* Try to find a symbol with the same name in the enclosing scope */
714 SymEntry* E = SymFindAny (S->SymTab->BackLink, S->Name);
716 /* If we found one, use the ZP flag */
717 if (E && (E->Flags & SF_ZP) != 0) {
722 /* Check the ZP flag */
723 return (S->Flags & SF_ZP) != 0;
728 int SymIsImport (SymEntry* S)
729 /* Return true if the given symbol is marked as import */
731 /* Resolve trampoline entries */
732 if (S->Flags & SF_TRAMPOLINE) {
736 /* Check the import flag */
737 return (S->Flags & SF_IMPORT) != 0;
742 int SymHasExpr (SymEntry* S)
743 /* Return true if the given symbol has an associated expression */
745 /* Resolve trampoline entries */
746 if (S->Flags & SF_TRAMPOLINE) {
750 /* Check the expression */
751 return ((S->Flags & SF_DEFINED) != 0 &&
752 (S->Flags & SF_IMPORT) == 0 &&
753 (S->Flags & SF_CONST) == 0);
758 void SymFinalize (SymEntry* S)
759 /* Finalize a symbol expression if there is one */
761 /* Resolve trampoline entries */
762 if (S->Flags & SF_TRAMPOLINE) {
766 /* Check if we have an expression */
767 if (SymHasExpr (S)) {
768 S->V.Expr = FinalizeExpr (S->V.Expr);
774 void SymMarkUser (SymEntry* S)
775 /* Set a user mark on the specified symbol */
777 /* Resolve trampoline entries */
778 if (S->Flags & SF_TRAMPOLINE) {
788 void SymUnmarkUser (SymEntry* S)
789 /* Remove a user mark from the specified symbol */
791 /* Resolve trampoline entries */
792 if (S->Flags & SF_TRAMPOLINE) {
797 S->Flags &= ~SF_USER;
802 int SymHasUserMark (SymEntry* S)
803 /* Return the state of the user mark for the specified symbol */
805 /* Resolve trampoline entries */
806 if (S->Flags & SF_TRAMPOLINE) {
811 return (S->Flags & SF_USER) != 0;
816 long GetSymVal (SymEntry* S)
817 /* Return the symbol value */
819 /* Resolve trampoline entries */
820 if (S->Flags & SF_TRAMPOLINE) {
824 PRECONDITION ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_CONST) != 0);
830 ExprNode* GetSymExpr (SymEntry* S)
831 /* Get the expression for a non-const symbol */
833 /* Resolve trampoline entries */
834 if (S->Flags & SF_TRAMPOLINE) {
838 PRECONDITION (S != 0 && (S->Flags & SF_CONST) == 0);
844 const char* GetSymName (SymEntry* S)
845 /* Return the name of the symbol */
847 /* Resolve trampoline entries */
848 if (S->Flags & SF_TRAMPOLINE) {
856 unsigned GetSymIndex (SymEntry* S)
857 /* Return the symbol index for the given symbol */
859 /* Resolve trampoline entries */
860 if (S->Flags & SF_TRAMPOLINE) {
863 PRECONDITION (S != 0 && (S->Flags & SF_INDEXED));
869 const FilePos* GetSymPos (SymEntry* S)
870 /* Return the position of first occurence in the source for the given symbol */
872 /* Resolve trampoline entries */
873 if (S->Flags & SF_TRAMPOLINE) {
876 PRECONDITION (S != 0);
882 static void SymCheckUndefined (SymEntry* S)
883 /* Handle an undefined symbol */
885 /* Undefined symbol. It may be...
887 * - An undefined symbol in a nested lexical level. In this
888 * case, search for the symbol in the higher levels and
889 * make the entry a trampoline entry if we find one.
891 * - If the symbol is not found, it is a real undefined symbol.
892 * If the AutoImport flag is set, make it an import. If the
893 * AutoImport flag is not set, it's an error.
897 /* It's a global symbol, get the higher level table */
898 SymTable* Tab = S->SymTab->BackLink;
900 Sym = SymFindAny (Tab, S->Name);
902 if (Sym->Flags & (SF_DEFINED | SF_IMPORT)) {
903 /* We've found a symbol in a higher level that is
904 * either defined in the source, or an import.
908 /* The symbol found is undefined itself. Look further */
909 Tab = Sym->SymTab->BackLink;
912 /* No symbol found */
918 /* We found the symbol in a higher level. Make S a trampoline
919 * symbol. Beware: We have to transfer the symbol attributes to
920 * the real symbol and check for any conflicts.
922 S->Flags |= SF_TRAMPOLINE;
925 /* Transfer the flags. Note: S may not be imported, since in that
926 * case it wouldn't be undefined.
928 if (S->Flags & SF_EXPORT) {
929 if (Sym->Flags & SF_IMPORT) {
930 /* The symbol is already marked as imported external symbol */
931 PError (&S->Pos, ERR_SYM_ALREADY_IMPORT, S->Name);
933 Sym->Flags |= S->Flags & (SF_EXPORT | SF_ZP);
936 /* Transfer the referenced flag */
937 Sym->Flags |= (S->Flags & SF_REFERENCED);
940 /* The symbol is definitely undefined */
941 if (S->Flags & SF_EXPORT) {
942 /* We will not auto-import an export */
943 PError (&S->Pos, ERR_EXPORT_UNDEFINED, S->Name);
946 /* Mark as import, will be indexed later */
947 S->Flags |= SF_IMPORT;
950 PError (&S->Pos, ERR_SYM_UNDEFINED, S->Name);
959 /* Run through all symbols and check for anomalies and errors */
963 /* Check for open lexical levels */
964 if (SymTab->BackLink != 0) {
965 Error (ERR_OPEN_PROC);
968 /* First pass: Walk through all symbols, checking for undefined's and
969 * changing them to trampoline symbols or make them imports.
973 /* If the symbol is marked as global, mark it as export, if it is
974 * already defined, otherwise mark it as import.
976 if (S->Flags & SF_GLOBAL) {
977 S->Flags &= ~SF_GLOBAL;
978 if (S->Flags & SF_DEFINED) {
979 S->Flags |= SF_EXPORT;
981 S->Flags |= SF_IMPORT;
985 /* Handle undefined symbols */
986 if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
987 /* This is an undefined symbol. Handle it. */
988 SymCheckUndefined (S);
995 /* Second pass: Walk again through the symbols. Ignore undefined's, since
996 * we handled them in the last pass, and ignore trampoline symbols, since
997 * we handled them in the last pass, too.
1001 if ((S->Flags & SF_TRAMPOLINE) == 0 &&
1002 (S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
1003 if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
1004 /* Symbol was defined but never referenced */
1005 PWarning (&S->Pos, WARN_SYM_NOT_REFERENCED, S->Name);
1007 if (S->Flags & SF_IMPORT) {
1008 if ((S->Flags & SF_REFERENCED) == 0) {
1009 /* Imported symbol is not referenced */
1010 PWarning (&S->Pos, WARN_IMPORT_NOT_REFERENCED, S->Name);
1012 /* Give the import an index, count imports */
1013 S->Index = ImportCount++;
1014 S->Flags |= SF_INDEXED;
1017 if (S->Flags & SF_EXPORT) {
1018 /* Give the export an index, count exports */
1019 S->Index = ExportCount++;
1020 S->Flags |= SF_INDEXED;
1031 void SymDump (FILE* F)
1032 /* Dump the symbol table */
1034 SymEntry* S = SymList;
1037 /* Ignore trampoline symbols */
1038 if ((S->Flags & SF_TRAMPOLINE) != 0) {
1040 "%-24s %s %s %s %s %s\n",
1042 (S->Flags & SF_DEFINED)? "DEF" : "---",
1043 (S->Flags & SF_REFERENCED)? "REF" : "---",
1044 (S->Flags & SF_IMPORT)? "IMP" : "---",
1045 (S->Flags & SF_EXPORT)? "EXP" : "---",
1046 (S->Flags & SF_ZP)? "ZP" : "--");
1055 void WriteImports (void)
1056 /* Write the imports list to the object file */
1060 /* Tell the object file module that we're about to start the imports */
1063 /* Write the import count to the list */
1064 ObjWriteVar (ImportCount);
1066 /* Walk throught list and write all imports to the file */
1069 if ((S->Flags & SF_IMPMASK) == SF_IMPVAL) {
1070 if (S->Flags & SF_ZP) {
1073 ObjWrite8 (IMP_ABS);
1075 ObjWriteStr (S->Name);
1076 ObjWritePos (&S->Pos);
1081 /* Done writing imports */
1087 static unsigned char GetExprMask (SymEntry* S)
1088 /* Return the expression bits for the given symbol table entry */
1090 unsigned char ExprMask;
1092 /* Check if the symbol is const */
1093 ExprMask = (SymIsConst (S))? EXP_CONST : EXP_EXPR;
1095 /* Add zeropage/abs bits */
1096 ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
1098 /* Add the label/equate bits */
1099 ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
1101 /* Return the mask */
1107 void WriteExports (void)
1108 /* Write the exports list to the object file */
1113 /* Tell the object file module that we're about to start the exports */
1116 /* Write the export count to the list */
1117 ObjWriteVar (ExportCount);
1119 /* Walk throught list and write all exports to the file */
1122 if ((S->Flags & SF_EXPMASK) == SF_EXPVAL) {
1123 unsigned char ExprMask;
1125 /* Finalize an associated expression if we have one */
1128 /* Get the expression bits */
1129 ExprMask = GetExprMask (S);
1131 /* Count the number of ConDes types */
1132 for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
1133 if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
1134 INC_EXP_CONDES_COUNT (ExprMask);
1138 /* Write the type */
1139 ObjWrite8 (ExprMask);
1141 /* Write any ConDes declarations */
1142 if (GET_EXP_CONDES_COUNT (ExprMask) > 0) {
1143 for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
1144 unsigned char Prio = S->ConDesPrio[Type];
1145 if (Prio != CD_PRIO_NONE) {
1146 ObjWrite8 (CD_BUILD (Type, Prio));
1151 /* Write the name */
1152 ObjWriteStr (S->Name);
1154 /* Write the value */
1155 if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
1156 /* Constant value */
1157 ObjWrite32 (S->V.Val);
1159 /* Expression involved */
1160 WriteExpr (S->V.Expr);
1163 /* Write the source file position */
1164 ObjWritePos (&S->Pos);
1169 /* Done writing exports */
1175 void WriteDbgSyms (void)
1176 /* Write a list of all symbols to the object file */
1181 /* Tell the object file module that we're about to start the debug info */
1184 /* Check if debug info is requested */
1187 /* Walk through the list and count the symbols */
1191 if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
1197 /* Write the symbol count to the list */
1198 ObjWriteVar (Count);
1200 /* Walk through list and write all symbols to the file */
1203 if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
1204 unsigned char ExprMask;
1206 /* Finalize an associated expression if we have one */
1209 /* Get the expression bits */
1210 ExprMask = GetExprMask (S);
1212 /* Write the type */
1213 ObjWrite8 (ExprMask);
1215 /* Write the name */
1216 ObjWriteStr (S->Name);
1218 /* Write the value */
1219 if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
1220 /* Constant value */
1221 ObjWrite32 (S->V.Val);
1223 /* Expression involved */
1224 WriteExpr (S->V.Expr);
1227 /* Write the source file position */
1228 ObjWritePos (&S->Pos);
1235 /* No debug symbols */
1240 /* Done writing debug symbols */