Exemple #1
0
SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val)
/* Add an constant symbol to the symbol table and return it */
{
    /* Enums must be inserted in the global symbol table */
    SymTable* Tab = ((Flags & SC_ENUM) == SC_ENUM)? SymTab0 : SymTab;

    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
    if (Entry) {
        if ((Entry->Flags & SC_CONST) != SC_CONST) {
            Error ("Symbol `%s' is already different kind", Name);
        } else {
            Error ("Multiple definition for `%s'", Name);
        }
        return Entry;
    }

    /* Create a new entry */
    Entry = NewSymEntry (Name, Flags);

    /* Enum values are ints */
    Entry->Type = TypeDup (T);

    /* Set the enum data */
    Entry->V.ConstVal = Val;

    /* Add the entry to the symbol table */
    AddSymEntry (Tab, Entry);

    /* Return the entry */
    return Entry;
}
Exemple #2
0
CodeLabel* CS_GenLabel (CodeSeg* S, struct CodeEntry* E)
/* If the code entry E does already have a label, return it. Otherwise
 * create a new label, attach it to E and return it.
 */
{
    CodeLabel* L;

    if (CE_HasLabel (E)) {

	/* Get the label from this entry */
	L = CE_GetLabel (E, 0);

    } else {

	/* Get a new name */
	const char* Name = LocalLabelName (GetLocalLabel ());

	/* Generate the hash over the name */
	unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE;

	/* Create a new label */
	L = CS_NewCodeLabel (S, Name, Hash);

	/* Attach this label to the code entry */
	CE_AttachLabel (E, L);

    }

    /* Return the label */
    return L;
}
Exemple #3
0
SymEntry* AddLabelSym (const char* Name, unsigned Flags)
/* Add a goto label to the label table */
{
    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (LabelTab, Name, HashStr (Name));
    if (Entry) {

        if (SymIsDef (Entry) && (Flags & SC_DEF) != 0) {
            /* Trying to define the label more than once */
            Error ("Label `%s' is defined more than once", Name);
        }
        Entry->Flags |= Flags;

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, SC_LABEL | Flags);

        /* Set a new label number */
        Entry->V.Label = GetLocalLabel ();

        /* Generate the assembler name of the label */
        Entry->AsmName = xstrdup (LocalLabelName (Entry->V.Label));

        /* Add the entry to the label table */
        AddSymEntry (LabelTab, Entry);

    }

    /* Return the entry */
    return Entry;
}
Exemple #4
0
static void AddSymEntry (SymTable* T, SymEntry* S)
/* Add a symbol to a symbol table */
{
    /* Get the hash value for the name */
    unsigned Hash = HashStr (S->Name) % T->Size;

    /* Insert the symbol into the list of all symbols in this level */
    if (T->SymTail) {
        T->SymTail->NextSym = S;
    }
    S->PrevSym = T->SymTail;
    T->SymTail = S;
    if (T->SymHead == 0) {
        /* First symbol */
        T->SymHead = S;
    }
    ++T->SymCount;

    /* Insert the symbol into the hash chain */
    S->NextHash  = T->Tab[Hash];
    T->Tab[Hash] = S;

    /* Tell the symbol in which table it is */
    S->Owner = T;
}
Exemple #5
0
SymEntry* AddBitField (const char* Name, unsigned Offs, unsigned BitOffs, unsigned Width)
/* Add a bit field to the local symbol table and return the symbol entry */
{
    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
    if (Entry) {

        /* We have a symbol with this name already */
        Error ("Multiple definition for `%s'", Name);

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, SC_BITFIELD);

        /* Set the symbol attributes. Bit-fields are always of type unsigned */
        Entry->Type         = type_uint;
        Entry->V.B.Offs     = Offs;
        Entry->V.B.BitOffs  = BitOffs;
        Entry->V.B.BitWidth = Width;

        /* Add the entry to the symbol table */
        AddSymEntry (SymTab, Entry);

    }

    /* Return the entry */
    return Entry;
}
Exemple #6
0
SymEntry* FindStructField (const Type* T, const char* Name)
/* Find a struct field in the fields list */
{
    SymEntry* Field = 0;

    /* The given type may actually be a pointer to struct */
    if (IsTypePtr (T)) {
        ++T;
    }

    /* Non-structs do not have any struct fields... */
    if (IsClassStruct (T)) {

        /* Get a pointer to the struct/union type */
        const SymEntry* Struct = GetSymEntry (T);
        CHECK (Struct != 0);

        /* Now search in the struct symbol table. Beware: The table may not
        ** exist.
        */
        if (Struct->V.S.SymTab) {
            Field = FindSymInTable (Struct->V.S.SymTab, Name, HashStr (Name));
        }
    }

    return Field;
}
Exemple #7
0
void ExpInsert (const char* Name, unsigned Module)
/* Insert an exported identifier and check if it's already in the list */
{
    HashEntry* L;

    /* Create a hash value for the given name */
    unsigned HashVal = HashStr (Name) % HASHTAB_SIZE;

    /* Create a new hash entry */
    HashEntry* H = NewHashEntry (Name, Module);

    /* Search through the list in that slot and print matching duplicates */
    if (HashTab [HashVal] == 0) {
    	/* The slot is empty */
    	HashTab [HashVal] = H;
    	return;
    }
    L = HashTab [HashVal];
    while (1) {
	if (strcmp (L->Name, Name) == 0) {
	    /* Duplicate entry */
	    Warning ("External symbol `%s' in module `%s' is duplicated in "
	       	     "module `%s'",
	  	     Name, GetObjName (L->Module), GetObjName (Module));
	}
     	if (L->Next == 0) {
     	    break;
     	} else {
     	    L = L->Next;
     	}
    }
    L->Next = H;
}
Exemple #8
0
CodeLabel* CS_AddLabel (CodeSeg* S, const char* Name)
/* Add a code label for the next instruction to follow */
{
    /* Calculate the hash from the name */
    unsigned Hash = HashStr (Name) % CS_LABEL_HASH_SIZE;

    /* Try to find the code label if it does already exist */
    CodeLabel* L = CS_FindLabel (S, Name, Hash);

    /* Did we find it? */
    if (L) {
     	/* We found it - be sure it does not already have an owner */
    	if (L->Owner) {
       	    Error ("ASM label `%s' is already defined", Name);
            return L;
    	}
    } else {
     	/* Not found - create a new one */
     	L = CS_NewCodeLabel (S, Name, Hash);
    }

    /* Safety. This call is quite costly, but safety is better */
    if (CollIndex (&S->Labels, L) >= 0) {
       	Error ("ASM label `%s' is already defined", Name);
        return L;
    }

    /* We do now have a valid label. Remember it for later */
    CollAppend (&S->Labels, L);

    /* Return the label */
    return L;
}
Exemple #9
0
void MakeZPSym (const char* Name)
/* Mark the given symbol as zero page symbol */
{
    /* Get the symbol table entry */
    SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));

    /* Mark the symbol as zeropage */
    if (Entry) {
        Entry->Flags |= SC_ZEROPAGE;
    } else {
        Error ("Undefined symbol: `%s'", Name);
    }
}
Exemple #10
0
int ExpFind (const char* Name)
/* Check for an identifier in the list. Return -1 if not found, otherwise
 * return the number of the module, that exports the identifer.
 */
{
    /* Get a pointer to the list with the symbols hash value */
    HashEntry* L = HashTab [HashStr (Name) % HASHTAB_SIZE];
    while (L) {
        /* Search through the list in that slot */
	if (strcmp (L->Name, Name) == 0) {
	    /* Entry found */
	    return L->Module;
	}
	L = L->Next;
    }

    /* Not found */
    return -1;
}
Exemple #11
0
SymEntry* AddStructSym (const char* Name, unsigned Type, unsigned Size, SymTable* Tab)
/* Add a struct/union entry and return it */
{
    SymEntry* Entry;

    /* Type must be struct or union */
    PRECONDITION (Type == SC_STRUCT || Type == SC_UNION);

    /* Do we have an entry with this name already? */
    Entry = FindSymInTable (TagTab, Name, HashStr (Name));
    if (Entry) {

        /* We do have an entry. This may be a forward, so check it. */
        if ((Entry->Flags & SC_TYPEMASK) != Type) {
            /* Existing symbol is not a struct */
            Error ("Symbol `%s' is already different kind", Name);
        } else if (Size > 0 && Entry->V.S.Size > 0) {
            /* Both structs are definitions. */
            Error ("Multiple definition for `%s'", Name);
        } else {
            /* Define the struct size if it is given */
            if (Size > 0) {
                Entry->V.S.SymTab = Tab;
                Entry->V.S.Size   = Size;
            }
        }

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, Type);

        /* Set the struct data */
        Entry->V.S.SymTab = Tab;
        Entry->V.S.Size   = Size;

        /* Add it to the current table */
        AddSymEntry (TagTab, Entry);
    }

    /* Return the entry */
    return Entry;
}
Exemple #12
0
SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs)
/* Add a local symbol and return the symbol entry */
{
    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
    if (Entry) {

        /* We have a symbol with this name already */
        Error ("Multiple definition for `%s'", Name);

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, Flags);

        /* Set the symbol attributes */
        Entry->Type = TypeDup (T);
        if ((Flags & SC_AUTO) == SC_AUTO) {
            Entry->V.Offs = Offs;
        } else if ((Flags & SC_REGISTER) == SC_REGISTER) {
            Entry->V.R.RegOffs  = Offs;
            Entry->V.R.SaveOffs = StackPtr;
        } else if ((Flags & SC_EXTERN) == SC_EXTERN) {
            Entry->V.Label = Offs;
            SymSetAsmName (Entry);
        } else if ((Flags & SC_STATIC) == SC_STATIC) {
            /* Generate the assembler name from the label number */
            Entry->V.Label = Offs;
            Entry->AsmName = xstrdup (LocalLabelName (Entry->V.Label));
        } else if ((Flags & SC_STRUCTFIELD) == SC_STRUCTFIELD) {
            Entry->V.Offs = Offs;
        } else {
            Internal ("Invalid flags in AddLocalSym: %04X", Flags);
        }

        /* Add the entry to the symbol table */
        AddSymEntry (SymTab, Entry);

    }

    /* Return the entry */
    return Entry;
}
Exemple #13
0
static SymEntry* FindSymInTree (const SymTable* Tab, const char* Name)
/* Find the symbol with the given name in the table tree that starts with T */
{
    /* Get the hash over the name */
    unsigned Hash = HashStr (Name);

    /* Check all symbol tables for the symbol */
    while (Tab) {
        /* Try to find the symbol in this table */
        SymEntry* E = FindSymInTable (Tab, Name, Hash);

        /* Bail out if we found it */
        if (E != 0) {
            return E;
        }

        /* Repeat the search in the next higher lexical level */
        Tab = Tab->PrevTab;
    }

    /* Not found */
    return 0;
}
Exemple #14
0
unsigned int OpenUtility::CBlockStream::Hash(const OpenUtility::CBlockStream *str)
{
	return(HashStr(str->GetStream()));
}
Exemple #15
0
SymEntry* FindLocalSym (const char* Name)
/* Find the symbol with the given name in the current symbol table only */
{
    return FindSymInTable (SymTab, Name, HashStr (Name));
}
Exemple #16
0
SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
/* Add an external or global symbol to the symbol table and return the entry */
{
    /* There is some special handling for functions, so check if it is one */
    int IsFunc = IsTypeFunc (T);

    /* Functions must be inserted in the global symbol table */
    SymTable* Tab = IsFunc? SymTab0 : SymTab;

    /* Do we have an entry with this name already? */
    SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
    if (Entry) {

        Type* EType;

        /* We have a symbol with this name already */
        if (Entry->Flags & SC_TYPE) {
            Error ("Multiple definition for `%s'", Name);
            return Entry;
        }

        /* Get the type string of the existing symbol */
        EType = Entry->Type;

        /* If we are handling arrays, the old entry or the new entry may be an
        ** incomplete declaration. Accept this, and if the exsting entry is
        ** incomplete, complete it.
        */
        if (IsTypeArray (T) && IsTypeArray (EType)) {

            /* Get the array sizes */
            long Size  = GetElementCount (T);
            long ESize = GetElementCount (EType);

            if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
                TypeCmp (T + 1, EType + 1) < TC_EQUAL) {
                /* Types not identical: Conflicting types */
                Error ("Conflicting types for `%s'", Name);
                return Entry;
            } else {
                /* Check if we have a size in the existing definition */
                if (ESize == UNSPECIFIED) {
                    /* Existing, size not given, use size from new def */
                    SetElementCount (EType, Size);
                }
            }

        } else {
            /* New type must be identical */
            if (TypeCmp (EType, T) < TC_EQUAL) {
                Error ("Conflicting types for `%s'", Name);
                return Entry;
            }

            /* In case of a function, use the new type descriptor, since it
            ** contains pointers to the new symbol tables that are needed if
            ** an actual function definition follows. Be sure not to use the
            ** new descriptor if it contains a function declaration with an
            ** empty parameter list.
            */
            if (IsFunc) {
                /* Get the function descriptor from the new type */
                FuncDesc* F = GetFuncDesc (T);
                /* Use this new function descriptor if it doesn't contain
                ** an empty parameter list.
                */
                if ((F->Flags & FD_EMPTY) == 0) {
                    Entry->V.F.Func = F;
                    SetFuncDesc (EType, F);
                }
            }
        }

        /* Add the new flags */
        Entry->Flags |= Flags;

    } else {

        /* Create a new entry */
        Entry = NewSymEntry (Name, Flags);

        /* Set the symbol attributes */
        Entry->Type = TypeDup (T);

        /* If this is a function, set the function descriptor and clear
        ** additional fields.
        */
        if (IsFunc) {
            Entry->V.F.Func = GetFuncDesc (Entry->Type);
            Entry->V.F.Seg  = 0;
        }

        /* Add the assembler name of the symbol */
        SymSetAsmName (Entry);

        /* Add the entry to the symbol table */
        AddSymEntry (Tab, Entry);
    }

    /* Return the entry */
    return Entry;
}
Exemple #17
0
SymEntry* FindGlobalSym (const char* Name)
/* Find the symbol with the given name in the global symbol table only */
{
    return FindSymInTable (SymTab0, Name, HashStr (Name));
}
Exemple #18
0
static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
/* Parse an instruction nnd generate a code entry from it. If the line contains
 * errors, output an error message and return NULL.
 * For simplicity, we don't accept the broad range of input a "real" assembler
 * does. The instruction and the argument are expected to be separated by
 * white space, for example.
 */
{
    char                Mnemo[IDENTSIZE+10];
    const OPCDesc* 	OPC;
    am_t      	   	AM = 0;	       	/* Initialize to keep gcc silent */
    char                Arg[IDENTSIZE+10];
    char      	      	Reg;
    CodeEntry*	     	E;
    CodeLabel*	   	Label;

    /* Read the first token and skip white space after it */
    L = SkipSpace (ReadToken (L, " \t:", Mnemo, sizeof (Mnemo)));

    /* Check if we have a label */
    if (*L == ':') {

	/* Skip the colon and following white space */
	L = SkipSpace (L+1);

	/* Add the label */
	CS_AddLabel (S,	Mnemo);

	/* If we have reached end of line, bail out, otherwise a mnemonic
	 * may follow.
	 */
	if (*L == '\0') {
	    return 0;
	}

	L = SkipSpace (ReadToken (L, " \t", Mnemo, sizeof (Mnemo)));
    }

    /* Try to find the opcode description for the mnemonic */
    OPC = FindOP65 (Mnemo);

    /* If we didn't find the opcode, print an error and bail out */
    if (OPC == 0) {
	Error ("ASM code error: %s is not a valid mnemonic", Mnemo);
	return 0;
    }

    /* Get the addressing mode */
    Arg[0] = '\0';
    switch (*L) {

	case '\0':
	    /* Implicit or accu */
            if (OPC->Info & OF_NOIMP) {
                AM = AM65_ACC;
            } else {
                AM = AM65_IMP;
            }
	    break;

	case '#':
	    /* Immidiate */
	    StrCopy (Arg, sizeof (Arg), L+1);
	    AM = AM65_IMM;
	    break;

	case '(':
	    /* Indirect */
	    L = ReadToken (L+1, ",)", Arg, sizeof (Arg));

	    /* Check for errors */
   	    if (*L == '\0') {
	     	Error ("ASM code error: syntax error");
	     	return 0;
	    }

	    /* Check the different indirect modes */
       	    if (*L == ',') {
	     	/* Expect zp x indirect */
	     	L = SkipSpace (L+1);
	     	if (toupper (*L) != 'X') {
	     	    Error ("ASM code error: `X' expected");
	     	    return 0;
	     	}
	     	L = SkipSpace (L+1);
	     	if (*L != ')') {
	     	    Error ("ASM code error: `)' expected");
	     	    return 0;
	     	}
	     	L = SkipSpace (L+1);
	      	if (*L != '\0') {
	     	    Error ("ASM code error: syntax error");
	     	    return 0;
	     	}
	     	AM = AM65_ZPX_IND;
	    } else if (*L == ')') {
	     	/* zp indirect or zp indirect, y */
	     	L = SkipSpace (L+1);
	      	if (*L == ',') {
	     	    L = SkipSpace (L+1);
	     	    if (toupper (*L) != 'Y') {
	     	      	Error ("ASM code error: `Y' expected");
	     	      	return 0;
	     	    }
	     	    L = SkipSpace (L+1);
	     	    if (*L != '\0') {
	       	       	Error ("ASM code error: syntax error");
	     	      	return 0;
	     	    }
	     	    AM = AM65_ZP_INDY;
	     	} else if (*L == '\0') {
	     	    AM = AM65_ZP_IND;
	     	} else {
	     	    Error ("ASM code error: syntax error");
   	     	    return 0;
	     	}
	    }
	    break;

	case 'a':
       	case 'A':
	    /* Accumulator? */
	    if (L[1] == '\0') {
	     	AM = AM65_ACC;
	     	break;
	    }
	    /* FALLTHROUGH */

	default:
	    /* Absolute, maybe indexed */
	    L = ReadToken (L, ",", Arg, sizeof (Arg));
	    if (*L == '\0') {
	     	/* Absolute, zeropage or branch */
	      	if ((OPC->Info & OF_BRA) != 0) {
		    /* Branch */
		    AM = AM65_BRA;
		} else if (GetZPInfo(Arg) != 0) {
		    AM = AM65_ZP;
		} else {
                    /* Check for subroutine call to local label */
                    if ((OPC->Info & OF_CALL) && IsLocalLabelName (Arg)) {
                        Error ("ASM code error: "
                               "Cannot use local label `%s' in subroutine call",
                               Arg);
                    }
		    AM = AM65_ABS;
		}
	    } else if (*L == ',') {
		/* Indexed */
		L = SkipSpace (L+1);
		if (*L == '\0') {
      		    Error ("ASM code error: syntax error");
		    return 0;
		} else {
	      	    Reg = toupper (*L);
		    L = SkipSpace (L+1);
		    if (Reg == 'X') {
		      	if (GetZPInfo(Arg) != 0) {
		      	    AM = AM65_ZPX;
		      	} else {
		      	    AM = AM65_ABSX;
	    	      	}
		    } else if (Reg == 'Y') {
   		      	AM = AM65_ABSY;
		    } else {
		       	Error ("ASM code error: syntax error");
	       	       	return 0;
		    }
		    if (*L != '\0') {
	    	       	Error ("ASM code error: syntax error");
	    	       	return 0;
	    	    }
	    	}
	    }
	    break;

    }

    /* If the instruction is a branch, check for the label and generate it
     * if it does not exist. This may lead to unused labels (if the label
     * is actually an external one) which are removed by the CS_MergeLabels
     * function later.
     */
    Label = 0;
    if (AM == AM65_BRA) {

	/* Generate the hash over the label, then search for the label */
	unsigned Hash = HashStr (Arg) % CS_LABEL_HASH_SIZE;
	Label = CS_FindLabel (S, Arg, Hash);

	/* If we don't have the label, it's a forward ref - create it */
	if (Label == 0) {
	    /* Generate a new label */
	    Label = CS_NewCodeLabel (S, Arg, Hash);
	}
    }

    /* We do now have the addressing mode in AM. Allocate a new CodeEntry
     * structure and initialize it.
     */
    E = NewCodeEntry (OPC->OPC, AM, Arg, Label, LI);

    /* Return the new code entry */
    return E;
}