1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-02 04:41:35 +00:00

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 */
#include "check.h"
#include "fname.h"
#include "segdefs.h"
#include "fragdefs.h"
#include "version.h"
#include "xmalloc.h"

View File

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

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_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 {

View File

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

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -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)

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -71,13 +71,13 @@ typedef enum {
void ConDesAddExport (struct Export* E);
/* Add the given export to the list of constructors/destructor */
void ConDesSetSegName (unsigned Type, const char* SegName);
void ConDesSetSegName (unsigned Type, unsigned SegName);
/* Set the segment name where the table should go */
void ConDesSetLabel (unsigned Type, const char* Name);
void ConDesSetLabel (unsigned Type, unsigned Name);
/* Set the label for the given ConDes type */
void ConDesSetCountSym (unsigned Type, const char* Name);
void ConDesSetCountSym (unsigned Type, unsigned Name);
/* Set the name for the given ConDes count symbol */
void ConDesSetOrder (unsigned Type, ConDesOrder Order);
@ -103,4 +103,3 @@ void ConDesDump (void);

View File

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

View File

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

View File

@ -35,18 +35,19 @@
#include <string.h>
/* common */
/* common */
#include "check.h"
#include "symdefs.h"
#include "xmalloc.h"
/* ld65 */
#include "global.h"
#include "error.h"
#include "fileio.h"
#include "objdata.h"
#include "expr.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);
/* 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);

View File

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

View File

@ -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) {
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;
/* 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);
}

View File

@ -63,10 +63,8 @@ struct Import {
Import* Next; /* Single linked list */
ObjData* Obj; /* Object file that imports the name */
FilePos Pos; /* File position of reference */
union {
struct Export* Exp; /* Matching export for this import */
const char* Name; /* Name if not in table */
} V;
struct Export* Exp; /* Matching export for this import */
unsigned Name; /* Name if not in table */
unsigned char Type; /* Type of import */
};
@ -75,6 +73,7 @@ struct Import {
/* Export symbol structure */
typedef struct Export Export;
struct Export {
unsigned Name; /* Name */
Export* Next; /* Hash table link */
unsigned Flags; /* Generic flags */
ObjData* Obj; /* Object file that exports the name */
@ -84,7 +83,6 @@ struct Export {
ExprNode* Expr; /* Expression (0 if not def'd) */
unsigned char Type; /* Type of export */
unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */
const char* Name; /* Name */
};
@ -95,7 +93,7 @@ struct Export {
* resolved, or a value != zero if the symbol could be resolved. The
* CheckExports routine will print out the missing symbol in the first case.
*/
typedef int (*ExpCheckFunc) (const char* Name, void* Data);
typedef int (*ExpCheckFunc) (unsigned Name, void* Data);
@ -117,24 +115,24 @@ Export* ReadExport (FILE* F, ObjData* Obj);
void InsertExport (Export* E);
/* Insert an exported identifier and check if it's already in the list */
Export* CreateConstExport (const char* Name, long Value);
Export* CreateConstExport (unsigned Name, long Value);
/* Create an export for a literal date */
Export* CreateMemoryExport (const char* Name, Memory* Mem, unsigned long Offs);
Export* CreateMemoryExport (unsigned Name, Memory* Mem, unsigned long Offs);
/* Create an relative export for a memory area offset */
Export* CreateSegmentExport (const char* Name, Segment* Seg, unsigned long Offs);
Export* CreateSegmentExport (unsigned Name, Segment* Seg, unsigned long Offs);
/* Create a relative export to a segment */
Export* CreateSectionExport (const char* Name, Section* S, unsigned long Offs);
Export* CreateSectionExport (unsigned Name, Section* S, unsigned long Offs);
/* Create a relative export to a section */
Export* FindExport (const char* Name);
Export* FindExport (unsigned Name);
/* Check for an identifier in the list. Return 0 if not found, otherwise
* return a pointer to the export.
*/
int IsUnresolved (const char* Name);
int IsUnresolved (unsigned Name);
/* Check if this symbol is an unresolved export */
int IsUnresolvedExport (const Export* E);
@ -180,3 +178,4 @@ void CircularRefError (const Export* E);

View File

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

View File

@ -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 */
{

View File

@ -50,6 +50,7 @@
struct LineInfo;
struct ObjData;
struct Section;
@ -61,9 +62,9 @@ struct Section;
/* Fragment check expression */
typedef struct CheckExpr CheckExpr;
struct CheckExpr {
struct CheckExpr* Next; /* Next check expression */
typedef struct FragCheck FragCheck;
struct FragCheck {
struct FragCheck* Next; /* Next check expression */
struct ExprNode* Expr; /* The expression itself */
unsigned Action; /* Action to take if the check fails */
unsigned Message; /* Message number */
@ -76,9 +77,9 @@ struct Fragment {
struct ObjData* Obj; /* Source of fragment */
unsigned Size; /* Size of data/expression */
struct ExprNode* Expr; /* Expression if FRAG_EXPR */
FilePos Pos; /* File position in source */
FilePos Pos; /* File position in source */
struct LineInfo* LI; /* Additional line info */
CheckExpr* Check; /* Single linked list of expressions */
FragCheck* Check; /* Single linked list of checks */
unsigned char Type; /* Type of fragment */
unsigned char LitBuf [1]; /* Dynamically alloc'ed literal buffer */
};
@ -91,6 +92,9 @@ struct Fragment {
FragCheck* ReadFragCheck (FILE* F, Fragment* Frag);
/* Read a fragment check expression from the given file */
Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
/* Create a new fragment and insert it into the section S */

View File

@ -278,9 +278,13 @@ void LibAdd (FILE* F, const char* Name)
/* We have the data now */
O->Flags |= OBJ_HAVEDATA;
}
/* All references to strings are now resolved, so we can delete
* the module string pool.
*/
FreeObjStrings (O);
/* Add a pointer to the library name */
O->LibName = LibName;
}

View File

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

View File

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

View File

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

View File

@ -43,6 +43,7 @@
#include "error.h"
#include "fileinfo.h"
#include "objdata.h"
#include "spool.h"
@ -107,13 +108,27 @@ ObjData* NewObjData (void)
const char* GetObjString (const ObjData* O, unsigned long Index)
void FreeObjStrings (ObjData* O)
/* Free the module string data. Used once the object file is loaded completely
* when all strings are converted to global strings.
*/
{
while (O->StringCount) {
xfree (O->Strings[--O->StringCount]);
}
xfree (O->Strings);
O->Strings = 0;
}
const char* GetObjString (const ObjData* O, unsigned Index)
/* Get a string from the object file string table. Abort if the string index
* is invalid.
*/
{
if (Index >= O->StringCount) {
Error ("Invalid string index (%lu) in module `%s'",
Error ("Invalid string index (%u) in module `%s'",
Index, GetObjFileName (O));
}
return O->Strings[Index];
@ -121,6 +136,18 @@ const char* GetObjString (const ObjData* O, unsigned long Index)
unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
/* Convert a local string id into a global one and return it. */
{
if (Index >= O->StringCount) {
Error ("Invalid string index (%u) in module `%s'",
Index, GetObjFileName (O));
}
return GetStringId (O->Strings[Index]);
}
const char* GetObjFileName (const ObjData* O)
/* Get the name of the object file. Return "[linker generated]" if the object
* file is NULL.

View File

@ -98,11 +98,19 @@ extern ObjData* ObjLast; /* Last entry in list */
ObjData* NewObjData (void);
/* Allocate a new structure on the heap, insert it into the list, return it */
const char* GetObjString (const ObjData* O, unsigned long Index);
void FreeObjStrings (ObjData* O);
/* Free the module string data. Used once the object file is loaded completely
* when all strings are converted to global strings.
*/
const char* GetObjString (const ObjData* O, unsigned Index);
/* Get a string from the object file string table. Abort if the string index
* is invalid.
*/
unsigned MakeGlobalStringId (const ObjData* O, unsigned Index);
/* Convert a local string id into a global one and return it. */
const char* GetObjFileName (const ObjData* O);
/* Get the name of the object file. Return "[linker generated]" if the object
* file is NULL.

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) */
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 */
#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;
}

View File

@ -54,6 +54,7 @@
/* Segment structure */
typedef struct Segment Segment;
struct Segment {
unsigned Name; /* Name index of the segment */
Segment* Next; /* Hash list */
Segment* List; /* List of all segments */
struct Section* SecRoot; /* Section list */
@ -65,7 +66,6 @@ struct Segment {
unsigned char FillVal; /* Value to use for fill bytes */
unsigned char Type; /* Type of segment */
char Dumped; /* Did we dump this segment? */
char Name [1]; /* Name, dynamically allocated */
};
@ -108,7 +108,7 @@ typedef unsigned (*SegWriteFunc) (ExprNode* E, /* The expression to write
Segment* GetSegment (const char* Name, unsigned char Type, const char* ObjName);
Segment* GetSegment (unsigned Name, unsigned char Type, const char* ObjName);
/* Search for a segment and return an existing one. If the segment does not
* exist, create a new one and return that. ObjName is only used for the error
* message and may be NULL if the segment is linker generated.
@ -120,7 +120,7 @@ Section* NewSection (Segment* Seg, unsigned char Align, unsigned char Type);
Section* ReadSection (FILE* F, struct ObjData* O);
/* Read a section from a file */
Segment* SegFind (const char* Name);
Segment* SegFind (unsigned Name);
/* Return the given segment or NULL if not found. */
int IsBSSType (Segment* S);
@ -156,5 +156,5 @@ void CheckSegments (void);
#endif

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;
@ -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 */