From 8f9a21ae3fdc66d0bebadb029bba0dc37aa68023 Mon Sep 17 00:00:00 2001 From: cuz Date: Fri, 28 Nov 2003 22:12:14 +0000 Subject: [PATCH] Extend the object code format by adding a (currently empty) scope table. Use the address size for import, export and debug symbols (object code change). More changes to support the --memory-model switch and address sizes. git-svn-id: svn://svn.cc65.org/cc65/trunk@2691 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ar65/error.c | 18 ++++--- src/ar65/exports.c | 4 +- src/ar65/fileio.c | 8 +-- src/ar65/library.c | 12 ++--- src/ar65/main.c | 10 ++-- src/ar65/objfile.c | 10 +++- src/ca65/global.c | 5 +- src/ca65/global.h | 1 - src/ca65/main.c | 37 +++++++++++--- src/ca65/objfile.c | 22 +++++++- src/ca65/objfile.h | 8 ++- src/ca65/segment.c | 31 +++++++++++ src/ca65/segment.h | 5 +- src/ca65/symentry.c | 119 ++++++++++++++++++++++++++----------------- src/ca65/symtab.c | 58 +++++++++++++-------- src/cc65/codeseg.c | 22 +++++--- src/cc65/datatype.c | 12 +++-- src/cc65/declare.c | 108 ++++++++++++++++++++++++++++++++------- src/cc65/funcdesc.h | 19 ++++--- src/common/libdefs.h | 2 +- src/common/mmodel.c | 44 ++++++++++++++++ src/common/mmodel.h | 11 +++- src/common/objdefs.h | 8 +-- src/common/symdefs.h | 24 ++------- src/ld65/dbgsyms.c | 9 ++-- src/ld65/dbgsyms.h | 1 + src/ld65/exports.c | 88 ++++++++++++++++++++++---------- src/ld65/exports.h | 7 +-- src/ld65/library.c | 17 ++++--- src/ld65/objdata.c | 6 ++- src/ld65/objdata.h | 17 ++++++- src/ld65/objfile.c | 25 ++++++++- src/ld65/objfile.h | 5 +- src/od65/dump.c | 56 ++++++++------------ src/od65/fileio.c | 4 +- 35 files changed, 584 insertions(+), 249 deletions(-) diff --git a/src/ar65/error.c b/src/ar65/error.c index efafb9c81..26e5619ee 100644 --- a/src/ar65/error.c +++ b/src/ar65/error.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ömerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -37,6 +37,10 @@ #include #include +/* common */ +#include "cmdline.h" + +/* ar65 */ #include "error.h" @@ -52,7 +56,7 @@ void Warning (const char* Format, ...) { va_list ap; va_start (ap, Format); - fprintf (stderr, "Warning: "); + fprintf (stderr, "%s: Warning: ", ProgName); vfprintf (stderr, Format, ap); putc ('\n', stderr); va_end (ap); @@ -65,7 +69,7 @@ void Error (const char* Format, ...) { va_list ap; va_start (ap, Format); - fprintf (stderr, "Error: "); + fprintf (stderr, "%s: Error: ", ProgName); vfprintf (stderr, Format, ap); putc ('\n', stderr); va_end (ap); @@ -79,7 +83,7 @@ void Internal (const char* Format, ...) { va_list ap; va_start (ap, Format); - fprintf (stderr, "Internal error: "); + fprintf (stderr, "%s: Internal error: ", ProgName); vfprintf (stderr, Format, ap); putc ('\n', stderr); va_end (ap); diff --git a/src/ar65/exports.c b/src/ar65/exports.c index 2019aedea..745ed7bba 100644 --- a/src/ar65/exports.c +++ b/src/ar65/exports.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -53,7 +53,7 @@ /* A hash table entry */ -typedef struct HashEntry HashEntry; +typedef struct HashEntry HashEntry; struct HashEntry { HashEntry* Next; /* Next in list */ unsigned Module; /* Module index */ diff --git a/src/ar65/fileio.c b/src/ar65/fileio.c index 730fc6332..b4c6b4aec 100644 --- a/src/ar65/fileio.c +++ b/src/ar65/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 */ diff --git a/src/ar65/library.c b/src/ar65/library.c index cd4bfcadf..6f73816cd 100644 --- a/src/ar65/library.c +++ b/src/ar65/library.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -408,20 +408,20 @@ static void LibCheckExports (ObjData* O) Print (stdout, 1, "Module `%s' (%u exports):\n", O->Name, Count); while (Count--) { - unsigned char Tag; const char* Name; - /* Get the export tag */ - Tag = *Exports++; + /* Get the export tag and skip the address size */ + unsigned char Type = *Exports++; + ++Exports; /* condes decls may follow */ - Exports += GET_EXP_CONDES_COUNT (Tag); + Exports += GET_EXP_CONDES_COUNT (Type); /* Next thing is index of name of symbol */ Name = GetObjString (O, GetVar (&Exports)); /* Skip value of symbol */ - if (Tag & EXP_EXPR) { + if (Type & EXP_EXPR) { /* Expression tree */ SkipExpr (&Exports); } else { diff --git a/src/ar65/main.c b/src/ar65/main.c index d7e658ad8..d45ee32b8 100644 --- a/src/ar65/main.c +++ b/src/ar65/main.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2001 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -122,7 +122,7 @@ int main (int argc, char* argv []) case 'V': fprintf (stderr, - "ar65 V%u.%u.%u - (C) Copyright 1998-2001 Ullrich von Bassewitz\n", + "ar65 V%u.%u.%u - (C) Copyright 1998-2003 Ullrich von Bassewitz\n", VER_MAJOR, VER_MINOR, VER_PATCH); break; diff --git a/src/ar65/objfile.c b/src/ar65/objfile.c index e165fc167..1c18fddd5 100644 --- a/src/ar65/objfile.c +++ b/src/ar65/objfile.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -113,6 +113,8 @@ void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) H->StrPoolSize = Read32 (Obj); H->AssertOffs = Read32 (Obj); H->AssertSize = Read32 (Obj); + H->ScopeOffs = Read32 (Obj); + H->ScopeSize = Read32 (Obj); } @@ -140,7 +142,9 @@ void ObjWriteHeader (FILE* Obj, ObjHeader* H) Write32 (Obj, H->StrPoolOffs); Write32 (Obj, H->StrPoolSize); Write32 (Obj, H->AssertOffs); - Write32 (Obj, H->AssertSize); + Write32 (Obj, H->AssertSize); + Write32 (Obj, H->ScopeOffs); + Write32 (Obj, H->ScopeSize); } @@ -225,6 +229,8 @@ void ObjAdd (const char* Name) H.LineInfoOffs = LibCopyTo (Obj, H.LineInfoSize) - O->Start; fseek (Obj, H.AssertOffs, SEEK_SET); H.AssertOffs = LibCopyTo (Obj, H.AssertSize) - O->Start; + fseek (Obj, H.ScopeOffs, SEEK_SET); + H.ScopeOffs = LibCopyTo (Obj, H.ScopeSize) - O->Start; /* Calculate the amount of data written */ O->Size = ftell (NewLib) - O->Start; diff --git a/src/ca65/global.c b/src/ca65/global.c index cc0dc79f3..eb6634569 100644 --- a/src/ca65/global.c +++ b/src/ca65/global.c @@ -37,7 +37,7 @@ #include "addrsize.h" /* ca65 */ -#include "global.h" +#include "global.h" @@ -64,8 +64,7 @@ unsigned char SmartMode = 0; /* Smart mode */ unsigned char DbgSyms = 0; /* Add debug symbols */ unsigned char Listing = 0; /* Create listing file */ unsigned char LineCont = 0; /* Allow line continuation */ -unsigned char DefAddrSize = ADDR_SIZE_ABS; /* Default address size */ - + /* Emulation features */ unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */ unsigned char NoColonLabels = 0; /* Allow labels without a colon */ diff --git a/src/ca65/global.h b/src/ca65/global.h index 69633c635..68670ad9b 100644 --- a/src/ca65/global.h +++ b/src/ca65/global.h @@ -61,7 +61,6 @@ extern unsigned char SmartMode; /* Smart mode */ extern unsigned char DbgSyms; /* Add debug symbols */ extern unsigned char Listing; /* Create listing file */ extern unsigned char LineCont; /* Allow line continuation */ -extern unsigned char DefAddrSize; /* Default address size */ /* Emulation features */ extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */ diff --git a/src/ca65/main.c b/src/ca65/main.c index 977057c58..31c92a198 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -42,6 +42,7 @@ #include "addrsize.h" #include "chartype.h" #include "cmdline.h" +#include "mmodel.h" #include "print.h" #include "target.h" #include "tgttrans.h" @@ -143,6 +144,7 @@ static void DefineSymbol (const char* Def) long Val; char SymName [MAX_STR_LEN+1]; SymEntry* Sym; + ExprNode* Expr; /* The symbol must start with a character or underline */ @@ -190,8 +192,11 @@ static void DefineSymbol (const char* Def) AbEnd ("`%s' is already defined", SymName); } + /* Generate an expression for the symbol */ + Expr = GenLiteralExpr (Val); + /* Mark the symbol as defined */ - SymDef (Sym, GenLiteralExpr (Val), ADDR_SIZE_DEFAULT, SF_NONE); + SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE); } @@ -274,16 +279,26 @@ static void OptListing (const char* Opt attribute ((unused)), -static void OptMemoryModel (const char* Opt attribute ((unused)), const char* Arg) +static void OptMemoryModel (const char* Opt, const char* Arg) /* Set the memory model */ { - if (strcmp (Arg, "near") == 0) { - DefAddrSize = ADDR_SIZE_ABS; - } else if (strcmp (Arg, "far") == 0) { - DefAddrSize = ADDR_SIZE_FAR; - } else { + mmodel_t M; + + /* Check the current memory model */ + if (MemoryModel != MMODEL_UNKNOWN) { + AbEnd ("Cannot use option `%s' twice", Opt); + } + + /* Translate the memory model name and check it */ + M = FindMemoryModel (Arg); + if (M == MMODEL_UNKNOWN) { AbEnd ("Unknown memory model: %s", Arg); + } else if (M == MMODEL_HUGE) { + AbEnd ("Unsupported memory model: %s", Arg); } + + /* Set the memory model */ + SetMemoryModel (M); } @@ -653,9 +668,17 @@ int main (int argc, char* argv []) } } + /* If no memory model was given, use the default */ + if (MemoryModel == MMODEL_UNKNOWN) { + MemoryModel = MMODEL_NEAR; + } + /* Intialize the target translation tables */ TgtTranslateInit (); + /* Initialize the segments */ + InitSegments (); + /* Initialize the scanner, open the input file */ InitScanner (InFile); diff --git a/src/ca65/objfile.c b/src/ca65/objfile.c index 512ccffb9..0adaaee54 100644 --- a/src/ca65/objfile.c +++ b/src/ca65/objfile.c @@ -83,7 +83,9 @@ static ObjHeader Header = { 0, /* 32: Offset to string pool */ 0, /* 32: Size of string pool */ 0, /* 32: Offset to assertion table */ - 0 /* 32: Size of assertion table */ + 0, /* 32: Size of assertion table */ + 0, /* 32: Offset into scope table */ + 0, /* 32: Size of scope table */ }; @@ -138,6 +140,8 @@ static void ObjWriteHeader (void) ObjWrite32 (Header.StrPoolSize); ObjWrite32 (Header.AssertOffs); ObjWrite32 (Header.AssertSize); + ObjWrite32 (Header.ScopeOffs); + ObjWrite32 (Header.ScopeSize); } @@ -462,3 +466,19 @@ void ObjEndAssertions (void) +void ObjStartScopes (void) +/* Mark the start of the scope table */ +{ + Header.ScopeOffs = ftell (F); +} + + + +void ObjEndScopes (void) +/* Mark the end of the scope table */ +{ + Header.ScopeSize = ftell (F) - Header.ScopeOffs; +} + + + diff --git a/src/ca65/objfile.h b/src/ca65/objfile.h index c0edde240..203d98993 100644 --- a/src/ca65/objfile.h +++ b/src/ca65/objfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -139,6 +139,12 @@ void ObjStartAssertions (void); void ObjEndAssertions (void); /* Mark the end of the assertion table */ +void ObjStartScopes (void); +/* Mark the start of the scope table */ + +void ObjEndScopes (void); +/* Mark the end of the scope table */ + /* End of objfile.h */ diff --git a/src/ca65/segment.c b/src/ca65/segment.c index 5db9fe2b4..66f67e57f 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -37,6 +37,7 @@ #include /* common */ +#include "mmodel.h" #include "segnames.h" #include "xmalloc.h" @@ -488,6 +489,36 @@ static void WriteOneSeg (Segment* Seg) +void InitSegments (void) +/* Initialize segments */ +{ + /* Initialize segment sizes. The segment definitions do already contain + * the correct values for the default case (near), so we must only change + * things that should be different. + */ + switch (MemoryModel) { + + case MMODEL_NEAR: + break; + + case MMODEL_FAR: + CodeSegDef.AddrSize = ADDR_SIZE_FAR; + break; + + case MMODEL_HUGE: + CodeSegDef.AddrSize = ADDR_SIZE_FAR; + DataSegDef.AddrSize = ADDR_SIZE_FAR; + BssSegDef.AddrSize = ADDR_SIZE_FAR; + RODataSegDef.AddrSize = ADDR_SIZE_FAR; + break; + + default: + Internal ("Invalid memory model: %d", MemoryModel); + } +} + + + void WriteSegments (void) /* Write the segment data to the object file */ { diff --git a/src/ca65/segment.h b/src/ca65/segment.h index f4b8c8240..57da03130 100644 --- a/src/ca65/segment.h +++ b/src/ca65/segment.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -146,6 +146,9 @@ void SegCheck (void); void SegDump (void); /* Dump the contents of all segments */ +void InitSegments (void); +/* Initialize segments */ + void WriteSegments (void); /* Write the segment data to the object file */ diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index bc2300971..6f67ec015 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -213,9 +213,10 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags /* Set the symbol value */ S->V.Expr = Expr; - /* If the symbol is marked as global, export it */ + /* If the symbol is marked as global, export it. Address size is checked + * below. + */ if (S->Flags & SF_GLOBAL) { - S->ExportSize = S->AddrSize; S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT; } @@ -229,20 +230,13 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags /* Use the real size of the symbol */ S->ExportSize = S->AddrSize; } else if (S->AddrSize > S->ExportSize) { - PWarning (GetSymPos (S), 1, "Symbol `%s' is %s but exported as %s", + /* We're exporting a symbol smaller than it actually is */ + PWarning (GetSymPos (S), 1, "Symbol `%s' is %s but exported %s", GetSymName (S), AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->ExportSize)); } } - /* If the symbol is a ZP symbol, check if the value is in correct range */ - if (S->AddrSize == ADDR_SIZE_ZP) { - /* Already marked as ZP symbol by some means */ - if (!IsByteExpr (Expr)) { - Error ("Range error"); - } - } - /* If this is not a local symbol, remember it as the last global one */ if (!IsLocalNameId (S->Name)) { SymLast = S; @@ -271,13 +265,15 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags) return; } - /* If no address size is given, use the default address size */ + /* If no address size is given, use the address size of the enclosing + * segment. + */ if (AddrSize == ADDR_SIZE_DEFAULT) { - AddrSize = DefAddrSize; + AddrSize = GetCurrentSegAddrSize (); } - /* If the symbol is marked as import or global, check the symbol flags, - * then do silently remove the global flag + /* If the symbol is marked as import or global, check the address size, + * then do silently remove the global flag. */ if (S->Flags & SF_IMPORT) { if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) { @@ -288,10 +284,10 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags) } } if (S->Flags & SF_GLOBAL) { - if (S->AddrSize != ADDR_SIZE_DEFAULT && S->AddrSize != AddrSize) { + S->Flags &= ~SF_GLOBAL; + if (AddrSize != S->AddrSize) { Error ("Address size mismatch for symbol `%s'", GetSymName (S)); } - S->Flags &= ~SF_GLOBAL; } /* Set the symbol data */ @@ -317,23 +313,21 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags) return; } - /* If the symbol was marked as global before, make it an export */ + /* If the symbol was marked as global before, remove the global flag and + * proceed, but check the address size. + */ if (S->Flags & SF_GLOBAL) { - S->ExportSize = S->AddrSize; + if (AddrSize != S->ExportSize) { + Error ("Address size mismatch for symbol `%s'", GetSymName (S)); + } S->Flags &= ~SF_GLOBAL; } - /* If the symbol was already marked as an export, check if this was done - * specifiying the same address size. If the old spec had no explicit - * address size, use the new one. + /* If the symbol was already marked as an export, but wasn't defined + * before, the address sizes in both definitions must match. */ - if (S->Flags & SF_EXPORT) { - if (S->ExportSize == ADDR_SIZE_DEFAULT) { - S->ExportSize = AddrSize; - } else if (AddrSize == ADDR_SIZE_DEFAULT) { - AddrSize = S->ExportSize; - } - if (S->ExportSize != ADDR_SIZE_DEFAULT && S->ExportSize != AddrSize) { + if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) { + if (S->ExportSize != AddrSize) { Error ("Address size mismatch for symbol `%s'", GetSymName (S)); } } @@ -347,7 +341,8 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags) /* No export size given, use the real size of the symbol */ S->ExportSize = S->AddrSize; } else if (S->AddrSize > S->ExportSize) { - Warning (1, "Symbol `%s' is %s but exported as %s", + /* We're exporting a symbol smaller than it actually is */ + Warning (1, "Symbol `%s' is %s but exported %s", GetSymName (S), AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->ExportSize)); } @@ -370,30 +365,53 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags) return; } - /* If the symbol is already marked as import or export, check the - * size of the definition, then bail out. + /* If the symbol is already marked as import, the address size must match. + * Apart from that, ignore the global declaration. */ if (S->Flags & SF_IMPORT) { - if (AddrSize != ADDR_SIZE_DEFAULT && AddrSize != S->AddrSize) { + if (AddrSize == ADDR_SIZE_DEFAULT) { + /* Use the size of the current segment */ + AddrSize = GetCurrentSegAddrSize (); + } + if (AddrSize != S->AddrSize) { Error ("Address size mismatch for symbol `%s'", GetSymName (S)); } return; } + + /* If the symbol is already an export: If it is not defined, the address + * sizes must match. + */ if (S->Flags & SF_EXPORT) { - /* If the old symbol had no explicit address size spec, use the - * new one. - */ - if (S->ExportSize == ADDR_SIZE_DEFAULT) { - S->ExportSize = AddrSize; + if ((S->Flags & SF_DEFINED) == 0) { + /* Symbol is undefined */ + if (AddrSize != S->ExportSize) { + Error ("Address size mismatch for symbol `%s'", GetSymName (S)); + } + } else if (AddrSize != ADDR_SIZE_DEFAULT) { + /* Symbol is defined and address size given */ + if (AddrSize != S->ExportSize) { + Error ("Address size mismatch for symbol `%s'", GetSymName (S)); + } } + return; + } + + /* If the symbol is already marked as global, the address size must match. + * Use the ExportSize here, since it contains the actual address size + * passed to this function. + */ + if (S->Flags & SF_GLOBAL) { if (AddrSize != S->ExportSize) { Error ("Address size mismatch for symbol `%s'", GetSymName (S)); } return; } - /* If the symbol is already defined, export it. Otherwise mark it as - * global. + /* If we come here, the symbol was neither declared as export, import or + * global before. Check if it is already defined, in which case it will + * become an export. If it is not defined, mark it as global and remember + * the given address sizes. */ if (S->Flags & SF_DEFINED) { /* The symbol is defined, export it */ @@ -402,15 +420,24 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags) /* No export size given, use the real size of the symbol */ S->ExportSize = S->AddrSize; } else if (S->AddrSize > S->ExportSize) { - Warning (1, "Symbol `%s' is %s but exported as %s", + /* We're exporting a symbol smaller than it actually is */ + Warning (1, "Symbol `%s' is %s but exported %s", GetSymName (S), AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->ExportSize)); } S->Flags |= (SF_EXPORT | Flags); - S->ExportSize = AddrSize; } else { - S->Flags |= (SF_GLOBAL | Flags); + /* Since we don't know if the symbol will get exported or imported, + * remember two different address sizes: One for an import in AddrSize, + * and the other one for an export in ExportSize. + */ S->AddrSize = AddrSize; + if (S->AddrSize == ADDR_SIZE_DEFAULT) { + /* Use the size of the current segment */ + S->AddrSize = GetCurrentSegAddrSize (); + } + S->ExportSize = AddrSize; + S->Flags |= (SF_GLOBAL | Flags); } } @@ -470,9 +497,9 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri * priority value is the same as the old one. */ if (S->ConDesPrio[Type] != CD_PRIO_NONE) { - if (S->ConDesPrio[Type] != Prio) { - Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S)); - } + if (S->ConDesPrio[Type] != Prio) { + Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S)); + } } S->ConDesPrio[Type] = Prio; diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index ca3966867..bf6a3da81 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -39,6 +39,7 @@ #include "addrsize.h" #include "check.h" #include "hashstr.h" +#include "mmodel.h" #include "symdefs.h" #include "xmalloc.h" @@ -475,6 +476,8 @@ static void SymCheckUndefined (SymEntry* S) if (AutoImport) { /* Mark as import, will be indexed later */ S->Flags |= SF_IMPORT; + /* Use the address size for code */ + S->AddrSize = CodeAddrSize; } else { /* Error */ PError (&S->Pos, "Symbol `%s' is undefined", GetString (S->Name)); @@ -607,11 +610,7 @@ void WriteImports (void) if ((S->Flags & (SF_TRAMPOLINE | SF_IMPORT)) == SF_IMPORT && (S->Flags & (SF_REFERENCED | SF_FORCED)) != 0) { - if (S->AddrSize == ADDR_SIZE_ZP) { - ObjWrite8 (IMP_ZP); - } else { - ObjWrite8 (IMP_ABS); - } + ObjWrite8 (S->AddrSize); ObjWriteVar (S->Name); ObjWritePos (&S->Pos); } @@ -645,7 +644,6 @@ void WriteExports (void) /* Get the expression bits */ unsigned char ExprMask = SymIsConst (S, &ConstVal)? EXP_CONST : EXP_EXPR; - ExprMask |= (S->ExportSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS; ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE; /* Count the number of ConDes types */ @@ -655,8 +653,9 @@ void WriteExports (void) } } - /* Write the type */ + /* Write the type and the export size */ ObjWrite8 (ExprMask); + ObjWrite8 (S->ExportSize); /* Write any ConDes declarations */ if (GET_EXP_CONDES_COUNT (ExprMask) > 0) { @@ -674,7 +673,7 @@ void WriteExports (void) /* Write the value */ if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) { /* Constant value */ - ObjWrite32 (ConstVal); + ObjWrite32 (ConstVal); } else { /* Expression involved */ WriteExpr (S->V.Expr); @@ -704,34 +703,36 @@ void WriteDbgSyms (void) /* Check if debug info is requested */ if (DbgSyms) { - /* Walk through the list and count the symbols */ - Count = 0; - S = SymList; - while (S) { - if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) { - ++Count; - } - S = S->List; - } + /* Walk through the list and count the symbols */ + Count = 0; + S = SymList; + while (S) { + if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) { + ++Count; + } + S = S->List; + } - /* Write the symbol count to the list */ + /* Write the symbol count to the list */ ObjWriteVar (Count); /* Walk through list and write all symbols to the file */ - S = SymList; - while (S) { - if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) { + S = SymList; + while (S) { + if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) { long ConstVal; /* Get the expression bits */ unsigned char ExprMask = (SymIsConst (S, &ConstVal))? EXP_CONST : EXP_EXPR; - ExprMask |= (S->AddrSize == ADDR_SIZE_ZP)? EXP_ZP : EXP_ABS; ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE; /* Write the type */ ObjWrite8 (ExprMask); + /* Write the address size */ + ObjWrite8 (S->AddrSize); + /* Write the name */ ObjWriteVar (S->Name); @@ -763,5 +764,18 @@ void WriteDbgSyms (void) +void WriteScopes (void) +/* Write the scope table to the object file */ +{ + /* Tell the object file module that we're about to start the scopes */ + ObjStartScopes (); + + /* For now ...*/ + ObjWriteVar (0); + + /* Done writing the scopes */ + ObjEndScopes (); +} + diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index eb2cb0679..710494cac 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -807,7 +807,7 @@ CodeLabel* CS_GenLabel (CodeSeg* S, struct CodeEntry* E) /* Attach this label to the code entry */ CE_AttachLabel (E, L); - } + } /* Return the label */ return L; @@ -1225,8 +1225,16 @@ void CS_OutputPrologue (const CodeSeg* S, FILE* F) * segment before outputing the function label. */ if (Func) { + /* Get the function descriptor */ + const FuncDesc* D = GetFuncDesc (Func->Type); CS_PrintFunctionHeader (S, F); - fprintf (F, ".segment\t\"%s\"\n\n.proc\t_%s\n\n", S->SegName, Func->Name); + fprintf (F, ".segment\t\"%s\"\n\n.proc\t_%s", S->SegName, Func->Name); + if (D->Flags & FD_NEAR) { + fputs (": near", F); + } else if (D->Flags & FD_FAR) { + fputs (": far", F); + } + fputs ("\n\n", F); } } @@ -1239,7 +1247,7 @@ void CS_OutputEpilogue (const CodeSeg* S, FILE* F) */ { if (S->Func) { - fprintf (F, "\n.endproc\n\n"); + fputs ("\n.endproc\n\n", F); } } @@ -1304,7 +1312,7 @@ void CS_Output (const CodeSeg* S, FILE* F) /* If debug info is enabled, terminate the last line number information */ if (DebugInfo) { - fprintf (F, "\t.dbg\tline\n"); + fputs ("\t.dbg\tline\n", F); } } @@ -1397,7 +1405,7 @@ void CS_GenRegInfo (CodeSeg* S) break; } if (J->RI->Out2.RegA != Regs.RegA) { - Regs.RegA = UNKNOWN_REGVAL; + Regs.RegA = UNKNOWN_REGVAL; } if (J->RI->Out2.RegX != Regs.RegX) { Regs.RegX = UNKNOWN_REGVAL; @@ -1443,7 +1451,7 @@ void CS_GenRegInfo (CodeSeg* S) /* Check the previous instruction */ switch (P->OPC) { - case OP65_ADC: + case OP65_ADC: case OP65_AND: case OP65_DEA: case OP65_EOR: @@ -1489,7 +1497,7 @@ void CS_GenRegInfo (CodeSeg* S) case OP65_CPY: /* If this is an immidiate compare, the Y register has * the value of the compare later. - */ + */ if (CE_KnownImm (P)) { if (BC == BC_EQ) { E->RI->Out2.RegY = (unsigned char)P->Num; diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index ea9dc6a71..e257d46ae 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -7,9 +7,9 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ -/* EMail: uz@musoftware.de */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -327,6 +327,12 @@ void PrintFuncSig (FILE* F, const char* Name, type* Type) /* Print a comment with the function signature */ PrintType (F, GetFuncReturn (Type)); + if (D->Flags & FD_NEAR) { + fprintf (F, " __near__"); + } + if (D->Flags & FD_FAR) { + fprintf (F, " __far__"); + } if (D->Flags & FD_FASTCALL) { fprintf (F, " __fastcall__"); } @@ -571,7 +577,7 @@ unsigned TypeOf (const type* T) return CF_LONG | CF_UNSIGNED; case T_FLOAT: - case T_DOUBLE: + case T_DOUBLE: /* These two are identical in the backend */ return CF_FLOAT; diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 8bd0b0b87..0d09f7f70 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -852,39 +852,111 @@ static FuncDesc* ParseFuncDecl (const DeclSpec* Spec) +static unsigned FunctionModifierFlags (void) +/* Parse __fastcall__, __near__ and __far__ and return the matching FD_ flags */ +{ + /* Read the flags */ + unsigned Flags = FD_NONE; + while (CurTok.Tok == TOK_FASTCALL || CurTok.Tok == TOK_NEAR || CurTok.Tok == TOK_FAR) { + + /* Get the flag bit for the next token */ + unsigned F = FD_NONE; + switch (CurTok.Tok) { + case TOK_FASTCALL: F = FD_FASTCALL; break; + case TOK_NEAR: F = FD_NEAR; break; + case TOK_FAR: F = FD_FAR; break; + default: Internal ("Unexpected token: %d", CurTok.Tok); + } + + /* Remember the flag for this modifier */ + if (Flags & F) { + Error ("Duplicate modifier"); + } + Flags |= F; + + /* Skip the token */ + NextToken (); + } + + /* Sanity check */ + if ((Flags & (FD_NEAR | FD_FAR)) == (FD_NEAR | FD_FAR)) { + Error ("Cannot specify both, `__near__' and `__far__' modifiers"); + Flags &= ~(FD_NEAR | FD_FAR); + } + + /* Return the flags read */ + return Flags; +} + + + +static void ApplyFunctionModifiers (type* T, unsigned Flags) +/* Apply a set of function modifier flags to a function */ +{ + /* Get the function descriptor */ + FuncDesc* F = GetFuncDesc (T); + + /* Special check for __fastcall__ */ + if ((Flags & FD_FASTCALL) != 0 && IsVariadicFunc (T)) { + Error ("Cannot apply `__fastcall__' to functions with " + "variable parameter list"); + Flags &= ~FD_FASTCALL; + } + + /* Add the flags */ + F->Flags |= Flags; +} + + + static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode) /* Recursively process declarators. Build a type array in reverse order. */ { - + /* Pointer to something */ if (CurTok.Tok == TOK_STAR) { - type T = T_PTR; + + type T; + + /* Skip the star */ NextToken (); + /* Allow optional const or volatile qualifiers */ - T |= OptionalQualifiers (T_QUAL_NONE); + T = T_PTR | OptionalQualifiers (T_QUAL_NONE); + + /* Parse the type, the pointer points to */ Decl (Spec, D, Mode); + *D->T++ = T; return; - } else if (CurTok.Tok == TOK_LPAREN) { - NextToken (); - Decl (Spec, D, Mode); - ConsumeRParen (); - } else if (CurTok.Tok == TOK_FASTCALL) { + } + + /* Function modifiers */ + if (CurTok.Tok == TOK_FASTCALL || CurTok.Tok == TOK_NEAR || CurTok.Tok == TOK_FAR) { + /* Remember the current type pointer */ type* T = D->T; - /* Skip the fastcall token */ - NextToken (); + + /* Read the flags */ + unsigned Flags = FunctionModifierFlags (); + /* Parse the function */ Decl (Spec, D, Mode); - /* Set the fastcall flag */ + + /* Check that we have a function */ if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) { - Error ("__fastcall__ modifier applied to non function"); - } else if (IsVariadicFunc (T)) { - Error ("Cannot apply __fastcall__ to functions with variable parameter list"); + Error ("Function modifier applied to non function"); } else { - FuncDesc* F = GetFuncDesc (T); - F->Flags |= FD_FASTCALL; - } + ApplyFunctionModifiers (T, Flags); + } + + /* Done */ return; + } + + if (CurTok.Tok == TOK_LPAREN) { + NextToken (); + Decl (Spec, D, Mode); + ConsumeRParen (); } else { /* Things depend on Mode now: * - Mode == DM_NEED_IDENT means: diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 973e1c2c8..9cb450046 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 2000-2003 Ullrich von Bassewitz */ +/* Römerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -44,15 +44,18 @@ -/* Masks for the Flags field in FuncDesc */ +/* Masks for the Flags field in FuncDesc */ +#define FD_NONE 0x0000U /* No flags */ #define FD_IMPLICIT 0x0001U /* Implicitly declared function */ #define FD_EMPTY 0x0002U /* Function with empty param list */ #define FD_VOID_PARAM 0x0004U /* Function with a void param list */ #define FD_VARIADIC 0x0008U /* Function with variable param list */ #define FD_FASTCALL 0x0010U /* __fastcall__ function */ -#define FD_OLDSTYLE 0x0020U /* Old style (K&R) function */ -#define FD_OLDSTYLE_INTRET 0x0040U /* K&R func has implicit int return */ -#define FD_UNNAMED_PARAMS 0x0080U /* Function has unnamed params */ +#define FD_FAR 0x0020U /* __far__ function */ +#define FD_NEAR 0x0040U /* __near__ function */ +#define FD_OLDSTYLE 0x0100U /* Old style (K&R) function */ +#define FD_OLDSTYLE_INTRET 0x0200U /* K&R func has implicit int return */ +#define FD_UNNAMED_PARAMS 0x0400U /* Function has unnamed params */ /* Bits that must be ignored when comparing funcs */ #define FD_IGNORE (FD_IMPLICIT | FD_UNNAMED_PARAMS) diff --git a/src/common/libdefs.h b/src/common/libdefs.h index 3b2157425..e945675e1 100644 --- a/src/common/libdefs.h +++ b/src/common/libdefs.h @@ -46,7 +46,7 @@ /* Defines for magic and version */ #define LIB_MAGIC 0x7A55616E -#define LIB_VERSION 0x000A +#define LIB_VERSION 0x000B /* Size of an library file header */ #define LIB_HDR_SIZE 12 diff --git a/src/common/mmodel.c b/src/common/mmodel.c index d3187ce00..66a93ada9 100644 --- a/src/common/mmodel.c +++ b/src/common/mmodel.c @@ -36,6 +36,7 @@ #include /* common */ +#include "addrsize.h" #include "mmodel.h" @@ -56,6 +57,11 @@ static const char* MemoryModelNames[MMODEL_COUNT] = { "huge", }; +/* Address sizes for the segments */ +unsigned char CodeAddrSize = ADDR_SIZE_ABS; +unsigned char DataAddrSize = ADDR_SIZE_ABS; +unsigned char ZpAddrSize = ADDR_SIZE_ZP; + /*****************************************************************************/ @@ -82,3 +88,41 @@ mmodel_t FindMemoryModel (const char* Name) +void SetMemoryModel (mmodel_t Model) +/* Set the memory model updating the MemoryModel variables and the address + * sizes for the segments. + */ +{ + /* Remember the memory model */ + MemoryModel = Model; + + /* Set the address sizes for the segments */ + switch (MemoryModel) { + + case MMODEL_NEAR: + /* Code: near, data: near */ + CodeAddrSize = ADDR_SIZE_ABS; + DataAddrSize = ADDR_SIZE_ABS; + break; + + case MMODEL_FAR: + /* Code: far, data: near */ + CodeAddrSize = ADDR_SIZE_FAR; + DataAddrSize = ADDR_SIZE_ABS; + break; + + case MMODEL_HUGE: + /* Code: far, data: far */ + CodeAddrSize = ADDR_SIZE_FAR; + DataAddrSize = ADDR_SIZE_FAR; + break; + + default: + break; + } + + /* Zeropage is always zeropage */ + ZpAddrSize = ADDR_SIZE_ZP; +} + + diff --git a/src/common/mmodel.h b/src/common/mmodel.h index fc66c47f9..098d03412 100644 --- a/src/common/mmodel.h +++ b/src/common/mmodel.h @@ -56,8 +56,10 @@ typedef enum { /* Memory model in use */ extern mmodel_t MemoryModel; - - +/* Address sizes for the segments */ +extern unsigned char CodeAddrSize; +extern unsigned char DataAddrSize; +extern unsigned char ZpAddrSize; @@ -70,6 +72,11 @@ extern mmodel_t MemoryModel; mmodel_t FindMemoryModel (const char* Name); /* Find a memory model by name. Return MMODEL_UNKNOWN for an unknown name. */ +void SetMemoryModel (mmodel_t Model); +/* Set the memory model updating the MemoryModel variables and the address + * sizes for the segments. + */ + /* End of mmodel.h */ diff --git a/src/common/objdefs.h b/src/common/objdefs.h index ebf414a7c..24ac15430 100644 --- a/src/common/objdefs.h +++ b/src/common/objdefs.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -46,10 +46,10 @@ /* Defines for magic and version */ #define OBJ_MAGIC 0x616E7A55 -#define OBJ_VERSION 0x000A +#define OBJ_VERSION 0x000B /* Size of an object file header */ -#define OBJ_HDR_SIZE (20*4) +#define OBJ_HDR_SIZE (22*4) /* Flag bits */ #define OBJ_FLAGS_DBGINFO 0x0001 /* File has debug info */ @@ -80,6 +80,8 @@ struct ObjHeader { unsigned long StrPoolSize; /* 32: Size of string pool */ unsigned long AssertOffs; /* 32: Offset to assertion table */ unsigned long AssertSize; /* 32: Size of assertion table */ + unsigned long ScopeOffs; /* 32: Offset into scope table */ + unsigned long ScopeSize; /* 32: Size of scope table */ }; diff --git a/src/common/symdefs.h b/src/common/symdefs.h index bcfabfd6a..b0d4bf643 100644 --- a/src/common/symdefs.h +++ b/src/common/symdefs.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ömerstraße 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -48,14 +48,6 @@ -/* Import size */ -#define IMP_ABS 0x00 /* Import as normal value */ -#define IMP_ZP 0x01 /* Import as zero page symbol */ -#define IMP_MASK_SIZE 0x01 /* Size mask */ - -#define IS_IMP_ABS(x) (((x) & IMP_MASK_SIZE) == IMP_ABS) -#define IS_IMP_ZP(x) (((x) & IMP_MASK_SIZE) == IMP_ZP) - /* Number of module constructor/destructor declarations for an export */ #define EXP_CONDES_MASK 0x07 @@ -63,14 +55,6 @@ #define GET_EXP_CONDES_COUNT(x) ((x) & EXP_CONDES_MASK) #define INC_EXP_CONDES_COUNT(x) ((x)++) -/* Export size */ -#define EXP_ABS 0x00 /* Export as normal value */ -#define EXP_ZP 0x08 /* Export as zero page value */ -#define EXP_MASK_SIZE 0x08 /* Size mask */ - -#define IS_EXP_ABS(x) (((x) & EXP_MASK_SIZE) == EXP_ABS) -#define IS_EXP_ZP(x) (((x) & EXP_MASK_SIZE) == EXP_ZP) - /* Export value type */ #define EXP_CONST 0x00 /* Mask bit for const values */ #define EXP_EXPR 0x10 /* Mask bit for expr values */ diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index 578c4d9e2..3cccc89f3 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -70,7 +70,7 @@ static DbgSym* DbgSymPool[256]; -static DbgSym* NewDbgSym (unsigned char Type, ObjData* O) +static DbgSym* NewDbgSym (unsigned char Type, unsigned char AddrSize, ObjData* O) /* Create a new DbgSym and return it */ { /* Allocate memory */ @@ -83,6 +83,7 @@ static DbgSym* NewDbgSym (unsigned char Type, ObjData* O) D->Expr = 0; D->Name = 0; D->Type = Type; + D->AddrSize = AddrSize; /* Return the new entry */ return D; @@ -139,11 +140,12 @@ static void InsertDbgSym (DbgSym* D, long Val) DbgSym* ReadDbgSym (FILE* F, ObjData* O) /* Read a debug symbol from a file, insert and return it */ { - /* Read the type */ + /* Read the type and address size */ unsigned char Type = Read8 (F); + unsigned char AddrSize = Read8 (F); /* Create a new debug symbol */ - DbgSym* D = NewDbgSym (Type, O); + DbgSym* D = NewDbgSym (Type, AddrSize, O); /* Read and assign the name */ D->Name = MakeGlobalStringId (O, ReadVar (F)); @@ -271,3 +273,4 @@ void PrintDbgSymLabels (ObjData* O, FILE* F) + diff --git a/src/ld65/dbgsyms.h b/src/ld65/dbgsyms.h index 250b50bd5..beee4ea00 100644 --- a/src/ld65/dbgsyms.h +++ b/src/ld65/dbgsyms.h @@ -65,6 +65,7 @@ struct DbgSym { ExprNode* Expr; /* Expression (0 if not def'd) */ unsigned Name; /* Name */ unsigned char Type; /* Type of symbol */ + unsigned char AddrSize; /* Address size of symbol */ }; diff --git a/src/ld65/exports.c b/src/ld65/exports.c index e8d513b6d..937b3379e 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -38,6 +38,7 @@ #include /* common */ +#include "addrsize.h" #include "check.h" #include "coll.h" #include "hashstr.h" @@ -90,12 +91,13 @@ static Export** ExpPool = 0; /* Exports array */ -static Export* NewExport (unsigned char Type, unsigned Name, ObjData* Obj); +static Export* NewExport (unsigned char Type, unsigned char AddrSize, + unsigned Name, ObjData* Obj); /* Create a new export and initialize it */ -static Import* NewImport (unsigned char Type, ObjData* Obj) +static Import* NewImport (unsigned char AddrSize, ObjData* Obj) /* Create a new import and initialize it */ { /* Allocate memory */ @@ -107,7 +109,7 @@ static Import* NewImport (unsigned char Type, ObjData* Obj) I->Exp = 0; I->Name = INVALID_STRING_ID; I->Flags = 0; - I->Type = Type; + I->AddrSize = AddrSize; /* Return the new structure */ return I; @@ -129,7 +131,7 @@ void InsertImport (Import* I) /* Search through the list in that slot and print matching duplicates */ if (HashTab[Hash] == 0) { /* The slot is empty, we need to insert a dummy export */ - E = HashTab[Hash] = NewExport (0, Name, 0); + E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0); ++ExpCount; } else { E = HashTab [Hash]; @@ -140,7 +142,7 @@ 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->Next = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0); E = E->Next; /* Point to dummy */ ++ExpCount; /* One export more */ break; @@ -189,15 +191,11 @@ Import* ReadImport (FILE* F, ObjData* Obj) { Import* I; - /* Read the import type and check it */ - unsigned char Type = Read8 (F); - if (Type != IMP_ZP && Type != IMP_ABS) { - Error ("Unknown import type in module `%s': %02X", - GetObjFileName (Obj), Type); - } + /* Read the import address size */ + unsigned char AddrSize = Read8 (F); /* Create a new import */ - I = NewImport (Type, Obj); + I = NewImport (AddrSize, Obj); /* Read the name */ I->Name = MakeGlobalStringId (Obj, ReadVar (F)); @@ -205,6 +203,26 @@ Import* ReadImport (FILE* F, ObjData* Obj) /* Read the file position */ ReadFilePos (F, &I->Pos); + /* Check the address size */ + if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) { + /* Beware: This function may be called in cases where the object file + * is not read completely into memory. In this case, the file list is + * invalid. Be sure not to access it in this case. + */ + if (ObjHasFiles (I->Obj)) { + Error ("Invalid import size in for `%s', imported from %s(%lu): 0x%02X", + GetString (I->Name), + GetSourceFileName (I->Obj, I->Pos.Name), + I->Pos.Line, + I->AddrSize); + } else { + Error ("Invalid import size in for `%s', imported from %s: 0x%02X", + GetString (I->Name), + GetObjFileName (I->Obj), + I->AddrSize); + } + } + /* Return the new import */ return I; } @@ -217,7 +235,8 @@ Import* ReadImport (FILE* F, ObjData* Obj) -static Export* NewExport (unsigned char Type, unsigned Name, ObjData* Obj) +static Export* NewExport (unsigned char Type, unsigned char AddrSize, + unsigned Name, ObjData* Obj) /* Create a new export and initialize it */ { /* Allocate memory */ @@ -232,6 +251,7 @@ static Export* NewExport (unsigned char Type, unsigned Name, ObjData* Obj) E->ImpList = 0; E->Expr = 0; E->Type = Type; + E->AddrSize = AddrSize; memset (E->ConDes, 0, sizeof (E->ConDes)); /* Return the new entry */ @@ -335,15 +355,17 @@ void InsertExport (Export* E) Export* ReadExport (FILE* F, ObjData* O) /* Read an export from a file */ { - unsigned char Type; unsigned ConDesCount; Export* E; /* Read the type */ - Type = Read8 (F); + unsigned char Type = Read8 (F); + + /* Read the address size */ + unsigned char AddrSize = Read8 (F); /* Create a new export without a name */ - E = NewExport (Type, INVALID_STRING_ID, O); + E = NewExport (Type, AddrSize, INVALID_STRING_ID, O); /* Read the constructor/destructor decls if we have any */ ConDesCount = GET_EXP_CONDES_COUNT (Type); @@ -391,7 +413,7 @@ Export* CreateConstExport (unsigned Name, long Value) /* Create an export for a literal date */ { /* Create a new export */ - Export* E = NewExport (EXP_ABS | EXP_CONST | EXP_EQUATE, Name, 0); + Export* E = NewExport (EXP_CONST | EXP_EQUATE, ADDR_SIZE_ABS, Name, 0); /* Assign the value */ E->Expr = LiteralExpr (Value, 0); @@ -409,7 +431,7 @@ Export* CreateMemoryExport (unsigned Name, Memory* Mem, unsigned long Offs) /* Create an relative export for a memory area offset */ { /* Create a new export */ - Export* E = NewExport (EXP_ABS | EXP_EXPR | EXP_LABEL, Name, 0); + Export* E = NewExport (EXP_EXPR | EXP_LABEL, ADDR_SIZE_ABS, Name, 0); /* Assign the value */ E->Expr = MemoryExpr (Mem, Offs, 0); @@ -427,7 +449,7 @@ Export* CreateSegmentExport (unsigned Name, Segment* Seg, unsigned long Offs) /* Create a relative export to a segment */ { /* Create a new export */ - Export* E = NewExport (EXP_ABS | EXP_EXPR | EXP_LABEL, Name, 0); + Export* E = NewExport (EXP_EXPR | EXP_LABEL, Seg->AddrSize, Name, 0); /* Assign the value */ E->Expr = SegmentExpr (Seg, Offs, 0); @@ -445,7 +467,7 @@ Export* CreateSectionExport (unsigned Name, Section* Sec, unsigned long Offs) /* Create a relative export to a section */ { /* Create a new export */ - Export* E = NewExport (EXP_ABS | EXP_EXPR | EXP_LABEL, Name, 0); + Export* E = NewExport (EXP_EXPR | EXP_LABEL, Sec->AddrSize, Name, 0); /* Assign the value */ E->Expr = SectionExpr (Sec, Offs, 0); @@ -529,13 +551,12 @@ static void CheckSymType (const Export* E) { /* External with matching imports */ Import* Imp = E->ImpList; - int ZP = IS_EXP_ZP (E->Type); while (Imp) { - if (ZP != IS_IMP_ZP (Imp->Type)) { + if (E->AddrSize != Imp->AddrSize) { /* Export is ZP, import is abs or the other way round */ if (E->Obj) { /* User defined export */ - Warning ("Type mismatch for `%s', export in " + Warning ("Address size mismatch for `%s', export in " "%s(%lu), import in %s(%lu)", GetString (E->Name), GetSourceFileName (E->Obj, E->Pos.Name), @@ -544,7 +565,7 @@ static void CheckSymType (const Export* E) Imp->Pos.Line); } else { /* Export created by the linker */ - Warning ("Type mismatch for `%s', imported from %s(%lu)", + Warning ("Address size mismatch for `%s', imported from %s(%lu)", GetString (E->Name), GetSourceFileName (Imp->Obj, Imp->Pos.Name), Imp->Pos.Line); @@ -656,6 +677,21 @@ void CheckExports (ExpCheckFunc F, void* Data) +static char GetAddrSizeCode (unsigned char AddrSize) +/* Get a one char code for the address size */ +{ + switch (AddrSize) { + case ADDR_SIZE_ZP: return 'Z'; + case ADDR_SIZE_ABS: return 'A'; + case ADDR_SIZE_FAR: return 'F'; + case ADDR_SIZE_LONG: return 'L'; + default: + Internal ("Invalid address size: %u", AddrSize); + } +} + + + void PrintExportMap (FILE* F) /* Print an export map to the given file */ { @@ -675,7 +711,7 @@ void PrintExportMap (FILE* F) GetExportVal (E), E->ImpCount? 'R' : ' ', IS_EXP_LABEL (E->Type)? 'L' : 'E', - IS_EXP_ZP (E->Type)? 'Z' : ' ', + GetAddrSizeCode (E->AddrSize), IS_EXP_CONDES (E->Type)? 'I' : ' '); if (++Count == 2) { Count = 0; diff --git a/src/ld65/exports.h b/src/ld65/exports.h index 97a6eea63..bfdca3c1f 100644 --- a/src/ld65/exports.h +++ b/src/ld65/exports.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -66,7 +66,7 @@ struct Import { struct Export* Exp; /* Matching export for this import */ unsigned Name; /* Name if not in table */ unsigned char Flags; /* Generic flags */ - unsigned char Type; /* Type of import */ + unsigned char AddrSize; /* Address size of import */ }; @@ -83,6 +83,7 @@ struct Export { FilePos Pos; /* File position of definition */ ExprNode* Expr; /* Expression (0 if not def'd) */ unsigned char Type; /* Type of export */ + unsigned char AddrSize; /* Address size of export */ unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */ }; @@ -188,7 +189,7 @@ void CircularRefError (const Export* E); /* End of exports.h */ #endif - + diff --git a/src/ld65/library.c b/src/ld65/library.c index 55c3656bc..f5e2bb2da 100644 --- a/src/ld65/library.c +++ b/src/ld65/library.c @@ -1,13 +1,13 @@ /*****************************************************************************/ -/* */ +/* */ /* library.c */ -/* */ +/* */ /* Library data structures and helpers for the ld65 linker */ -/* */ -/* */ -/* */ +/* */ +/* */ +/* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -107,6 +107,8 @@ static void LibReadObjHeader (ObjData* O, const char* LibName) O->Header.StrPoolSize = Read32 (Lib); O->Header.AssertOffs = Read32 (Lib); O->Header.AssertSize = Read32 (Lib); + O->Header.ScopeOffs = Read32 (Lib); + O->Header.ScopeSize = Read32 (Lib); } @@ -261,6 +263,9 @@ void LibAdd (FILE* F, const char* Name) /* Read the assertions from the object file */ ObjReadAssertions (Lib, O->Start + O->Header.AssertOffs, O); + /* Read the scope table from the object file */ + ObjReadScopes (Lib, O->Start + O->Header.ScopeOffs, O); + /* Seek to the start of the segment list and read the segments. * This must be last, since the data here may reference other * stuff. diff --git a/src/ld65/objdata.c b/src/ld65/objdata.c index 7e5209331..ebdf3948f 100644 --- a/src/ld65/objdata.c +++ b/src/ld65/objdata.c @@ -90,6 +90,8 @@ ObjData* NewObjData (void) O->Strings = 0; O->AssertionCount = 0; O->Assertions = 0; + O->ScopeCount = 0; + O->Scopes = 0; /* Return the new entry */ return O; @@ -192,8 +194,10 @@ const char* GetSourceFileName (const ObjData* O, unsigned Index) /* Check the parameter */ if (Index >= O->FileCount) { - Error ("Invalid file index (%u) in module `%s' (input file corrupt?)", + /* Error() will terminate the program */ + Warning ("Invalid file index (%u) in module `%s' (input file corrupt?)", Index, GetObjFileName (O)); + return "[invalid]"; /* ### */ } /* Return the name */ diff --git a/src/ld65/objdata.h b/src/ld65/objdata.h index 5adbce6b3..0598c50f6 100644 --- a/src/ld65/objdata.h +++ b/src/ld65/objdata.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -40,6 +40,7 @@ /* common */ #include "coll.h" +#include "inline.h" #include "objdefs.h" @@ -61,7 +62,7 @@ struct ObjData { unsigned LibName; /* Name of library */ unsigned long MTime; /* Time of last modification */ ObjHeader Header; /* Header of file */ - unsigned long Start; /* Start offset of data in library */ + unsigned long Start; /* Start offset of data in library */ unsigned Flags; unsigned FileCount; /* Input file count */ struct FileInfo** Files; /* List of input files */ @@ -79,6 +80,8 @@ struct ObjData { unsigned* Strings; /* List of global string indices */ unsigned AssertionCount; /* Count of module assertions */ struct Assertion** Assertions; /* List of module assertions */ + unsigned ScopeCount; /* Count of scopes */ + struct Scope** Scopes; /* List of scopes */ }; @@ -124,6 +127,16 @@ const char* GetObjFileName (const ObjData* O); * file is NULL. */ +#if defined(HAVE_INLINE) +INLINE int ObjHasFiles (const ObjData* O) +/* Return true if the files list does exist */ +{ + return (O != 0 && O->Files != 0); +} +#else +# defined ObjHasFiles(O) ((O) != 0 && (O)->Files != 0) +#endif + const char* GetSourceFileName (const ObjData* O, unsigned Index); /* Get the name of the source file with the given index. If O is NULL, return * "[linker generated]" as the file name. diff --git a/src/ld65/objfile.c b/src/ld65/objfile.c index a8c389cd7..bea9fda69 100644 --- a/src/ld65/objfile.c +++ b/src/ld65/objfile.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -104,6 +104,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) H->StrPoolSize = Read32 (Obj); H->AssertOffs = Read32 (Obj); H->AssertSize = Read32 (Obj); + H->ScopeOffs = Read32 (Obj); + H->ScopeSize = Read32 (Obj); } @@ -252,6 +254,24 @@ void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O) +void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O) +/* Read the scope table from a file at the given offset */ +{ + unsigned I; + + /* Seek to the correct position */ + FileSetPos (F, Pos); + + /* Read the data */ + O->ScopeCount = ReadVar (F); + O->Scopes = xmalloc (O->ScopeCount * sizeof (O->Scopes[0])); + for (I = 0; I < O->ScopeCount; ++I) { + O->Scopes[I] = 0; /* ReadScope (F, O); ### not implemented */ + } +} + + + void ObjAdd (FILE* Obj, const char* Name) /* Add an object file to the module list */ { @@ -288,6 +308,9 @@ void ObjAdd (FILE* Obj, const char* Name) /* Read the assertions from the object file */ ObjReadAssertions (Obj, O->Header.AssertOffs, O); + /* Read the scope table from the object file */ + ObjReadScopes (Obj, O->Header.ScopeOffs, O); + /* Read the segment list from the object file. This must be last, since * the expressions stored in the code may reference segments or imported * symbols. diff --git a/src/ld65/objfile.h b/src/ld65/objfile.h index f3bdf4cac..f26d5bdd5 100644 --- a/src/ld65/objfile.h +++ b/src/ld65/objfile.h @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -78,6 +78,9 @@ void ObjReadStrPool (FILE* F, unsigned long Pos, ObjData* O); void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O); /* Read the assertions from a file at the given offset */ +void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O); +/* Read the scope table from a file at the given offset */ + void ObjAdd (FILE* F, const char* Name); /* Add an object file to the module list */ diff --git a/src/od65/dump.c b/src/od65/dump.c index 7c7b880b9..208c4bfbc 100644 --- a/src/od65/dump.c +++ b/src/od65/dump.c @@ -172,23 +172,17 @@ static const char* GetExportFlags (unsigned Flags, const unsigned char* ConDes) unsigned Count; unsigned I; - /* Adressing mode */ - TypeDesc[0] = '\0'; - switch (Flags & EXP_MASK_SIZE) { - case EXP_ABS: strcat (TypeDesc, "EXP_ABS"); break; - case EXP_ZP: strcat (TypeDesc, "EXP_ZP"); break; - } - /* Type of expression */ + TypeDesc[0] = '\0'; switch (Flags & EXP_MASK_VAL) { - case EXP_CONST: strcat (TypeDesc, ",EXP_CONST"); break; - case EXP_EXPR: strcat (TypeDesc, ",EXP_EXPR"); break; + case EXP_CONST: strcat (TypeDesc, "EXP_CONST"); break; + case EXP_EXPR: strcat (TypeDesc, "EXP_EXPR"); break; } /* Constructor/destructor declarations */ T = TypeDesc + strlen (TypeDesc); Count = GET_EXP_CONDES_COUNT (Flags); - if (Count > 0) { + if (Count > 0 && ConDes) { T += sprintf (T, ",EXP_CONDES="); for (I = 0; I < Count; ++I) { unsigned Type = CD_GET_TYPE (ConDes[I]); @@ -490,26 +484,18 @@ void DumpObjImports (FILE* F, unsigned long Offset) /* Read and print all imports */ for (I = 0; I < Count; ++I) { - const char* TypeDesc; - /* Read the data for one import */ - unsigned char Type = Read8 (F); - const char* Name = GetString (&StrPool, ReadVar (F)); - unsigned Len = strlen (Name); + unsigned char AddrSize = Read8 (F); + const char* Name = GetString (&StrPool, ReadVar (F)); + unsigned Len = strlen (Name); ReadFilePos (F, &Pos); - /* Get a description for the type */ - switch (Type) { - case IMP_ZP: TypeDesc = "IMP_ZP"; break; - case IMP_ABS: TypeDesc = "IMP_ABS"; break; - default: TypeDesc = "IMP_UNKNOWN"; break; - } - /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ - printf (" Type:%22s0x%02X (%s)\n", "", Type, TypeDesc); + printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, + AddrSizeToStr (AddrSize)); printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); } @@ -551,14 +537,14 @@ void DumpObjExports (FILE* F, unsigned long Offset) unsigned long Value = 0; int HaveValue; - unsigned char Type; unsigned char ConDes [CD_TYPE_COUNT]; const char* Name; unsigned Len; /* Read the data for one export */ - Type = Read8 (F); + unsigned char Type = Read8 (F); + unsigned char AddrSize = Read8 (F); ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type)); Name = GetString (&StrPool, ReadVar (F)); Len = strlen (Name); @@ -576,6 +562,8 @@ void DumpObjExports (FILE* F, unsigned long Offset) /* Print the data */ printf (" Type:%22s0x%02X (%s)\n", "", Type, GetExportFlags (Type, ConDes)); + printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, + AddrSizeToStr (AddrSize)); printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); if (HaveValue) { printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value); @@ -626,17 +614,13 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset) for (I = 0; I < Count; ++I) { unsigned long Value = 0; - int HaveValue; - unsigned char Type; - unsigned char ConDes [CD_TYPE_COUNT]; - const char* Name; - unsigned Len; + int HaveValue; /* Read the data for one symbol */ - Type = Read8 (F); - ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type)); - Name = GetString (&StrPool, ReadVar (F)); - Len = strlen (Name); + unsigned char Type = Read8 (F); + unsigned char AddrSize = Read8 (F); + const char* Name = GetString (&StrPool, ReadVar (F)); + unsigned Len = strlen (Name); if (IS_EXP_EXPR (Type)) { SkipExpr (F); HaveValue = 0; @@ -650,7 +634,9 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset) printf (" Index:%27u\n", I); /* Print the data */ - printf (" Type:%22s0x%02X (%s)\n", "", Type, GetExportFlags (Type, ConDes)); + printf (" Type:%22s0x%02X (%s)\n", "", Type, GetExportFlags (Type, 0)); + printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize, + AddrSizeToStr (AddrSize)); printf (" Name:%*s\"%s\"\n", 24-Len, "", Name); if (HaveValue) { printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value); diff --git a/src/od65/fileio.c b/src/od65/fileio.c index 43a34ad92..4a061af94 100644 --- a/src/od65/fileio.c +++ b/src/od65/fileio.c @@ -7,7 +7,7 @@ /* */ /* */ /* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* Römerstraße 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -227,6 +227,8 @@ void ReadObjHeader (FILE* F, ObjHeader* H) H->StrPoolSize = Read32 (F); H->AssertOffs = Read32 (F); H->AssertSize = Read32 (F); + H->ScopeOffs = Read32 (F); + H->ScopeSize = Read32 (F); } -- 2.39.5