]> git.sur5r.net Git - cc65/commitdiff
Write spans out in a separate object file section. This allows to merge
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 21 Aug 2011 19:08:23 +0000 (19:08 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 21 Aug 2011 19:08:23 +0000 (19:08 +0000)
duplicate spans in an object file and more extensions to come.

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

18 files changed:
src/ar65/objfile.c
src/ca65/lineinfo.c
src/ca65/main.c
src/ca65/objfile.c
src/ca65/objfile.h
src/ca65/span.c
src/ca65/span.h
src/ca65/symtab.c
src/common/objdefs.h
src/ld65/library.c
src/ld65/lineinfo.c
src/ld65/objfile.c
src/ld65/objfile.h
src/ld65/scopes.c
src/ld65/span.c
src/ld65/span.h
src/od65/dump.c
src/od65/fileio.c

index 1696ecc0c65753ac259e268c17e45287d16de9d5..43862cb93f5cf3f7e81bf5d51a4f7f3b4ee6a2a4 100644 (file)
@@ -116,6 +116,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
     H->AssertSize   = Read32 (Obj);
     H->ScopeOffs    = Read32 (Obj);
     H->ScopeSize    = Read32 (Obj);
+    H->SpanOffs     = Read32 (Obj);
+    H->SpanSize     = Read32 (Obj);
 }
 
 
index 50419c60e8dda19cca18c9e29979ae95139a0e3f..e17aa251da8ab6e62dade9e18443d053604a9374 100644 (file)
@@ -272,7 +272,7 @@ void EndLine (LineInfo* LI)
 /* End a line that is tracked by the given LineInfo structure */
 {
     /* Close the spans for the line */
-    CloseSpans (&LI->OpenSpans);
+    CloseSpanList (&LI->OpenSpans);
 
     /* Move the spans to the list of all spans for this line, then clear the
      * list of open spans.
@@ -308,7 +308,7 @@ LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count)
     }
 
     /* Open the spans for this line info */
-    OpenSpans (&LI->OpenSpans);
+    OpenSpanList (&LI->OpenSpans);
 
     /* Add the line info to the list of current line infos */
     CollAppend (&CurLineInfo, LI);
@@ -447,8 +447,6 @@ void WriteLineInfos (void)
 {
     unsigned I;
 
-    Collection EmptySpans = STATIC_COLLECTION_INITIALIZER;
-
     /* Tell the object file module that we're about to write line infos */
     ObjStartLineInfos ();
 
@@ -467,22 +465,12 @@ void WriteLineInfos (void)
         /* Write the type and count of the line info */
         ObjWriteVar (LI->Key.Type);
 
-        /* Spans are only added to the debug file if debug information is
-         * requested. Otherwise we write an empty list.
-         */
-        if (DbgSyms) {
-            WriteSpans (&LI->Spans);
-        } else {
-            /* Write out an empty list */
-            WriteSpans (&EmptySpans);
-        }
+        /* Write the ids of the spans for this line */
+        WriteSpanList (&LI->Spans);
     }
 
     /* End of line infos */
     ObjEndLineInfos ();
-
-    /* For the sake of completeness, but not really necessary */
-    DoneCollection (&EmptySpans);
 }
 
 
index 8dc77a38d28f856f2dd5035ef654d49497861d8a..240bf2ef2498c72c0777739234709aff3d54eadf 100644 (file)
@@ -72,6 +72,7 @@
 #include "scanner.h"
 #include "segment.h"
 #include "sizeof.h"
+#include "span.h"
 #include "spool.h"
 #include "symbol.h"
 #include "symtab.h"
@@ -561,7 +562,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
 
 
 static void OptVerbose (const char* Opt attribute ((unused)),
-                       const char* Arg attribute ((unused)))
+                       const char* Arg attribute ((unused)))
 /* Increase verbosity */
 {
     ++Verbosity;
@@ -822,6 +823,9 @@ static void CreateObjFile (void)
     /* Write the assertions */
     WriteAssertions ();
 
+    /* Write the spans */
+    WriteSpans ();
+
     /* Write an updated header and close the file */
     ObjClose ();
 }
