From 76e67e2f971944cbca0f06642684ad1c45587e28 Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 25 May 2003 17:57:50 +0000 Subject: [PATCH] Changed the object file and library format. There is now an additional string table in the object file that (currently) holds all identifiers from the import, export and debug info sections. The plan is to put all strings into this table, so we have them in a central place and don't waste memory. Apart from that, the indices are unique, so comparing strings should be a lot easier than before (as soon as the programs take advantage of this fact, which is currently not the case). git-svn-id: svn://svn.cc65.org/cc65/trunk@2169 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ar65/exports.c | 15 ++- src/ar65/library.c | 62 ++++++----- src/ar65/objdata.c | 50 ++++++--- src/ar65/objdata.h | 29 +++-- src/ar65/objfile.c | 50 +++++++-- src/ca65/expr.c | 2 +- src/ca65/global.c | 11 +- src/ca65/global.h | 11 +- src/ca65/listing.c | 11 +- src/ca65/main.c | 18 +-- src/ca65/make/gcc.mak | 1 + src/ca65/make/watcom.mak | 1 + src/ca65/objcode.c | 1 - src/ca65/objfile.c | 46 +++++++- src/ca65/objfile.h | 14 ++- src/ca65/spool.c | 82 ++++++++++++++ src/ca65/spool.h | 83 ++++++++++++++ src/ca65/symtab.c | 7 +- src/common/coll.h | 4 +- src/common/libdefs.h | 16 +-- src/common/make/gcc.mak | 1 + src/common/objdefs.h | 18 +-- src/common/segdefs.h | 53 +++++---- src/common/strpool.c | 79 +++---------- src/common/strpool.h | 47 ++++---- src/ld65/dbgsyms.c | 12 +- src/ld65/dbgsyms.h | 10 +- src/ld65/exports.c | 23 ++-- src/ld65/exports.h | 12 +- src/ld65/expr.c | 4 +- src/ld65/fragment.c | 22 ++-- src/ld65/fragment.h | 8 +- src/ld65/library.c | 39 ++++--- src/ld65/objdata.c | 25 +++-- src/ld65/objdata.h | 14 ++- src/ld65/objfile.c | 28 ++++- src/ld65/objfile.h | 11 +- src/ld65/segments.c | 25 ++++- src/od65/dump.c | 234 ++++++++++++++++++++++++++------------- src/od65/fileio.c | 24 +++- src/od65/fileio.h | 12 +- 41 files changed, 809 insertions(+), 406 deletions(-) create mode 100644 src/ca65/spool.c create mode 100644 src/ca65/spool.h diff --git a/src/ar65/exports.c b/src/ar65/exports.c index 34d34227f..2019aedea 100644 --- a/src/ar65/exports.c +++ b/src/ar65/exports.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -38,7 +38,7 @@ /* common */ #include "hashstr.h" #include "xmalloc.h" - + /* ar65 */ #include "error.h" #include "objdata.h" @@ -53,8 +53,8 @@ /* A hash table entry */ -typedef struct HashEntry_ HashEntry; -struct HashEntry_ { +typedef struct HashEntry HashEntry; +struct HashEntry { HashEntry* Next; /* Next in list */ unsigned Module; /* Module index */ char Name [1]; /* Name of identifier */ @@ -149,4 +149,3 @@ int ExpFind (const char* Name) - diff --git a/src/ar65/library.c b/src/ar65/library.c index 1925d6818..cd4bfcadf 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -71,7 +71,8 @@ static const char* LibName = 0; static LibHeader Header = { LIB_MAGIC, LIB_VERSION, - 0, 0 + 0, + 0 }; @@ -106,6 +107,8 @@ static void ReadHeader (void) static void ReadIndexEntry (void) /* Read one entry in the index */ { + unsigned I; + /* Create a new entry and insert it into the list */ ObjData* O = NewObjData (); @@ -116,13 +119,20 @@ static void ReadIndexEntry (void) O->Start = Read32 (Lib); O->Size = Read32 (Lib); + /* Strings */ + O->StringCount = ReadVar (Lib); + O->Strings = xmalloc (O->StringCount * sizeof (char*)); + for (I = 0; I < O->StringCount; ++I) { + O->Strings[I] = ReadStr (Lib); + } + /* Exports */ - O->ExportSize = Read16 (Lib); + O->ExportSize = ReadVar (Lib); O->Exports = xmalloc (O->ExportSize); ReadData (Lib, O->Exports, O->ExportSize); /* Imports */ - O->ImportSize = Read16 (Lib); + O->ImportSize = ReadVar (Lib); O->Imports = xmalloc (O->ImportSize); ReadData (Lib, O->Imports, O->ImportSize); } @@ -138,7 +148,7 @@ static void ReadIndex (void) fseek (Lib, Header.IndexOffs, SEEK_SET); /* Read the object file count and calculate the cross ref size */ - Count = Read16 (Lib); + Count = ReadVar (Lib); /* Read all entries in the index */ while (Count--) { @@ -172,6 +182,8 @@ static void WriteHeader (void) static void WriteIndexEntry (ObjData* O) /* Write one index entry */ { + unsigned I; + /* Module name/flags/MTime/start/size */ WriteStr (NewLib, O->Name); Write16 (NewLib, O->Flags & ~OBJ_HAVEDATA); @@ -179,12 +191,18 @@ static void WriteIndexEntry (ObjData* O) Write32 (NewLib, O->Start); Write32 (NewLib, O->Size); + /* Strings */ + WriteVar (NewLib, O->StringCount); + for (I = 0; I < O->StringCount; ++I) { + WriteStr (NewLib, O->Strings[I]); + } + /* Exports */ - Write16 (NewLib, O->ExportSize); + WriteVar (NewLib, O->ExportSize); WriteData (NewLib, O->Exports, O->ExportSize); /* Imports */ - Write16 (NewLib, O->ImportSize); + WriteVar (NewLib, O->ImportSize); WriteData (NewLib, O->Imports, O->ImportSize); } @@ -202,7 +220,7 @@ static void WriteIndex (void) Header.IndexOffs = ftell (NewLib); /* Write the object file count */ - Write16 (NewLib, ObjCount); + WriteVar (NewLib, ObjCount); /* Write the object files */ O = ObjRoot; @@ -348,8 +366,8 @@ static void SkipExpr (unsigned char** Buf) return; case EXPR_SYMBOL: - /* 16 bit symbol index */ - *Buf += 2; + /* Variable seized symbol index */ + (void) GetVar (Buf); return; case EXPR_SECTION: @@ -359,8 +377,8 @@ static void SkipExpr (unsigned char** Buf) } /* What's left are unary and binary nodes */ - SkipExpr (Buf); /* Skip left */ - SkipExpr (Buf); /* Skip right */ + SkipExpr (Buf); /* Skip left */ + SkipExpr (Buf); /* Skip right */ } @@ -391,8 +409,7 @@ static void LibCheckExports (ObjData* O) while (Count--) { unsigned char Tag; - unsigned Len; - char* Name; + const char* Name; /* Get the export tag */ Tag = *Exports++; @@ -400,12 +417,8 @@ static void LibCheckExports (ObjData* O) /* condes decls may follow */ Exports += GET_EXP_CONDES_COUNT (Tag); - /* Next thing is name of symbol */ - Len = GetVar (&Exports); - Name = xmalloc (Len + 1); - memcpy (Name, Exports, Len); - Name [Len] = '\0'; - Exports += Len; + /* Next thing is index of name of symbol */ + Name = GetObjString (O, GetVar (&Exports)); /* Skip value of symbol */ if (Tag & EXP_EXPR) { @@ -422,9 +435,6 @@ static void LibCheckExports (ObjData* O) /* Insert the name into the hash table */ Print (stdout, 1, " %s\n", Name); ExpInsert (Name, O->Index); - - /* Free the name */ - xfree (Name); } } diff --git a/src/ar65/objdata.c b/src/ar65/objdata.c index 6b42f33a8..6d25bb850 100644 --- a/src/ar65/objdata.c +++ b/src/ar65/objdata.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -72,17 +72,19 @@ ObjData* NewObjData (void) ObjData* O = xmalloc (sizeof (ObjData)); /* Initialize the data */ - O->Next = 0; - O->Name = 0; - O->Index = ~0; - O->Flags = 0; - O->MTime = 0; - O->Start = 0; - O->Size = 0; - O->ImportSize = 0; - O->Imports = 0; - O->ExportSize = 0; - O->Exports = 0; + O->Next = 0; + O->Name = 0; + O->Index = ~0; + O->Flags = 0; + O->MTime = 0; + O->Start = 0; + O->Size = 0; + O->StringCount = 0; + O->Strings = 0; + O->ImportSize = 0; + O->Imports = 0; + O->ExportSize = 0; + O->Exports = 0; /* Link it into the list */ if (ObjLast) { @@ -105,9 +107,15 @@ ObjData* NewObjData (void) void FreeObjData (ObjData* O) /* Free a complete struct */ { + unsigned I; + xfree (O->Name); xfree (O->Imports); xfree (O->Exports); + for (I = 0; I < O->StringCount; ++I) { + xfree (O->Strings[I]); + } + xfree (O->Strings); xfree (O); } @@ -189,7 +197,7 @@ void MakeObjPool (void) /* Set the pool pointer */ ObjPool [Index] = O; - + /* Next object */ ++Index; O = O->Next; @@ -207,5 +215,15 @@ const char* GetObjName (unsigned Index) +const char* GetObjString (const ObjData* O, unsigned Index) +/* Get a string from the string pool of an object file */ +{ + if (Index >= O->StringCount) { + Error ("Invalid string index (%u) in module `%s'", + Index, GetObjName (O->Index)); + } + return O->Strings[Index]; +} + diff --git a/src/ar65/objdata.h b/src/ar65/objdata.h index 66acb7688..731040af4 100644 --- a/src/ar65/objdata.h +++ b/src/ar65/objdata.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998 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 */ @@ -50,19 +50,21 @@ /* Internal structure holding object file data */ -typedef struct ObjData_ ObjData; -struct ObjData_ { - ObjData* Next; /* Linked list of all objects */ - char* Name; /* Module name */ - unsigned Index; /* Module index */ - unsigned Flags; +typedef struct ObjData ObjData; +struct ObjData { + ObjData* Next; /* Linked list of all objects */ + char* Name; /* Module name */ + unsigned Index; /* Module index */ + unsigned Flags; unsigned long MTime; /* Modifiation time of object file */ unsigned long Start; /* Start offset of data in library */ unsigned long Size; /* Size of data in library */ + unsigned StringCount; /* Number of strings */ + char** Strings; /* Strings from the object file */ unsigned long ImportSize; /* Size of imports */ - void* Imports; /* Imports as raw data */ + void* Imports; /* Imports as raw data */ unsigned long ExportSize; /* Size of exports */ - void* Exports; /* Exports as raw data */ + void* Exports; /* Exports as raw data */ }; @@ -101,6 +103,9 @@ void MakeObjPool (void); const char* GetObjName (unsigned Index); /* Get the name of a module by index */ +const char* GetObjString (const ObjData* O, unsigned Index); +/* Get a string from the string pool of an object file */ + /* End of objdata.h */ diff --git a/src/ar65/objfile.c b/src/ar65/objfile.c index 28d133201..a7675e7d0 100644 --- a/src/ar65/objfile.c +++ b/src/ar65/objfile.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (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 */ @@ -47,7 +47,7 @@ /* common */ #include "xmalloc.h" - + /* ar65 */ #include "error.h" #include "objdata.h" @@ -109,6 +109,8 @@ void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) H->DbgSymSize = Read32 (Obj); H->LineInfoOffs = Read32 (Obj); H->LineInfoSize = Read32 (Obj); + H->StrPoolOffs = Read32 (Obj); + H->StrPoolSize = Read32 (Obj); } @@ -133,6 +135,8 @@ void ObjWriteHeader (FILE* Obj, ObjHeader* H) Write32 (Obj, H->DbgSymSize); Write32 (Obj, H->LineInfoOffs); Write32 (Obj, H->LineInfoSize); + Write32 (Obj, H->StrPoolOffs); + Write32 (Obj, H->StrPoolSize); } @@ -144,6 +148,7 @@ void ObjAdd (const char* Name) const char* Module; ObjHeader H; ObjData* O; + unsigned I; /* Open the object file */ FILE* Obj = fopen (Name, "rb"); @@ -191,6 +196,14 @@ void ObjAdd (const char* Name) fseek (Obj, H.ExportOffs, SEEK_SET); ReadData (Obj, O->Exports, O->ExportSize); + /* Read the string pool */ + fseek (Obj, H.StrPoolOffs, SEEK_SET); + O->StringCount = ReadVar (Obj); + O->Strings = xmalloc (O->StringCount * sizeof (char*)); + for (I = 0; I < O->StringCount; ++I) { + O->Strings[I] = ReadStr (Obj); + } + /* Skip the object file header */ O->Start = ftell (NewLib); fseek (NewLib, OBJ_HDR_SIZE, SEEK_CUR); @@ -211,8 +224,9 @@ void ObjAdd (const char* Name) O->Size = ftell (NewLib) - O->Start; /* Clear the remaining header fields */ - H.ImportOffs = H.ImportSize = 0; - H.ExportOffs = H.ExportSize = 0; + H.ImportOffs = H.ImportSize = 0; + H.ExportOffs = H.ExportSize = 0; + H.StrPoolOffs = H.StrPoolSize = 0; /* Seek back and write the updated header */ fseek (NewLib, O->Start, SEEK_SET); @@ -232,10 +246,12 @@ void ObjExtract (const char* Name) { unsigned long ImportStart; unsigned long ExportStart; + unsigned long StrPoolStart; + unsigned long StrPoolSize; struct utimbuf U; ObjHeader H; FILE* Obj; - + unsigned I; /* Make a module name from the file name */ const char* Module = GetModule (Name); @@ -263,15 +279,25 @@ void ObjExtract (const char* Name) ExportStart = ftell (Obj); WriteData (Obj, O->Exports, O->ExportSize); + /* Write the string pool */ + StrPoolStart = ftell (Obj); + WriteVar (Obj, O->StringCount); + for (I = 0; I < O->StringCount; ++I) { + WriteStr (Obj, O->Strings[I]); + } + StrPoolSize = ftell (Obj) - StrPoolStart; + /* Seek back and read the header */ fseek (Obj, 0, SEEK_SET); ObjReadHeader (Obj, &H, Name); /* Update the header fields */ - H.ImportOffs = ImportStart; - H.ImportSize = O->ImportSize; - H.ExportOffs = ExportStart; - H.ExportSize = O->ExportSize; + H.ImportOffs = ImportStart; + H.ImportSize = O->ImportSize; + H.ExportOffs = ExportStart; + H.ExportSize = O->ExportSize; + H.StrPoolOffs = StrPoolStart; + H.StrPoolSize = StrPoolSize; /* Write the changed header */ fseek (Obj, 0, SEEK_SET); diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 0c638c642..42c90d154 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -1603,7 +1603,7 @@ void WriteExpr (ExprNode* Expr) case EXPR_SYMBOL: /* Maybe we should use a code here? */ CHECK (SymIsImport (Expr->V.Sym)); /* Safety */ - ObjWrite16 (GetSymIndex (Expr->V.Sym)); + ObjWriteVar (GetSymIndex (Expr->V.Sym)); break; case EXPR_SECTION: diff --git a/src/ca65/global.c b/src/ca65/global.c index 6adc46d4c..051845ac5 100644 --- a/src/ca65/global.c +++ b/src/ca65/global.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2002 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 */ @@ -71,5 +71,8 @@ unsigned char DollarInIdents = 0; /* Allow '$' in identifiers */ unsigned char LeadingDotInIdents = 0; /* Allow '.' to start an identifier */ unsigned char PCAssignment = 0; /* Allow "* = $XXX" or "$ = $XXX" */ +/* Misc stuff */ +const char Copyright[] = "(C) Copyright 1998-2003 Ullrich von Bassewitz"; + diff --git a/src/ca65/global.h b/src/ca65/global.h index 0e21814df..24a41c03b 100644 --- a/src/ca65/global.h +++ b/src/ca65/global.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2002 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 */ @@ -72,6 +72,9 @@ extern unsigned char DollarInIdents; /* Allow '$' in identifiers */ extern unsigned char LeadingDotInIdents; /* Allow '.' to start an identifier */ extern unsigned char PCAssignment; /* Allow "* = $XXX" or "$ = $XXX" */ +/* Misc stuff */ +extern const char Copyright[]; /* Copyright string */ + /* End of global.h */ diff --git a/src/ca65/listing.c b/src/ca65/listing.c index df256c5a8..f7e777bcc 100644 --- a/src/ca65/listing.c +++ b/src/ca65/listing.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2000-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -221,11 +221,12 @@ static void PrintPageHeader (FILE* F, const ListLine* L) { /* Print the header on the new page */ fprintf (F, - "ca65 V%u.%u.%u - (C) Copyright 1998-2000 Ullrich von Bassewitz\n" + "ca65 V%u.%u.%u - %s\n" "Main file : %s\n" "Current file: %s\n" "\n", VER_MAJOR, VER_MINOR, VER_PATCH, + Copyright, InFile, GetFileName (L->File)); diff --git a/src/ca65/main.c b/src/ca65/main.c index e7738d153..f3ae99809 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2002 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 */ @@ -65,6 +65,7 @@ #include "options.h" #include "pseudo.h" #include "scanner.h" +#include "spool.h" #include "symtab.h" #include "ulabel.h" @@ -320,8 +321,8 @@ static void OptVersion (const char* Opt attribute ((unused)), /* Print the assembler version */ { fprintf (stderr, - "ca65 V%u.%u.%u - (C) Copyright 1998-2000 Ullrich von Bassewitz\n", - VER_MAJOR, VER_MINOR, VER_PATCH); + "ca65 V%u.%u.%u - %s\n", + VER_MAJOR, VER_MINOR, VER_PATCH, Copyright); } @@ -480,6 +481,9 @@ static void CreateObjFile (void) /* Write line infos if requested */ WriteLineInfo (); + /* Write the string pool */ + WriteStrPool (); + /* Write an updated header and close the file */ ObjClose (); } @@ -610,7 +614,7 @@ int main (int argc, char* argv []) } /* If no CPU given, use the default CPU for the target */ - if (GetCPU () == CPU_UNKNOWN) { + if (GetCPU () == CPU_UNKNOWN) { if (Target != TGT_UNKNOWN) { SetCPU (DefaultCPU[Target]); } else { diff --git a/src/ca65/make/gcc.mak b/src/ca65/make/gcc.mak index 2a0df89ef..dc0502be6 100644 --- a/src/ca65/make/gcc.mak +++ b/src/ca65/make/gcc.mak @@ -34,6 +34,7 @@ OBJS = condasm.o \ pseudo.o \ repeat.o \ scanner.o \ + spool.o \ symtab.o \ toklist.o \ ulabel.o diff --git a/src/ca65/make/watcom.mak b/src/ca65/make/watcom.mak index 5161a78d7..3e9bec5b0 100644 --- a/src/ca65/make/watcom.mak +++ b/src/ca65/make/watcom.mak @@ -67,6 +67,7 @@ OBJS = condasm.obj \ pseudo.obj \ repeat.obj \ scanner.obj \ + spool.obj \ symtab.obj \ toklist.obj \ ulabel.obj diff --git a/src/ca65/objcode.c b/src/ca65/objcode.c index f0842d5f3..175c0acc4 100644 --- a/src/ca65/objcode.c +++ b/src/ca65/objcode.c @@ -578,7 +578,6 @@ static Fragment* NewFragment (unsigned char Type, unsigned short Len) void Emit0 (unsigned char OPC) /* Emit an instruction with a zero sized operand */ { - /* First fragment, wrong type or out of space, create new one */ Fragment* F = NewFragment (FRAG_LITERAL, 1); F->V.Data [0] = OPC; } diff --git a/src/ca65/objfile.c b/src/ca65/objfile.c index c8859f5fc..020096fd5 100644 --- a/src/ca65/objfile.c +++ b/src/ca65/objfile.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -63,9 +63,25 @@ static FILE* F = 0; /* Header structure */ static ObjHeader Header = { - OBJ_MAGIC, - OBJ_VERSION, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + OBJ_MAGIC, /* 32: Magic number */ + OBJ_VERSION, /* 16: Version number */ + 0, /* 16: flags */ + 0, /* 32: Offset to option table */ + 0, /* 32: Size of options */ + 0, /* 32: Offset to file table */ + 0, /* 32: Size of files */ + 0, /* 32: Offset to segment table */ + 0, /* 32: Size of segment table */ + 0, /* 32: Offset to import list */ + 0, /* 32: Size of import list */ + 0, /* 32: Offset to export list */ + 0, /* 32: Size of export list */ + 0, /* 32: Offset to list of debug symbols */ + 0, /* 32: Size of debug symbols */ + 0, /* 32: Offset to list of line infos */ + 0, /* 32: Size of line infos */ + 0, /* 32: Offset to string pool */ + 0 /* 32: Size of string pool */ }; @@ -116,6 +132,8 @@ static void ObjWriteHeader (void) ObjWrite32 (Header.DbgSymSize); ObjWrite32 (Header.LineInfoOffs); ObjWrite32 (Header.LineInfoSize); + ObjWrite32 (Header.StrPoolOffs); + ObjWrite32 (Header.StrPoolSize); } @@ -386,3 +404,19 @@ void ObjEndLineInfos (void) +void ObjStartStrPool (void) +/* Mark the start of the string pool section */ +{ + Header.StrPoolOffs = ftell (F); +} + + + +void ObjEndStrPool (void) +/* Mark the end of the string pool section */ +{ + Header.StrPoolSize = ftell (F) - Header.StrPoolOffs; +} + + + diff --git a/src/ca65/objfile.h b/src/ca65/objfile.h index 07ba44c4a..4268907c8 100644 --- a/src/ca65/objfile.h +++ b/src/ca65/objfile.h @@ -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 */ /* */ /* */ @@ -121,10 +121,16 @@ void ObjStartLineInfos (void); void ObjEndLineInfos (void); /* Mark the end of the line info section */ +void ObjStartStrPool (void); +/* Mark the start of the string pool section */ + +void ObjEndStrPool (void); +/* Mark the end of the string pool section */ -/* End of objfile.h */ +/* End of objfile.h */ + #endif diff --git a/src/ca65/spool.c b/src/ca65/spool.c new file mode 100644 index 000000000..f33e0583a --- /dev/null +++ b/src/ca65/spool.c @@ -0,0 +1,82 @@ +/*****************************************************************************/ +/* */ +/* spool.c */ +/* */ +/* Id and message pool for the ca65 macroassembler */ +/* */ +/* */ +/* */ +/* (C) 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. */ +/* */ +/*****************************************************************************/ + + + +/* ca65 */ +#include "objfile.h" +#include "spool.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +StringPool StrPool = STATIC_STRINGPOOL_INITIALIZER; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +void WriteStrPool (void) +/* Write the string pool to the object file */ +{ + unsigned I; + + /* Get the number of strings in the string pool */ + unsigned Count = SP_GetCount (&StrPool); + + /* Tell the object file module that we're about to start the string pool */ + ObjStartStrPool (); + + /* Write the string count to the list */ + ObjWriteVar (Count); + + /* Write the strings in id order */ + for (I = 0; I < Count; ++I) { + ObjWriteStr (SP_Get (&StrPool, I)); + } + + /* Done writing the string pool */ + ObjEndStrPool (); +} + + + diff --git a/src/ca65/spool.h b/src/ca65/spool.h new file mode 100644 index 000000000..6cf9d18e4 --- /dev/null +++ b/src/ca65/spool.h @@ -0,0 +1,83 @@ +/*****************************************************************************/ +/* */ +/* spool.h */ +/* */ +/* Id and message pool for the ca65 macroassembler */ +/* */ +/* */ +/* */ +/* (C) 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 SPOOL_H +#define SPOOL_H + + + +/* common */ +#include "strpool.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +extern StringPool StrPool; + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +#if defined(HAVE_INLINE) +INLINE unsigned GetStringId (const char* S) +/* Return the id of the given string */ +{ + return SP_Add (&StrPool, S); +} +#else +# define GetStringId(S) SP_Add (&StrPool, (S)) +#endif + +void WriteStrPool (void); +/* Write the string pool to the object file */ + + + +/* End of spool.h */ + +#endif + + + + diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index bd275c0d6..a89113d2b 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -48,6 +48,7 @@ #include "expr.h" #include "objfile.h" #include "scanner.h" +#include "spool.h" #include "symtab.h" @@ -1137,7 +1138,7 @@ void WriteImports (void) } else { ObjWrite8 (IMP_ABS); } - ObjWriteStr (S->Name); + ObjWriteVar (GetStringId (S->Name)); ObjWritePos (&S->Pos); } S = S->List; @@ -1214,7 +1215,7 @@ void WriteExports (void) } /* Write the name */ - ObjWriteStr (S->Name); + ObjWriteVar (GetStringId (S->Name)); /* Write the value */ if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) { @@ -1278,7 +1279,7 @@ void WriteDbgSyms (void) ObjWrite8 (ExprMask); /* Write the name */ - ObjWriteStr (S->Name); + ObjWriteVar (GetStringId (S->Name)); /* Write the value */ if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) { diff --git a/src/common/coll.h b/src/common/coll.h index 470c54235..a2e8ff7a8 100644 --- a/src/common/coll.h +++ b/src/common/coll.h @@ -66,7 +66,7 @@ extern const Collection EmptyCollection; #define STATIC_COLLECTION_INITIALIZER { 0, 0, 0 } /* Initializer for auto collections */ -#define AUTO_COLLECTION_INITIALIZER EmptyCollection; +#define AUTO_COLLECTION_INITIALIZER EmptyCollection @@ -285,4 +285,4 @@ void CollSort (Collection* C, - + diff --git a/src/common/libdefs.h b/src/common/libdefs.h index 2c02a6fdb..3b2157425 100644 --- a/src/common/libdefs.h +++ b/src/common/libdefs.h @@ -1,15 +1,15 @@ /*****************************************************************************/ /* */ -/* libdefs.h */ +/* libdefs.h */ /* */ /* Library file definitions */ /* */ /* */ /* */ -/* (C) 1998 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 */ @@ -46,7 +46,7 @@ /* Defines for magic and version */ #define LIB_MAGIC 0x7A55616E -#define LIB_VERSION 0x0009 +#define LIB_VERSION 0x000A /* Size of an library file header */ #define LIB_HDR_SIZE 12 @@ -54,8 +54,8 @@ /* Header structure for the library */ -typedef struct LibHeader_ LibHeader; -struct LibHeader_ { +typedef struct LibHeader LibHeader; +struct LibHeader { unsigned long Magic; /* 32: Magic number */ unsigned Version; /* 16: Version number */ unsigned Flags; /* 16: flags */ diff --git a/src/common/make/gcc.mak b/src/common/make/gcc.mak index 732c7c95b..3d24b788b 100644 --- a/src/common/make/gcc.mak +++ b/src/common/make/gcc.mak @@ -26,6 +26,7 @@ OBJS = abend.o \ segdefs.o \ segnames.o \ strbuf.o \ + strpool.o \ strutil.o \ target.o \ tgttrans.o \ diff --git a/src/common/objdefs.h b/src/common/objdefs.h index c173ba651..aae965362 100644 --- a/src/common/objdefs.h +++ b/src/common/objdefs.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998 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 */ @@ -46,10 +46,10 @@ /* Defines for magic and version */ #define OBJ_MAGIC 0x616E7A55 -#define OBJ_VERSION 0x0009 +#define OBJ_VERSION 0x000A /* Size of an object file header */ -#define OBJ_HDR_SIZE 64 +#define OBJ_HDR_SIZE 72 /* Flag bits */ #define OBJ_FLAGS_DBGINFO 0x0001 /* File has debug info */ @@ -57,8 +57,8 @@ /* Header structure */ -typedef struct ObjHeader_ ObjHeader; -struct ObjHeader_ { +typedef struct ObjHeader ObjHeader; +struct ObjHeader { unsigned long Magic; /* 32: Magic number */ unsigned Version; /* 16: Version number */ unsigned Flags; /* 16: flags */ @@ -76,6 +76,8 @@ struct ObjHeader_ { unsigned long DbgSymSize; /* 32: Size of debug symbols */ unsigned long LineInfoOffs; /* 32: Offset to list of line infos */ unsigned long LineInfoSize; /* 32: Size of line infos */ + unsigned long StrPoolOffs; /* 32: Offset to string pool */ + unsigned long StrPoolSize; /* 32: Size of string pool */ }; diff --git a/src/common/segdefs.h b/src/common/segdefs.h index c983db22c..d20826ddb 100644 --- a/src/common/segdefs.h +++ b/src/common/segdefs.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2002 Ullrich von Bassewitz */ +/* (C) 1998-2003 Ullrich von Bassewitz */ /* Römerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -45,30 +45,37 @@ /* Available segment types */ -#define SEGTYPE_DEFAULT 0 -#define SEGTYPE_ABS 1 -#define SEGTYPE_ZP 2 -#define SEGTYPE_FAR 3 +#define SEGTYPE_DEFAULT 0 +#define SEGTYPE_ABS 1 +#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_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 */ +#define FRAG_TYPEMASK 0x38 /* Mask the type of the fragment */ +#define FRAG_BYTEMASK 0x07 /* Mask for byte count */ +#define FRAG_CHECKMASK 0xC0 /* Mask for check type */ + +/* 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_NONE 0x00 /* No checks applied */ +#define FRAG_CHECK_WARN 0x40 /* Check and warn */ +#define FRAG_CHECK_ERROR 0x80 /* Check and abort */ diff --git a/src/common/strpool.c b/src/common/strpool.c index b6411865f..6416c24a7 100644 --- a/src/common/strpool.c +++ b/src/common/strpool.c @@ -60,8 +60,8 @@ /* A string pool entry */ -struct StrPoolEntry { - StrPoolEntry* Next; /* Pointer to next entry in hash chain */ +struct StringPoolEntry { + StringPoolEntry* Next; /* Pointer to next entry in hash chain */ unsigned Hash; /* Full hash value */ unsigned Id; /* The numeric string id */ unsigned Len; /* Length of the string (excluding terminator) */ @@ -71,19 +71,19 @@ struct StrPoolEntry { /*****************************************************************************/ -/* struct StrPoolEntry */ +/* struct StringPoolEntry */ /*****************************************************************************/ -static StrPoolEntry* NewStrPoolEntry (const char* S, unsigned Hash, unsigned Id) +static StringPoolEntry* NewStringPoolEntry (const char* S, unsigned Hash, unsigned Id) /* Create a new string pool entry and return it. */ { /* Get the length of the string */ unsigned Len = strlen (S); /* Allocate memory */ - StrPoolEntry* E = xmalloc (sizeof (StrPoolEntry) + Len); + StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry) + Len); /* Initialize the fields */ E->Next = 0; @@ -104,7 +104,7 @@ static StrPoolEntry* NewStrPoolEntry (const char* S, unsigned Hash, unsigned Id) -StrPool* InitStrPool (StrPool* P) +StringPool* InitStringPool (StringPool* P) /* Initialize a string pool */ { unsigned I; @@ -122,7 +122,7 @@ StrPool* InitStrPool (StrPool* P) -void DoneStrPool (StrPool* P) +void DoneStringPool (StringPool* P) /* Free the data of a string pool (but not the data itself) */ { unsigned I; @@ -144,20 +144,20 @@ void DoneStrPool (StrPool* P) -StrPool* NewStrPool (void) +StringPool* NewStringPool (void) /* Allocate, initialize and return a new string pool */ { /* Allocate memory, initialize and return it */ - return InitStrPool (xmalloc (sizeof (StrPool))); + return InitStringPool (xmalloc (sizeof (StringPool))); } -void FreeStrPool (StrPool* P) +void FreeStringPool (StringPool* P) /* Free a string pool */ { /* Free all entries */ - DoneStrPool (P); + DoneStringPool (P); /* Free the string pool itself */ xfree (P); @@ -165,11 +165,11 @@ void FreeStrPool (StrPool* P) -const char* SP_Get (const StrPool* P, unsigned Index) +const char* SP_Get (const StringPool* P, unsigned Index) /* Return a string from the pool. Index must exist, otherwise FAIL is called. */ { /* Get the collection entry */ - const StrPoolEntry* E = CollConstAt (&P->Entries, Index); + const StringPoolEntry* E = CollConstAt (&P->Entries, Index); /* Return the string from the entry */ return E->S; @@ -177,7 +177,7 @@ const char* SP_Get (const StrPool* P, unsigned Index) -unsigned SP_Add (StrPool* P, const char* S) +unsigned SP_Add (StringPool* P, const char* S) /* Add a string to the buffer and return the index. If the string does already * exist in the pool, SP_Add will just return the index of the existing string. */ @@ -189,7 +189,7 @@ unsigned SP_Add (StrPool* P, const char* S) unsigned RHash = Hash % (sizeof (P->Tab)/sizeof (P->Tab[0])); /* Search for an existing entry */ - StrPoolEntry* E = P->Tab[RHash]; + StringPoolEntry* E = P->Tab[RHash]; while (E) { if (E->Hash == Hash && strcmp (E->S, S) == 0) { /* Found, return the id of the existing string */ @@ -199,7 +199,7 @@ unsigned SP_Add (StrPool* P, const char* S) } /* We didn't find the entry, so create a new one */ - E = NewStrPoolEntry (S, Hash, CollCount (&P->Entries)); + E = NewStringPoolEntry (S, Hash, CollCount (&P->Entries)); /* Insert the new entry into the entry collection */ CollAppend (&P->Entries, E); @@ -217,50 +217,3 @@ unsigned SP_Add (StrPool* P, const char* S) -unsigned SP_AddBuf (StrPool* P, const void* Buffer, unsigned Size) -/* Add strings from a string buffer. Buffer must contain a list of zero - * terminated strings. These strings are added to the pool, starting with - * the current index. The number of strings added is returned. - * Beware: The function will do only loose range checking for the buffer - * limits, so a SEGV may occur if the last string in the buffer is not - * correctly terminated. - */ -{ - /* Cast the buffer pointer to something useful */ - const char* Buf = Buffer; - - /* Remember the current number of strings in the buffer. */ - unsigned OldCount = SB_GetCount (P); - - /* Add all strings from the buffer */ - while (Size) { - - /* Add the next entry */ - unsigned Id = SP_Add (P, Buf); - - /* Get the entry from the id */ - const StrPoolEntry* E = CollConstAt (&P->Entries, Id); - - /* Skip this string */ - Buf += E->Len + 1; - Size -= E->Len + 1; - } - - /* Return the number of strings added */ - return SB_GetCount (P) - OldCount; -} - - - -void SP_Build (StrPool* P, const void* Buffer, unsigned Size) -/* Delete existing data and use the data from Buffer instead. */ -{ - /* Delete old data */ - DoneStrPool (P); - - /* Add the buffer data */ - SP_AddBuf (P, Buffer, Size); -} - - - diff --git a/src/common/strpool.h b/src/common/strpool.h index 6a93bd8b0..eec1e8714 100644 --- a/src/common/strpool.h +++ b/src/common/strpool.h @@ -60,16 +60,26 @@ -/* Opaque entry */ -typedef struct StrPoolEntry StrPoolEntry; - -typedef struct StrPool StrPool; -struct StrPool { - StrPoolEntry* Tab[211]; /* Entry hash table */ - Collection Entries; /* Entries sorted by number */ - unsigned TotalSize; /* Total size of all string data */ +/* Opaque string pool entry */ +typedef struct StringPoolEntry StringPoolEntry; + +/* A string pool */ +typedef struct StringPool StringPool; +struct StringPool { + Collection Entries; /* Entries sorted by number */ + unsigned TotalSize; /* Total size of all string data */ + StringPoolEntry* Tab[211]; /* Entry hash table */ }; +/* A string pool initializer. We do only initialize the first field, all + * others will get zeroed out by the compiler. + */ +#define STATIC_STRINGPOOL_INITIALIZER { \ + STATIC_COLLECTION_INITIALIZER, \ + 0, \ + { 0 } \ +} + /*****************************************************************************/ @@ -78,39 +88,34 @@ struct StrPool { -StrPool* InitStrPool (StrPool* P); +StringPool* InitStringPool (StringPool* P); /* Initialize a string pool */ -void DoneStrPool (StrPool* P); +void DoneStringPool (StringPool* P); /* Free the data of a string pool (but not the data itself) */ -StrPool* NewStrPool (void); +StringPool* NewStringPool (void); /* Allocate, initialize and return a new string pool */ -void FreeStrPool (StrPool* P); +void FreeStringPool (StringPool* P); /* Free a string pool */ -void SP_Use (char* Buffer, unsigned Size); -/* Delete existing data and use the data from Buffer instead. Buffer must be - * allocated on the heap and will be freed using xfree() if necessary. - */ - -const char* SP_Get (const StrPool* P, unsigned Index); +const char* SP_Get (const StringPool* P, unsigned Index); /* Return a string from the pool. Index must exist, otherwise FAIL is called. */ -unsigned SP_Add (StrPool* P, const char* S); +unsigned SP_Add (StringPool* P, const char* S); /* Add a string to the buffer and return the index. If the string does already * exist in the pool, SP_Add will just return the index of the existing string. */ #if defined(HAVE_INLINE) -INLINE unsigned SB_GetCount (const StrPool* P) +INLINE unsigned SP_GetCount (const StringPool* P) /* Return the number of strings in the pool */ { return CollCount (&P->Entries); } #else -# define SB_GetCount(P) CollCount (&(P)->Entries) +# define SP_GetCount(P) CollCount (&(P)->Entries) #endif diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index e728c2907..9e70eda2c 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -80,8 +80,8 @@ static DbgSym* NewDbgSym (unsigned char Type, ObjData* O) D->Flags = 0; D->Obj = O; D->Expr = 0; - D->Type = Type; D->Name = 0; + D->Type = Type; /* Return the new entry */ return D; @@ -148,7 +148,7 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O) D = NewDbgSym (Type, O); /* Read and assign the name */ - D->Name = ReadStr (F); + D->Name = GetObjString (O, ReadVar (F)); /* Read the value */ if (IS_EXP_EXPR (Type)) { diff --git a/src/ld65/dbgsyms.h b/src/ld65/dbgsyms.h index 6964ca1ba..3b2518a43 100644 --- a/src/ld65/dbgsyms.h +++ b/src/ld65/dbgsyms.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998 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 */ @@ -63,8 +63,8 @@ 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 char Type; /* Type of symbol */ - char* Name; /* Name - dynamically allocated */ }; diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 1978f22a6..55ec1fdb4 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998 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 */ @@ -114,7 +114,7 @@ void InsertImport (Import* I) unsigned HashVal; /* As long as the import is not inserted, V.Name is valid */ - char* Name = I->V.Name; + const char* Name = I->V.Name; /* Create a hash value for the given name */ HashVal = HashStr (Name) % HASHTAB_SIZE; @@ -134,8 +134,8 @@ void InsertImport (Import* I) if (E->Next == 0) { /* End of list an entry not found, insert a dummy */ E->Next = NewExport (0, Name, 0); - E = E->Next; /* Point to dummy */ - ++ExpCount; /* One export more */ + E = E->Next; /* Point to dummy */ + ++ExpCount; /* One export more */ break; } else { E = E->Next; @@ -150,14 +150,11 @@ void InsertImport (Import* I) I->Next = E->ImpList; E->ImpList = I; E->ImpCount++; - ++ImpCount; /* Total import count */ + ++ImpCount; /* Total import count */ if (E->Expr == 0) { /* This is a dummy export */ ++ImpOpen; } - - /* Now free the name since it's no longer needed */ - xfree (Name); } @@ -178,7 +175,7 @@ Import* ReadImport (FILE* F, ObjData* Obj) I = NewImport (Type, Obj); /* Read the name */ - I->V.Name = ReadStr (F); + I->V.Name = GetObjString (Obj, ReadVar (F)); /* Read the file position */ ReadFilePos (F, &I->Pos); @@ -328,7 +325,7 @@ Export* ReadExport (FILE* F, ObjData* O) } /* Read the name */ - E->Name = ReadStr (F); + E->Name = GetObjString (O, ReadVar (F)); /* Read the value */ if (IS_EXP_EXPR (Type)) { diff --git a/src/ld65/exports.h b/src/ld65/exports.h index 4a2c8751d..06cb763dd 100644 --- a/src/ld65/exports.h +++ b/src/ld65/exports.h @@ -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 */ @@ -65,7 +65,7 @@ struct Import { FilePos Pos; /* File position of reference */ union { struct Export* Exp; /* Matching export for this import */ - char* Name; /* Name if not in table */ + const char* Name; /* Name if not in table */ } V; unsigned char Type; /* Type of import */ }; @@ -84,7 +84,7 @@ 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 */ - char* Name; /* Name - dynamically allocated */ + const char* Name; /* Name */ }; diff --git a/src/ld65/expr.c b/src/ld65/expr.c index a59e1f2be..039e9efae 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -468,7 +468,7 @@ ExprNode* ReadExpr (FILE* F, ObjData* O) case EXPR_SYMBOL: /* Read the import number */ - Expr->V.ImpNum = Read16 (F); + Expr->V.ImpNum = ReadVar (F); break; case EXPR_SECTION: @@ -485,7 +485,7 @@ ExprNode* ReadExpr (FILE* F, ObjData* O) /* Not a leaf node */ Expr->Left = ReadExpr (F, O); - Expr->Right = ReadExpr (F, O); + Expr->Right = ReadExpr (F, O); } diff --git a/src/ld65/fragment.c b/src/ld65/fragment.c index 0051a26d5..cd4ae6028 100644 --- a/src/ld65/fragment.c +++ b/src/ld65/fragment.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -52,16 +52,18 @@ Fragment* NewFragment (unsigned char Type, unsigned long Size, Section* S) /* Create a new fragment and insert it into the section S */ { /* Allocate memory */ - Fragment* F = xmalloc (sizeof (Fragment) - 1 + Size); /* Portable? */ + Fragment* F = xmalloc (sizeof (Fragment) - 1 + Size); /* Initialize the data */ - F->Next = 0; - F->Obj = 0; - F->Size = Size; - F->Expr = 0; + F->Next = 0; + F->Obj = 0; + F->Size = Size; + F->Expr = 0; InitFilePos (&F->Pos); - F->LI = 0; - F->Type = Type; + F->LI = 0; + F->WarnExpr = 0; + F->ErrorExpr = 0; + F->Type = Type; /* Insert the code fragment into the section */ if (S->FragRoot == 0) { diff --git a/src/ld65/fragment.h b/src/ld65/fragment.h index be9a8f016..4165a15f3 100644 --- a/src/ld65/fragment.h +++ b/src/ld65/fragment.h @@ -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 */ /* */ /* */ @@ -69,6 +69,8 @@ struct Fragment { struct ExprNode* Expr; /* Expression if FRAG_EXPR */ FilePos Pos; /* File position in source */ struct LineInfo* LI; /* Additional line info */ + struct ExprNode* WarnExpr; /* Print warning if expr true */ + struct ExprNode* ErrorExpr; /* Print error if expr true */ unsigned char Type; /* Type of fragment */ unsigned char LitBuf [1]; /* Dynamically alloc'ed literal buffer */ }; diff --git a/src/ld65/library.c b/src/ld65/library.c index cb59f034d..a337cc1b1 100644 --- a/src/ld65/library.c +++ b/src/ld65/library.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (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 */ @@ -103,6 +103,8 @@ static void LibReadObjHeader (ObjData* O) O->Header.DbgSymSize = Read32 (Lib); O->Header.LineInfoOffs = Read32 (Lib); O->Header.LineInfoSize = Read32 (Lib); + O->Header.StrPoolOffs = Read32 (Lib); + O->Header.StrPoolSize = Read32 (Lib); } @@ -122,20 +124,23 @@ static ObjData* ReadIndexEntry (void) O->Start = Read32 (Lib); Read32 (Lib); /* Skip Size */ + /* Read the string pool */ + ObjReadStrPool (Lib, O); + /* Skip the export size, then read the exports */ - Read16 (Lib); + (void) ReadVar (Lib); O->ExportCount = ReadVar (Lib); O->Exports = xmalloc (O->ExportCount * sizeof (Export*)); for (I = 0; I < O->ExportCount; ++I) { - O->Exports [I] = ReadExport (Lib, O); + O->Exports[I] = ReadExport (Lib, O); } /* Skip the import size, then read the imports */ - Read16 (Lib); + (void) ReadVar (Lib); O->ImportCount = ReadVar (Lib); O->Imports = xmalloc (O->ImportCount * sizeof (Import*)); for (I = 0; I < O->ImportCount; ++I) { - O->Imports [I] = ReadImport (Lib, O); + O->Imports[I] = ReadImport (Lib, O); } /* Done */ @@ -150,19 +155,19 @@ static void ReadIndex (void) unsigned I; /* Read the object file count and allocate memory */ - ModuleCount = Read16 (Lib); + ModuleCount = ReadVar (Lib); Index = xmalloc (ModuleCount * sizeof (ObjData*)); /* Read all entries in the index */ for (I = 0; I < ModuleCount; ++I) { - Index [I] = ReadIndexEntry (); + Index[I] = ReadIndexEntry (); } } /*****************************************************************************/ -/* High level stuff */ +/* High level stuff */ /*****************************************************************************/ @@ -176,7 +181,7 @@ static void LibCheckExports (ObjData* O) /* Check all exports */ for (I = 0; I < O->ExportCount; ++I) { - if (IsUnresolved (O->Exports [I]->Name)) { + if (IsUnresolved (O->Exports[I]->Name)) { /* We need this module */ O->Flags |= OBJ_REF; break; @@ -187,11 +192,11 @@ static void LibCheckExports (ObjData* O) if (O->Flags & OBJ_REF) { /* Insert the exports */ for (I = 0; I < O->ExportCount; ++I) { - InsertExport (O->Exports [I]); + InsertExport (O->Exports[I]); } /* Insert the imports */ - for (I = 0; I < O->ImportCount; ++I) { - InsertImport (O->Imports [I]); + for (I = 0; I < O->ImportCount; ++I) { + InsertImport (O->Imports[I]); } } } @@ -215,7 +220,7 @@ void LibAdd (FILE* F, const char* Name) Header.Magic = LIB_MAGIC; Header.Version = Read16 (Lib); if (Header.Version != LIB_VERSION) { - Error ("Wrong data version in `%s'", Name); + Error ("Wrong data version in `%s'", Name); } Header.Flags = Read16 (Lib); Header.IndexOffs = Read32 (Lib); @@ -258,7 +263,7 @@ void LibAdd (FILE* F, const char* Name) /* Seek to the start of the debug info and read the debug info */ fseek (Lib, O->Start + O->Header.DbgSymOffs, SEEK_SET); - ObjReadDbgSyms (Lib, O); + ObjReadDbgSyms (Lib, O); /* Seek to the start of the line infos and read them */ fseek (Lib, O->Start + O->Header.LineInfoOffs, SEEK_SET); diff --git a/src/ld65/objdata.c b/src/ld65/objdata.c index 5183c7d81..3b667eace 100644 --- a/src/ld65/objdata.c +++ b/src/ld65/objdata.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -86,6 +86,8 @@ ObjData* NewObjData (void) O->DbgSyms = 0; O->LineInfoCount = 0; O->LineInfos = 0; + O->StringCount = 0; + O->Strings = 0; /* Link it into the list */ if (ObjLast) { @@ -105,15 +107,16 @@ ObjData* NewObjData (void) -void FreeObjData (ObjData* O) -/* Free a complete struct */ +const char* GetObjString (const ObjData* O, unsigned long Index) +/* Get a string from the object file string table. Abort if the string index + * is invalid. + */ { - xfree (O->Name); - xfree (O->Imports); - xfree (O->Exports); - xfree (O->DbgSyms); - xfree (O->LineInfos); - xfree (O); + if (Index >= O->StringCount) { + Error ("Invalid string index (%lu) in module `%s'", + Index, GetObjFileName (O)); + } + return O->Strings[Index]; } diff --git a/src/ld65/objdata.h b/src/ld65/objdata.h index cca2f7a38..b5c0eea71 100644 --- a/src/ld65/objdata.h +++ b/src/ld65/objdata.h @@ -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 */ /* */ /* */ @@ -76,6 +76,8 @@ struct ObjData { struct DbgSym** DbgSyms; /* List of debug symbols */ unsigned LineInfoCount; /* Count of additional line infos */ struct LineInfo** LineInfos; /* List of additional line infos */ + unsigned StringCount; /* Count of strings */ + char** Strings; /* List of strings used */ }; @@ -96,8 +98,10 @@ extern ObjData* ObjLast; /* Last entry in list */ ObjData* NewObjData (void); /* Allocate a new structure on the heap, insert it into the list, return it */ -void FreeObjData (ObjData* O); -/* Free a complete struct */ +const char* GetObjString (const ObjData* O, unsigned long Index); +/* Get a string from the object file string table. Abort if the string index + * is invalid. + */ const char* GetObjFileName (const ObjData* O); /* Get the name of the object file. Return "[linker generated]" if the object diff --git a/src/ld65/objfile.c b/src/ld65/objfile.c index 7eabc472e..899a612e4 100644 --- a/src/ld65/objfile.c +++ b/src/ld65/objfile.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -86,7 +86,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) { H->Version = Read16 (Obj); if (H->Version != OBJ_VERSION) { - Error ("Object file `%s' has wrong version", Name); + Error ("Object file `%s' has wrong version, expected %08X, got %08X", + Name, OBJ_VERSION, H->Version); } H->Flags = Read16 (Obj); H->OptionOffs = Read32 (Obj); @@ -103,6 +104,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) H->DbgSymSize = Read32 (Obj); H->LineInfoOffs = Read32 (Obj); H->LineInfoSize = Read32 (Obj); + H->StrPoolOffs = Read32 (Obj); + H->StrPoolSize = Read32 (Obj); } @@ -179,6 +182,19 @@ void ObjReadLineInfos (FILE* F, ObjData* O) +void ObjReadStrPool (FILE* F, ObjData* O) +/* Read the string pool from a file at the current position */ +{ + unsigned I; + O->StringCount = ReadVar (F); + O->Strings = xmalloc (O->StringCount * sizeof (char*)); + for (I = 0; I < O->StringCount; ++I) { + O->Strings[I] = ReadStr (F); + } +} + + + void ObjReadSections (FILE* F, ObjData* O) /* Read the section data from a file at the current position */ { @@ -209,6 +225,10 @@ void ObjAdd (FILE* Obj, const char* Name) O->Name = xstrdup (GetModule (Name)); O->Flags = OBJ_HAVEDATA; + /* Read the string pool from the object file */ + fseek (Obj, O->Header.StrPoolOffs, SEEK_SET); + ObjReadStrPool (Obj, O); + /* Read the files list from the object file */ fseek (Obj, O->Header.FileOffs, SEEK_SET); ObjReadFiles (Obj, O); diff --git a/src/ld65/objfile.h b/src/ld65/objfile.h index fbf58d4f2..1c05d5761 100644 --- a/src/ld65/objfile.h +++ b/src/ld65/objfile.h @@ -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 */ /* */ /* */ @@ -42,7 +42,7 @@ /* common */ #include "objdefs.h" - + /* ld65 */ #include "objdata.h" @@ -69,6 +69,9 @@ void ObjReadDbgSyms (FILE* F, ObjData* O); void ObjReadLineInfos (FILE* F, ObjData* O); /* Read the line infos from a file at the current position */ +void ObjReadStrPool (FILE* F, ObjData* O); +/* Read the string pool from a file at the current position */ + void ObjReadSections (FILE* F, ObjData* O); /* Read the section data from a file at the current position */ diff --git a/src/ld65/segments.c b/src/ld65/segments.c index c65a1d344..9d8e6d0e5 100644 --- a/src/ld65/segments.c +++ b/src/ld65/segments.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -259,6 +259,10 @@ Section* ReadSection (FILE* F, ObjData* O) /* Read the fragment type */ unsigned char Type = Read8 (F); + /* Extract the check mask from the type */ + unsigned char Check = Type & FRAG_CHECKMASK; + Type &= ~FRAG_CHECKMASK; + /* Handle the different fragment types */ switch (Type) { @@ -305,6 +309,14 @@ Section* ReadSection (FILE* F, ObjData* O) } + /* A check expression may follow */ + if (Check & FRAG_CHECK_WARN) { + Frag->WarnExpr = ReadExpr (F, O); + } + if (Check & FRAG_CHECK_ERROR) { + Frag->ErrorExpr = ReadExpr (F, O); + } + /* Read the file position of the fragment */ ReadFilePos (F, &Frag->Pos); @@ -506,7 +518,12 @@ void SegWrite (FILE* Tgt, Segment* S, SegWriteFunc F, void* Data) /* Loop over all fragments in this section */ Frag = Sec->FragRoot; while (Frag) { + + /* Do fragment alignment checks */ + + + /* Output fragment data */ switch (Frag->Type) { case FRAG_LITERAL: @@ -525,7 +542,7 @@ void SegWrite (FILE* Tgt, Segment* S, SegWriteFunc F, void* Data) case SEG_EXPR_RANGE_ERROR: Error ("Range error in module `%s', line %lu", GetSourceFileName (Frag->Obj, Frag->Pos.Name), - Frag->Pos.Line); + Frag->Pos.Line); break; case SEG_EXPR_TOO_COMPLEX: diff --git a/src/od65/dump.c b/src/od65/dump.c index 86fb93ba9..366ca82c5 100644 --- a/src/od65/dump.c +++ b/src/od65/dump.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 2000-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 2002-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ @@ -38,6 +38,7 @@ /* common */ #include "cddefs.h" +#include "coll.h" #include "exprdefs.h" #include "filepos.h" #include "objdefs.h" @@ -54,11 +55,39 @@ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ +static void DestroyStrPool (Collection* C) +/* Free all strings in the given pool plus the item pointers. Note: The + * collection may not be reused later. + */ +{ + unsigned I; + for (I = 0; I < CollCount (C); ++I) { + xfree (CollAtUnchecked (C, I)); + } + DoneCollection (C); +} + + + +static const char* GetString (const Collection* C, unsigned Index) +/* Get a string from a collection. In fact, this function calls CollConstAt, + * but will print a somewhat more readable error message if the index is out + * of bounds. + */ +{ + if (Index >= CollCount (C)) { + Error ("Invalid string index (%u) - file corrupt!", Index); + } + return CollConstAt (C, Index); +} + + + static void DumpObjHeaderSection (const char* Name, unsigned long Offset, unsigned long Size) @@ -109,7 +138,7 @@ static void SkipExpr (FILE* F) case EXPR_SYMBOL: /* Read the import number */ - (void) Read16 (F); + (void) ReadVar (F); break; case EXPR_SECTION: @@ -142,6 +171,10 @@ static unsigned SkipFragment (FILE* F) /* Read the fragment type */ unsigned char Type = Read8 (F); + /* Extract the check mask */ + unsigned char Check = Type & FRAG_CHECKMASK; + Type &= ~FRAG_CHECKMASK; + /* Handle the different fragment types */ switch (Type) { @@ -188,6 +221,14 @@ static unsigned SkipFragment (FILE* F) } + /* Skip the check expression if we have one */ + if (Check & FRAG_CHECK_WARN) { + SkipExpr (F); + } + if (Check & FRAG_CHECK_ERROR) { + SkipExpr (F); + } + /* Skip the file position of the fragment */ ReadFilePos (F, &Pos); @@ -290,6 +331,12 @@ void DumpObjHeader (FILE* F, unsigned long Offset) /* Debug symbols */ DumpObjHeaderSection ("Debug symbols", H.DbgSymOffs, H.DbgSymSize); + + /* Line infos */ + DumpObjHeaderSection ("Line infos", H.LineInfoOffs, H.LineInfoSize); + + /* String pool */ + DumpObjHeaderSection ("String pool", H.StrPoolOffs, H.StrPoolSize); } @@ -297,16 +344,19 @@ void DumpObjHeader (FILE* F, unsigned long Offset) void DumpObjOptions (FILE* F, unsigned long Offset) /* Dump the file options */ { - ObjHeader H; - unsigned Count; - unsigned I; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; - /* Seek to the header position */ + /* Seek to the header position and read the header */ FileSeek (F, Offset); - - /* Read the header */ ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + FileSeek (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + /* Seek to the start of the options */ FileSeek (F, Offset + H.OptionOffs); @@ -374,6 +424,9 @@ void DumpObjOptions (FILE* F, unsigned long Offset) break; } } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -381,16 +434,19 @@ void DumpObjOptions (FILE* F, unsigned long Offset) void DumpObjFiles (FILE* F, unsigned long Offset) /* Dump the source files */ { - ObjHeader H; - unsigned Count; - unsigned I; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; - /* Seek to the header position */ + /* Seek to the header position and read the header */ FileSeek (F, Offset); - - /* Read the header */ ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + FileSeek (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + /* Seek to the start of the source files */ FileSeek (F, Offset + H.FileOffs); @@ -421,6 +477,9 @@ void DumpObjFiles (FILE* F, unsigned long Offset) /* Free the Name */ xfree (Name); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -428,17 +487,20 @@ void DumpObjFiles (FILE* F, unsigned long Offset) void DumpObjSegments (FILE* F, unsigned long Offset) /* Dump the segments in the object file */ { - ObjHeader H; - unsigned Count; - unsigned I; - unsigned FragCount; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; + unsigned FragCount; - /* Seek to the header position */ + /* Seek to the header position and read the header */ FileSeek (F, Offset); - - /* Read the header */ ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + FileSeek (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + /* Seek to the start of the segments */ FileSeek (F, Offset + H.SegOffs); @@ -451,7 +513,7 @@ void DumpObjSegments (FILE* F, unsigned long Offset) /* Read and print all segments */ for (I = 0; I < Count; ++I) { - + /* Read the data for one segments */ char* Name = ReadStr (F); unsigned Len = strlen (Name); @@ -486,8 +548,8 @@ void DumpObjSegments (FILE* F, unsigned long Offset) while (Size > 0) { unsigned FragSize = SkipFragment (F); if (FragSize > Size) { - /* OOPS - file data invalid */ - Error ("Invalid fragment data - file corrupt!"); + /* OOPS - file data invalid */ + Error ("Invalid fragment data - file corrupt!"); } Size -= FragSize; ++FragCount; @@ -496,6 +558,9 @@ void DumpObjSegments (FILE* F, unsigned long Offset) /* Print the fragment count */ printf (" Fragment count:%16u\n", FragCount); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -503,17 +568,20 @@ void DumpObjSegments (FILE* F, unsigned long Offset) void DumpObjImports (FILE* F, unsigned long Offset) /* Dump the imports in the object file */ { - ObjHeader H; - unsigned Count; - unsigned I; - FilePos Pos; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; + FilePos Pos; - /* Seek to the header position */ + /* Seek to the header position and read the header */ FileSeek (F, Offset); - - /* Read the header */ ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + FileSeek (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + /* Seek to the start of the imports */ FileSeek (F, Offset + H.ImportOffs); @@ -531,7 +599,7 @@ void DumpObjImports (FILE* F, unsigned long Offset) /* Read the data for one import */ unsigned char Type = Read8 (F); - char* Name = ReadStr (F); + const char* Name = GetString (&StrPool, ReadVar (F)); unsigned Len = strlen (Name); ReadFilePos (F, &Pos); @@ -548,10 +616,10 @@ void DumpObjImports (FILE* F, unsigned long Offset) /* Print the data */ printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); - - /* Free the Name */ - xfree (Name); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -559,17 +627,20 @@ void DumpObjImports (FILE* F, unsigned long Offset) void DumpObjExports (FILE* F, unsigned long Offset) /* Dump the exports in the object file */ { - ObjHeader H; - unsigned Count; - unsigned I; - FilePos Pos; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; + FilePos Pos; - /* Seek to the header position */ + /* Seek to the header position and read the header */ FileSeek (F, Offset); - - /* Read the header */ ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + FileSeek (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + /* Seek to the start of the exports */ FileSeek (F, Offset + H.ExportOffs); @@ -584,17 +655,17 @@ void DumpObjExports (FILE* F, unsigned long Offset) for (I = 0; I < Count; ++I) { unsigned long Value = 0; - int HaveValue; + int HaveValue; unsigned char Type; unsigned char ConDes [CD_TYPE_COUNT]; - char* Name; + const char* Name; unsigned Len; /* Read the data for one export */ Type = Read8 (F); ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type)); - Name = ReadStr (F); + Name = GetString (&StrPool, ReadVar (F)); Len = strlen (Name); if (IS_EXP_EXPR (Type)) { SkipExpr (F); @@ -614,10 +685,10 @@ void DumpObjExports (FILE* F, unsigned long Offset) if (HaveValue) { printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value); } - - /* Free the Name */ - xfree (Name); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -625,17 +696,20 @@ void DumpObjExports (FILE* F, unsigned long Offset) void DumpObjDbgSyms (FILE* F, unsigned long Offset) /* Dump the debug symbols from an object file */ { - ObjHeader H; - unsigned Count; - unsigned I; - FilePos Pos; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; + FilePos Pos; - /* Seek to the header position */ + /* Seek to the header position and read the header */ FileSeek (F, Offset); - - /* Read the header */ ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + FileSeek (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + /* Seek to the start of the debug syms */ FileSeek (F, Offset + H.DbgSymOffs); @@ -660,13 +734,13 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset) int HaveValue; unsigned char Type; unsigned char ConDes [CD_TYPE_COUNT]; - char* Name; + const char* Name; unsigned Len; /* Read the data for one symbol */ Type = Read8 (F); ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type)); - Name = ReadStr (F); + Name = GetString (&StrPool, ReadVar (F)); Len = strlen (Name); if (IS_EXP_EXPR (Type)) { SkipExpr (F); @@ -686,10 +760,10 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset) if (HaveValue) { printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value); } - - /* Free the Name */ - xfree (Name); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -697,16 +771,19 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset) void DumpObjLineInfo (FILE* F, unsigned long Offset) /* Dump the line info from an object file */ { - ObjHeader H; - unsigned Count; - unsigned I; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; + unsigned I; - /* Seek to the header position */ + /* Seek to the header position and read the header */ FileSeek (F, Offset); - - /* Read the header */ ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + FileSeek (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + /* Seek to the start of line infos */ FileSeek (F, Offset + H.LineInfoOffs); @@ -740,6 +817,9 @@ void DumpObjLineInfo (FILE* F, unsigned long Offset) printf (" Col:%27u\n", Pos.Col); printf (" Name:%26u\n", Pos.Name); } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } @@ -747,15 +827,18 @@ void DumpObjLineInfo (FILE* F, unsigned long Offset) void DumpObjSegSize (FILE* F, unsigned long Offset) /* Dump the sizes of the segment in the object file */ { - ObjHeader H; - unsigned Count; + ObjHeader H; + Collection StrPool = AUTO_COLLECTION_INITIALIZER; + unsigned Count; - /* Seek to the header position */ + /* Seek to the header position and read the header */ FileSeek (F, Offset); - - /* Read the header */ ReadObjHeader (F, &H); + /* Seek to the start of the string pool and read it */ + FileSeek (F, Offset + H.StrPoolOffs); + ReadStrPool (F, &StrPool); + /* Seek to the start of the segments */ FileSeek (F, Offset + H.SegOffs); @@ -793,6 +876,9 @@ void DumpObjSegSize (FILE* F, unsigned long Offset) Size -= FragSize; } } + + /* Destroy the string pool */ + DestroyStrPool (&StrPool); } diff --git a/src/od65/fileio.c b/src/od65/fileio.c index ee0e32372..300321164 100644 --- a/src/od65/fileio.c +++ b/src/od65/fileio.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -211,6 +211,22 @@ void ReadObjHeader (FILE* F, ObjHeader* H) H->DbgSymSize = Read32 (F); H->LineInfoOffs = Read32 (F); H->LineInfoSize = Read32 (F); + H->StrPoolOffs = Read32 (F); + H->StrPoolSize = Read32 (F); +} + + + +void ReadStrPool (FILE* F, Collection* C) +/* Read a string pool from the current position into C. */ +{ + /* The number of strings is the first item */ + unsigned long Count = ReadVar (F); + + /* Read all the strings into C */ + while (Count--) { + CollAppend (C, ReadStr (F)); + } } diff --git a/src/od65/fileio.h b/src/od65/fileio.h index 862c9b206..89e9a43d4 100644 --- a/src/od65/fileio.h +++ b/src/od65/fileio.h @@ -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 */ @@ -41,6 +41,7 @@ #include /* common */ +#include "coll.h" #include "filepos.h" #include "objdefs.h" @@ -85,6 +86,9 @@ void* ReadData (FILE* F, void* Data, unsigned Size); void ReadObjHeader (FILE* F, ObjHeader* Header); /* Read an object file header from the file */ +void ReadStrPool (FILE* F, Collection* C); +/* Read a string pool from the current position into C. */ + /* End of fileio.h */ -- 2.39.5