]> git.sur5r.net Git - cc65/commitdiff
Read and allow access to the segment for (segment based) symbols.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 14 Jun 2011 21:18:44 +0000 (21:18 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 14 Jun 2011 21:18:44 +0000 (21:18 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@5063 b7a2c559-68d2-44c3-8de9-860c34a00d81

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

index 06a040cb4bedc74a29f4f6049503e67989aa510f..7865f53a46a09ad5a02c8ddb0eb5ac9b1bed4ddf 100644 (file)
@@ -224,6 +224,7 @@ struct SymInfo {
     cc65_symbol_type    Type;           /* Type of symbol */
     long                Value;          /* Value of symbol */
     cc65_size           Size;           /* Size of symbol */
+    unsigned            Segment;        /* Id of segment if any */
     char                SymName[1];     /* Name of symbol */
 };
 
@@ -1038,17 +1039,19 @@ static int CompareFileInfoById (const void* L, const void* R)
 
 
 
-static SymInfo* NewSymInfo (const StrBuf* Name, long Val,
-                            cc65_symbol_type Type, cc65_size Size)
+static SymInfo* NewSymInfo (const StrBuf* Name, long Val, 
+                            cc65_symbol_type Type, cc65_size Size,
+                            unsigned Segment)
 /* Create a new SymInfo struct, intialize and return it */
 {
     /* Allocate memory */
     SymInfo* S = xmalloc (sizeof (SymInfo) + SB_GetLen (Name));
 
     /* Initialize it */
-    S->Type  = Type;
-    S->Value = Val;
-    S->Size  = Size;
+    S->Type    = Type;
+    S->Value   = Val;
+    S->Size    = Size;
+    S->Segment = Segment;
     memcpy (S->SymName, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
 
     /* Return it */
@@ -1357,9 +1360,7 @@ static void FreeDbgInfo (DbgInfo* Info)
 
 
 static void CopyLineInfo (cc65_linedata* D, const LineInfo* L)
-/* Copy data from a LineInfo struct to the cc65_linedata struct returned to
- * the caller.
- */
+/* Copy data from a LineInfo struct to a cc65_linedata struct */
 {
     D->source_name  = L->File.Info->FileName;
     D->source_size  = L->File.Info->Size;
@@ -1380,15 +1381,38 @@ static void CopyLineInfo (cc65_linedata* D, const LineInfo* L)
 
 
 
+static void CopyFileInfo (cc65_sourcedata* D, const FileInfo* F)
+/* Copy data from a FileInfo struct to a cc65_sourcedata struct */
+{
+    D->id           = F->Id;
+    D->source_name  = F->FileName;
+    D->source_size  = F->Size;
+    D->source_mtime = F->MTime;
+}
+
+
+
+static void CopySegInfo (cc65_segmentdata* D, const SegInfo* S)
+/* Copy data from a SegInfo struct to a cc65_segmentdata struct */
+{
+    D->id            = S->Id;
+    D->segment_name  = S->SegName;
+    D->segment_start = S->Start;
+    D->segment_size  = S->Size;
+    D->output_name   = S->OutputName;
+    D->output_offs   = S->OutputOffs;
+}
+
+
+
 static void CopySymInfo (cc65_symboldata* D, const SymInfo* S)
-/* Copy data from a SymInfo struct to the cc65_symboldata struct returned to
- * the caller.
- */
+/* Copy data from a SymInfo struct to a cc65_symboldata struct */
 {
-    D->symbol_name  = S->SymName;
-    D->symbol_type  = S->Type;
-    D->symbol_size  = S->Size;
-    D->symbol_value = S->Value;
+    D->symbol_name    = S->SymName;
+    D->symbol_type    = S->Type;
+    D->symbol_size    = S->Size;
+    D->symbol_value   = S->Value;
+    D->symbol_segment = S->Segment;
 }
 
 
@@ -1459,7 +1483,7 @@ static void UnknownKeyword (InputData* D)
     /* Output a warning */
     ParseError (D, CC65_WARNING, "Unknown keyword \"%s\" - skipping",
                 SB_GetConstBuf (&D->SVal));
-
+                            
     /* Skip the identifier */
     NextToken (D);
 
@@ -2211,6 +2235,7 @@ static void ParseSym (InputData* D)
     long                Value;
     cc65_size           Size = 0;
     StrBuf              SymName = STRBUF_INITIALIZER;
+    unsigned            Segment = CC65_INV_ID;
     SymInfo*            S;
     enum {
         ibNone          = 0x00,
@@ -2234,8 +2259,8 @@ static void ParseSym (InputData* D)
 
         /* Something we know? */
         if (D->Tok != TOK_ADDRSIZE      && D->Tok != TOK_FILE   &&
-            D->Tok != TOK_NAME          && D->Tok != TOK_SEGMENT&& 
-            D->Tok != TOK_SIZE          && D->Tok != TOK_TYPE   && 
+            D->Tok != TOK_NAME          && D->Tok != TOK_SEGMENT&&
+            D->Tok != TOK_SIZE          && D->Tok != TOK_TYPE   &&
             D->Tok != TOK_VALUE) {
 
             /* Try smart error recovery */
@@ -2286,7 +2311,7 @@ static void ParseSym (InputData* D)
                 if (!IntConstFollows (D)) {
                     goto ErrorExit;
                 }
-                /* ### Drop value for now */
+                Segment = (unsigned) D->IVal;
                 InfoBits |= ibSegment;
                 NextToken (D);
                 break;
@@ -2355,7 +2380,7 @@ static void ParseSym (InputData* D)
     }
 
     /* Create the symbol info and remember it */
-    S = NewSymInfo (&SymName, Value, Type, Size);
+    S = NewSymInfo (&SymName, Value, Type, Size, Segment);
     CollAppend (&D->Info->SymInfoByName, S);
     CollAppend (&D->Info->SymInfoByVal, S);
 
@@ -2454,11 +2479,11 @@ ErrorExit:
 
 
 
-static SegInfo* FindSegInfoById (InputData* D, unsigned Id)
+static SegInfo* FindSegInfoById (DbgInfo* D, unsigned Id)
 /* Find the SegInfo with a given Id */
 {
     /* Get a pointer to the segment info collection */
-    Collection* SegInfos = &D->Info->SegInfoById;
+    Collection* SegInfos = &D->SegInfoById;
 
     /* Do a binary search */
     int Lo = 0;
@@ -2532,9 +2557,12 @@ static int FindFileInfoByName (Collection* FileInfos, const char* FileName,
 
 
 
-static FileInfo* FindFileInfoById (Collection* FileInfos, unsigned Id)
+static FileInfo* FindFileInfoById (DbgInfo* D, unsigned Id)
 /* Find the FileInfo with a given Id */
 {
+    /* Get a pointer to the collection */
+    Collection* FileInfos = &D->FileInfoById;
+
     /* Do a binary search */
     int Lo = 0;
     int Hi = (int) CollCount (FileInfos) - 1;
@@ -2637,7 +2665,7 @@ static void ProcessLineInfo (InputData* D)
         if (LastFileInfo && LastFileInfo->Id == L->File.Id) {
             F = LastFileInfo;
         } else {
-            F = FindFileInfoById (&D->Info->FileInfoById, L->File.Id);
+            F = FindFileInfoById (D->Info, L->File.Id);
 
             /* If we have no corresponding file info, print a warning and
              * remove the line info.
@@ -2665,7 +2693,7 @@ static void ProcessLineInfo (InputData* D)
         if (LastSegInfo && LastSegInfo->Id == L->Seg.Id) {
             S = LastSegInfo;
         } else {
-            S = FindSegInfoById (D, L->Seg.Id);
+            S = FindSegInfoById (D->Info, L->Seg.Id);
 
             /* If we have no corresponding segment info, print a warning and
              * remove the line info.
@@ -2884,7 +2912,7 @@ static int FindSymInfoByValue (Collection* SymInfos, long Value, unsigned* Index
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                             Debug info files                              */
 /*****************************************************************************/
 
 
@@ -3065,6 +3093,12 @@ void cc65_free_dbginfo (cc65_dbginfo Handle)
 
 
 
+/*****************************************************************************/
+/*                                 Line info                                 */
+/*****************************************************************************/
+
+
+
 cc65_lineinfo* cc65_lineinfo_byaddr (cc65_dbginfo Handle, unsigned long Addr)
 /* Return line information for the given address. The function returns 0
  * if no line information was found.
@@ -3187,6 +3221,12 @@ void cc65_free_lineinfo (cc65_dbginfo Handle, cc65_lineinfo* Info)
 
 
 
+/*****************************************************************************/
+/*                               Source files                                */
+/*****************************************************************************/
+
+
+
 cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo Handle)
 /* Return a list of all source files */
 {
@@ -3226,9 +3266,7 @@ cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo Handle)
         }
 
         /* Copy the data */
-        D->data[D->count].source_name  = F->FileName;
-        D->data[D->count].source_size  = F->Size;
-        D->data[D->count].source_mtime = F->MTime;
+        CopyFileInfo (D->data + D->count, F);
 
         /* One more valid entry */
         ++D->count;
@@ -3240,6 +3278,44 @@ cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo Handle)
 
 
 
+cc65_sourceinfo* cc65_sourceinfo_byid (cc65_dbginfo Handle, unsigned Id)
+/* Return information about a source file with a specific id. The function
+ * returns NULL if the id is invalid (no such source file) and otherwise a
+ * cc65_sourceinfo structure with one entry that contains the requested
+ * source file information.
+ */
+{
+    DbgInfo*            Info;
+    const FileInfo*     F;
+    cc65_sourceinfo*    D;
+
+    /* Check the parameter */
+    assert (Handle != 0);
+
+    /* The handle is actually a pointer to a debug info struct */
+    Info = (DbgInfo*) Handle;
+
+    /* Search for the Id */
+    F = FindFileInfoById (Info, Id);
+
+    /* If not found return NULL */
+    if (F == 0) {
+        return 0;
+    }
+
+    /* Allocate memory for the data structure returned to the caller */
+    D = new_cc65_sourceinfo (1);
+
+    /* Fill in the data */
+    CopyFileInfo (D->data, F);
+
+    /* Return the result */
+    return D;
+}
+
+
+
+
 void cc65_free_sourceinfo (cc65_dbginfo Handle, cc65_sourceinfo* Info)
 /* Free a source info record */
 {
@@ -3252,6 +3328,12 @@ void cc65_free_sourceinfo (cc65_dbginfo Handle, cc65_sourceinfo* Info)
 
 
 
+/*****************************************************************************/
+/*                                 Segments                                  */
+/*****************************************************************************/
+
+
+
 cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo Handle)
 /* Return a list of all segments referenced in the debug information */
 {
@@ -3275,18 +3357,46 @@ cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo Handle)
     /* Fill in the data */
     D->count = CollCount (SegInfoByName);
     for (I = 0; I < CollCount (SegInfoByName); ++I) {
+        /* Copy the data */
+        CopySegInfo (D->data + I, CollAt (SegInfoByName, I));
+    }
 
-        /* Get this item */
-        const SegInfo* S = CollAt (SegInfoByName, I);
+    /* Return the result */
+    return D;
+}
 
-        /* Copy the data */
-        D->data[I].segment_name  = S->SegName;
-        D->data[I].segment_start = S->Start;
-        D->data[I].segment_size  = S->Size;
-        D->data[I].output_name   = S->OutputName;
-        D->data[I].output_offs   = S->OutputOffs;
+
+
+cc65_segmentinfo* cc65_segmentinfo_byid (cc65_dbginfo Handle, unsigned Id)
+/* Return information about a segment with a specific id. The function returns
+ * NULL if the id is invalid (no such segment) and otherwise a segmentinfo
+ * structure with one entry that contains the requested segment information.
+ */
+{
+    DbgInfo*            Info;
+    const SegInfo*      S;
+    cc65_segmentinfo*   D;
+
+    /* Check the parameter */
+    assert (Handle != 0);
+
+    /* The handle is actually a pointer to a debug info struct */
+    Info = (DbgInfo*) Handle;
+
+    /* Search for the Id */
+    S = FindSegInfoById (Info, Id);
+
+    /* If not found return NULL */
+    if (S == 0) {
+        return 0;
     }
 
+    /* Allocate memory for the data structure returned to the caller */
+    D = new_cc65_segmentinfo (1);
+
+    /* Fill in the data */
+    CopySegInfo (D->data, S);
+
     /* Return the result */
     return D;
 }
@@ -3305,6 +3415,12 @@ void cc65_free_segmentinfo (cc65_dbginfo Handle, cc65_segmentinfo* Info)
 
 
 
+/*****************************************************************************/
+/*                                  Symbols                                  */
+/*****************************************************************************/
+
+
+
 cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo Handle, const char* Name)
 /* Return a list of symbols with a given name. The function returns NULL if
  * no symbol with this name was found.
index b4c6375e92b47fad5a98997ceaf7dfd3acdc1442..d63bd68b2a82f5be6377275c894b62c47092f117 100644 (file)
@@ -46,12 +46,12 @@ extern "C" {
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                          Data                                    */
 /*****************************************************************************/
 
 
 
-/* Data types used for addresses, sizes and line numbers. Change to "unsigned 
+/* Data types used for addresses, sizes and line numbers. Change to "unsigned
  * long" if you ever want to run the code on a 16-bit machine.
  */
 typedef unsigned cc65_line;             /* Used to store line numbers */
@@ -63,6 +63,9 @@ typedef unsigned cc65_size;             /* Used to store (65xx) sizes */
  */
 typedef void* cc65_dbginfo;
 
+/* A value that is used to mark invalid ids */
+#define CC65_INV_ID     (~0U)
+
 /* Severity for cc65_parseerror */
 typedef enum {
     CC65_WARNING,
@@ -120,6 +123,7 @@ struct cc65_lineinfo {
 /* Source file information */
 typedef struct cc65_sourcedata cc65_sourcedata;
 struct cc65_sourcedata {
+    unsigned            id;             /* The internal file id */
     const char*         source_name;    /* Name of the file */
     unsigned long       source_size;    /* Size of file */
     unsigned long       source_mtime;   /* Modification time */
@@ -140,6 +144,7 @@ struct cc65_sourceinfo {
  */
 typedef struct cc65_segmentdata cc65_segmentdata;
 struct cc65_segmentdata {
+    unsigned            id;             /* The internal segment id */
     const char*         segment_name;   /* Name of the segment */
     cc65_addr           segment_start;  /* Start address of segment */
     cc65_addr           segment_size;   /* Size of segment */
@@ -165,6 +170,10 @@ struct cc65_symboldata {
     cc65_symbol_type    symbol_type;    /* Type of symbol */
     cc65_size           symbol_size;    /* Size of symbol, 0 if unknown */
     long                symbol_value;   /* Value of symbol */
+    unsigned            symbol_segment; /* If the symbol is segment relative,
+                                         * this contains the id of segment,
+                                         * otherwise CC65_INV_ID 
+                                         */
 };
 
 typedef struct cc65_symbolinfo cc65_symbolinfo;
@@ -176,7 +185,7 @@ struct cc65_symbolinfo {
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                             Debug info files                              */
 /*****************************************************************************/
 
 
@@ -192,6 +201,14 @@ cc65_dbginfo cc65_read_dbginfo (const char* filename, cc65_errorfunc errorfunc);
 void cc65_free_dbginfo (cc65_dbginfo Handle);
 /* Free debug information read from a file */
 
+
+
+/*****************************************************************************/
+/*                                 Line info                                 */
+/*****************************************************************************/
+
+
+
 cc65_lineinfo* cc65_lineinfo_byaddr (cc65_dbginfo handle, unsigned long addr);
 /* Return line information for the given address. The function returns NULL
  * if no line information was found.
@@ -206,18 +223,55 @@ cc65_lineinfo* cc65_lineinfo_byname (cc65_dbginfo handle, const char* filename,
 void cc65_free_lineinfo (cc65_dbginfo handle, cc65_lineinfo* info);
 /* Free line info returned by one of the other functions */
 
+
+
+/*****************************************************************************/
+/*                               Source files                                */
+/*****************************************************************************/
+
+
+
 cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo handle);
 /* Return a list of all source files */
 
+cc65_sourceinfo* cc65_sourceinfo_byid (cc65_dbginfo handle, unsigned id);
+/* Return information about a source file with a specific id. The function
+ * returns NULL if the id is invalid (no such source file) and otherwise a
+ * cc65_sourceinfo structure with one entry that contains the requested
+ * source file information.
+ */
+
 void cc65_free_sourceinfo (cc65_dbginfo handle, cc65_sourceinfo* info);
 /* Free a source info record */
 
+
+
+/*****************************************************************************/
+/*                                 Segments                                  */
+/*****************************************************************************/
+
+
+
 cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo handle);
 /* Return a list of all segments referenced in the debug information */
 
+cc65_segmentinfo* cc65_segmentinfo_byid (cc65_dbginfo handle, unsigned id);
+/* Return information about a segment with a specific id. The function returns
+ * NULL if the id is invalid (no such segment) and otherwise a cc65_segmentinfo
+ * structure with one entry that contains the requested segment information.
+ */
+
 void cc65_free_segmentinfo (cc65_dbginfo handle, cc65_segmentinfo* info);
 /* Free a segment info record */
 
+
+
+/*****************************************************************************/
+/*                                  Symbols                                  */
+/*****************************************************************************/
+
+
+
 cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo handle, const char* name);
 /* Return a list of symbols with a given name. The function returns NULL if
  * no symbol with this name was found.
index 9d7b7ad48f5feef1d530f08c02bbd9c2e42521f4..197816c1441f16d0e8dd0559defde721395f47e2 100644 (file)
 
 
 
+static cc65_dbginfo Info;
+
+
+
 static void ErrorFunc (const struct cc65_parseerror* E)
 /* Handle errors or warnings that occur while parsing a debug file */
 {
@@ -113,9 +117,20 @@ static void PrintLineData (const cc65_linedata* D)
 static void PrintSymbolData (const cc65_symboldata* D)
 /* Print the data for one symbol */
 {
-    printf ("  %-20s = %04lX (size %u)\n", 
-            D->symbol_name, 
+    char Segment[256] = { 0 };  /* Needs dynamic alloc ### */
+    if (D->symbol_segment != CC65_INV_ID) {
+        cc65_segmentinfo* I = cc65_segmentinfo_byid (Info, D->symbol_segment);
+        if (I && I->count == 1) {
+            sprintf (Segment, "segment=%s,", I->data[0].segment_name);
+            cc65_free_segmentinfo (Info, I);
+        }
+    }
+
+
+    printf ("  %-20s = %04lX (%ssize=%u)\n",
+            D->symbol_name,
             D->symbol_value,
+            Segment,
             D->symbol_size);
 }
 
@@ -176,7 +191,6 @@ static void PrintSymbolInfo (const cc65_symbolinfo* Symbols)
 int main (int argc, char** argv)
 {
     const char*         Input;
-    cc65_dbginfo        Info;
     cc65_sourceinfo*    Sources;
     cc65_segmentinfo*   Segments;
     cc65_lineinfo*      Lines;