@@ -950,7 +954,7 @@ int main (int argc, char* argv [])
                            break;
 
                        case 'V':
-                   OptVersion (Arg, 0);
+                   OptVersion (Arg, 0);
                            break;
 
                        case 'W':
index f9fba1521141de0c06e30920ad7acf52e4217392..199bc13c58c8e4259db11ccd470cff0a9f5826b6 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -86,6 +86,8 @@ static ObjHeader Header = {
     0,                  /* 32: Size of assertion table */
     0,                  /* 32: Offset into scope table */
     0,                  /* 32: Size of scope table */
+    0,                  /* 32: Offset into span table */
+    0,                  /* 32: Size of span table */
 };
 
 
@@ -142,6 +144,8 @@ static void ObjWriteHeader (void)
     ObjWrite32 (Header.AssertSize);
     ObjWrite32 (Header.ScopeOffs);
     ObjWrite32 (Header.ScopeSize);
+    ObjWrite32 (Header.SpanOffs);
+    ObjWrite32 (Header.SpanSize);
 }
 
 
@@ -304,7 +308,7 @@ void ObjWriteBuf (const StrBuf* S)
      * advance).
      */
     ObjWriteVar (SB_GetLen (S));
-    ObjWriteData (SB_GetConstBuf (S), SB_GetLen (S));    
+    ObjWriteData (SB_GetConstBuf (S), SB_GetLen (S));
 }
 
 
@@ -495,3 +499,19 @@ void ObjEndScopes (void)
 
 
 
+void ObjStartSpans (void)
+/* Mark the start of the span table */
+{
+    Header.SpanOffs = ftell (F);
+}
+
+
+
+void ObjEndSpans (void)
+/* Mark the end of the span table */
+{
+    Header.SpanSize = ftell (F) - Header.SpanOffs;
+}
+
+
+
index 3abcd7cf6ffe05291bc4b021d64f5075c88788e9..91987b3d953f8f4e1c4908df5be5cae9cb2b67be 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -149,6 +149,12 @@ void ObjStartScopes (void);
 void ObjEndScopes (void);
 /* Mark the end of the scope table */
 
+void ObjStartSpans (void);
+/* Mark the start of the span table */
+
+void ObjEndSpans (void);
+/* Mark the end of the span table */
+
 
 
 /* End of objfile.h */
index 3346eda0aca482fed4eb0c8fa85eb0d1c397c66f..2fa823a8ba686a6c313af21a95a2da1980f64f2c 100644 (file)
 
 
 /* common */
+#include "hashfunc.h"
+#include "hashtab.h"
 #include "xmalloc.h"
 
 /* ca65 */
+#include "global.h"
 #include "objfile.h"
 #include "segment.h"
 #include "span.h"
 
 
 
+/*****************************************************************************/
+/*                                 Forwards                                  */
+/*****************************************************************************/
+
+
+
+static unsigned HT_GenHash (const void* Key);
+/* Generate the hash over a key. */
+
+static const void* HT_GetKey (const void* Entry);
+/* Given a pointer to the user entry data, return a pointer to the key */
+
+static int HT_Compare (const void* Key1, const void* Key2);
+/* Compare two keys. The function must return a value less than zero if
+ * Key1 is smaller than Key2, zero if both are equal, and a value greater
+ * than zero if Key1 is greater then Key2.
+ */
+
+
+
 /*****************************************************************************/
 /*                                   Data                                    */
 /*****************************************************************************/
 
 
 
