示例#1
0
文件: segment.c 项目: eakmeister/cc65
void SegDone (void)
/* Check the segments for range and other errors. Do cleanup. */
{
    static const unsigned long U_Hi[4] = {
       	0x000000FFUL, 0x0000FFFFUL, 0x00FFFFFFUL, 0xFFFFFFFFUL
    };
    static const long S_Hi[4] = {
       	0x0000007FL, 0x00007FFFL, 0x007FFFFFL, 0x7FFFFFFFL
    };

    unsigned I;
    for (I = 0; I < CollCount (&SegmentList); ++I) {
        Segment* S = CollAtUnchecked (&SegmentList, I);
     	Fragment* F = S->Root;
     	while (F) {
       	    if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {

                /* We have an expression, study it */
                ExprDesc ED;
                ED_Init (&ED);
                StudyExpr (F->V.Expr, &ED);

                /* Check if the expression is constant */
                if (ED_IsConst (&ED)) {

     	       	    unsigned J;

       	       	    /* The expression is constant. Check for range errors. */
                    CHECK (F->Len <= 4);
                    if (F->Type == FRAG_SEXPR) {
                        long Hi = S_Hi[F->Len-1];
                        long Lo = ~Hi;
                        if (ED.Val > Hi || ED.Val < Lo) {
                            LIError (&F->LI,
                                     "Range error (%ld not in [%ld..%ld])",
                                     ED.Val, Lo, Hi);
                        }
                    } else {
                        if (((unsigned long)ED.Val) > U_Hi[F->Len-1]) {
                            LIError (&F->LI,
                                     "Range error (%lu not in [0..%lu])",
                                     (unsigned long)ED.Val, U_Hi[F->Len-1]);
                        }
                    }

                    /* We don't need the expression tree any longer */
                    FreeExpr (F->V.Expr);

     	     	    /* Convert the fragment into a literal fragment */
     	     	    for (J = 0; J < F->Len; ++J) {
     	     	       	F->V.Data[J] = ED.Val & 0xFF;
     	     	       	ED.Val >>= 8;
     	     	    }
     	     	    F->Type = FRAG_LITERAL;

      	     	} else if (RelaxChecks == 0) {

      	     	    /* We cannot evaluate the expression now, leave the job for
      	     	     * the linker. However, we can check if the address size
                     * matches the fragment size. Mismatches are errors in 
                     * most situations.
      	    	     */
                    if ((F->Len == 1 && ED.AddrSize > ADDR_SIZE_ZP)  ||
                        (F->Len == 2 && ED.AddrSize > ADDR_SIZE_ABS) ||
                        (F->Len == 3 && ED.AddrSize > ADDR_SIZE_FAR)) {
      	       	        LIError (&F->LI, "Range error");
      	     	    }
     	    	}

                /* Release memory allocated for the expression decriptor */
                ED_Done (&ED);
     	    }
示例#2
0
void SegCheck (void)
/* Check the segments for range and other errors */
{
    Segment* S = SegmentList;
    while (S) {
     	Fragment* F = S->Root;
     	while (F) {
       	    if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {

                /* We have an expression, study it */
                ExprDesc ED;
                ED_Init (&ED);
                StudyExpr (F->V.Expr, &ED);

                /* Try to simplify it before looking further */
                F->V.Expr = SimplifyExpr (F->V.Expr, &ED);

                /* Check if the expression is constant */
                if (ED_IsConst (&ED)) {

       	       	    /* The expression is constant. Check for range errors. */
     	       	    int Abs = (F->Type != FRAG_SEXPR);
                    long Val = ED.Val;
     	       	    unsigned I;

     	       	    if (F->Len == 1) {
     	       	   	if (Abs) {
     	       	   	    /* Absolute value */
     	       	   	    if (Val > 255) {
     	       	       	     	PError (&F->Pos, "Range error (%ld not in [0..255])", Val);
     	       	   	    }
     	       	   	} else {
     	     	   	    /* PC relative value */
     	     	   	    if (Val < -128 || Val > 127) {
     	       	       	     	PError (&F->Pos, "Range error (%ld not in [-128..127])", Val);
     	     	   	    }
     	     	   	}
     	       	    } else if (F->Len == 2) {
     	     	    	if (Abs) {
     	     	   	    /* Absolute value */
     	     	   	    if (Val > 65535) {
     	       	       	     	PError (&F->Pos, "Range error (%ld not in [0..65535])", Val);
     	     	   	    }
     	     	   	} else {
     	     	   	    /* PC relative value */
     	     	   	    if (Val < -32768 || Val > 32767) {
     	       	       	     	PError (&F->Pos, "Range error (%ld not in [-32768..32767])", Val);
     	       		    }
     	     		}
     	     	    }

                    /* We don't need the expression tree any longer */
                    FreeExpr (F->V.Expr);

     	     	    /* Convert the fragment into a literal fragment */
     	     	    for (I = 0; I < F->Len; ++I) {
     	     	       	F->V.Data [I] = Val & 0xFF;
     	     	       	Val >>= 8;
     	     	    }
     	     	    F->Type = FRAG_LITERAL;

     	     	} else if (ED.AddrSize != ADDR_SIZE_DEFAULT) {

     	     	    /* We cannot evaluate the expression now, leave the job for
     	     	     * the linker. However, we can check if the address size
                     * matches the fragment size, and we will do so.
     		     */
                    if ((F->Len == 1 && ED.AddrSize > ADDR_SIZE_ZP)  ||
                        (F->Len == 2 && ED.AddrSize > ADDR_SIZE_ABS) ||
                        (F->Len == 3 && ED.AddrSize > ADDR_SIZE_FAR)) {
     	       	        PError (&F->Pos, "Range error");
     	     	    }
     		}

                /* Release memory allocated for the expression decriptor */
                ED_Done (&ED);
     	    }