{
/* 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];
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);
}
}
}
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
+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 */
{
/* */
/* */
/* */
-/* (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 */
/*****************************************************************************/
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 */