]> git.sur5r.net Git - cc65/commitdiff
Separate processing the linker config file into two phases: The config file is
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 8 Nov 2010 21:52:24 +0000 (21:52 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 8 Nov 2010 21:52:24 +0000 (21:52 +0000)
read when the -t or -C switch is encountered and parts of it are processed.
The remaining parts are processed when all object files and libraries have
been read. To make this work, the expression evaluation in cfgexpr has been
rewritten to generate true expression trees. This means that expressions in
the linker config may use exports from the object files.

Separation of config file processing is the base for several enhancements, for
example forced imports by linker config.

This code needs more work and is only very, very, very roughly tested.

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

21 files changed:
src/ar65/library.c
src/common/exprdefs.h
src/common/libdefs.h
src/ld65/bin.c
src/ld65/cfgexpr.c
src/ld65/cfgexpr.h
src/ld65/config.c
src/ld65/config.h
src/ld65/exports.c
src/ld65/exports.h
src/ld65/expr.c
src/ld65/expr.h
src/ld65/library.c
src/ld65/main.c
src/ld65/make/gcc.mak
src/ld65/make/watcom.mak
src/ld65/memarea.c [new file with mode: 0644]
src/ld65/memarea.h [new file with mode: 0644]
src/ld65/o65.c
src/ld65/segments.c
src/ld65/segments.h

index 1214f23435c1150e8f830c4d0afc57e28ac8c881..8eb178788025b3ec051fef04844d35dc061f9c60 100644 (file)
@@ -126,15 +126,15 @@ static void ReadIndexEntry (void)
         O->Strings[I] = ReadStr (Lib);
     }
 
-    /* Exports */
-    O->ExportSize = ReadVar (Lib);
-    O->Exports    = xmalloc (O->ExportSize);
-    ReadData (Lib, O->Exports, O->ExportSize);
-
     /* Imports */
     O->ImportSize = ReadVar (Lib);
     O->Imports    = xmalloc (O->ImportSize);
     ReadData (Lib, O->Imports, O->ImportSize);
+
+    /* Exports */
+    O->ExportSize = ReadVar (Lib);
+    O->Exports    = xmalloc (O->ExportSize);
+    ReadData (Lib, O->Exports, O->ExportSize);
 }
 
 
@@ -197,13 +197,13 @@ static void WriteIndexEntry (ObjData* O)
         WriteStr (NewLib, O->Strings[I]);
     }
 
-    /* Exports */
-    WriteVar (NewLib, O->ExportSize);
-    WriteData (NewLib, O->Exports, O->ExportSize);
-
     /* Imports */
     WriteVar (NewLib, O->ImportSize);
     WriteData (NewLib, O->Imports, O->ImportSize);
+
+    /* Exports */
+    WriteVar (NewLib, O->ExportSize);
+    WriteData (NewLib, O->Exports, O->ExportSize);
 }
 
 
index 354c6ba1a64e784627589e49e1c23f47f2062c43..d9a3970c036b0b820245053037ee019636b9919b 100644 (file)
@@ -110,8 +110,8 @@ struct ExprNode {
                long                IVal;       /* If this is a int value */
                struct SymEntry*    Sym;        /* If this is a symbol */
        unsigned            SegNum;     /* If this is a segment */
-       unsigned            ImpNum;     /* If this is an import */
-        struct Memory*      Mem;        /* If this is a memory area */
+               struct Import*      Imp;        /* If this is an import */
+        struct MemoryArea*  Mem;        /* If this is a memory area */
        struct Segment*     Seg;        /* If this is a segment */
        struct Section*     Sec;        /* If section and Obj is NULL */
     } V;
index e945675e16c815b1ee017b94bc8c39a055bc033b..c7086cbbe5621d7d5d774cace2c347e02c405af7 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                          Data                                    */
 /*****************************************************************************/
 
 
 
 /* Defines for magic and version */
 #define LIB_MAGIC      0x7A55616E
-#define LIB_VERSION    0x000B
+#define LIB_VERSION    0x000C
 
 /* Size of an library file header */
 #define        LIB_HDR_SIZE    12
index 3c7c4a7a7f47baadc40d98cf34f54104078d6724..7c26febeddd9b9ba22ef53c763ff72f52e70c3ec 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1999-2008 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1999-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -50,6 +50,7 @@
 #include "global.h"
 #include "fileio.h"
 #include "lineinfo.h"
+#include "memarea.h"
 #include "segments.h"
 #include "spool.h"
 
@@ -129,7 +130,7 @@ static void PrintNumVal (const char* Name, unsigned long V)
 
 
 
-static void BinWriteMem (BinDesc* D, Memory* M)
+static void BinWriteMem (BinDesc* D, MemoryArea* M)
 /* Write the segments of one memory area to a file */
 {
     /* Get the start address of this memory area */
@@ -294,9 +295,9 @@ void BinWriteTarget (BinDesc* D, struct File* F)
     Print (stdout, 1, "Opened `%s'...\n", D->Filename);
 
     /* Dump all memory areas */
-    for (I = 0; I < CollCount (&F->MemList); ++I) {
+    for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
         /* Get this entry */
-        Memory* M = CollAtUnchecked (&F->MemList, I);
+        MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I);
        Print (stdout, 1, "  Dumping `%s'\n", GetString (M->Name));
        BinWriteMem (D, M);
     }
index 6d06389a4a75f1d302bfc0c83350158ea91b5cdd..584ad0d4ae35f8734221db145ecea6a46e056ad2 100644 (file)
 
 
 /* common */
+#include "addrsize.h"
 #include "strbuf.h"
 
 /* ld65 */
 #include "cfgexpr.h"
 #include "error.h"
 #include "exports.h"
+#include "expr.h"
 #include "scanner.h"
 #include "spool.h"
 
 
 
-/*****************************************************************************/
-/*                                          Data                                    */
-/*****************************************************************************/
-
-
-
-/* Type of a CfgExpr */
-enum {
-    ceEmpty,
-    ceInt,
-    ceString
-};
-
-typedef struct CfgExpr CfgExpr;
-struct CfgExpr {
-    unsigned    Type;           /* Type of the expression */
-    long        IVal;           /* Integer value if it's a string */
-    StrBuf      SVal;           /* String value if it's a string */
-};
-
-#define CFGEXPR_INITIALIZER { ceEmpty, 0, STATIC_STRBUF_INITIALIZER }
-
-
-
-/*****************************************************************************/
-/*                                 Forwards                                  */
-/*****************************************************************************/
-
-
-
-static void Expr (CfgExpr* E);
-/* Full expression */
-
-
-
-/*****************************************************************************/
-/*                              struct CfgExpr                               */
-/*****************************************************************************/
-
-
-
-static void CE_Done (CfgExpr* E)
-/* Cleanup a CfgExpr struct */
-{
-    /* If the type is a string, we must delete the string buffer */
-    if (E->Type == ceString) {
-        SB_Done (&E->SVal);
-    }
-}
-
-
-
-static void CE_AssureInt (const CfgExpr* E)
-/* Make sure, E contains an integer */
-{
-    if (E->Type != ceInt) {
-        CfgError ("Integer type expected");
-    }
-}
-
-
-
 /*****************************************************************************/
 /*                                          Code                                    */
 /*****************************************************************************/
 
 
 
