524 lines
12 KiB
C
524 lines
12 KiB
C
#include "common.h"
|
|
|
|
|
|
/*************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*************************************************************/
|
|
|
|
int cdbOpenFile (const char *file);
|
|
int cdbCloseFile (void);
|
|
int cdbWriteFunction (symbol *pSym, iCode *ic);
|
|
int cdbWriteEndFunction (symbol *pSym, iCode *ic, int offset);
|
|
int cdbWriteLabel (symbol *pSym, const iCode *ic);
|
|
int cdbWriteScope (iCode *ic);
|
|
int cdbWriteSymbol (symbol *pSym);
|
|
int cdbWriteType (structdef *sdef, int block, int inStruct, const char *tag);
|
|
int cdbWriteModule (const char *name);
|
|
int cdbWriteCLine (iCode *ic);
|
|
int cdbWriteALine (const char *module, int Line);
|
|
int cdbWriteFrameAddress (const char *variable, struct reg_info *reg, int offset);
|
|
int cdbWriteBasicSymbol (symbol *sym, int isStructSym, int isFunc);
|
|
void cdbTypeInfo (sym_link * type);
|
|
|
|
|
|
DEBUGFILE cdbDebugFile =
|
|
{
|
|
&cdbOpenFile,
|
|
&cdbCloseFile,
|
|
&cdbWriteModule,
|
|
&cdbWriteFunction,
|
|
&cdbWriteEndFunction,
|
|
&cdbWriteLabel,
|
|
&cdbWriteScope,
|
|
&cdbWriteSymbol,
|
|
&cdbWriteType,
|
|
&cdbWriteCLine,
|
|
&cdbWriteALine,
|
|
&cdbWriteFrameAddress
|
|
};
|
|
|
|
FILE *cdbFilePtr = NULL;
|
|
const char *cdbModuleName = NULL;
|
|
|
|
/******************************************************************
|
|
* spacesToUnderscores - replace all non alpha-numerics with
|
|
* underscores
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
static char *
|
|
spacesToUnderscores (char *dest, const char *src, size_t len)
|
|
{
|
|
unsigned int i;
|
|
char *p;
|
|
|
|
assert (dest != NULL);
|
|
assert (src != NULL);
|
|
assert (len > 0);
|
|
|
|
--len;
|
|
for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
|
|
*p++ = (isspace ((unsigned char)*src) || (*src == '-')) ? '_' : *src;
|
|
}
|
|
*p = '\0';
|
|
|
|
return dest;
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbOpenFile (const char *file)
|
|
{
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbOpenFile (%s)\n", file);
|
|
|
|
return (cdbFilePtr = fopen(file, "w")) ? 1 : 0;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
int
|
|
cdbCloseFile (void)
|
|
{
|
|
if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbCloseFile()\n");
|
|
|
|
if(!cdbFilePtr) return 0;
|
|
|
|
fclose(cdbFilePtr);
|
|
cdbFilePtr = NULL;
|
|
cdbModuleName = NULL;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteFunction (symbol *pSym, iCode *ic)
|
|
{
|
|
char debugSym[INITIAL_INLINEASM];
|
|
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteFunction()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
if (IS_STATIC (pSym->etype))
|
|
sprintf (debugSym, "F%s$%s$0$0", moduleName, pSym->name);
|
|
else
|
|
sprintf (debugSym, "G$%s$0$0", pSym->name);
|
|
emitDebuggerSymbol (debugSym);
|
|
|
|
return cdbWriteBasicSymbol (pSym, FALSE, TRUE);
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteEndFunction (symbol *pSym, iCode *ic, int offset)
|
|
{
|
|
char debugSym[INITIAL_INLINEASM];
|
|
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteEndFunction()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
if (ic)
|
|
{
|
|
sprintf (debugSym, "C$%s$%d$%ld_%ld$%d",
|
|
FileBaseName (ic->filename), pSym->lastLine,
|
|
ic->level / LEVEL_UNIT, ic->level % LEVEL_UNIT, ic->block);
|
|
spacesToUnderscores (debugSym, debugSym, sizeof (debugSym));
|
|
emitDebuggerSymbol (debugSym);
|
|
}
|
|
|
|
if (IS_STATIC (pSym->etype))
|
|
sprintf (debugSym, "XF%s$%s$0$0", moduleName, pSym->name);
|
|
else
|
|
sprintf (debugSym, "XG$%s$0$0", pSym->name);
|
|
emitDebuggerSymbol (debugSym);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteLabel (symbol *pSym, const iCode *ic)
|
|
{
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteLabel()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteScope (iCode *ic)
|
|
{
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteScope()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteSymbol(symbol *pSym)
|
|
{
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteSymbol()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
return cdbWriteBasicSymbol(pSym, FALSE, FALSE);
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteType (structdef *sdef, int block, int inStruct, const char *tag)
|
|
{
|
|
symbol *sym;
|
|
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteType()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
fprintf (cdbFilePtr, "T:");
|
|
|
|
/* if block # then must have function scope */
|
|
fprintf (cdbFilePtr, "F%s$", moduleName);
|
|
|
|
fprintf (cdbFilePtr, "%s[", (tag ? tag : sdef->tag));
|
|
|
|
for (sym = sdef->fields; sym; sym = sym->next)
|
|
{
|
|
fprintf (cdbFilePtr, "({%d}", sym->offset);
|
|
cdbWriteBasicSymbol (sym, TRUE, FALSE);
|
|
fprintf (cdbFilePtr, ")");
|
|
}
|
|
|
|
fprintf (cdbFilePtr, "]");
|
|
|
|
if (!inStruct)
|
|
fprintf (cdbFilePtr, "\n");
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteModule(const char *name)
|
|
{
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteModule()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
cdbModuleName = name;
|
|
|
|
fprintf(cdbFilePtr, "M:%s\n", cdbModuleName);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
int
|
|
cdbWriteCLine (iCode *ic)
|
|
{
|
|
char debugSym[INITIAL_INLINEASM];
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
sprintf (debugSym, "C$%s$%d$%ld_%ld$%d",
|
|
FileBaseName (ic->filename), ic->lineno,
|
|
ic->level / LEVEL_UNIT, ic->level % LEVEL_UNIT, ic->block);
|
|
spacesToUnderscores (debugSym, debugSym, sizeof (debugSym));
|
|
emitDebuggerSymbol (debugSym);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteALine (const char *module, int Line)
|
|
{
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteFrameAddress (const char *variable, struct reg_info *reg, int offset)
|
|
{
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteFrameAddress()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
int
|
|
cdbWriteBasicSymbol (symbol *sym, int isStructSym, int isFunc)
|
|
{
|
|
memmap *map;
|
|
symbol *sym2;
|
|
|
|
if (getenv ("SDCC_DEBUG_FUNCTION_POINTERS"))
|
|
fprintf (stderr, "cdbFile.c:cdbWriteBasicSymbol()\n");
|
|
|
|
if (!cdbFilePtr) return 0;
|
|
|
|
if (!sym) return 0;
|
|
|
|
/* WRITE HEADER, Function or Symbol */
|
|
if (isFunc)
|
|
fprintf (cdbFilePtr, "F:");
|
|
else
|
|
fprintf (cdbFilePtr, "S:");
|
|
|
|
/* STRUCTS do not have scope info.. */
|
|
|
|
if (!isStructSym)
|
|
{
|
|
if (sym->level && sym->localof) /* symbol is local */
|
|
{
|
|
fprintf (cdbFilePtr, "L%s.%s$", moduleName, sym->localof->name);
|
|
}
|
|
else if (IS_STATIC (sym->etype)) /* scope is file */
|
|
{
|
|
fprintf (cdbFilePtr, "F%s$", moduleName);
|
|
}
|
|
else /* scope is global */
|
|
{
|
|
fprintf (cdbFilePtr, "G$");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf (cdbFilePtr, "S$"); /* scope is structure */
|
|
}
|
|
|
|
/* print the name, & mangled name */
|
|
fprintf (cdbFilePtr, "%s$%ld_%ld$%d(", sym->name, sym->level / LEVEL_UNIT, sym->level % LEVEL_UNIT, sym->block);
|
|
|
|
cdbTypeInfo (sym->type);
|
|
|
|
fprintf (cdbFilePtr, "),");
|
|
|
|
/* CHECK FOR REGISTER SYMBOL... */
|
|
if (!sym->allocreq && sym->reqv)
|
|
{
|
|
int a;
|
|
symbol *TempSym = OP_SYMBOL (sym->reqv);
|
|
|
|
if (!TempSym->isspilt || TempSym->remat)
|
|
{
|
|
fprintf (cdbFilePtr, "R,0,0,[");
|
|
|
|
for (a = 0; a < 4; a++)
|
|
{
|
|
if (TempSym->regs[a])
|
|
{
|
|
fprintf (cdbFilePtr, "%s%s", port->getRegName(TempSym->regs[a]),
|
|
((a < 3) && (TempSym->regs[a+1])) ? "," : "");
|
|
}
|
|
}
|
|
|
|
fprintf (cdbFilePtr, "]");
|
|
sym2 = NULL;
|
|
}
|
|
else
|
|
{
|
|
sym2 = TempSym->usl.spillLoc;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sym2 = sym;
|
|
}
|
|
|
|
if (sym2)
|
|
{
|
|
/* print the address space */
|
|
map = SPEC_OCLS (sym2->etype);
|
|
|
|
fprintf (cdbFilePtr, "%c,%d,%d",
|
|
(map ? map->dbName : 'Z'), sym2->onStack, SPEC_STAK (sym2->etype));
|
|
}
|
|
|
|
/* if assigned to registers then output register names */
|
|
/* if this is a function then print
|
|
if is it an interrupt routine & interrupt number
|
|
and the register bank it is using */
|
|
if (isFunc)
|
|
fprintf (cdbFilePtr, ",%d,%d,%d", FUNC_ISISR (sym->type),
|
|
FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
|
|
|
|
/* alternate location to find this symbol @ : eg registers
|
|
or spillocation */
|
|
|
|
if (!isStructSym)
|
|
fprintf (cdbFilePtr, "\n");
|
|
|
|
return 1;
|
|
}
|
|
|
|
/******************************************************************
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*****************************************************************/
|
|
|
|
/*-----------------------------------------------------------------*/
|
|
/* cdbTypeInfo - print the type information for debugger */
|
|
/*-----------------------------------------------------------------*/
|
|
void
|
|
cdbTypeInfo (sym_link * type)
|
|
{
|
|
fprintf (cdbFilePtr, "{%d}", getSize (type));
|
|
|
|
while (type)
|
|
{
|
|
if (IS_DECL (type))
|
|
{
|
|
switch (DCL_TYPE (type))
|
|
{
|
|
case FUNCTION: fprintf (cdbFilePtr, "DF,"); break;
|
|
case GPOINTER: fprintf (cdbFilePtr, "DG,"); break;
|
|
case CPOINTER: fprintf (cdbFilePtr, "DC,"); break;
|
|
case FPOINTER: fprintf (cdbFilePtr, "DX,"); break;
|
|
case POINTER: fprintf (cdbFilePtr, "DD,"); break;
|
|
case IPOINTER: fprintf (cdbFilePtr, "DI,"); break;
|
|
case PPOINTER: fprintf (cdbFilePtr, "DP,"); break;
|
|
case EEPPOINTER: fprintf (cdbFilePtr, "DA,"); break;
|
|
case ARRAY: fprintf (cdbFilePtr, "DA%ud,", (unsigned int) DCL_ELEM (type)); break;
|
|
default: break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (SPEC_NOUN (type))
|
|
{
|
|
case V_INT:
|
|
if (IS_LONG (type))
|
|
fprintf (cdbFilePtr, "SL");
|
|
else
|
|
fprintf (cdbFilePtr, "SI");
|
|
break;
|
|
|
|
case V_CHAR: fprintf (cdbFilePtr, "SC"); break;
|
|
case V_VOID: fprintf (cdbFilePtr, "SV"); break;
|
|
case V_FLOAT: fprintf (cdbFilePtr, "SF"); break;
|
|
case V_FIXED16X16: fprintf(cdbFilePtr, "SQ"); break;
|
|
case V_STRUCT:
|
|
fprintf (cdbFilePtr, "ST%s", SPEC_STRUCT (type)->tag);
|
|
break;
|
|
|
|
case V_SBIT: fprintf (cdbFilePtr, "SX"); break;
|
|
case V_BIT:
|
|
case V_BITFIELD:
|
|
fprintf (cdbFilePtr, "SB%d$%d", SPEC_BSTR (type),
|
|
SPEC_BLEN (type));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
fputs (":", cdbFilePtr);
|
|
if (SPEC_USIGN (type))
|
|
fputs ("U", cdbFilePtr);
|
|
else
|
|
fputs ("S", cdbFilePtr);
|
|
}
|
|
type = type->next;
|
|
}
|
|
}
|