+/* Hash table functions */
+static const HashFunctions HashFunc = {
+    HT_GenHash,
+    HT_GetKey,
+    HT_Compare
+};
+
+/* Span hash table */
+static HashTable SpanTab = STATIC_HASHTABLE_INITIALIZER (1051, &HashFunc);
+
+
+
+/*****************************************************************************/
+/*                           Hash table functions                            */
+/*****************************************************************************/
+
+
+
+static unsigned HT_GenHash (const void* Key)
+/* Generate the hash over a key. */
+{
+    /* Key is a Span pointer */
+    const Span* S = Key;
+
+    /* Hash over a combination of segment number, start and end */
+    return HashInt ((S->Seg->Num << 28) ^ (S->Start << 14) ^ S->End);
+}
+
+
+
+static const void* HT_GetKey (const void* Entry)
+/* Given a pointer to the user entry data, return a pointer to the key */
+{
+    return Entry;
+}
+
+
+
+static int HT_Compare (const void* Key1, const void* Key2)
+/* Compare two keys. The function must return a value less than zero if
+ * Key1 is smaller than Key2, zero if both are equal, and a value greater
+ * than zero if Key1 is greater then Key2.
+ */
+{
+    /* Convert both parameters to Span pointers */
+    const Span* S1 = Key1;
+    const Span* S2 = Key2;
+
+    /* Compare segment number, then start and end */
+    int Res = (int)S2->Seg->Num - (int)S1->Seg->Num;
+    if (Res == 0) {
+        Res = (int)S2->Start - (int)S1->Start;
+        if (Res == 0) {
+            Res = (int)S2->End - (int)S1->End;
+        }
+    }
+
+    /* Done */
+    return Res;
+}
+
+
+
 /*****************************************************************************/
 /*                                   Code                                    */
 /*****************************************************************************/
@@ -64,9 +150,12 @@ static Span* NewSpan (Segment* Seg, unsigned long Start, unsigned long End)
     Span* S = xmalloc (sizeof (Span));
 
     /* Initialize the struct */
+    InitHashNode (&S->Node);
+    S->Id       = ~0U;
     S->Seg      = Seg;
     S->Start    = Start;
     S->End      = End;
+    S->Type     = 0;
 
     /* Return the new struct */
     return S;
@@ -82,7 +171,68 @@ static void FreeSpan (Span* S)
 
 
 
-void OpenSpans (Collection* Spans)
+static Span* MergeSpan (Span* S)
+/* Check if we have a span with the same data as S already. If so, free S and
+ * return the already existing one. If not, remember S and return it.
+ */
+{
+    /* Check if we have such a span already. If so use the existing
+     * one and free the one from the collection. If not, add the one to
+     * the hash table and return it.
+     */
+    Span* E = HT_Find (&SpanTab, S);
+    if (E) {
+        /* If S has a type and E not, move the type */
+        CHECK (E->Type == 0);
+        E->Type = S->Type;
+        S->Type = 0;
+        /* Free S and return E */
+        FreeSpan (S);
+        return E;
+    } else {
+        /* Assign the id, insert S, then return it */
+        S->Id = HT_GetCount (&SpanTab);
+        HT_Insert (&SpanTab, S);
+        return S;
+    }
+}
+
+
+
+Span* OpenSpan (void)
+/* Open a span for the active segment and return it. */
+{
+    return NewSpan (ActiveSeg, ActiveSeg->PC, ActiveSeg->PC);
+}
+
+
+
+Span* CloseSpan (Span* S)
+/* Close the given span. Be sure to replace the passed span by the one
+ * returned, since the span will get deleted if it is empty or may be
+ * replaced if a duplicate exists.
+ */
+{
+    /* Set the end offset */
+    if (S->Start == S->Seg->PC) {
+        /* Span is empty */
+        FreeSpan (S);
+        return 0;
+    } else {
+        /* Span is not empty */
+        S->End = S->Seg->PC;
+
+        /* Check if we have such a span already. If so use the existing
+         * one and free the one from the collection. If not, add the one to
+         * the hash table and return it.
+         */
+        return MergeSpan (S);
+    }
+}
+
+
+
+void OpenSpanList (Collection* Spans)
 /* Open a list of spans for all existing segments to the given collection of
  * spans. The currently active segment will be inserted first with all others
  * following.
@@ -109,7 +259,7 @@ void OpenSpans (Collection* Spans)
 
 
 
-void CloseSpans (Collection* Spans)
+void CloseSpanList (Collection* Spans)
 /* Close a list of spans. This will add new segments to the list, mark the end
  * of existing ones, and remove empty spans from the list.
  */
