示例#1
0
文件: segments.c 项目: cc65/cc65
void SegDump (void)
/* Dump the segments and it's contents */
{
    unsigned I, J;
    unsigned long Count;
    unsigned char* Data;

    for (I = 0; I < CollCount (&SegmentList); ++I) {
        Segment* Seg = CollAtUnchecked (&SegmentList, I);
        printf ("Segment: %s (%lu)\n", GetString (Seg->Name), Seg->Size);
        for (J = 0; J < CollCount (&Seg->Sections); ++J) {
            Section* S = CollAtUnchecked (&Seg->Sections, J);
            unsigned J;
            Fragment* F = S->FragRoot;
            printf ("  Section:\n");
            while (F) {
                switch (F->Type) {

                    case FRAG_LITERAL:
                        printf ("    Literal (%u bytes):", F->Size);
                        Count = F->Size;
                        Data  = F->LitBuf;
                        J = 100;
                        while (Count--) {
                            if (J > 75) {
                                printf ("\n   ");
                                J = 3;
                            }
                            printf (" %02X", *Data++);
                            J += 3;
                        }
                        printf ("\n");
                        break;

                    case FRAG_EXPR:
                        printf ("    Expression (%u bytes):\n", F->Size);
                        printf ("    ");
                        DumpExpr (F->Expr, 0);
                        break;

                    case FRAG_SEXPR:
                        printf ("    Signed expression (%u bytes):\n", F->Size);
                        printf ("      ");
                        DumpExpr (F->Expr, 0);
                        break;

                    case FRAG_FILL:
                        printf ("    Empty space (%u bytes)\n", F->Size);
                        break;

                    default:
                        Internal ("Invalid fragment type: %02X", F->Type);
                }
                F = F->Next;
            }
        }
    }
}
示例#2
0
文件: library.c 项目: nedwidek/cc65
static void ReadIndex (void)
/* Read the index of a library file */
{
    unsigned Count, I;

    /* Seek to the start of the index */
    fseek (Lib, Header.IndexOffs, SEEK_SET);

    /* Read the object file count and calculate the cross ref size */
    Count = ReadVar (Lib);

    /* Read all entries in the index */
    while (Count--) {
        ReadIndexEntry ();
    }

    /* Read basic object file data from the actual entries */
    for (I = 0; I < CollCount (&ObjPool); ++I) {

        /* Get the object file entry */
        ObjData* O = CollAtUnchecked (&ObjPool, I);

        /* Read data */
        ObjReadData (Lib, O);
    }
}
示例#3
0
int CS_RangeHasLabel (CodeSeg* S, unsigned Start, unsigned Count)
/* Return true if any of the code entries in the given range has a label
 * attached. If the code segment does not span the given range, check the
 * possible span instead.
 */
{
    unsigned EntryCount = CS_GetEntryCount(S);

    /* Adjust count. We expect at least Start to be valid. */
    CHECK (Start < EntryCount);
    if (Start + Count > EntryCount) {
    	Count = EntryCount - Start;
    }

    /* Check each entry. Since we have validated the index above, we may
     * use the unchecked access function in the loop which is faster.
     */
    while (Count--) {
	const CodeEntry* E = CollAtUnchecked (&S->Entries, Start++);
	if (CE_HasLabel (E)) {
	    return 1;
	}
    }

    /* No label in the complete range */
    return 0;
}
示例#4
0
文件: segments.c 项目: cc65/cc65
int IsBSSType (Segment* S)
/* Check if the given segment is a BSS style segment, that is, it does not
** contain non-zero data.
*/
{
    /* Loop over all sections */
    unsigned I;
    for (I = 0; I < CollCount (&S->Sections); ++I) {

        /* Get the next section */
        Section* Sec = CollAtUnchecked (&S->Sections, I);

        /* Loop over all fragments */
        Fragment* F = Sec->FragRoot;
        while (F) {
            if (F->Type == FRAG_LITERAL) {
                unsigned char* Data = F->LitBuf;
                unsigned long Count = F->Size;
                while (Count--) {
                    if (*Data++ != 0) {
                        return 0;
                    }
                }
            } else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
                if (GetExprVal (F->Expr) != 0) {
                    return 0;
                }
            }
            F = F->Next;
        }
    }
    return 1;
}
示例#5
0
文件: symtab.c 项目: Aliandrana/cc65
void SymLeaveLevel (void)
/* Leave the current lexical level */
{
    /* If this is a scope that allows to emit data into segments, close the
    ** open the spans.
    */
    if (CurrentScope->Type <= SCOPE_HAS_DATA) {
        CloseSpanList (&CurrentScope->Spans);
    }

    /* If we have spans, the first one is the segment that was active, when the
    ** scope was opened. Set the size of the scope to the number of data bytes
    ** emitted into this segment. If we have an owner symbol set the size of
    ** this symbol, too.
    */
    if (CollCount (&CurrentScope->Spans) > 0) {
        const Span* S = CollAtUnchecked (&CurrentScope->Spans, 0);
        unsigned long Size = GetSpanSize (S);
        DefSizeOfScope (CurrentScope, Size);
        if (CurrentScope->Label) {
            DefSizeOfSymbol (CurrentScope->Label, Size);
        }
    }

    /* Mark the scope as closed */
    CurrentScope->Flags |= ST_CLOSED;

    /* Leave the scope */
    CurrentScope = CurrentScope->Parent;
}
示例#6
0
文件: segment.c 项目: eakmeister/cc65
void UseSeg (const SegDef* D)
/* Use the segment with the given name */
{
    unsigned I;
    for (I = 0; I < CollCount (&SegmentList); ++I) {
        Segment* Seg = CollAtUnchecked (&SegmentList, I);
       	if (strcmp (Seg->Def->Name, D->Name) == 0) {
     	    /* We found this segment. Check if the type is identical */
	    if (D->AddrSize != ADDR_SIZE_DEFAULT &&
                Seg->Def->AddrSize != D->AddrSize) {
	 	Error ("Segment attribute mismatch");
	 	/* Use the new attribute to avoid errors */
	        Seg->Def->AddrSize = D->AddrSize;
       	    }
       	    ActiveSeg = Seg;
     	    return;
     	}
    }

    /* Segment is not in list, create a new one */
    if (D->AddrSize == ADDR_SIZE_DEFAULT) {
        ActiveSeg = NewSegment (D->Name, ADDR_SIZE_ABS);
    } else {
        ActiveSeg = NewSegment (D->Name, D->AddrSize);
    }
}
示例#7
0
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);
}
示例#8
0
文件: asserts.c 项目: eakmeister/cc65
void WriteAssertions (void)
/* Write the assertion table to the object file */
{
    unsigned I;

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

    /* Tell the object file module that we're about to start the assertions */
    ObjStartAssertions ();

    /* Write the string count to the list */
    ObjWriteVar (Count);

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

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

        /* Write it to the file */
        WriteExpr (A->Expr);
        ObjWriteVar ((unsigned) A->Action);
        ObjWriteVar (A->Msg);
        WriteLineInfo (&A->LI);
    }

    /* Done writing the assertions */
    ObjEndAssertions ();
}
示例#9
0
文件: asserts.c 项目: eakmeister/cc65
void CheckAssertions (void)
/* Check all assertions */
{
    unsigned I;

    /* Walk over all assertions */
    for (I = 0; I < CollCount (&Assertions); ++I) {

        const LineInfo* LI;
        const char* Module;
        unsigned Line;

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

        /* Ignore assertions that shouldn't be handled at link time */
        if (!AssertAtLinkTime (A->Action)) {
            continue;
        }

        /* Retrieve the relevant line info for this assertion */
        LI = CollConstAt (&A->LineInfos, 0);

        /* Get file name and line number from the source */
        Module = GetSourceName (LI);
        Line   = GetSourceLine (LI);

        /* If the expression is not constant, we're not able to handle it */
        if (!IsConstExpr (A->Expr)) {
            Warning ("Cannot evaluate assertion in module `%s', line %u",
                     Module, Line);
        } else if (GetExprVal (A->Expr) == 0) {

            /* Assertion failed */
            const char* Message = GetString (A->Msg);

            switch (A->Action) {

                case ASSERT_ACT_WARN:
                case ASSERT_ACT_LDWARN:
                    Warning ("%s(%u): %s", Module, Line, Message);
                    break;

                case ASSERT_ACT_ERROR:
                case ASSERT_ACT_LDERROR:
                    Error ("%s(%u): %s", Module, Line, Message);
                    break;

                default:
                    Internal ("Invalid assertion action (%u) in module `%s', "
                              "line %u (file corrupt?)",
                              A->Action, Module, Line);
                    break;
            }
        }
    }
}
示例#10
0
struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id)
/* Get a debug symbol from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->DbgSyms)) {
        Error ("Invalid debug symbol index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->DbgSyms, Id);
}
示例#11
0
struct Export* GetObjExport (const ObjData* O, unsigned Id)
/* Get an export from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->Exports)) {
        Error ("Invalid export index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->Exports, Id);
}
示例#12
0
char* GetSearchPath (SearchPaths* P, unsigned Index)
/* Return the search path at the given index, if the index is valid, return an
** empty string otherwise.
*/
{
    if (Index < CollCount (P))
        return CollAtUnchecked (P, Index);
    return "";
}
示例#13
0
struct Scope* GetObjScope (const ObjData* O, unsigned Id)
/* Get a scope from an object file checking for a valid index */
{
    if (Id >= CollCount (&O->Scopes)) {
        Error ("Invalid scope index (%u) in module `%s'",
               Id, GetObjFileName (O));
    }
    return CollAtUnchecked (&O->Scopes, Id);
}
示例#14
0
文件: dump.c 项目: eakmeister/cc65
static void DestroyStrPool (Collection* C)
/* Free all strings in the given pool plus the item pointers. Note: The
 * collection may not be reused later.
 */
{
    unsigned I;
    for (I = 0; I < CollCount (C); ++I) {
        xfree (CollAtUnchecked (C, I));
    }
    DoneCollection (C);
}
示例#15
0
文件: segment.c 项目: eakmeister/cc65
unsigned char GetSegAddrSize (unsigned SegNum)
/* Return the address size of the segment with the given number */
{
    /* Is there such a segment? */
    if (SegNum >= CollCount (&SegmentList)) {
    	FAIL ("Invalid segment number");
    }

    /* Return the address size */
    return ((Segment*) CollAtUnchecked (&SegmentList, SegNum))->Def->AddrSize;
}
示例#16
0
static void DoneMacroExp (MacroExp* E)
/* Cleanup after use of a MacroExp structure */
{
    unsigned I;

    /* Delete the list with actual arguments */
    for (I = 0; I < CollCount (&E->ActualArgs); ++I) {
        FreeStrBuf (CollAtUnchecked (&E->ActualArgs, I));
    }
    DoneCollection (&E->ActualArgs);
    SB_Done (&E->Replacement);
}
示例#17
0
struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index)
/* Get the code entry following the one with the index Index. If there is no
 * following code entry, return NULL.
 */
{
    if (Index >= CollCount (&S->Entries)-1) {
   	/* This is the last entry */
   	return 0;
    } else {
   	/* Code entries left */
       	return CollAtUnchecked (&S->Entries, Index+1);
    }
}
示例#18
0
文件: attr.c 项目: PanchoManera/cc65
void FreeAttrList (Collection* C)
/* Free a list of attributes */
{
    unsigned I;

    /* Walk over the collection and free all attributes */
    for (I = 0; I < CollCount (C); ++I) {
        FreeAttr (CollAtUnchecked (C, I));
    }

    /* Free the collection itself */
    FreeCollection (C);
}
示例#19
0
struct CodeEntry* CS_GetPrevEntry (CodeSeg* S, unsigned Index)
/* Get the code entry preceeding the one with the index Index. If there is no
 * preceeding code entry, return NULL.
 */
{
    if (Index == 0) {
   	/* This is the first entry */
   	return 0;
    } else {
   	/* Previous entry available */
       	return CollAtUnchecked (&S->Entries, Index-1);
    }
}
示例#20
0
ExprNode* ULabRef (int Which)
/* Get an unnamed label. If Which is negative, it is a backreference (a
 * reference to an already defined label), and the function will return a
 * segment relative expression. If Which is positive, it is a forward ref,
 * and the function will return a expression node for an unnamed label that
 * must be resolved later.
 */
{
    int     Index;
    ULabel* L;

    /* Which can never be 0 */
    PRECONDITION (Which != 0);

    /* Get the index of the referenced label */
    if (Which > 0) {
        --Which;
    }
    Index = (int) ULabDefCount + Which;

    /* We cannot have negative label indices */
    if (Index < 0) {
        /* Label does not exist */
        Error ("Undefined label");
        /* We must return something valid */
        return GenCurrentPC();
    }

    /* Check if the label exists. If not, generate enough forward labels. */
    if (Index < (int) CollCount (&ULabList)) {
        /* The label exists, get it. */
        L = CollAtUnchecked (&ULabList, Index);
    } else {
        /* Generate new, undefined labels */
        while (Index >= (int) CollCount (&ULabList)) {
            L = NewULabel (0);
        }
    }

    /* Mark the label as referenced */
    ++L->Ref;

    /* If the label is already defined, return its value, otherwise return
     * just a reference.
     */
    if (L->Val) {
        return CloneExpr (L->Val);
    } else {
        return GenULabelExpr (Index);
    }
}
示例#21
0
void FreeObjData (ObjData* O)
/* Free an ObjData object. NOTE: This function works only for unused object
 * data, that is, ObjData objects that aren't used because they aren't
 * referenced.
 */
{
    unsigned I;

    for (I = 0; I < CollCount (&O->Files); ++I) {
        CollDeleteItem (&((FileInfo*) CollAtUnchecked (&O->Files, I))->Modules, O);
    }
    DoneCollection (&O->Files);
    DoneCollection (&O->Sections);
    for (I = 0; I < CollCount (&O->Exports); ++I) {
        FreeExport (CollAtUnchecked (&O->Exports, I));
    }
    DoneCollection (&O->Exports);
    for (I = 0; I < CollCount (&O->Imports); ++I) {
        FreeImport (CollAtUnchecked (&O->Imports, I));
    }
    DoneCollection (&O->Imports);
    DoneCollection (&O->DbgSyms);
    DoneCollection (&O->HLLDbgSyms);

    for (I = 0; I < CollCount (&O->LineInfos); ++I) {
        FreeLineInfo (CollAtUnchecked (&O->LineInfos, I));
    }
    DoneCollection (&O->LineInfos);
    xfree (O->Strings);
    DoneCollection (&O->Assertions);
    DoneCollection (&O->Scopes);
    for (I = 0; I < CollCount (&O->Spans); ++I) {
        FreeSpan (CollAtUnchecked (&O->Spans, I));
    }
    DoneCollection (&O->Spans);

    xfree (O);
}
示例#22
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);
    }
}
示例#23
0
文件: input.c 项目: eakmeister/cc65
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';
}
示例#24
0
文件: dbginfo.c 项目: cc65/cc65
void WriteHLLDbgSyms (void)
/* Write a list of all high level language symbols to the object file. */
{
    unsigned I;

    /* Only if debug info is enabled */
    if (DbgSyms) {

        /* Write the symbol count to the list */
        ObjWriteVar (CollCount (&HLLDbgSyms));

        /* Walk through list and write all symbols to the file. */
        for (I = 0; I < CollCount (&HLLDbgSyms); ++I) {

            /* Get the next symbol */
            HLLDbgSym* S = CollAtUnchecked (&HLLDbgSyms, I);

            /* Get the type of the symbol */
            unsigned SC = HLL_GET_SC (S->Flags);

            /* Remember if the symbol has debug info attached
            ** ### This should go into DbgInfoCheck
            */
            if (S->Sym && S->Sym->DebugSymId != ~0U) {
                S->Flags |= HLL_DATA_SYM;
            }

            /* Write the symbol data */
            ObjWriteVar (S->Flags);
            ObjWriteVar (S->Name);
            if (HLL_HAS_SYM (S->Flags)) {
                ObjWriteVar (S->Sym->DebugSymId);
            }
            if (SC == HLL_SC_AUTO || SC == HLL_SC_REG) {
                ObjWriteVar (S->Offs);
            }
            ObjWriteVar (S->Type);
            ObjWriteVar (S->Scope->Id);
        }

    } else {

        /* Write a count of zero */
        ObjWriteVar (0);

    }
}
示例#25
0
文件: segments.c 项目: cc65/cc65
void CheckSegments (void)
/* Walk through the segment list and check if there are segments that were
** not written to the output file. Output an error if this is the case.
*/
{
    unsigned I;
    for (I = 0; I < CollCount (&SegmentList); ++I) {

        /* Get the next segment */
        const Segment* S = CollAtUnchecked (&SegmentList, I);

        /* Check it */
        if (S->Size > 0 && S->Dumped == 0) {
            Error ("Missing memory area assignment for segment '%s'",
                   GetString (S->Name));
        }
    }
}
示例#26
0
文件: bin.c 项目: PanchoManera/cc65
void BinWriteTarget (BinDesc* D, struct File* F)
/* Write a binary output file */
{
    unsigned I;

    /* Place the filename in the control structure */
    D->Filename = GetString (F->Name);

    /* Check for unresolved symbols. The function BinUnresolved is called
     * if we get an unresolved symbol.
     */
    D->Undef = 0;               /* Reset the counter */
    CheckUnresolvedImports (BinUnresolved, D);
    if (D->Undef > 0) {
        /* We had unresolved symbols, cannot create output file */
        Error ("%u unresolved external(s) found - cannot create output file", D->Undef);
    }

    /* Open the file */
    D->F = fopen (D->Filename, "wb");
    if (D->F == 0) {
        Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
    }

    /* Keep the user happy */
    Print (stdout, 1, "Opened `%s'...\n", D->Filename);

    /* Dump all memory areas */
    for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
        /* Get this entry */
        MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I);
        Print (stdout, 1, "  Dumping `%s'\n", GetString (M->Name));
        BinWriteMem (D, M);
    }

    /* Close the file */
    if (fclose (D->F) != 0) {
        Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
    }

    /* Reset the file and filename */
    D->F        = 0;
    D->Filename = 0;
}
示例#27
0
int CS_GetEntries (CodeSeg* S, struct CodeEntry** List,
       	       	   unsigned Start, unsigned Count)
