mirror of
https://github.com/cc65/cc65.git
synced 2024-12-26 08:32:00 +00:00
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
This commit is contained in:
parent
82bab7fb89
commit
c768fc7373
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
{
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user