@@ -141,7 +291,9 @@ void CloseSpans (Collection* Spans)
         } else {
             /* Span is not empty */
             S->End = S->Seg->PC;
-            CollReplace (Spans, S, J++);
+
+            /* Merge duplicate spans, then insert it at the new position */
+            CollReplace (Spans, MergeSpan (S), J++);
         }
     }
 
@@ -151,37 +303,96 @@ void CloseSpans (Collection* Spans)
 
 
 
-static void WriteSpan (const Span* S)
-/* Write one span to the output file */
+void WriteSpanList (const Collection* Spans)
+/* Write a list of spans to the output file */
 {
-    /* Done accept empty spans */
-    CHECK (S->End > S->Start);
+    unsigned I;
 
-    /* Write data for the span We will write the size instead of the end
-     * offset to save some bytes, since most spans are expected to be
-     * rather small.
-     */
-    ObjWriteVar (S->Seg->Num);
-    ObjWriteVar (S->Start);
-    ObjWriteVar (S->End - S->Start);
+    /* We only write spans if debug info is enabled */
+    if (DbgSyms == 0) {
+        /* Number of spans is zero */
+        ObjWriteVar (0);
+    } else {
+        /* Write the number of spans */
+        ObjWriteVar (CollCount (Spans));
+
+        /* Write the spans */
+        for (I = 0; I < CollCount (Spans); ++I) {
+            /* Write the id of the next span */
+            ObjWriteVar (((const Span*)CollConstAt (Spans, I))->Id);
+        }
+    }
 }
 
 
 
