mirror of
https://github.com/cc65/cc65.git
synced 2025-08-10 04:25:21 +00:00
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
This commit is contained in:
@@ -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)
|
void DbgInfoLine (void)
|
||||||
/* Parse and handle LINE subcommand of the .dbg pseudo instruction */
|
/* Parse and handle LINE subcommand of the .dbg pseudo instruction */
|
||||||
{
|
{
|
||||||
@@ -158,7 +215,68 @@ void DbgInfoLine (void)
|
|||||||
void DbgInfoSym (void)
|
void DbgInfoSym (void)
|
||||||
/* Parse and handle SYM subcommand of the .dbg pseudo instruction */
|
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -47,6 +47,9 @@
|
|||||||
void DbgInfoFile (void);
|
void DbgInfoFile (void);
|
||||||
/* Parse and handle FILE subcommand of the .dbg pseudo instruction */
|
/* 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);
|
void DbgInfoLine (void);
|
||||||
/* Parse and handle LINE subcommand of the .dbg pseudo instruction */
|
/* Parse and handle LINE subcommand of the .dbg pseudo instruction */
|
||||||
|
|
||||||
|
@@ -753,6 +753,7 @@ static void DoDbg (void)
|
|||||||
{
|
{
|
||||||
static const char* Keys[] = {
|
static const char* Keys[] = {
|
||||||
"FILE",
|
"FILE",
|
||||||
|
"FUNC",
|
||||||
"LINE",
|
"LINE",
|
||||||
"SYM",
|
"SYM",
|
||||||
};
|
};
|
||||||
@@ -774,8 +775,9 @@ static void DoDbg (void)
|
|||||||
/* Check the key and dispatch to a handler */
|
/* Check the key and dispatch to a handler */
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
case 0: DbgInfoFile (); break;
|
case 0: DbgInfoFile (); break;
|
||||||
case 1: DbgInfoLine (); break;
|
case 1: DbgInfoFunc (); break;
|
||||||
case 2: DbgInfoSym (); break;
|
case 2: DbgInfoLine (); break;
|
||||||
|
case 3: DbgInfoSym (); break;
|
||||||
default: ErrorSkip ("Syntax error"); break;
|
default: ErrorSkip ("Syntax error"); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2009, Ullrich von Bassewitz */
|
/* (C) 2000-2011, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -47,7 +47,6 @@
|
|||||||
#include "litpool.h"
|
#include "litpool.h"
|
||||||
#include "locals.h"
|
#include "locals.h"
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "segments.h"
|
|
||||||
#include "stackptr.h"
|
#include "stackptr.h"
|
||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
#include "stmt.h"
|
#include "stmt.h"
|
||||||
@@ -74,7 +73,7 @@ typedef enum {
|
|||||||
struct Function {
|
struct Function {
|
||||||
struct SymEntry* FuncEntry; /* Symbol table entry */
|
struct SymEntry* FuncEntry; /* Symbol table entry */
|
||||||
Type* ReturnType; /* Function return type */
|
Type* ReturnType; /* Function return type */
|
||||||
struct FuncDesc* Desc; /* Function descriptor */
|
FuncDesc* Desc; /* Function descriptor */
|
||||||
int Reserved; /* Reserved local space */
|
int Reserved; /* Reserved local space */
|
||||||
unsigned RetLab; /* Return code label */
|
unsigned RetLab; /* Return code label */
|
||||||
int TopLevelSP; /* SP at function top level */
|
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 */
|
/* Emit references to imports/exports */
|
||||||
EmitExternals ();
|
EmitExternals ();
|
||||||
|
|
||||||
|
/* Emit function debug info */
|
||||||
|
EmitDebugInfo ();
|
||||||
|
|
||||||
/* Leave the lexical level */
|
/* Leave the lexical level */
|
||||||
LeaveFunctionLevel ();
|
LeaveFunctionLevel ();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user