]> git.sur5r.net Git - cc65/commitdiff
Read and manage additional line information for symbols.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 18 Aug 2011 16:27:18 +0000 (16:27 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 18 Aug 2011 16:27:18 +0000 (16:27 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@5215 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ld65/cfgexpr.c
src/ld65/config.c
src/ld65/dbgfile.c
src/ld65/dbgsyms.c
src/ld65/exports.c
src/ld65/exports.h
src/ld65/lineinfo.c
src/ld65/lineinfo.h

index 3057e054ca076670e99999428894e50602fa7437..17f9cb57d1dbb5ae109f80a2daf30d683382e2b2 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2005-2010, Ullrich von Bassewitz                                      */
+/* (C) 2005-2011, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -75,7 +75,7 @@ static ExprNode* Factor (void)
             } else {
                 N = NewExprNode (0, EXPR_SYMBOL);
                 N->V.Imp = InsertImport (GenImport (Name, ADDR_SIZE_ABS));
-                CollAppend (&N->V.Imp->LineInfos, GenLineInfo (&CfgErrorPos));
+                CollAppend (&N->V.Imp->RefLines, GenLineInfo (&CfgErrorPos));
             }
 
             /* Skip the symbol name */
index f3e6bf6a1c4c75a0f9d271e5e1b4d2c99ede114c..96baf392c2a18268c99adb7ee6c10635e77d65f3 100644 (file)
@@ -358,7 +358,7 @@ static SegDesc* NewSegDesc (unsigned Name)
 
 static void FreeSegDesc (SegDesc* S)
 /* Free a segment descriptor */
-{               
+{
     FreeLineInfo (S->LI);
     xfree (S);
 }
@@ -1418,7 +1418,7 @@ static void ParseSymbols (void)
                 AttrCheck (AttrFlags, atType, "TYPE");
                 /* Create the export */
                 Exp = CreateExprExport (Name, Value, AddrSize);
-                CollAppend (&Exp->LineInfos, GenLineInfo (&CfgErrorPos));
+                CollAppend (&Exp->DefLines, GenLineInfo (&CfgErrorPos));
                 break;
 
             case CfgSymImport:
@@ -1429,7 +1429,7 @@ static void ParseSymbols (void)
                 /* Generate the import */
                 Imp = InsertImport (GenImport (Name, AddrSize));
                 /* Remember the file position */
-                CollAppend (&Imp->LineInfos, GenLineInfo (&CfgErrorPos));
+                CollAppend (&Imp->DefLines, GenLineInfo (&CfgErrorPos));
                 break;
 
             case CfgSymWeak:
@@ -1679,7 +1679,7 @@ static void ProcessSymbols (void)
                 if ((E = FindExport (Sym->Name)) == 0 || IsUnresolvedExport (E)) {
                     /* The symbol is undefined, generate an export */
                     E = CreateExprExport (Sym->Name, Sym->Value, Sym->AddrSize);
-                    CollAppend (&E->LineInfos, Sym->LI);
+                    CollAppend (&E->DefLines, Sym->LI);
                 }
                 break;
 
@@ -1702,12 +1702,12 @@ static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
     /* Define the run address of the segment */
     SB_Printf (&Buf, "__%s_RUN__", GetString (S->Name));
     E = CreateMemoryExport (GetStrBufId (&Buf), S->Run, SegAddr - S->Run->Start);
-    CollAppend (&E->LineInfos, S->LI);
+    CollAppend (&E->DefLines, S->LI);
 
     /* Define the size of the segment */
     SB_Printf (&Buf, "__%s_SIZE__", GetString (S->Name));
     E = CreateConstExport (GetStrBufId (&Buf), S->Seg->Size);
-    CollAppend (&E->LineInfos, S->LI);
+    CollAppend (&E->DefLines, S->LI);
 
     S->Flags |= SF_RUN_DEF;
     SB_Done (&Buf);
@@ -1724,7 +1724,7 @@ static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr)
     /* Define the load address of the segment */
     SB_Printf (&Buf, "__%s_LOAD__", GetString (S->Name));
     E = CreateMemoryExport (GetStrBufId (&Buf), S->Load, SegAddr - S->Load->Start);
-    CollAppend (&E->LineInfos, S->LI);
+    CollAppend (&E->DefLines, S->LI);
 
     S->Flags |= SF_LOAD_DEF;
     SB_Done (&Buf);
@@ -1789,7 +1789,7 @@ unsigned CfgProcess (void)
             /* Define the start of the memory area */
            SB_Printf (&Buf, "__%s_START__", GetString (M->Name));
            E = CreateMemoryExport (GetStrBufId (&Buf), M, 0);
-            CollAppend (&E->LineInfos, M->LI);
+            CollAppend (&E->DefLines, M->LI);
 
             SB_Done (&Buf);
         }
@@ -1906,12 +1906,12 @@ unsigned CfgProcess (void)
             /* Define the size of the memory area */
            SB_Printf (&Buf, "__%s_SIZE__", GetString (M->Name));
            E = CreateConstExport (GetStrBufId (&Buf), M->Size);
-            CollAppend (&E->LineInfos, M->LI);
+            CollAppend (&E->DefLines, M->LI);
 
             /* Define the fill level of the memory area */
            SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name));
            E = CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
