]> git.sur5r.net Git - cc65/commitdiff
Parse csym lines in the debug info file. No api functions til now.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 30 Aug 2011 13:19:28 +0000 (13:19 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 30 Aug 2011 13:19:28 +0000 (13:19 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@5289 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/dbginfo/dbginfo.c
src/dbginfo/dbginfo.h

index d61949a39d9d9389d3951fd2b853b36d0886c1be..bf4c4480165c37d16be12c5476c710a925f32b36 100644 (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;
index c001cbcb8d96ab75d0a9e9e894757510ddd050ad..a2b8cf4ba66f542d67d06d3cb94b713cd855feb1 100644 (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