Use a string pool to reduce the memory footprint

git-svn-id: svn://svn.cc65.org/cc65/trunk@2197 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2003-06-04 12:40:14 +00:00
parent 4937cd236f
commit edde7a3f45
27 changed files with 551 additions and 374 deletions

View File

@@ -40,7 +40,7 @@
/* common */ /* common */
#include "check.h" #include "check.h"
#include "fname.h" #include "fname.h"
#include "segdefs.h" #include "fragdefs.h"
#include "version.h" #include "version.h"
#include "xmalloc.h" #include "xmalloc.h"

View File

@@ -39,6 +39,7 @@
/* common */ /* common */
#include "chartype.h" #include "chartype.h"
#include "check.h" #include "check.h"
#include "fragdefs.h"
#include "segdefs.h" #include "segdefs.h"
#include "segnames.h" #include "segnames.h"
#include "xmalloc.h" #include "xmalloc.h"
@@ -49,10 +50,11 @@
#include "global.h" #include "global.h"
#include "lineinfo.h" #include "lineinfo.h"
#include "listing.h" #include "listing.h"
#include "objcode.h"
#include "objfile.h" #include "objfile.h"
#include "scanner.h" #include "scanner.h"
#include "spool.h"
#include "symtab.h" #include "symtab.h"
#include "objcode.h"
@@ -420,11 +422,11 @@ static void WriteOneSeg (Segment* Seg)
ObjWrite32 (0); ObjWrite32 (0);
/* Write the segment data */ /* Write the segment data */
ObjWriteStr (Seg->Def->Name); /* Name of the segment */ ObjWriteVar (GetStringId (Seg->Def->Name)); /* Name of the segment */
ObjWrite32 (Seg->PC); /* Size */ ObjWrite32 (Seg->PC); /* Size */
ObjWrite8 (Seg->Align); /* Segment alignment */ ObjWrite8 (Seg->Align); /* Segment alignment */
ObjWrite8 (Seg->Def->Type); /* Type of the segment */ ObjWrite8 (Seg->Def->Type); /* Type of the segment */
ObjWriteVar (Seg->FragCount); /* Number of fragments that follow */ ObjWriteVar (Seg->FragCount); /* Number of fragments */
/* Now walk through the fragment list for this segment and write the /* Now walk through the fragment list for this segment and write the
* fragments. * fragments.

83
src/common/fragdefs.h Normal file
View File

@@ -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

View File

@@ -50,33 +50,6 @@
#define SEGTYPE_ZP 2 #define SEGTYPE_ZP 2
#define SEGTYPE_FAR 3 #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 */ /* Segment definition */
typedef struct SegDef SegDef; typedef struct SegDef SegDef;
struct SegDef { struct SegDef {

View File

@@ -42,15 +42,16 @@
#include "xmalloc.h" #include "xmalloc.h"
/* ld65 */ /* ld65 */
#include "global.h" #include "bin.h"
#include "config.h"
#include "exports.h"
#include "expr.h"
#include "error.h" #include "error.h"
#include "global.h"
#include "fileio.h" #include "fileio.h"
#include "lineinfo.h" #include "lineinfo.h"
#include "segments.h" #include "segments.h"
#include "exports.h" #include "spool.h"
#include "config.h"
#include "expr.h"
#include "bin.h"
@@ -136,7 +137,7 @@ static void BinWriteMem (BinDesc* D, Memory* M)
SegDesc* S = N->Seg; SegDesc* S = N->Seg;
/* Keep the user happy */ /* 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 */ /* Writes do only occur in the load area and not for BSS segments */
DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */ DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */
@@ -157,7 +158,7 @@ static void BinWriteMem (BinDesc* D, Memory* M)
* in the linker. * in the linker.
*/ */
Warning ("Segment `%s' in module `%s' requires larger alignment", 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 */ /* 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 */ /* Called if an unresolved symbol is encountered */
{ {
/* Unresolved symbols are an error in binary format. Bump the counter /* Unresolved symbols are an error in binary format. Bump the counter
@@ -236,7 +237,7 @@ void BinWriteTarget (BinDesc* D, struct File* F)
Memory* M; Memory* M;
/* Place the filename in the control structure */ /* 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 /* Check for unresolved symbols. The function BinUnresolved is called
* if we get an unresolved symbol. * if we get an unresolved symbol.
@@ -249,25 +250,25 @@ void BinWriteTarget (BinDesc* D, struct File* F)
} }
/* Open the file */ /* Open the file */
D->F = fopen (F->Name, "wb"); D->F = fopen (D->Filename, "wb");
if (D->F == 0) { 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 */ /* Keep the user happy */
Print (stdout, 1, "Opened `%s'...\n", F->Name); Print (stdout, 1, "Opened `%s'...\n", D->Filename);
/* Dump all memory areas */ /* Dump all memory areas */
M = F->MemList; M = F->MemList;
while (M) { while (M) {
Print (stdout, 1, " Dumping `%s'\n", M->Name); Print (stdout, 1, " Dumping `%s'\n", GetString (M->Name));
BinWriteMem (D, M); BinWriteMem (D, M);
M = M->FNext; M = M->FNext;
} }
/* Close the file */ /* Close the file */
if (fclose (D->F) != 0) { 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 */ /* Reset the file and filename */
@@ -277,3 +278,4 @@ void BinWriteTarget (BinDesc* D, struct File* F)

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000 Ullrich von Bassewitz */ /* (C) 2000-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* R<EFBFBD>merstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -38,14 +38,16 @@
/* common */ /* common */
#include "check.h" #include "check.h"
#include "coll.h" #include "coll.h"
#include "fragdefs.h"
#include "segdefs.h" #include "segdefs.h"
#include "xmalloc.h" #include "xmalloc.h"
/* ld65 */ /* ld65 */
#include "condes.h"
#include "exports.h" #include "exports.h"
#include "fragment.h" #include "fragment.h"
#include "segments.h" #include "segments.h"
#include "condes.h" #include "spool.h"
@@ -59,21 +61,21 @@
typedef struct ConDesDesc ConDesDesc; typedef struct ConDesDesc ConDesDesc;
struct ConDesDesc { struct ConDesDesc {
Collection ExpList; /* List of exported symbols */ Collection ExpList; /* List of exported symbols */
char* SegName; /* Name of segment the table is in */ unsigned SegName; /* Name of segment the table is in */
char* Label; /* Name of table label */ unsigned Label; /* Name of table label */
char* CountSym; /* Name of symbol for entry count */ unsigned CountSym; /* Name of symbol for entry count */
unsigned char Order; /* Table order (increasing/decreasing) */ unsigned char Order; /* Table order (increasing/decreasing) */
}; };
/* Array for all types */ /* Array for all types */
static ConDesDesc ConDes[CD_TYPE_COUNT] = { static ConDesDesc ConDes[CD_TYPE_COUNT] = {
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing }, { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing }, { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing }, { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing }, { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing }, { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0, cdIncreasing }, { STATIC_COLLECTION_INITIALIZER, INVALID_STRING_ID, INVALID_STRING_ID, INVALID_STRING_ID, cdIncreasing },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0, 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; Cmp = 1;
} else { } else {
/* Use the name in this case */ /* 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 */ /* 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, /* Check if this table has a segment and table label defined. If not,
* creation was not requested in the config file - ignore it. * 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; return;
} }
@@ -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 */ /* Set the segment name where the table should go */
{ {
/* Check the parameters */ /* Check the parameters */
PRECONDITION (Type <= CD_TYPE_MAX && SegName != 0); PRECONDITION (Type <= CD_TYPE_MAX && SegName != 0);
/* Setting the segment name twice is bad */ /* Setting the segment name twice is bad */
CHECK (ConDes[Type].SegName == 0); CHECK (ConDes[Type].SegName == INVALID_STRING_ID);
/* Set the name */ /* 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 */ /* Set the label for the given ConDes type */
{ {
/* Check the parameters */ /* Check the parameters */
PRECONDITION (Type <= CD_TYPE_MAX && Name != 0); PRECONDITION (Type <= CD_TYPE_MAX && Name != 0);
/* Setting the label twice is bad */ /* Setting the label twice is bad */
CHECK (ConDes[Type].Label == 0); CHECK (ConDes[Type].Label == INVALID_STRING_ID);
/* Set the name */ /* 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 */ /* Set the name for the given ConDes count symbol */
{ {
/* Check the parameters */ /* Check the parameters */
PRECONDITION (Type <= CD_TYPE_MAX && Name != 0); PRECONDITION (Type <= CD_TYPE_MAX && Name != 0);
/* Setting the symbol twice is bad */ /* Setting the symbol twice is bad */
CHECK (ConDes[Type].CountSym == 0); CHECK (ConDes[Type].CountSym == INVALID_STRING_ID);
/* Set the name */ /* Set the name */
ConDes[Type].CountSym = xstrdup (Name); ConDes[Type].CountSym = Name;
} }
@@ -272,7 +274,7 @@ int ConDesHasSegName (unsigned Type)
/* Check the parameters */ /* Check the parameters */
PRECONDITION (Type <= CD_TYPE_MAX); 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 */ /* Check the parameters */
PRECONDITION (Type <= CD_TYPE_MAX); PRECONDITION (Type <= CD_TYPE_MAX);
return (ConDes[Type].Label != 0); return (ConDes[Type].Label != INVALID_STRING_ID);
} }
@@ -313,5 +315,3 @@ void ConDesDump (void)

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000 Ullrich von Bassewitz */ /* (C) 2000-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* R<EFBFBD>merstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -71,13 +71,13 @@ typedef enum {
void ConDesAddExport (struct Export* E); void ConDesAddExport (struct Export* E);
/* Add the given export to the list of constructors/destructor */ /* 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 */ /* 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 */ /* 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 */ /* Set the name for the given ConDes count symbol */
void ConDesSetOrder (unsigned Type, ConDesOrder Order); void ConDesSetOrder (unsigned Type, ConDesOrder Order);
@@ -103,4 +103,3 @@ void ConDesDump (void);

View File

@@ -49,12 +49,13 @@
#include "bin.h" #include "bin.h"
#include "binfmt.h" #include "binfmt.h"
#include "condes.h" #include "condes.h"
#include "config.h"
#include "error.h" #include "error.h"
#include "exports.h" #include "exports.h"
#include "global.h" #include "global.h"
#include "o65.h" #include "o65.h"
#include "scanner.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 */ /* 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. */ /* Find a file with a given name. */
{ {
File* F = FileList; File* F = FileList;
while (F) { while (F) {
if (strcmp (F->Name, Name) == 0) { if (F->Name == Name) {
return F; return F;
} }
F = F->Next; 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. */ /* Get a file entry with the given name. Create a new one if needed. */
{ {
File* F = FindFile (Name); 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 */ /* Find the memory are with the given name. Return NULL if not found */
{ {
Memory* M = MemoryList; Memory* M = MemoryList;
while (M) { while (M) {
if (strcmp (M->Name, Name) == 0) { if (M->Name == Name) {
return M; return M;
} }
M = M->Next; 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 */ /* Find the memory are with the given name. Print an error on an invalid name */
{ {
Memory* M = CfgFindMemory (Name); Memory* M = CfgFindMemory (Name);
if (M == 0) { if (M == 0) {
CfgError ("Invalid memory area `%s'", Name); CfgError ("Invalid memory area `%s'", GetString (Name));
} }
return M; 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. */ /* Find the segment descriptor with the given name, return NULL if not found. */
{ {
SegDesc* S = SegDescList; SegDesc* S = SegDescList;
while (S) { while (S) {
if (strcmp (S->Name, Name) == 0) { if (S->Name == Name) {
/* Found */ /* Found */
return S; 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 */ /* Create a new file descriptor and insert it into the list */
{ {
/* Get the length of the name */
unsigned Len = strlen (Name);
/* Allocate memory */ /* Allocate memory */
File* F = xmalloc (sizeof (File) + Len); File* F = xmalloc (sizeof (File));
/* Initialize the fields */ /* Initialize the fields */
F->Name = Name;
F->Flags = 0; F->Flags = 0;
F->Format = BINFMT_DEFAULT; F->Format = BINFMT_DEFAULT;
F->MemList = 0; F->MemList = 0;
F->MemLast = 0; F->MemLast = 0;
memcpy (F->Name, Name, Len);
F->Name [Len] = '\0';
/* Insert the struct into the list */ /* Insert the struct into the list */
F->Next = FileList; 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 */ /* 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 */ /* Check for duplicate names */
Memory* M = CfgFindMemory (Name); Memory* M = CfgFindMemory (Name);
if (M) { if (M) {
CfgError ("Memory area `%s' defined twice", Name); CfgError ("Memory area `%s' defined twice", GetString (Name));
} }
/* Allocate memory */ /* Allocate memory */
M = xmalloc (sizeof (Memory) + Len); M = xmalloc (sizeof (Memory));
/* Initialize the fields */ /* Initialize the fields */
M->Name = Name;
M->Next = 0; M->Next = 0;
M->FNext = 0; M->FNext = 0;
M->Attr = 0; M->Attr = 0;
@@ -304,8 +299,6 @@ static Memory* NewMemory (const char* Name)
M->SegList = 0; M->SegList = 0;
M->SegLast = 0; M->SegLast = 0;
M->F = 0; M->F = 0;
memcpy (M->Name, Name, Len);
M->Name [Len] = '\0';
/* Insert the struct into the list */ /* Insert the struct into the list */
if (MemoryLast == 0) { 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 */ /* Create a segment descriptor */
{ {
Segment* Seg; Segment* Seg;
/* Get the length of the name */
unsigned Len = strlen (Name);
/* Check for duplicate names */ /* Check for duplicate names */
SegDesc* S = CfgFindSegDesc (Name); SegDesc* S = CfgFindSegDesc (Name);
if (S) { 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 /* 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); Seg = SegFind (Name);
/* Allocate memory */ /* Allocate memory */
S = xmalloc (sizeof (SegDesc) + Len); S = xmalloc (sizeof (SegDesc));
/* Initialize the fields */ /* Initialize the fields */
S->Name = Name;
S->Next = 0; S->Next = 0;
S->Seg = Seg; S->Seg = Seg;
S->Attr = 0; S->Attr = 0;
S->Flags = 0; S->Flags = 0;
S->Align = 0; S->Align = 0;
memcpy (S->Name, Name, Len);
S->Name [Len] = '\0';
/* ...and return it */ /* ...and return it */
return S; return S;
@@ -417,7 +406,7 @@ static void ParseMemory (void)
while (CfgTok == CFGTOK_IDENT) { while (CfgTok == CFGTOK_IDENT) {
/* Create a new entry on the heap */ /* Create a new entry on the heap */
Memory* M = NewMemory (CfgSVal); Memory* M = NewMemory (GetStringId (CfgSVal));
/* Skip the name and the following colon */ /* Skip the name and the following colon */
CfgNextTok (); CfgNextTok ();
@@ -462,7 +451,7 @@ static void ParseMemory (void)
FlagAttr (&M->Attr, MA_FILE, "FILE"); FlagAttr (&M->Attr, MA_FILE, "FILE");
CfgAssureStr (); CfgAssureStr ();
/* Get the file entry and insert the memory area */ /* Get the file entry and insert the memory area */
FileInsert (GetFile (CfgSVal), M); FileInsert (GetFile (GetStringId (CfgSVal)), M);
break; break;
case CFGTOK_DEFINE: case CFGTOK_DEFINE:
@@ -511,7 +500,7 @@ static void ParseMemory (void)
* file name. * file name.
*/ */
if ((M->Attr & MA_FILE) == 0) { if ((M->Attr & MA_FILE) == 0) {
FileInsert (GetFile (OutputName), M); FileInsert (GetFile (GetStringId (OutputName)), M);
} }
} }
} }
@@ -540,7 +529,7 @@ static void ParseFiles (void)
CfgAssureStr (); CfgAssureStr ();
/* Search for the file, it must exist */ /* Search for the file, it must exist */
F = FindFile (CfgSVal); F = FindFile (GetStringId (CfgSVal));
if (F == 0) { if (F == 0) {
CfgError ("No such file: `%s'", CfgSVal); CfgError ("No such file: `%s'", CfgSVal);
} }
@@ -633,7 +622,7 @@ static void ParseSegments (void)
SegDesc* S; SegDesc* S;
/* Create a new entry on the heap */ /* Create a new entry on the heap */
S = NewSegDesc (CfgSVal); S = NewSegDesc (GetStringId (CfgSVal));
/* Skip the name and the following colon */ /* Skip the name and the following colon */
CfgNextTok (); CfgNextTok ();
@@ -676,7 +665,7 @@ static void ParseSegments (void)
case CFGTOK_LOAD: case CFGTOK_LOAD:
FlagAttr (&S->Attr, SA_LOAD, "LOAD"); FlagAttr (&S->Attr, SA_LOAD, "LOAD");
S->Load = CfgGetMemory (CfgSVal); S->Load = CfgGetMemory (GetStringId (CfgSVal));
break; break;
case CFGTOK_OFFSET: case CFGTOK_OFFSET:
@@ -697,7 +686,7 @@ static void ParseSegments (void)
case CFGTOK_RUN: case CFGTOK_RUN:
FlagAttr (&S->Attr, SA_RUN, "RUN"); FlagAttr (&S->Attr, SA_RUN, "RUN");
S->Run = CfgGetMemory (CfgSVal); S->Run = CfgGetMemory (GetStringId (CfgSVal));
break; break;
case CFGTOK_START: case CFGTOK_START:
@@ -768,7 +757,7 @@ static void ParseSegments (void)
if ((S->Flags & SF_RO) == 0) { if ((S->Flags & SF_RO) == 0) {
if (S->Run->Flags & MF_RO) { if (S->Run->Flags & MF_RO) {
CfgError ("Cannot put r/w segment `%s' in r/o memory area `%s'", 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 { } else {
/* Print a warning if the segment is not optional */ /* Print a warning if the segment is not optional */
if ((S->Flags & SF_OPTIONAL) == 0) { 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 */ /* Discard the descriptor */
FreeSegDesc (S); FreeSegDesc (S);
@@ -1048,9 +1037,9 @@ static void ParseConDes (void)
}; };
/* Attribute values. */ /* Attribute values. */
char SegName[sizeof (CfgSVal)]; unsigned SegName = INVALID_STRING_ID;
char Label[sizeof (CfgSVal)]; unsigned Label = INVALID_STRING_ID;
char Count[sizeof (CfgSVal)]; unsigned Count = INVALID_STRING_ID;
/* Initialize to avoid gcc warnings: */ /* Initialize to avoid gcc warnings: */
int Type = -1; int Type = -1;
ConDesOrder Order = cdIncreasing; ConDesOrder Order = cdIncreasing;
@@ -1087,7 +1076,7 @@ static void ParseConDes (void)
/* We expect an identifier */ /* We expect an identifier */
CfgAssureIdent (); CfgAssureIdent ();
/* Remember the value for later */ /* Remember the value for later */
strcpy (SegName, CfgSVal); SegName = GetStringId (CfgSVal);
break; break;
case CFGTOK_LABEL: case CFGTOK_LABEL:
@@ -1096,7 +1085,7 @@ static void ParseConDes (void)
/* We expect an identifier */ /* We expect an identifier */
CfgAssureIdent (); CfgAssureIdent ();
/* Remember the value for later */ /* Remember the value for later */
strcpy (Label, CfgSVal); Label = GetStringId (CfgSVal);
break; break;
case CFGTOK_COUNT: case CFGTOK_COUNT:
@@ -1105,7 +1094,7 @@ static void ParseConDes (void)
/* We expect an identifier */ /* We expect an identifier */
CfgAssureIdent (); CfgAssureIdent ();
/* Remember the value for later */ /* Remember the value for later */
strcpy (Count, CfgSVal); Count = GetStringId (CfgSVal);
break; break;
case CFGTOK_TYPE: case CFGTOK_TYPE:
@@ -1297,8 +1286,7 @@ static void ParseSymbols (void)
long Val; long Val;
/* Remember the name */ /* Remember the name */
char Name [sizeof (CfgSVal)]; unsigned Name = GetStringId (CfgSVal);
strcpy (Name, CfgSVal);
CfgNextTok (); CfgNextTok ();
/* Allow an optional assignment */ /* Allow an optional assignment */
@@ -1408,10 +1396,10 @@ static void CreateRunDefines (SegDesc* S)
{ {
char Buf [256]; char Buf [256];
xsprintf (Buf, sizeof (Buf), "__%s_RUN__", S->Name); xsprintf (Buf, sizeof (Buf), "__%s_RUN__", GetString (S->Name));
CreateSegmentExport (Buf, S->Seg, 0); CreateSegmentExport (GetStringId (Buf), S->Seg, 0);
xsprintf (Buf, sizeof (Buf), "__%s_SIZE__", S->Name); xsprintf (Buf, sizeof (Buf), "__%s_SIZE__", GetString (S->Name));
CreateConstExport (Buf, S->Seg->Size); CreateConstExport (GetStringId (Buf), S->Seg->Size);
S->Flags |= SF_RUN_DEF; S->Flags |= SF_RUN_DEF;
} }
@@ -1422,8 +1410,8 @@ static void CreateLoadDefines (Memory* M, SegDesc* S)
{ {
char Buf [256]; char Buf [256];
xsprintf (Buf, sizeof (Buf), "__%s_LOAD__", S->Name); xsprintf (Buf, sizeof (Buf), "__%s_LOAD__", GetString (S->Name));
CreateMemoryExport (Buf, M, S->Seg->PC - M->Start); CreateMemoryExport (GetStringId (Buf), M, S->Seg->PC - M->Start);
S->Flags |= SF_LOAD_DEF; S->Flags |= SF_LOAD_DEF;
} }
@@ -1465,10 +1453,10 @@ void CfgAssignSegments (void)
/* Offset already too large */ /* Offset already too large */
if (S->Flags & SF_OFFSET) { if (S->Flags & SF_OFFSET) {
Error ("Offset too small in `%s', segment `%s'", Error ("Offset too small in `%s', segment `%s'",
M->Name, S->Name); GetString (M->Name), GetString (S->Name));
} else { } else {
Error ("Start address too low in `%s', segment `%s'", Error ("Start address too low in `%s', segment `%s'",
M->Name, S->Name); GetString (M->Name), GetString (S->Name));
} }
} }
Addr = NewAddr; Addr = NewAddr;
@@ -1485,7 +1473,8 @@ void CfgAssignSegments (void)
M->FillLevel = Addr + S->Seg->Size - M->Start; M->FillLevel = Addr + S->Seg->Size - M->Start;
if (M->FillLevel > M->Size) { if (M->FillLevel > M->Size) {
Error ("Memory area overflow in `%s', segment `%s' (%lu bytes)", 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 /* If requested, define symbols for the start and size of the
@@ -1531,12 +1520,12 @@ void CfgAssignSegments (void)
/* If requested, define symbols for start and size of the memory area */ /* If requested, define symbols for start and size of the memory area */
if (M->Flags & MF_DEFINE) { if (M->Flags & MF_DEFINE) {
char Buf [256]; char Buf [256];
sprintf (Buf, "__%s_START__", M->Name); sprintf (Buf, "__%s_START__", GetString (M->Name));
CreateMemoryExport (Buf, M, 0); CreateMemoryExport (GetStringId (Buf), M, 0);
sprintf (Buf, "__%s_SIZE__", M->Name); sprintf (Buf, "__%s_SIZE__", GetString (M->Name));
CreateConstExport (Buf, M->Size); CreateConstExport (GetStringId (Buf), M->Size);
sprintf (Buf, "__%s_LAST__", M->Name); sprintf (Buf, "__%s_LAST__", GetString (M->Name));
CreateConstExport (Buf, M->FillLevel); CreateConstExport (GetStringId (Buf), M->FillLevel);
} }
/* Next memory area */ /* Next memory area */
@@ -1558,7 +1547,7 @@ void CfgWriteTarget (void)
if (F->MemList) { if (F->MemList) {
/* Is there an output file? */ /* Is there an output file? */
if (strlen (F->Name) > 0) { if (strlen (GetString (F->Name)) > 0) {
/* Assign a proper binary format */ /* Assign a proper binary format */
if (F->Format == BINFMT_DEFAULT) { if (F->Format == BINFMT_DEFAULT) {
@@ -1592,7 +1581,7 @@ void CfgWriteTarget (void)
MemListNode* N; MemListNode* N;
/* Debugging */ /* Debugging */
Print (stdout, 2, "Skipping `%s'...\n", M->Name); Print (stdout, 2, "Skipping `%s'...\n", GetString (M->Name));
/* Walk throught the segments */ /* Walk throught the segments */
N = M->SegList; N = M->SegList;

View File

@@ -51,12 +51,12 @@
/* File list entry */ /* File list entry */
typedef struct File File; typedef struct File File;
struct File { struct File {
unsigned Name; /* Name index of the file */
File* Next; /* Pointer to next entry in list */ File* Next; /* Pointer to next entry in list */
unsigned Flags; unsigned Flags;
unsigned Format; /* Output format */ unsigned Format; /* Output format */
struct Memory* MemList; /* List of memory areas in this file */ struct Memory* MemList; /* List of memory areas in this file */
struct Memory* MemLast; /* Last memory area 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) */ /* Segment list node. Needed because there are two lists (RUN & LOAD) */
@@ -69,6 +69,7 @@ struct MemListNode {
/* Memory list entry */ /* Memory list entry */
typedef struct Memory Memory; typedef struct Memory Memory;
struct Memory { struct Memory {
unsigned Name; /* Name index of the memory section */
Memory* Next; /* Pointer to next entry in list */ Memory* Next; /* Pointer to next entry in list */
Memory* FNext; /* Next in file list */ Memory* FNext; /* Next in file list */
unsigned Attr; /* Which values are valid? */ unsigned Attr; /* Which values are valid? */
@@ -80,12 +81,12 @@ struct Memory {
MemListNode* SegList; /* List of segments for this section */ MemListNode* SegList; /* List of segments for this section */
MemListNode* SegLast; /* Last segment in this section */ MemListNode* SegLast; /* Last segment in this section */
File* F; /* File that contains the entry */ File* F; /* File that contains the entry */
char Name [1]; /* Name of the memory section */
}; };
/* Segment descriptor entry */ /* Segment descriptor entry */
typedef struct SegDesc SegDesc; typedef struct SegDesc SegDesc;
struct SegDesc { struct SegDesc {
unsigned Name; /* Index of the name */
SegDesc* Next; /* Pointer to next entry in list */ SegDesc* Next; /* Pointer to next entry in list */
Segment* Seg; /* Pointer to segment structure */ Segment* Seg; /* Pointer to segment structure */
unsigned Attr; /* Attributes for segment */ unsigned Attr; /* Attributes for segment */
@@ -94,7 +95,6 @@ struct SegDesc {
Memory* Run; /* Run memory section */ Memory* Run; /* Run memory section */
unsigned long Addr; /* Start address or offset into segment */ unsigned long Addr; /* Start address or offset into segment */
unsigned char Align; /* Alignment if given */ unsigned char Align; /* Alignment if given */
char Name [1]; /* Copy of name */
}; };
/* Segment list */ /* Segment list */

View File

@@ -41,12 +41,13 @@
#include "xmalloc.h" #include "xmalloc.h"
/* ld65 */ /* ld65 */
#include "global.h"
#include "error.h"
#include "fileio.h"
#include "objdata.h"
#include "expr.h"
#include "dbgsyms.h" #include "dbgsyms.h"
#include "error.h"
#include "expr.h"
#include "fileio.h"
#include "global.h"
#include "objdata.h"
#include "spool.h"
@@ -101,10 +102,10 @@ static DbgSym* GetDbgSym (DbgSym* D, long Val)
((Val >> 0) & 0xFF); ((Val >> 0) & 0xFF);
/* Check for this symbol */ /* Check for this symbol */
DbgSym* Sym = DbgSymPool [Hash]; DbgSym* Sym = DbgSymPool[Hash];
while (Sym) { while (Sym) {
/* Is this symbol identical? */ /* 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 */ /* Found */
return Sym; return Sym;
} }
@@ -148,7 +149,7 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O)
D = NewDbgSym (Type, O); D = NewDbgSym (Type, O);
/* Read and assign the name */ /* Read and assign the name */
D->Name = GetObjString (O, ReadVar (F)); D->Name = MakeGlobalStringId (O, ReadVar (F));
/* Read the value */ /* Read the value */
if (IS_EXP_EXPR (Type)) { if (IS_EXP_EXPR (Type)) {
@@ -196,7 +197,7 @@ void PrintDbgSymLabels (ObjData* O, FILE* F)
if (GetDbgSym (D, Val) == 0) { if (GetDbgSym (D, Val) == 0) {
/* Emit the VICE label line */ /* 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 */ /* Insert the symbol into the table */
InsertDbgSym (D, Val); InsertDbgSym (D, Val);

View File

@@ -63,7 +63,7 @@ struct DbgSym {
ObjData* Obj; /* Object file that exports the name */ ObjData* Obj; /* Object file that exports the name */
FilePos Pos; /* File position of definition */ FilePos Pos; /* File position of definition */
ExprNode* Expr; /* Expression (0 if not def'd) */ ExprNode* Expr; /* Expression (0 if not def'd) */
const char* Name; /* Name */ unsigned Name; /* Name */
unsigned char Type; /* Type of symbol */ unsigned char Type; /* Type of symbol */
}; };
@@ -92,5 +92,3 @@ void PrintDbgSymLabels (ObjData* O, FILE* F);

View File

@@ -47,11 +47,12 @@
/* ld65 */ /* ld65 */
#include "condes.h" #include "condes.h"
#include "error.h" #include "error.h"
#include "exports.h"
#include "expr.h"
#include "fileio.h" #include "fileio.h"
#include "global.h" #include "global.h"
#include "objdata.h" #include "objdata.h"
#include "expr.h" #include "spool.h"
#include "exports.h"
@@ -62,8 +63,9 @@
/* Hash table */ /* Hash table */
#define HASHTAB_SIZE 4081 #define HASHTAB_MASK 0x0FFFU
static Export* HashTab [HASHTAB_SIZE]; #define HASHTAB_SIZE (HASHTAB_MASK + 1)
static Export* HashTab[HASHTAB_SIZE];
/* Import management variables */ /* Import management variables */
static unsigned ImpCount = 0; /* Import count */ 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 */ /* Create a new export and initialize it */
@@ -98,7 +100,8 @@ static Import* NewImport (unsigned char Type, ObjData* Obj)
/* Initialize the fields */ /* Initialize the fields */
I->Next = 0; I->Next = 0;
I->Obj = Obj; I->Obj = Obj;
I->V.Name = 0; I->Exp = 0;
I->Name = INVALID_STRING_ID;
I->Type = Type; I->Type = Type;
/* Return the new structure */ /* Return the new structure */
@@ -111,23 +114,22 @@ void InsertImport (Import* I)
/* Insert an import into the table */ /* Insert an import into the table */
{ {
Export* E; Export* E;
unsigned HashVal;
/* As long as the import is not inserted, V.Name is valid */ /* 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 */ /* 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 */ /* 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 */ /* 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; ++ExpCount;
} else { } else {
E = HashTab [HashVal]; E = HashTab [Hash];
while (1) { while (1) {
if (strcmp (E->Name, Name) == 0) { if (E->Name == Name) {
/* We have an entry, L points to it */ /* We have an entry, L points to it */
break; break;
} }
@@ -146,7 +148,7 @@ void InsertImport (Import* I)
/* Ok, E now points to a valid exports entry for the given import. Insert /* Ok, E now points to a valid exports entry for the given import. Insert
* the import into the imports list and update the counters. * the import into the imports list and update the counters.
*/ */
I->V.Exp = E; I->Exp = E;
I->Next = E->ImpList; I->Next = E->ImpList;
E->ImpList = I; E->ImpList = I;
E->ImpCount++; E->ImpCount++;
@@ -175,7 +177,7 @@ Import* ReadImport (FILE* F, ObjData* Obj)
I = NewImport (Type, Obj); I = NewImport (Type, Obj);
/* Read the name */ /* Read the name */
I->V.Name = GetObjString (Obj, ReadVar (F)); I->Name = MakeGlobalStringId (Obj, ReadVar (F));
/* Read the file position */ /* Read the file position */
ReadFilePos (F, &I->Pos); 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 */ /* Create a new export and initialize it */
{ {
/* Allocate memory */ /* Allocate memory */
Export* E = xmalloc (sizeof (Export)); Export* E = xmalloc (sizeof (Export));
/* Initialize the fields */ /* Initialize the fields */
E->Name = Name;
E->Next = 0; E->Next = 0;
E->Flags = 0; E->Flags = 0;
E->Obj = Obj; E->Obj = Obj;
@@ -207,12 +210,6 @@ static Export* NewExport (unsigned char Type, const char* Name, ObjData* Obj)
E->Expr = 0; E->Expr = 0;
E->Type = Type; E->Type = Type;
memset (E->ConDes, 0, sizeof (E->ConDes)); 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 the new entry */
return E; return E;
@@ -226,7 +223,7 @@ void InsertExport (Export* E)
Export* L; Export* L;
Export* Last; Export* Last;
Import* Imp; Import* Imp;
unsigned HashVal; unsigned Hash;
/* Insert the export into any condes tables if needed */ /* Insert the export into any condes tables if needed */
if (IS_EXP_CONDES (E->Type)) { if (IS_EXP_CONDES (E->Type)) {
@@ -234,19 +231,19 @@ void InsertExport (Export* E)
} }
/* Create a hash value for the given name */ /* 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 */ /* Search through the list in that slot */
if (HashTab [HashVal] == 0) { if (HashTab[Hash] == 0) {
/* The slot is empty */ /* The slot is empty */
HashTab [HashVal] = E; HashTab[Hash] = E;
++ExpCount; ++ExpCount;
} else { } else {
Last = 0; Last = 0;
L = HashTab [HashVal]; L = HashTab[Hash];
do { do {
if (strcmp (L->Name, E->Name) == 0) { if (L->Name == E->Name) {
/* This may be an unresolved external */ /* This may be an unresolved external */
if (L->Expr == 0) { if (L->Expr == 0) {
@@ -257,7 +254,7 @@ void InsertExport (Export* E)
if (Last) { if (Last) {
Last->Next = E; Last->Next = E;
} else { } else {
HashTab [HashVal] = E; HashTab[Hash] = E;
} }
ImpOpen -= E->ImpCount; /* Decrease open imports now */ ImpOpen -= E->ImpCount; /* Decrease open imports now */
xfree (L); xfree (L);
@@ -266,12 +263,13 @@ void InsertExport (Export* E)
*/ */
Imp = E->ImpList; Imp = E->ImpList;
while (Imp) { while (Imp) {
Imp->V.Exp = E; Imp->Exp = E;
Imp = Imp->Next; Imp = Imp->Next;
} }
} else { } else {
/* Duplicate entry, ignore it */ /* Duplicate entry, ignore it */
Warning ("Duplicate external identifier: `%s'", L->Name); Warning ("Duplicate external identifier: `%s'",
GetString (L->Name));
} }
return; return;
} }
@@ -299,7 +297,7 @@ Export* ReadExport (FILE* F, ObjData* O)
Type = Read8 (F); Type = Read8 (F);
/* Create a new export without a name */ /* 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 */ /* Read the constructor/destructor decls if we have any */
ConDesCount = GET_EXP_CONDES_COUNT (Type); ConDesCount = GET_EXP_CONDES_COUNT (Type);
@@ -325,7 +323,7 @@ Export* ReadExport (FILE* F, ObjData* O)
} }
/* Read the name */ /* Read the name */
E->Name = GetObjString (O, ReadVar (F)); E->Name = MakeGlobalStringId (O, ReadVar (F));
/* Read the value */ /* Read the value */
if (IS_EXP_EXPR (Type)) { 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 an export for a literal date */
{ {
/* Create a new export */ /* 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 an relative export for a memory area offset */
{ {
/* Create a new export */ /* 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 relative export to a segment */
{ {
/* Create a new export */ /* 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 relative export to a section */
{ {
/* Create a new export */ /* 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 /* Check for an identifier in the list. Return 0 if not found, otherwise
* return a pointer to the export. * return a pointer to the export.
*/ */
{ {
/* Get a pointer to the list with the symbols hash value */ /* 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) { while (L) {
/* Search through the list in that slot */ /* Search through the list in that slot */
if (strcmp (L->Name, Name) == 0) { if (L->Name == Name) {
/* Entry found */ /* Entry found */
return L; 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 */ /* Check if this symbol is an unresolved export */
{ {
/* Find the export */ /* Find the export */
@@ -473,7 +471,7 @@ long GetExportVal (const Export* E)
{ {
if (E->Expr == 0) { if (E->Expr == 0) {
/* OOPS */ /* OOPS */
Internal ("`%s' is an undefined external", E->Name); Internal ("`%s' is an undefined external", GetString (E->Name));
} }
return GetExprVal (E->Expr); return GetExprVal (E->Expr);
} }
@@ -493,13 +491,16 @@ static void CheckSymType (const Export* E)
/* User defined export */ /* User defined export */
Warning ("Type mismatch for `%s', export in " Warning ("Type mismatch for `%s', export in "
"%s(%lu), import in %s(%lu)", "%s(%lu), import in %s(%lu)",
E->Name, GetSourceFileName (E->Obj, Imp->Pos.Name), GetString (E->Name),
E->Pos.Line, GetSourceFileName (Imp->Obj, Imp->Pos.Name), GetSourceFileName (E->Obj, Imp->Pos.Name),
E->Pos.Line,
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
Imp->Pos.Line); Imp->Pos.Line);
} else { } else {
/* Export created by the linker */ /* Export created by the linker */
Warning ("Type mismatch for `%s', imported from %s(%lu)", 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); Imp->Pos.Line);
} }
} }
@@ -541,7 +542,7 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
Import* Imp = E->ImpList; Import* Imp = E->ImpList;
fprintf (stderr, fprintf (stderr,
"Unresolved external `%s' referenced in:\n", "Unresolved external `%s' referenced in:\n",
E->Name); GetString (E->Name));
while (Imp) { while (Imp) {
const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name); const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name);
fprintf (stderr, " %s(%lu)\n", Name, Imp->Pos.Line); 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) static int CmpExpName (const void* K1, const void* K2)
/* Compare function for qsort */ /* 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 */ /* Walk through the list and insert the exports */
for (I = 0, J = 0; I < sizeof (HashTab) / sizeof (HashTab [0]); ++I) { for (I = 0, J = 0; I < sizeof (HashTab) / sizeof (HashTab [0]); ++I) {
Export* E = HashTab [I]; Export* E = HashTab[I];
while (E) { while (E) {
CHECK (J < ExpCount); CHECK (J < ExpCount);
ExpPool [J++] = E; ExpPool[J++] = E;
E = E->Next; E = E->Next;
} }
} }
@@ -623,7 +625,7 @@ void PrintExportMap (FILE* F)
if (VerboseMap || E->ImpCount > 0 || IS_EXP_CONDES (E->Type)) { if (VerboseMap || E->ImpCount > 0 || IS_EXP_CONDES (E->Type)) {
fprintf (F, fprintf (F,
"%-25s %06lX %c%c%c%c ", "%-25s %06lX %c%c%c%c ",
E->Name, GetString (E->Name),
GetExportVal (E), GetExportVal (E),
E->ImpCount? 'R' : ' ', E->ImpCount? 'R' : ' ',
IS_EXP_LABEL (E->Type)? 'L' : 'E', IS_EXP_LABEL (E->Type)? 'L' : 'E',
@@ -660,7 +662,7 @@ void PrintImportMap (FILE* F)
/* Print the export */ /* Print the export */
fprintf (F, fprintf (F,
"%s (%s):\n", "%s (%s):\n",
Exp->Name, GetString (Exp->Name),
GetObjFileName (Exp->Obj)); GetObjFileName (Exp->Obj));
/* Print all imports for this symbol */ /* Print all imports for this symbol */
@@ -692,7 +694,7 @@ void PrintExportLabels (FILE* F)
/* Print all exports */ /* Print all exports */
for (I = 0; I < ExpCount; ++I) { for (I = 0; I < ExpCount; ++I) {
const Export* E = ExpPool [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 */ /* Print an error about a circular reference using to define the given export */
{ {
Error ("Circular reference for symbol `%s', %s(%lu)", 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);
} }

View File

@@ -63,10 +63,8 @@ struct Import {
Import* Next; /* Single linked list */ Import* Next; /* Single linked list */
ObjData* Obj; /* Object file that imports the name */ ObjData* Obj; /* Object file that imports the name */
FilePos Pos; /* File position of reference */ FilePos Pos; /* File position of reference */
union {
struct Export* Exp; /* Matching export for this import */ struct Export* Exp; /* Matching export for this import */
const char* Name; /* Name if not in table */ unsigned Name; /* Name if not in table */
} V;
unsigned char Type; /* Type of import */ unsigned char Type; /* Type of import */
}; };
@@ -75,6 +73,7 @@ struct Import {
/* Export symbol structure */ /* Export symbol structure */
typedef struct Export Export; typedef struct Export Export;
struct Export { struct Export {
unsigned Name; /* Name */
Export* Next; /* Hash table link */ Export* Next; /* Hash table link */
unsigned Flags; /* Generic flags */ unsigned Flags; /* Generic flags */
ObjData* Obj; /* Object file that exports the name */ ObjData* Obj; /* Object file that exports the name */
@@ -84,7 +83,6 @@ struct Export {
ExprNode* Expr; /* Expression (0 if not def'd) */ ExprNode* Expr; /* Expression (0 if not def'd) */
unsigned char Type; /* Type of export */ unsigned char Type; /* Type of export */
unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */ 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 * resolved, or a value != zero if the symbol could be resolved. The
* CheckExports routine will print out the missing symbol in the first case. * 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); void InsertExport (Export* E);
/* Insert an exported identifier and check if it's already in the list */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 /* Check for an identifier in the list. Return 0 if not found, otherwise
* return a pointer to the export. * return a pointer to the export.
*/ */
int IsUnresolved (const char* Name); int IsUnresolved (unsigned Name);
/* Check if this symbol is an unresolved export */ /* Check if this symbol is an unresolved export */
int IsUnresolvedExport (const Export* E); int IsUnresolvedExport (const Export* E);
@@ -180,3 +178,4 @@ void CircularRefError (const Export* E);

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2000 Ullrich von Bassewitz */ /* (C) 1998-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* R<EFBFBD>merstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* 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. * which in turn means, that we have a circular reference.
*/ */
if (ExportHasMark (E)) { if (ExportHasMark (E)) {
Error ("Circular reference for symbol `%s', %s(%lu)", CircularRefError (E);
E->Name, GetSourceFileName (E->Obj, E->Pos.Name),
E->Pos.Line);
Const = 0; Const = 0;
} else { } else {
MarkExport (E); MarkExport (E);
@@ -198,7 +196,7 @@ Export* GetExprExport (ExprNode* Expr)
PRECONDITION (Expr->Op == EXPR_SYMBOL); PRECONDITION (Expr->Op == EXPR_SYMBOL);
/* Return the export */ /* Return the export */
return Expr->Obj->Imports [Expr->V.ImpNum]->V.Exp; return Expr->Obj->Imports [Expr->V.ImpNum]->Exp;
} }

View File

@@ -34,12 +34,16 @@
/* common */ /* common */
#include "segdefs.h" #include "fragdefs.h"
#include "xmalloc.h" #include "xmalloc.h"
/* ld65 */ /* ld65 */
#include "segments.h" #include "error.h"
#include "expr.h"
#include "fragment.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) Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
/* Create a new fragment and insert it into the section S */ /* Create a new fragment and insert it into the section S */
{ {

View File

@@ -50,6 +50,7 @@
struct LineInfo; struct LineInfo;
struct ObjData;
struct Section; struct Section;
@@ -61,9 +62,9 @@ struct Section;
/* Fragment check expression */ /* Fragment check expression */
typedef struct CheckExpr CheckExpr; typedef struct FragCheck FragCheck;
struct CheckExpr { struct FragCheck {
struct CheckExpr* Next; /* Next check expression */ struct FragCheck* Next; /* Next check expression */
struct ExprNode* Expr; /* The expression itself */ struct ExprNode* Expr; /* The expression itself */
unsigned Action; /* Action to take if the check fails */ unsigned Action; /* Action to take if the check fails */
unsigned Message; /* Message number */ unsigned Message; /* Message number */
@@ -78,7 +79,7 @@ struct Fragment {
struct ExprNode* Expr; /* Expression if FRAG_EXPR */ 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 */ 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 Type; /* Type of fragment */
unsigned char LitBuf [1]; /* Dynamically alloc'ed literal buffer */ 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); Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
/* Create a new fragment and insert it into the section S */ /* Create a new fragment and insert it into the section S */

View File

@@ -278,9 +278,13 @@ void LibAdd (FILE* F, const char* Name)
/* We have the data now */ /* We have the data now */
O->Flags |= OBJ_HAVEDATA; 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 */ /* Add a pointer to the library name */
O->LibName = LibName; O->LibName = LibName;
} }

View File

@@ -62,6 +62,7 @@
#include "objfile.h" #include "objfile.h"
#include "scanner.h" #include "scanner.h"
#include "segments.h" #include "segments.h"
#include "spool.h"
#include "tgtcfg.h" #include "tgtcfg.h"
@@ -404,6 +405,9 @@ int main (int argc, char* argv [])
/* Initialize the input file search paths */ /* Initialize the input file search paths */
InitSearchPaths (); InitSearchPaths ();
/* Initialize the string pool */
InitStrPool ();
/* Check the parameters */ /* Check the parameters */
I = 1; I = 1;
while (I < ArgCount) { while (I < ArgCount) {

View File

@@ -6,9 +6,9 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2001 Ullrich von Bassewitz */ /* (C) 1998-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* R<EFBFBD>merstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
@@ -37,15 +37,17 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "global.h" /* ld65 */
#include "error.h" #include "config.h"
#include "objdata.h"
#include "segments.h"
#include "dbginfo.h" #include "dbginfo.h"
#include "dbgsyms.h" #include "dbgsyms.h"
#include "exports.h" #include "exports.h"
#include "config.h" #include "global.h"
#include "error.h"
#include "mapfile.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) { if (VerboseMap || S->Size > 0) {
fprintf (F, " %-15s Offs = %06lX Size = %06lX\n", fprintf (F, " %-15s Offs = %06lX Size = %06lX\n",
S->Seg->Name, S->Offs, S->Size); GetString (S->Seg->Name), S->Offs, S->Size);
} }
} }
} }

View File

@@ -6,9 +6,9 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1999-2001 Ullrich von Bassewitz */ /* (C) 1998-2003 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* R<EFBFBD>merstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
@@ -53,6 +53,7 @@
#include "global.h" #include "global.h"
#include "lineinfo.h" #include "lineinfo.h"
#include "o65.h" #include "o65.h"
#include "spool.h"
@@ -149,7 +150,7 @@ struct O65Desc {
ExtSymTab* Imports; /* Table with imported symbols */ ExtSymTab* Imports; /* Table with imported symbols */
unsigned Undef; /* Count of undefined symbols */ unsigned Undef; /* Count of undefined symbols */
FILE* F; /* The file we're writing to */ 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* TextReloc; /* Relocation table for text segment */
O65RelocTab* DataReloc; /* Relocation table for data segment */ O65RelocTab* DataReloc; /* Relocation table for data segment */
@@ -315,7 +316,7 @@ static void O65ParseExpr (ExprNode* Expr, ExprDesc* D, int Sign)
CircularRefError (E); CircularRefError (E);
} else if (E->Expr == 0) { } else if (E->Expr == 0) {
/* Dummy export, must be an o65 imported symbol */ /* 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); CHECK (S != 0);
if (D->ExtRef) { if (D->ExtRef) {
/* We cannot have more than one external reference in o65 */ /* 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]; S = Seg [I];
/* Keep the user happy */ /* Keep the user happy */
Print (stdout, 1, " Writing `%s'\n", S->Name); Print (stdout, 1, " Writing `%s'\n", GetString (S->Name));
/* Write this segment */ /* Write this segment */
if (DoWrite) { 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 * export does really exist, so if it is unresolved, or if we don't
* find it, there is an error in the linker code. * find it, there is an error in the linker code.
*/ */
Export* E = FindExport (Name); Export* E = FindExport (GetStringId (Name));
if (E == 0 || IsUnresolvedExport (E)) { if (E == 0 || IsUnresolvedExport (E)) {
Internal ("Unresolved export `%s' found in O65WriteExports", Name); 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 /* Get the export for this symbol and check if it does exist and is
* a resolved symbol. * a resolved symbol.
*/ */
Export* E = FindExport (Ident); Export* E = FindExport (GetStringId (Ident));
if (E == 0 || IsUnresolvedExport (E)) { if (E == 0 || IsUnresolvedExport (E)) {
Error ("Unresolved export: `%s'", Ident); 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 */ /* Called if an unresolved symbol is encountered */
{ {
/* Check if the symbol is an imported o65 symbol */ /* 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... */ /* This is an external symbol, relax... */
return 1; return 1;
} else { } else {
@@ -1280,7 +1281,7 @@ void O65WriteTarget (O65Desc* D, File* F)
time_t T; time_t T;
/* Place the filename in the control structure */ /* 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 /* Check for unresolved symbols. The function O65Unresolved is called
* if we get an unresolved symbol. * if we get an unresolved symbol.
@@ -1299,13 +1300,13 @@ void O65WriteTarget (O65Desc* D, File* F)
O65SetupHeader (D); O65SetupHeader (D);
/* Open the file */ /* Open the file */
D->F = fopen (F->Name, "wb"); D->F = fopen (D->Filename, "wb");
if (D->F == 0) { 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 */ /* 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 */ /* Define some more options: A timestamp and the linker version */
T = time (0); T = time (0);
@@ -1352,7 +1353,7 @@ void O65WriteTarget (O65Desc* D, File* F)
/* Close the file */ /* Close the file */
if (fclose (D->F) != 0) { 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 */ /* Reset the file and filename */
@@ -1362,3 +1363,4 @@ void O65WriteTarget (O65Desc* D, File* F)

View File

@@ -43,6 +43,7 @@
#include "error.h" #include "error.h"
#include "fileinfo.h" #include "fileinfo.h"
#include "objdata.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 /* Get a string from the object file string table. Abort if the string index
* is invalid. * is invalid.
*/ */
{ {
if (Index >= O->StringCount) { if (Index >= O->StringCount) {
Error ("Invalid string index (%lu) in module `%s'", Error ("Invalid string index (%u) in module `%s'",
Index, GetObjFileName (O)); Index, GetObjFileName (O));
} }
return O->Strings[Index]; 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) const char* GetObjFileName (const ObjData* O)
/* Get the name of the object file. Return "[linker generated]" if the object /* Get the name of the object file. Return "[linker generated]" if the object
* file is NULL. * file is NULL.

View File

@@ -98,11 +98,19 @@ extern ObjData* ObjLast; /* Last entry in list */
ObjData* NewObjData (void); ObjData* NewObjData (void);
/* Allocate a new structure on the heap, insert it into the list, return it */ /* 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 /* Get a string from the object file string table. Abort if the string index
* is invalid. * 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); const char* GetObjFileName (const ObjData* O);
/* Get the name of the object file. Return "[linker generated]" if the object /* Get the name of the object file. Return "[linker generated]" if the object
* file is NULL. * file is NULL.

View File

@@ -255,6 +255,11 @@ void ObjAdd (FILE* Obj, const char* Name)
/* Done, close the file (we read it only, so no error check) */ /* Done, close the file (we read it only, so no error check) */
fclose (Obj); fclose (Obj);
/* All references to strings are now resolved, so we can delete the module
* string pool.
*/
FreeObjStrings (O);
} }

View File

@@ -39,6 +39,7 @@
/* common */ /* common */
#include "check.h" #include "check.h"
#include "exprdefs.h" #include "exprdefs.h"
#include "fragdefs.h"
#include "hashstr.h" #include "hashstr.h"
#include "print.h" #include "print.h"
#include "segdefs.h" #include "segdefs.h"
@@ -53,6 +54,7 @@
#include "global.h" #include "global.h"
#include "lineinfo.h" #include "lineinfo.h"
#include "segments.h" #include "segments.h"
#include "spool.h"
@@ -63,7 +65,8 @@
/* Hash table */ /* Hash table */
#define HASHTAB_SIZE 253 #define HASHTAB_MASK 0x3FU
#define HASHTAB_SIZE (HASHTAB_MASK + 1)
static Segment* HashTab [HASHTAB_SIZE]; static Segment* HashTab [HASHTAB_SIZE];
static unsigned SegCount = 0; /* Segment count */ 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) static Segment* NewSegment (unsigned Name, unsigned char Type)
/* 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)
/* Create a new segment and initialize it */ /* Create a new segment and initialize it */
{ {
/* Get the length of the symbol name */ unsigned Hash;
unsigned Len = strlen (Name);
/* Allocate memory */ /* Allocate memory */
Segment* S = xmalloc (sizeof (Segment) + Len); Segment* S = xmalloc (sizeof (Segment));
/* Initialize the fields */ /* Initialize the fields */
S->Name = Name;
S->Next = 0; S->Next = 0;
S->SecRoot = 0; S->SecRoot = 0;
S->SecLast = 0; S->SecLast = 0;
@@ -116,8 +100,6 @@ static Segment* NewSegment (const char* Name, unsigned HashVal, unsigned char Ty
S->FillVal = 0; S->FillVal = 0;
S->Type = Type; S->Type = Type;
S->Dumped = 0; S->Dumped = 0;
memcpy (S->Name, Name, Len);
S->Name [Len] = '\0';
/* Insert the segment into the segment list */ /* Insert the segment into the segment list */
S->List = SegRoot; S->List = SegRoot;
@@ -125,8 +107,9 @@ static Segment* NewSegment (const char* Name, unsigned HashVal, unsigned char Ty
++SegCount; ++SegCount;
/* Insert the segment into the segment hash list */ /* Insert the segment into the segment hash list */
S->Next = HashTab [HashVal]; Hash = (S->Name & HASHTAB_MASK);
HashTab [HashVal] = S; S->Next = HashTab[Hash];
HashTab[Hash] = S;
/* Return the new entry */ /* Return the new entry */
return S; 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 /* 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 * 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. * 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 */ /* Try to locate the segment in the table */
unsigned HashVal = HashStr (Name) % HASHTAB_SIZE; Segment* S = SegFind (Name);
Segment* S = SegFindInternal (Name, HashVal);
/* If we don't have that segment already, allocate it using the type of /* If we don't have that segment already, allocate it using the type of
* the first section. * the first section.
*/ */
if (S == 0) { if (S == 0) {
/* Create a new segment */ /* Create a new segment */
S = NewSegment (Name, HashVal, Type); S = NewSegment (Name, Type);
} else { } else {
/* Check if the existing segment has the requested type */ /* Check if the existing segment has the requested type */
if (S->Type != Type) { if (S->Type != Type) {
@@ -157,7 +139,8 @@ Segment* GetSegment (const char* Name, unsigned char Type, const char* ObjName)
if (ObjName == 0) { if (ObjName == 0) {
ObjName = "[linker generated]"; 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 */ /* Allocate memory */
Section* S = xmalloc (sizeof (Segment)); Section* S = xmalloc (sizeof (Section));
/* Initialize the data */ /* Initialize the data */
S->Next = 0; S->Next = 0;
@@ -211,7 +194,7 @@ Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type)
Section* ReadSection (FILE* F, ObjData* O) Section* ReadSection (FILE* F, ObjData* O)
/* Read a section from a file */ /* Read a section from a file */
{ {
char* Name; unsigned Name;
unsigned Size; unsigned Size;
unsigned char Align; unsigned char Align;
unsigned char Type; unsigned char Type;
@@ -221,7 +204,7 @@ Section* ReadSection (FILE* F, ObjData* O)
/* Read the segment data */ /* Read the segment data */
(void) Read32 (F); /* File size of 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 */ Size = Read32 (F); /* Size of data */
Align = Read8 (F); /* Alignment */ Align = Read8 (F); /* Alignment */
Type = Read8 (F); /* Segment type */ Type = Read8 (F); /* Segment type */
@@ -230,14 +213,11 @@ Section* ReadSection (FILE* F, ObjData* O)
/* Print some data */ /* Print some data */
Print (stdout, 2, "Module `%s': Found segment `%s', size = %u, align = %u, type = %u\n", Print (stdout, 2, "Module `%s': Found segment `%s', size = %u, align = %u, type = %u\n",
GetObjFileName (O), Name, Size, Align, Type); GetObjFileName (O), GetString (Name), Size, Align, Type);
/* Get the segment for this section */ /* Get the segment for this section */
S = GetSegment (Name, Type, GetObjFileName (O)); 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 */ /* Allocate the section we will return later */
Sec = NewSection (S, Align, Type); Sec = NewSection (S, Align, Type);
@@ -283,7 +263,7 @@ Section* ReadSection (FILE* F, ObjData* O)
default: default:
Error ("Unknown fragment type in module `%s', segment `%s': %02X", Error ("Unknown fragment type in module `%s', segment `%s': %02X",
GetObjFileName (O), S->Name, Type); GetObjFileName (O), GetString (S->Name), Type);
/* NOTREACHED */ /* NOTREACHED */
return 0; return 0;
} }
@@ -295,7 +275,6 @@ Section* ReadSection (FILE* F, ObjData* O)
unsigned Count = ReadVar (F); unsigned Count = ReadVar (F);
/* Read the expressions */ /* Read the expressions */
CheckExpr* Last = 0;
while (Count--) { 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 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; Segment* Seg = SegRoot;
while (Seg) { while (Seg) {
Section* S = Seg->SecRoot; 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) { while (S) {
Fragment* F = S->FragRoot; Fragment* F = S->FragRoot;
printf (" Section:\n"); printf (" Section:\n");
@@ -578,7 +566,7 @@ static int CmpSegStart (const void* K1, const void* K2)
return -1; return -1;
} else { } else {
/* Sort segments with equal starts by name */ /* 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; --End;
} }
fprintf (F, "%-20s %06lX %06lX %06lX\n", 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; Segment* S = SegRoot;
while (S) { while (S) {
if (S->Size > 0 && S->Dumped == 0) { 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; S = S->List;
} }

View File

@@ -54,6 +54,7 @@
/* Segment structure */ /* Segment structure */
typedef struct Segment Segment; typedef struct Segment Segment;
struct Segment { struct Segment {
unsigned Name; /* Name index of the segment */
Segment* Next; /* Hash list */ Segment* Next; /* Hash list */
Segment* List; /* List of all segments */ Segment* List; /* List of all segments */
struct Section* SecRoot; /* Section list */ struct Section* SecRoot; /* Section list */
@@ -65,7 +66,6 @@ struct Segment {
unsigned char FillVal; /* Value to use for fill bytes */ unsigned char FillVal; /* Value to use for fill bytes */
unsigned char Type; /* Type of segment */ unsigned char Type; /* Type of segment */
char Dumped; /* Did we dump this 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 /* 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 * 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. * 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); Section* ReadSection (FILE* F, struct ObjData* O);
/* Read a section from a file */ /* Read a section from a file */
Segment* SegFind (const char* Name); Segment* SegFind (unsigned Name);
/* Return the given segment or NULL if not found. */ /* Return the given segment or NULL if not found. */
int IsBSSType (Segment* S); int IsBSSType (Segment* S);

View 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>");
}

View File

@@ -49,6 +49,10 @@
/* An invalid message index */
#define INVALID_STRING_ID 0U
/* The string pool we're using */
extern StringPool StrPool; extern StringPool StrPool;
@@ -69,6 +73,19 @@ INLINE unsigned GetStringId (const char* S)
# define GetStringId(S) SP_Add (&StrPool, (S)) # define GetStringId(S) SP_Add (&StrPool, (S))
#endif #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 */ /* End of spool.h */