]> git.sur5r.net Git - cc65/commitdiff
Added assertions
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 6 Jun 2003 12:45:19 +0000 (12:45 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 6 Jun 2003 12:45:19 +0000 (12:45 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2202 b7a2c559-68d2-44c3-8de9-860c34a00d81

29 files changed:
src/ar65/objfile.c
src/ca65/error.c
src/ca65/error.h
src/ca65/main.c
src/ca65/make/gcc.mak
src/ca65/make/watcom.mak
src/ca65/objfile.c
src/ca65/objfile.h
src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/scanner.h
src/common/objdefs.h
src/ld65/config.c
src/ld65/config.h
src/ld65/expr.c
src/ld65/fileinfo.c
src/ld65/fileio.c
src/ld65/fileio.h
src/ld65/library.c
src/ld65/main.c
src/ld65/make/gcc.mak
src/ld65/make/watcom.mak
src/ld65/objdata.c
src/ld65/objdata.h
src/ld65/objfile.c
src/ld65/objfile.h
src/ld65/segments.c
src/ld65/segments.h
src/od65/fileio.c

index a7675e7d0edc49168e1536a0fa67a318db123f97..e165fc1671064236aea5e3347770ac51a80ddbb5 100644 (file)
@@ -111,6 +111,8 @@ void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
     H->LineInfoSize = Read32 (Obj);
     H->StrPoolOffs  = Read32 (Obj);
     H->StrPoolSize  = Read32 (Obj);
+    H->AssertOffs   = Read32 (Obj);
+    H->AssertSize   = Read32 (Obj);
 }
 
 
@@ -137,6 +139,8 @@ void ObjWriteHeader (FILE* Obj, ObjHeader* H)
     Write32 (Obj, H->LineInfoSize);
     Write32 (Obj, H->StrPoolOffs);
     Write32 (Obj, H->StrPoolSize);
+    Write32 (Obj, H->AssertOffs);
+    Write32 (Obj, H->AssertSize);
 }
 
 
@@ -201,7 +205,7 @@ void ObjAdd (const char* Name)
     O->StringCount = ReadVar (Obj);
     O->Strings     = xmalloc (O->StringCount * sizeof (char*));
     for (I = 0; I < O->StringCount; ++I) {
-        O->Strings[I] = ReadStr (Obj);    
+        O->Strings[I] = ReadStr (Obj);
     }
 
     /* Skip the object file header */
@@ -219,6 +223,8 @@ void ObjAdd (const char* Name)
     H.FileOffs = LibCopyTo (Obj, H.FileSize) - O->Start;
     fseek (Obj, H.LineInfoOffs, SEEK_SET);
     H.LineInfoOffs = LibCopyTo (Obj, H.LineInfoSize) - O->Start;
+    fseek (Obj, H.AssertOffs, SEEK_SET);
+    H.AssertOffs = LibCopyTo (Obj, H.AssertSize) - O->Start;
 
     /* Calculate the amount of data written */
     O->Size = ftell (NewLib) - O->Start;
@@ -270,7 +276,7 @@ void ObjExtract (const char* Name)
        Error ("Cannot open target file `%s': %s", Name, strerror (errno));
     }
 
-    /* Copy the first four segments including the header to the new file */
+    /* Copy anything to the new file that has no special handling */
     LibCopyFrom (O->Start, O->Size, Obj);
 
     /* Write imports and exports */
@@ -284,7 +290,7 @@ void ObjExtract (const char* Name)
     WriteVar (Obj, O->StringCount);
     for (I = 0; I < O->StringCount; ++I) {
         WriteStr (Obj, O->Strings[I]);
-    }                             
+    }
     StrPoolSize = ftell (Obj) - StrPoolStart;
 
     /* Seek back and read the header */
index 162080d7b8ec6d9317f66b369fd9db4daa147609..ce5212638346ccea2d2b1557485bf3850782d48e 100644 (file)
@@ -162,6 +162,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
        "Illegal macro package name",
        "Illegal emulation feature",
         "Illegal scope specifier",
+        "Illegal assert action",
        "Syntax error",
        "Symbol `%s' is already defined",
        "Undefined symbol `%s'",
index ca7ef370e3ab3ee7b1d1b1353af397381d95062f..1d6611318712148b6d60477a7060e03d23fa8676 100644 (file)
@@ -103,6 +103,7 @@ enum Errors {
     ERR_ILLEGAL_MACPACK,
     ERR_ILLEGAL_FEATURE,
     ERR_ILLEGAL_SCOPE,
+    ERR_ILLEGAL_ASSERT_ACTION,
     ERR_SYNTAX,
     ERR_SYM_ALREADY_DEFINED,
     ERR_SYM_UNDEFINED,
index f3ae998097f9cab1c3d6debc135cc6ad72ea6f89..31dfef06951f3c69c0bcf87583f1b27b2e677591 100644 (file)
@@ -56,6 +56,7 @@
 #include "incpath.h"
 #include "instr.h"
 #include "istack.h"
+#include "ldassert.h"
 #include "lineinfo.h"
 #include "listing.h"
 #include "macro.h"
@@ -484,6 +485,9 @@ static void CreateObjFile (void)
     /* Write the string pool */
     WriteStrPool ();
 
+    /* Write the assertions */
+    WriteAssertions ();
+
     /* Write an updated header and close the file */
     ObjClose ();
 }
index dc0502be6f1f55ac89bb2d73a806738041815661..12efb6503afda8b71f13bfa67990602f26418d2a 100644 (file)
@@ -22,6 +22,7 @@ OBJS =  condasm.o     \
        incpath.o       \
         instr.o                \
        istack.o        \
+        ldassert.o      \
        lineinfo.o      \
        listing.o       \
        macpack.o       \
