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
This commit is contained in:
cuz
2003-11-28 22:12:14 +00:00
parent e3eea961c2
commit 8f9a21ae3f
35 changed files with 589 additions and 254 deletions

View File

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

View File

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

View File

@@ -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 {
AbEnd ("Unknown memory model: %s", Arg);
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);

View File

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

View File

@@ -7,7 +7,7 @@
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* R<>merstrasse 52 */
/* R<>merstra<EFBFBD>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 */

View File

@@ -37,6 +37,7 @@
#include <errno.h>
/* 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 */
{

View File

@@ -7,7 +7,7 @@
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* R<>merstrasse 52 */
/* R<>merstra<EFBFBD>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 */

View File

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

View File

@@ -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 ();
}