-            CollAppend (&E->LineInfos, M->LI);
+            CollAppend (&E->DefLines, M->LI);
 
             SB_Done (&Buf);
        }
index 1412d1b3f13a197ac8537b6715415a2f7d406e5c..5f56460b58e67aa70247d1dc849d647aa0193b5d 100644 (file)
@@ -66,9 +66,9 @@ static void AssignIds (void)
 {
     /* Walk over all modules */
     unsigned I;
-    unsigned SymBaseId   = 0;
     unsigned ScopeBaseId = 0;
     unsigned SpanBaseId  = 0;
+    unsigned SymBaseId   = 0;
     for (I = 0; I < CollCount (&ObjDataList); ++I) {
 
         /* Get this module */
@@ -78,18 +78,21 @@ static void AssignIds (void)
         O->Id = I;
 
         /* Assign base ids */
-        O->SymBaseId   = SymBaseId;
         O->ScopeBaseId = ScopeBaseId;
         O->SpanBaseId  = SpanBaseId;
+        O->SymBaseId   = SymBaseId;
 
         /* Bump the base ids */
-        SymBaseId     += CollCount (&O->DbgSyms);
         ScopeBaseId   += CollCount (&O->Scopes);
         SpanBaseId    += CollCount (&O->Spans);
+        SymBaseId     += CollCount (&O->DbgSyms);
     }
 
     /* Assign the ids to the file infos */
     AssignFileInfoIds ();
+
+    /* Assign the ids to line infos */
+    AssignLineInfoIds ();
 }
 
 
@@ -105,7 +108,7 @@ void CreateDbgFile (void)
 
     /* Output version information */
     fprintf (F, "version\tmajor=2,minor=0\n");
-                                               
+
     /* Output a line with the item numbers so the debug info module is able
      * to preallocate the required memory.
      */
