void ClearObjData (ObjData* O) /* Remove any data stored in O */ { unsigned I; xfree (O->Name); O->Name = 0; for (I = 0; I < CollCount (&O->Strings); ++I) { xfree (CollAt (&O->Strings, I)); } CollDeleteAll (&O->Strings); CollDeleteAll (&O->Exports); }
static void SymReplaceExprRefs (SymEntry* S) /* Replace the references to this symbol by a copy of the symbol expression */ { unsigned I; long Val; /* Check if the expression is const and get its value */ int IsConst = IsConstExpr (S->Expr, &Val); CHECK (IsConst); /* Loop over all references */ for (I = 0; I < CollCount (&S->ExprRefs); ++I) { /* Get the expression node */ ExprNode* E = CollAtUnchecked (&S->ExprRefs, I); /* Safety */ CHECK (E->Op == EXPR_SYMBOL && E->V.Sym == S); /* We cannot touch the root node, since there are pointers to it. ** Replace it by a literal node. */ E->Op = EXPR_LITERAL; E->V.IVal = Val; } /* Remove all symbol references from the symbol */ CollDeleteAll (&S->ExprRefs); }
void CS_DelLabel (CodeSeg* S, CodeLabel* L) /* Remove references from this label and delete it. */ { unsigned Count, I; /* First, remove the label from the hash chain */ CS_RemoveLabelFromHash (S, L); /* Remove references from insns jumping to this label */ Count = CollCount (&L->JumpFrom); for (I = 0; I < Count; ++I) { /* Get the insn referencing this label */ CodeEntry* E = CollAt (&L->JumpFrom, I); /* Remove the reference */ CE_ClearJumpTo (E); } CollDeleteAll (&L->JumpFrom); /* Remove the reference to the owning instruction if it has one. The * function may be called for a label without an owner when deleting * unfinished parts of the code. This is unfortunate since it allows * errors to slip through. */ if (L->Owner) { CollDeleteItem (&L->Owner->Labels, L); } /* All references removed, delete the label itself */ FreeCodeLabel (L); }
static void CS_MoveLabelsToPool (CodeSeg* S, CodeEntry* E) /* Move the labels of the code entry E to the label pool of the code segment */ { unsigned LabelCount = CE_GetLabelCount (E); while (LabelCount--) { CodeLabel* L = CE_GetLabel (E, LabelCount); L->Owner = 0; CollAppend (&S->Labels, L); } CollDeleteAll (&E->Labels); }
void ClearLine (void) /* Clear the current input line */ { unsigned I; /* Remove all pushed fragments from the input stack */ for (I = 0; I < CollCount (&InputStack); ++I) { FreeStrBuf (CollAtUnchecked (&InputStack, I)); } CollDeleteAll (&InputStack); /* Clear the contents of Line */ SB_Clear (Line); CurC = '\0'; NextC = '\0'; }
static void CS_MoveLabelsToEntry (CodeSeg* S, CodeEntry* E) /* Move all labels from the label pool to the given entry and remove them * from the pool. */ { /* Transfer the labels if we have any */ unsigned I; unsigned LabelCount = CollCount (&S->Labels); for (I = 0; I < LabelCount; ++I) { /* Get the label */ CodeLabel* L = CollAt (&S->Labels, I); /* Attach it to the entry */ CE_AttachLabel (E, L); } /* Delete the transfered labels */ CollDeleteAll (&S->Labels); }
void SymTransferExprRefs (SymEntry* From, SymEntry* To) /* Transfer all expression references from one symbol to another. */ { unsigned I; for (I = 0; I < CollCount (&From->ExprRefs); ++I) { /* Get the expression node */ ExprNode* E = CollAtUnchecked (&From->ExprRefs, I); /* Safety */ CHECK (E->Op == EXPR_SYMBOL && E->V.Sym == From); /* Replace the symbol reference */ E->V.Sym = To; /* Add the expression reference */ SymAddExprRef (To, E); } /* Remove all symbol references from the old symbol */ CollDeleteAll (&From->ExprRefs); }
static void SymCheckUndefined (SymEntry* S) /* Handle an undefined symbol */ { /* Undefined symbol. It may be... ** ** - An undefined symbol in a nested lexical level. If the symbol is not ** fixed to this level, search for the symbol in the higher levels and ** make the entry a trampoline entry if we find one. ** ** - If the symbol is not found, it is a real undefined symbol. If the ** AutoImport flag is set, make it an import. If the AutoImport flag is ** not set, it's an error. */ SymEntry* Sym = 0; if ((S->Flags & SF_FIXED) == 0) { SymTable* Tab = GetSymParentScope (S); while (Tab) { Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING | SYM_CHECK_ONLY); if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) { /* We've found a symbol in a higher level that is ** either defined in the source, or an import. */ break; } /* No matching symbol found in this level. Look further */ Tab = Tab->Parent; } } if (Sym) { /* We found the symbol in a higher level. Transfer the flags and ** address size from the local symbol to that in the higher level ** and check for problems. */ if (S->Flags & SF_EXPORT) { if (Sym->Flags & SF_IMPORT) { /* The symbol is already marked as import */ LIError (&S->RefLines, "Symbol `%s' is already an import", GetString (Sym->Name)); } if ((Sym->Flags & SF_EXPORT) == 0) { /* Mark the symbol as an export */ Sym->Flags |= SF_EXPORT; Sym->ExportSize = S->ExportSize; if (Sym->ExportSize == ADDR_SIZE_DEFAULT) { /* Use the actual size of the symbol */ Sym->ExportSize = Sym->AddrSize; } if (Sym->AddrSize > Sym->ExportSize) { /* We're exporting a symbol smaller than it actually is */ LIWarning (&Sym->DefLines, 1, "Symbol `%m%p' is %s but exported %s", GetSymName (Sym), AddrSizeToStr (Sym->AddrSize), AddrSizeToStr (Sym->ExportSize)); } } } if (S->Flags & SF_REFERENCED) { /* Mark as referenced and move the line info */ Sym->Flags |= SF_REFERENCED; CollTransfer (&Sym->RefLines, &S->RefLines); CollDeleteAll (&S->RefLines); } /* Transfer all expression references */ SymTransferExprRefs (S, Sym); /* Mark the symbol as unused removing all other flags */ S->Flags = SF_UNUSED; } else { /* The symbol is definitely undefined */ if (S->Flags & SF_EXPORT) { /* We will not auto-import an export */ LIError (&S->RefLines, "Exported symbol `%m%p' was never defined", GetSymName (S)); } else { if (AutoImport) { /* Mark as import, will be indexed later */ S->Flags |= SF_IMPORT; /* Use the address size for code */ S->AddrSize = CodeAddrSize; /* Mark point of import */ GetFullLineInfo (&S->DefLines); } else { /* Error */ LIError (&S->RefLines, "Symbol `%m%p' is undefined", GetSymName (S)); } } } }