index 3e9bec5b0a4951c494450a43c70ce58d6bf39fe1..ac2ca050ef24ecf16d3b12f75488c53759702e08 100644 (file)
@@ -55,6 +55,7 @@ OBJS =        condasm.obj     \
        incpath.obj     \
                instr.obj       \
        istack.obj      \
+        ldassert.obj    \
        lineinfo.obj    \
        listing.obj     \
        macpack.obj     \
index 840dd6d5412700e88c46ee758d876a2589f9bfbe..50bcafcf475b00930a8775fc310c7f5bf190fe3b 100644 (file)
@@ -81,7 +81,9 @@ static ObjHeader Header = {
     0,                  /* 32: Offset to list of line infos */
     0,                  /* 32: Size of line infos */
     0,                  /* 32: Offset to string pool */
-    0                   /* 32: Size of string pool */
+    0,                  /* 32: Size of string pool */
+    0,                  /* 32: Offset to assertion table */
+    0                   /* 32: Size of assertion table */
 };
 
 
@@ -134,6 +136,8 @@ static void ObjWriteHeader (void)
     ObjWrite32 (Header.LineInfoSize);
     ObjWrite32 (Header.StrPoolOffs);
     ObjWrite32 (Header.StrPoolSize);
+    ObjWrite32 (Header.AssertOffs);
+    ObjWrite32 (Header.AssertSize);
 }
 
 
@@ -442,3 +446,19 @@ void ObjEndStrPool (void)
 
 
 
+void ObjStartAssertions (void)
+/* Mark the start of the assertion table */
+{
+    Header.AssertOffs = ftell (F);
+}
+
+
+
+void ObjEndAssertions (void)
+/* Mark the end of the assertion table */
+{
+    Header.AssertSize = ftell (F) - Header.AssertOffs;
+}
+
+
+
index b6d8d6e34321052d8febc9236ee33980dcd846c6..c0edde24018201a899debe81476c0b16e476a6ef 100644 (file)
@@ -133,6 +133,12 @@ void ObjStartStrPool (void);
 void ObjEndStrPool (void);
 /* Mark the end of the string pool section */
 
+void ObjStartAssertions (void);
+/* Mark the start of the assertion table */
+
+void ObjEndAssertions (void);
+/* Mark the end of the assertion table */
+
 
 
 /* End of objfile.h */
index d3918ec6248a7eb85f6910129c6d7adf5a415a32..407cf5e7fdd6332b0dc58e8b2b2ae5a7dc1dc893 100644 (file)
 #include "global.h"
 #include "incpath.h"
 #include "instr.h"
+#include "ldassert.h"
 #include "listing.h"
 #include "macpack.h"
 #include "macro.h"
 #include "nexttok.h"
 #include "objcode.h"
 #include "options.h"
+#include "pseudo.h"
 #include "repeat.h"
+#include "spool.h"
 #include "symtab.h"
-#include "pseudo.h"
 
 
 
@@ -326,6 +328,55 @@ static void DoASCIIZ (void)
 
 
 
+static void DoAssert (void)
+/* Add an assertion */
+{
+    static const char* ActionTab [] = {
+       "WARN", "WARNING",
+        "ERROR"
+    };
+
+    int Action;
+
+
+    /* First we have the expression that has to evaluated */
+    ExprNode* Expr = Expression ();
+    ConsumeComma ();
+
+    /* Action follows */
+    if (Tok != TOK_IDENT) {
+        ErrorSkip (ERR_IDENT_EXPECTED);
+        return;
+    }
+    Action = GetSubKey (ActionTab, sizeof (ActionTab) / sizeof (ActionTab[0]));
+    switch (Action) {
+
+        case 0:
+        case 1:
+            /* Warning */
+            break;
+
+        case 2:
+            /* Error */
+            break;
+
+        default:
+            Error (ERR_ILLEGAL_SEG_ATTR);
+    }
+    NextTok ();
+    ConsumeComma ();
+
+    /* Read the message */
+    if (Tok != TOK_STRCON) {
+       ErrorSkip (ERR_STRCON_EXPECTED);
+    } else {
+        AddAssertion (Expr, Action, GetStringId (SVal));
+        NextTok ();
+    }
+}
+
+
+
 static void DoAutoImport (void)
 /* Mark unresolved symbols as imported */
 {
@@ -1078,7 +1129,7 @@ static void DoMacPack (void)
 
     /* Insert the package */
     InsertMacPack (Package);
-}            
+}
 
 
 
@@ -1403,11 +1454,11 @@ enum {
 };
 
 /* Control command table */