index 50c9c654ce6d074ef03c91aaf5623a12df695f1f..7c018461b2b63c04a4816c95c7febc78b8e77820 100644 (file)
@@ -65,7 +65,8 @@ struct DbgSym {
     unsigned            Id;             /* Id of debug symbol */
     DbgSym*                    Next;           /* Pool linear list link */
     ObjData*                   Obj;            /* Object file that exports the name */
-    Collection          LineInfos;      /* Line infos of definition */
+    Collection          DefLines;       /* Line infos for definition */
+    Collection          RefLines;       /* Line infos for references */
     ExprNode*                  Expr;           /* Expression (0 if not def'd) */
     unsigned            Size;           /* Symbol size if any */
     unsigned            OwnerId;        /* Id of parent/owner */
@@ -99,7 +100,8 @@ static DbgSym* NewDbgSym (unsigned Id, unsigned Type, unsigned char AddrSize,
     D->Id         = Id;
     D->Next       = 0;
     D->Obj        = O;
-    D->LineInfos  = EmptyCollection;
+    D->DefLines   = EmptyCollection;
+    D->RefLines   = EmptyCollection;
     D->Expr              = 0;
     D->Size       = 0;
     D->OwnerId    = ~0U;
@@ -202,7 +204,8 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O, unsigned Id)
     }
 
     /* Last is the list of line infos for this symbol */
-    ReadLineInfoList (F, O, &D->LineInfos);
+    ReadLineInfoList (F, O, &D->DefLines);
+    ReadLineInfoList (F, O, &D->RefLines);
 
     /* Return the new DbgSym */
     return D;
@@ -273,6 +276,17 @@ void PrintDbgSyms (FILE* F)
                 fprintf (F, ",parent=%u", O->SymBaseId + S->OwnerId);
             }
 
+            /* Output line infos */
+            if (CollCount (&S->DefLines) > 0) {
+                unsigned K;
+                const LineInfo* LI = CollConstAt (&S->DefLines, 0);
+                fprintf (F, ",line=%u", LI->Id);
+                for (K = 1; K < CollCount (&S->DefLines); ++K) {
+                    LI = CollConstAt (&S->DefLines, K);
+                    fprintf (F, "+%u", LI->Id);
+                }
+            }
+
             /* If this is an import, output the id of the matching export.
              * If this is not an import, output its value and - if we have
              * it - the segment.
index e1571d782beab90b9216d22b2d2f701e7e0e2c06..405bf5407c03cff2535151ada249eefa5d417158 100644 (file)
@@ -108,7 +108,8 @@ static Import* NewImport (unsigned char AddrSize, ObjData* Obj)
     /* Initialize the fields */
     I->Next             = 0;
     I->Obj              = Obj;
-    I->LineInfos = EmptyCollection;
+    I->DefLines  = EmptyCollection;
+    I->RefLines  = EmptyCollection;
     I->Exp       = 0;
     I->Name      = INVALID_STRING_ID;
     I->Flags     = 0;
@@ -129,8 +130,9 @@ void FreeImport (Import* I)
     /* Safety */
     PRECONDITION ((I->Flags & IMP_INLIST) == 0);
 
-    /* Free the line info collection */
-    DoneCollection (&I->LineInfos);
+    /* Free the line info collections */
+    DoneCollection (&I->DefLines);
+    DoneCollection (&I->RefLines);
 
     /* Free the struct */
     xfree (I);
@@ -153,7 +155,8 @@ Import* ReadImport (FILE* F, ObjData* Obj)
     I->Name = MakeGlobalStringId (Obj, ReadVar (F));
 
     /* Read the line infos */
-    ReadLineInfoList (F, Obj, &I->LineInfos);
+    ReadLineInfoList (F, Obj, &I->DefLines);
+    ReadLineInfoList (F, Obj, &I->RefLines);
 
     /* Check the address size */
     if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
