]> git.sur5r.net Git - cc65/commitdiff
Use a string pool to reduce the memory footprint
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 4 Jun 2003 12:40:14 +0000 (12:40 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 4 Jun 2003 12:40:14 +0000 (12:40 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2197 b7a2c559-68d2-44c3-8de9-860c34a00d81

27 files changed:
src/ca65/listing.c
src/ca65/objcode.c
src/common/fragdefs.h [new file with mode: 0644]
src/common/segdefs.h
src/ld65/bin.c
src/ld65/condes.c
src/ld65/condes.h
src/ld65/config.c
src/ld65/config.h
src/ld65/dbgsyms.c
src/ld65/dbgsyms.h
src/ld65/exports.c
src/ld65/exports.h
src/ld65/expr.c
src/ld65/fragment.c
src/ld65/fragment.h
src/ld65/library.c
src/ld65/main.c
src/ld65/mapfile.c
src/ld65/o65.c
src/ld65/objdata.c
src/ld65/objdata.h
src/ld65/objfile.c
src/ld65/segments.c
src/ld65/segments.h
src/ld65/spool.c
src/ld65/spool.h

index f7e777bcc80b218d73701aed23367c3f24372305..a7d6d3c99c7fd2d5addf9904f033c9bd3204b431 100644 (file)
@@ -40,7 +40,7 @@
 /* common */
 #include "check.h"
 #include "fname.h"
-#include "segdefs.h"
+#include "fragdefs.h"
 #include "version.h"
 #include "xmalloc.h"
 
index f483fabeae35393ecc155416d511b1ef87418c50..bbb42b8f18488cff36dd04a40d1bd2274a4a47c9 100644 (file)
@@ -39,6 +39,7 @@
 /* common */
 #include "chartype.h"
 #include "check.h"
+#include "fragdefs.h"
 #include "segdefs.h"
 #include "segnames.h"
 #include "xmalloc.h"
 #include "global.h"
 #include "lineinfo.h"
 #include "listing.h"
+#include "objcode.h"
 #include "objfile.h"
 #include "scanner.h"
+#include "spool.h"
 #include "symtab.h"
-#include "objcode.h"
 
 
 
@@ -420,11 +422,11 @@ static void WriteOneSeg (Segment* Seg)
     ObjWrite32 (0);
 
     /* Write the segment data */
-    ObjWriteStr (Seg->Def->Name);       /* Name of the segment */
-    ObjWrite32 (Seg->PC);               /* Size */
-    ObjWrite8 (Seg->Align);             /* Segment alignment */
-    ObjWrite8 (Seg->Def->Type);         /* Type of the segment */
-    ObjWriteVar (Seg->FragCount);       /* Number of fragments that follow */
+    ObjWriteVar (GetStringId (Seg->Def->Name)); /* Name of the segment */
+    ObjWrite32 (Seg->PC);                       /* Size */
+    ObjWrite8 (Seg->Align);                     /* Segment alignment */
+    ObjWrite8 (Seg->Def->Type);                 /* Type of the segment */
+    ObjWriteVar (Seg->FragCount);               /* Number of fragments */
 
     /* Now walk through the fragment list for this segment and write the
      * fragments.
diff --git a/src/common/fragdefs.h b/src/common/fragdefs.h
new file mode 100644 (file)
index 0000000..257b20f
--- /dev/null
@@ -0,0 +1,83 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                fragdefs.h                                */
+/*                                                                           */
+/*              Fragment definitions for the bin65 binary utils              */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef FRAGDEFS_H
+#define FRAGDEFS_H
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* Masks for the fragment type byte */
+#define FRAG_TYPEMASK   0x38                   /* Mask the type of the fragment */
+#define FRAG_BYTEMASK   0x07                   /* Mask for byte count */
+#define FRAG_CHECKMASK  0x40            /* Mask for check expressions */
+
+/* Fragment types */
+#define FRAG_LITERAL           0x00            /* Literal data */
+
+#define FRAG_EXPR              0x08            /* Expression */
+#define FRAG_EXPR8             (FRAG_EXPR | 1) /* 8 bit expression */
+#define FRAG_EXPR16            (FRAG_EXPR | 2) /* 16 bit expression */
+#define FRAG_EXPR24            (FRAG_EXPR | 3) /* 24 bit expression */
+#define FRAG_EXPR32            (FRAG_EXPR | 4) /* 32 bit expression */
+
+#define FRAG_SEXPR             0x10            /* Signed expression */
+#define FRAG_SEXPR8            (FRAG_SEXPR | 1)/* 8 bit signed expression */
+#define FRAG_SEXPR16           (FRAG_SEXPR | 2)/* 16 bit signed expression */
+#define FRAG_SEXPR24           (FRAG_SEXPR | 3)/* 24 bit signed expression */
+#define FRAG_SEXPR32           (FRAG_SEXPR | 4)/* 32 bit signed expression */
+
+#define FRAG_FILL              0x20            /* Fill bytes */
+
+/* Fragment checks */
+#define FRAG_CHECK      0x40            /* Check expressions exist */
+
+/* Fragment check actions */
+#define FRAG_ACT_WARN   0x00U           /* Print a warning */
+#define FRAG_ACT_ERROR  0x01U           /* Exit with an error */
+
+
+
+/* End of fragdefs.h */
+
+#endif
+
+
+
index b6bc530b67ca54ed43b0e549fd86b455ad7c9a94..c41edaff3caaee882f59362a391ad086bfcb96ab 100644 (file)
 #define SEGTYPE_ZP                     2
 #define SEGTYPE_FAR                    3
 
-/* Fragment types in the object file */
-#define FRAG_TYPEMASK                  0x38    /* Mask the type of the fragment */
-#define FRAG_BYTEMASK           0x07           /* Mask for byte count */
-#define FRAG_CHECKMASK          0x40    /* Mask for check expressions */
-
-/* Fragment types */
-#define FRAG_LITERAL                   0x00    /* Literal data */
-
-#define FRAG_EXPR                      0x08    /* Expression */
-#define FRAG_EXPR8                     0x09    /* 8 bit expression */
-#define FRAG_EXPR16                    0x0A    /* 16 bit expression */
-#define FRAG_EXPR24                    0x0B    /* 24 bit expression */
-#define FRAG_EXPR32                    0x0C    /* 32 bit expression */
-
-#define FRAG_SEXPR                     0x10    /* Signed expression */
-#define FRAG_SEXPR8                    0x11    /* 8 bit signed expression */
-#define FRAG_SEXPR16                   0x12    /* 16 bit signed expression */
-#define FRAG_SEXPR24                   0x13    /* 24 bit signed expression */
-#define FRAG_SEXPR32                   0x14    /* 32 bit signed expression */
-
-#define FRAG_FILL                      0x20    /* Fill bytes */
-
-/* Fragment checks */
-#define FRAG_CHECK              0x40    /* Check expressions exist */
-
-
-
 /* Segment definition */
 typedef struct SegDef SegDef;
 struct SegDef {
index 017b5a15cf8139e8cdeef6d6d32c0264aa4a4ccf..d1f8acd9a0019507aa58264294363ff4a0d9332a 100644 (file)
 #include "xmalloc.h"
 
 /* ld65 */
-#include "global.h"
+#include "bin.h"
+#include "config.h"
+#include "exports.h"
+#include "expr.h"
 #include "error.h"
+#include "global.h"
 #include "fileio.h"
 #include "lineinfo.h"
 #include "segments.h"
-#include "exports.h"
-#include "config.h"
-#include "expr.h"
-#include "bin.h"
+#include "spool.h"
 
 
 
@@ -136,7 +137,7 @@ static void BinWriteMem (BinDesc* D, Memory* M)
        SegDesc* S = N->Seg;
 
        /* Keep the user happy */
-               Print (stdout, 1, "    Writing `%s'\n", S->Name);
+               Print (stdout, 1, "    Writing `%s'\n", GetString (S->Name));
 
        /* Writes do only occur in the load area and not for BSS segments */
                DoWrite = (S->Flags & SF_BSS) == 0      &&      /* No BSS segment */
@@ -157,7 +158,7 @@ static void BinWriteMem (BinDesc* D, Memory* M)
             * in the linker.
             */
            Warning ("Segment `%s' in module `%s' requires larger alignment",
-                    S->Name, GetObjFileName (S->Seg->AlignObj));
+                    GetString (S->Name), GetObjFileName (S->Seg->AlignObj));
        }
 
        /* Handle ALIGN and OFFSET/START */
@@ -217,7 +218,7 @@ static void BinWriteMem (BinDesc* D, Memory* M)
 
 
 
-static int BinUnresolved (const char* Name attribute ((unused)), void* D)
+static int BinUnresolved (unsigned Name attribute ((unused)), void* D)
 /* Called if an unresolved symbol is encountered */
 {
     /* Unresolved symbols are an error in binary format. Bump the counter
@@ -228,7 +229,7 @@ static int BinUnresolved (const char* Name attribute ((unused)), void* D)
     return 0;
 }
 
-
+                                   
 
 void BinWriteTarget (BinDesc* D, struct File* F)
 /* Write a binary output file */
@@ -236,7 +237,7 @@ void BinWriteTarget (BinDesc* D, struct File* F)
     Memory* M;
 
     /* Place the filename in the control structure */
-    D->Filename = F->Name;
+    D->Filename = GetString (F->Name);
 
     /* Check for unresolved symbols. The function BinUnresolved is called
      * if we get an unresolved symbol.
@@ -249,25 +250,25 @@ void BinWriteTarget (BinDesc* D, struct File* F)
     }
 
     /* Open the file */
-    D->F = fopen (F->Name, "wb");
+    D->F = fopen (D->Filename, "wb");
     if (D->F == 0) {
-       Error ("Cannot open `%s': %s", F->Name, strerror (errno));
+       Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
     }
 
     /* Keep the user happy */
-    Print (stdout, 1, "Opened `%s'...\n", F->Name);
+    Print (stdout, 1, "Opened `%s'...\n", D->Filename);
 
     /* Dump all memory areas */
     M = F->MemList;
     while (M) {
-       Print (stdout, 1, "  Dumping `%s'\n", M->Name);
+       Print (stdout, 1, "  Dumping `%s'\n", GetString (M->Name));
        BinWriteMem (D, M);
        M = M->FNext;
     }
 
     /* Close the file */
     if (fclose (D->F) != 0) {
-       Error ("Cannot write to `%s': %s", F->Name, strerror (errno));
+       Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
     }
 
     /* Reset the file and filename */
@@ -277,3 +278,4 @@ void BinWriteTarget (BinDesc* D, struct File* F)
 
 
 
+
index cbe03f4cf5e6e3150b46a09dd0270c53d3849ccd..2f9f29263c528565f29fe0f25fe317c6b975f720 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2000-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 /* common */
 #include "check.h"
 #include "coll.h"
+#include "fragdefs.h"
 #include "segdefs.h"
 #include "xmalloc.h"
 
 /* ld65 */
+#include "condes.h"
 #include "exports.h"
 #include "fragment.h"
 #include "segments.h"
-#include "condes.h"
+#include "spool.h"
 
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                          Data                                    */
 /*****************************************************************************/
 
 
 /* Struct describing one condes type */
 typedef struct ConDesDesc ConDesDesc;
 struct ConDesDesc {
-    Collection         ExpList;        /* List of exported symbols */
-    char*              SegName;        /* Name of segment the table is in */
-    char*              Label;          /* Name of table label */
-    char*              CountSym;       /* Name of symbol for entry count */
-    unsigned char      Order;          /* Table order (increasing/decreasing) */
+    Collection         ExpList;        /* List of exported symbols */
+    unsigned            SegName;       /* Name of segment the table is in */
+    unsigned            Label;         /* Name of table label */
+    unsigned            CountSym;      /* Name of symbol for entry count */
+    unsigned char      Order;          /* Table order (increasing/decreasing) */
 };
 
 /* Array for all types */
 static ConDesDesc ConDes[CD_TYPE_COUNT] = {
-    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
-    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
-    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
-    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
-    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
-    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
-    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing },
+    { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
+    { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
+    { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
+    { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
+    { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
+    { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
+    { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
 };
 
 
@@ -109,7 +111,7 @@ static int ConDesCompare (void* Data, const void* E1, const void* E2)
        Cmp = 1;
     } else {
        /* Use the name in this case */
-               Cmp = strcmp (Exp1->Name, Exp2->Name);
+               Cmp = strcmp (GetString (Exp1->Name), GetString (Exp2->Name));
     }
 
     /* Reverse the result for decreasing order */
@@ -133,7 +135,7 @@ static void ConDesCreateOne (ConDesDesc* CD)
     /* Check if this table has a segment and table label defined. If not,
      * creation was not requested in the config file - ignore it.
      */
-    if (CD->SegName == 0 || CD->Label == 0) {
+    if (CD->SegName == INVALID_STRING_ID || CD->Label == INVALID_STRING_ID) {
        return;
     }
 
@@ -175,7 +177,7 @@ static void ConDesCreateOne (ConDesDesc* CD)
     /* Define the table start as an export, offset into section is zero
      * (the section only contains the table).
      */
-    CreateSectionExport (CD->Label,    Sec, 0);
+    CreateSectionExport (CD->Label, Sec, 0);
 
     /* If we have a CountSym name given AND if it is referenced, define it
      * with the number of elements in the table.
@@ -209,47 +211,47 @@ void ConDesAddExport (struct Export* E)
 
 
 
-void ConDesSetSegName (unsigned Type, const char* SegName)
+void ConDesSetSegName (unsigned Type, unsigned SegName)
 /* Set the segment name where the table should go */
 {
     /* Check the parameters */
     PRECONDITION (Type <= CD_TYPE_MAX && SegName != 0);
 
     /* Setting the segment name twice is bad */
-    CHECK (ConDes[Type].SegName == 0);
+    CHECK (ConDes[Type].SegName == INVALID_STRING_ID);
 
     /* Set the name */
-    ConDes[Type].SegName = xstrdup (SegName);
+    ConDes[Type].SegName = SegName;
 }
 
 
 
-void ConDesSetLabel (unsigned Type, const char* Name)
+void ConDesSetLabel (unsigned Type, unsigned Name)
 /* Set the label for the given ConDes type */
 {
     /* Check the parameters */
     PRECONDITION (Type <= CD_TYPE_MAX && Name != 0);
 
     /* Setting the label twice is bad */
-    CHECK (ConDes[Type].Label == 0);
+    CHECK (ConDes[Type].Label == INVALID_STRING_ID);
 
     /* Set the name */
-    ConDes[Type].Label = xstrdup (Name);
+    ConDes[Type].Label = Name;
 }
 
 
 
-void ConDesSetCountSym (unsigned Type, const char* Name)
+void ConDesSetCountSym (unsigned Type, unsigned Name)
 /* Set the name for the given ConDes count symbol */
 {
     /* Check the parameters */
     PRECONDITION (Type <= CD_TYPE_MAX && Name != 0);
 
     /* Setting the symbol twice is bad */
-    CHECK (ConDes[Type].CountSym == 0);
+    CHECK (ConDes[Type].CountSym == INVALID_STRING_ID);
 
     /* Set the name */
-    ConDes[Type].CountSym = xstrdup (Name);
+    ConDes[Type].CountSym = Name;
 }
 
 
@@ -272,7 +274,7 @@ int ConDesHasSegName (unsigned Type)
     /* Check the parameters */
     PRECONDITION (Type <= CD_TYPE_MAX);
 
-    return (ConDes[Type].SegName != 0);
+    return (ConDes[Type].SegName != INVALID_STRING_ID);
 }
 
 
@@ -283,7 +285,7 @@ int ConDesHasLabel (unsigned Type)
     /* Check the parameters */
     PRECONDITION (Type <= CD_TYPE_MAX);
 
-    return (ConDes[Type].Label != 0);
+    return (ConDes[Type].Label != INVALID_STRING_ID);
 }
 
 
@@ -313,5 +315,3 @@ void ConDesDump (void)
 
 
 
-
-
index 6285ac01becedb81d0debe65729040e2397398f3..d9960817644cad92cf13b3d5a8705bb32f430c25 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2000-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -71,13 +71,13 @@ typedef enum {
 void ConDesAddExport (struct Export* E);
 /* Add the given export to the list of constructors/destructor */
 
-void ConDesSetSegName (unsigned Type, const char* SegName);
+void ConDesSetSegName (unsigned Type, unsigned SegName);
 /* Set the segment name where the table should go */
 
-void ConDesSetLabel (unsigned Type, const char* Name);
+void ConDesSetLabel (unsigned Type, unsigned Name);
 /* Set the label for the given ConDes type */
 
-void ConDesSetCountSym (unsigned Type, const char* Name);
+void ConDesSetCountSym (unsigned Type, unsigned Name);
 /* Set the name for the given ConDes count symbol */
 
 void ConDesSetOrder (unsigned Type, ConDesOrder Order);
@@ -103,4 +103,3 @@ void ConDesDump (void);
 
 
 
-
index 5a9c1d8d89edec483d134f2fecd1e96e401132ed..5a87fd03bb5ca36237112dfaac1560b8ed9cea4e 100644 (file)
 #include "bin.h"
 #include "binfmt.h"
 #include "condes.h"
+#include "config.h"
 #include "error.h"
 #include "exports.h"
 #include "global.h"
 #include "o65.h"
 #include "scanner.h"
-#include "config.h"
+#include "spool.h"
 
 
 
@@ -114,7 +115,7 @@ static O65Desc* O65FmtDesc  = 0;
 
 
 
-static File* NewFile (const char* Name);
+static File* NewFile (unsigned Name);
 /* Create a new file descriptor and insert it into the list */
 
 
@@ -125,12 +126,12 @@ static File* NewFile (const char* Name);
 
 
 
-static File* FindFile (const char* Name)
+static File* FindFile (unsigned Name)
 /* Find a file with a given name. */
 {
     File* F = FileList;
     while (F) {
-       if (strcmp (F->Name, Name) == 0) {
+       if (F->Name == Name) {
            return F;
        }
        F = F->Next;
@@ -140,7 +141,7 @@ static File* FindFile (const char* Name)
 
 
 
-static File* GetFile (const char* Name)
+static File* GetFile (unsigned Name)
 /* Get a file entry with the given name. Create a new one if needed. */
 {
     File* F = FindFile (Name);
@@ -168,12 +169,12 @@ static void FileInsert (File* F, Memory* M)
 
 
 
-static Memory* CfgFindMemory (const char* Name)
+static Memory* CfgFindMemory (unsigned Name)
 /* Find the memory are with the given name. Return NULL if not found */
 {
     Memory* M = MemoryList;
     while (M) {
-               if (strcmp (M->Name, Name) == 0) {
+               if (M->Name == Name) {
                    return M;
                }
                M = M->Next;
@@ -183,24 +184,24 @@ static Memory* CfgFindMemory (const char* Name)
 
 
 
-static Memory* CfgGetMemory (const char* Name)
+static Memory* CfgGetMemory (unsigned Name)
 /* Find the memory are with the given name. Print an error on an invalid name */
 {
     Memory* M = CfgFindMemory (Name);
     if (M == 0) {
-       CfgError ("Invalid memory area `%s'", Name);
+       CfgError ("Invalid memory area `%s'", GetString (Name));
     }
     return M;
 }
 
 
 
-static SegDesc* CfgFindSegDesc (const char* Name)
+static SegDesc* CfgFindSegDesc (unsigned Name)
 /* Find the segment descriptor with the given name, return NULL if not found. */
 {
     SegDesc* S = SegDescList;
     while (S) {
-       if (strcmp (S->Name, Name) == 0) {
+               if (S->Name == Name) {
            /* Found */
            return S;
                }
@@ -249,22 +250,18 @@ static void MemoryInsert (Memory* M, SegDesc* S)
 
 
 
-static File* NewFile (const char* Name)
+static File* NewFile (unsigned Name)
 /* Create a new file descriptor and insert it into the list */
 {
-    /* Get the length of the name */
-    unsigned Len = strlen (Name);
-
     /* Allocate memory */
-    File* F = xmalloc (sizeof (File) + Len);
+    File* F = xmalloc (sizeof (File));
 
     /* Initialize the fields */
+    F->Name    = Name;
     F->Flags   = 0;
     F->Format  = BINFMT_DEFAULT;
     F->MemList = 0;
     F->MemLast = 0;
-    memcpy (F->Name, Name, Len);
-    F->Name [Len] = '\0';
 
     /* Insert the struct into the list */
     F->Next  = FileList;
@@ -277,22 +274,20 @@ static File* NewFile (const char* Name)
 
 
 
-static Memory* NewMemory (const char* Name)
+static Memory* NewMemory (unsigned Name)
 /* Create a new memory section and insert it into the list */
 {
-    /* Get the length of the name */
-    unsigned Len = strlen (Name);
-
     /* Check for duplicate names */
     Memory* M =        CfgFindMemory (Name);
     if (M) {
-       CfgError ("Memory area `%s' defined twice", Name);
+       CfgError ("Memory area `%s' defined twice", GetString (Name));
     }
 
     /* Allocate memory */
-    M = xmalloc (sizeof (Memory) + Len);
+    M = xmalloc (sizeof (Memory));
 
     /* Initialize the fields */
+    M->Name      = Name;
     M->Next     = 0;
     M->FNext     = 0;
     M->Attr      = 0;
@@ -304,8 +299,6 @@ static Memory* NewMemory (const char* Name)
     M->SegList   = 0;
     M->SegLast   = 0;
     M->F         = 0;
-    memcpy (M->Name, Name, Len);
-    M->Name [Len] = '\0';
 
     /* Insert the struct into the list */
     if (MemoryLast == 0) {
@@ -323,18 +316,15 @@ static Memory* NewMemory (const char* Name)
 
 
 
-static SegDesc* NewSegDesc (const char* Name)
+static SegDesc* NewSegDesc (unsigned Name)
 /* Create a segment descriptor */
 {
     Segment* Seg;
 
-    /* Get the length of the name */
-    unsigned Len = strlen (Name);
-
     /* Check for duplicate names */
     SegDesc* S = CfgFindSegDesc (Name);
     if (S) {
-       CfgError ("Segment `%s' defined twice", Name);
+       CfgError ("Segment `%s' defined twice", GetString (Name));
     }
 
     /* Search for the actual segment in the input files. The function may
@@ -343,16 +333,15 @@ static SegDesc* NewSegDesc (const char* Name)
     Seg = SegFind (Name);
 
     /* Allocate memory */
-    S = xmalloc (sizeof (SegDesc) + Len);
+    S = xmalloc (sizeof (SegDesc));
 
     /* Initialize the fields */
+    S->Name    = Name;
     S->Next    = 0;
     S->Seg     = Seg;
     S->Attr    = 0;
     S->Flags   = 0;
     S->Align   = 0;
-    memcpy (S->Name, Name, Len);
-    S->Name [Len] = '\0';
 
     /* ...and return it */
     return S;
@@ -417,7 +406,7 @@ static void ParseMemory (void)
     while (CfgTok == CFGTOK_IDENT) {
 
        /* Create a new entry on the heap */
-               Memory* M = NewMemory (CfgSVal);
+               Memory* M = NewMemory (GetStringId (CfgSVal));
 
        /* Skip the name and the following colon */
        CfgNextTok ();
@@ -462,7 +451,7 @@ static void ParseMemory (void)
                    FlagAttr (&M->Attr, MA_FILE, "FILE");
                    CfgAssureStr ();
                            /* Get the file entry and insert the memory area */
-                   FileInsert (GetFile (CfgSVal), M);
+                   FileInsert (GetFile (GetStringId (CfgSVal)), M);
                    break;
 
                case CFGTOK_DEFINE:
@@ -511,7 +500,7 @@ static void ParseMemory (void)
         * file name.
         */
        if ((M->Attr & MA_FILE) == 0) {
-           FileInsert (GetFile (OutputName), M);
+           FileInsert (GetFile (GetStringId (OutputName)), M);
        }
     }
 }
@@ -540,7 +529,7 @@ static void ParseFiles (void)
        CfgAssureStr ();
 
        /* Search for the file, it must exist */
-               F = FindFile (CfgSVal);
+               F = FindFile (GetStringId (CfgSVal));
        if (F == 0) {
            CfgError ("No such file: `%s'", CfgSVal);
        }
@@ -633,7 +622,7 @@ static void ParseSegments (void)
        SegDesc* S;
 
        /* Create a new entry on the heap */
-               S = NewSegDesc (CfgSVal);
+               S = NewSegDesc (GetStringId (CfgSVal));
 
        /* Skip the name and the following colon */
        CfgNextTok ();
@@ -676,7 +665,7 @@ static void ParseSegments (void)
 
                case CFGTOK_LOAD:
                    FlagAttr (&S->Attr, SA_LOAD, "LOAD");
-                   S->Load = CfgGetMemory (CfgSVal);
+                   S->Load = CfgGetMemory (GetStringId (CfgSVal));
                    break;
 
                case CFGTOK_OFFSET:
@@ -697,7 +686,7 @@ static void ParseSegments (void)
 
                case CFGTOK_RUN:
                    FlagAttr (&S->Attr, SA_RUN, "RUN");
-                   S->Run = CfgGetMemory (CfgSVal);
+                   S->Run = CfgGetMemory (GetStringId (CfgSVal));
                    break;
 
                case CFGTOK_START:
@@ -768,7 +757,7 @@ static void ParseSegments (void)
        if ((S->Flags & SF_RO) == 0) {
                    if (S->Run->Flags & MF_RO) {
                CfgError ("Cannot put r/w segment `%s' in r/o memory area `%s'",
-                         S->Name, S->Run->Name);
+                         GetString (S->Name), GetString (S->Run->Name));
            }
        }
 
@@ -797,7 +786,7 @@ static void ParseSegments (void)
        } else {
             /* Print a warning if the segment is not optional */
             if ((S->Flags & SF_OPTIONAL) == 0) {
-                CfgWarning ("Segment `%s' does not exist", S->Name);
+                CfgWarning ("Segment `%s' does not exist", GetString (S->Name));
             }
            /* Discard the descriptor */
            FreeSegDesc (S);
@@ -1048,21 +1037,21 @@ static void ParseConDes (void)
     };
 
     /* Attribute values. */
-    char SegName[sizeof (CfgSVal)];
-    char Label[sizeof (CfgSVal)];
-    char Count[sizeof (CfgSVal)];
+    unsigned SegName = INVALID_STRING_ID;
+    unsigned Label   = INVALID_STRING_ID;
+    unsigned Count   = INVALID_STRING_ID;
     /* Initialize to avoid gcc warnings: */
     int Type = -1;
     ConDesOrder Order = cdIncreasing;
 
     /* Bitmask to remember the attributes we got already */
     enum {
-       atNone          = 0x0000,
-       atSegName       = 0x0001,
-       atLabel         = 0x0002,
-       atCount         = 0x0004,
-       atType          = 0x0008,
-       atOrder         = 0x0010
+       atNone          = 0x0000,
+       atSegName       = 0x0001,
+       atLabel         = 0x0002,
+       atCount         = 0x0004,
+       atType          = 0x0008,
+       atOrder         = 0x0010
     };
     unsigned AttrFlags = atNone;
 
@@ -1087,7 +1076,7 @@ static void ParseConDes (void)
                /* We expect an identifier */
                CfgAssureIdent ();
                /* Remember the value for later */
-               strcpy (SegName, CfgSVal);
+               SegName = GetStringId (CfgSVal);
                break;
 
            case CFGTOK_LABEL:
@@ -1096,7 +1085,7 @@ static void ParseConDes (void)
                /* We expect an identifier */
                CfgAssureIdent ();
                /* Remember the value for later */
-               strcpy (Label, CfgSVal);
+               Label = GetStringId (CfgSVal);
                break;
 
            case CFGTOK_COUNT:
@@ -1105,7 +1094,7 @@ static void ParseConDes (void)
                /* We expect an identifier */
                CfgAssureIdent ();
                /* Remember the value for later */
-               strcpy (Count, CfgSVal);
+               Count = GetStringId (CfgSVal);
                break;
 
            case CFGTOK_TYPE:
@@ -1120,7 +1109,7 @@ static void ParseConDes (void)
                    switch (CfgTok) {
                        case CFGTOK_CONSTRUCTOR: Type = CD_TYPE_CON;    break;
                        case CFGTOK_DESTRUCTOR:  Type = CD_TYPE_DES;    break;
-                       default: FAIL ("Unexpected type token");
+                       default: FAIL ("Unexpected type token");
                    }
                }
                break;
@@ -1297,8 +1286,7 @@ static void ParseSymbols (void)
        long Val;
 
        /* Remember the name */
-       char Name [sizeof (CfgSVal)];
-       strcpy (Name, CfgSVal);
+       unsigned Name = GetStringId (CfgSVal);
        CfgNextTok ();
 
        /* Allow an optional assignment */
@@ -1408,10 +1396,10 @@ static void CreateRunDefines (SegDesc* S)
 {
     char Buf [256];
 
-    xsprintf (Buf, sizeof (Buf), "__%s_RUN__", S->Name);
-    CreateSegmentExport (Buf, S->Seg, 0);
-    xsprintf (Buf, sizeof (Buf), "__%s_SIZE__", S->Name);
-    CreateConstExport (Buf, S->Seg->Size);
+    xsprintf (Buf, sizeof (Buf), "__%s_RUN__", GetString (S->Name));
+    CreateSegmentExport (GetStringId (Buf), S->Seg, 0);
+    xsprintf (Buf, sizeof (Buf), "__%s_SIZE__", GetString (S->Name));
+    CreateConstExport (GetStringId (Buf), S->Seg->Size);
     S->Flags |= SF_RUN_DEF;
 }
 
@@ -1422,8 +1410,8 @@ static void CreateLoadDefines (Memory* M, SegDesc* S)
 {
     char Buf [256];
 
-    xsprintf (Buf, sizeof (Buf), "__%s_LOAD__", S->Name);
-    CreateMemoryExport (Buf, M, S->Seg->PC - M->Start);
+    xsprintf (Buf, sizeof (Buf), "__%s_LOAD__", GetString (S->Name));
+    CreateMemoryExport (GetStringId (Buf), M, S->Seg->PC - M->Start);
     S->Flags |= SF_LOAD_DEF;
 }
 
@@ -1465,10 +1453,10 @@ void CfgAssignSegments (void)
                    /* Offset already too large */
                    if (S->Flags & SF_OFFSET) {
                        Error ("Offset too small in `%s', segment `%s'",
-                              M->Name, S->Name);
+                              GetString (M->Name), GetString (S->Name));
                    } else {
                        Error ("Start address too low in `%s', segment `%s'",
-                              M->Name, S->Name);
+                              GetString (M->Name), GetString (S->Name));
                    }
                }
                Addr = NewAddr;
@@ -1485,7 +1473,8 @@ void CfgAssignSegments (void)
            M->FillLevel = Addr + S->Seg->Size - M->Start;
            if (M->FillLevel > M->Size) {
                Error ("Memory area overflow in `%s', segment `%s' (%lu bytes)",
-                      M->Name, S->Name, M->FillLevel - M->Size);
+                      GetString (M->Name), GetString (S->Name),
+                       M->FillLevel - M->Size);
            }
 
            /* If requested, define symbols for the start and size of the
@@ -1500,12 +1489,12 @@ void CfgAssignSegments (void)
                     * relevant symbols on each walk.
                     */
                    if (S->Load == M) {
-                       if ((S->Flags & SF_LOAD_DEF) == 0) {
-                           CreateLoadDefines (M, S);
-                       } else {
-                           CHECK ((S->Flags & SF_RUN_DEF) == 0);
-                           CreateRunDefines (S);
-                       }
+                       if ((S->Flags & SF_LOAD_DEF) == 0) {
+                           CreateLoadDefines (M, S);
+                       } else {
+                           CHECK ((S->Flags & SF_RUN_DEF) == 0);
+                           CreateRunDefines (S);
+                       }
                    }
                } else {
                    /* RUN and LOAD in different memory areas, or RUN not
@@ -1513,10 +1502,10 @@ void CfgAssignSegments (void)
                     * have only one copy of the segment in the area.
                     */
                    if (S->Run == M) {
-                       CreateRunDefines (S);
+                       CreateRunDefines (S);
                    }
                    if (S->Load == M) {
-                       CreateLoadDefines (M, S);
+                       CreateLoadDefines (M, S);
                    }
                }
            }
@@ -1531,12 +1520,12 @@ void CfgAssignSegments (void)
        /* If requested, define symbols for start and size of the memory area */
        if (M->Flags & MF_DEFINE) {
            char Buf [256];
-           sprintf (Buf, "__%s_START__", M->Name);
-           CreateMemoryExport (Buf, M, 0);
-           sprintf (Buf, "__%s_SIZE__", M->Name);
-           CreateConstExport (Buf, M->Size);
-           sprintf (Buf, "__%s_LAST__", M->Name);
-           CreateConstExport (Buf, M->FillLevel);
+           sprintf (Buf, "__%s_START__", GetString (M->Name));
+           CreateMemoryExport (GetStringId (Buf), M, 0);
+           sprintf (Buf, "__%s_SIZE__", GetString (M->Name));
+           CreateConstExport (GetStringId (Buf), M->Size);
+           sprintf (Buf, "__%s_LAST__", GetString (M->Name));
+           CreateConstExport (GetStringId (Buf), M->FillLevel);
        }
 
        /* Next memory area */
@@ -1558,7 +1547,7 @@ void CfgWriteTarget (void)
        if (F->MemList) {
 
            /* Is there an output file? */
-           if (strlen (F->Name) > 0) {
+           if (strlen (GetString (F->Name)) > 0) {
 
                /* Assign a proper binary format */
                if (F->Format == BINFMT_DEFAULT) {
@@ -1569,12 +1558,12 @@ void CfgWriteTarget (void)
                switch (F->Format) {
 
                    case BINFMT_BINARY:
-                       BinWriteTarget (BinFmtDesc, F);
-                       break;
+                       BinWriteTarget (BinFmtDesc, F);
+                       break;
 
                    case BINFMT_O65:
-                       O65WriteTarget (O65FmtDesc, F);
-                       break;
+                       O65WriteTarget (O65FmtDesc, F);
+                       break;
 
                    default:
                        Internal ("Invalid binary format: %u", F->Format);
@@ -1592,18 +1581,18 @@ void CfgWriteTarget (void)
                    MemListNode* N;
 
                    /* Debugging */
-                           Print (stdout, 2, "Skipping `%s'...\n", M->Name);
+                           Print (stdout, 2, "Skipping `%s'...\n", GetString (M->Name));
 
                    /* Walk throught the segments */
                    N = M->SegList;
                    while (N) {
-                       if (N->Seg->Load == M) {
-                           /* Load area - mark the segment as dumped */
-                           N->Seg->Seg->Dumped = 1;
-                       }
+                       if (N->Seg->Load == M) {
+                           /* Load area - mark the segment as dumped */
+                           N->Seg->Seg->Dumped = 1;
+                       }
 
-                       /* Next segment node */
-                       N = N->Next;
+                       /* Next segment node */
+                       N = N->Next;
                    }
                    /* Next memory area */
                    M = M->FNext;
index e2c91e3bada9b5843e298b6763152cc08229f137..f815fc398c1d8341ba584e70e28ffb8fb444b05b 100644 (file)
 /* File list entry */
 typedef struct File File;
 struct File {
+    unsigned            Name;           /* Name index of the file */
     File*              Next;           /* Pointer to next entry in list */
     unsigned           Flags;
     unsigned           Format;         /* Output format */
     struct Memory*     MemList;        /* List of memory areas in this file */
     struct Memory*     MemLast;        /* Last memory area in this file */
-    char               Name [1];       /* Name of file */
 };
 
 /* Segment list node. Needed because there are two lists (RUN & LOAD) */
@@ -69,6 +69,7 @@ struct MemListNode {
 /* Memory list entry */
 typedef struct Memory Memory;
 struct Memory {
+    unsigned            Name;           /* Name index of the memory section */
     Memory*            Next;           /* Pointer to next entry in list */
     Memory*                    FNext;          /* Next in file list */
     unsigned                   Attr;           /* Which values are valid? */
@@ -80,21 +81,20 @@ struct Memory {
     MemListNode*       SegList;        /* List of segments for this section */
     MemListNode*       SegLast;        /* Last segment in this section */
     File*              F;              /* File that contains the entry */
-    char               Name [1];       /* Name of the memory section */
 };
 
 /* Segment descriptor entry */
 typedef struct SegDesc SegDesc;
 struct SegDesc {
+    unsigned            Name;           /* Index of the name */
     SegDesc*                   Next;           /* Pointer to next entry in list */
-    Segment*           Seg;            /* Pointer to segment structure */
-    unsigned           Attr;           /* Attributes for segment */
-    unsigned           Flags;          /* Set of bitmapped flags */
+    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 */
+    Memory*                    Run;            /* Run memory section */
     unsigned long              Addr;           /* Start address or offset into segment */
     unsigned char      Align;          /* Alignment if given */
-    char               Name [1];       /* Copy of name */
 };
 
 /* Segment list */
index 9e70eda2cb5de966655dcd80f1b005321732ccd9..12d13a83d694baaa50ffdba2e347d62251b157e3 100644 (file)
 
 #include <string.h>
 
-/* common */
+/* common */                                                      
 #include "check.h"
 #include "symdefs.h"
 #include "xmalloc.h"
 
 /* ld65 */
-#include "global.h"
+#include "dbgsyms.h"
 #include "error.h"
+#include "expr.h"
 #include "fileio.h"
+#include "global.h"
 #include "objdata.h"
-#include "expr.h"
-#include "dbgsyms.h"
+#include "spool.h"
 
 
 
@@ -101,10 +102,10 @@ static DbgSym* GetDbgSym (DbgSym* D, long Val)
                    ((Val >>  0) & 0xFF);
 
     /* Check for this symbol */
-    DbgSym* Sym = DbgSymPool [Hash];
+    DbgSym* Sym = DbgSymPool[Hash];
     while (Sym) {
        /* Is this symbol identical? */
-       if (strcmp (Sym->Name, D->Name) == 0 && EqualExpr (Sym->Expr, D->Expr)) {
+       if (Sym->Name == D->Name && EqualExpr (Sym->Expr, D->Expr)) {
            /* Found */
            return Sym;
        }
@@ -148,7 +149,7 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O)
     D = NewDbgSym (Type, O);
 
     /* Read and assign the name */
-    D->Name = GetObjString (O, ReadVar (F));
+    D->Name = MakeGlobalStringId (O, ReadVar (F));
 
     /* Read the value */
     if (IS_EXP_EXPR (Type)) {
@@ -196,7 +197,7 @@ void PrintDbgSymLabels (ObjData* O, FILE* F)
                if (GetDbgSym (D, Val) == 0) {
 
            /* Emit the VICE label line */
-                   fprintf (F, "al %06lX .%s\n", Val, D->Name);
+                   fprintf (F, "al %06lX .%s\n", Val, GetString (D->Name));
 
            /* Insert the symbol into the table */
            InsertDbgSym (D, Val);
index 3b2518a439ef30f36480235cb30bd6489dc72d53..5483116feaafc959253a2cc78b2cbd9a54ebcf34 100644 (file)
@@ -63,7 +63,7 @@ struct DbgSym {
     ObjData*                   Obj;            /* Object file that exports the name */
     FilePos                    Pos;            /* File position of definition */
     ExprNode*                  Expr;           /* Expression (0 if not def'd) */
-    const char*                Name;           /* Name */
+    unsigned            Name;                  /* Name */
     unsigned char      Type;           /* Type of symbol */
 };
 
@@ -92,5 +92,3 @@ void PrintDbgSymLabels (ObjData* O, FILE* F);
 
 
 
-
-
index 55ec1fdb4150e315e92258c724ed3c2a4fe83c3d..7520a1c9b3a636642648df0a6dfec5e4d7a0e66f 100644 (file)
 /* ld65 */
 #include "condes.h"
 #include "error.h"
+#include "exports.h"
+#include "expr.h"
 #include "fileio.h"
 #include "global.h"
 #include "objdata.h"
-#include "expr.h"
-#include "exports.h"
+#include "spool.h"
 
 
 
@@ -62,8 +63,9 @@
 
 
 /* Hash table */
-#define HASHTAB_SIZE           4081
-static Export*                 HashTab [HASHTAB_SIZE];
+#define HASHTAB_MASK    0x0FFFU
+#define HASHTAB_SIZE           (HASHTAB_MASK + 1)
+static Export*                 HashTab[HASHTAB_SIZE];
 
 /* Import management variables */
 static unsigned                ImpCount = 0;           /* Import count */
@@ -84,7 +86,7 @@ static Export**               ExpPool  = 0;           /* Exports array */
 
 
 
-static Export* NewExport (unsigned char Type, const char* Name, ObjData* Obj);
+static Export* NewExport (unsigned char Type, unsigned Name, ObjData* Obj);
 /* Create a new export and initialize it */
 
 
@@ -98,7 +100,8 @@ static Import* NewImport (unsigned char Type, ObjData* Obj)
     /* Initialize the fields */
     I->Next    = 0;
     I->Obj     = Obj;
-    I->V.Name  = 0;
+    I->Exp      = 0;
+    I->Name     = INVALID_STRING_ID;
     I->Type    = Type;
 
     /* Return the new structure */
@@ -111,25 +114,24 @@ void InsertImport (Import* I)
 /* Insert an import into the table */
 {
     Export* E;
-    unsigned HashVal;
 
     /* As long as the import is not inserted, V.Name is valid */
-    const char* Name = I->V.Name;
+    unsigned Name = I->Name;
 
     /* Create a hash value for the given name */
-    HashVal = HashStr (Name) % HASHTAB_SIZE;
+    unsigned Hash = (Name & HASHTAB_MASK);
 
     /* Search through the list in that slot and print matching duplicates */
-    if (HashTab [HashVal] == 0) {
+    if (HashTab[Hash] == 0) {
        /* The slot is empty, we need to insert a dummy export */
-       E = HashTab [HashVal] = NewExport (0, Name, 0);
+       E = HashTab[Hash] = NewExport (0, Name, 0);
        ++ExpCount;
     } else {
-       E = HashTab [HashVal];
+       E = HashTab [Hash];
        while (1) {
-           if (strcmp (E->Name, Name) == 0) {
+           if (E->Name == Name) {
                /* We have an entry, L points to it */
-                       break;
+                       break;
            }
            if (E->Next == 0) {
                /* End of list an entry not found, insert a dummy */
@@ -146,7 +148,7 @@ void InsertImport (Import* I)
     /* Ok, E now points to a valid exports entry for the given import. Insert
      * the import into the imports list and update the counters.
      */
-    I->V.Exp   = E;
+    I->Exp     = E;
     I->Next    = E->ImpList;
     E->ImpList = I;
     E->ImpCount++;
@@ -175,7 +177,7 @@ Import* ReadImport (FILE* F, ObjData* Obj)
     I = NewImport (Type, Obj);
 
     /* Read the name */
-    I->V.Name = GetObjString (Obj, ReadVar (F));
+    I->Name = MakeGlobalStringId (Obj, ReadVar (F));
 
     /* Read the file position */
     ReadFilePos (F, &I->Pos);
@@ -192,13 +194,14 @@ Import* ReadImport (FILE* F, ObjData* Obj)
 
 
 
-static Export* NewExport (unsigned char Type, const char* Name, ObjData* Obj)
+static Export* NewExport (unsigned char Type, unsigned Name, ObjData* Obj)
 /* Create a new export and initialize it */
 {
     /* Allocate memory */
     Export* E = xmalloc (sizeof (Export));
 
     /* Initialize the fields */
+    E->Name     = Name;
     E->Next     = 0;
     E->Flags           = 0;
     E->Obj      = Obj;
@@ -207,12 +210,6 @@ static Export* NewExport (unsigned char Type, const char* Name, ObjData* Obj)
     E->Expr            = 0;
     E->Type            = Type;
     memset (E->ConDes, 0, sizeof (E->ConDes));
-    if (Name) {
-        E->Name = xstrdup (Name);
-    } else {
-               /* Name will get added later */
-               E->Name = 0;
-    }
 
     /* Return the new entry */
     return E;
@@ -226,7 +223,7 @@ void InsertExport (Export* E)
     Export* L;
     Export* Last;
     Import* Imp;
-    unsigned HashVal;
+    unsigned Hash;
 
     /* Insert the export into any condes tables if needed */
     if (IS_EXP_CONDES (E->Type)) {
@@ -234,30 +231,30 @@ void InsertExport (Export* E)
     }
 
     /* Create a hash value for the given name */
-    HashVal = HashStr (E->Name) % HASHTAB_SIZE;
+    Hash = (E->Name & HASHTAB_MASK);
 
     /* Search through the list in that slot */
-    if (HashTab [HashVal] == 0) {
+    if (HashTab[Hash] == 0) {
        /* The slot is empty */
-       HashTab [HashVal] = E;
+       HashTab[Hash] = E;
        ++ExpCount;
     } else {
 
        Last = 0;
-       L = HashTab [HashVal];
+       L = HashTab[Hash];
        do {
-           if (strcmp (L->Name, E->Name) == 0) {
-               /* This may be an unresolved external */
-               if (L->Expr == 0) {
-
-                   /* This *is* an unresolved external */
-                   E->Next     = L->Next;
-                   E->ImpCount = L->ImpCount;
-                   E->ImpList  = L->ImpList;
+           if (L->Name == E->Name) {
+               /* This may be an unresolved external */
+               if (L->Expr == 0) {
+
+                   /* This *is* an unresolved external */
+                   E->Next     = L->Next;
+                   E->ImpCount = L->ImpCount;
+                   E->ImpList  = L->ImpList;
                    if (Last) {
                        Last->Next = E;
                    } else {
-                       HashTab [HashVal] = E;
+                       HashTab[Hash] = E;
                    }
                            ImpOpen -= E->ImpCount;     /* Decrease open imports now */
                    xfree (L);
@@ -266,12 +263,13 @@ void InsertExport (Export* E)
                     */
                    Imp = E->ImpList;
                    while (Imp) {
-                       Imp->V.Exp = E;
+                       Imp->Exp = E;
                        Imp = Imp->Next;
                    }
                } else {
                    /* Duplicate entry, ignore it */
-                           Warning ("Duplicate external identifier: `%s'", L->Name);
+                           Warning ("Duplicate external identifier: `%s'", 
+                             GetString (L->Name));
                }
                return;
            }
@@ -299,7 +297,7 @@ Export* ReadExport (FILE* F, ObjData* O)
     Type = Read8 (F);
 
     /* Create a new export without a name */
-    E = NewExport (Type, 0, O);
+    E = NewExport (Type, INVALID_STRING_ID, O);
 
     /* Read the constructor/destructor decls if we have any */
     ConDesCount = GET_EXP_CONDES_COUNT (Type);
@@ -325,7 +323,7 @@ Export* ReadExport (FILE* F, ObjData* O)
     }
 
     /* Read the name */
-    E->Name = GetObjString (O, ReadVar (F));
+    E->Name = MakeGlobalStringId (O, ReadVar (F));
 
     /* Read the value */
     if (IS_EXP_EXPR (Type)) {
@@ -343,7 +341,7 @@ Export* ReadExport (FILE* F, ObjData* O)
 
 
 
-Export* CreateConstExport (const char* Name, long Value)
+Export* CreateConstExport (unsigned Name, long Value)
 /* Create an export for a literal date */
 {
     /* Create a new export */
@@ -361,7 +359,7 @@ Export* CreateConstExport (const char* Name, long Value)
 
 
 
-Export* CreateMemoryExport (const char* Name, Memory* Mem, unsigned long Offs)
+Export* CreateMemoryExport (unsigned Name, Memory* Mem, unsigned long Offs)
 /* Create an relative export for a memory area offset */
 {
     /* Create a new export */
@@ -379,7 +377,7 @@ Export* CreateMemoryExport (const char* Name, Memory* Mem, unsigned long Offs)
 
 
 
-Export* CreateSegmentExport (const char* Name, Segment* Seg, unsigned long Offs)
+Export* CreateSegmentExport (unsigned Name, Segment* Seg, unsigned long Offs)
 /* Create a relative export to a segment */
 {
     /* Create a new export */
@@ -397,7 +395,7 @@ Export* CreateSegmentExport (const char* Name, Segment* Seg, unsigned long Offs)
 
 
 
-Export* CreateSectionExport (const char* Name, Section* Sec, unsigned long Offs)
+Export* CreateSectionExport (unsigned Name, Section* Sec, unsigned long Offs)
 /* Create a relative export to a section */
 {
     /* Create a new export */
@@ -415,16 +413,16 @@ Export* CreateSectionExport (const char* Name, Section* Sec, unsigned long Offs)
 
 
 
-Export* FindExport (const char* Name)
+Export* FindExport (unsigned Name)
 /* Check for an identifier in the list. Return 0 if not found, otherwise
  * return a pointer to the export.
  */
 {
     /* Get a pointer to the list with the symbols hash value */
-    Export* L = HashTab [HashStr (Name) % HASHTAB_SIZE];
+    Export* L = HashTab[Name & HASHTAB_MASK];
     while (L) {
         /* Search through the list in that slot */
-       if (strcmp (L->Name, Name) == 0) {
+               if (L->Name == Name) {
            /* Entry found */
            return L;
        }
@@ -437,7 +435,7 @@ Export* FindExport (const char* Name)
 
 
 
-int IsUnresolved (const char* Name)
+int IsUnresolved (unsigned Name)
 /* Check if this symbol is an unresolved export */
 {
     /* Find the export */
@@ -473,7 +471,7 @@ long GetExportVal (const Export* E)
 {
     if (E->Expr == 0) {
        /* OOPS */
-               Internal ("`%s' is an undefined external", E->Name);
+               Internal ("`%s' is an undefined external", GetString (E->Name));
     }
     return GetExprVal (E->Expr);
 }
@@ -493,13 +491,16 @@ static void CheckSymType (const Export* E)
                /* User defined export */
                Warning ("Type mismatch for `%s', export in "
                         "%s(%lu), import in %s(%lu)",
-                        E->Name, GetSourceFileName (E->Obj, Imp->Pos.Name),
-                        E->Pos.Line, GetSourceFileName (Imp->Obj, Imp->Pos.Name),
+                        GetString (E->Name), 
+                         GetSourceFileName (E->Obj, Imp->Pos.Name),
+                        E->Pos.Line, 
+                         GetSourceFileName (Imp->Obj, Imp->Pos.Name),
                         Imp->Pos.Line);
            } else {
                /* Export created by the linker */
                Warning ("Type mismatch for `%s', imported from %s(%lu)",
-                        E->Name, GetSourceFileName (Imp->Obj, Imp->Pos.Name),
+                        GetString (E->Name), 
+                         GetSourceFileName (Imp->Obj, Imp->Pos.Name),
                         Imp->Pos.Line);
            }
        }
@@ -541,7 +542,7 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
            Import* Imp = E->ImpList;
            fprintf (stderr,
                     "Unresolved external `%s' referenced in:\n",
-                    E->Name);
+                    GetString (E->Name));
            while (Imp) {
                const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name);
                fprintf (stderr, "  %s(%lu)\n", Name, Imp->Pos.Line);
@@ -556,7 +557,8 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
 static int CmpExpName (const void* K1, const void* K2)
 /* Compare function for qsort */
 {
-    return strcmp ((*(Export**)K1)->Name, (*(Export**)K2)->Name);
+    return strcmp (GetString ((*(Export**)K1)->Name), 
+                   GetString ((*(Export**)K2)->Name));
 }
 
 
@@ -574,10 +576,10 @@ static void CreateExportPool (void)
 
     /* Walk through the list and insert the exports */
     for (I = 0, J = 0; I < sizeof (HashTab) / sizeof (HashTab [0]); ++I) {
-       Export* E = HashTab [I];
+       Export* E = HashTab[I];
        while (E) {
            CHECK (J < ExpCount);
-           ExpPool [J++] = E;
+                   ExpPool[J++] = E;
            E = E->Next;
        }
     }
@@ -623,7 +625,7 @@ void PrintExportMap (FILE* F)
        if (VerboseMap || E->ImpCount > 0 || IS_EXP_CONDES (E->Type)) {
            fprintf (F,
                     "%-25s %06lX %c%c%c%c   ",
-                    E->Name,
+                    GetString (E->Name),
                     GetExportVal (E),
                     E->ImpCount? 'R' : ' ',
                     IS_EXP_LABEL (E->Type)? 'L' : 'E',
@@ -660,7 +662,7 @@ void PrintImportMap (FILE* F)
            /* Print the export */
            fprintf (F,
                     "%s (%s):\n",
-                    Exp->Name,
+                    GetString (Exp->Name),
                     GetObjFileName (Exp->Obj));
 
            /* Print all imports for this symbol */
@@ -692,7 +694,7 @@ void PrintExportLabels (FILE* F)
     /* Print all exports */
     for (I = 0; I < ExpCount; ++I) {
        const Export* E = ExpPool [I];
-               fprintf (F, "al %06lX .%s\n", GetExportVal (E), E->Name);
+               fprintf (F, "al %06lX .%s\n", GetExportVal (E), GetString (E->Name));
     }
 }
 
@@ -726,8 +728,11 @@ void CircularRefError (const Export* E)
 /* Print an error about a circular reference using to define the given export */
 {
     Error ("Circular reference for symbol `%s', %s(%lu)",
-          E->Name, GetSourceFileName (E->Obj, E->Pos.Name), E->Pos.Line);
+          GetString (E->Name), 
+           GetSourceFileName (E->Obj, E->Pos.Name),
+           E->Pos.Line);
 }
 
 
 
+           
index 06cb763ddf84f6e1f0476590911c82be07cda9e2..c28d49ed4018954cc4bc0a9da13ed7d8e59d5803 100644 (file)
@@ -63,10 +63,8 @@ struct Import {
     Import*            Next;           /* Single linked list */
     ObjData*           Obj;            /* Object file that imports the name */
     FilePos            Pos;            /* File position of reference */
-    union {
-       struct Export*  Exp;            /* Matching export for this import */
-               const char*     Name;           /* Name if not in table */
-    } V;
+    struct Export*     Exp;            /* Matching export for this import */
+    unsigned            Name;          /* Name if not in table */
     unsigned char      Type;           /* Type of import */
 };
 
@@ -75,6 +73,7 @@ struct Import {
 /* Export symbol structure */
 typedef struct Export Export;
 struct Export {
+    unsigned            Name;                  /* Name */
     Export*                    Next;           /* Hash table link */
     unsigned           Flags;          /* Generic flags */
     ObjData*           Obj;            /* Object file that exports the name */
@@ -84,7 +83,6 @@ struct Export {
     ExprNode*                  Expr;           /* Expression (0 if not def'd) */
     unsigned char      Type;           /* Type of export */
     unsigned char      ConDes[CD_TYPE_COUNT];  /* Constructor/destructor decls */
-    const char*                Name;           /* Name */
 };
 
 
@@ -95,7 +93,7 @@ struct Export {
  * resolved, or a value != zero if the symbol could be resolved. The
  * CheckExports routine will print out the missing symbol in the first case.
  */
-typedef int (*ExpCheckFunc) (const char* Name, void* Data);
+typedef int (*ExpCheckFunc) (unsigned Name, void* Data);
 
 
 
@@ -117,24 +115,24 @@ Export* ReadExport (FILE* F, ObjData* Obj);
 void InsertExport (Export* E);
 /* Insert an exported identifier and check if it's already in the list */
 
-Export* CreateConstExport (const char* Name, long Value);
+Export* CreateConstExport (unsigned Name, long Value);
 /* Create an export for a literal date */
 
-Export* CreateMemoryExport (const char* Name, Memory* Mem, unsigned long Offs);
+Export* CreateMemoryExport (unsigned Name, Memory* Mem, unsigned long Offs);
 /* Create an relative export for a memory area offset */
 
-Export* CreateSegmentExport (const char* Name, Segment* Seg, unsigned long Offs);
+Export* CreateSegmentExport (unsigned Name, Segment* Seg, unsigned long Offs);
 /* Create a relative export to a segment */
 
-Export* CreateSectionExport (const char* Name, Section* S, unsigned long Offs);
+Export* CreateSectionExport (unsigned Name, Section* S, unsigned long Offs);
 /* Create a relative export to a section */
 
-Export* FindExport (const char* Name);
+Export* FindExport (unsigned Name);
 /* Check for an identifier in the list. Return 0 if not found, otherwise
  * return a pointer to the export.
  */
 
-int IsUnresolved (const char* Name);
+int IsUnresolved (unsigned Name);
 /* Check if this symbol is an unresolved export */
 
 int IsUnresolvedExport (const Export* E);
@@ -180,3 +178,4 @@ void CircularRefError (const Export* E);
 
 
 
+
index 039e9efaed78061041fdbe76447efe94bf862f73..9006826dd0318e786c0eefa947eedffe2dfb3d8e 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2000 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -118,9 +118,7 @@ int IsConstExpr (ExprNode* Root)
                 * which in turn means, that we have a circular reference.
                 */
                if (ExportHasMark (E)) {
-                   Error ("Circular reference for symbol `%s', %s(%lu)",
-                          E->Name, GetSourceFileName (E->Obj, E->Pos.Name),
-                          E->Pos.Line);
+                    CircularRefError (E);
                    Const = 0;
                } else {
                    MarkExport (E);
@@ -198,7 +196,7 @@ Export* GetExprExport (ExprNode* Expr)
     PRECONDITION (Expr->Op == EXPR_SYMBOL);
 
     /* Return the export */
-    return Expr->Obj->Imports [Expr->V.ImpNum]->V.Exp;
+    return Expr->Obj->Imports [Expr->V.ImpNum]->Exp;
 }
 
 
@@ -485,7 +483,7 @@ ExprNode* ReadExpr (FILE* F, ObjData* O)
 
        /* Not a leaf node */
        Expr->Left = ReadExpr (F, O);
-       Expr->Right = ReadExpr (F, O);  
+       Expr->Right = ReadExpr (F, O);
 
     }
 
index 19cf95311c780845a12892fb2c26fd9d2501198c..65f10bed0f86b6d3a6c042888405a019916a78bd 100644 (file)
 
 
 /* common */
-#include "segdefs.h"
+#include "fragdefs.h"
 #include "xmalloc.h"
 
 /* ld65 */
-#include "segments.h"
+#include "error.h"
+#include "expr.h"
 #include "fragment.h"
+#include "fileio.h"
+#include "segments.h"
+#include "spool.h"
 
 
 
 
 
 
+static FragCheck* NewFragCheck (unsigned Action)
+/* Allocate a new FragCheck struct and return it */
+{
+    /* Allocate memory */
+    FragCheck* FC = xmalloc (sizeof (FragCheck));
+
+    /* Initialize the fields */
+    FC->Next    = 0;
+    FC->Expr    = 0;
+    FC->Action  = Action;
+    FC->Message = INVALID_STRING_ID;
+
+    /* Return the new struct */
+    return FC;
+}
+
+
+
+FragCheck* ReadFragCheck (FILE* F, Fragment* Frag)
+/* Read a fragment check expression from the given file */
+{
+    /* Get the object file pointer from the fragment */
+    ObjData* O = Frag->Obj;
+
+    /* Read the action and create a new struct */
+    FragCheck* FC = NewFragCheck (ReadVar (F));
+
+    /* Determine the remaining data from the action */
+    switch (FC->Action) {
+
+        case FRAG_ACT_WARN:
+        case FRAG_ACT_ERROR:
+            FC->Expr = ReadExpr (F, O);
+            FC->Message = MakeGlobalStringId (O, ReadVar (F));
+            break;
+
+        default:
+            Internal ("In module `%s', file `%s', line %lu: Invalid fragment "
+                      "check action: %u",
+                      GetObjFileName (O),
+                      GetSourceFileName (O, Frag->Pos.Name),
+                      Frag->Pos.Line, FC->Action);
+    }
+
+    /* Return the new fragment check */
+    return FC;
+}
+
+
+
 Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
 /* Create a new fragment and insert it into the section S */
 {
index 9d70fc3ea6cc01f9986c5d4213ffb6126b05c5e0..342f5696c695c60688f4b3f37b2fcc30ff7b58e9 100644 (file)
@@ -50,6 +50,7 @@
 
 
 struct LineInfo;
+struct ObjData;
 struct Section;
 
 
@@ -61,9 +62,9 @@ struct Section;
 
 
 /* Fragment check expression */
-typedef struct CheckExpr CheckExpr;
-struct CheckExpr {
-    struct CheckExpr*   Next;           /* Next check expression */
+typedef struct FragCheck FragCheck;
+struct FragCheck {
+    struct FragCheck*   Next;           /* Next check expression */
     struct ExprNode*    Expr;           /* The expression itself */
     unsigned            Action;         /* Action to take if the check fails */
     unsigned            Message;        /* Message number */
@@ -76,9 +77,9 @@ struct Fragment {
     struct ObjData*    Obj;            /* Source of fragment */
     unsigned            Size;                  /* Size of data/expression */
     struct ExprNode*   Expr;           /* Expression if FRAG_EXPR */
-    FilePos            Pos;            /* File position in source */
+    FilePos            Pos;            /* File position in source */
     struct LineInfo*    LI;             /* Additional line info */
-    CheckExpr*          Check;          /* Single linked list of expressions */
+    FragCheck*          Check;          /* Single linked list of checks */
     unsigned char      Type;           /* Type of fragment */
     unsigned char              LitBuf [1];     /* Dynamically alloc'ed literal buffer */
 };
@@ -91,6 +92,9 @@ struct Fragment {
 
 
 
+FragCheck* ReadFragCheck (FILE* F, Fragment* Frag);
+/* Read a fragment check expression from the given file */
+
 Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
 /* Create a new fragment and insert it into the section S */
 
index a337cc1b11d99dd808c71e283273a9cb00b4c040..8b3c868a56355881458b4b503004d3b9b7bc4e4a 100644 (file)
@@ -278,9 +278,13 @@ void LibAdd (FILE* F, const char* Name)
 
            /* We have the data now */
            O->Flags |= OBJ_HAVEDATA;
-
        }
 
+        /* All references to strings are now resolved, so we can delete
+         * the module string pool.
+         */
+        FreeObjStrings (O);
+
        /* Add a pointer to the library name */
        O->LibName = LibName;
     }
index 0024fef17e8373180edac705a96a8032ad4cd321..c92d96a54cf60e6a36652fddd01175b5d2b463a0 100644 (file)
@@ -62,6 +62,7 @@
 #include "objfile.h"
 #include "scanner.h"
 #include "segments.h"
+#include "spool.h"
 #include "tgtcfg.h"
 
 
@@ -404,6 +405,9 @@ int main (int argc, char* argv [])
     /* Initialize the input file search paths */
     InitSearchPaths ();
 
+    /* Initialize the string pool */
+    InitStrPool ();
+
     /* Check the parameters */
     I = 1;
     while (I < ArgCount) {
index ff9c74f9865d0feadea18d5fb5ec3fe5d9676012..7a8eab44ed0ea11021d12f9a040e23fb78457dff 100644 (file)
@@ -6,9 +6,9 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2001 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 #include <string.h>
 #include <errno.h>
 
-#include "global.h"
-#include "error.h"
-#include "objdata.h"
-#include "segments.h"
+/* ld65 */
+#include "config.h"
 #include "dbginfo.h"
 #include "dbgsyms.h"
 #include "exports.h"
-#include "config.h"
+#include "global.h"
+#include "error.h"
 #include "mapfile.h"
+#include "objdata.h"
+#include "segments.h"
+#include "spool.h"
 
 
 
@@ -87,7 +89,7 @@ void CreateMapFile (void)
                 */
                if (VerboseMap || S->Size > 0) {
                            fprintf (F, "    %-15s   Offs = %06lX   Size = %06lX\n",
-                            S->Seg->Name, S->Offs, S->Size);
+                            GetString (S->Seg->Name), S->Offs, S->Size);
                }
            }
        }
index 3f8d2058cdc6af6d2429a500ee63f30eb9f247f3..1a0c64544ac8656a4413491e152035c8ef562d0a 100644 (file)
@@ -6,9 +6,9 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1999-2001 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
@@ -53,6 +53,7 @@
 #include "global.h"
 #include "lineinfo.h"
 #include "o65.h"
+#include "spool.h"
 
 
 
@@ -149,7 +150,7 @@ struct O65Desc {
     ExtSymTab*     Imports;            /* Table with imported symbols */
     unsigned               Undef;              /* Count of undefined symbols */
     FILE*          F;                  /* The file we're writing to */
-    char*          Filename;           /* Name of the output file */
+    const char*     Filename;          /* Name of the output file */
     O65RelocTab*    TextReloc;         /* Relocation table for text segment */
     O65RelocTab*    DataReloc;         /* Relocation table for data segment */
 
@@ -315,7 +316,7 @@ static void O65ParseExpr (ExprNode* Expr, ExprDesc* D, int Sign)
                CircularRefError (E);
            } else if (E->Expr == 0) {
                /* Dummy export, must be an o65 imported symbol */
-               ExtSym* S = O65GetImport (D->D, E->Name);
+               ExtSym* S = O65GetImport (D->D, GetString (E->Name));
                CHECK (S != 0);
                if (D->ExtRef) {
                    /* We cannot have more than one external reference in o65 */
@@ -714,7 +715,7 @@ static void O65WriteSeg (O65Desc* D, SegDesc** Seg, unsigned Count, int DoWrite)
                S = Seg [I];
 
        /* Keep the user happy */
-       Print (stdout, 1, "    Writing `%s'\n", S->Name);
+       Print (stdout, 1, "    Writing `%s'\n", GetString (S->Name));
 
        /* Write this segment */
                if (DoWrite) {
@@ -868,7 +869,7 @@ static void O65WriteExports (O65Desc* D)
         * export does really exist, so if it is unresolved, or if we don't
         * find it, there is an error in the linker code.
         */
-       Export* E = FindExport (Name);
+       Export* E = FindExport (GetStringId (Name));
        if (E == 0 || IsUnresolvedExport (E)) {
            Internal ("Unresolved export `%s' found in O65WriteExports", Name);
        }
@@ -1137,7 +1138,7 @@ void O65SetExport (O65Desc* D, const char* Ident)
     /* Get the export for this symbol and check if it does exist and is
      * a resolved symbol.
      */
-    Export* E = FindExport (Ident);
+    Export* E = FindExport (GetStringId (Ident));
     if (E == 0 || IsUnresolvedExport (E)) {
        Error ("Unresolved export: `%s'", Ident);
     }
@@ -1224,11 +1225,11 @@ static void O65SetupSegments (O65Desc* D, File* F)
 
 
 
-static int O65Unresolved (const char* Name, void* D)
+static int O65Unresolved (unsigned Name, void* D)
 /* Called if an unresolved symbol is encountered */
 {
     /* Check if the symbol is an imported o65 symbol */
-    if (O65GetImport (D, Name) != 0) {
+    if (O65GetImport (D, GetString (Name)) != 0) {
        /* This is an external symbol, relax... */
        return 1;
     } else {
@@ -1280,7 +1281,7 @@ void O65WriteTarget (O65Desc* D, File* F)
     time_t      T;
 
     /* Place the filename in the control structure */
-    D->Filename = F->Name;
+    D->Filename = GetString (F->Name);
 
     /* Check for unresolved symbols. The function O65Unresolved is called
      * if we get an unresolved symbol.
@@ -1299,13 +1300,13 @@ void O65WriteTarget (O65Desc* D, File* F)
     O65SetupHeader (D);
 
     /* Open the file */
-    D->F = fopen (F->Name, "wb");
+    D->F = fopen (D->Filename, "wb");
     if (D->F == 0) {
-       Error ("Cannot open `%s': %s", F->Name, strerror (errno));
+       Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
     }
 
     /* Keep the user happy */
-    Print (stdout, 1, "Opened `%s'...\n", F->Name);
+    Print (stdout, 1, "Opened `%s'...\n", D->Filename);
 
     /* Define some more options: A timestamp and the linker version */
     T = time (0);
@@ -1352,7 +1353,7 @@ void O65WriteTarget (O65Desc* D, File* F)
 
     /* Close the file */
     if (fclose (D->F) != 0) {
-       Error ("Cannot write to `%s': %s", F->Name, strerror (errno));
+       Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
     }
 
     /* Reset the file and filename */
@@ -1362,3 +1363,4 @@ void O65WriteTarget (O65Desc* D, File* F)
 
 
 
+
index 3b667eace58464e0f4059f2d301b208fac55a248..81320796d4dd03b18dabe5b2e63edd77643252af 100644 (file)
@@ -43,6 +43,7 @@
 #include "error.h"
 #include "fileinfo.h"
 #include "objdata.h"
+#include "spool.h"
 
 
 
@@ -107,13 +108,27 @@ ObjData* NewObjData (void)
 
 
 
-const char* GetObjString (const ObjData* O, unsigned long Index)
+void FreeObjStrings (ObjData* O)
+/* Free the module string data. Used once the object file is loaded completely
+ * when all strings are converted to global strings.
+ */
+{
+    while (O->StringCount) {
+        xfree (O->Strings[--O->StringCount]);
+    }
+    xfree (O->Strings);
+    O->Strings = 0;
+}
+
+
+
+const char* GetObjString (const ObjData* O, unsigned Index)
 /* Get a string from the object file string table. Abort if the string index
  * is invalid.
  */
 {
     if (Index >= O->StringCount) {
-               Error ("Invalid string index (%lu) in module `%s'",
+               Error ("Invalid string index (%u) in module `%s'",
               Index, GetObjFileName (O));
     }
     return O->Strings[Index];
@@ -121,6 +136,18 @@ const char* GetObjString (const ObjData* O, unsigned long Index)
 
 
 
+unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
+/* Convert a local string id into a global one and return it. */
+{
+    if (Index >= O->StringCount) {
+               Error ("Invalid string index (%u) in module `%s'",
+              Index, GetObjFileName (O));
+    }
+    return GetStringId (O->Strings[Index]);
+}
+
+
+
 const char* GetObjFileName (const ObjData* O)
 /* Get the name of the object file. Return "[linker generated]" if the object
  * file is NULL.
index b5c0eea71272464b255fd31eedb4569f92c53e47..8da6fc080dd179b9f020bb5c5bb5db8c93fcc244 100644 (file)
@@ -98,11 +98,19 @@ extern ObjData*             ObjLast;        /* Last entry in list */
 ObjData* NewObjData (void);
 /* Allocate a new structure on the heap, insert it into the list, return it */
 
-const char* GetObjString (const ObjData* O, unsigned long Index);
+void FreeObjStrings (ObjData* O);
+/* Free the module string data. Used once the object file is loaded completely
+ * when all strings are converted to global strings.
+ */
+
+const char* GetObjString (const ObjData* O, unsigned Index);
 /* Get a string from the object file string table. Abort if the string index
  * is invalid.
  */
 
+unsigned MakeGlobalStringId (const ObjData* O, unsigned Index);
+/* Convert a local string id into a global one and return it. */
+
 const char* GetObjFileName (const ObjData* O);
 /* Get the name of the object file. Return "[linker generated]" if the object
  * file is NULL.
index 89875fd797b5634e30384e02d8a021e2d9b26728..ff9a14b57315bf44b54807470a7c8a5f82e27888 100644 (file)
@@ -255,6 +255,11 @@ void ObjAdd (FILE* Obj, const char* Name)
 
     /* Done, close the file (we read it only, so no error check) */
     fclose (Obj);
+
+    /* All references to strings are now resolved, so we can delete the module
+     * string pool.
+     */
+    FreeObjStrings (O);
 }
 
 
index 84f1b90e2089160b36d18377f1d45a1f4e4f11fa..2c887829bbd365afe03f0f70e0e567adcb82b494 100644 (file)
@@ -39,6 +39,7 @@
 /* common */
 #include "check.h"
 #include "exprdefs.h"
+#include "fragdefs.h"
 #include "hashstr.h"
 #include "print.h"
 #include "segdefs.h"
@@ -53,6 +54,7 @@
 #include "global.h"
 #include "lineinfo.h"
 #include "segments.h"
+#include "spool.h"
 
 
 
@@ -63,7 +65,8 @@
 
 
 /* Hash table */
-#define HASHTAB_SIZE   253
+#define HASHTAB_MASK    0x3FU
+#define HASHTAB_SIZE   (HASHTAB_MASK + 1)
 static Segment*                HashTab [HASHTAB_SIZE];
 
 static unsigned                SegCount = 0;   /* Segment count */
@@ -77,35 +80,16 @@ static Segment*             SegRoot = 0;    /* List of all segments */
 
 
 
-static Segment* SegFindInternal (const char* Name, unsigned HashVal)
-/* Try to find the segment with the given name, return a pointer to the
- * segment structure, or 0 if not found.
- */
-{
-    Segment* S = HashTab [HashVal];
-    while (S) {
-       if (strcmp (Name, S->Name) == 0) {
-           /* Found */
-           break;
-       }
-       S = S->Next;
-    }
-    /* Not found */
-    return S;
-}
-
-
-
-static Segment* NewSegment (const char* Name, unsigned HashVal, unsigned char Type)
+static Segment* NewSegment (unsigned Name, unsigned char Type)
 /* Create a new segment and initialize it */
 {
-    /* Get the length of the symbol name */
-    unsigned Len = strlen (Name);
+    unsigned Hash;
 
     /* Allocate memory */
-    Segment* S = xmalloc (sizeof (Segment) + Len);
+    Segment* S = xmalloc (sizeof (Segment));
 
     /* Initialize the fields */
+    S->Name     = Name;
     S->Next    = 0;
     S->SecRoot = 0;
     S->SecLast = 0;
@@ -116,8 +100,6 @@ static Segment* NewSegment (const char* Name, unsigned HashVal, unsigned char Ty
     S->FillVal = 0;
     S->Type     = Type;
     S->Dumped   = 0;
-    memcpy (S->Name, Name, Len);
-    S->Name [Len] = '\0';
 
     /* Insert the segment into the segment list */
     S->List = SegRoot;
@@ -125,8 +107,9 @@ static Segment* NewSegment (const char* Name, unsigned HashVal, unsigned char Ty
     ++SegCount;
 
     /* Insert the segment into the segment hash list */
-    S->Next = HashTab [HashVal];
-    HashTab [HashVal] = S;
+    Hash = (S->Name & HASHTAB_MASK);
+    S->Next = HashTab[Hash];
+    HashTab[Hash] = S;
 
     /* Return the new entry */
     return S;
@@ -134,22 +117,21 @@ static Segment* NewSegment (const char* Name, unsigned HashVal, unsigned char Ty
 
 
 
-Segment* GetSegment (const char* Name, unsigned char Type, const char* ObjName)
+Segment* GetSegment (unsigned Name, unsigned char Type, const char* ObjName)
 /* Search for a segment and return an existing one. If the segment does not
  * exist, create a new one and return that. ObjName is only used for the error
  * message and may be NULL if the segment is linker generated.
  */
 {
-    /* Create a hash over the name and try to locate the segment in the table */
-    unsigned HashVal = HashStr (Name) % HASHTAB_SIZE;
-    Segment* S = SegFindInternal (Name, HashVal);
+    /* Try to locate the segment in the table */
+    Segment* S = SegFind (Name);
 
     /* If we don't have that segment already, allocate it using the type of
      * the first section.
      */
     if (S == 0) {
        /* Create a new segment */
-       S = NewSegment (Name, HashVal, Type);
+       S = NewSegment (Name, Type);
     } else {
                /* Check if the existing segment has the requested type */
                if (S->Type != Type) {
@@ -157,7 +139,8 @@ Segment* GetSegment (const char* Name, unsigned char Type, const char* ObjName)
            if (ObjName == 0) {
                ObjName = "[linker generated]";
            }
-           Error ("Module `%s': Type mismatch for segment `%s'", ObjName, Name);
+           Error ("Module `%s': Type mismatch for segment `%s'", ObjName,
+                   GetString (Name));
        }
     }
 
@@ -174,7 +157,7 @@ Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type)
 
 
     /* Allocate memory */
-    Section* S = xmalloc (sizeof (Segment));
+    Section* S = xmalloc (sizeof (Section));
 
     /* Initialize the data */
     S->Next    = 0;
@@ -211,7 +194,7 @@ Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type)
 Section* ReadSection (FILE* F, ObjData* O)
 /* Read a section from a file */
 {
-    char*         Name;
+    unsigned      Name;
     unsigned      Size;
     unsigned char Align;
     unsigned char Type;
@@ -221,7 +204,7 @@ Section* ReadSection (FILE* F, ObjData* O)
 
     /* Read the segment data */
     (void) Read32 (F);            /* File size of data */
-    Name      = ReadStr (F);      /* Segment name */
+    Name      = MakeGlobalStringId (O, ReadVar (F));    /* Segment name */
     Size      = Read32 (F);       /* Size of data */
     Align     = Read8 (F);        /* Alignment */
     Type      = Read8 (F);        /* Segment type */
@@ -230,14 +213,11 @@ Section* ReadSection (FILE* F, ObjData* O)
 
     /* Print some data */
     Print (stdout, 2, "Module `%s': Found segment `%s', size = %u, align = %u, type = %u\n",
-          GetObjFileName (O), Name, Size, Align, Type);
+          GetObjFileName (O), GetString (Name), Size, Align, Type);
 
     /* Get the segment for this section */
     S = GetSegment (Name, Type, GetObjFileName (O));
 
-    /* We have the segment and don't need the name any longer */
-    xfree (Name);
-
     /* Allocate the section we will return later */
     Sec = NewSection (S, Align, Type);
 
@@ -283,7 +263,7 @@ Section* ReadSection (FILE* F, ObjData* O)
 
            default:
                Error ("Unknown fragment type in module `%s', segment `%s': %02X",
-                      GetObjFileName (O), S->Name, Type);
+                      GetObjFileName (O), GetString (S->Name), Type);
                /* NOTREACHED */
                return 0;
                }
@@ -295,7 +275,6 @@ Section* ReadSection (FILE* F, ObjData* O)
             unsigned Count = ReadVar (F);
 
             /* Read the expressions */
-            CheckExpr* Last = 0;
             while (Count--) {
                 /* ### */
             }
@@ -331,10 +310,19 @@ Section* ReadSection (FILE* F, ObjData* O)
 
 
 
-Segment* SegFind (const char* Name)
+Segment* SegFind (unsigned Name)
 /* Return the given segment or NULL if not found. */
 {
-    return SegFindInternal (Name, HashStr (Name) % HASHTAB_SIZE);
+    Segment* S = HashTab[Name & HASHTAB_MASK];
+    while (S) {
+               if (Name == S->Name) {
+           /* Found */
+           break;
+       }
+       S = S->Next;
+    }
+    /* Not found */
+    return S;
 }
 
 
@@ -382,7 +370,7 @@ void SegDump (void)
     Segment* Seg = SegRoot;
     while (Seg) {
        Section* S = Seg->SecRoot;
-               printf ("Segment: %s (%lu)\n", Seg->Name, Seg->Size);
+               printf ("Segment: %s (%lu)\n", GetString (Seg->Name), Seg->Size);
        while (S) {
            Fragment* F = S->FragRoot;
            printf ("  Section:\n");
@@ -420,7 +408,7 @@ void SegDump (void)
                    case FRAG_FILL:
                        printf ("    Empty space (%u bytes)\n", F->Size);
                        break;
-                                                   
+
                    default:
                        Internal ("Invalid fragment type: %02X", F->Type);
                }
@@ -578,7 +566,7 @@ static int CmpSegStart (const void* K1, const void* K2)
        return -1;
     } else {
        /* Sort segments with equal starts by name */
-       return strcmp (S1->Name, S2->Name);
+       return strcmp (GetString (S1->Name), GetString (S2->Name));
     }
 }
 
@@ -635,7 +623,7 @@ void PrintSegmentMap (FILE* F)
                --End;
            }
            fprintf (F, "%-20s  %06lX  %06lX  %06lX\n",
-                    S->Name, S->PC, End, S->Size);
+                            GetString (S->Name), S->PC, End, S->Size);
        }
     }
 
@@ -653,7 +641,8 @@ void CheckSegments (void)
     Segment* S = SegRoot;
     while (S) {
        if (S->Size > 0 && S->Dumped == 0) {
-                   Error ("Missing memory area assignment for segment `%s'", S->Name);
+                   Error ("Missing memory area assignment for segment `%s'",
+                   GetString (S->Name));
        }
        S = S->List;
     }
index d7bfe24434e16c71c37ee3ee0b6838a204c33da0..23b21bd12cfec8070c0923110cc503fc73c7f78b 100644 (file)
@@ -54,6 +54,7 @@
 /* Segment structure */
 typedef struct Segment Segment;
 struct Segment {
+    unsigned            Name;           /* Name index of the segment */
     Segment*           Next;           /* Hash list */
     Segment*           List;           /* List of all segments */
     struct Section*    SecRoot;        /* Section list */
@@ -65,7 +66,6 @@ struct Segment {
     unsigned char      FillVal;        /* Value to use for fill bytes */
     unsigned char      Type;           /* Type of segment */
     char               Dumped;         /* Did we dump this segment? */
-    char                       Name [1];       /* Name, dynamically allocated */
 };
 
 
@@ -108,7 +108,7 @@ typedef unsigned (*SegWriteFunc) (ExprNode* E,            /* The expression to write
 
 
 
-Segment* GetSegment (const char* Name, unsigned char Type, const char* ObjName);
+Segment* GetSegment (unsigned Name, unsigned char Type, const char* ObjName);
 /* Search for a segment and return an existing one. If the segment does not
  * exist, create a new one and return that. ObjName is only used for the error
  * message and may be NULL if the segment is linker generated.
@@ -120,7 +120,7 @@ Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type);
 Section* ReadSection (FILE* F, struct ObjData* O);
 /* Read a section from a file */
 
-Segment* SegFind (const char* Name);
+Segment* SegFind (unsigned Name);
 /* Return the given segment or NULL if not found. */
 
 int IsBSSType (Segment* S);
@@ -156,5 +156,5 @@ void CheckSegments (void);
 #endif
 
 
-
+                           
 
index d21b6e52bbfff6df3dbc70d6911162ecd65368ce..c6e4b83cb38844204e7809e4d43617ade39f2107 100644 (file)
@@ -54,3 +54,15 @@ StringPool StrPool = STATIC_STRINGPOOL_INITIALIZER;
 
 
 
+void InitStrPool (void)
+/* Initialize the string pool */
+{
+    /* We insert a first string here, which will have id zero. This means 
+     * that we can treat index zero later as invalid.
+     */
+    SP_Add (&StrPool, "<invalid message #0>");
+}
+
+
+
+     
index 0397e3eff173815aa540c12dbfea4cbecabb6465..44e0c620cb788dfc3f8821498b89203dd86e552b 100644 (file)
 
 
 
+/* An invalid message index */
+#define INVALID_STRING_ID       0U
+
+/* The string pool we're using */
 extern StringPool StrPool;
 
 
@@ -69,6 +73,19 @@ INLINE unsigned GetStringId (const char* S)
 #  define GetStringId(S)        SP_Add (&StrPool, (S))
 #endif
 
+#if defined(HAVE_INLINE)
+INLINE const char* GetString (unsigned Index)
+/* Convert a string index into a string */
+{
+    return SP_Get (&StrPool, Index);
+}
+#else
+#  define GetString(Index)      SP_Get (&StrPool, (Index))
+#endif
+
+void InitStrPool (void);
+/* Initialize the string pool */
+
 
 
 /* End of spool.h */