-struct CtrlDesc_ {
+typedef struct CtrlDesc CtrlDesc;
+struct CtrlDesc {
     unsigned           Flags;                  /* Flags for this directive */
     void               (*Handler) (void);      /* Command handler */
 };
-typedef struct CtrlDesc_ CtrlDesc;
 
 #define PSEUDO_COUNT   (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0]))
 static CtrlDesc CtrlCmdTab [] = {
@@ -1416,6 +1467,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoAddr          },      /* .ADDR */
     { ccNone,          DoAlign         },
     { ccNone,          DoASCIIZ        },
+    { ccNone,           DoAssert        },
     { ccNone,          DoAutoImport    },
     { ccNone,          DoUnexpected    },      /* .BLANK */
     { ccNone,          DoBss           },
index 1e485fc5cc7db3e8c8fde3b19d8f111ff84182aa..39f04174d74c3b806910c6c96ae1029cf7db4127 100644 (file)
@@ -123,6 +123,7 @@ struct DotKeyword {
     { ".ALIGN",                TOK_ALIGN       },
     { ".AND",          TOK_BAND        },
     { ".ASCIIZ",               TOK_ASCIIZ      },
+    { ".ASSERT",        TOK_ASSERT      },
     { ".AUTOIMPORT",   TOK_AUTOIMPORT  },
     { ".BITAND",       TOK_AND         },
     { ".BITNOT",       TOK_NOT         },
index 442affa767afc8ba345abb49e2d364e8cc59bd09..46549b91ec7b28df8942a6319caa3ca64187a171 100644 (file)
@@ -115,6 +115,7 @@ enum Token {
     TOK_ADDR,
     TOK_ALIGN,
     TOK_ASCIIZ,
+    TOK_ASSERT,
     TOK_AUTOIMPORT,
     TOK_BLANK,
     TOK_BSS,
@@ -235,7 +236,7 @@ extern int          ForcedEnd;              /* Force end of assembly */
 /*****************************************************************************/
 
 
-                    
+
 void NewInputFile (const char* Name);
 /* Open a new input file */
 
index aae965362f0ef9f3a248e249b948b3a863d971ce..ebf414a7c20f979b5afb5e9cab2a0f14297cc6a3 100644 (file)
@@ -49,7 +49,7 @@
 #define OBJ_VERSION    0x000A
 
 /* Size of an object file header */
-#define        OBJ_HDR_SIZE    72
+#define        OBJ_HDR_SIZE    (20*4)
 
 /* Flag bits */
 #define OBJ_FLAGS_DBGINFO      0x0001  /* File has debug info */
@@ -78,6 +78,8 @@ struct ObjHeader {
     unsigned long       LineInfoSize;   /* 32: Size of line infos */
     unsigned long       StrPoolOffs;    /* 32: Offset to string pool */
     unsigned long       StrPoolSize;    /* 32: Size of string pool */
+    unsigned long       AssertOffs;     /* 32: Offset to assertion table */
+    unsigned long       AssertSize;     /* 32: Size of assertion table */
 };
 
 
index 19f42f23f91aca3074b371f5e009994f28332cdf..8d5a8ecf75214e7caf641069281e2886ca935209 100644 (file)
@@ -287,18 +287,19 @@ static Memory* NewMemory (unsigned Name)
     M = xmalloc (sizeof (Memory));
 
     /* Initialize the fields */
-    M->Name      = Name;
-    M->Next     = 0;
-    M->FNext     = 0;
-    M->Attr      = 0;
-    M->Flags     = 0;
-    M->Start     = 0;
-    M->Size      = 0;
-    M->FillLevel = 0;
-    M->FillVal   = 0;
-    M->SegList   = 0;
-    M->SegLast   = 0;
-    M->F         = 0;
+    M->Name        = Name;
+    M->Next               = 0;
+    M->FNext       = 0;
+    M->Attr        = 0;
+    M->Flags       = 0;
+    M->Start       = 0;
+    M->Size        = 0;
+    M->FillLevel   = 0;
+    M->FillVal     = 0;
+    M->Relocatable = 0;
+    M->SegList     = 0;
+    M->SegLast     = 0;
+    M->F           = 0;
 
     /* Insert the struct into the list */
     if (MemoryLast == 0) {
@@ -992,7 +993,7 @@ static void ParseFormats (void)
        /* Map the identifier to a token */
        cfgtok_t FormatTok;
                CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
-       FormatTok = CfgTok;                        
+       FormatTok = CfgTok;
 
        /* Skip the name and the following colon */
        CfgNextTok ();
@@ -1432,11 +1433,16 @@ void CfgAssignSegments (void)
     Memory* M = MemoryList;
     while (M) {
 
+        MemListNode* N;
+
        /* Get the start address of this memory area */
        unsigned long Addr = M->Start;
 
+        /* Remember if this is a relocatable memory area */
+        M->Relocatable = RelocatableBinFmt (M->F->Format);
+
        /* Walk through the segments in this memory area */
-       MemListNode* N = M->SegList;
+       N = M->SegList;
        while (N) {
 
            /* Get the segment from the node */
@@ -1444,32 +1450,35 @@ void CfgAssignSegments (void)
 
            /* Handle ALIGN and OFFSET/START */
            if (S->Flags & SF_ALIGN) {
-               /* Align the address */
-               unsigned long Val = (0x01UL << S->Align) - 1;
-               Addr = (Addr + Val) & ~Val;
+               /* Align the address */
+               unsigned long Val = (0x01UL << S->Align) - 1;
+               Addr = (Addr + Val) & ~Val;
            } else if (S->Flags & (SF_OFFSET | SF_START)) {
-               /* Give the segment a fixed starting address */
-               unsigned long NewAddr = S->Addr;
-               if (S->Flags & SF_OFFSET) {
-                   /* An offset was given, no address, make an address */
-                   NewAddr += M->Start;
-               }
+               /* Give the segment a fixed starting address */
+               unsigned long NewAddr = S->Addr;
+               if (S->Flags & SF_OFFSET) {
+                   /* An offset was given, no address, make an address */
+                   NewAddr += M->Start;
+               }
                        if (Addr > NewAddr) {
-                   /* Offset already too large */
-                   if (S->Flags & SF_OFFSET) {
-                       Error ("Offset too small in `%s', segment `%s'",
-                              GetString (M->Name), GetString (S->Name));
-                   } else {
-                       Error ("Start address too low in `%s', segment `%s'",
-                              GetString (M->Name), GetString (S->Name));
-                   }
-               }
-               Addr = NewAddr;
+                   /* Offset already too large */
+                   if (S->Flags & SF_OFFSET) {
+                       Error ("Offset too small in `%s', segment `%s'",
+                              GetString (M->Name), GetString (S->Name));
+                   } else {
+                       Error ("Start address too low in `%s', segment `%s'",
+                              GetString (M->Name), GetString (S->Name));
+                   }
+               }
+               Addr = NewAddr;
            }
 
-                   /* If this is the run area, set the start address of this segment */
+                   /* If this is the run area, set the start address of this segment
+             * and remember if the segment is in a relocatable file or not.
+             */
            if (S->Run == M) {
                S->Seg->PC = Addr;
+                S->Seg->Relocatable = M->Relocatable;
            }
 
            /* Increment the fill level of the memory area and check for an
index f815fc398c1d8341ba584e70e28ffb8fb444b05b..58036d5f3cbe687d3d945d00d768ffab96e121d8 100644 (file)
@@ -78,6 +78,7 @@ struct Memory {
     unsigned long              Size;           /* Length of memory section */
     unsigned long              FillLevel;      /* Actual fill level of segment */
     unsigned char      FillVal;        /* Value used to fill rest of seg */
+    unsigned char       Relocatable;    /* Memory are is relocatable */
     MemListNode*       SegList;        /* List of segments for this section */
     MemListNode*       SegLast;        /* Last segment in this section */
     File*              F;              /* File that contains the entry */
index 9006826dd0318e786c0eefa947eedffe2dfb3d8e..425ee93f855c02b47ce95e170f1fb800d0ef5008 100644 (file)
@@ -101,8 +101,9 @@ int IsConstExpr (ExprNode* Root)
  * with no references to external symbols.
  */
 {
-    int Const;
-    Export* E;
+    int         Const;
+    Export*     E;
+    Section*    S;      
 
     if (EXPR_IS_LEAF (Root->Op)) {
        switch (Root->Op) {
@@ -111,23 +112,39 @@ int IsConstExpr (ExprNode* Root)
                return 1;
 
            case EXPR_SYMBOL:
-               /* Get the referenced export */
+               /* Get the referenced export */
                        E = GetExprExport (Root);
-               /* If this export has a mark set, we've already encountered it.
-                * This means that the export is used to define it's own value,
-                * which in turn means, that we have a circular reference.
-                */
-               if (ExportHasMark (E)) {
+               /* If this export has a mark set, we've already encountered it.
+                * This means that the export is used to define it's own value,
+                * which in turn means, that we have a circular reference.
+                */
+               if (ExportHasMark (E)) {
                     CircularRefError (E);
-                   Const = 0;
-               } else {
-                   MarkExport (E);
-                   Const = IsConstExport (E);
-                   UnmarkExport (E);
-               }
-               return Const;
+                   Const = 0;
+               } else {
+                   MarkExport (E);
+                   Const = IsConstExport (E);
+                   UnmarkExport (E);
+               }
+               return Const;
+
+            case EXPR_SECTION:
+                /* A section expression is const if the segment it is in is
+                 * not relocatable.
+                 */
+                S = GetExprSection (Root);
+                return !S->Seg->Relocatable;
+
+            case EXPR_SEGMENT:
+                /* A segment is const if it is not relocatable */
+                return !Root->V.Seg->Relocatable;
+
+            case EXPR_MEMAREA:
+                /* A memory area is const if it is not relocatable */
+                return !Root->V.Mem->Relocatable;
 
            default:
+                /* Anything else is not const */
                return 0;
 
        }
@@ -213,7 +230,7 @@ Section* GetExprSection (ExprNode* Expr)
      */
     if (Expr->Obj) {
        /* Return the export */
-       return Expr->Obj->Sections [Expr->V.SegNum];
+       return Expr->Obj->Sections[Expr->V.SegNum];
     } else {
        return Expr->V.Sec;
     }
@@ -231,47 +248,47 @@ long GetExprVal (ExprNode* Expr)
     switch (Expr->Op) {
 
                case EXPR_LITERAL:
-           return Expr->V.Val;
+           return Expr->V.Val;
 
                case EXPR_SYMBOL:
-           /* Get the referenced export */
+           /* Get the referenced export */
                    E = GetExprExport (Expr);
-           /* If this export has a mark set, we've already encountered it.
-            * This means that the export is used to define it's own value,
-            * which in turn means, that we have a circular reference.
-            */
-           if (ExportHasMark (E)) {
-               CircularRefError (E);
-               Val = 0;
-           } else {
-               MarkExport (E);
-               Val = GetExportVal (E);
-               UnmarkExport (E);
-           }
-           return Val;
+           /* If this export has a mark set, we've already encountered it.
+            * This means that the export is used to define it's own value,
+            * which in turn means, that we have a circular reference.
+            */
+           if (ExportHasMark (E)) {
+               CircularRefError (E);
+               Val = 0;
+           } else {
+               MarkExport (E);
+               Val = GetExportVal (E);
+               UnmarkExport (E);
+           }
+           return Val;
 
         case EXPR_SECTION:
                    S = GetExprSection (Expr);
-           return S->Offs + S->Seg->PC;
+           return S->Offs + S->Seg->PC;
 
-       case EXPR_SEGMENT:
+       case EXPR_SEGMENT:
                    return Expr->V.Seg->PC;
 
         case EXPR_MEMAREA:
             return Expr->V.Mem->Start;
 
                case EXPR_PLUS:
-           return GetExprVal (Expr->Left) + GetExprVal (Expr->Right);
+           return GetExprVal (Expr->Left) + GetExprVal (Expr->Right);
 
                case EXPR_MINUS:
-           return GetExprVal (Expr->Left) - GetExprVal (Expr->Right);
+           return GetExprVal (Expr->Left) - GetExprVal (Expr->Right);
 
                case EXPR_MUL:
-           return GetExprVal (Expr->Left) * GetExprVal (Expr->Right);
+           return GetExprVal (Expr->Left) * GetExprVal (Expr->Right);
 
                case EXPR_DIV:
-           Left  = GetExprVal (Expr->Left);
-           Right = GetExprVal (Expr->Right);
+           Left  = GetExprVal (Expr->Left);
+           Right = GetExprVal (Expr->Right);
            if (Right == 0) {
                Error ("Division by zero");
            }
index 2aeb5284bb02063ca9aa17aa025b9319a7acf054..58b5826b16dfee5af601085f9b35cd903a0db6a2 100644 (file)
@@ -60,14 +60,14 @@ static FileInfo* NewFileInfo (void)
 
 
 
-FileInfo* ReadFileInfo (FILE* F, ObjData* O attribute ((unused)))
+FileInfo* ReadFileInfo (FILE* F, ObjData* O)
 /* Read a file info from a file and return it */
 {
     /* Allocate a new FileInfo structure */
     FileInfo* FI = NewFileInfo ();
 
     /* Read the fields from the file */
-    FI->Name  = ReadVar (F);
+    FI->Name  = MakeGlobalStringId (O, ReadVar (F));
     FI->MTime = Read32 (F);
     FI->Size  = Read32 (F);
 
index 6ddc17158a101d2b6662728254a068b233c46e76..b2e93bea6a33bcb2ba61c353f21471260baf74dc 100644 (file)
@@ -34,6 +34,7 @@
 
 
 #include <string.h>
+#include <errno.h>
 
 /* common */
 #include "xmalloc.h"
 
 
 
+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));
+    }
+}
+
+
+
+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;
+}
+
+
+
 void Write8 (FILE* F, unsigned Val)
 /* Write an 8 bit value to the file */
 {
index b8dd2b1ecc805ccad3a32498b6a1065e770ce868..7bcc96f30aea57133dd4122fcafb4fd2baa49155 100644 (file)
 
 
 
+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 */
+
 void Write8 (FILE* F, unsigned Val);
 /* Write an 8 bit value to the file */
 
index 98ff05e0bfd47721a150a689e73c398b26e7a028..55c3656bc0a8925a308e132b3da53b77ab6889b3 100644 (file)
@@ -105,6 +105,8 @@ static void LibReadObjHeader (ObjData* O, const char* LibName)
     O->Header.LineInfoSize = Read32 (Lib);
     O->Header.StrPoolOffs  = Read32 (Lib);
     O->Header.StrPoolSize  = Read32 (Lib);
+    O->Header.AssertOffs   = Read32 (Lib);
+    O->Header.AssertSize   = Read32 (Lib);
 }
 
 
@@ -112,8 +114,6 @@ static void LibReadObjHeader (ObjData* O, const char* LibName)
 static ObjData* ReadIndexEntry (void)
 /* Read one entry in the index */
 {
-    unsigned I;
-
     /* Create a new entry and insert it into the list */
     ObjData* O = NewObjData ();
 
@@ -127,23 +127,15 @@ static ObjData* ReadIndexEntry (void)
     Read32 (Lib);                      /* Skip Size */
 
     /* Read the string pool */
-    ObjReadStrPool (Lib, O);
+    ObjReadStrPool (Lib, FileGetPos (Lib), O);
 
     /* Skip the export size, then read the exports */
     (void) ReadVar (Lib);
-    O->ExportCount = ReadVar (Lib);
-    O->Exports = xmalloc (O->ExportCount * sizeof (Export*));
-    for (I = 0; I < O->ExportCount; ++I) {
-       O->Exports[I] = ReadExport (Lib, O);
-    }
+    ObjReadExports (Lib, FileGetPos (Lib), O);
 
     /* Skip the import size, then read the imports */
     (void) ReadVar (Lib);
-    O->ImportCount = ReadVar (Lib);
-    O->Imports = xmalloc (O->ImportCount * sizeof (Import*));
-    for (I = 0; I < O->ImportCount; ++I) {
-               O->Imports[I] = ReadImport (Lib, O);
-    }
+    ObjReadImports (Lib, FileGetPos (Lib), O);
 
     /* Done */
     return O;
@@ -158,7 +150,7 @@ static void ReadIndex (void)
 
     /* Read the object file count and allocate memory */
     ModuleCount = ReadVar (Lib);
-    Index = xmalloc (ModuleCount * sizeof (ObjData*));
+    Index = xmalloc (ModuleCount * sizeof (Index[0]));
 
     /* Read all entries in the index */
     for (I = 0; I < ModuleCount; ++I) {
@@ -192,14 +184,7 @@ static void LibCheckExports (ObjData* O)
 
     /* If we need this module, insert the imports and exports */
     if (O->Flags & OBJ_REF) {
-       /* Insert the exports */
-       for (I = 0; I < O->ExportCount; ++I) {
-           InsertExport (O->Exports[I]);
-       }
-       /* Insert the imports */
-       for (I = 0; I < O->ImportCount; ++I) {
-           InsertImport (O->Imports[I]);
-       }
+        InsertObjGlobals (O);
     }
 }
 
@@ -265,23 +250,22 @@ void LibAdd (FILE* F, const char* Name)
            LibReadObjHeader (O, Name);
 
            /* Seek to the start of the files list and read the files list */
-           fseek (Lib, O->Start + O->Header.FileOffs, SEEK_SET);
-           ObjReadFiles (Lib, O);
+           ObjReadFiles (Lib, O->Start + O->Header.FileOffs, O);
 
            /* Seek to the start of the debug info and read the debug info */
-           fseek (Lib, O->Start + O->Header.DbgSymOffs, SEEK_SET);
-                   ObjReadDbgSyms (Lib, O);
+                   ObjReadDbgSyms (Lib, O->Start + O->Header.DbgSymOffs, O);
 
            /* Seek to the start of the line infos and read them */
-           fseek (Lib, O->Start + O->Header.LineInfoOffs, SEEK_SET);
-           ObjReadLineInfos (Lib, O);
+           ObjReadLineInfos (Lib, O->Start + O->Header.LineInfoOffs, O);
+
+            /* Read the assertions from the object file */
+            ObjReadAssertions (Lib, O->Start + O->Header.AssertOffs, O);
 
            /* Seek to the start of the segment list and read the segments.
             * This must be last, since the data here may reference other
             * stuff.
             */
-           fseek (Lib, O->Start + O->Header.SegOffs, SEEK_SET);
-           ObjReadSections (Lib, O);
+           ObjReadSections (Lib, O->Start + O->Header.SegOffs, O);
 
             /* Add a pointer to the library name */
             O->LibName = LibName;
index c92d96a54cf60e6a36652fddd01175b5d2b463a0..0c87cf1d377e4b2b8ade9e1f065decf24b79b78d 100644 (file)
@@ -49,6 +49,7 @@
 #include "xmalloc.h"
 
 /* ld65 */
+#include "asserts.h"
 #include "binfmt.h"
 #include "condes.h"
 #include "config.h"
@@ -509,6 +510,9 @@ int main (int argc, char* argv [])
     /* Assign start addresses for the segments, define linker symbols */
     CfgAssignSegments ();
 
+    /* Check module assertions */
+    CheckAssertions ();
+
     /* Create the output file */
     CfgWriteTarget ();
 
index cb74a511211099dd694eb9d359bacf423cc62db0..24260bb76350253967c9b62044eee7255c06b8be 100644 (file)
@@ -18,7 +18,8 @@ CVT=cfg/cvt-cfg.pl
 # -----------------------------------------------------------------------------
 # List of all object files
 
-OBJS =         bin.o           \
+OBJS =         asserts.o       \
+        bin.o          \
        binfmt.o        \
        condes.o        \
        config.o        \
index 35820b14e54f22a9b868179e104dd1a498575a44..37b01652298702bf23acddfbb77fbd6c4558b466 100644 (file)
@@ -43,7 +43,8 @@ CFLAGS  += -i=..\common
 # ------------------------------------------------------------------------------
 # All OBJ files
 
-OBJS = bin.obj         \
+OBJS = asserts.obj     \
+        bin.obj                \
        binfmt.obj      \
        condes.obj      \
        config.obj      \
index c962c5164cb047a8c7c16899d32f96d1fab9551c..2a4c1f6741b3a9bb0f7e7c59c2836f69e4f11585 100644 (file)
@@ -88,6 +88,8 @@ ObjData* NewObjData (void)
     O->LineInfos        = 0;
     O->StringCount      = 0;
     O->Strings          = 0;
+    O->AssertionCount   = 0;
+    O->Assertions       = 0;
 
     /* Return the new entry */
     return O;
@@ -135,6 +137,24 @@ void InsertObjData (ObjData* O)
 
 
 
+void InsertObjGlobals (ObjData* O)
+/* Insert imports and exports from the object file into the global import and
+ * export lists.
+ */
+{
+    unsigned I;
+
+    /* Insert exports and imports */
+    for (I = 0; I < O->ExportCount; ++I) {
+        InsertExport (O->Exports[I]);
+    }
+    for (I = 0; I < O->ImportCount; ++I) {
+        InsertImport (O->Imports[I]);
+    }
+}
+
+
+
 unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
 /* Convert a local string id into a global one and return it. */
 {
index d1e5414a62d065b4f6982eae036c1d27aa8dfd24..5adbce6b394ced632213645f6e173dee3b9ae25b 100644 (file)
@@ -66,17 +66,19 @@ struct ObjData {
     unsigned           FileCount;      /* Input file count */
     struct FileInfo**          Files;          /* List of input files */
     unsigned           SectionCount;   /* Count of sections in this object */
-    struct Section**   Sections;       /* List of all sections */
+    struct Section**   Sections;       /* List of all sections */
     unsigned           ExportCount;    /* Count of exports */
     struct Export**    Exports;        /* List of all exports */
     unsigned           ImportCount;    /* Count of imports */
-    struct Import**    Imports;        /* List of all imports */
+    struct Import**    Imports;        /* List of all imports */
     unsigned           DbgSymCount;    /* Count of debug symbols */
     struct DbgSym**    DbgSyms;        /* List of debug symbols */
     unsigned            LineInfoCount;  /* Count of additional line infos */
     struct LineInfo**   LineInfos;      /* List of additional line infos */
     unsigned            StringCount;    /* Count of strings */
     unsigned*           Strings;        /* List of global string indices */
+    unsigned            AssertionCount; /* Count of module assertions */
+    struct Assertion**  Assertions;     /* List of module assertions */
 };
 
 
@@ -109,6 +111,11 @@ void FreeObjStrings (ObjData* O);
 void InsertObjData (ObjData* O);
 /* Insert the ObjData object into the collection of used ObjData objects. */
 
+void InsertObjGlobals (ObjData* O);
+/* Insert imports and exports from the object file into the global import and
+ * export lists.
+ */
+
 unsigned MakeGlobalStringId (const ObjData* O, unsigned Index);
 /* Convert a local string id into a global one and return it. */
 
index 313977973fdfc0b67b9efa68b94dca17ab7a309f..a8c389cd7e736749de3f9bcec97666a18a475e3d 100644 (file)
@@ -44,6 +44,7 @@
 #include "xmalloc.h"
 
 /* ld65 */
+#include "asserts.h"
 #include "dbgsyms.h"
 #include "error.h"
 #include "exports.h"
@@ -101,15 +102,21 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
     H->LineInfoSize = Read32 (Obj);
     H->StrPoolOffs  = Read32 (Obj);
     H->StrPoolSize  = Read32 (Obj);
+    H->AssertOffs   = Read32 (Obj);
+    H->AssertSize   = Read32 (Obj);
 }
 
 
 
-void ObjReadFiles (FILE* F, ObjData* O)
-/* Read the files list from a file at the current position */
+void ObjReadFiles (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the files list from a file at the given position */
 {
     unsigned I;
 
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
     O->FileCount  = ReadVar (F);
     O->Files      = xmalloc (O->FileCount * sizeof (O->Files[0]));
     for (I = 0; I < O->FileCount; ++I) {
@@ -119,41 +126,69 @@ void ObjReadFiles (FILE* F, ObjData* O)
 
 
 
-void ObjReadImports (FILE* F, ObjData* O)
-/* Read the imports from a file at the current position */
+void ObjReadSections (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the section data from a file at the given position */
+{
+    unsigned I;
+
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
+    O->SectionCount = ReadVar (F);
+    O->Sections     = xmalloc (O->SectionCount * sizeof (O->Sections[0]));
+    for (I = 0; I < O->SectionCount; ++I) {
+       O->Sections [I] = ReadSection (F, O);
+    }
+}
+
+
+
+void ObjReadImports (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the imports from a file at the given position */
 {
     unsigned I;
 
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
     O->ImportCount = ReadVar (F);
     O->Imports     = xmalloc (O->ImportCount * sizeof (O->Imports[0]));
     for (I = 0; I < O->ImportCount; ++I) {
        O->Imports [I] = ReadImport (F, O);
-       InsertImport (O->Imports [I]);
     }
 }
 
 
 
-void ObjReadExports (FILE* F, ObjData* O)
-/* Read the exports from a file at the current position */
+void ObjReadExports (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the exports from a file at the given position */
 {
     unsigned I;
 
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
     O->ExportCount = ReadVar (F);
     O->Exports     = xmalloc (O->ExportCount * sizeof (O->Exports[0]));
     for (I = 0; I < O->ExportCount; ++I) {
        O->Exports [I] = ReadExport (F, O);
-       InsertExport (O->Exports [I]);
     }
 }
 
 
 
-void ObjReadDbgSyms (FILE* F, ObjData* O)
-/* Read the debug symbols from a file at the current position */
+void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the debug symbols from a file at the given position */
 {
     unsigned I;
 
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
     O->DbgSymCount = ReadVar (F);
     O->DbgSyms    = xmalloc (O->DbgSymCount * sizeof (O->DbgSyms[0]));
     for (I = 0; I < O->DbgSymCount; ++I) {
@@ -163,11 +198,15 @@ void ObjReadDbgSyms (FILE* F, ObjData* O)
 
 
 
-void ObjReadLineInfos (FILE* F, ObjData* O)
-/* Read the line infos from a file at the current position */
+void ObjReadLineInfos (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the line infos from a file at the given position */
 {
     unsigned I;
 
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
     O->LineInfoCount = ReadVar (F);
     O->LineInfos     = xmalloc (O->LineInfoCount * sizeof (O->LineInfos[0]));
     for (I = 0; I < O->LineInfoCount; ++I) {
@@ -177,11 +216,15 @@ void ObjReadLineInfos (FILE* F, ObjData* O)
 
 
 
-void ObjReadStrPool (FILE* F, ObjData* O)
-/* Read the string pool from a file at the current position */
+void ObjReadStrPool (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the string pool from a file at the given position */
 {
     unsigned I;
 
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
     O->StringCount = ReadVar (F);
     O->Strings     = xmalloc (O->StringCount * sizeof (O->Strings[0]));
     for (I = 0; I < O->StringCount; ++I) {
@@ -191,15 +234,19 @@ void ObjReadStrPool (FILE* F, ObjData* O)
 
 
 
-void ObjReadSections (FILE* F, ObjData* O)
-/* Read the section data from a file at the current position */
+void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O)
+/* Read the assertions from a file at the given offset */
 {
     unsigned I;
 
-    O->SectionCount = ReadVar (F);
-    O->Sections     = xmalloc (O->SectionCount * sizeof (O->Sections[0]));
-    for (I = 0; I < O->SectionCount; ++I) {
-       O->Sections [I] = ReadSection (F, O);
+    /* Seek to the correct position */
+    FileSetPos (F, Pos);
+
+    /* Read the data */
+    O->AssertionCount = ReadVar (F);
+    O->Assertions     = xmalloc (O->AssertionCount * sizeof (O->Assertions[0]));
+    for (I = 0; I < O->AssertionCount; ++I) {
+        O->Assertions[I] = ReadAssertion (F, O);
     }
 }
 
@@ -221,35 +268,31 @@ void ObjAdd (FILE* Obj, const char* Name)
     O->Name  = GetModule (Name);
 
     /* Read the string pool from the object file */
-    fseek (Obj, O->Header.StrPoolOffs, SEEK_SET);
-    ObjReadStrPool (Obj, O);
+    ObjReadStrPool (Obj, O->Header.StrPoolOffs, O);
 
     /* Read the files list from the object file */
-    fseek (Obj, O->Header.FileOffs, SEEK_SET);
-    ObjReadFiles (Obj, O);
+    ObjReadFiles (Obj, O->Header.FileOffs, O);
 
     /* Read the imports list from the object file */
-    fseek (Obj, O->Header.ImportOffs, SEEK_SET);
-    ObjReadImports (Obj, O);
+    ObjReadImports (Obj, O->Header.ImportOffs, O);
 
     /* Read the object file exports and insert them into the exports list */
-    fseek (Obj, O->Header.ExportOffs, SEEK_SET);
-    ObjReadExports (Obj, O);
+    ObjReadExports (Obj, O->Header.ExportOffs, O);
 
     /* Read the object debug symbols from the object file */
-    fseek (Obj, O->Header.DbgSymOffs, SEEK_SET);
-    ObjReadDbgSyms (Obj, O);
+    ObjReadDbgSyms (Obj, O->Header.DbgSymOffs, O);
 
     /* Read the line infos from the object file */
-    fseek (Obj, O->Header.LineInfoOffs, SEEK_SET);
-    ObjReadLineInfos (Obj, O);
+    ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O);
+
+    /* Read the assertions from the object file */
+    ObjReadAssertions (Obj, O->Header.AssertOffs, O);
 
     /* Read the segment list from the object file. This must be last, since
      * the expressions stored in the code may reference segments or imported
      * symbols.
      */
-    fseek (Obj, O->Header.SegOffs, SEEK_SET);
-    ObjReadSections (Obj, O);
+    ObjReadSections (Obj, O->Header.SegOffs, O);
 
     /* Mark this object file as needed */
     O->Flags |= OBJ_REF;
@@ -257,13 +300,16 @@ void ObjAdd (FILE* Obj, const char* Name)
     /* Done, close the file (we read it only, so no error check) */
     fclose (Obj);
 
+    /* Insert the imports and exports to the global lists */
+    InsertObjGlobals (O);
+
+    /* Insert the object into the list of all used object files */
+    InsertObjData (O);
+
     /* All references to strings are now resolved, so we can delete the module
      * string pool.
      */
     FreeObjStrings (O);
-
-    /* Insert the object into the list of all used object files */
-    InsertObjData (O);
 }
 
 
index 1c05d576124842ae1823e716803fe9939f05df86..f3bdf4cacbf21dfce28ea8e5abaf1dd10fa4f148 100644 (file)
 
 
 
-void ObjReadFiles (FILE* F, ObjData* O);
-/* Read the files list from a file at the current position */
+void ObjReadFiles (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the files list from a file at the given position */
 
-void ObjReadImports (FILE* F, ObjData* O);
-/* Read the imports from a file at the current position */
+void ObjReadSections (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the section data from a file at the given position */
 
-void ObjReadExports (FILE* F, ObjData* O);
-/* Read the exports from a file at the current position */
+void ObjReadImports (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the imports from a file at the given position */
 
-void ObjReadDbgSyms (FILE* F, ObjData* O);
-/* Read the debug symbols from a file at the current position */
+void ObjReadExports (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the exports from a file at the given position */
 
-void ObjReadLineInfos (FILE* F, ObjData* O);
-/* Read the line infos from a file at the current position */
+void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the debug symbols from a file at the given position */
 
-void ObjReadStrPool (FILE* F, ObjData* O);
-/* Read the string pool from a file at the current position */
+void ObjReadLineInfos (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the line infos from a file at the given position */
 
-void ObjReadSections (FILE* F, ObjData* O);
-/* Read the section data from a file at the current position */
+void ObjReadStrPool (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the string pool from a file at the given position */
+
+void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O);
+/* Read the assertions from a file at the given offset */
 
 void ObjAdd (FILE* F, const char* Name);
 /* Add an object file to the module list */
index c685ac48eecd6b91bb7b968e7161c33faecd2ca5..d834641d887e4b0f22efa8a5bbd83050b55b7ae1 100644 (file)
@@ -89,17 +89,18 @@ static Segment* NewSegment (unsigned Name, unsigned char Type)
     Segment* S = xmalloc (sizeof (Segment));
 
     /* Initialize the fields */
-    S->Name     = Name;
-    S->Next    = 0;
-    S->SecRoot = 0;
-    S->SecLast = 0;
-    S->PC      = 0;
-    S->Size            = 0;
-    S->AlignObj        = 0;
-    S->Align    = 0;
-    S->FillVal = 0;
-    S->Type     = Type;
-    S->Dumped   = 0;
+    S->Name        = Name;
+    S->Next       = 0;
+    S->SecRoot    = 0;
+    S->SecLast    = 0;
+    S->PC         = 0;
+    S->Size               = 0;
+    S->AlignObj           = 0;
+    S->Align       = 0;
+    S->FillVal    = 0;
+    S->Type        = Type;
+    S->Relocatable = 0;
+    S->Dumped      = 0;
 
     /* Insert the segment into the segment list */
     S->List = SegRoot;
index 23b21bd12cfec8070c0923110cc503fc73c7f78b..660ed78d11e6ad686e841ca178b9a42f5865e648 100644 (file)
@@ -65,7 +65,8 @@ struct Segment {
     unsigned char      Align;          /* Alignment needed */
     unsigned char      FillVal;        /* Value to use for fill bytes */
     unsigned char      Type;           /* Type of segment */
-    char               Dumped;         /* Did we dump this segment? */
+    unsigned char       Relocatable;    /* True if the segment is relocatable */
+    unsigned char              Dumped;         /* Did we dump this segment? */
 };
 
 
@@ -156,5 +157,5 @@ void CheckSegments (void);
 #endif
 
 
-                           
+
 
index b7f36f6d71822b6617bb5171656a124879b123a8..43a34ad9219005a321420f7c1aa0cdec7b5232fc 100644 (file)
@@ -225,6 +225,8 @@ void ReadObjHeader (FILE* F, ObjHeader* H)
     H->LineInfoSize = Read32 (F);
     H->StrPoolOffs  = Read32 (F);
     H->StrPoolSize  = Read32 (F);
+    H->AssertOffs   = Read32 (F);
+    H->AssertSize   = Read32 (F);
 }