@@ -278,18 +281,12 @@ Import* InsertImport (Import* I)
 const LineInfo* GetImportPos (const Import* Imp)
 /* Return the basic line info of an import */
 {
-    unsigned I;
-
-    /* Search for a line info of LI_TYPE_ASM */
-    for (I = 0; I < CollCount (&Imp->LineInfos); ++I) {
-        const LineInfo* LI = CollConstAt (&Imp->LineInfos, I);
-        if (LI_GET_TYPE (LI->Type) == LI_TYPE_ASM) {
-            return LI;
-        }
+    /* Search in DefLines, then in RefLines */
+    const LineInfo* LI = GetAsmLineInfo (&Imp->DefLines);
+    if (LI == 0) {
+        LI = GetAsmLineInfo (&Imp->RefLines);
     }
-
-    /* Not found - return the one in slot zero */
-    return CollConstAt (&Imp->LineInfos, 0);
+    return LI;
 }
 
 
@@ -316,7 +313,8 @@ static Export* NewExport (unsigned Type, unsigned char AddrSize,
     E->ImpList   = 0;
     E->Expr             = 0;
     E->Size      = 0;
-    E->LineInfos = EmptyCollection;
+    E->DefLines  = EmptyCollection;
+    E->RefLines  = EmptyCollection;
     E->DbgSymId  = ~0U;
     E->Type             = Type | SYM_EXPORT;
     E->AddrSize  = AddrSize;
@@ -338,7 +336,8 @@ void FreeExport (Export* E)
     PRECONDITION ((E->Flags & EXP_INLIST) == 0);
 
     /* Free the line infos */
-    DoneCollection (&E->LineInfos);
+    DoneCollection (&E->DefLines);
+    DoneCollection (&E->RefLines);
 
     /* Free the export expression */
     FreeExpr (E->Expr);
@@ -402,8 +401,9 @@ Export* ReadExport (FILE* F, ObjData* O)
         E->Size = ReadVar (F);
     }
 
-    /* Last is the file position where the definition was done */
-    ReadLineInfoList (F, O, &E->LineInfos);
+    /* Last are the locations */
+    ReadLineInfoList (F, O, &E->DefLines);
+    ReadLineInfoList (F, O, &E->RefLines);
 
     /* Return the new export */
     return E;
@@ -488,8 +488,12 @@ void InsertExport (Export* E)
 const LineInfo* GetExportPos (const Export* E)
 /* Return the basic line info of an export */
 {
-    /* Source file position is always in slot zero */
-    return CollConstAt (&E->LineInfos, 0);
+    /* Search in DefLines, then in RefLines */
+    const LineInfo* LI = GetAsmLineInfo (&E->DefLines);
+    if (LI == 0) {
+        LI = GetAsmLineInfo (&E->RefLines);
+    }
+    return LI;
 }
 
 
index d71e5d53318f985612c10eb848ef93a4b557bc17..97315686595aaf47ab35821a1b2fcddd09a0dfa0 100644 (file)
@@ -64,7 +64,8 @@ typedef struct Import Import;
 struct Import {
     Import*            Next;           /* Single linked list */
     ObjData*           Obj;            /* Object file that imports the name */
-    Collection          LineInfos;      /* Line info of reference */
+    Collection          DefLines;       /* Line infos of definition */
+    Collection          RefLines;       /* Line infos of reference */
     struct Export*     Exp;            /* Matching export for this import */
     unsigned            Name;          /* Name if not in table */
     unsigned short      Flags;          /* Generic flags */
@@ -84,7 +85,8 @@ struct Export {
     Import*            ImpList;        /* List of imports for this symbol */
     ExprNode*                  Expr;           /* Expression (0 if not def'd) */
     unsigned            Size;           /* Size of the symbol if any */
-    Collection          LineInfos;      /* Line info of definition */
+    Collection          DefLines;       /* Line infos of definition */
+    Collection          RefLines;       /* Line infos of reference */
     unsigned            DbgSymId;       /* Id of debug symbol for this export */
     unsigned short      Type;          /* Type of export */
     unsigned short      AddrSize;       /* Address size of export */
index 1320c24efec7e4f3578a0e1f291e41aefb26c704..aa5d99741e87b9ea08bbbcbf2eb557f40be56d55 100644 (file)
@@ -61,6 +61,7 @@ static LineInfo* NewLineInfo (void)
     LineInfo* LI = xmalloc (sizeof (LineInfo));
 
     /* Initialize the fields */
+    LI->Id         = ~0U;
     LI->File       = 0;
     LI->Type       = LI_MAKE_TYPE (LI_TYPE_ASM, 0);
     LI->Pos.Name   = INVALID_STRING_ID;
@@ -155,13 +156,59 @@ void ReadLineInfoList (FILE* F, ObjData* O, Collection* LineInfos)
 
 
 
+const LineInfo* GetAsmLineInfo (const Collection* LineInfos)
+/* Find a line info of type LI_TYPE_ASM in the given collection and return it.
+ * Return NULL if no such line info was found.
+ */
+{
+    unsigned I;
+
+    /* Search for a line info of LI_TYPE_ASM */
+    for (I = 0; I < CollCount (LineInfos); ++I) {
+        const LineInfo* LI = CollConstAt (LineInfos, I);
+        if (LI_GET_TYPE (LI->Type) == LI_TYPE_ASM) {
+            return LI;
+        }
+    }
+
+    /* Not found */
+    return 0;
+}
+
+
+
+void AssignLineInfoIds (void)
+/* Assign the ids to the line infos */
+{
+    unsigned I, J;
+
+    /* Walk over all line infos */
+    unsigned Id = 0;
+    for (I = 0; I < CollCount (&ObjDataList); ++I) {
+
+        /* Get the object file */
+        ObjData* O = CollAtUnchecked (&ObjDataList, I);
+
+        /* Output the line infos */
+        for (J = 0; J < CollCount (&O->LineInfos); ++J) {
+
+            /* Get this line info */
+            LineInfo* LI = CollAtUnchecked (&O->LineInfos, J);
+
+            /* Assign the id */
+            LI->Id = Id++;
+        }
+    }
+}
+
+
+
 void PrintDbgLineInfo (FILE* F)
 /* Output the line infos to a debug info file */
 {
     unsigned I, J, K;
 
     /* Print line infos from all modules we have linked into the output file */
-    unsigned Id = 0;
     for (I = 0; I < CollCount (&ObjDataList); ++I) {
 
         /* Get the object file */
@@ -183,7 +230,7 @@ void PrintDbgLineInfo (FILE* F)
             /* Print the start of the line */
             fprintf (F,
                      "line\tid=%u,file=%u,line=%lu",
-                     Id++, LI->File->Id, GetSourceLine (LI));
+                     LI->Id, LI->File->Id, GetSourceLine (LI));
 
             /* Print type if not LI_TYPE_ASM and count if not zero */
             if (Type != LI_TYPE_ASM) {
index 54e40861ca250bc61d0cd946394f4eb3e729be9b..6a04a4a37aaee26354bad50a3c84a99b179fa3ee 100644 (file)
@@ -73,6 +73,7 @@ struct Segment;
  */
 typedef struct LineInfo LineInfo;
 struct LineInfo {
+    unsigned            Id;             /* Line info id */
     struct FileInfo*    File;          /* File struct for this line if any */
     unsigned            Type;           /* Type of line info */
     FilePos             Pos;            /* Position in file */
@@ -101,6 +102,11 @@ void ReadLineInfoList (FILE* F, struct ObjData* O, Collection* LineInfos);
  * make real line infos from them and place them into the passed collection.
  */
 
+const LineInfo* GetAsmLineInfo (const Collection* LineInfos);
+/* Find a line info of type LI_TYPE_ASM in the given collection and return it.
+ * Return NULL if no such line info was found.
+ */
+
 #if defined(HAVE_INLINE)
 INLINE const FilePos* GetSourcePos (const LineInfo* LI)
 /* Return the source file position from the given line info */
@@ -165,6 +171,9 @@ INLINE unsigned long GetSourceLineFromList (const Collection* LineInfos)
         GetSourceLine ((const LineInfo*) CollConstAt ((LineInfos), 0))
 #endif
 
+void AssignLineInfoIds (void);
+/* Assign the ids to the line infos */
+
 void PrintDbgLineInfo (FILE* F);
 /* Output the line infos to a debug info file */