1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 05:29:30 +00:00

Parse csym lines in the debug info file. No api functions til now.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5289 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-08-30 13:19:28 +00:00
parent 1157cff1bd
commit f204ec956a
2 changed files with 338 additions and 7 deletions

View File

@ -128,10 +128,12 @@ typedef enum {
TOK_ADDRSIZE, /* ADDRSIZE keyword */
TOK_AUTO, /* AUTO keyword */
TOK_COUNT, /* COUNT keyword */
TOK_CSYM, /* CSYM keyword */
TOK_DEF, /* DEF keyword */
TOK_ENUM, /* ENUM keyword */
TOK_EQUATE, /* EQUATE keyword */
TOK_EXPORT, /* EXPORT keyword */
TOK_EXTERN, /* EXTERN keyword */
TOK_FILE, /* FILE keyword */
TOK_FUNC, /* FUNC keyword */
TOK_GLOBAL, /* GLOBAL keyword */
@ -147,12 +149,15 @@ typedef enum {
TOK_MODULE, /* MODULE keyword */
TOK_MTIME, /* MTIME keyword */
TOK_NAME, /* NAME keyword */
TOK_OFFS, /* OFFS keyword */
TOK_OUTPUTNAME, /* OUTPUTNAME keyword */
TOK_OUTPUTOFFS, /* OUTPUTOFFS keyword */
TOK_PARENT, /* PARENT keyword */
TOK_REF, /* REF keyword */
TOK_REGISTER, /* REGISTER keyword */
TOK_RO, /* RO keyword */
TOK_RW, /* RW keyword */
TOK_SC, /* SC keyword */
TOK_SCOPE, /* SCOPE keyword */
TOK_SEGMENT, /* SEGMENT keyword */
TOK_SIZE, /* SIZE keyword */
@ -182,6 +187,7 @@ struct DbgInfo {
* The collections are also used when the objects are deleted, so they're
* actually the ones that "own" the items.
*/
Collection CSymInfoById; /* C symbol infos sorted by id */
Collection FileInfoById; /* File infos sorted by id */
Collection LibInfoById; /* Library infos sorted by id */
Collection LineInfoById; /* Line infos sorted by id */
@ -229,6 +235,7 @@ struct InputData {
};
/* Typedefs for the item structures. Do also serve as forwards */
typedef struct CSymInfo CSymInfo;
typedef struct FileInfo FileInfo;
typedef struct LibInfo LibInfo;
typedef struct LineInfo LineInfo;
@ -239,6 +246,27 @@ typedef struct SpanInfo SpanInfo;
typedef struct SymInfo SymInfo;
typedef struct TypeInfo TypeInfo;
/* Internally used c symbol info struct */
struct CSymInfo {
unsigned Id; /* Id of file */
unsigned short Kind; /* Kind of C symbol */
unsigned short SC; /* Storage class of C symbol */
int Offs; /* Offset */
union {
unsigned Id; /* Id of attached asm symbol */
SymInfo* Info; /* Pointer to attached asm symbol */
} Sym;
union {
unsigned Id; /* Id of type */
TypeInfo* Info; /* Pointer to type */
} Type;
union {
unsigned Id; /* Id of scope */
ScopeInfo* Info; /* Pointer to scope */
} Scope;
char Name[1]; /* Name of file with full path */
};
/* Internally used file info struct */
struct FileInfo {
unsigned Id; /* Id of file */
@ -1135,6 +1163,46 @@ static void UnknownKeyword (InputData* D)
/*****************************************************************************/
/* C symbol info */
/*****************************************************************************/
static CSymInfo* NewCSymInfo (const StrBuf* Name)
/* Create a new CSymInfo struct and return it */
{
/* Allocate memory */
CSymInfo* S = xmalloc (sizeof (CSymInfo) + SB_GetLen (Name));
/* Initialize it */
memcpy (S->Name, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
/* Return it */
return S;
}
static void FreeCSymInfo (CSymInfo* S)
/* Free a CSymInfo struct */
{
/* Free the structure itself */
xfree (S);
}
static int CompareCSymInfoByName (const void* L, const void* R)
/* Helper function to sort c symbol infos in a collection by name */
{
/* Sort by symbol name */
return strcmp (((const CSymInfo*) L)->Name,
((const CSymInfo*) R)->Name);
}
/*****************************************************************************/
/* File info */
/*****************************************************************************/
@ -2286,6 +2354,7 @@ static DbgInfo* NewDbgInfo (const char* FileName)
DbgInfo* Info = xmalloc (sizeof (DbgInfo) + Len);
/* Initialize it */
CollInit (&Info->CSymInfoById);
CollInit (&Info->FileInfoById);
CollInit (&Info->LibInfoById);
CollInit (&Info->LineInfoById);
@ -2322,6 +2391,9 @@ static void FreeDbgInfo (DbgInfo* Info)
unsigned I;
/* First, free the items in the collections */
for (I = 0; I < CollCount (&Info->CSymInfoById); ++I) {
FreeCSymInfo (CollAt (&Info->CSymInfoById, I));
}
for (I = 0; I < CollCount (&Info->FileInfoById); ++I) {
FreeFileInfo (CollAt (&Info->FileInfoById, I));
}
@ -2351,6 +2423,7 @@ static void FreeDbgInfo (DbgInfo* Info)
}
/* Free the memory used by the id collections */
CollDone (&Info->CSymInfoById);
CollDone (&Info->FileInfoById);
CollDone (&Info->LibInfoById);
CollDone (&Info->LineInfoById);
@ -2425,10 +2498,12 @@ static void NextToken (InputData* D)
{ "addrsize", TOK_ADDRSIZE },
{ "auto", TOK_AUTO },
{ "count", TOK_COUNT },
{ "csym", TOK_CSYM },
{ "def", TOK_DEF },
{ "enum", TOK_ENUM },
{ "equ", TOK_EQUATE },
{ "exp", TOK_EXPORT },
{ "ext", TOK_EXTERN },
{ "file", TOK_FILE },
{ "func", TOK_FUNC },
{ "global", TOK_GLOBAL },
@ -2444,12 +2519,15 @@ static void NextToken (InputData* D)
{ "mod", TOK_MODULE },
{ "mtime", TOK_MTIME },
{ "name", TOK_NAME },
{ "offs", TOK_OFFS },
{ "oname", TOK_OUTPUTNAME },
{ "ooffs", TOK_OUTPUTOFFS },
{ "parent", TOK_PARENT },
{ "ref", TOK_REF },
{ "reg", TOK_REGISTER },
{ "ro", TOK_RO },
{ "rw", TOK_RW },
{ "sc", TOK_SC },
{ "scope", TOK_SCOPE },
{ "seg", TOK_SEGMENT },
{ "size", TOK_SIZE },
@ -2660,6 +2738,196 @@ static void ConsumeEOL (InputData* D)
static void ParseCSym (InputData* D)
/* Parse a CSYM line */
{
/* Most of the following variables are initialized with a value that is
* overwritten later. This is just to avoid compiler warnings.
*/
unsigned Id = 0;
StrBuf Name = STRBUF_INITIALIZER;
int Offs = 0;
cc65_csym_sc SC = CC65_CSYM_AUTO;
unsigned ScopeId = 0;
unsigned SymId = CC65_INV_ID;
unsigned TypeId = CC65_INV_ID;
CSymInfo* S;
enum {
ibNone = 0x0000,
ibId = 0x0001,
ibOffs = 0x0002,
ibName = 0x0004,
ibSC = 0x0008,
ibScopeId = 0x0010,
ibSymId = 0x0020,
ibType = 0x0040,
ibRequired = ibId | ibName | ibSC | ibScopeId | ibType,
} InfoBits = ibNone;
/* Skip the CSYM token */
NextToken (D);
/* More stuff follows */
while (1) {
Token Tok;
/* Something we know? */
if (D->Tok != TOK_ID && D->Tok != TOK_NAME &&
D->Tok != TOK_OFFS && D->Tok != TOK_SC &&
D->Tok != TOK_SCOPE && D->Tok != TOK_SYM &&
D->Tok != TOK_TYPE) {
/* Try smart error recovery */
if (D->Tok == TOK_IDENT || TokenIsKeyword (D->Tok)) {
UnknownKeyword (D);
continue;
}
/* Done */
break;
}
/* Remember the token, skip it, check for equal */
Tok = D->Tok;
NextToken (D);
if (!ConsumeEqual (D)) {
goto ErrorExit;
}
/* Check what the token was */
switch (Tok) {
case TOK_ID:
if (!IntConstFollows (D)) {
goto ErrorExit;
}
Id = D->IVal;
NextToken (D);
InfoBits |= ibId;
break;
case TOK_NAME:
if (!StrConstFollows (D)) {
goto ErrorExit;
}
SB_Copy (&Name, &D->SVal);
SB_Terminate (&Name);
InfoBits |= ibName;
NextToken (D);
break;
case TOK_OFFS:
Offs = 1;
if (D->Tok == TOK_MINUS) {
Offs = -1;
NextToken (D);
}
if (!IntConstFollows (D)) {
goto ErrorExit;
}
Offs *= (int) D->IVal;
InfoBits |= ibOffs;
NextToken (D);
break;
case TOK_SC:
switch (D->Tok) {
case TOK_AUTO: SC = CC65_CSYM_AUTO; break;
case TOK_EXTERN: SC = CC65_CSYM_EXTERN; break;
case TOK_REGISTER: SC = CC65_CSYM_REG; break;
case TOK_STATIC: SC = CC65_CSYM_STATIC; break;
default:
ParseError (D, CC65_ERROR, "Invalid storage class token");
break;
}
InfoBits |= ibSC;
NextToken (D);
break;
case TOK_SCOPE:
if (!IntConstFollows (D)) {
goto ErrorExit;
}
ScopeId = D->IVal;
NextToken (D);
InfoBits |= ibScopeId;
break;
case TOK_SYM:
if (!IntConstFollows (D)) {
goto ErrorExit;
}
SymId = D->IVal;
NextToken (D);
InfoBits |= ibSymId;
break;
case TOK_TYPE:
if (!IntConstFollows (D)) {
goto ErrorExit;
}
TypeId = D->IVal;
NextToken (D);
InfoBits |= ibType;
break;
default:
/* NOTREACHED */
UnexpectedToken (D);
goto ErrorExit;
}
/* Comma or done */
if (D->Tok != TOK_COMMA) {
break;
}
NextToken (D);
}
/* Check for end of line */
if (D->Tok != TOK_EOL && D->Tok != TOK_EOF) {
UnexpectedToken (D);
SkipLine (D);
goto ErrorExit;
}
/* Check for required and/or matched information */
if ((InfoBits & ibRequired) != ibRequired) {
ParseError (D, CC65_ERROR, "Required attributes missing");
goto ErrorExit;
}
/* Symbol only valid if storage class not auto */
if (((InfoBits & ibSymId) != 0) != (SC != CC65_CSYM_AUTO)) {
ParseError (D, CC65_ERROR, "Only non auto symbols can have a symbol attached");
goto ErrorExit;
}
/* Create the symbol info */
S = NewCSymInfo (&Name);
S->Id = Id;
S->Kind = CC65_CSYM_VAR;
S->SC = SC;
S->Offs = Offs;
S->Sym.Id = SymId;
S->Type.Id = TypeId;
S->Scope.Id = ScopeId;
/* Remember it */
CollReplaceExpand (&D->Info->CSymInfoById, S, Id);
ErrorExit:
/* Entry point in case of errors */
SB_Done (&Name);
return;
}
static void ParseFile (InputData* D)
/* Parse a FILE line */
{
@ -2821,11 +3089,11 @@ static void ParseInfo (InputData* D)
Token Tok;
/* Something we know? */
if (D->Tok != TOK_FILE && D->Tok != TOK_LIBRARY &&
D->Tok != TOK_LINE && D->Tok != TOK_MODULE &&
D->Tok != TOK_SCOPE && D->Tok != TOK_SEGMENT &&
D->Tok != TOK_SPAN && D->Tok != TOK_SYM &&
D->Tok != TOK_TYPE) {
if (D->Tok != TOK_CSYM && D->Tok != TOK_FILE &&
D->Tok != TOK_LIBRARY && D->Tok != TOK_LINE &&
D->Tok != TOK_MODULE && D->Tok != TOK_SCOPE &&
D->Tok != TOK_SEGMENT && D->Tok != TOK_SPAN &&
D->Tok != TOK_SYM && D->Tok != TOK_TYPE) {
/* Try smart error recovery */
if (D->Tok == TOK_IDENT || TokenIsKeyword (D->Tok)) {
@ -2852,9 +3120,13 @@ static void ParseInfo (InputData* D)
/* Check what the token was */
switch (Tok) {
case TOK_CSYM:
CollGrow (&D->Info->CSymInfoById, D->IVal);
break;
case TOK_FILE:
CollGrow (&D->Info->FileInfoById, D->IVal);
CollGrow (&D->Info->FileInfoByName, D->IVal);
CollGrow (&D->Info->FileInfoByName, D->IVal);
break;
case TOK_LIBRARY:
@ -5219,6 +5491,10 @@ cc65_dbginfo cc65_read_dbginfo (const char* FileName, cc65_errorfunc ErrFunc)
switch (D.Tok) {
case TOK_CSYM:
ParseCSym (&D);
break;
case TOK_FILE:
ParseFile (&D);
break;

View File

@ -108,6 +108,61 @@ void cc65_free_dbginfo (cc65_dbginfo Handle);
/*****************************************************************************/
/* C Symbols */
/*****************************************************************************/
/* C symbol kinds */
typedef enum {
CC65_CSYM_FUNC,
CC65_CSYM_VAR
} cc65_csym_kind;
/* C object storage classes */
typedef enum {
CC65_CSYM_AUTO, /* Auto = on stack */
CC65_CSYM_REG, /* Register = in register bank */
CC65_CSYM_STATIC, /* Static = static storage */
CC65_CSYM_EXTERN /* Extern = static storage + external visibility */
} cc65_csym_sc;
/* C symbol information */
typedef struct cc65_csymdata cc65_csymdata;
struct cc65_csymdata {
unsigned csym_id; /* The internal c symbol id */
unsigned char csym_kind; /* Kind of c symbol */
unsigned char csym_sc; /* Storage class of c symbol */
int csym_offs; /* Offset for auto and register */
unsigned symbol_id; /* Attached asm symbol if any */
unsigned scope_id; /* Scope of c symbol */
const char* csym_name; /* Name of the symbol */
};
typedef struct cc65_csyminfo cc65_csyminfo;
struct cc65_csyminfo {
unsigned count; /* Number of data sets that follow */
cc65_csymdata data[1]; /* Data sets, number is dynamic */
};
const cc65_csyminfo* cc65_get_csymlist (cc65_dbginfo handle);
/* Return a list of all c symbols */
const cc65_csyminfo* cc65_csym_byid (cc65_dbginfo handle, unsigned id);
/* Return information about a c symbol with a specific id. The function
* returns NULL if the id is invalid (no such c symbol) and otherwise a
* cc65_csyminfo structure with one entry that contains the requested
* symbol information.
*/
void cc65_free_csyminfo (cc65_dbginfo handle, const cc65_csyminfo* info);
/* Free a c symbol info record */
/*****************************************************************************/
/* Libraries */
/*****************************************************************************/
@ -624,7 +679,7 @@ void cc65_free_typedata (cc65_dbginfo Handle, const cc65_typedata* data);
/* Allow usage from C++ */
#ifdef __cplusplus
#ifdef __cplusplus
}
#endif