]> git.sur5r.net Git - cc65/commitdiff
For segment based symbols, add information about the segment to the debug info.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 14 Jun 2011 19:25:50 +0000 (19:25 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 14 Jun 2011 19:25:50 +0000 (19:25 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@5062 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ld65/dbgsyms.c
src/ld65/expr.c
src/ld65/expr.h

index be981ac8481da3347c2a9a717eb9be41a7625a17..7ce767c4e32a17b63071e306c0cecb61e0502191 100644 (file)
@@ -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);
                }
     }
 }
index 6dc43db726ae7b5a42152404e0e0235d6d93452f..c6d3c7ef3a63563a138c1949c0910cdb10d6e973 100644 (file)
@@ -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 */
 {
index 0e9eafecf962786d2af986078c4ea1a5c6ed92c8..e35cfdf136ca67aa3ed9840cb5d4662f29dd150d 100644 (file)
@@ -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       */
 
 
 
+/*****************************************************************************/
+/*                                   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 */