-void WriteSpans (const Collection* Spans)
-/* Write a list of spans to the output file */
+static int CollectSpans (void* Entry, void* Data)
+/* Collect all spans in a collection sorted by id */
 {
-    unsigned I;
+    /* Cast the pointers to real objects */
+    Span* S       = Entry;
+    Collection* C = Data;
+
+    /* Place the entry into the collection */
+    CollReplaceExpand (C, S, S->Id);
+
+    /* Keep the span */
+    return 0;
+}
+
+
+
+void WriteSpans (void)
+/* Write all spans to the object file */
+{
+    /* Tell the object file module that we're about to start the spans */
+    ObjStartSpans ();
+
+    /* We will write scopes only if debug symbols are requested */
+    if (DbgSyms) {
+
+        unsigned I;
 
-    /* Write the number of spans */
-    ObjWriteVar (CollCount (Spans));
+        /* We must first collect all items in a collection sorted by id */
+        Collection SpanList = STATIC_COLLECTION_INITIALIZER;
+        CollGrow (&SpanList, HT_GetCount (&SpanTab));
+
+        /* Walk over the hash table and fill the span list */
+        HT_Walk (&SpanTab, CollectSpans, &SpanList);
+
+        /* Write the span count to the file */
+        ObjWriteVar (CollCount (&SpanList));
+
+        /* Write all spans */
+        for (I = 0; I < CollCount (&SpanList); ++I) {
+
+            /* Get the span and check it */
+            const Span* S = CollAtUnchecked (&SpanList, I);
+            CHECK (S->End > S->Start);
+
+            /* Write data for the span We will write the size instead of the
+             * end offset to save some bytes, since most spans are expected
+             * to be rather small.
+             */
+            ObjWriteVar (S->Seg->Num);
+            ObjWriteVar (S->Start);
+            ObjWriteVar (S->End - S->Start);
+        }
+
+        /* Free the collection with the spans */
+        DoneCollection (&SpanList);
+
+    } else {
+
+        /* No debug info requested */
+        ObjWriteVar (0);
 
-    /* Write the spans */
-    for (I = 0; I < CollCount (Spans); ++I) {
-        /* Write the next span */
-        WriteSpan (CollConstAt (Spans, I));
     }
+
+    /* Done writing the spans */
+    ObjEndSpans ();
 }
 
 
 
+
index 04af807a28154a14d6fa887ed41e3a9515aa182f..a1b85b2dc2175c261d8ad4107cf5f63782ea6e9a 100644 (file)
 
 /* common */
 #include "coll.h"
+#include "gentype.h"
+#include "hashtab.h"
 #include "inline.h"
 
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                  Data                                    */
 /*****************************************************************************/
 
 
@@ -56,9 +58,12 @@ struct Segment;
 /* Span definition */
 typedef struct Span Span;
 struct Span{
+    HashNode        Node;               /* Node for hash table */
+    unsigned        Id;                 /* Id of span */
     struct Segment* Seg;                       /* Pointer to segment */
-    unsigned long   Start;              /* Start of range */
-    unsigned long   End;                /* End of range */
+    unsigned        Start;              /* Start of range */
+    unsigned        End;                /* End of range */
+    unsigned        Type;               /* Type of data in span */
 };
 
 
@@ -79,18 +84,30 @@ INLINE unsigned long GetSpanSize (const Span* R)
 #  define GetSpanSize(R)   ((R)->End - (R)->Start)
 #endif
 
-void OpenSpans (Collection* Spans);
+Span* OpenSpan (void);
+/* Open a span for the active segment and return it. */
+
+Span* CloseSpan (Span* S);
+/* Close the given span. Be sure to replace the passed span by the one
+ * returned, since the span will get deleted if it is empty or may be
+ * replaced if a duplicate exists.
+ */
+
+void OpenSpanList (Collection* Spans);
 /* Open a list of spans for all existing segments to the given collection of
  * spans. The currently active segment will be inserted first with all others
  * following.
  */
 
-void CloseSpans (Collection* Spans);
+void CloseSpanList (Collection* Spans);
 /* Close all open spans by setting PC to the current PC for the segment. */
 
-void WriteSpans (const Collection* Spans);
+void WriteSpanList (const Collection* Spans);
 /* Write a list of spans to the output file */
 
+void WriteSpans (void);
+/* Write all spans to the object file */
+
 
 
 /* End of span.h */
index bc64b03641512cb8302bc62727b7c7b19fa0208d..e0d6f830987ee6ce19e2404302b4265a5316e224 100644 (file)
@@ -235,7 +235,7 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type,
      * space in any segment).
      */
     if (CurrentScope->Type <= SCOPE_HAS_DATA) {
-        OpenSpans (&CurrentScope->Spans);
+        OpenSpanList (&CurrentScope->Spans);
     }
 }
 
@@ -248,7 +248,7 @@ void SymLeaveLevel (void)
      * open the spans.
      */
     if (CurrentScope->Type <= SCOPE_HAS_DATA) {
-        CloseSpans (&CurrentScope->Spans);
+        CloseSpanList (&CurrentScope->Spans);
     }
 
     /* If we have spans, the first one is the segment that was active, when the
@@ -983,7 +983,7 @@ void WriteScopes (void)
             }
 
             /* Spans for this scope */
-            WriteSpans (&S->Spans);
+            WriteSpanList (&S->Spans);
 
             /* Next scope */
             S = S->Next;
index c336e959918514830882490307ffd09df79a53fe..fcd4488749b5f56ea856364af932dc312db1f733 100644 (file)
 
 /* Defines for magic and version */
 #define OBJ_MAGIC      0x616E7A55
-#define OBJ_VERSION    0x000E
+#define OBJ_VERSION    0x000F
 
 /* Size of an object file header */
-#define        OBJ_HDR_SIZE    (22*4)
+#define        OBJ_HDR_SIZE    (24*4)
 
 /* Flag bits */
 #define OBJ_FLAGS_DBGINFO      0x0001  /* File has debug info */
@@ -83,6 +83,8 @@ struct ObjHeader {
     unsigned long       AssertSize;     /* 32: Size of assertion table */
     unsigned long       ScopeOffs;      /* 32: Offset into scope table */
     unsigned long       ScopeSize;      /* 32: Size of scope table */
+    unsigned long       SpanOffs;       /* 32: Offset into span table */
+    unsigned long       SpanSize;       /* 32: Size of span table */
 };
 
 
index 038c2d9caa75b880990c0f0448c417661b512a1b..e05831d0c476db4b9d9785b4e820871f4ab6ce89 100644 (file)
@@ -200,6 +200,8 @@ static void LibReadObjHeader (Library* L, ObjData* O)
     O->Header.AssertSize   = Read32 (L->F);
     O->Header.ScopeOffs    = Read32 (L->F);
     O->Header.ScopeSize    = Read32 (L->F);
+    O->Header.SpanOffs     = Read32 (L->F);
+    O->Header.SpanSize     = Read32 (L->F);
 }
 
 
@@ -220,7 +222,7 @@ static ObjData* ReadIndexEntry (Library* L)
     O->Flags   = Read16 (L->F);
     O->MTime    = Read32 (L->F);
     O->Start   = Read32 (L->F);
-    Read32 (L->F);                     /* Skip Size */
+    Read32 (L->F);                     /* Skip Size */
 
     /* Done */
     return O;
@@ -243,6 +245,9 @@ static void ReadBasicData (Library* L, ObjData* O)
     /* Read the files list */
     ObjReadFiles (L->F, O->Start + O->Header.FileOffs, O);
 
+    /* Read the spans */
+    ObjReadSpans (L->F, O->Start + O->Header.SpanOffs, O);
+
     /* Read the line infos */
     ObjReadLineInfos (L->F, O->Start + O->Header.LineInfoOffs, O);
 
index 1e60d8162d7a5d6b168e3f8dc5fde95720fd1fd2..f53738c4d156238b2c5496f123df788f74c08b63 100644 (file)
@@ -114,7 +114,7 @@ LineInfo* ReadLineInfo (FILE* F, ObjData* O)
     LI->File     = CollAt (&O->Files, ReadVar (F));
     LI->Pos.Name = LI->File->Name;
     LI->Type     = ReadVar (F);
-    ReadSpans (&LI->Spans, F, O);
+    ReadSpanList (&LI->Spans, F, O);
 
     /* Return the struct read */
     return LI;
index 66bcc64fefc1a8cf3ea96514dd0cdd9dd75bc9ff..7e914a57277dec3cb927ec24ec21f44faad82f98 100644 (file)
@@ -107,6 +107,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
     H->AssertSize   = Read32 (Obj);
     H->ScopeOffs    = Read32 (Obj);
     H->ScopeSize    = Read32 (Obj);
+    H->SpanOffs     = Read32 (Obj);
+    H->SpanSize     = Read32 (Obj);
 }
 
 
@@ -281,6 +283,25 @@ void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O)
 
 
 
