]> git.sur5r.net Git - cc65/commitdiff
Handle file position information for fragments differently: Instead of
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 30 Jul 2010 22:44:09 +0000 (22:44 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 30 Jul 2010 22:44:09 +0000 (22:44 +0000)
handling them separately (which has historic reasons), generate real line info
information. This means that line info for the assembler source will be part
of the debug info file.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4774 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ld65/fragment.c
src/ld65/fragment.h
src/ld65/lineinfo.c
src/ld65/lineinfo.h
src/ld65/objdata.c
src/ld65/segments.c

index 3f543b33d17f64212248d443b19cd3427368076d..c3f902c75a4e32f7d0cdc563dc4363e01fe90c06 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -40,6 +40,8 @@
 /* ld65 */
 #include "error.h"
 #include "fragment.h"
+#include "lineinfo.h"
+#include "objdata.h"
 #include "segments.h"
 
 
@@ -71,8 +73,7 @@ Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
     F->Obj       = 0;
     F->Size      = Size;
     F->Expr      = 0;
-    InitFilePos (&F->Pos);
-    F->LI        = 0;
+    F->LineInfos = EmptyCollection;
     F->Type      = Type;
 
     /* Insert the code fragment into the section */
@@ -96,3 +97,39 @@ Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
 
 
 
+void AddLineInfo (Fragment* F, LineInfo* LI)
+/* Add the line info to the given fragment */
+{
+    /* Point from the fragment to the line info ... */
+    CollAppend (&F->LineInfos, LI);
+
+    /* ... and back from the line info to the fragment */
+    CollAppend (&LI->Fragments, F);
+}
+
+
+
+const char* GetFragmentSourceName (const Fragment* F)
+/* Return the name of the source file for this fragment */
+{
+    /* Each fragment has the basic info in line info #0 */
+    const LineInfo* LI = CollConstAt (&F->LineInfos, 0);
+
+    /* Return the source file name */
+    return GetSourceFileName (F->Obj, LI->Pos.Name);
+}
+
+
+
+unsigned long GetFragmentSourceLine (const Fragment* F)
+/* Return the source file line for this fragment */
+{
+    /* Each fragment has the basic info in line info #0 */
+    const LineInfo* LI = CollConstAt (&F->LineInfos, 0);
+
+    /* Return the source file line */
+    return LI->Pos.Line;
+}
+
+
+
index d6a6233cb256acef899d6c6c4a5e604301d36102..94e40656b1f18637e8c802911cfa5917c3453ffc 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -39,6 +39,7 @@
 
 
 /* common */
+#include "coll.h"
 #include "filepos.h"
 
 
@@ -68,8 +69,7 @@ struct Fragment {
     struct ObjData*    Obj;            /* Source of fragment */
     unsigned            Size;                  /* Size of data/expression */
     struct ExprNode*   Expr;           /* Expression if FRAG_EXPR */
-    FilePos            Pos;            /* File position in source */
-    struct LineInfo*    LI;             /* Additional line info */
+    Collection          LineInfos;      /* Line info for this fragment */
     unsigned char      Type;           /* Type of fragment */
     unsigned char              LitBuf [1];     /* Dynamically alloc'ed literal buffer */
 };
@@ -85,6 +85,15 @@ struct Fragment {
 Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
 /* Create a new fragment and insert it into the section S */
 
+void AddLineInfo (Fragment* F, struct LineInfo* LI);
+/* Add the line info to the given fragment */
+
+const char* GetFragmentSourceName (const Fragment* F);
+/* Return the name of the source file for this fragment */
+
+unsigned long GetFragmentSourceLine (const Fragment* F);
+/* Return the source file line for this fragment */
+
 
 
 /* End of fragment.h */
index 2db2057821a3428e88025c26f51028709dfebd65..2cc4d86ac2a4754289e07bc3edbd4737a6591d2b 100644 (file)
@@ -40,6 +40,7 @@
 /* ld65 */
 #include "fileio.h"
 #include "fragment.h"
+#include "objdata.h"
 #include "segments.h"
 #include "lineinfo.h"
 
@@ -67,15 +68,18 @@ static CodeRange* NewCodeRange (unsigned long Offs, unsigned long Size)
 
 
 
-static LineInfo* NewLineInfo (void)
+LineInfo* NewLineInfo (ObjData* O, const FilePos* Pos)
 /* Create and return a new LineInfo struct */
 {
     /* Allocate memory */
     LineInfo* LI = xmalloc (sizeof (LineInfo));
 
+    /* Make sure the name index is valid */
+    CHECK (Pos->Name < CollCount (&O->Files));
+
     /* Initialize the fields */
-    LI->File = 0;
-    InitFilePos (&LI->Pos);
+    LI->File = CollAt (&O->Files, Pos->Name);
+    LI->Pos = *Pos;
     InitCollection (&LI->Fragments);
     InitCollection (&LI->CodeRanges);
 
@@ -88,18 +92,12 @@ static LineInfo* NewLineInfo (void)
 LineInfo* ReadLineInfo (FILE* F, ObjData* O)
 /* Read a line info from a file and return it */
 {
-    /* Allocate a new LineInfo struct and initialize it */
-    LineInfo* LI = NewLineInfo ();
-
     /* Read the file position */
-    ReadFilePos (F, &LI->Pos);
-
-    /* Resolve the file index to a pointer to FileInfo struct */
-    CHECK (LI->Pos.Name < CollCount (&O->Files));
-    LI->File = CollAt (&O->Files, LI->Pos.Name);
+    FilePos Pos;
+    ReadFilePos (F, &Pos);
 
-    /* Return the new LineInfo */
-    return LI;
+    /* Allocate a new LineInfo struct, initialize and return it */
+    return NewLineInfo (O, &Pos);
 }
 
 
@@ -168,11 +166,11 @@ void RelocLineInfo (Segment* S)
                Frag = Sec->FragRoot;
                while (Frag) {
 
-                   /* Add the range for this fragment to the line info if there
-                    * is any
-                    */
-                   if (Frag->LI) {
-                       AddCodeRange (Frag->LI, Offs, Frag->Size);
+            unsigned I;
+
+                   /* Add the range for this fragment to all line infos */
+            for (I = 0; I < CollCount (&Frag->LineInfos); ++I) {
+                       AddCodeRange (CollAt (&Frag->LineInfos, I), Offs, Frag->Size);
                    }
 
                    /* Update the offset */
index 6d02504af49a813b2ce902d3a15b62e20eb1468b..7ef66d6d42eb18b4eb3ba04c7e24a581cfa2fd9a 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2001      Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2001-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 
+#include <stdio.h>
+
 /* common */
 #include "coll.h"
 #include "filepos.h"
 
-/* ld65 */
-#include "objdata.h"
-
 
 
 /*****************************************************************************/
-/*                                Forwards                                  */
+/*                                Forwards                                  */
 /*****************************************************************************/
 
 
 
+struct ObjData;
 struct Segment;
 
 
@@ -87,7 +87,10 @@ struct LineInfo {
 
 
 
-LineInfo* ReadLineInfo (FILE* F, ObjData* O);
+LineInfo* NewLineInfo (struct ObjData* O, const FilePos* Pos);
+/* Create and return a new LineInfo struct */
+
+LineInfo* ReadLineInfo (FILE* F, struct ObjData* O);
 /* Read a line info from a file and return it */
 
 void RelocLineInfo (struct Segment* S);
index 3365b665f54365905a1f6f9367f0109ea0f1046b..ade6192a7e54c1d24e5b9f9aabad95bdb4bbdc42 100644 (file)
@@ -208,7 +208,7 @@ const char* GetSourceFileName (const ObjData* O, unsigned Index)
         } else {
 
             /* Get a pointer to the file info struct */
-            const FileInfo* FI = CollAt (&O->Files, Index);
+            const FileInfo* FI = CollConstAt (&O->Files, Index);
 
             /* Return the name */
             return GetString (FI->Name);
index 11943dc772c877e6d3150362d67027d185b5816a..ca99e44036f06c274c8dacc94b83990ff769f391 100644 (file)
@@ -203,6 +203,7 @@ Section* ReadSection (FILE* F, ObjData* O)
     unsigned      FragCount;
     Segment*      S;
     Section*      Sec;
+    LineInfo*     LI;
 
     /* Read the segment data */
     (void) Read32 (F);            /* File size of data */
@@ -231,9 +232,11 @@ Section* ReadSection (FILE* F, ObjData* O)
     }
 
     /* Start reading fragments from the file and insert them into the section . */
+    LI = 0;
     while (FragCount--) {
 
        Fragment* Frag;
+        FilePos   Pos;
        unsigned  LineInfoIndex;
 
        /* Read the fragment type */
@@ -270,24 +273,41 @@ Section* ReadSection (FILE* F, ObjData* O)
                }
 
        /* Read the file position of the fragment */
-       ReadFilePos (F, &Frag->Pos);
+       ReadFilePos (F, &Pos);
+
+        /* Generate a LineInfo for this fragment. First check if this fragment
+         * was generated by the same line than that before. If not, generate
+         * a new LineInfo.
+         */
+        if (LI == 0 || LI->Pos.Line != Pos.Line || LI->Pos.Col != Pos.Col ||
+            LI->Pos.Name != Pos.Name) {
+            /* We don't have a previous line info or this one is different */
+            LI = NewLineInfo (O, &Pos);
+            CollAppend (&O->LineInfos, LI);
+        }
+        AddLineInfo (Frag, LI);
 
        /* Read the additional line info and resolve it */
        LineInfoIndex = ReadVar (F);
        if (LineInfoIndex) {
            --LineInfoIndex;
-           if (LineInfoIndex >= CollCount (&O->LineInfos)) {
+            /* The line info index was written by the assembler and must
+             * therefore be part of the line infos read from the object file.
+             * To make sure this is true, don't compare against the count
+             * of line infos in the collection (which grows) but against the
+             * count initialized when reading from the file.
+             */
+           if (LineInfoIndex >= O->LineInfoCount) {
                        Internal ("In module `%s', file `%s', line %lu: Invalid line "
-                         "info with index %u (max count %u)",
-                         GetObjFileName (O),
-                         GetSourceFileName (O, Frag->Pos.Name),
-                                 Frag->Pos.Line, LineInfoIndex, 
-                          CollCount (&O->LineInfos));
+                         "info with index %u (max count %u)",
+                         GetObjFileName (O),
+                                 GetFragmentSourceName (Frag),
+                                 GetFragmentSourceLine (Frag),
+                          LineInfoIndex,
+                          O->LineInfoCount);
            }
-           /* Point from the fragment to the line info... */
-           Frag->LI = CollAt (&O->LineInfos, LineInfoIndex);
-           /* ...and back from the line info to the fragment */
-           CollAppend (&Frag->LI->Fragments, Frag);
+            /* Add line info to the fragment */
+            AddLineInfo (Frag, CollAt (&O->LineInfos, LineInfoIndex));
        }
 
        /* Remember the module we had this fragment from */
@@ -499,20 +519,20 @@ void SegWrite (FILE* Tgt, Segment* S, SegWriteFunc F, void* Data)
 
                        case SEG_EXPR_RANGE_ERROR:
                            Error ("Range error in module `%s', line %lu",
-                                  GetSourceFileName (Frag->Obj, Frag->Pos.Name),
-                                  Frag->Pos.Line);
+                                  GetFragmentSourceName (Frag),
+                                  GetFragmentSourceLine (Frag));
                            break;
 
                        case SEG_EXPR_TOO_COMPLEX:
                            Error ("Expression too complex in module `%s', line %lu",
-                                  GetSourceFileName (Frag->Obj, Frag->Pos.Name),
-                                  Frag->Pos.Line);
+                                  GetFragmentSourceName (Frag),
+                                  GetFragmentSourceLine (Frag));
                            break;
 
                        case SEG_EXPR_INVALID:
                            Error ("Invalid expression in module `%s', line %lu",
-                                  GetSourceFileName (Frag->Obj, Frag->Pos.Name),
-                                  Frag->Pos.Line);
+                                  GetFragmentSourceName (Frag),
+                                  GetFragmentSourceLine (Frag));
                            break;
 
                        default: