From c768fc737358024421d36f0725edaf614af36707 Mon Sep 17 00:00:00 2001 From: uz Date: Tue, 14 Jun 2011 19:25:50 +0000 Subject: [PATCH] For segment based symbols, add information about the segment to the debug info. git-svn-id: svn://svn.cc65.org/cc65/trunk@5062 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ld65/dbgsyms.c | 40 ++++++++++++------- src/ld65/expr.c | 96 +++++++++++++++++++++++++++++++++++++++++++++- src/ld65/expr.h | 30 +++++++++++++-- 3 files changed, 148 insertions(+), 18 deletions(-) diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index be981ac84..7ce767c4e 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -130,9 +130,9 @@ static void InsertDbgSym (DbgSym* D, long Val) { /* Create the hash. We hash over the symbol value */ unsigned Hash = ((Val >> 24) & 0xFF) ^ - ((Val >> 16) & 0xFF) ^ - ((Val >> 8) & 0xFF) ^ - ((Val >> 0) & 0xFF); + ((Val >> 16) & 0xFF) ^ + ((Val >> 8) & 0xFF) ^ + ((Val >> 0) & 0xFF); /* Insert the symbol */ D->Next = DbgSymPool [Hash]; @@ -212,31 +212,45 @@ void PrintDbgSyms (ObjData* O, FILE* F) long Val; /* Get the next debug symbol */ - DbgSym* D = CollAt (&O->DbgSyms, I); + DbgSym* S = CollAt (&O->DbgSyms, I); /* Get the symbol value */ - Val = GetDbgSymVal (D); + Val = GetDbgSymVal (S); /* Lookup this symbol in the table. If it is found in the table, it was * already written to the file, so don't emit it twice. If it is not in * the table, insert and output it. */ - if (GetDbgSym (D, Val) == 0) { + if (GetDbgSym (S, Val) == 0) { - /* Emit the debug file line */ + SegExprDesc D; + + /* Emit the base data for the entry */ fprintf (F, "sym\tname=\"%s\",value=0x%lX,addrsize=%s,type=%s", - GetString (D->Name), + GetString (S->Name), Val, - AddrSizeToStr (D->AddrSize), - SYM_IS_LABEL (D->Type)? "label" : "equate"); - if (D->Size != 0) { - fprintf (F, ",size=%lu", D->Size); + AddrSizeToStr (S->AddrSize), + SYM_IS_LABEL (S->Type)? "label" : "equate"); + + /* Emit the size only if we know it */ + if (S->Size != 0) { + fprintf (F, ",size=%lu", S->Size); } + + /* Check for a segmented expression and add the segment id to the + * debug info if we have one. + */ + GetSegExprVal (S->Expr, &D); + if (!D.TooComplex && D.Seg != 0) { + fprintf (F, ",segment=%u", D.Seg->Id); + } + + /* Terminate the output line */ fputc ('\n', F); /* Insert the symbol into the table */ - InsertDbgSym (D, Val); + InsertDbgSym (S, Val); } } } diff --git a/src/ld65/expr.c b/src/ld65/expr.c index 6dc43db72..c6d3c7ef3 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2010, Ullrich von Bassewitz */ +/* (C) 1998-2011, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -398,6 +398,100 @@ long GetExprVal (ExprNode* Expr) +static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign) +/* Check if the given expression consists of a segment reference and only + * constant values, additions and subtractions. If anything else is found, + * set D->TooComplex to true. + * Internal, recursive routine. + */ +{ + Export* E; + + switch (Expr->Op) { + + case EXPR_LITERAL: + D->Val += (Sign * Expr->V.IVal); + break; + + case EXPR_SYMBOL: + /* Get the referenced export */ + E = GetExprExport (Expr); + /* If this export has a mark set, we've already encountered it. + * This means that the export is used to define it's own value, + * which in turn means, that we have a circular reference. + */ + if (ExportHasMark (E)) { + CircularRefError (E); + } else { + MarkExport (E); + GetSegExprValInternal (E->Expr, D, Sign); + UnmarkExport (E); + } + break; + + case EXPR_SECTION: + if (D->Seg) { + /* We cannot handle more than one segment reference in o65 */ + D->TooComplex = 1; + } else { + /* Get the section from the expression */ + Section* S = GetExprSection (Expr); + /* Remember the segment reference */ + D->Seg = S->Seg; + /* Add the offset of the section to the constant value */ + D->Val += Sign * (S->Offs + D->Seg->PC); + } + break; + + case EXPR_SEGMENT: + if (D->Seg) { + /* We cannot handle more than one segment reference in o65 */ + D->TooComplex = 1; + } else { + /* Remember the segment reference */ + D->Seg = Expr->V.Seg; + /* Add the offset of the segment to the constant value */ + D->Val += (Sign * D->Seg->PC); + } + break; + + case EXPR_PLUS: + GetSegExprValInternal (Expr->Left, D, Sign); + GetSegExprValInternal (Expr->Right, D, Sign); + break; + + case EXPR_MINUS: + GetSegExprValInternal (Expr->Left, D, Sign); + GetSegExprValInternal (Expr->Right, D, -Sign); + break; + + default: + /* Expression contains illegal operators */ + D->TooComplex = 1; + break; + + } +} + + + +void GetSegExprVal (ExprNode* Expr, SegExprDesc* D) +/* Check if the given expression consists of a segment reference and only + * constant values, additions and subtractions. If anything else is found, + * set D->TooComplex to true. The function will initialize D. + */ +{ + /* Initialize the given structure */ + D->Val = 0; + D->TooComplex = 0; + D->Seg = 0; + + /* Call our recursive calculation routine */ + GetSegExprValInternal (Expr, D, 1); +} + + + ExprNode* LiteralExpr (long Val, ObjData* O) /* Return an expression tree that encodes the given literal value */ { diff --git a/src/ld65/expr.h b/src/ld65/expr.h index 0e9eafecf..e35cfdf13 100644 --- a/src/ld65/expr.h +++ b/src/ld65/expr.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -48,6 +48,22 @@ +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* Structure for parsing segment based expression trees */ +typedef struct SegExprDesc SegExprDesc; +struct SegExprDesc { + long Val; /* The offset value */ + int TooComplex; /* Expression too complex */ + Segment* Seg; /* Segment reference if any */ +}; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -77,6 +93,12 @@ Section* GetExprSection (ExprNode* Expr); long GetExprVal (ExprNode* Expr); /* Get the value of a constant expression */ +void GetSegExprVal (ExprNode* Expr, SegExprDesc* D); +/* Check if the given expression consists of a segment reference and only + * constant values, additions and subtractions. If anything else is found, + * set D->TooComplex to true. The function will initialize D. + */ + ExprNode* LiteralExpr (long Val, ObjData* O); /* Return an expression tree that encodes the given literal value */