+void ObjReadSpans (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the span table from a file at the given offset */
+{
+    unsigned I;
+    unsigned SpanCount;
+
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
+    SpanCount = ReadVar (F);
+    CollGrow (&O->Spans, SpanCount);
+    for (I = 0; I < SpanCount; ++I) {
+        CollAppend (&O->Spans,  ReadSpan (F, O, I));
+    }
+}
+
+
+
 void ObjAdd (FILE* Obj, const char* Name)
 /* Add an object file to the module list */
 {
@@ -302,6 +323,9 @@ void ObjAdd (FILE* Obj, const char* Name)
     /* Read the files list from the object file */
     ObjReadFiles (Obj, O->Header.FileOffs, O);
 
+    /* Read the spans from the object file */
+    ObjReadSpans (Obj, O->Header.SpanOffs, O);
+
     /* Read the line infos from the object file */
     ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O);
 
index f26d5bdd5e0845823150fe6f37206a0ca7bd5868..1b7796625a1556fd8c6d5b4d0469f9722a7d3990 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -81,6 +81,9 @@ void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O);
 void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O);
 /* Read the scope table from a file at the given offset */
 
+void ObjReadSpans (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the span table from a file at the given offset */
+
 void ObjAdd (FILE* F, const char* Name);
 /* Add an object file to the module list */
 
index 60f66044aae4a2fe83dd12b8d136149f377ee02c..62a5e30a4eea6594ab90e96c364d46cd0c633bef 100644 (file)
@@ -90,7 +90,7 @@ Scope* ReadScope (FILE* F, ObjData* Obj, unsigned Id)
     }
 
     /* Read the spans for this scope */
-    ReadSpans (&S->Spans, F, Obj);
+    ReadSpanList (&S->Spans, F, Obj);
 
     /* Return the new Scope */
     return S;
index 68c5059516c89ee75e0e8fb45f7b86d683849e6f..da8cd83dd609bd02e5d8578a12f7084e4f126047 100644 (file)
@@ -34,6 +34,7 @@
 
 
 /* common */
+#include "attrib.h"
 #include "xmalloc.h"
 
 /* ld65 */