-static void Factor (CfgExpr* E)
-/* Read and return a factor in E */
+static ExprNode* Factor (void)
+/* Read and return a factor */
 {
-    Export* Sym;
+    ExprNode* N = 0;            /* Initialize to avoid compiler warnings */
+    Export*   E;
+    unsigned  Name;
 
 
     switch (CfgTok) {
 
        case CFGTOK_IDENT:
-           /* An identifier - search an export with the given name */
-            Sym = FindExport (GetStrBufId (&CfgSVal));
-            if (Sym == 0) {
-                CfgError ("Unknown symbol in expression: `%s'",
-                          SB_GetConstBuf (&CfgSVal));
+            /* Get the name as an id */
+            Name = GetStrBufId (&CfgSVal);
+
+            /* Check if we know the symbol already */
+            E = FindExport (Name);
+            if (E != 0 && IsConstExport (E)) {
+                N = LiteralExpr (GetExportVal (E), 0);
+            } else {
+                N = NewExprNode (0, EXPR_SYMBOL);
+                N->V.Imp = InsertImport (GenImport (Name, ADDR_SIZE_ABS));
             }
-            /* We can only handle constants */
-            if (!IsConstExport (Sym)) {
-                CfgError ("Value for symbol `%s' is not constant",
-                          SB_GetConstBuf (&CfgSVal));
-            }
-
-            /* Use the symbol value */
-            E->IVal = GetExportVal (Sym);
-            E->Type = ceInt;
 
             /* Skip the symbol name */
             CfgNextTok ();
@@ -144,37 +82,27 @@ static void Factor (CfgExpr* E)
 
        case CFGTOK_INTCON:
             /* An integer constant */
-            E->IVal = CfgIVal;
-            E->Type = ceInt;
+            N = LiteralExpr (CfgIVal, 0);
            CfgNextTok ();
                    break;
 
-       case CFGTOK_STRCON:
-           /* A string constant */
-            SB_Copy (&E->SVal, &CfgSVal);
-            E->Type = ceString;
-           CfgNextTok ();
-           break;
-
         case CFGTOK_PLUS:
             /* Unary plus */
             CfgNextTok ();
-            Factor (E);
-            CE_AssureInt (E);
+            N = Factor ();
             break;
 
         case CFGTOK_MINUS:
             /* Unary minus */
             CfgNextTok ();
-            Factor (E);
-            CE_AssureInt (E);
-            E->IVal = -E->IVal;
+            N = NewExprNode (0, EXPR_UNARY_MINUS);
+            N->Left = Factor ();
             break;
 
                case CFGTOK_LPAR:
             /* Left parenthesis */
                    CfgNextTok ();
-                   Expr (E);
+                   N = CfgExpr ();
                    CfgConsume (CFGTOK_RPAR, "')' expected");
                    break;
 
@@ -182,139 +110,115 @@ static void Factor (CfgExpr* E)
                    CfgError ("Invalid expression: %d", CfgTok);
                    break;
     }
+
+    /* Return the new expression node */
+    return N;
 }
 
 
 
-static void Term (CfgExpr* E)
+static ExprNode* Term (void)
 /* Multiplicative operators: * and / */
 {
-    /* Left operand */
-    Factor (E);
+    /* Read left hand side */
+    ExprNode* Root = Factor ();
 
     /* Handle multiplicative operators */
     while (CfgTok == CFGTOK_MUL || CfgTok == CFGTOK_DIV) {
 
-        CfgExpr RightSide = CFGEXPR_INITIALIZER;
+        ExprNode* Left;
+        ExprNode* Right;
+        unsigned char Op;
 
         /* Remember the token, then skip it */
         cfgtok_t Tok = CfgTok;
         CfgNextTok ();
 
-        /* Left side must be an int */
-        CE_AssureInt (E);
-
-        /* Get the right operand and make sure it's an int */
-        Factor (&RightSide);
-        CE_AssureInt (&RightSide);
+        /* Move root to left side, then read right side */
+        Left = Root;
+        Right = Factor ();
 
         /* Handle the operation */
         switch (Tok) {
-
-            case CFGTOK_MUL:
-                E->IVal *= RightSide.IVal;
-                break;
-
-            case CFGTOK_DIV:
-                if (RightSide.IVal == 0) {
-                    CfgError ("Division by zero");
-                }
-                E->IVal /= RightSide.IVal;
-                break;
-
-            default:
-                Internal ("Unhandled token in Term: %d", Tok);
+            case CFGTOK_MUL:    Op = EXPR_MUL;  break;
+            case CFGTOK_DIV:    Op = EXPR_DIV;  break;
+            default:            Internal ("Unhandled token in Term: %d", Tok);
         }
-
-        /* Cleanup RightSide (this is not really needed since it may not
-         * contain strings at this point, but call it anyway for clarity.
-         */
-        CE_Done (&RightSide);
+        Root = NewExprNode (0, Op);
+        Root->Left = Left;
+        Root->Right = Right;
     }
+
+    /* Return the expression tree we've created */
+    return Root;
 }
 
 
 
-static void SimpleExpr (CfgExpr* E)
+static ExprNode* SimpleExpr (void)
 /* Additive operators: + and - */
 {
-    /* Left operand */
-    Term (E);
+    /* Read left hand side */
+    ExprNode* Root = Term ();
 
     /* Handle additive operators */
     while (CfgTok == CFGTOK_PLUS || CfgTok == CFGTOK_MINUS) {
 
-        CfgExpr RightSide = CFGEXPR_INITIALIZER;
+        ExprNode* Left;
+        ExprNode* Right;
+        unsigned char Op;
 
         /* Remember the token, then skip it */
         cfgtok_t Tok = CfgTok;
         CfgNextTok ();
 
-        /* Get the right operand */
-        Term (&RightSide);
-
-        /* Make sure, left and right side are of the same type */
-        if (E->Type != RightSide.Type) {
-            CfgError ("Incompatible types in expression");
-        }
+        /* Move root to left side, then read right side */
+        Left = Root;
+        Right = Term ();
 
         /* Handle the operation */
         switch (Tok) {
-
-            case CFGTOK_PLUS:
-                /* Plus is defined for strings and ints */
-                if (E->Type == ceInt) {
-                    E->IVal += RightSide.IVal;
-                } else if (E->Type == ceString) {
-                    SB_Append (&E->SVal, &RightSide.SVal);
-                } else {
-                    Internal ("Unhandled type in '+' operator: %u", E->Type);
-                }
-                break;
-
-            case CFGTOK_MINUS:
-                /* Operands must be ints */
-                CE_AssureInt (E);
-                E->IVal -= RightSide.IVal;
-                break;
-
-            default:
-                Internal ("Unhandled token in SimpleExpr: %d", Tok);
+            case CFGTOK_PLUS:   Op = EXPR_PLUS;         break;
+            case CFGTOK_MINUS:  Op = EXPR_MINUS;        break;
+            default:            Internal ("Unhandled token in SimpleExpr: %d", Tok);
         }
-
-        /* Cleanup RightSide */
-        CE_Done (&RightSide);
+        Root = NewExprNode (0, Op);
+        Root->Left = Left;
+        Root->Right = Right;
     }
+
+    /* Return the expression tree we've created */
+    return Root;
 }
 
 
 
-static void Expr (CfgExpr* E)
+ExprNode* CfgExpr (void)
 /* Full expression */
 {
-    SimpleExpr (E);
+    return SimpleExpr ();
 }
 
 
 
-long CfgIntExpr (void)
-/* Read an expression, make sure it's an int, and return its value */
+long CfgConstExpr (void)
+/* Read an integer expression, make sure its constant and return its value */
 {
     long Val;
 
-    CfgExpr E = CFGEXPR_INITIALIZER;
-
     /* Parse the expression */
-    Expr (&E);
+    ExprNode* Expr = CfgExpr ();
 
-    /* Make sure it's an integer */
-    CE_AssureInt (&E);
+    /* Check that it's const */
+    if (!IsConstExpr (Expr)) {
+        CfgError ("Constant expression expected");
+    }
 
     /* Get the value */
-    Val = E.IVal;
+    Val = GetExprVal (Expr);
 
-    /* Cleaup E */
-    CE_Done (&E);
+    /* Cleanup E */
+    FreeExpr (Expr);
 
     /* Return the value */
     return Val;
@@ -322,17 +226,17 @@ long CfgIntExpr (void)
 
 
 
-long CfgCheckedIntExpr (long Min, long Max)
+long CfgCheckedConstExpr (long Min, long Max)
 /* Read an expression, make sure it's an int and in range, then return its
  * value.
  */
 {
     /* Get the value */
-    long Val = CfgIntExpr ();
+    long Val = CfgConstExpr ();
 
     /* Check the range */
     if (Val < Min || Val > Max) {
-       CfgError ("Range error");
+       CfgError ("Range error");
     }
 
     /* Return the value */
index dc6b99bb428c54c28a824b8e826e3a5fbb722804..68247ca08ee8eeb4d2ab5dc35f86b80692d7a9a8 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2005,      Ullrich von Bassewitz                                      */
-/*                Römerstrasse 52                                            */
+/* (C) 2005-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 
 
 
+/* common */
+#include "exprdefs.h"
+
+
+
 /*****************************************************************************/
 /*                                          Code                                    */
 /*****************************************************************************/
 
 
 
-long CfgIntExpr (void);
-/* Read an expression, make sure it's an int, and return its value */
+ExprNode* CfgExpr (void);
+/* Read an integer expression and return its value */
+
+long CfgConstExpr (void);
+/* Read an integer expression, make sure its constant and return its value */
 
-long CfgCheckedIntExpr (long Min, long Max);
+long CfgCheckedConstExpr (long Min, long Max);
 /* Read an expression, make sure it's an int and in range, then return its
  * value.
  */
index 0dae0bc735e1e1bd62a589a8f2fd9a9bd371814a..3de6c9a1a860c690416eb73a713f06d9a91de452 100644 (file)
@@ -53,7 +53,9 @@
 #include "config.h"
 #include "error.h"
 #include "exports.h"
+#include "expr.h"
 #include "global.h"
+#include "memarea.h"
 #include "o65.h"
 #include "objdata.h"
 #include "scanner.h"
@@ -84,7 +86,7 @@ static enum {
 static Collection       FileList = STATIC_COLLECTION_INITIALIZER;
 
 /* Memory list */
-static Collection       MemoryList = STATIC_COLLECTION_INITIALIZER;
+static Collection       MemoryAreas = STATIC_COLLECTION_INITIALIZER;
 
 /* Memory attributes */
 #define MA_START               0x0001
@@ -95,8 +97,6 @@ static Collection       MemoryList = STATIC_COLLECTION_INITIALIZER;
 #define MA_FILL                0x0020
 #define MA_FILLVAL             0x0040
 
-
-
 /* Segment list */
 static Collection       SegDescList = STATIC_COLLECTION_INITIALIZER;
 
@@ -111,7 +111,30 @@ static Collection       SegDescList = STATIC_COLLECTION_INITIALIZER;
 #define SA_START       0x0080
 #define SA_OPTIONAL     0x0100
 
-
+/* Symbol structure. It is used for o65 imports and exports, but also for
+ * symbols from the SYMBOLS sections (symbols defined in the config file or
+ * forced imports).
+ */
+typedef struct Symbol Symbol;
+struct Symbol {
+    const char* CfgName;        /* Config file name */
+    unsigned    CfgLine;        /* Config file position */
+    unsigned    CfgCol;
+    unsigned    Name;           /* Symbol name */
+    unsigned    Flags;          /* Symbol flags */
+    long        Val;            /* Symbol value if any */
+};
+
+/* Collections with symbols */
+static Collection       O65Imports = STATIC_COLLECTION_INITIALIZER;
+static Collection       O65Exports = STATIC_COLLECTION_INITIALIZER;
+static Collection       Symbols    = STATIC_COLLECTION_INITIALIZER;
+
+/* Symbol flags */
+#define SYM_NONE        0x00    /* No special meaning */
+#define SYM_DEF         0x01    /* Symbol defined in the config file */
+#define SYM_WEAK        0x02    /* Defined symbol is weak */
+#define SYM_IMPORT      0x04    /* A forced import */
 
 /* Descriptor holding information about the binary formats */
 static BinDesc*        BinFmtDesc      = 0;
@@ -164,21 +187,21 @@ static File* GetFile (unsigned Name)
 
 
 
-static void FileInsert (File* F, Memory* M)
+static void FileInsert (File* F, MemoryArea* M)
 /* Insert the memory area into the files list */
 {
     M->F = F;
-    CollAppend (&F->MemList, M);
+    CollAppend (&F->MemoryAreas, M);
 }
 
 
 
-static Memory* CfgFindMemory (unsigned Name)
+static MemoryArea* CfgFindMemory (unsigned Name)
 /* Find the memory are with the given name. Return NULL if not found */
 {
     unsigned I;
-    for (I = 0; I < CollCount (&MemoryList); ++I) {
-        Memory* M = CollAtUnchecked (&MemoryList, I);
+    for (I = 0; I < CollCount (&MemoryAreas); ++I) {
+        MemoryArea* M = CollAtUnchecked (&MemoryAreas, I);
                if (M->Name == Name) {
                    return M;
                }
@@ -188,10 +211,10 @@ static Memory* CfgFindMemory (unsigned Name)
 
 
 
-static Memory* CfgGetMemory (unsigned Name)
+static MemoryArea* CfgGetMemory (unsigned Name)
 /* Find the memory are with the given name. Print an error on an invalid name */
 {
-    Memory* M = CfgFindMemory (Name);
+    MemoryArea* M = CfgFindMemory (Name);
     if (M == 0) {
        CfgError ("Invalid memory area `%s'", GetString (Name));
     }
@@ -218,16 +241,7 @@ static SegDesc* CfgFindSegDesc (unsigned Name)
 
 
 
-static void SegDescInsert (SegDesc* S)
-/* Insert a segment descriptor into the list of segment descriptors */
-{
-    /* Insert the struct into the list */
-    CollAppend (&SegDescList, S);
-}
-
-
-
-static void MemoryInsert (Memory* M, SegDesc* S)
+static void MemoryInsert (MemoryArea* M, SegDesc* S)
 /* Insert the segment descriptor into the memory area list */
 {
     /* Insert the segment into the segment list of the memory area */
@@ -242,6 +256,39 @@ static void MemoryInsert (Memory* M, SegDesc* S)
 
 
 
+static Symbol* NewSymbol (unsigned Name, unsigned Flags, long Val)
+/* Create a new Symbol structure with the given name name and flags. The
+ * current config file position is recorded in the returned struct.
+ */
+{
+    /* Allocate memory */
+    Symbol* Sym = xmalloc (sizeof (Symbol));
+
+    /* Initialize the fields */
+    Sym->CfgName = CfgGetName ();
+    Sym->CfgLine = CfgErrorLine;
+    Sym->CfgCol  = CfgErrorCol;
+    Sym->Name    = Name;
+    Sym->Flags   = Flags;
+    Sym->Val     = Val;
+
+    /* Return the initialized struct */
+    return Sym;
+}
+
+
+
+static Symbol* NewO65Symbol (void)
+/* Create a new Symbol structure with the name in the current CfgSVal variable
+ * ready for use as an o65 symbol. The current config file position is recorded
+ * in the returned struct.
+ */
+{
+    return NewSymbol (GetStrBufId (&CfgSVal), SYM_NONE, 0);
+}
+
+
+
 static File* NewFile (unsigned Name)
 /* Create a new file descriptor and insert it into the list */
 {
@@ -252,7 +299,7 @@ static File* NewFile (unsigned Name)
     F->Name    = Name;
     F->Flags   = 0;
     F->Format  = BINFMT_DEFAULT;
-    InitCollection (&F->MemList);
+    InitCollection (&F->MemoryAreas);
 
     /* Insert the struct into the list */
     CollAppend (&FileList, F);
@@ -263,32 +310,20 @@ static File* NewFile (unsigned Name)
 
 
 
-static Memory* NewMemory (unsigned Name)
-/* Create a new memory section and insert it into the list */
+static MemoryArea* CreateMemoryArea (unsigned Name)
+/* Create a new memory area and insert it into the list */
 {
     /* Check for duplicate names */
-    Memory* M =        CfgFindMemory (Name);
+    MemoryArea* M = CfgFindMemory (Name);
     if (M) {
        CfgError ("Memory area `%s' defined twice", GetString (Name));
     }
 
-    /* Allocate memory */
-    M = xmalloc (sizeof (Memory));
-
-    /* Initialize the fields */
-    M->Name        = Name;
-    M->Attr        = 0;
-    M->Flags       = 0;
-    M->Start       = 0;
-    M->Size        = 0;
-    M->FillLevel   = 0;
-    M->FillVal     = 0;
-    M->Relocatable = 0;
-    InitCollection (&M->SegList);
-    M->F           = 0;
+    /* Create a new memory area */
+    M = NewMemoryArea (Name);
 
-    /* Insert the struct into the list */
-    CollAppend (&MemoryList, M);
+    /* Insert the struct into the list ... */
+    CollAppend (&MemoryAreas, M);
 
     /* ...and return it */
     return M;
@@ -297,9 +332,8 @@ static Memory* NewMemory (unsigned Name)
 
 
 static SegDesc* NewSegDesc (unsigned Name)
-/* Create a segment descriptor */
+/* Create a segment descriptor and insert it into the list */
 {
-    Segment* Seg;
 
     /* Check for duplicate names */
     SegDesc* S = CfgFindSegDesc (Name);
@@ -307,21 +341,19 @@ static SegDesc* NewSegDesc (unsigned Name)
        CfgError ("Segment `%s' defined twice", GetString (Name));
     }
 
-    /* Search for the actual segment in the input files. The function may
-     * return NULL (no such segment), this is checked later.
-     */
-    Seg = SegFind (Name);
-
     /* Allocate memory */
     S = xmalloc (sizeof (SegDesc));
 
     /* Initialize the fields */
     S->Name    = Name;
-    S->Seg     = Seg;
+    S->Seg     = 0;
     S->Attr    = 0;
     S->Flags   = 0;
     S->Align   = 0;
 
+    /* Insert the struct into the list ... */
+    CollAppend (&SegDescList, S);
+
     /* ...and return it */
     return S;
 }
@@ -337,7 +369,7 @@ static void FreeSegDesc (SegDesc* S)
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                            Config file parsing                            */
 /*****************************************************************************/
 
 
@@ -385,7 +417,7 @@ static void ParseMemory (void)
     while (CfgTok == CFGTOK_IDENT) {
 
        /* Create a new entry on the heap */
-               Memory* M = NewMemory (GetStrBufId (&CfgSVal));
+               MemoryArea* M = CreateMemoryArea (GetStrBufId (&CfgSVal));
 
        /* Skip the name and the following colon */
        CfgNextTok ();
@@ -408,13 +440,13 @@ static void ParseMemory (void)
 
                case CFGTOK_START:
                    FlagAttr (&M->Attr, MA_START, "START");
-                    M->Start = CfgIntExpr ();
+                    M->StartExpr = CfgExpr ();
                    break;
 
                case CFGTOK_SIZE:
                    FlagAttr (&M->Attr, MA_SIZE, "SIZE");
-                   M->Size = CfgIntExpr ();
-                   break;
+                   M->SizeExpr = CfgExpr ();
+                   break;
 
                case CFGTOK_TYPE:
                    FlagAttr (&M->Attr, MA_TYPE, "TYPE");
@@ -455,7 +487,7 @@ static void ParseMemory (void)
 
                case CFGTOK_FILLVAL:
                    FlagAttr (&M->Attr, MA_FILLVAL, "FILLVAL");
-                   M->FillVal = (unsigned char) CfgCheckedIntExpr (0, 0xFF);
+                   M->FillVal = (unsigned char) CfgCheckedConstExpr (0, 0xFF);
                    break;
 
                default:
@@ -640,7 +672,7 @@ static void ParseSegments (void)
 
                case CFGTOK_ALIGN:
                    FlagAttr (&S->Attr, SA_ALIGN, "ALIGN");
-                   Val = CfgCheckedIntExpr (1, 0x10000);
+                   Val = CfgCheckedConstExpr (1, 0x10000);
                    S->Align = BitFind (Val);
                    if ((0x01L << S->Align) != Val) {
                        CfgError ("Alignment must be a power of 2");
@@ -650,7 +682,7 @@ static void ParseSegments (void)
 
                 case CFGTOK_ALIGN_LOAD:
                    FlagAttr (&S->Attr, SA_ALIGN_LOAD, "ALIGN_LOAD");
-                   Val = CfgCheckedIntExpr (1, 0x10000);
+                   Val = CfgCheckedConstExpr (1, 0x10000);
                            S->AlignLoad = BitFind (Val);
                    if ((0x01L << S->AlignLoad) != Val) {
                        CfgError ("Alignment must be a power of 2");
@@ -676,7 +708,7 @@ static void ParseSegments (void)
 
                case CFGTOK_OFFSET:
                    FlagAttr (&S->Attr, SA_OFFSET, "OFFSET");
-                   S->Addr   = CfgCheckedIntExpr (1, 0x1000000);
+                   S->Addr   = CfgCheckedConstExpr (1, 0x1000000);
                    S->Flags |= SF_OFFSET;
                    break;
 
@@ -697,7 +729,7 @@ static void ParseSegments (void)
 
                case CFGTOK_START:
                    FlagAttr (&S->Attr, SA_START, "START");
-                   S->Addr   = CfgCheckedIntExpr (1, 0x1000000);
+                   S->Addr   = CfgCheckedConstExpr (1, 0x1000000);
                    S->Flags |= SF_START;
                    break;
 
@@ -732,15 +764,6 @@ static void ParseSegments (void)
            S->Run = S->Load;
        }
 
-       /* If the segment is marked as BSS style, and if the segment exists
-         * in any of the object file, check that there's no initialized data
-         * in the segment.
-        */
-       if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
-           Warning ("%s(%u): Segment with type `bss' contains initialized data",
-                    CfgGetName (), CfgErrorLine);
-       }
-
         /* An attribute of ALIGN_LOAD doesn't make sense if there are no
          * separate run and load memory areas.
          */
@@ -776,29 +799,6 @@ static void ParseSegments (void)
                    CfgError ("Only one of ALIGN, START, OFFSET may be used");
        }
 
-       /* If this segment does exist in any of the object files, insert the
-        * descriptor into the list of segment descriptors. Otherwise print a
-         * warning and discard it, because the segment pointer in the
-         * descriptor is invalid.
-        */
-       if (S->Seg != 0) {
-           /* Insert the descriptor into the list of all descriptors */
-           SegDescInsert (S);
-           /* Insert the segment into the memory area list */
-           MemoryInsert (S->Run, S);
-           if (S->Load != S->Run) {
-               /* We have separate RUN and LOAD areas */
-               MemoryInsert (S->Load, S);
-           }
-       } else {
-            /* Print a warning if the segment is not optional */
-            if ((S->Flags & SF_OPTIONAL) == 0) {
-                CfgWarning ("Segment `%s' does not exist", GetString (S->Name));
-            }
-           /* Discard the descriptor */
-           FreeSegDesc (S);
-       }
-
        /* Skip the semicolon */
        CfgConsumeSemi ();
     }
@@ -845,7 +845,6 @@ static void ParseO65 (void)
     unsigned AttrFlags = atNone;
 
     /* Remember the attributes read */
-    unsigned CfgSValId;
     unsigned OS = 0;            /* Initialize to keep gcc happy */
     unsigned Version = 0;
 
@@ -869,23 +868,8 @@ static void ParseO65 (void)
                 AttrFlags |= atExport;
                /* We expect an identifier */
                CfgAssureIdent ();
-                /* Convert the string into a string index */
-                CfgSValId = GetStrBufId (&CfgSVal);
-               /* Check if the export symbol is also defined as an import. */
-               if (O65GetImport (O65FmtDesc, CfgSValId) != 0) {
-                   CfgError ("Exported symbol `%s' cannot be an import",
-                              SB_GetConstBuf (&CfgSVal));
-               }
-               /* Check if we have this symbol defined already. The entry
-                * routine will check this also, but we get a more verbose
-                * error message when checking it here.
-                */
-               if (O65GetExport (O65FmtDesc, CfgSValId) != 0) {
-                   CfgError ("Duplicate exported symbol: `%s'",
-                              SB_GetConstBuf (&CfgSVal));
-               }
-               /* Insert the symbol into the table */
-               O65SetExport (O65FmtDesc, CfgSValId);
+                /* Remember it as an export for later */
+                CollAppend (&O65Exports, NewO65Symbol ());
                 /* Eat the identifier token */
                 CfgNextTok ();
                break;
@@ -895,23 +879,8 @@ static void ParseO65 (void)
                 AttrFlags |= atImport;
                /* We expect an identifier */
                CfgAssureIdent ();
-                /* Convert the string into a string index */
-                CfgSValId = GetStrBufId (&CfgSVal);
-               /* Check if the imported symbol is also defined as an export. */
-               if (O65GetExport (O65FmtDesc, CfgSValId) != 0) {
-                   CfgError ("Imported symbol `%s' cannot be an export",
-                              SB_GetConstBuf (&CfgSVal));
-               }
-               /* Check if we have this symbol defined already. The entry
-                * routine will check this also, but we get a more verbose
-                * error message when checking it here.
-                */
-               if (O65GetImport (O65FmtDesc, CfgSValId) != 0) {
-                   CfgError ("Duplicate imported symbol: `%s'",
-                              SB_GetConstBuf (&CfgSVal));
-               }
-               /* Insert the symbol into the table */
-               O65SetImport (O65FmtDesc, CfgSValId);
+                /* Remember it as an import for later */
+                CollAppend (&O65Imports, NewO65Symbol ());
                 /* Eat the identifier token */
                 CfgNextTok ();
                break;
@@ -919,7 +888,7 @@ static void ParseO65 (void)
            case CFGTOK_TYPE:
                /* Cannot have this attribute twice */
                FlagAttr (&AttrFlags, atType, "TYPE");
-               /* Get the type of the executable */
+               /* Get the type of the executable */
                CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
                switch (CfgTok) {
 
@@ -964,14 +933,14 @@ static void ParseO65 (void)
                 /* Cannot have this attribute twice */
                 FlagAttr (&AttrFlags, atID, "ID");
                 /* We're expecting a number in the 0..$FFFF range*/
-                ModuleId = (unsigned) CfgCheckedIntExpr (0, 0xFFFF);
+                ModuleId = (unsigned) CfgCheckedConstExpr (0, 0xFFFF);
                 break;
 
             case CFGTOK_VERSION:
                 /* Cannot have this attribute twice */
                 FlagAttr (&AttrFlags, atVersion, "VERSION");
                 /* We're expecting a number in byte range */
-                Version = (unsigned) CfgCheckedIntExpr (0, 0xFF);
+                Version = (unsigned) CfgCheckedConstExpr (0, 0xFF);
                 break;
 
            default:
@@ -1237,7 +1206,7 @@ static void ParseStartAddress (void)
                /* Don't allow this twice */
                FlagAttr (&AttrFlags, atDefault, "DEFAULT");
                /* We expect a numeric expression */
-                DefStartAddr = CfgCheckedIntExpr (0, 0xFFFFFF);
+                DefStartAddr = CfgCheckedConstExpr (0, 0xFFFFFF);
                break;
 
            default:
@@ -1322,8 +1291,7 @@ static void ParseSymbols (void)
     while (CfgTok == CFGTOK_IDENT) {
 
        long Val = 0L;
-        int  Weak = 0;
-        Export* E;
+        unsigned Flags = SYM_NONE;
 
        /* Remember the name */
        unsigned Name = GetStrBufId (&CfgSVal);
@@ -1343,13 +1311,16 @@ static void ParseSymbols (void)
             /* Make sure the next token is an integer expression, read and
              * skip it.
              */
-            Val = CfgIntExpr ();
+            Val = CfgConstExpr ();
+
+            /* This is a defined symbol */
+            Flags = SYM_DEF;
 
         } else {
 
             /* Bitmask to remember the attributes we got already */
             enum {
-                atNone         = 0x0000,
+                atNone         = 0x0000,
                 atValue         = 0x0001,
                 atWeak          = 0x0002
             };
@@ -1380,14 +1351,18 @@ static void ParseSymbols (void)
                         /* Don't allow this twice */
                         FlagAttr (&AttrFlags, atValue, "VALUE");
                         /* We expect a numeric expression */
-                        Val = CfgIntExpr ();
+                        Val = CfgConstExpr ();
+                        /* Symbol is defined */
+                        Flags |= SYM_DEF;
                         break;
 
                     case CFGTOK_WEAK:
                         /* Don't allow this twice */
                         FlagAttr (&AttrFlags, atWeak, "WEAK");
                         CfgBoolToken ();
-                        Weak = (CfgTok == CFGTOK_TRUE);
+                        if (CfgTok == CFGTOK_TRUE) {
+                            Flags |= SYM_WEAK;
+                        }
                         CfgNextTok ();
                         break;
 
@@ -1406,26 +1381,10 @@ static void ParseSymbols (void)
 
             /* Check if we have all mandatory attributes */
             AttrCheck (AttrFlags, atValue, "VALUE");
-
-            /* Weak is optional, the default are non weak symbols */
-            if ((AttrFlags & atWeak) == 0) {
-                Weak = 0;
-            }
-
         }
 
-        /* Check if the symbol is already defined */
-        if ((E = FindExport (Name)) != 0 && !IsUnresolvedExport (E)) {
-            /* If the symbol is not marked as weak, this is an error.
-             * Otherwise ignore the symbol from the config.
-             */
-            if (!Weak) {
-                CfgError ("Symbol `%s' is already defined", GetString (Name));
-            }
-        } else {
-            /* The symbol is undefined, generate an export */
-            CreateConstExport (Name, Val);
-        }
+        /* Remember the symbol for later */
+        CollAppend (&Symbols, NewSymbol (Name, Flags, Val));
 
        /* Skip the semicolon */
        CfgConsumeSemi ();
@@ -1521,6 +1480,220 @@ void CfgRead (void)
 
 
 
+/*****************************************************************************/
+/*                          Config file processing                           */
+/*****************************************************************************/
+
+
+
+static void ProcessMemory (void)
+/* Process the MEMORY section */
+{
+    /* Walk over the list with the memory areas */
+    unsigned I;
+    for (I = 0; I < CollCount (&MemoryAreas); ++I) {
+
+        /* Get the next memory area */
+        MemoryArea* M = CollAtUnchecked (&MemoryAreas, I);
+
+        /* Remember if this is a relocatable memory area */
+        M->Relocatable = RelocatableBinFmt (M->F->Format);
+
+        /* Resolve the expressions */
+        if (!IsConstExpr (M->StartExpr)) {
+            Error ("Start address of memory area `%s' is not constant",
+                   GetString (M->Name));
+        }
+        M->Start = GetExprVal (M->StartExpr);
+
+        if (!IsConstExpr (M->SizeExpr)) {
+            Error ("Size of memory area `%s' is not constant",
+                   GetString (M->Name));
+        }
+        M->Size = GetExprVal (M->SizeExpr);
+
+        /* Mark the memory area as placed */
+        M->Flags |= MF_PLACED;
+    }
+}
+
+
+
+static void ProcessSegments (void)
+/* Process the SEGMENTS section */
+{
+    unsigned I;
+
+    /* Walk over the list of segment descriptors */
+    I = 0;
+    while (I < CollCount (&SegDescList)) {
+
+        /* Get the next segment descriptor */
+       SegDesc* S = CollAtUnchecked (&SegDescList, I);
+
+        /* Search for the actual segment in the input files. The function may
+         * return NULL (no such segment), this is checked later.
+         */
+        S->Seg = SegFind (S->Name);
+
+       /* If the segment is marked as BSS style, and if the segment exists
+         * in any of the object file, check that there's no initialized data
+         * in the segment.
+        */
+       if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
+                   Warning ("Segment `%s' with type `bss' contains initialized data",
+                    GetString (S->Name));
+       }
+
+       /* If this segment does exist in any of the object files, insert the
+                * segment into the load/run memory areas. Otherwise print a warning
+         * and discard it, because the segment pointer in the descriptor is
+         * invalid.
+        */
+       if (S->Seg != 0) {
+
+           /* Insert the segment into the memory area list */
+           MemoryInsert (S->Run, S);
+           if (S->Load != S->Run) {
+               /* We have separate RUN and LOAD areas */
+               MemoryInsert (S->Load, S);
+           }
+
+            /* Process the next segment descriptor in the next run */
+            ++I;
+
+       } else {
+
+            /* Print a warning if the segment is not optional */
+            if ((S->Flags & SF_OPTIONAL) == 0) {
+                CfgWarning ("Segment `%s' does not exist", GetString (S->Name));
+            }
+
+           /* Discard the descriptor and remove it from the collection */
+           FreeSegDesc (S);
+            CollDelete (&SegDescList, I);
+       }
+    }
+}
+
+
+
+static void ProcessO65 (void)
+/* Process the o65 format section */
+{
+    unsigned I;
+
+    /* Walk over the imports, check and add them to the o65 data */
+    for (I = 0; I < CollCount (&O65Imports); ++I) {
+
+        /* Get the import */
+        Symbol* Sym = CollAtUnchecked (&O65Imports, I);
+
+        /* Check if we have this symbol defined already. The entry
+         * routine will check this also, but we get a more verbose
+         * error message when checking it here.
+         */
+        if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
+            Error ("%s(%u): Duplicate imported o65 symbol: `%s'",
+                   Sym->CfgName, Sym->CfgLine, GetString (Sym->Name));
+        }
+
+        /* Insert the symbol into the table */
+        O65SetImport (O65FmtDesc, Sym->Name);
+    }
+
+    /* Walk over the exports, check and add them to the o65 data */
+    for (I = 0; I < CollCount (&O65Exports); ++I) {
+
+        /* Get the export */
+        Symbol* Sym = CollAtUnchecked (&O65Exports, I);
+
+        /* Check if the export symbol is also defined as an import. */
+        if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
+            Error ("%s(%u): Exported o65 symbol `%s' cannot also be an o65 import",
+                   Sym->CfgName, Sym->CfgLine, GetString (Sym->Name));
+        }
+
+        /* Check if we have this symbol defined already. The entry
+         * routine will check this also, but we get a more verbose
+         * error message when checking it here.
+         */
+        if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
+            Error ("%s(%u): Duplicate exported o65 symbol: `%s'",
+                   Sym->CfgName, Sym->CfgLine, GetString (Sym->Name));
+        }
+
+        /* Insert the symbol into the table */
+        O65SetExport (O65FmtDesc, Sym->Name);
+    }
+}
+
+
+
+static void ProcessBin (void)
+/* Process the bin format section */
+{
+}
+
+
+
+static void ProcessFormats (void)
+/* Process the target format section */
+{
+    ProcessO65 ();
+    ProcessBin ();
+}
+
+
+
+static void ProcessSymbols (void)
+/* Process the SYMBOLS section */
+{
+    Export* E;
+
+    /* Walk over all symbols */
+    unsigned I;
+    for (I = 0; I < CollCount (&Symbols); ++I) {
+
+        /* Get the next symbol */
+        Symbol* Sym = CollAtUnchecked (&Symbols, I);
+
+        /* Do we define this symbol? */
+        if ((Sym->Flags & SYM_DEF) != 0) {
+            /* Check if the symbol is already defined somewhere else */
+            if ((E = FindExport (Sym->Name)) != 0 && !IsUnresolvedExport (E)) {
+                /* If the symbol is not marked as weak, this is an error.
+                 * Otherwise ignore the symbol from the config.
+                 */
+                if ((Sym->Flags & SYM_WEAK) == 0) {
+                    CfgError ("Symbol `%s' is already defined",
+                              GetString (Sym->Name));
+                }
+            } else {
+                /* The symbol is undefined, generate an export */
+                CreateConstExport (Sym->Name, Sym->Val);
+            }
+
+        } else {
+
+
+        }
+    }
+}
+
+
+
+void CfgProcess (void)
+/* Process the config file after reading in object files and libraries */
+{
+    ProcessSymbols (); /* ######## */
+    ProcessMemory ();
+    ProcessSegments ();
+    ProcessFormats ();
+}
+
+
+
 static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
 /* Create the defines for a RUN segment */
 {
@@ -1563,19 +1736,16 @@ unsigned CfgAssignSegments (void)
      * segments while doing this.
      */
     unsigned I;
-    for (I = 0; I < CollCount (&MemoryList); ++I) {
+    for (I = 0; I < CollCount (&MemoryAreas); ++I) {
 
         unsigned J;
 
         /* Get this entry */
-        Memory* M = CollAtUnchecked (&MemoryList, I);
+        MemoryArea* M = CollAtUnchecked (&MemoryAreas, I);
 
        /* 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 */
         for (J = 0; J < CollCount (&M->SegList); ++J) {
 
@@ -1622,6 +1792,9 @@ unsigned CfgAssignSegments (void)
                 S->Seg->ReadOnly = (S->Flags & SF_RO) != 0;
                 S->Seg->Relocatable = M->Relocatable;
 
+                /* Remember that this segment is placed */
+                S->Seg->Placed = 1;
+
             } else if (S->Load == M) {
 
                 /* This is the load memory area, *and* run and load are
@@ -1696,7 +1869,7 @@ void CfgWriteTarget (void)
         File* F = CollAtUnchecked (&FileList, I);
 
        /* We don't need to look at files with no memory areas */
-       if (CollCount (&F->MemList) > 0) {
+       if (CollCount (&F->MemoryAreas) > 0) {
 
            /* Is there an output file? */
            if (SB_GetLen (GetStrBuf (F->Name)) > 0) {
@@ -1714,7 +1887,7 @@ void CfgWriteTarget (void)
                        break;
 
                    case BINFMT_O65:
-                       O65WriteTarget (O65FmtDesc, F);
+                       O65WriteTarget (O65FmtDesc, F);
                        break;
 
                    default:
@@ -1728,12 +1901,12 @@ void CfgWriteTarget (void)
                         * loading into these memory areas in this file as dumped.
                 */
                 unsigned J;
-                for (J = 0; J < CollCount (&F->MemList); ++J) {
+                for (J = 0; J < CollCount (&F->MemoryAreas); ++J) {
 
                     unsigned K;
 
                     /* Get this entry */
-                   Memory* M = CollAtUnchecked (&F->MemList, J);
+                   MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, J);
 
                    /* Debugging */
                            Print (stdout, 2, "Skipping `%s'...\n", GetString (M->Name));
index aa455da0000a02a3fe8ec214ea329b7c99b87b5e..4f16e6dab005689d872f3f08fb301b9f91fe9b78 100644 (file)
 
 
 
+/* Forward for struct MemoryArea */
+struct MemoryArea;
+
 /* File list entry */
 typedef struct File File;
 struct File {
     unsigned            Name;           /* Name index of the file */
-    unsigned           Flags;
-    unsigned           Format;         /* Output format */
-    Collection          MemList;        /* List of memory areas in this file */
-};
-
-/* Memory list entry */
-typedef struct Memory Memory;
-struct Memory {
-    unsigned            Name;           /* Name index of the memory section */
-    unsigned                   Attr;           /* Which values are valid? */
-    unsigned           Flags;          /* Set of bitmapped flags */
-    unsigned long      Start;          /* Start address */
-    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 area is relocatable */
-    Collection          SegList;       /* List of segments for this section */
-    File*              F;              /* File that contains the entry */
+    unsigned           Flags;
+    unsigned           Format;         /* Output format */
+    Collection          MemoryAreas;    /* List of memory areas in this file */
 };
 
 /* Segment descriptor entry */
@@ -83,19 +71,13 @@ struct SegDesc {
     Segment*                   Seg;            /* Pointer to segment structure */
     unsigned                   Attr;           /* Attributes for segment */
     unsigned                   Flags;          /* Set of bitmapped flags */
-    Memory*            Load;           /* Load memory section */
-    Memory*                    Run;            /* Run memory section */
+    struct MemoryArea*  Load;           /* Load memory section */
+    struct MemoryArea*  Run;            /* Run memory section */
     unsigned long              Addr;           /* Start address or offset into segment */
     unsigned char      Align;          /* Run area alignment if given */
     unsigned char       AlignLoad;      /* Load area alignment if given */
 };
 
-/* Memory flags */
-#define MF_DEFINE              0x0001          /* Define start and size */
-#define MF_FILL                0x0002          /* Fill segment */
-#define MF_RO          0x0004          /* Read only memory area */
-#define MF_OVERFLOW     0x0008          /* Memory area overflow */
-
 /* Segment flags */
 #define SF_RO                  0x0001          /* Read only segment */
 #define SF_BSS                 0x0002          /* Segment is BSS style segment */
@@ -120,6 +102,9 @@ struct SegDesc {
 void CfgRead (void);
 /* Read the configuration */
 
+void CfgProcess (void);
+/* Process the config file after reading in object files and libraries */
+
 unsigned CfgAssignSegments (void);
 /* Assign segments, define linker symbols where requested. The function will
  * return the number of memory area overflows (so zero means anything went ok).
index b971308999bd3ec1b317575206b6cb9bd70d5158..ca44892af9d100ada8775c9dea240f23acca79c2 100644 (file)
@@ -52,6 +52,7 @@
 #include "expr.h"
 #include "fileio.h"
 #include "global.h"
+#include "memarea.h"
 #include "objdata.h"
 #include "spool.h"
 
@@ -176,14 +177,14 @@ Import* ReadImport (FILE* F, ObjData* Obj)
 
 
 
-Import* GenImport (const char* Name, unsigned char AddrSize)
+Import* GenImport (unsigned Name, unsigned char AddrSize)
 /* Generate a new import with the given name and address size and return it */
 {
     /* Create a new import */
     Import* I = NewImport (AddrSize, 0);
 
     /* Read the name */
-    I->Name = GetStringId (Name);
+    I->Name = Name;
 
     /* Check the address size */
     if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) {
@@ -211,8 +212,8 @@ Import* GenImport (const char* Name, unsigned char AddrSize)
 
 
 
-void InsertImport (Import* I)
-/* Insert an import into the table */
+Import* InsertImport (Import* I)
+/* Insert an import into the table, return I */
 {
     Export* E;
 
@@ -261,6 +262,9 @@ void InsertImport (Import* I)
 
     /* Mark the import so we know it's in the list */
     I->Flags |= IMP_INLIST;
+
+    /* Return the import to allow shorter code */
+    return I;
 }
 
 
@@ -463,7 +467,7 @@ Export* CreateConstExport (unsigned Name, long Value)
 
 
 
-Export* CreateMemoryExport (unsigned Name, Memory* Mem, unsigned long Offs)
+Export* CreateMemoryExport (unsigned Name, MemoryArea* Mem, unsigned long Offs)
 /* Create an relative export for a memory area offset */
 {
     /* Create a new export */
index e3c3d89a1081e84d4dbc7b48add5259ea797965c..170f80978fa7b57cffdc9512f520f90d68733432 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/* (C) 1998-2010, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -46,8 +46,9 @@
 #include "filepos.h"
 
 /* ld65 */
-#include "objdata.h"
 #include "config.h"
+#include "memarea.h"
+#include "objdata.h"
 
 
 
@@ -114,11 +115,11 @@ void FreeImport (Import* I);
 Import* ReadImport (FILE* F, ObjData* Obj);
 /* Read an import from a file and insert it into the table */
 
-Import* GenImport (const char* Name, unsigned char AddrSize);
+Import* GenImport (unsigned Name, unsigned char AddrSize);
 /* Generate a new import with the given name and address size and return it */
 
-void InsertImport (Import* I);
-/* Insert an import into the table */
+Import* InsertImport (Import* I);
+/* Insert an import into the table, return I */
 
 void FreeExport (Export* E);
 /* Free an export. NOTE: This won't remove the export from the exports table,
@@ -135,7 +136,7 @@ void InsertExport (Export* E);
 Export* CreateConstExport (unsigned Name, long Value);
 /* Create an export for a literal date */
 
-Export* CreateMemoryExport (unsigned Name, Memory* Mem, unsigned long Offs);
+Export* CreateMemoryExport (unsigned Name, MemoryArea* Mem, unsigned long Offs);
 /* Create an relative export for a memory area offset */
 
 Export* CreateSegmentExport (unsigned Name, Segment* Seg, unsigned long Offs);
index 94f910d7acfe54d78700eeff71f8fe5b236c6e55..a5b7a3c5c3da8aba1bfe8648acb51d5a6d1ef234 100644 (file)
 #include "global.h"
 #include "error.h"
 #include "fileio.h"
+#include "memarea.h"
 #include "segments.h"
 #include "expr.h"
 
 
 
 /*****************************************************************************/
-/*                                 Helpers                                  */
+/*                                          Code                                    */
 /*****************************************************************************/
 
 
 
-static ExprNode* NewExprNode (ObjData* O)
+ExprNode* NewExprNode (ObjData* O, unsigned char Op)
 /* Create a new expression node */
 {
     /* Allocate fresh memory */
     ExprNode* N = xmalloc (sizeof (ExprNode));
-    N->Op      = EXPR_NULL;
+    N->Op      = Op;
     N->Left    = 0;
     N->Right   = 0;
     N->Obj     = O;
@@ -78,12 +79,6 @@ static void FreeExprNode (ExprNode* E)
 
 
 
-/*****************************************************************************/
-/*                                          Code                                    */
-/*****************************************************************************/
-
-
-
 void FreeExpr (ExprNode* Root)
 /* Free the expression, Root is pointing to. */
 {
@@ -130,18 +125,19 @@ int IsConstExpr (ExprNode* Root)
 
             case EXPR_SECTION:
                 /* A section expression is const if the segment it is in is
-                 * not relocatable.
+                 * not relocatable and already placed.
                  */
                 S = GetExprSection (Root);
-                return !S->Seg->Relocatable;
+                return !S->Seg->Relocatable && S->Seg->Placed;
 
             case EXPR_SEGMENT:
-                /* A segment is const if it is not relocatable */
-                return !Root->V.Seg->Relocatable;
+                /* A segment is const if it is not relocatable and placed */
+                return !Root->V.Seg->Relocatable && Root->V.Seg->Placed;
 
             case EXPR_MEMAREA:
-                /* A memory area is const if it is not relocatable */
-                return !Root->V.Mem->Relocatable;
+                /* A memory area is const if it is not relocatable and placed */
+                return !Root->V.Mem->Relocatable && 
+                       (Root->V.Mem->Flags & MF_PLACED);
 
            default:
                 /* Anything else is not const */
@@ -201,7 +197,7 @@ Import* GetExprImport (ExprNode* Expr)
     PRECONDITION (Expr->Op == EXPR_SYMBOL);
 
     /* Return the import */
-    return CollAt (&Expr->Obj->Imports, Expr->V.ImpNum);
+    return Expr->V.Imp;
 }
 
 
@@ -397,26 +393,23 @@ long GetExprVal (ExprNode* Expr)
 ExprNode* LiteralExpr (long Val, ObjData* O)
 /* Return an expression tree that encodes the given literal value */
 {
-    ExprNode* Expr = NewExprNode (O);
-    Expr->Op = EXPR_LITERAL;
+    ExprNode* Expr = NewExprNode (O, EXPR_LITERAL);
     Expr->V.IVal = Val;
     return Expr;
 }
 
 
 
-ExprNode* MemoryExpr (Memory* Mem, long Offs, ObjData* O)
+ExprNode* MemoryExpr (MemoryArea* Mem, long Offs, ObjData* O)
 /* Return an expression tree that encodes an offset into a memory area */
 {
     ExprNode* Root;
 
-    ExprNode* Expr = NewExprNode (O);
-    Expr->Op = EXPR_MEMAREA;
+    ExprNode* Expr = NewExprNode (O, EXPR_MEMAREA);
     Expr->V.Mem = Mem;
 
     if (Offs != 0) {
-        Root = NewExprNode (O);
-        Root->Op = EXPR_PLUS;
+        Root = NewExprNode (O, EXPR_PLUS);
         Root->Left = Expr;
         Root->Right = LiteralExpr (Offs, O);
     } else {
@@ -433,13 +426,11 @@ ExprNode* SegmentExpr (Segment* Seg, long Offs, ObjData* O)
 {
     ExprNode* Root;
 
-    ExprNode* Expr = NewExprNode (O);
-    Expr->Op = EXPR_SEGMENT;
+    ExprNode* Expr = NewExprNode (O, EXPR_SEGMENT);
     Expr->V.Seg = Seg;
 
     if (Offs != 0) {
-        Root = NewExprNode (O);
-        Root->Op = EXPR_PLUS;
+        Root = NewExprNode (O, EXPR_PLUS);
         Root->Left = Expr;
         Root->Right = LiteralExpr (Offs, O);
     } else {
@@ -456,13 +447,11 @@ ExprNode* SectionExpr (Section* Sec, long Offs, ObjData* O)
 {
     ExprNode* Root;
 
-    ExprNode* Expr = NewExprNode (O);
-    Expr->Op = EXPR_SECTION;
+    ExprNode* Expr = NewExprNode (O, EXPR_SECTION);
     Expr->V.Sec = Sec;
 
     if (Offs != 0) {
-        Root = NewExprNode (O);
-        Root->Op = EXPR_PLUS;
+        Root = NewExprNode (O, EXPR_PLUS);
         Root->Left = Expr;
         Root->Right = LiteralExpr (Offs, O);
     } else {
@@ -478,6 +467,7 @@ ExprNode* ReadExpr (FILE* F, ObjData* O)
 /* Read an expression from the given file */
 {
     ExprNode* Expr;
+    unsigned ImpNum;
 
     /* Read the node tag and handle NULL nodes */
     unsigned char Op = Read8 (F);
@@ -486,29 +476,29 @@ ExprNode* ReadExpr (FILE* F, ObjData* O)
     }
 
     /* Create a new node */
-    Expr = NewExprNode (O);
-    Expr->Op = Op;
+    Expr = NewExprNode (O, Op);
 
     /* Check the tag and handle the different expression types */
     if (EXPR_IS_LEAF (Op)) {
        switch (Op) {
 
            case EXPR_LITERAL:
-               Expr->V.IVal = Read32Signed (F);
-               break;
+               Expr->V.IVal = Read32Signed (F);
+               break;
 
            case EXPR_SYMBOL:
-               /* Read the import number */
-               Expr->V.ImpNum = ReadVar (F);
-               break;
+               /* Read the import number */
+               ImpNum = ReadVar (F);
+                Expr->V.Imp = CollAt (&O->Imports, ImpNum);
+               break;
 
            case EXPR_SECTION:
-               /* Read the segment number */
-               Expr->V.SegNum = Read8 (F);
-               break;
+               /* Read the segment number */
+               Expr->V.SegNum = Read8 (F);
+               break;
 
            default:
-               Error ("Invalid expression op: %02X", Op);
+               Error ("Invalid expression op: %02X", Op);
 
        }
 
@@ -550,8 +540,8 @@ int EqualExpr (ExprNode* E1, ExprNode* E2)
            return (E1->V.IVal == E2->V.IVal);
 
        case EXPR_SYMBOL:
-           /* Import number must be identical */
-           return (E1->V.ImpNum == E2->V.ImpNum);
+           /* Import must be identical */
+           return (E1->V.Imp == E2->V.Imp);
 
        case EXPR_SECTION:
                    /* Section must be identical */
@@ -563,7 +553,7 @@ int EqualExpr (ExprNode* E1, ExprNode* E2)
 
        case EXPR_MEMAREA:
                    /* Memory area must be identical */
-                   return (E1->V.Mem == E2->V.Mem );
+                   return (E1->V.Mem == E2->V.Mem);
 
        default:
            /* Not a leaf node */
index 536f08c41b0fe5bf0a06c8bf1809982df6b63cb7..0e9eafecf962786d2af986078c4ea1a5c6ed92c8 100644 (file)
@@ -54,6 +54,9 @@
 
 
 
+ExprNode* NewExprNode (ObjData* O, unsigned char Op);
+/* Create a new expression node */
+
 void FreeExpr (ExprNode* Root);
 /* Free the expression tree, Root is pointing to. */
 
@@ -77,7 +80,7 @@ long GetExprVal (ExprNode* Expr);
 ExprNode* LiteralExpr (long Val, ObjData* O);
 /* Return an expression tree that encodes the given literal value */
 
-ExprNode* MemoryExpr (Memory* Mem, long Offs, ObjData* O);
+ExprNode* MemoryExpr (MemoryArea* Mem, long Offs, ObjData* O);
 /* Return an expression tree that encodes an offset into the memory area */
 
 ExprNode* SegmentExpr (Segment* Seg, long Offs, ObjData* O);
index 228f6c2ee7ee3d68502f1343502eadee55f54f28..2c45d0010bc86f30cfba43edc21764cb0f93ead4 100644 (file)
@@ -211,14 +211,14 @@ static ObjData* ReadIndexEntry (Library* L)
     /* Read the string pool */
     ObjReadStrPool (L->F, FileGetPos (L->F), O);
 
-    /* Skip the export size, then read the exports */
-    (void) ReadVar (L->F);
-    ObjReadExports (L->F, FileGetPos (L->F), O);
-
     /* Skip the import size, then read the imports */
     (void) ReadVar (L->F);
     ObjReadImports (L->F, FileGetPos (L->F), O);
 
+    /* Skip the export size, then read the exports */
+    (void) ReadVar (L->F);
+    ObjReadExports (L->F, FileGetPos (L->F), O);
+
     /* Done */
     return O;
 }
index 10fff402e6c05a0d484397405ca2996453822e1f..19356630c721acfcc3bbcbab3eb3e6a43e39d08d 100644 (file)
@@ -302,6 +302,9 @@ static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
     } else {
         CfgSetName (PathName);
     }
+
+    /* Read the config */
+    CfgRead ();
 }
 
 
@@ -356,7 +359,7 @@ static void OptForceImport (const char* Opt attribute ((unused)), const char* Ar
         /* Use default address size (which for now is always absolute
          * addressing)
          */
-        InsertImport (GenImport (Arg, ADDR_SIZE_ABS));
+        InsertImport (GenImport (GetStringId (Arg), ADDR_SIZE_ABS));
 
     } else {
 
@@ -375,7 +378,7 @@ static void OptForceImport (const char* Opt attribute ((unused)), const char* Ar
         A[ColPos - Arg] = '\0';
 
         /* Generate the import */
-        InsertImport (GenImport (A, AddrSize));
+        InsertImport (GenImport (GetStringId (A), AddrSize));
 
         /* Delete the copy of the argument */
         xfree (A);
@@ -481,6 +484,9 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
     /* Set the target data */
     DefaultBinFmt = D->BinFmt;
     CfgSetBuf (D->Cfg);
+
+    /* Read the target config */
+    CfgRead ();
 }
 
 
@@ -643,12 +649,12 @@ int main (int argc, char* argv [])
     /* Check if we have open library groups */
     LibCheckGroup ();
 
-    /* Read the config file */
-    CfgRead ();
-
     /* Create the condes tables if requested */
     ConDesCreate ();
 
+    /* Process data from the config file */
+    CfgProcess ();
+
     /* Assign start addresses for the segments, define linker symbols. The
      * function will return the number of memory area overflows (zero on
      * success).
index 9d5c0c99692e8931d5be24571b3ab35a81effbec..292bd1e8b3558e3ca8d75647e787c01f3aa87bd8 100644 (file)
@@ -51,6 +51,7 @@ OBJS =        asserts.o       \
        lineinfo.o      \
        main.o          \
        mapfile.o       \
+        memarea.o       \
        o65.o           \
        objdata.o       \
        objfile.o       \
index c1f6b04af9588f05dcc08dab53da4193a51e2aa2..b54e1a3b041a31fe7a3d161cde5474fe80caba03 100644 (file)
@@ -82,6 +82,7 @@ OBJS =        asserts.obj     \
        lineinfo.obj    \
        main.obj        \
        mapfile.obj     \
+        memarea.obj     \
        o65.obj         \
        objdata.obj     \
        objfile.obj     \
diff --git a/src/ld65/memarea.c b/src/ld65/memarea.c
new file mode 100644 (file)
index 0000000..a637664
--- /dev/null
@@ -0,0 +1,76 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 memarea.c                                 */
+/*                                                                           */
+/*                Memory area definition for the ld65 linker                 */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2010,      Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "xmalloc.h"
+
+/* ld65 */
+#include "memarea.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+MemoryArea* NewMemoryArea (unsigned Name)
+/* Create a new memory area and insert it into the list */
+{
+    /* Allocate memory */
+    MemoryArea* M = xmalloc (sizeof (MemoryArea));
+
+    /* Initialize the fields ... */
+    M->Name        = Name;
+    M->Attr        = 0;
+    M->Flags       = 0;
+    M->StartExpr   = 0;
+    M->Start       = 0;
+    M->SizeExpr    = 0;
+    M->Size        = 0;
+    M->FillLevel   = 0;
+    M->FillVal     = 0;
+    M->Relocatable = 0;
+    InitCollection (&M->SegList);
+    M->F           = 0;
+
+    /* ...and return it */
+    return M;
+}
+
+
+
+
diff --git a/src/ld65/memarea.h b/src/ld65/memarea.h
new file mode 100644 (file)
index 0000000..7306c11
--- /dev/null
@@ -0,0 +1,100 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 memarea.h                                 */
+/*                                                                           */
+/*                Memory area definition for the ld65 linker                 */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2010,      Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 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 MEMAREA_H
+#define MEMAREA_H
+
+
+
+/* common */
+#include "coll.h"
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* Forwards for structures */
+struct ExprNode;
+struct File;
+
+/* Memory area entry */
+typedef struct MemoryArea MemoryArea;
+struct MemoryArea {
+    unsigned            Name;           /* Name index of the memory section */
+    unsigned                   Attr;           /* Which values are valid? */
+    unsigned                   Flags;          /* Set of bitmapped flags */
+    struct ExprNode*    StartExpr;      /* Expression for start address */
+    unsigned long              Start;          /* Start address */
+    struct ExprNode*    SizeExpr;       /* Expression for size */
+    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 area is relocatable */
+    Collection          SegList;       /* List of segments for this area */
+    struct File*               F;              /* Output file for this area */
+};
+
+/* Memory flags */
+#define MF_DEFINE              0x0001          /* Define start and size */
+#define MF_FILL                0x0002          /* Fill segment */
+#define MF_RO          0x0004          /* Read only memory area */
+#define MF_OVERFLOW     0x0008          /* Memory area overflow */
+#define MF_PLACED       0x0010          /* Memory area was placed */
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+MemoryArea* NewMemoryArea (unsigned Name);
+/* Create a new memory area and insert it into the list */
+
+
+
+/* End of memarea.h */
+
+#endif
+
+
+
+
+
index e583bb8c3dea176b9410d0153fe0b91731374a24..6845efed112d8acad023b1d3efaa7f289eb284fa 100644 (file)
@@ -53,6 +53,7 @@
 #include "fileio.h"
 #include "global.h"
 #include "lineinfo.h"
+#include "memarea.h"
 #include "o65.h"
 #include "spool.h"
 
@@ -175,7 +176,7 @@ struct ExprDesc {
     O65Desc*               D;                  /* File format descriptor */
     long                   Val;                /* The offset value */
     int                    TooComplex;         /* Expression too complex */
-    Memory*         MemRef;             /* Memory reference if any */
+    MemoryArea*     MemRef;             /* Memory reference if any */
     Segment*        SegRef;             /* Segment reference if any */
     Section*               SecRef;             /* Section reference if any */
     ExtSym*                ExtRef;             /* External reference if any */
@@ -244,7 +245,7 @@ static void CvtMemoryToSegment (ExprDesc* ED)
  */
 {
     /* Get the memory area from the expression */
-    Memory* M = ED->MemRef;
+    MemoryArea* M = ED->MemRef;
 
     /* Remember the "nearest" segment and its offset */
     Segment* Nearest   = 0;
@@ -1227,9 +1228,9 @@ static void O65SetupSegments (O65Desc* D, File* F)
     D->ZPCount   = 0;
 
     /* Walk over the memory list */
-    for (I = 0; I < CollCount (&F->MemList); ++I) {
+    for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
         /* Get this entry */
-        Memory* M = CollAtUnchecked (&F->MemList, I);
+        MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I);
 
         /* Walk through the segment list and count the segment types */
         unsigned J;
@@ -1257,9 +1258,9 @@ static void O65SetupSegments (O65Desc* D, File* F)
 
     /* Walk again through the list and setup the segment arrays */
     TextIdx = DataIdx = BssIdx = ZPIdx = 0;
-    for (I = 0; I < CollCount (&F->MemList); ++I) {
+    for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
         /* Get this entry */
-        Memory* M = CollAtUnchecked (&F->MemList, I);
+        MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I);
 
         /* Walk over the segment list and check the segment types */
         unsigned J;
index f9154e194237ef2626cdc0f83ce9a9e9dbdd61e0..3d762cae1efb2743a8702d981f9d69c5d24c4260 100644 (file)
@@ -103,6 +103,7 @@ static Segment* NewSegment (unsigned Name, unsigned char AddrSize)
     S->AddrSize    = AddrSize;
     S->ReadOnly    = 0;
     S->Relocatable = 0;
+    S->Placed      = 0;
     S->Dumped      = 0;
 
     /* Insert the segment into the segment list and assign the segment id */
@@ -487,7 +488,7 @@ void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void*
 /* Write the data from the given segment to a file. For expressions, F is
  * called (see description of SegWriteFunc above).
  */
-{   
+{
     Section*      Sec;
     int           Sign;
     unsigned long Offs = 0;
index c61d7839e62b582056e7fbef9c2f46c2e06867fa..3af9fa09e412cce34ab1ceb7889a3a0c4562222a 100644 (file)
@@ -70,6 +70,7 @@ struct Segment {
     unsigned char      AddrSize;       /* Address size of segment */
     unsigned char       ReadOnly;       /* True for readonly segments (config) */
     unsigned char       Relocatable;    /* True if the segment is relocatable */
+    unsigned char       Placed;         /* Did we place this segment already? */ 
     unsigned char              Dumped;         /* Did we dump this segment? */
 };