Ejemplo n.º 1
0
void CheckAssertions (void)
/* Check all assertions and evaluate the ones we can evaluate here. */
{
    unsigned I;

    /* Get the number of assertions */
    unsigned Count = CollCount (&Assertions);

    /* Check the assertions */
    for (I = 0; I < Count; ++I) {

        long Val;

        /* Get the next assertion */
        Assertion* A = CollAtUnchecked (&Assertions, I);

        /* Ignore it, if it should only be evaluated by the linker */
        if (!AssertAtAsmTime (A->Action)) {
            continue;
        }

        /* Can we evaluate the expression? */
        if (IsConstExpr (A->Expr, &Val) && Val == 0) {
            /* Apply the action */
            const char* Msg = GetString (A->Msg);
            switch (A->Action) {

            case ASSERT_ACT_WARN:
                LIWarning (&A->LI, 0, "%s", Msg);
                break;

            case ASSERT_ACT_ERROR:
                LIError (&A->LI, "%s", Msg);
                break;

            default:
                Internal ("Illegal assert action specifier");
                break;
            }
        }
    }
}
Ejemplo n.º 2
0
void ULabDone (void)
/* Run through all unnamed labels, check for anomalies and errors and do 
 * necessary cleanups.
 */
{
    /* Check if there are undefined labels */
    unsigned I = ULabDefCount;
    while (I < CollCount (&ULabList)) {
        ULabel* L = CollAtUnchecked (&ULabList, I);
        LIError (&L->LineInfos, "Undefined label");
        ++I;
    }

    /* Walk over all labels and emit a warning if any unreferenced ones
     * are found. Remove line infos because they're no longer needed.
     */
    for (I = 0; I < CollCount (&ULabList); ++I) {
        ULabel* L = CollAtUnchecked (&ULabList, I);
        if (L->Ref == 0) {
            LIWarning (&L->LineInfos, 1, "No reference to unnamed label");
        }
        ReleaseFullLineInfo (&L->LineInfos);
    }
}
Ejemplo n.º 3
0
void SymCheck (void)
/* Run through all symbols and check for anomalies and errors */
{
    SymEntry* S;

    /* Check for open scopes */
    if (CurrentScope->Parent != 0) {
        Error ("Local scope was not closed");
    }

    /* First pass: Walk through all symbols, checking for undefined's and
    ** changing them to trampoline symbols or make them imports.
    */
    S = SymList;
    while (S) {
        /* If the symbol is marked as global, mark it as export, if it is
        ** already defined, otherwise mark it as import.
        */
        if (S->Flags & SF_GLOBAL) {
            if (S->Flags & SF_DEFINED) {
                SymExportFromGlobal (S);
            } else {
                SymImportFromGlobal (S);
            }
        }

        /* Handle undefined symbols */
        if ((S->Flags & SF_UNDEFMASK) == SF_UNDEFVAL) {
            /* This is an undefined symbol. Handle it. */
            SymCheckUndefined (S);
        }

        /* Next symbol */
        S = S->List;
    }

    /* Second pass: Walk again through the symbols. Count exports and imports
    ** and set address sizes where this has not happened before. Ignore
    ** undefined's, since we handled them in the last pass, and ignore unused
    ** symbols, since we handled them in the last pass, too.
    */
    S = SymList;
    while (S) {
        if ((S->Flags & SF_UNUSED) == 0 &&
            (S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {

            /* Check for defined symbols that were never referenced */
            if (IsSizeOfSymbol (S)) {
                /* Remove line infos, we don't need them any longer */
                ReleaseFullLineInfo (&S->DefLines);
                ReleaseFullLineInfo (&S->RefLines);
            } else if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
                LIWarning (&S->DefLines, 2,
                           "Symbol `%m%p' is defined but never used",
                           GetSymName (S));
            }

            /* Assign an index to all imports */
            if (S->Flags & SF_IMPORT) {
                if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
                    /* Imported symbol is not referenced */
                    LIWarning (&S->DefLines, 2,
                               "Symbol `%m%p' is imported but never used",
                               GetSymName (S));
                } else {
                    /* Give the import an id, count imports */
                    S->ImportId = ImportCount++;
                }
            }

            /* Count exports, assign the export ID */
            if (S->Flags & SF_EXPORT) {
                S->ExportId = ExportCount++;
            }

            /* If the symbol is defined but has an unknown address size,
            ** recalculate it.
            */
            if (SymHasExpr (S) && S->AddrSize == ADDR_SIZE_DEFAULT) {
                ExprDesc ED;
                ED_Init (&ED);
                StudyExpr (S->Expr, &ED);
                S->AddrSize = ED.AddrSize;
                if (SymIsExport (S)) {
                    if (S->ExportSize == ADDR_SIZE_DEFAULT) {
                        /* Use the real export size */
                        S->ExportSize = S->AddrSize;
                    } else if (S->AddrSize > S->ExportSize) {
                        /* We're exporting a symbol smaller than it actually is */
                        LIWarning (&S->DefLines, 1,
                                   "Symbol `%m%p' is %s but exported %s",
                                   GetSymName (S),
                                   AddrSizeToStr (S->AddrSize),
                                   AddrSizeToStr (S->ExportSize));
                    }
                }
                ED_Done (&ED);
            }

            /* If the address size of the symbol was guessed, check the guess
            ** against the actual address size and print a warning if the two
            ** differ.
            */
            if (S->AddrSize != ADDR_SIZE_DEFAULT) {
                /* Do we have data for this address size? */
                if (S->AddrSize <= sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0])) {
                    /* Get the file position where the symbol was used */
                    const FilePos* P = S->GuessedUse[S->AddrSize - 1];
                    if (P) {
                        PWarning (P, 0,
                                  "Didn't use %s addressing for `%m%p'",
                                  AddrSizeToStr (S->AddrSize),
                                  GetSymName (S));
                    }
                }
            }

        }

        /* Next symbol */
        S = S->List;
    }
}
Ejemplo n.º 4
0
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));
            }
        }
    }
}