From 2fbebd25cf9460060e73398abd244ea253d20807 Mon Sep 17 00:00:00 2001 From: uz Date: Fri, 26 Aug 2011 12:05:00 +0000 Subject: [PATCH] Started to add debug infos for C functions and symbols. git-svn-id: svn://svn.cc65.org/cc65/trunk@5273 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/dbginfo.c | 120 +++++++++++++++++++++++++++++++++++++++++++- src/ca65/dbginfo.h | 3 ++ src/ca65/pseudo.c | 6 ++- src/cc65/function.c | 48 ++++++++++++++++-- 4 files changed, 170 insertions(+), 7 deletions(-) diff --git a/src/ca65/dbginfo.c b/src/ca65/dbginfo.c index 86a470d6c..dfa513053 100644 --- a/src/ca65/dbginfo.c +++ b/src/ca65/dbginfo.c @@ -104,6 +104,63 @@ void DbgInfoFile (void) +void DbgInfoFunc (void) +/* Parse and handle func subcommand of the .dbg pseudo instruction */ +{ + static const char* StorageKeys[] = { + "EXTERN", + "STATIC", + }; + + StrBuf Name = STATIC_STRBUF_INITIALIZER; + StrBuf AsmName = STATIC_STRBUF_INITIALIZER; + int StorageClass; + + + /* Parameters are separated by a comma */ + ConsumeComma (); + + /* Name */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + return; + } + SB_Copy (&Name, &CurTok.SVal); + NextTok (); + + /* Comma expected */ + ConsumeComma (); + + /* The storage class follows */ + if (CurTok.Tok != TOK_IDENT) { + ErrorSkip ("Storage class specifier expected"); + return; + } + StorageClass = GetSubKey (StorageKeys, sizeof (StorageKeys)/sizeof (StorageKeys[0])); + if (StorageClass < 0) { + ErrorSkip ("Storage class specifier expected"); + return; + } + NextTok (); + + /* Comma expected */ + ConsumeComma (); + + /* Assembler name follows */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + return; + } + SB_Copy (&AsmName, &CurTok.SVal); + NextTok (); + + /* Free memory used for the strings */ + SB_Done (&AsmName); + SB_Done (&Name); +} + + + void DbgInfoLine (void) /* Parse and handle LINE subcommand of the .dbg pseudo instruction */ { @@ -158,7 +215,68 @@ void DbgInfoLine (void) void DbgInfoSym (void) /* Parse and handle SYM subcommand of the .dbg pseudo instruction */ { - ErrorSkip ("Not implemented"); + static const char* StorageKeys[] = { + "AUTO", + "EXTERN", + "REGISTER", + "STATIC", + }; + + StrBuf Name = STATIC_STRBUF_INITIALIZER; + StrBuf AsmName = STATIC_STRBUF_INITIALIZER; + int StorageClass; + int Offs; + + + /* Parameters are separated by a comma */ + ConsumeComma (); + + /* Name */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + return; + } + SB_Copy (&Name, &CurTok.SVal); + NextTok (); + + /* Comma expected */ + ConsumeComma (); + + /* The storage class follows */ + if (CurTok.Tok != TOK_IDENT) { + ErrorSkip ("Storage class specifier expected"); + return; + } + StorageClass = GetSubKey (StorageKeys, sizeof (StorageKeys)/sizeof (StorageKeys[0])); + if (StorageClass < 0) { + ErrorSkip ("Storage class specifier expected"); + return; + } + + /* Skip the storage class token and the following comma */ + NextTok (); + ConsumeComma (); + + /* The next tokens depend on the storage class */ + if (StorageClass == 0) { + /* Auto: Stack offset follows */ + Offs = ConstExpression (); + } else if (StorageClass == 2) { + /* Register: Register bank offset follows */ + Offs = ConstExpression (); + } else { + /* Extern or static: Assembler name follows */ + if (CurTok.Tok != TOK_STRCON) { + ErrorSkip ("String constant expected"); + return; + } + SB_Copy (&AsmName, &CurTok.SVal); + NextTok (); + } + + /* Free memory used for the strings */ + SB_Done (&AsmName); + SB_Done (&Name); } diff --git a/src/ca65/dbginfo.h b/src/ca65/dbginfo.h index 30fd7ed56..1334c06b2 100644 --- a/src/ca65/dbginfo.h +++ b/src/ca65/dbginfo.h @@ -47,6 +47,9 @@ void DbgInfoFile (void); /* Parse and handle FILE subcommand of the .dbg pseudo instruction */ +void DbgInfoFunc (void); +/* Parse and handle FUNC subcommand of the .dbg pseudo instruction */ + void DbgInfoLine (void); /* Parse and handle LINE subcommand of the .dbg pseudo instruction */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index 02db0ecb4..477a6a698 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -753,6 +753,7 @@ static void DoDbg (void) { static const char* Keys[] = { "FILE", + "FUNC", "LINE", "SYM", }; @@ -774,8 +775,9 @@ static void DoDbg (void) /* Check the key and dispatch to a handler */ switch (Key) { case 0: DbgInfoFile (); break; - case 1: DbgInfoLine (); break; - case 2: DbgInfoSym (); break; + case 1: DbgInfoFunc (); break; + case 2: DbgInfoLine (); break; + case 3: DbgInfoSym (); break; default: ErrorSkip ("Syntax error"); break; } } diff --git a/src/cc65/function.c b/src/cc65/function.c index 0f3229084..b31bfd796 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2000-2009, Ullrich von Bassewitz */ +/* (C) 2000-2011, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -47,7 +47,6 @@ #include "litpool.h" #include "locals.h" #include "scanner.h" -#include "segments.h" #include "stackptr.h" #include "standard.h" #include "stmt.h" @@ -74,7 +73,7 @@ typedef enum { struct Function { struct SymEntry* FuncEntry; /* Symbol table entry */ Type* ReturnType; /* Function return type */ - struct FuncDesc* Desc; /* Function descriptor */ + FuncDesc* Desc; /* Function descriptor */ int Reserved; /* Reserved local space */ unsigned RetLab; /* Return code label */ int TopLevelSP; /* SP at function top level */ @@ -360,8 +359,46 @@ static void F_RestoreRegVars (Function* F) +static void EmitDebugInfo (void) +/* Emit debug infos for the current function */ +{ + /* Fetch stuff for the current fuction */ + const SymEntry* Sym = CurrentFunc->FuncEntry; + const FuncDesc* Desc = CurrentFunc->Desc; + const SymTable* Tab = Desc->SymTab; + + /* Output info for the function itself */ + AddTextLine ("\t.dbg\tfunc, \"%s\", %s, \"%s\"", + Sym->Name, + (Sym->Flags & SC_EXTERN)? "extern" : "static", + Sym->AsmName); + + /* Output info for locals */ + Sym = Tab->SymHead; + while (Sym) { + if ((Sym->Flags & (SC_CONST|SC_TYPE)) == 0) { + if (Sym->Flags & SC_AUTO) { + AddTextLine ("\t.dbg\tsym, \"%s\", auto, %d", + Sym->Name, Sym->V.Offs); + } else if (Sym->Flags & SC_REGISTER) { + AddTextLine ("\t.dbg\tsym, \"%s\", register, %d", + Sym->Name, Sym->V.R.RegOffs); + + } else { + AddTextLine ("\t.dbg\tsym, \"%s\", %s, \"%s\"", + Sym->Name, + (Sym->Flags & SC_EXTERN)? "extern" : "static", + Sym->AsmName); + } + } + Sym = Sym->NextSym; + } +} + + + /*****************************************************************************/ -/* code */ +/* code */ /*****************************************************************************/ @@ -555,6 +592,9 @@ void NewFunc (SymEntry* Func) /* Emit references to imports/exports */ EmitExternals (); + /* Emit function debug info */ + EmitDebugInfo (); + /* Leave the lexical level */ LeaveFunctionLevel (); -- 2.39.5