From edde7a3f453ae863d958d6b8db0a95e1062bfe77 Mon Sep 17 00:00:00 2001 From: cuz Date: Wed, 4 Jun 2003 12:40:14 +0000 Subject: [PATCH] Use a string pool to reduce the memory footprint git-svn-id: svn://svn.cc65.org/cc65/trunk@2197 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ca65/listing.c | 2 +- src/ca65/objcode.c | 14 ++-- src/common/fragdefs.h | 83 ++++++++++++++++++++ src/common/segdefs.h | 27 ------- src/ld65/bin.c | 32 ++++---- src/ld65/condes.c | 68 ++++++++-------- src/ld65/condes.h | 15 ++-- src/ld65/config.c | 175 ++++++++++++++++++++---------------------- src/ld65/config.h | 14 ++-- src/ld65/dbgsyms.c | 17 ++-- src/ld65/dbgsyms.h | 4 +- src/ld65/exports.c | 127 +++++++++++++++--------------- src/ld65/exports.h | 23 +++--- src/ld65/expr.c | 16 ++-- src/ld65/fragment.c | 58 +++++++++++++- src/ld65/fragment.h | 14 ++-- src/ld65/library.c | 6 +- src/ld65/main.c | 4 + src/ld65/mapfile.c | 20 ++--- src/ld65/o65.c | 32 ++++---- src/ld65/objdata.c | 31 +++++++- src/ld65/objdata.h | 10 ++- src/ld65/objfile.c | 5 ++ src/ld65/segments.c | 89 ++++++++++----------- src/ld65/segments.h | 8 +- src/ld65/spool.c | 12 +++ src/ld65/spool.h | 17 ++++ 27 files changed, 550 insertions(+), 373 deletions(-) create mode 100644 src/common/fragdefs.h diff --git a/src/ca65/listing.c b/src/ca65/listing.c index f7e777bcc..a7d6d3c99 100644 --- a/src/ca65/listing.c +++ b/src/ca65/listing.c @@ -40,7 +40,7 @@ /* common */ #include "check.h" #include "fname.h" -#include "segdefs.h" +#include "fragdefs.h" #include "version.h" #include "xmalloc.h" diff --git a/src/ca65/objcode.c b/src/ca65/objcode.c index f483fabea..bbb42b8f1 100644 --- a/src/ca65/objcode.c +++ b/src/ca65/objcode.c @@ -39,6 +39,7 @@ /* common */ #include "chartype.h" #include "check.h" +#include "fragdefs.h" #include "segdefs.h" #include "segnames.h" #include "xmalloc.h" @@ -49,10 +50,11 @@ #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 index 000000000..257b20fa3 --- /dev/null +++ b/src/common/fragdefs.h @@ -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 + + + diff --git a/src/common/segdefs.h b/src/common/segdefs.h index b6bc530b6..c41edaff3 100644 --- a/src/common/segdefs.h +++ b/src/common/segdefs.h @@ -50,33 +50,6 @@ #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 { diff --git a/src/ld65/bin.c b/src/ld65/bin.c index 017b5a15c..d1f8acd9a 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -42,15 +42,16 @@ #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) + diff --git a/src/ld65/condes.c b/src/ld65/condes.c index cbe03f4cf..2f9f29263 100644 --- a/src/ld65/condes.c +++ b/src/ld65/condes.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2000-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -38,19 +38,21 @@ /* 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 */ /*****************************************************************************/ @@ -58,22 +60,22 @@ /* 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) - - diff --git a/src/ld65/condes.h b/src/ld65/condes.h index 6285ac01b..d99608176 100644 --- a/src/ld65/condes.h +++ b/src/ld65/condes.h @@ -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); - diff --git a/src/ld65/config.c b/src/ld65/config.c index 5a9c1d8d8..5a87fd03b 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -49,12 +49,13 @@ #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; diff --git a/src/ld65/config.h b/src/ld65/config.h index e2c91e3ba..f815fc398 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -51,12 +51,12 @@ /* 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 */ diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index 9e70eda2c..12d13a83d 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -35,18 +35,19 @@ #include -/* 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); diff --git a/src/ld65/dbgsyms.h b/src/ld65/dbgsyms.h index 3b2518a43..5483116fe 100644 --- a/src/ld65/dbgsyms.h +++ b/src/ld65/dbgsyms.h @@ -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); - - diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 55ec1fdb4..7520a1c9b 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -47,11 +47,12 @@ /* 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); } + diff --git a/src/ld65/exports.h b/src/ld65/exports.h index 06cb763dd..c28d49ed4 100644 --- a/src/ld65/exports.h +++ b/src/ld65/exports.h @@ -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); + diff --git a/src/ld65/expr.c b/src/ld65/expr.c index 039e9efae..9006826dd 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -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); } diff --git a/src/ld65/fragment.c b/src/ld65/fragment.c index 19cf95311..65f10bed0 100644 --- a/src/ld65/fragment.c +++ b/src/ld65/fragment.c @@ -34,12 +34,16 @@ /* 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" @@ -49,6 +53,56 @@ +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 */ { diff --git a/src/ld65/fragment.h b/src/ld65/fragment.h index 9d70fc3ea..342f5696c 100644 --- a/src/ld65/fragment.h +++ b/src/ld65/fragment.h @@ -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 */ diff --git a/src/ld65/library.c b/src/ld65/library.c index a337cc1b1..8b3c868a5 100644 --- a/src/ld65/library.c +++ b/src/ld65/library.c @@ -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; } diff --git a/src/ld65/main.c b/src/ld65/main.c index 0024fef17..c92d96a54 100644 --- a/src/ld65/main.c +++ b/src/ld65/main.c @@ -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) { diff --git a/src/ld65/mapfile.c b/src/ld65/mapfile.c index ff9c74f98..7a8eab44e 100644 --- a/src/ld65/mapfile.c +++ b/src/ld65/mapfile.c @@ -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 */ /* */ /* */ @@ -37,15 +37,17 @@ #include #include -#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); } } } diff --git a/src/ld65/o65.c b/src/ld65/o65.c index 3f8d2058c..1a0c64544 100644 --- a/src/ld65/o65.c +++ b/src/ld65/o65.c @@ -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) + diff --git a/src/ld65/objdata.c b/src/ld65/objdata.c index 3b667eace..81320796d 100644 --- a/src/ld65/objdata.c +++ b/src/ld65/objdata.c @@ -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. diff --git a/src/ld65/objdata.h b/src/ld65/objdata.h index b5c0eea71..8da6fc080 100644 --- a/src/ld65/objdata.h +++ b/src/ld65/objdata.h @@ -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. diff --git a/src/ld65/objfile.c b/src/ld65/objfile.c index 89875fd79..ff9a14b57 100644 --- a/src/ld65/objfile.c +++ b/src/ld65/objfile.c @@ -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); } diff --git a/src/ld65/segments.c b/src/ld65/segments.c index 84f1b90e2..2c887829b 100644 --- a/src/ld65/segments.c +++ b/src/ld65/segments.c @@ -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; } diff --git a/src/ld65/segments.h b/src/ld65/segments.h index d7bfe2443..23b21bd12 100644 --- a/src/ld65/segments.h +++ b/src/ld65/segments.h @@ -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 - + diff --git a/src/ld65/spool.c b/src/ld65/spool.c index d21b6e52b..c6e4b83cb 100644 --- a/src/ld65/spool.c +++ b/src/ld65/spool.c @@ -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, ""); +} + + + + diff --git a/src/ld65/spool.h b/src/ld65/spool.h index 0397e3eff..44e0c620c 100644 --- a/src/ld65/spool.h +++ b/src/ld65/spool.h @@ -49,6 +49,10 @@ +/* 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 */ -- 2.39.5