]> git.sur5r.net Git - cc65/commitdiff
Restructuring the object file format
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 3 Jun 2003 22:19:46 +0000 (22:19 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 3 Jun 2003 22:19:46 +0000 (22:19 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2196 b7a2c559-68d2-44c3-8de9-860c34a00d81

18 files changed:
src/ca65/fragment.h
src/ca65/listing.h
src/ca65/objcode.c
src/ca65/objfile.c
src/ca65/objfile.h
src/common/cmdline.c
src/common/segdefs.h
src/ld65/fragment.c
src/ld65/fragment.h
src/ld65/make/gcc.mak
src/ld65/make/watcom.mak
src/ld65/o65.c
src/ld65/segments.c
src/ld65/spool.c [new file with mode: 0644]
src/ld65/spool.h [new file with mode: 0644]
src/od65/dump.c
src/od65/fileio.c
src/od65/fileio.h

index c9ea5742b9df5221a95f5c0617564e78a416a912..2235f55d644cd0059d18b0b3d8ba678d70324fc4 100644 (file)
@@ -6,9 +6,9 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2001 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
@@ -62,8 +62,7 @@ struct LineInfo;
 
 typedef struct Fragment Fragment;
 struct Fragment {
-    Fragment*          List;           /* List of all fragments */
-    Fragment*                  Next;           /* Fragment list in one segment */
+    Fragment*                  Next;           /* Pointer to next fragment in segment */
     Fragment*          LineList;       /* List of fragments for one src line */
     FilePos                    Pos;            /* File position for this fragment */
     struct LineInfo*    LI;             /* Extra line info */
@@ -77,12 +76,6 @@ struct Fragment {
 
 
 
-/* List of all fragments */
-extern Fragment* FragList;
-extern Fragment* FragLast;
-
-
-
 /* End of fragment.h */
 #endif
 
index 51b3e809b8825360f114417f3bac5b7e2b9ac887..01df0c3609b0c1a32b97cbbb9d319d4079de2161 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2000-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -38,6 +38,7 @@
 
 
 
+/* ca65 */
 #include "fragment.h"
 
 
@@ -52,8 +53,8 @@
 #define LINE_HEADER_LEN                24
 
 /* One listing line as it is stored in memory */
-typedef struct ListLine_ ListLine;
-struct ListLine_ {
+typedef struct ListLine ListLine;
+struct ListLine {
     ListLine*          Next;           /* Pointer to next line */
     Fragment*          FragList;       /* List of fragments for this line */
     Fragment*          FragLast;       /* Last entry in fragment list */
index 175c0acc474ab0655ce421291dc2f4562cc329ea..f483fabeae35393ecc155416d511b1ef87418c50 100644 (file)
@@ -6,9 +6,9 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
@@ -73,6 +73,7 @@ struct Segment {
     Segment*               List;               /* List of all segments */
     Fragment*              Root;               /* Root of fragment list */
     Fragment*              Last;               /* Pointer to last fragment */
+    unsigned long   FragCount;          /* Number of fragments */
     unsigned        Num;               /* Segment number */
     unsigned        Align;             /* Segment alignment */
     unsigned long   PC;
@@ -81,7 +82,7 @@ struct Segment {
 
 
 #define SEG(segdef, num, prev)      \
-    { prev, 0, 0, num, 0, 0, segdef }
+    { prev, 0, 0, 0, num, 0, 0, segdef }
 
 /* Definitions for predefined segments */
 SegDef NullSegDef     = STATIC_SEGDEF_INITIALIZER (SEGNAME_NULL,     SEGTYPE_ABS);
@@ -136,13 +137,14 @@ static Segment* NewSegment (const char* Name, unsigned SegType)
     S = xmalloc (sizeof (*S));
 
     /* Initialize it */
-    S->List   = 0;
-    S->Root   = 0;
-    S->Last   = 0;
-    S->Num    = SegmentCount++;
-    S->Align  = 0;
-    S->PC     = 0;
-    S->Def    = NewSegDef (Name, SegType);
+    S->List      = 0;
+    S->Root      = 0;
+    S->Last      = 0;
+    S->FragCount = 0;
+    S->Num       = SegmentCount++;
+    S->Align     = 0;
+    S->PC        = 0;
+    S->Def       = NewSegDef (Name, SegType);
 
     /* Insert it into the segment list */
     SegmentLast->List = S;
@@ -314,7 +316,7 @@ void SegCheck (void)
                                PError (&F->Pos, ERR_RANGE);
                            }
                        } else {
-                           /* PC relative value */
+                           /* PC relative value */
                            if (Val < -128 || Val > 127) {
                                PError (&F->Pos, ERR_RANGE);
                            }
@@ -408,12 +410,21 @@ static void WriteOneSeg (Segment* Seg)
 {
     Fragment* Frag;
     unsigned LineInfoIndex;
+    unsigned long DataSize;
+    unsigned long EndPos;
 
-    /* Write the segment name followed by the byte count in this segment */
-    ObjWriteStr (Seg->Def->Name);
-    ObjWrite32 (Seg->PC);
-    ObjWrite8 (Seg->Align);
-    ObjWrite8 (Seg->Def->Type);
+    /* Remember the file position, then write a dummy for the size of the
+     * following data
+     */
+    unsigned long SizePos = ObjGetFilePos ();
+    ObjWrite32 (0);
+
+    /* Write the segment data */
+    ObjWriteStr (Seg->Def->Name);       /* Name of the segment */
+    ObjWrite32 (Seg->PC);               /* Size */
+    ObjWrite8 (Seg->Align);             /* Segment alignment */
+    ObjWrite8 (Seg->Def->Type);         /* Type of the segment */
+    ObjWriteVar (Seg->FragCount);       /* Number of fragments that follow */
 
     /* Now walk through the fragment list for this segment and write the
      * fragments.
@@ -425,40 +436,40 @@ static void WriteOneSeg (Segment* Seg)
                switch (Frag->Type) {
 
            case FRAG_LITERAL:
-               ObjWrite8 (FRAG_LITERAL);
-               ObjWriteVar (Frag->Len);
-               ObjWriteData (Frag->V.Data, Frag->Len);
-               break;
+               ObjWrite8 (FRAG_LITERAL);
+               ObjWriteVar (Frag->Len);
+               ObjWriteData (Frag->V.Data, Frag->Len);
+               break;
 
            case FRAG_EXPR:
-               switch (Frag->Len) {
-                   case 1:   ObjWrite8 (FRAG_EXPR8);   break;
-                   case 2:   ObjWrite8 (FRAG_EXPR16);  break;
-                   case 3:   ObjWrite8 (FRAG_EXPR24);  break;
-                   case 4:   ObjWrite8 (FRAG_EXPR32);  break;
-                   default:  Internal ("Invalid fragment size: %u", Frag->Len);
-               }
-               WriteExpr (Frag->V.Expr);
-               break;
+               switch (Frag->Len) {
+                   case 1:   ObjWrite8 (FRAG_EXPR8);   break;
+                   case 2:   ObjWrite8 (FRAG_EXPR16);  break;
+                   case 3:   ObjWrite8 (FRAG_EXPR24);  break;
+                   case 4:   ObjWrite8 (FRAG_EXPR32);  break;
+                   default:  Internal ("Invalid fragment size: %u", Frag->Len);
+               }
+               WriteExpr (Frag->V.Expr);
+               break;
 
            case FRAG_SEXPR:
-               switch (Frag->Len) {
-                   case 1:   ObjWrite8 (FRAG_SEXPR8);  break;
-                   case 2:   ObjWrite8 (FRAG_SEXPR16); break;
-                   case 3:   ObjWrite8 (FRAG_SEXPR24); break;
-                   case 4:   ObjWrite8 (FRAG_SEXPR32); break;
-                   default:  Internal ("Invalid fragment size: %u", Frag->Len);
-               }
-               WriteExpr (Frag->V.Expr);
-               break;
+               switch (Frag->Len) {
+                   case 1:   ObjWrite8 (FRAG_SEXPR8);  break;
+                   case 2:   ObjWrite8 (FRAG_SEXPR16); break;
+                   case 3:   ObjWrite8 (FRAG_SEXPR24); break;
+                   case 4:   ObjWrite8 (FRAG_SEXPR32); break;
+                   default:  Internal ("Invalid fragment size: %u", Frag->Len);
+               }
+               WriteExpr (Frag->V.Expr);
+               break;
 
            case FRAG_FILL:
-               ObjWrite8 (FRAG_FILL);
+               ObjWrite8 (FRAG_FILL);
                        ObjWriteVar (Frag->Len);
-               break;
+               break;
 
            default:
-               Internal ("Invalid fragment type: %u", Frag->Type);
+               Internal ("Invalid fragment type: %u", Frag->Type);
 
        }
 
@@ -474,6 +485,13 @@ static void WriteOneSeg (Segment* Seg)
        /* Next fragment */
        Frag = Frag->Next;
     }
+
+    /* Calculate the size of the data, seek back and write it */
+    EndPos = ObjGetFilePos ();          /* Remember where we are */
+    DataSize = EndPos - SizePos - 4;    /* Don't count size itself */
+    ObjSetFilePos (SizePos);            /* Seek back to the size */
+    ObjWrite32 (DataSize);              /* Write the size */
+    ObjSetFilePos (EndPos);             /* Seek back to the end */
 }
 
 
@@ -532,7 +550,6 @@ static Fragment* NewFragment (unsigned char Type, unsigned short Len)
     F = xmalloc (sizeof (*F));
 
     /* Initialize it */
-    F->List    = 0;
     F->Next    = 0;
     F->LineList = 0;
     F->Pos     = CurPos;
@@ -540,21 +557,14 @@ static Fragment* NewFragment (unsigned char Type, unsigned short Len)
     F->Len     = Len;
     F->Type    = Type;
 
-    /* Insert it into the list of all segments */
-    if (FragList == 0) {
-       FragList = F;
-    } else {
-       FragLast->List = F;
-    }
-    FragLast = F;
-
-    /* Insert it into the current segment */
+    /* Insert the fragment into the current segment */
     if (ActiveSeg->Root) {
        ActiveSeg->Last->Next = F;
        ActiveSeg->Last = F;
     } else {
        ActiveSeg->Root = ActiveSeg->Last = F;
     }
+    ++ActiveSeg->FragCount;
 
     /* Add this fragment to the current listing line */
     if (LineCur) {
index 020096fd5f1da20c1ce4349b71a34bc16e25b884..840dd6d5412700e88c46ee758d876a2589f9bfbe 100644 (file)
@@ -191,6 +191,28 @@ void ObjClose (void)
 
 
 
+unsigned long ObjGetFilePos (void)
+/* Get the current file position */
+{
+    long Pos = ftell (F);
+    if (Pos < 0) {
+        ObjWriteError ();
+    }
+    return Pos;
+}
+
+
+
+void ObjSetFilePos (unsigned long Pos)
+/* Set the file position */
+{
+    if (fseek (F, Pos, SEEK_SET) != 0) {
+        ObjWriteError ();
+    }
+}
+
+
+
 void ObjWrite8 (unsigned V)
 /* Write an 8 bit value to the file */
 {
index 4268907c8259defd1a63c353b8915dc92fda442e..b6d8d6e34321052d8febc9236ee33980dcd846c6 100644 (file)
@@ -55,6 +55,12 @@ void ObjOpen (void);
 void ObjClose (void);
 /* Write an update header and close the object file. */
 
+unsigned long ObjGetFilePos (void);
+/* Get the current file position */
+
+void ObjSetFilePos (unsigned long Pos);
+/* Set the file position */
+
 void ObjWrite8 (unsigned V);
 /* Write an 8 bit value to the file */
 
@@ -130,7 +136,7 @@ void ObjEndStrPool (void);
 
 
 /* End of objfile.h */
-              
+
 #endif
 
 
index 1772a50c2eb455f55a6bce2cdeb83c09fc3ee46c..ea3b7e9e997a1ab03b827d33ae064e0a3e309728 100644 (file)
@@ -40,6 +40,7 @@
 /* common */
 #include "abend.h"
 #include "chartype.h"
+#include "fname.h"
 #include "xmalloc.h"
 #include "cmdline.h"
 
@@ -60,9 +61,9 @@ unsigned ArgCount = 0;
 
 /* Struct to pass the command line */
 typedef struct {
-    char**             Vec;            /* The argument vector */
-    unsigned           Count;          /* Actual number of arguments */
-    unsigned           Size;           /* Number of argument allocated */
+    char**      Vec;            /* The argument vector */
+    unsigned           Count;          /* Actual number of arguments */
+    unsigned           Size;           /* Number of argument allocated */
 } CmdLine;
 
 
@@ -94,7 +95,7 @@ static void NewCmdLine (CmdLine* L)
 
 
 
-static void AddArg (CmdLine* L, const char* Arg)
+static void AddArg (CmdLine* L, char* Arg)
 /* Add one argument to the list */
 {
     if (L->Size <= L->Count) {
@@ -108,7 +109,7 @@ static void AddArg (CmdLine* L, const char* Arg)
     }
 
     /* We have space left, add a copy of the argument */
-    L->Vec [L->Count++] = xstrdup (Arg);
+    L->Vec[L->Count++] = Arg;
 }
 
 
@@ -152,7 +153,7 @@ static void ExpandFile (CmdLine* L, const char* Name)
        }
 
        /* Add anything not empty to the command line */
-       AddArg (L, B);
+       AddArg (L, xstrdup (B));
 
     }
 
@@ -185,15 +186,7 @@ void InitCmdLine (int* aArgCount, char** aArgVec[], const char* aProgName)
        ProgName = aProgName;
     } else {
        /* Strip a path */
-       const char* FirstArg = (*aArgVec)[0];
-               ProgName = strchr (FirstArg, '\0');
-       while (ProgName > FirstArg) {
-           --ProgName;
-                   if (*ProgName == '/' || *ProgName == '\\') {
-               ++ProgName;
-               break;
-           }
-       }
+               ProgName = FindName ((*aArgVec)[0]);
        if (ProgName[0] == '\0') {
            /* Use the default */
            ProgName = aProgName;
@@ -319,4 +312,4 @@ void LongOption (unsigned* ArgNum, const LongOpt* OptTab, unsigned OptCount)
 
 
 
-                                    
+
index d20826ddb1c68019344ab2b5c21f0868a9e93b72..b6bc530b67ca54ed43b0e549fd86b455ad7c9a94 100644 (file)
@@ -53,7 +53,7 @@
 /* Fragment types in the object file */
 #define FRAG_TYPEMASK                  0x38    /* Mask the type of the fragment */
 #define FRAG_BYTEMASK           0x07           /* Mask for byte count */
-#define FRAG_CHECKMASK          0xC0    /* Mask for check type */
+#define FRAG_CHECKMASK          0x40    /* Mask for check expressions */
 
 /* Fragment types */
 #define FRAG_LITERAL                   0x00    /* Literal data */
@@ -73,9 +73,7 @@
 #define FRAG_FILL                      0x20    /* Fill bytes */
 
 /* Fragment checks */
-#define FRAG_CHECK_NONE         0x00    /* No checks applied */
-#define FRAG_CHECK_WARN         0x40    /* Check and warn */
-#define FRAG_CHECK_ERROR        0x80    /* Check and abort */
+#define FRAG_CHECK              0x40    /* Check expressions exist */
 
 
 
index cd4ae6028d1654d0ec051a9680b49c1fc4601482..19cf95311c780845a12892fb2c26fd9d2501198c 100644 (file)
@@ -34,6 +34,7 @@
 
 
 /* common */
+#include "segdefs.h"
 #include "xmalloc.h"
 
 /* ld65 */
 
 
 
-Fragment* NewFragment (unsigned char Type, unsigned long Size, Section* S)
+Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
 /* Create a new fragment and insert it into the section S */
 {
+    Fragment* F;
+
+    /* Calculate the size of the memory block. LitBuf is only needed if the
+     * fragment contains literal data.
+     */
+    unsigned FragSize = sizeof (Fragment) - 1;
+    if (Type == FRAG_LITERAL) {
+        FragSize += Size;
+    }
+
     /* Allocate memory */
-    Fragment* F = xmalloc (sizeof (Fragment) - 1 + Size);    
+    F = xmalloc (FragSize);
 
     /* Initialize the data */
     F->Next      = 0;
@@ -61,8 +72,7 @@ Fragment* NewFragment (unsigned char Type, unsigned long Size, Section* S)
     F->Expr      = 0;
     InitFilePos (&F->Pos);
     F->LI        = 0;
-    F->WarnExpr  = 0;
-    F->ErrorExpr = 0;
+    F->Check     = 0;
     F->Type      = Type;
 
     /* Insert the code fragment into the section */
index 4165a15f3f22332f24a86d2003e7cc199aa56673..9d70fc3ea6cc01f9986c5d4213ffb6126b05c5e0 100644 (file)
@@ -60,17 +60,25 @@ struct Section;
 
 
 
+/* Fragment check expression */
+typedef struct CheckExpr CheckExpr;
+struct CheckExpr {
+    struct CheckExpr*   Next;           /* Next check expression */
+    struct ExprNode*    Expr;           /* The expression itself */
+    unsigned            Action;         /* Action to take if the check fails */
+    unsigned            Message;        /* Message number */
+};
+
 /* Fragment structure */
 typedef struct Fragment Fragment;
 struct Fragment {
     Fragment*          Next;           /* Next fragment in list */
     struct ObjData*    Obj;            /* Source of fragment */
-    unsigned long              Size;           /* Size of data/expression */
+    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 */
-    struct ExprNode*    WarnExpr;       /* Print warning if expr true */
-    struct ExprNode*    ErrorExpr;      /* Print error if expr true */
+    CheckExpr*          Check;          /* Single linked list of expressions */
     unsigned char      Type;           /* Type of fragment */
     unsigned char              LitBuf [1];     /* Dynamically alloc'ed literal buffer */
 };
@@ -83,7 +91,7 @@ struct Fragment {
 
 
 
-Fragment* NewFragment (unsigned char Type, unsigned long Size, struct Section* S);
+Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
 /* Create a new fragment and insert it into the section S */
 
 
index 913a8f179ec977dfc0f4c459b61dbad03f98e22a..cb74a511211099dd694eb9d359bacf423cc62db0 100644 (file)
@@ -42,6 +42,7 @@ OBJS =        bin.o           \
        objfile.o       \
        scanner.o       \
        segments.o      \
+        spool.o         \
        tgtcfg.o
 
 # -----------------------------------------------------------------------------
index c4b0981e406ed92a54456372224c2067e53baf63..35820b14e54f22a9b868179e104dd1a498575a44 100644 (file)
@@ -67,6 +67,7 @@ OBJS =        bin.obj         \
        objfile.obj     \
        scanner.obj     \
        segments.obj    \
+        spool.obj       \
        tgtcfg.obj
 
 LIBS = ..\common\common.lib
index 8fe7cef4c2a0b7bdbf91817016bd59acfa2a8ecc..3f8d2058cdc6af6d2429a500ee63f30eb9f247f3 100644 (file)
@@ -398,9 +398,9 @@ static O65RelocTab* NewO65RelocTab (void)
     O65RelocTab* R = xmalloc (sizeof (O65RelocTab));
 
     /* Initialize the data */
-    R->Size = RELOC_BLOCKSIZE;
+    R->Size = 0;
     R->Fill = 0;
-    R->Buf  = xmalloc (RELOC_BLOCKSIZE);
+    R->Buf  = 0;
 
     /* Return the created struct */
     return R;
index 9d8e6d0e598519fa307e198d7770f2e16abc860d..84f1b90e2089160b36d18377f1d45a1f4e4f11fa 100644 (file)
@@ -211,27 +211,25 @@ Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type)
 Section* ReadSection (FILE* F, ObjData* O)
 /* Read a section from a file */
 {
-    char* Name;
-    unsigned long Size;
+    char*         Name;
+    unsigned      Size;
     unsigned char Align;
     unsigned char Type;
-    Segment* S;
-    Section* Sec;
-
-    /* Read the name */
-    Name = ReadStr (F);
-
-    /* Read the size */
-    Size = Read32 (F);
+    unsigned      FragCount;
+    Segment*      S;
+    Section*      Sec;
 
-    /* Read the alignment */
-    Align = Read8 (F);
+    /* Read the segment data */
+    (void) Read32 (F);            /* File size of data */
+    Name      = ReadStr (F);      /* Segment name */
+    Size      = Read32 (F);       /* Size of data */
+    Align     = Read8 (F);        /* Alignment */
+    Type      = Read8 (F);        /* Segment type */
+    FragCount = ReadVar (F);      /* Number of fragments */
 
-    /* Read the segment type */
-    Type = Read8 (F);
 
     /* Print some data */
-    Print (stdout, 2, "Module `%s': Found segment `%s', size = %lu, align = %u, type = %u\n",
+    Print (stdout, 2, "Module `%s': Found segment `%s', size = %u, align = %u, type = %u\n",
           GetObjFileName (O), Name, Size, Align, Type);
 
     /* Get the segment for this section */
@@ -251,7 +249,7 @@ Section* ReadSection (FILE* F, ObjData* O)
     }
 
     /* Start reading fragments from the file and insert them into the section . */
-    while (Size) {
+    while (FragCount--) {
 
        Fragment* Frag;
        unsigned  LineInfoIndex;
@@ -261,24 +259,21 @@ Section* ReadSection (FILE* F, ObjData* O)
 
         /* Extract the check mask from the type */
         unsigned char Check = Type & FRAG_CHECKMASK;
-        Type &= ~FRAG_CHECKMASK;
+        unsigned char Bytes = Type & FRAG_BYTEMASK;
+        Type &= FRAG_TYPEMASK;
 
        /* Handle the different fragment types */
        switch (Type) {
 
            case FRAG_LITERAL:
                Frag = NewFragment (Type, ReadVar (F), Sec);
+               ReadData (F, Frag->LitBuf, Frag->Size);
                break;
 
-           case FRAG_EXPR8:
-           case FRAG_EXPR16:
-                   case FRAG_EXPR24:
-           case FRAG_EXPR32:
-           case FRAG_SEXPR8:
-           case FRAG_SEXPR16:
-           case FRAG_SEXPR24:
-           case FRAG_SEXPR32:
-                       Frag = NewFragment (Type & FRAG_TYPEMASK, Type & FRAG_BYTEMASK, Sec);
+           case FRAG_EXPR:
+           case FRAG_SEXPR:
+                       Frag = NewFragment (Type, Bytes, Sec);
+               Frag->Expr = ReadExpr (F, O);
                break;
 
            case FRAG_FILL:
@@ -293,28 +288,17 @@ Section* ReadSection (FILE* F, ObjData* O)
                return 0;
                }
 
-       /* Now read the fragment data */
-       switch (Frag->Type) {
+        /* A list of check expressions may follow */
+        if (Check) {
 
-           case FRAG_LITERAL:
-               /* Literal data */
-               ReadData (F, Frag->LitBuf, Frag->Size);
-               break;
+            /* Read the number of expressions that follow */
+            unsigned Count = ReadVar (F);
 
-           case FRAG_EXPR:
-           case FRAG_SEXPR:
-               /* An expression */
-               Frag->Expr = ReadExpr (F, O);
-               break;
-
-       }
-
-        /* A check expression may follow */
-        if (Check & FRAG_CHECK_WARN) {
-            Frag->WarnExpr = ReadExpr (F, O);
-        }
-        if (Check & FRAG_CHECK_ERROR) {
-            Frag->ErrorExpr = ReadExpr (F, O);
+            /* Read the expressions */
+            CheckExpr* Last = 0;
+            while (Count--) {
+                /* ### */
+            }
         }
 
        /* Read the file position of the fragment */
@@ -339,10 +323,6 @@ Section* ReadSection (FILE* F, ObjData* O)
 
        /* Remember the module we had this fragment from */
        Frag->Obj = O;
-
-       /* Next one */
-       CHECK (Size >= Frag->Size);
-       Size -= Frag->Size;
     }
 
     /* Return the section */
@@ -410,7 +390,7 @@ void SegDump (void)
                switch (F->Type) {
 
                    case FRAG_LITERAL:
-                       printf ("    Literal (%lu bytes):", F->Size);
+                       printf ("    Literal (%u bytes):", F->Size);
                        Count = F->Size;
                        Data  = F->LitBuf;
                        I = 100;
@@ -426,21 +406,21 @@ void SegDump (void)
                        break;
 
                    case FRAG_EXPR:
-                       printf ("    Expression (%lu bytes):\n", F->Size);
+                       printf ("    Expression (%u bytes):\n", F->Size);
                        printf ("    ");
                        DumpExpr (F->Expr);
                        break;
 
                    case FRAG_SEXPR:
-                       printf ("    Signed expression (%lu bytes):\n", F->Size);
+                       printf ("    Signed expression (%u bytes):\n", F->Size);
                        printf ("      ");
                        DumpExpr (F->Expr);
                        break;
 
                    case FRAG_FILL:
-                       printf ("    Empty space (%lu bytes)\n", F->Size);
+                       printf ("    Empty space (%u bytes)\n", F->Size);
                        break;
-
+                                                   
                    default:
                        Internal ("Invalid fragment type: %02X", F->Type);
                }
@@ -518,7 +498,7 @@ void SegWrite (FILE* Tgt, Segment* S, SegWriteFunc F, void* Data)
        /* Loop over all fragments in this section */
        Frag = Sec->FragRoot;
        while (Frag) {
-                                      
+
             /* Do fragment alignment checks */
 
 
diff --git a/src/ld65/spool.c b/src/ld65/spool.c
new file mode 100644 (file)
index 0000000..d21b6e5
--- /dev/null
@@ -0,0 +1,56 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                  spool.c                                  */
+/*                                                                           */
+/*                  Id and message pool for the ld65 linker                  */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2003      Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* ld65 */
+#include "spool.h"
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+StringPool StrPool = STATIC_STRINGPOOL_INITIALIZER;
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
diff --git a/src/ld65/spool.h b/src/ld65/spool.h
new file mode 100644 (file)
index 0000000..0397e3e
--- /dev/null
@@ -0,0 +1,80 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                  spool.h                                  */
+/*                                                                           */
+/*                  Id and message pool for the ld65 linker                  */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2003      Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef SPOOL_H
+#define SPOOL_H
+
+
+
+/* common */
+#include "strpool.h"
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+extern StringPool StrPool;
+
+
+
+/*****************************************************************************/
+/*                                  Code                                    */
+/*****************************************************************************/
+
+
+
+#if defined(HAVE_INLINE)
+INLINE unsigned GetStringId (const char* S)
+/* Return the id of the given string */
+{
+    return SP_Add (&StrPool, S);
+}
+#else
+#  define GetStringId(S)        SP_Add (&StrPool, (S))
+#endif
+
+
+
+/* End of spool.h */
+
+#endif
+
+
+
+
index 48c910ccc4b59204768b3a019d84455be6178c67..6a2256a54909ca77363357a9c8559ad4ccf87f65 100644 (file)
@@ -156,91 +156,11 @@ static void SkipExpr (FILE* F)
        /* Not a leaf node */
                SkipExpr (F);
        SkipExpr (F);
-
     }
 }
 
 
 
-static unsigned SkipFragment (FILE* F)
-/* Skip a fragment from the given file and return the size */
-{
-    FilePos Pos;
-    unsigned long Size;
-
-    /* Read the fragment type */
-    unsigned char Type = Read8 (F);
-
-    /* Extract the check mask */
-    unsigned char Check = Type & FRAG_CHECKMASK;
-    Type &= ~FRAG_CHECKMASK;
-
-    /* Handle the different fragment types */
-    switch (Type) {
-
-       case FRAG_LITERAL:
-                   Size = ReadVar (F);
-           break;
-
-       case FRAG_EXPR8:
-       case FRAG_EXPR16:
-       case FRAG_EXPR24:
-       case FRAG_EXPR32:
-       case FRAG_SEXPR8:
-       case FRAG_SEXPR16:
-       case FRAG_SEXPR24:
-       case FRAG_SEXPR32:
-           Size = Type & FRAG_BYTEMASK;
-           break;
-
-       case FRAG_FILL:
-           Size = ReadVar (F);
-           break;
-
-       default:
-           Error ("Unknown fragment type: 0x%02X", Type);
-           /* NOTREACHED */
-           return 0;
-    }
-
-
-
-    /* Now read the fragment data */
-    switch (Type & FRAG_TYPEMASK) {
-
-       case FRAG_LITERAL:
-           /* Literal data */
-           FileSeek (F, ftell (F) + Size);
-           break;
-
-       case FRAG_EXPR:
-       case FRAG_SEXPR:
-           /* An expression */
-           SkipExpr (F);
-           break;
-
-    }
-
-    /* Skip the check expression if we have one */
-    if (Check & FRAG_CHECK_WARN) {
-        SkipExpr (F);
-    }
-    if (Check & FRAG_CHECK_ERROR) {
-        SkipExpr (F);
-    }
-
-    /* Skip the file position of the fragment */
-    ReadFilePos (F, &Pos);
-
-    /* Skip the        additional line info */
-    (void) ReadVar (F);
-
-    /* Return the size */
-    return Size;
-}
-
-
-
 static const char* GetExportFlags (unsigned Flags, const unsigned char* ConDes)
 /* Get the export flags as a (static) string */
 {
@@ -291,7 +211,7 @@ void DumpObjHeader (FILE* F, unsigned long Offset)
     ObjHeader H;
 
     /* Seek to the header position */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
 
     /* Read the header */
     ReadObjHeader (F, &H);
@@ -350,15 +270,15 @@ void DumpObjOptions (FILE* F, unsigned long Offset)
     unsigned   I;
 
     /* Seek to the header position and read the header */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
     ReadObjHeader (F, &H);
 
     /* Seek to the start of the string pool and read it */
-    FileSeek (F, Offset + H.StrPoolOffs);
+    FileSetPos (F, Offset + H.StrPoolOffs);
     ReadStrPool (F, &StrPool);
 
     /* Seek to the start of the options */
-    FileSeek (F, Offset + H.OptionOffs);
+    FileSetPos (F, Offset + H.OptionOffs);
 
     /* Output a header */
     printf ("  Options:\n");
@@ -370,7 +290,7 @@ void DumpObjOptions (FILE* F, unsigned long Offset)
     /* Read and print all options */
     for (I = 0; I < Count; ++I) {
 
-       const char*   ArgStr;                      
+       const char*   ArgStr;
        unsigned      ArgLen;
 
        /* Read the type of the option and the value */
@@ -438,15 +358,15 @@ void DumpObjFiles (FILE* F, unsigned long Offset)
     unsigned   I;
 
     /* Seek to the header position and read the header */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
     ReadObjHeader (F, &H);
 
     /* Seek to the start of the string pool and read it */
-    FileSeek (F, Offset + H.StrPoolOffs);
+    FileSetPos (F, Offset + H.StrPoolOffs);
     ReadStrPool (F, &StrPool);
 
     /* Seek to the start of the source files */
-    FileSeek (F, Offset + H.FileOffs);
+    FileSetPos (F, Offset + H.FileOffs);
 
     /* Output a header */
     printf ("  Files:\n");
@@ -489,18 +409,17 @@ void DumpObjSegments (FILE* F, unsigned long Offset)
     Collection StrPool = AUTO_COLLECTION_INITIALIZER;
     unsigned   Count;
     unsigned   I;
-    unsigned   FragCount;
 
     /* Seek to the header position and read the header */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
     ReadObjHeader (F, &H);
 
     /* Seek to the start of the string pool and read it */
-    FileSeek (F, Offset + H.StrPoolOffs);
+    FileSetPos (F, Offset + H.StrPoolOffs);
     ReadStrPool (F, &StrPool);
 
     /* Seek to the start of the segments */
-    FileSeek (F, Offset + H.SegOffs);
+    FileSetPos (F, Offset + H.SegOffs);
 
     /* Output a header */
     printf ("  Segments:\n");
@@ -513,11 +432,14 @@ void DumpObjSegments (FILE* F, unsigned long Offset)
     for (I = 0; I < Count; ++I) {
 
        /* Read the data for one segments */
-       char*         Name  = ReadStr (F);
-       unsigned      Len   = strlen (Name);
-       unsigned long Size  = Read32 (F);
-       unsigned      Align = (1U << Read8 (F));
-       unsigned char Type  = Read8 (F);
+        unsigned long DataSize  = Read32 (F);
+        unsigned long NextSeg   = ftell (F) + DataSize;
+       char*         Name      = ReadStr (F);
+       unsigned      Len       = strlen (Name);
+       unsigned long Size      = Read32 (F);
+       unsigned      Align     = (1U << Read8 (F));
+       unsigned char Type      = Read8 (F);
+        unsigned long FragCount = ReadVar (F);
 
        /* Get the description for the type */
        const char* TypeDesc;
@@ -526,7 +448,7 @@ void DumpObjSegments (FILE* F, unsigned long Offset)
            case SEGTYPE_ABS:           TypeDesc = "SEGTYPE_ABS";       break;
            case SEGTYPE_ZP:            TypeDesc = "SEGTYPE_ZP";        break;
            case SEGTYPE_FAR:           TypeDesc = "SEGTYPE_FAR";       break;
-           default:                    TypeDesc = "SEGTYPE_UNKNOWN";   break;
+           default:                    TypeDesc = "SEGTYPE_UNKNOWN";   break;
        }
 
        /* Print the header */
@@ -537,24 +459,13 @@ void DumpObjSegments (FILE* F, unsigned long Offset)
                printf ("      Size:%26lu\n", Size);
        printf ("      Alignment:%21u\n", Align);
        printf ("      Type:%22s0x%02X  (%s)\n", "", Type, TypeDesc);
+               printf ("      Fragment count:%16lu\n", FragCount);
 
        /* Free the Name */
        xfree (Name);
 
-       /* Skip the fragments for this segment, counting them */
-       FragCount = 0;
-       while (Size > 0) {
-           unsigned FragSize = SkipFragment (F);
-           if (FragSize > Size) {
-               /* OOPS - file data invalid */
-               Error ("Invalid fragment data - file corrupt!");
-           }
-           Size -= FragSize;
-           ++FragCount;
-       }
-
-       /* Print the fragment count */
-               printf ("      Fragment count:%16u\n", FragCount);
+        /* Seek to the end of the segment data (start of next) */
+        FileSetPos (F, NextSeg);
     }
 
     /* Destroy the string pool */
@@ -573,15 +484,15 @@ void DumpObjImports (FILE* F, unsigned long Offset)
     FilePos    Pos;
 
     /* Seek to the header position and read the header */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
     ReadObjHeader (F, &H);
 
     /* Seek to the start of the string pool and read it */
-    FileSeek (F, Offset + H.StrPoolOffs);
+    FileSetPos (F, Offset + H.StrPoolOffs);
     ReadStrPool (F, &StrPool);
 
     /* Seek to the start of the imports */
-    FileSeek (F, Offset + H.ImportOffs);
+    FileSetPos (F, Offset + H.ImportOffs);
 
     /* Output a header */
     printf ("  Imports:\n");
@@ -632,15 +543,15 @@ void DumpObjExports (FILE* F, unsigned long Offset)
     FilePos            Pos;
 
     /* Seek to the header position and read the header */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
     ReadObjHeader (F, &H);
 
     /* Seek to the start of the string pool and read it */
-    FileSeek (F, Offset + H.StrPoolOffs);
+    FileSetPos (F, Offset + H.StrPoolOffs);
     ReadStrPool (F, &StrPool);
 
     /* Seek to the start of the exports */
-    FileSeek (F, Offset + H.ExportOffs);
+    FileSetPos (F, Offset + H.ExportOffs);
 
     /* Output a header */
     printf ("  Exports:\n");
@@ -701,15 +612,15 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset)
     FilePos     Pos;
 
     /* Seek to the header position and read the header */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
     ReadObjHeader (F, &H);
 
     /* Seek to the start of the string pool and read it */
-    FileSeek (F, Offset + H.StrPoolOffs);
+    FileSetPos (F, Offset + H.StrPoolOffs);
     ReadStrPool (F, &StrPool);
 
     /* Seek to the start of the debug syms */
-    FileSeek (F, Offset + H.DbgSymOffs);
+    FileSetPos (F, Offset + H.DbgSymOffs);
 
     /* Output a header */
     printf ("  Debug symbols:\n");
@@ -775,15 +686,15 @@ void DumpObjLineInfo (FILE* F, unsigned long Offset)
     unsigned    I;
 
     /* Seek to the header position and read the header */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
     ReadObjHeader (F, &H);
 
     /* Seek to the start of the string pool and read it */
-    FileSeek (F, Offset + H.StrPoolOffs);
+    FileSetPos (F, Offset + H.StrPoolOffs);
     ReadStrPool (F, &StrPool);
 
     /* Seek to the start of line infos */
-    FileSeek (F, Offset + H.LineInfoOffs);
+    FileSetPos (F, Offset + H.LineInfoOffs);
 
     /* Output a header */
     printf ("  Line info:\n");
@@ -830,15 +741,15 @@ void DumpObjSegSize (FILE* F, unsigned long Offset)
     unsigned    Count;
 
     /* Seek to the header position and read the header */
-    FileSeek (F, Offset);
+    FileSetPos (F, Offset);
     ReadObjHeader (F, &H);
 
     /* Seek to the start of the string pool and read it */
-    FileSeek (F, Offset + H.StrPoolOffs);
+    FileSetPos (F, Offset + H.StrPoolOffs);
     ReadStrPool (F, &StrPool);
 
     /* Seek to the start of the segments */
-    FileSeek (F, Offset + H.SegOffs);
+    FileSetPos (F, Offset + H.SegOffs);
 
     /* Output a header */
     printf ("  Segment sizes:\n");
@@ -850,13 +761,16 @@ void DumpObjSegSize (FILE* F, unsigned long Offset)
     while (Count--) {
 
                /* Read the data for one segments */
-       char*         Name  = ReadStr (F);
-       unsigned      Len   = strlen (Name);
-       unsigned long Size  = Read32 (F);
+        unsigned long DataSize = Read32 (F);
+        unsigned long NextSeg  = ftell (F) + DataSize;
+       char*         Name     = ReadStr (F);
+       unsigned      Len      = strlen (Name);
+       unsigned long Size     = Read32 (F);
 
-        /* Skip alignment and type */
+        /* Skip alignment, type and fragment count */
         (void) Read8 (F);
         (void) Read8 (F);
+        (void) ReadVar (F);
 
        /* Print the size for this segment */
        printf ("    %s:%*s%6lu\n", Name, 24-Len, "", Size);
@@ -864,16 +778,9 @@ void DumpObjSegSize (FILE* F, unsigned long Offset)
        /* Free the Name */
        xfree (Name);
 
-       /* Skip the fragments for this segment, counting them */
-       while (Size > 0) {
-           unsigned FragSize = SkipFragment (F);
-           if (FragSize > Size) {
-               /* OOPS - file data invalid */
-               Error ("Invalid fragment data - file corrupt!");
-           }
-           Size -= FragSize;
-       }
-    }
+        /* Seek to the end of the segment data (start of next) */
+        FileSetPos (F, NextSeg);
+    }                               
 
     /* Destroy the string pool */
     DestroyStrPool (&StrPool);
index 300321164087f2cc6ddb981d701544491d5b0808..b7f36f6d71822b6617bb5171656a124879b123a8 100644 (file)
@@ -51,7 +51,7 @@
 
 
 
-void FileSeek (FILE* F, unsigned long Pos)
+void FileSetPos (FILE* F, unsigned long Pos)
 /* Seek to the given absolute position, fail on errors */
 {
     if (fseek (F, Pos, SEEK_SET) != 0) {
@@ -61,6 +61,18 @@ void FileSeek (FILE* F, unsigned long Pos)
 
 
 
+unsigned long FileGetPos (FILE* F)
+/* Return the current file position, fail on errors */
+{
+    long Pos = ftell (F);
+    if (Pos < 0) {
+               Error ("Error in ftell: %s", strerror (errno));
+    }
+    return Pos;
+}
+
+
+
 unsigned Read8 (FILE* F)
 /* Read an 8 bit value from the file */
 {
index 89e9a43d423e461e213efc1a9fe87ea7387bc755..1601fbee8803378a22233d1ca68e3e59e1fb8054 100644 (file)
 
 
 
-void FileSeek (FILE* F, unsigned long Pos);
+void FileSetPos (FILE* F, unsigned long Pos);
 /* Seek to the given absolute position, fail on errors */
 
+unsigned long FileGetPos (FILE* F);
+/* Return the current file position, fail on errors */
+
 unsigned Read8 (FILE* F);
 /* Read an 8 bit value from the file */