/* Get Count code entries into List starting at index start. Return true if
 * we got the lines, return false if not enough lines were available.
 */
{
    /* Check if enough entries are available */
    if (Start + Count > CollCount (&S->Entries)) {
	return 0;
    }

    /* Copy the entries */
    while (Count--) {
	*List++ = CollAtUnchecked (&S->Entries, Start++);
    }

    /* We have the entries */
    return 1;
}
示例#28
0
文件: segments.c 项目: cc65/cc65
void PrintSegmentMap (FILE* F)
/* Print a segment map to the given file */
{

    /* Allocate memory for the segment pool */
    Segment** SegPool = xmalloc (CollCount (&SegmentList) * sizeof (Segment*));

    /* Copy the segment pointers */
    unsigned I;
    for (I = 0; I < CollCount (&SegmentList); ++I) {
        SegPool[I] = CollAtUnchecked (&SegmentList, I);
    }

    /* Sort the array by increasing start addresses */
    qsort (SegPool, CollCount (&SegmentList), sizeof (Segment*), CmpSegStart);

    /* Print a header */
    fprintf (F, "Name                   Start     End    Size  Align\n"
                "----------------------------------------------------\n");

    /* Print the segments */
    for (I = 0; I < CollCount (&SegmentList); ++I) {

        /* Get a pointer to the segment */
        Segment* S = SegPool[I];

        /* Print empty segments only if explicitly requested */
        if (VerboseMap || S->Size > 0) {
            /* Print the segment data */
            long End = S->PC + S->Size;
            if (S->Size > 0) {
                /* Point to last element addressed */
                --End;
            }
            fprintf (F, "%-20s  %06lX  %06lX  %06lX  %05lX\n",
                     GetString (S->Name), S->PC, End, S->Size, S->Alignment);
        }
    }

    /* Free the segment pool */
    xfree (SegPool);
}
示例#29
0
文件: asserts.c 项目: eakmeister/cc65
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;
            }
        }
    }
}
示例#30
0
文件: objdata.c 项目: cc65/cc65
ObjData* FindObjData (const char* Module)
/* Search for the module with the given name and return it. Return NULL if the
** module is not in the list.
*/
{
    unsigned I;

    /* Hmm. Maybe we should hash the module names? */
    for (I = 0; I < CollCount (&ObjPool); ++I) {

        /* Get this object file */
        ObjData* O = CollAtUnchecked (&ObjPool, I);

        /* Did we find it? */
        if (strcmp (O->Name, Module) == 0) {
            return O;
        }
    }
    return 0;
}