@@ -66,41 +67,38 @@ struct Span {
 
 
 
-Span* NewSpan (ObjData* Obj, unsigned SecId, unsigned long Offs, unsigned long Size)
+static Span* NewSpan (unsigned Id, unsigned Sec, unsigned long Offs, unsigned long Size)
 /* Create and return a new span */
 {
     /* Allocate memory */
     Span* S = xmalloc (sizeof (*S));
 
     /* Initialize the fields */
-    S->Id       = CollCount (&Obj->Spans);
-    S->Sec      = SecId;
+    S->Id       = Id;
+    S->Sec      = Sec;
     S->Offs     = Offs;
     S->Size     = Size;
 
-    /* Insert it into the collection of all spans of this object file */
-    CollAppend (&Obj->Spans, S);
-
     /* Return the result */
     return S;
 }
 
 
 
-Span* ReadSpan (FILE* F, ObjData* O)
+Span* ReadSpan (FILE* F, ObjData* O attribute ((unused)), unsigned Id)
 /* Read a Span from a file and return it */
 {
     /* Create a new Span and return it */
     unsigned SecId     = ReadVar (F);
     unsigned long Offs = ReadVar (F);
     unsigned Size      = ReadVar (F);
-    return NewSpan (O, SecId, Offs, Size);
+    return NewSpan (Id, SecId, Offs, Size);
 }
 
 
 
-void ReadSpans (Collection* Spans, FILE* F, ObjData* O)
-/* Read a list of Spans from a file and return it */
+void ReadSpanList (Collection* Spans, FILE* F, ObjData* O)
+/* Read a list of span ids from a file and return the spans for the ids */
 {
     /* First is number of Spans */
     unsigned Count = ReadVar (F);
@@ -110,7 +108,7 @@ void ReadSpans (Collection* Spans, FILE* F, ObjData* O)
 
     /* Read the spans and add them */
     while (Count--) {
-        CollAppend (Spans, ReadSpan (F, O));
+        CollAppend (Spans, CollAt (&O->Spans, ReadVar (F)));
     }
 }
 
index 54726f6dec30f35b3108c8d3b5d758c15f7e147e..f3b00e5682f972802af36ba38fda92bc62df7c42 100644 (file)
@@ -73,15 +73,11 @@ typedef struct Span Span;
 
 
 
-Span* NewSpan (struct ObjData* Obj, unsigned SecId, unsigned long Offs, 
-               unsigned long Size);
-/* Create and return a new span */
-
-Span* ReadSpan (FILE* F, struct ObjData* O);
+Span* ReadSpan (FILE* F, struct ObjData* O, unsigned Id);
 /* Read a Span from a file and return it */
 
-void ReadSpans (Collection* Spans, FILE* F, struct ObjData* O);
-/* Read a list of Spans from a file and return it */
+void ReadSpanList (Collection* Spans, FILE* F, struct ObjData* O);
+/* Read a list of span ids from a file and return the spans for the ids */
 
 void FreeSpan (Span* S);
 /* Free a span structure */
index 1025f6c28e2cec442df10ccaa8297a38cb554ce8..e4ebcff7afcff19ce3fbb663ec1b96c4483f186a 100644 (file)
@@ -136,6 +136,20 @@ static void SkipLineInfoList (FILE* F)
 
 
 
+static void SkipSpanList (FILE* F)
+/* Skip a span list from the given file */
+{
+    /* Count preceeds the list */
+    unsigned long Count = ReadVar (F);
+
+    /* Skip indices */
+    while (Count--) {
+        (void) ReadVar (F);
+    }
+}
+
+
+
 static void SkipExpr (FILE* F)
 /* Skip an expression from the given file */
 {
@@ -772,13 +786,17 @@ void DumpObjLineInfo (FILE* F, unsigned long Offset)
     for (I = 0; I < Count; ++I) {
 
        FilePos   Pos;
-
-        /* Type of line info */
-        unsigned Type = ReadVar (F);
+        unsigned  Type;
 
                /* File position of line info */
        ReadFilePos (F, &Pos);
 
+        /* Type of line info */
+        Type = ReadVar (F);
+
+        /* Skip the spans */
+        SkipSpanList (F);
+
        /* Print the header */
        printf ("    Index:%27u\n", I);
 
@@ -834,8 +852,6 @@ void DumpObjScopes (FILE* F, unsigned long Offset)
 
         const char*     Name;
         unsigned        Len;
-        unsigned        SpanCount;
-        unsigned        J;
 
         /* Read the data */
         unsigned        ParentId = ReadVar (F);
@@ -869,17 +885,8 @@ void DumpObjScopes (FILE* F, unsigned long Offset)
             printf ("      Label id:%22u\n", LabelId);
         }
 
-        /* Spans */
-        SpanCount = ReadVar (F);
-        printf ("      Segment spans:\n");
-        printf ("        Count:%23u\n", SpanCount);
-
-        for (J = 0; J < SpanCount; ++J) {
-            printf ("        Index:%23u\n", J);
-            printf ("          Segment:%19lu\n", ReadVar (F));
-            printf ("          Start:%13s0x%06lX\n", "", ReadVar (F));
-            printf ("          Size:%14s0x%06lX\n", "", ReadVar (F));
-        }
+        /* Skip the spans */
+        SkipSpanList (F);
     }
 
     /* Destroy the string pool */
index 4a061af943f40af873bf99278b3ba9d6c592055b..a1493500689331bc6b8cde996cd6fb1de88b1722 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -53,7 +53,7 @@
 
 void FileSetPos (FILE* F, unsigned long Pos)
 /* Seek to the given absolute position, fail on errors */
-{
+{                 
     if (fseek (F, Pos, SEEK_SET) != 0) {
        Error ("Cannot seek: %s", strerror (errno));
     }
@@ -229,6 +229,8 @@ void ReadObjHeader (FILE* F, ObjHeader* H)
     H->AssertSize   = Read32 (F);
     H->ScopeOffs    = Read32 (F);
     H->ScopeSize    = Read32 (F);
+    H->SpanOffs     = Read32 (F);
+    H->SpanSize     = Read32 (F);
 }