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:
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<>merstra<72>e 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -37,6 +37,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "cmdline.h"
|
||||||
|
|
||||||
|
/* ar65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -52,7 +56,7 @@ void Warning (const char* Format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
fprintf (stderr, "Warning: ");
|
fprintf (stderr, "%s: Warning: ", ProgName);
|
||||||
vfprintf (stderr, Format, ap);
|
vfprintf (stderr, Format, ap);
|
||||||
putc ('\n', stderr);
|
putc ('\n', stderr);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
@@ -65,7 +69,7 @@ void Error (const char* Format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
fprintf (stderr, "Error: ");
|
fprintf (stderr, "%s: Error: ", ProgName);
|
||||||
vfprintf (stderr, Format, ap);
|
vfprintf (stderr, Format, ap);
|
||||||
putc ('\n', stderr);
|
putc ('\n', stderr);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
@@ -79,7 +83,7 @@ void Internal (const char* Format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
fprintf (stderr, "Internal error: ");
|
fprintf (stderr, "%s: Internal error: ", ProgName);
|
||||||
vfprintf (stderr, Format, ap);
|
vfprintf (stderr, Format, ap);
|
||||||
putc ('\n', stderr);
|
putc ('\n', stderr);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<EFBFBD>merstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -408,20 +408,20 @@ static void LibCheckExports (ObjData* O)
|
|||||||
Print (stdout, 1, "Module `%s' (%u exports):\n", O->Name, Count);
|
Print (stdout, 1, "Module `%s' (%u exports):\n", O->Name, Count);
|
||||||
while (Count--) {
|
while (Count--) {
|
||||||
|
|
||||||
unsigned char Tag;
|
|
||||||
const char* Name;
|
const char* Name;
|
||||||
|
|
||||||
/* Get the export tag */
|
/* Get the export tag and skip the address size */
|
||||||
Tag = *Exports++;
|
unsigned char Type = *Exports++;
|
||||||
|
++Exports;
|
||||||
|
|
||||||
/* condes decls may follow */
|
/* condes decls may follow */
|
||||||
Exports += GET_EXP_CONDES_COUNT (Tag);
|
Exports += GET_EXP_CONDES_COUNT (Type);
|
||||||
|
|
||||||
/* Next thing is index of name of symbol */
|
/* Next thing is index of name of symbol */
|
||||||
Name = GetObjString (O, GetVar (&Exports));
|
Name = GetObjString (O, GetVar (&Exports));
|
||||||
|
|
||||||
/* Skip value of symbol */
|
/* Skip value of symbol */
|
||||||
if (Tag & EXP_EXPR) {
|
if (Type & EXP_EXPR) {
|
||||||
/* Expression tree */
|
/* Expression tree */
|
||||||
SkipExpr (&Exports);
|
SkipExpr (&Exports);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2001 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<>merstra<72>e 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -122,7 +122,7 @@ int main (int argc, char* argv [])
|
|||||||
|
|
||||||
case 'V':
|
case 'V':
|
||||||
fprintf (stderr,
|
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);
|
VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -113,6 +113,8 @@ void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
|||||||
H->StrPoolSize = Read32 (Obj);
|
H->StrPoolSize = Read32 (Obj);
|
||||||
H->AssertOffs = Read32 (Obj);
|
H->AssertOffs = Read32 (Obj);
|
||||||
H->AssertSize = Read32 (Obj);
|
H->AssertSize = Read32 (Obj);
|
||||||
|
H->ScopeOffs = Read32 (Obj);
|
||||||
|
H->ScopeSize = Read32 (Obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -141,6 +143,8 @@ void ObjWriteHeader (FILE* Obj, ObjHeader* H)
|
|||||||
Write32 (Obj, H->StrPoolSize);
|
Write32 (Obj, H->StrPoolSize);
|
||||||
Write32 (Obj, H->AssertOffs);
|
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;
|
H.LineInfoOffs = LibCopyTo (Obj, H.LineInfoSize) - O->Start;
|
||||||
fseek (Obj, H.AssertOffs, SEEK_SET);
|
fseek (Obj, H.AssertOffs, SEEK_SET);
|
||||||
H.AssertOffs = LibCopyTo (Obj, H.AssertSize) - O->Start;
|
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 */
|
/* Calculate the amount of data written */
|
||||||
O->Size = ftell (NewLib) - O->Start;
|
O->Size = ftell (NewLib) - O->Start;
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ unsigned char SmartMode = 0; /* Smart mode */
|
|||||||
unsigned char DbgSyms = 0; /* Add debug symbols */
|
unsigned char DbgSyms = 0; /* Add debug symbols */
|
||||||
unsigned char Listing = 0; /* Create listing file */
|
unsigned char Listing = 0; /* Create listing file */
|
||||||
unsigned char LineCont = 0; /* Allow line continuation */
|
unsigned char LineCont = 0; /* Allow line continuation */
|
||||||
unsigned char DefAddrSize = ADDR_SIZE_ABS; /* Default address size */
|
|
||||||
|
|
||||||
/* Emulation features */
|
/* Emulation features */
|
||||||
unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */
|
unsigned char DollarIsPC = 0; /* Allow the $ symbol as current PC */
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ extern unsigned char SmartMode; /* Smart mode */
|
|||||||
extern unsigned char DbgSyms; /* Add debug symbols */
|
extern unsigned char DbgSyms; /* Add debug symbols */
|
||||||
extern unsigned char Listing; /* Create listing file */
|
extern unsigned char Listing; /* Create listing file */
|
||||||
extern unsigned char LineCont; /* Allow line continuation */
|
extern unsigned char LineCont; /* Allow line continuation */
|
||||||
extern unsigned char DefAddrSize; /* Default address size */
|
|
||||||
|
|
||||||
/* Emulation features */
|
/* Emulation features */
|
||||||
extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */
|
extern unsigned char DollarIsPC; /* Allow the $ symbol as current PC */
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include "addrsize.h"
|
#include "addrsize.h"
|
||||||
#include "chartype.h"
|
#include "chartype.h"
|
||||||
#include "cmdline.h"
|
#include "cmdline.h"
|
||||||
|
#include "mmodel.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "tgttrans.h"
|
#include "tgttrans.h"
|
||||||
@@ -143,6 +144,7 @@ static void DefineSymbol (const char* Def)
|
|||||||
long Val;
|
long Val;
|
||||||
char SymName [MAX_STR_LEN+1];
|
char SymName [MAX_STR_LEN+1];
|
||||||
SymEntry* Sym;
|
SymEntry* Sym;
|
||||||
|
ExprNode* Expr;
|
||||||
|
|
||||||
|
|
||||||
/* The symbol must start with a character or underline */
|
/* 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);
|
AbEnd ("`%s' is already defined", SymName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate an expression for the symbol */
|
||||||
|
Expr = GenLiteralExpr (Val);
|
||||||
|
|
||||||
/* Mark the symbol as defined */
|
/* 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 */
|
/* Set the memory model */
|
||||||
{
|
{
|
||||||
if (strcmp (Arg, "near") == 0) {
|
mmodel_t M;
|
||||||
DefAddrSize = ADDR_SIZE_ABS;
|
|
||||||
} else if (strcmp (Arg, "far") == 0) {
|
/* Check the current memory model */
|
||||||
DefAddrSize = ADDR_SIZE_FAR;
|
if (MemoryModel != MMODEL_UNKNOWN) {
|
||||||
} else {
|
AbEnd ("Cannot use option `%s' twice", Opt);
|
||||||
AbEnd ("Unknown memory model: %s", Arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
/* Intialize the target translation tables */
|
||||||
TgtTranslateInit ();
|
TgtTranslateInit ();
|
||||||
|
|
||||||
|
/* Initialize the segments */
|
||||||
|
InitSegments ();
|
||||||
|
|
||||||
/* Initialize the scanner, open the input file */
|
/* Initialize the scanner, open the input file */
|
||||||
InitScanner (InFile);
|
InitScanner (InFile);
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,9 @@ static ObjHeader Header = {
|
|||||||
0, /* 32: Offset to string pool */
|
0, /* 32: Offset to string pool */
|
||||||
0, /* 32: Size of string pool */
|
0, /* 32: Size of string pool */
|
||||||
0, /* 32: Offset to assertion table */
|
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.StrPoolSize);
|
||||||
ObjWrite32 (Header.AssertOffs);
|
ObjWrite32 (Header.AssertOffs);
|
||||||
ObjWrite32 (Header.AssertSize);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -139,6 +139,12 @@ void ObjStartAssertions (void);
|
|||||||
void ObjEndAssertions (void);
|
void ObjEndAssertions (void);
|
||||||
/* Mark the end of the assertion table */
|
/* 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 */
|
/* End of objfile.h */
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "mmodel.h"
|
||||||
#include "segnames.h"
|
#include "segnames.h"
|
||||||
#include "xmalloc.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)
|
void WriteSegments (void)
|
||||||
/* Write the segment data to the object file */
|
/* Write the segment data to the object file */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -146,6 +146,9 @@ void SegCheck (void);
|
|||||||
void SegDump (void);
|
void SegDump (void);
|
||||||
/* Dump the contents of all segments */
|
/* Dump the contents of all segments */
|
||||||
|
|
||||||
|
void InitSegments (void);
|
||||||
|
/* Initialize segments */
|
||||||
|
|
||||||
void WriteSegments (void);
|
void WriteSegments (void);
|
||||||
/* Write the segment data to the object file */
|
/* Write the segment data to the object file */
|
||||||
|
|
||||||
|
|||||||
@@ -213,9 +213,10 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
|||||||
/* Set the symbol value */
|
/* Set the symbol value */
|
||||||
S->V.Expr = Expr;
|
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) {
|
if (S->Flags & SF_GLOBAL) {
|
||||||
S->ExportSize = S->AddrSize;
|
|
||||||
S->Flags = (S->Flags & ~SF_GLOBAL) | SF_EXPORT;
|
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 */
|
/* Use the real size of the symbol */
|
||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize > S->ExportSize) {
|
} 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),
|
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
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 this is not a local symbol, remember it as the last global one */
|
||||||
if (!IsLocalNameId (S->Name)) {
|
if (!IsLocalNameId (S->Name)) {
|
||||||
SymLast = S;
|
SymLast = S;
|
||||||
@@ -271,13 +265,15 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
return;
|
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) {
|
if (AddrSize == ADDR_SIZE_DEFAULT) {
|
||||||
AddrSize = DefAddrSize;
|
AddrSize = GetCurrentSegAddrSize ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the symbol is marked as import or global, check the symbol flags,
|
/* If the symbol is marked as import or global, check the address size,
|
||||||
* then do silently remove the global flag
|
* then do silently remove the global flag.
|
||||||
*/
|
*/
|
||||||
if (S->Flags & SF_IMPORT) {
|
if (S->Flags & SF_IMPORT) {
|
||||||
if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
|
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->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));
|
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
||||||
}
|
}
|
||||||
S->Flags &= ~SF_GLOBAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the symbol data */
|
/* Set the symbol data */
|
||||||
@@ -317,23 +313,21 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
return;
|
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) {
|
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;
|
S->Flags &= ~SF_GLOBAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the symbol was already marked as an export, check if this was done
|
/* If the symbol was already marked as an export, but wasn't defined
|
||||||
* specifiying the same address size. If the old spec had no explicit
|
* before, the address sizes in both definitions must match.
|
||||||
* address size, use the new one.
|
|
||||||
*/
|
*/
|
||||||
if (S->Flags & SF_EXPORT) {
|
if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) {
|
||||||
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
|
if (S->ExportSize != AddrSize) {
|
||||||
S->ExportSize = AddrSize;
|
|
||||||
} else if (AddrSize == ADDR_SIZE_DEFAULT) {
|
|
||||||
AddrSize = S->ExportSize;
|
|
||||||
}
|
|
||||||
if (S->ExportSize != ADDR_SIZE_DEFAULT && S->ExportSize != AddrSize) {
|
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
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 */
|
/* No export size given, use the real size of the symbol */
|
||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize > S->ExportSize) {
|
} 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),
|
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
AddrSizeToStr (S->ExportSize));
|
||||||
}
|
}
|
||||||
@@ -370,30 +365,53 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the symbol is already marked as import or export, check the
|
/* If the symbol is already marked as import, the address size must match.
|
||||||
* size of the definition, then bail out.
|
* Apart from that, ignore the global declaration.
|
||||||
*/
|
*/
|
||||||
if (S->Flags & SF_IMPORT) {
|
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));
|
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the symbol is already an export: If it is not defined, the address
|
||||||
|
* sizes must match.
|
||||||
|
*/
|
||||||
if (S->Flags & SF_EXPORT) {
|
if (S->Flags & SF_EXPORT) {
|
||||||
/* If the old symbol had no explicit address size spec, use the
|
if ((S->Flags & SF_DEFINED) == 0) {
|
||||||
* new one.
|
/* Symbol is undefined */
|
||||||
*/
|
if (AddrSize != S->ExportSize) {
|
||||||
if (S->ExportSize == ADDR_SIZE_DEFAULT) {
|
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
||||||
S->ExportSize = AddrSize;
|
}
|
||||||
|
} 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) {
|
if (AddrSize != S->ExportSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the symbol is already defined, export it. Otherwise mark it as
|
/* If we come here, the symbol was neither declared as export, import or
|
||||||
* global.
|
* 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) {
|
if (S->Flags & SF_DEFINED) {
|
||||||
/* The symbol is defined, export it */
|
/* 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 */
|
/* No export size given, use the real size of the symbol */
|
||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize > S->ExportSize) {
|
} 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),
|
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
AddrSizeToStr (S->ExportSize));
|
||||||
}
|
}
|
||||||
S->Flags |= (SF_EXPORT | Flags);
|
S->Flags |= (SF_EXPORT | Flags);
|
||||||
S->ExportSize = AddrSize;
|
|
||||||
} else {
|
} 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;
|
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.
|
* priority value is the same as the old one.
|
||||||
*/
|
*/
|
||||||
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
||||||
if (S->ConDesPrio[Type] != Prio) {
|
if (S->ConDesPrio[Type] != Prio) {
|
||||||
Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S));
|
Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
S->ConDesPrio[Type] = Prio;
|
S->ConDesPrio[Type] = Prio;
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
#include "addrsize.h"
|
#include "addrsize.h"
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "hashstr.h"
|
#include "hashstr.h"
|
||||||
|
#include "mmodel.h"
|
||||||
#include "symdefs.h"
|
#include "symdefs.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
@@ -475,6 +476,8 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
if (AutoImport) {
|
if (AutoImport) {
|
||||||
/* Mark as import, will be indexed later */
|
/* Mark as import, will be indexed later */
|
||||||
S->Flags |= SF_IMPORT;
|
S->Flags |= SF_IMPORT;
|
||||||
|
/* Use the address size for code */
|
||||||
|
S->AddrSize = CodeAddrSize;
|
||||||
} else {
|
} else {
|
||||||
/* Error */
|
/* Error */
|
||||||
PError (&S->Pos, "Symbol `%s' is undefined", GetString (S->Name));
|
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 &&
|
if ((S->Flags & (SF_TRAMPOLINE | SF_IMPORT)) == SF_IMPORT &&
|
||||||
(S->Flags & (SF_REFERENCED | SF_FORCED)) != 0) {
|
(S->Flags & (SF_REFERENCED | SF_FORCED)) != 0) {
|
||||||
|
|
||||||
if (S->AddrSize == ADDR_SIZE_ZP) {
|
ObjWrite8 (S->AddrSize);
|
||||||
ObjWrite8 (IMP_ZP);
|
|
||||||
} else {
|
|
||||||
ObjWrite8 (IMP_ABS);
|
|
||||||
}
|
|
||||||
ObjWriteVar (S->Name);
|
ObjWriteVar (S->Name);
|
||||||
ObjWritePos (&S->Pos);
|
ObjWritePos (&S->Pos);
|
||||||
}
|
}
|
||||||
@@ -645,7 +644,6 @@ void WriteExports (void)
|
|||||||
|
|
||||||
/* Get the expression bits */
|
/* Get the expression bits */
|
||||||
unsigned char ExprMask = SymIsConst (S, &ConstVal)? EXP_CONST : EXP_EXPR;
|
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;
|
ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
|
||||||
|
|
||||||
/* Count the number of ConDes types */
|
/* 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 (ExprMask);
|
||||||
|
ObjWrite8 (S->ExportSize);
|
||||||
|
|
||||||
/* Write any ConDes declarations */
|
/* Write any ConDes declarations */
|
||||||
if (GET_EXP_CONDES_COUNT (ExprMask) > 0) {
|
if (GET_EXP_CONDES_COUNT (ExprMask) > 0) {
|
||||||
@@ -674,7 +673,7 @@ void WriteExports (void)
|
|||||||
/* Write the value */
|
/* Write the value */
|
||||||
if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
|
if ((ExprMask & EXP_MASK_VAL) == EXP_CONST) {
|
||||||
/* Constant value */
|
/* Constant value */
|
||||||
ObjWrite32 (ConstVal);
|
ObjWrite32 (ConstVal);
|
||||||
} else {
|
} else {
|
||||||
/* Expression involved */
|
/* Expression involved */
|
||||||
WriteExpr (S->V.Expr);
|
WriteExpr (S->V.Expr);
|
||||||
@@ -704,34 +703,36 @@ void WriteDbgSyms (void)
|
|||||||
/* Check if debug info is requested */
|
/* Check if debug info is requested */
|
||||||
if (DbgSyms) {
|
if (DbgSyms) {
|
||||||
|
|
||||||
/* Walk through the list and count the symbols */
|
/* Walk through the list and count the symbols */
|
||||||
Count = 0;
|
Count = 0;
|
||||||
S = SymList;
|
S = SymList;
|
||||||
while (S) {
|
while (S) {
|
||||||
if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
|
if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
|
||||||
++Count;
|
++Count;
|
||||||
}
|
}
|
||||||
S = S->List;
|
S = S->List;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the symbol count to the list */
|
/* Write the symbol count to the list */
|
||||||
ObjWriteVar (Count);
|
ObjWriteVar (Count);
|
||||||
|
|
||||||
/* Walk through list and write all symbols to the file */
|
/* Walk through list and write all symbols to the file */
|
||||||
S = SymList;
|
S = SymList;
|
||||||
while (S) {
|
while (S) {
|
||||||
if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
|
if ((S->Flags & SF_DBGINFOMASK) == SF_DBGINFOVAL) {
|
||||||
|
|
||||||
long ConstVal;
|
long ConstVal;
|
||||||
|
|
||||||
/* Get the expression bits */
|
/* Get the expression bits */
|
||||||
unsigned char ExprMask = (SymIsConst (S, &ConstVal))? EXP_CONST : EXP_EXPR;
|
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;
|
ExprMask |= (S->Flags & SF_LABEL)? EXP_LABEL : EXP_EQUATE;
|
||||||
|
|
||||||
/* Write the type */
|
/* Write the type */
|
||||||
ObjWrite8 (ExprMask);
|
ObjWrite8 (ExprMask);
|
||||||
|
|
||||||
|
/* Write the address size */
|
||||||
|
ObjWrite8 (S->AddrSize);
|
||||||
|
|
||||||
/* Write the name */
|
/* Write the name */
|
||||||
ObjWriteVar (S->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 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1225,8 +1225,16 @@ void CS_OutputPrologue (const CodeSeg* S, FILE* F)
|
|||||||
* segment before outputing the function label.
|
* segment before outputing the function label.
|
||||||
*/
|
*/
|
||||||
if (Func) {
|
if (Func) {
|
||||||
|
/* Get the function descriptor */
|
||||||
|
const FuncDesc* D = GetFuncDesc (Func->Type);
|
||||||
CS_PrintFunctionHeader (S, F);
|
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) {
|
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 debug info is enabled, terminate the last line number information */
|
||||||
if (DebugInfo) {
|
if (DebugInfo) {
|
||||||
fprintf (F, "\t.dbg\tline\n");
|
fputs ("\t.dbg\tline\n", F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1397,7 +1405,7 @@ void CS_GenRegInfo (CodeSeg* S)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (J->RI->Out2.RegA != Regs.RegA) {
|
if (J->RI->Out2.RegA != Regs.RegA) {
|
||||||
Regs.RegA = UNKNOWN_REGVAL;
|
Regs.RegA = UNKNOWN_REGVAL;
|
||||||
}
|
}
|
||||||
if (J->RI->Out2.RegX != Regs.RegX) {
|
if (J->RI->Out2.RegX != Regs.RegX) {
|
||||||
Regs.RegX = UNKNOWN_REGVAL;
|
Regs.RegX = UNKNOWN_REGVAL;
|
||||||
@@ -1443,7 +1451,7 @@ void CS_GenRegInfo (CodeSeg* S)
|
|||||||
/* Check the previous instruction */
|
/* Check the previous instruction */
|
||||||
switch (P->OPC) {
|
switch (P->OPC) {
|
||||||
|
|
||||||
case OP65_ADC:
|
case OP65_ADC:
|
||||||
case OP65_AND:
|
case OP65_AND:
|
||||||
case OP65_DEA:
|
case OP65_DEA:
|
||||||
case OP65_EOR:
|
case OP65_EOR:
|
||||||
@@ -1489,7 +1497,7 @@ void CS_GenRegInfo (CodeSeg* S)
|
|||||||
case OP65_CPY:
|
case OP65_CPY:
|
||||||
/* If this is an immidiate compare, the Y register has
|
/* If this is an immidiate compare, the Y register has
|
||||||
* the value of the compare later.
|
* the value of the compare later.
|
||||||
*/
|
*/
|
||||||
if (CE_KnownImm (P)) {
|
if (CE_KnownImm (P)) {
|
||||||
if (BC == BC_EQ) {
|
if (BC == BC_EQ) {
|
||||||
E->RI->Out2.RegY = (unsigned char)P->Num;
|
E->RI->Out2.RegY = (unsigned char)P->Num;
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -327,6 +327,12 @@ void PrintFuncSig (FILE* F, const char* Name, type* Type)
|
|||||||
|
|
||||||
/* Print a comment with the function signature */
|
/* Print a comment with the function signature */
|
||||||
PrintType (F, GetFuncReturn (Type));
|
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) {
|
if (D->Flags & FD_FASTCALL) {
|
||||||
fprintf (F, " __fastcall__");
|
fprintf (F, " __fastcall__");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* 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)
|
static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
||||||
/* Recursively process declarators. Build a type array in reverse order. */
|
/* Recursively process declarators. Build a type array in reverse order. */
|
||||||
{
|
{
|
||||||
|
/* Pointer to something */
|
||||||
if (CurTok.Tok == TOK_STAR) {
|
if (CurTok.Tok == TOK_STAR) {
|
||||||
type T = T_PTR;
|
|
||||||
|
type T;
|
||||||
|
|
||||||
|
/* Skip the star */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Allow optional const or volatile qualifiers */
|
/* 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);
|
Decl (Spec, D, Mode);
|
||||||
|
|
||||||
*D->T++ = T;
|
*D->T++ = T;
|
||||||
return;
|
return;
|
||||||
} else if (CurTok.Tok == TOK_LPAREN) {
|
}
|
||||||
|
|
||||||
|
/* Function modifiers */
|
||||||
|
if (CurTok.Tok == TOK_FASTCALL || CurTok.Tok == TOK_NEAR || CurTok.Tok == TOK_FAR) {
|
||||||
|
|
||||||
|
/* Remember the current type pointer */
|
||||||
|
type* T = D->T;
|
||||||
|
|
||||||
|
/* Read the flags */
|
||||||
|
unsigned Flags = FunctionModifierFlags ();
|
||||||
|
|
||||||
|
/* Parse the function */
|
||||||
|
Decl (Spec, D, Mode);
|
||||||
|
|
||||||
|
/* Check that we have a function */
|
||||||
|
if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) {
|
||||||
|
Error ("Function modifier applied to non function");
|
||||||
|
} else {
|
||||||
|
ApplyFunctionModifiers (T, Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CurTok.Tok == TOK_LPAREN) {
|
||||||
NextToken ();
|
NextToken ();
|
||||||
Decl (Spec, D, Mode);
|
Decl (Spec, D, Mode);
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
} else if (CurTok.Tok == TOK_FASTCALL) {
|
|
||||||
/* Remember the current type pointer */
|
|
||||||
type* T = D->T;
|
|
||||||
/* Skip the fastcall token */
|
|
||||||
NextToken ();
|
|
||||||
/* Parse the function */
|
|
||||||
Decl (Spec, D, Mode);
|
|
||||||
/* Set the fastcall flag */
|
|
||||||
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");
|
|
||||||
} else {
|
|
||||||
FuncDesc* F = GetFuncDesc (T);
|
|
||||||
F->Flags |= FD_FASTCALL;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
/* Things depend on Mode now:
|
/* Things depend on Mode now:
|
||||||
* - Mode == DM_NEED_IDENT means:
|
* - Mode == DM_NEED_IDENT means:
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
/* (C) 2000-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<>merstra<72>e 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -45,14 +45,17 @@
|
|||||||
|
|
||||||
|
|
||||||
/* 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_IMPLICIT 0x0001U /* Implicitly declared function */
|
||||||
#define FD_EMPTY 0x0002U /* Function with empty param list */
|
#define FD_EMPTY 0x0002U /* Function with empty param list */
|
||||||
#define FD_VOID_PARAM 0x0004U /* Function with a void param list */
|
#define FD_VOID_PARAM 0x0004U /* Function with a void param list */
|
||||||
#define FD_VARIADIC 0x0008U /* Function with variable param list */
|
#define FD_VARIADIC 0x0008U /* Function with variable param list */
|
||||||
#define FD_FASTCALL 0x0010U /* __fastcall__ function */
|
#define FD_FASTCALL 0x0010U /* __fastcall__ function */
|
||||||
#define FD_OLDSTYLE 0x0020U /* Old style (K&R) function */
|
#define FD_FAR 0x0020U /* __far__ function */
|
||||||
#define FD_OLDSTYLE_INTRET 0x0040U /* K&R func has implicit int return */
|
#define FD_NEAR 0x0040U /* __near__ function */
|
||||||
#define FD_UNNAMED_PARAMS 0x0080U /* Function has unnamed params */
|
#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 */
|
/* Bits that must be ignored when comparing funcs */
|
||||||
#define FD_IGNORE (FD_IMPLICIT | FD_UNNAMED_PARAMS)
|
#define FD_IGNORE (FD_IMPLICIT | FD_UNNAMED_PARAMS)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
/* Defines for magic and version */
|
/* Defines for magic and version */
|
||||||
#define LIB_MAGIC 0x7A55616E
|
#define LIB_MAGIC 0x7A55616E
|
||||||
#define LIB_VERSION 0x000A
|
#define LIB_VERSION 0x000B
|
||||||
|
|
||||||
/* Size of an library file header */
|
/* Size of an library file header */
|
||||||
#define LIB_HDR_SIZE 12
|
#define LIB_HDR_SIZE 12
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "addrsize.h"
|
||||||
#include "mmodel.h"
|
#include "mmodel.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -56,6 +57,11 @@ static const char* MemoryModelNames[MMODEL_COUNT] = {
|
|||||||
"huge",
|
"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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -56,8 +56,10 @@ typedef enum {
|
|||||||
/* Memory model in use */
|
/* Memory model in use */
|
||||||
extern mmodel_t MemoryModel;
|
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);
|
mmodel_t FindMemoryModel (const char* Name);
|
||||||
/* Find a memory model by name. Return MMODEL_UNKNOWN for an unknown 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 */
|
/* End of mmodel.h */
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -46,10 +46,10 @@
|
|||||||
|
|
||||||
/* Defines for magic and version */
|
/* Defines for magic and version */
|
||||||
#define OBJ_MAGIC 0x616E7A55
|
#define OBJ_MAGIC 0x616E7A55
|
||||||
#define OBJ_VERSION 0x000A
|
#define OBJ_VERSION 0x000B
|
||||||
|
|
||||||
/* Size of an object file header */
|
/* Size of an object file header */
|
||||||
#define OBJ_HDR_SIZE (20*4)
|
#define OBJ_HDR_SIZE (22*4)
|
||||||
|
|
||||||
/* Flag bits */
|
/* Flag bits */
|
||||||
#define OBJ_FLAGS_DBGINFO 0x0001 /* File has debug info */
|
#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 StrPoolSize; /* 32: Size of string pool */
|
||||||
unsigned long AssertOffs; /* 32: Offset to assertion table */
|
unsigned long AssertOffs; /* 32: Offset to assertion table */
|
||||||
unsigned long AssertSize; /* 32: Size of 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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* R<>merstra<72>e 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -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 */
|
/* Number of module constructor/destructor declarations for an export */
|
||||||
#define EXP_CONDES_MASK 0x07
|
#define EXP_CONDES_MASK 0x07
|
||||||
|
|
||||||
@@ -63,14 +55,6 @@
|
|||||||
#define GET_EXP_CONDES_COUNT(x) ((x) & EXP_CONDES_MASK)
|
#define GET_EXP_CONDES_COUNT(x) ((x) & EXP_CONDES_MASK)
|
||||||
#define INC_EXP_CONDES_COUNT(x) ((x)++)
|
#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 */
|
/* Export value type */
|
||||||
#define EXP_CONST 0x00 /* Mask bit for const values */
|
#define EXP_CONST 0x00 /* Mask bit for const values */
|
||||||
#define EXP_EXPR 0x10 /* Mask bit for expr values */
|
#define EXP_EXPR 0x10 /* Mask bit for expr values */
|
||||||
|
|||||||
@@ -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 */
|
/* Create a new DbgSym and return it */
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
@@ -83,6 +83,7 @@ static DbgSym* NewDbgSym (unsigned char Type, ObjData* O)
|
|||||||
D->Expr = 0;
|
D->Expr = 0;
|
||||||
D->Name = 0;
|
D->Name = 0;
|
||||||
D->Type = Type;
|
D->Type = Type;
|
||||||
|
D->AddrSize = AddrSize;
|
||||||
|
|
||||||
/* Return the new entry */
|
/* Return the new entry */
|
||||||
return D;
|
return D;
|
||||||
@@ -139,11 +140,12 @@ static void InsertDbgSym (DbgSym* D, long Val)
|
|||||||
DbgSym* ReadDbgSym (FILE* F, ObjData* O)
|
DbgSym* ReadDbgSym (FILE* F, ObjData* O)
|
||||||
/* Read a debug symbol from a file, insert and return it */
|
/* 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 Type = Read8 (F);
|
||||||
|
unsigned char AddrSize = Read8 (F);
|
||||||
|
|
||||||
/* Create a new debug symbol */
|
/* Create a new debug symbol */
|
||||||
DbgSym* D = NewDbgSym (Type, O);
|
DbgSym* D = NewDbgSym (Type, AddrSize, O);
|
||||||
|
|
||||||
/* Read and assign the name */
|
/* Read and assign the name */
|
||||||
D->Name = MakeGlobalStringId (O, ReadVar (F));
|
D->Name = MakeGlobalStringId (O, ReadVar (F));
|
||||||
@@ -271,3 +273,4 @@ void PrintDbgSymLabels (ObjData* O, FILE* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ struct DbgSym {
|
|||||||
ExprNode* Expr; /* Expression (0 if not def'd) */
|
ExprNode* Expr; /* Expression (0 if not def'd) */
|
||||||
unsigned Name; /* Name */
|
unsigned Name; /* Name */
|
||||||
unsigned char Type; /* Type of symbol */
|
unsigned char Type; /* Type of symbol */
|
||||||
|
unsigned char AddrSize; /* Address size of symbol */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "addrsize.h"
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
#include "hashstr.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 */
|
/* 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 */
|
/* Create a new import and initialize it */
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
@@ -107,7 +109,7 @@ static Import* NewImport (unsigned char Type, ObjData* Obj)
|
|||||||
I->Exp = 0;
|
I->Exp = 0;
|
||||||
I->Name = INVALID_STRING_ID;
|
I->Name = INVALID_STRING_ID;
|
||||||
I->Flags = 0;
|
I->Flags = 0;
|
||||||
I->Type = Type;
|
I->AddrSize = AddrSize;
|
||||||
|
|
||||||
/* Return the new structure */
|
/* Return the new structure */
|
||||||
return I;
|
return I;
|
||||||
@@ -129,7 +131,7 @@ void InsertImport (Import* I)
|
|||||||
/* Search through the list in that slot and print matching duplicates */
|
/* Search through the list in that slot and print matching duplicates */
|
||||||
if (HashTab[Hash] == 0) {
|
if (HashTab[Hash] == 0) {
|
||||||
/* The slot is empty, we need to insert a dummy export */
|
/* The slot is empty, we need to insert a dummy export */
|
||||||
E = HashTab[Hash] = NewExport (0, Name, 0);
|
E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
|
||||||
++ExpCount;
|
++ExpCount;
|
||||||
} else {
|
} else {
|
||||||
E = HashTab [Hash];
|
E = HashTab [Hash];
|
||||||
@@ -140,7 +142,7 @@ void InsertImport (Import* I)
|
|||||||
}
|
}
|
||||||
if (E->Next == 0) {
|
if (E->Next == 0) {
|
||||||
/* End of list an entry not found, insert a dummy */
|
/* 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 */
|
E = E->Next; /* Point to dummy */
|
||||||
++ExpCount; /* One export more */
|
++ExpCount; /* One export more */
|
||||||
break;
|
break;
|
||||||
@@ -189,15 +191,11 @@ Import* ReadImport (FILE* F, ObjData* Obj)
|
|||||||
{
|
{
|
||||||
Import* I;
|
Import* I;
|
||||||
|
|
||||||
/* Read the import type and check it */
|
/* Read the import address size */
|
||||||
unsigned char Type = Read8 (F);
|
unsigned char AddrSize = Read8 (F);
|
||||||
if (Type != IMP_ZP && Type != IMP_ABS) {
|
|
||||||
Error ("Unknown import type in module `%s': %02X",
|
|
||||||
GetObjFileName (Obj), Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create a new import */
|
/* Create a new import */
|
||||||
I = NewImport (Type, Obj);
|
I = NewImport (AddrSize, Obj);
|
||||||
|
|
||||||
/* Read the name */
|
/* Read the name */
|
||||||
I->Name = MakeGlobalStringId (Obj, ReadVar (F));
|
I->Name = MakeGlobalStringId (Obj, ReadVar (F));
|
||||||
@@ -205,6 +203,26 @@ Import* ReadImport (FILE* F, ObjData* Obj)
|
|||||||
/* Read the file position */
|
/* Read the file position */
|
||||||
ReadFilePos (F, &I->Pos);
|
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 the new import */
|
||||||
return I;
|
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 */
|
/* Create a new export and initialize it */
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
@@ -232,6 +251,7 @@ static Export* NewExport (unsigned char Type, unsigned Name, ObjData* Obj)
|
|||||||
E->ImpList = 0;
|
E->ImpList = 0;
|
||||||
E->Expr = 0;
|
E->Expr = 0;
|
||||||
E->Type = Type;
|
E->Type = Type;
|
||||||
|
E->AddrSize = AddrSize;
|
||||||
memset (E->ConDes, 0, sizeof (E->ConDes));
|
memset (E->ConDes, 0, sizeof (E->ConDes));
|
||||||
|
|
||||||
/* Return the new entry */
|
/* Return the new entry */
|
||||||
@@ -335,15 +355,17 @@ void InsertExport (Export* E)
|
|||||||
Export* ReadExport (FILE* F, ObjData* O)
|
Export* ReadExport (FILE* F, ObjData* O)
|
||||||
/* Read an export from a file */
|
/* Read an export from a file */
|
||||||
{
|
{
|
||||||
unsigned char Type;
|
|
||||||
unsigned ConDesCount;
|
unsigned ConDesCount;
|
||||||
Export* E;
|
Export* E;
|
||||||
|
|
||||||
/* Read the type */
|
/* 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 */
|
/* 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 */
|
/* Read the constructor/destructor decls if we have any */
|
||||||
ConDesCount = GET_EXP_CONDES_COUNT (Type);
|
ConDesCount = GET_EXP_CONDES_COUNT (Type);
|
||||||
@@ -391,7 +413,7 @@ Export* CreateConstExport (unsigned Name, long Value)
|
|||||||
/* Create an export for a literal date */
|
/* Create an export for a literal date */
|
||||||
{
|
{
|
||||||
/* Create a new export */
|
/* Create a new export */
|
||||||
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 */
|
/* Assign the value */
|
||||||
E->Expr = LiteralExpr (Value, 0);
|
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 an relative export for a memory area offset */
|
||||||
{
|
{
|
||||||
/* Create a new export */
|
/* 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 */
|
/* Assign the value */
|
||||||
E->Expr = MemoryExpr (Mem, Offs, 0);
|
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 relative export to a segment */
|
||||||
{
|
{
|
||||||
/* Create a new export */
|
/* 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 */
|
/* Assign the value */
|
||||||
E->Expr = SegmentExpr (Seg, Offs, 0);
|
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 relative export to a section */
|
||||||
{
|
{
|
||||||
/* Create a new export */
|
/* 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 */
|
/* Assign the value */
|
||||||
E->Expr = SectionExpr (Sec, Offs, 0);
|
E->Expr = SectionExpr (Sec, Offs, 0);
|
||||||
@@ -529,13 +551,12 @@ static void CheckSymType (const Export* E)
|
|||||||
{
|
{
|
||||||
/* External with matching imports */
|
/* External with matching imports */
|
||||||
Import* Imp = E->ImpList;
|
Import* Imp = E->ImpList;
|
||||||
int ZP = IS_EXP_ZP (E->Type);
|
|
||||||
while (Imp) {
|
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 */
|
/* Export is ZP, import is abs or the other way round */
|
||||||
if (E->Obj) {
|
if (E->Obj) {
|
||||||
/* User defined export */
|
/* User defined export */
|
||||||
Warning ("Type mismatch for `%s', export in "
|
Warning ("Address size mismatch for `%s', export in "
|
||||||
"%s(%lu), import in %s(%lu)",
|
"%s(%lu), import in %s(%lu)",
|
||||||
GetString (E->Name),
|
GetString (E->Name),
|
||||||
GetSourceFileName (E->Obj, E->Pos.Name),
|
GetSourceFileName (E->Obj, E->Pos.Name),
|
||||||
@@ -544,7 +565,7 @@ static void CheckSymType (const Export* E)
|
|||||||
Imp->Pos.Line);
|
Imp->Pos.Line);
|
||||||
} else {
|
} else {
|
||||||
/* Export created by the linker */
|
/* Export created by the linker */
|
||||||
Warning ("Type mismatch for `%s', imported from %s(%lu)",
|
Warning ("Address size mismatch for `%s', imported from %s(%lu)",
|
||||||
GetString (E->Name),
|
GetString (E->Name),
|
||||||
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
|
GetSourceFileName (Imp->Obj, Imp->Pos.Name),
|
||||||
Imp->Pos.Line);
|
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)
|
void PrintExportMap (FILE* F)
|
||||||
/* Print an export map to the given file */
|
/* Print an export map to the given file */
|
||||||
{
|
{
|
||||||
@@ -675,7 +711,7 @@ void PrintExportMap (FILE* F)
|
|||||||
GetExportVal (E),
|
GetExportVal (E),
|
||||||
E->ImpCount? 'R' : ' ',
|
E->ImpCount? 'R' : ' ',
|
||||||
IS_EXP_LABEL (E->Type)? 'L' : 'E',
|
IS_EXP_LABEL (E->Type)? 'L' : 'E',
|
||||||
IS_EXP_ZP (E->Type)? 'Z' : ' ',
|
GetAddrSizeCode (E->AddrSize),
|
||||||
IS_EXP_CONDES (E->Type)? 'I' : ' ');
|
IS_EXP_CONDES (E->Type)? 'I' : ' ');
|
||||||
if (++Count == 2) {
|
if (++Count == 2) {
|
||||||
Count = 0;
|
Count = 0;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -66,7 +66,7 @@ struct Import {
|
|||||||
struct Export* Exp; /* Matching export for this import */
|
struct Export* Exp; /* Matching export for this import */
|
||||||
unsigned Name; /* Name if not in table */
|
unsigned Name; /* Name if not in table */
|
||||||
unsigned char Flags; /* Generic flags */
|
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 */
|
FilePos Pos; /* File position of definition */
|
||||||
ExprNode* Expr; /* Expression (0 if not def'd) */
|
ExprNode* Expr; /* Expression (0 if not def'd) */
|
||||||
unsigned char Type; /* Type of export */
|
unsigned char Type; /* Type of export */
|
||||||
|
unsigned char AddrSize; /* Address size of export */
|
||||||
unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */
|
unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* library.c */
|
/* library.c */
|
||||||
/* */
|
/* */
|
||||||
/* Library data structures and helpers for the ld65 linker */
|
/* Library data structures and helpers for the ld65 linker */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -107,6 +107,8 @@ static void LibReadObjHeader (ObjData* O, const char* LibName)
|
|||||||
O->Header.StrPoolSize = Read32 (Lib);
|
O->Header.StrPoolSize = Read32 (Lib);
|
||||||
O->Header.AssertOffs = Read32 (Lib);
|
O->Header.AssertOffs = Read32 (Lib);
|
||||||
O->Header.AssertSize = 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 */
|
/* Read the assertions from the object file */
|
||||||
ObjReadAssertions (Lib, O->Start + O->Header.AssertOffs, O);
|
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.
|
/* Seek to the start of the segment list and read the segments.
|
||||||
* This must be last, since the data here may reference other
|
* This must be last, since the data here may reference other
|
||||||
* stuff.
|
* stuff.
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ ObjData* NewObjData (void)
|
|||||||
O->Strings = 0;
|
O->Strings = 0;
|
||||||
O->AssertionCount = 0;
|
O->AssertionCount = 0;
|
||||||
O->Assertions = 0;
|
O->Assertions = 0;
|
||||||
|
O->ScopeCount = 0;
|
||||||
|
O->Scopes = 0;
|
||||||
|
|
||||||
/* Return the new entry */
|
/* Return the new entry */
|
||||||
return O;
|
return O;
|
||||||
@@ -192,8 +194,10 @@ const char* GetSourceFileName (const ObjData* O, unsigned Index)
|
|||||||
|
|
||||||
/* Check the parameter */
|
/* Check the parameter */
|
||||||
if (Index >= O->FileCount) {
|
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));
|
Index, GetObjFileName (O));
|
||||||
|
return "[invalid]"; /* ### */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the name */
|
/* Return the name */
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
|
#include "inline.h"
|
||||||
#include "objdefs.h"
|
#include "objdefs.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -61,7 +62,7 @@ struct ObjData {
|
|||||||
unsigned LibName; /* Name of library */
|
unsigned LibName; /* Name of library */
|
||||||
unsigned long MTime; /* Time of last modification */
|
unsigned long MTime; /* Time of last modification */
|
||||||
ObjHeader Header; /* Header of file */
|
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 Flags;
|
||||||
unsigned FileCount; /* Input file count */
|
unsigned FileCount; /* Input file count */
|
||||||
struct FileInfo** Files; /* List of input files */
|
struct FileInfo** Files; /* List of input files */
|
||||||
@@ -79,6 +80,8 @@ struct ObjData {
|
|||||||
unsigned* Strings; /* List of global string indices */
|
unsigned* Strings; /* List of global string indices */
|
||||||
unsigned AssertionCount; /* Count of module assertions */
|
unsigned AssertionCount; /* Count of module assertions */
|
||||||
struct Assertion** Assertions; /* List 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.
|
* 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);
|
const char* GetSourceFileName (const ObjData* O, unsigned Index);
|
||||||
/* Get the name of the source file with the given index. If O is NULL, return
|
/* Get the name of the source file with the given index. If O is NULL, return
|
||||||
* "[linker generated]" as the file name.
|
* "[linker generated]" as the file name.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -104,6 +104,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
|||||||
H->StrPoolSize = Read32 (Obj);
|
H->StrPoolSize = Read32 (Obj);
|
||||||
H->AssertOffs = Read32 (Obj);
|
H->AssertOffs = Read32 (Obj);
|
||||||
H->AssertSize = 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)
|
void ObjAdd (FILE* Obj, const char* Name)
|
||||||
/* Add an object file to the module list */
|
/* 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 */
|
/* Read the assertions from the object file */
|
||||||
ObjReadAssertions (Obj, O->Header.AssertOffs, O);
|
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
|
/* Read the segment list from the object file. This must be last, since
|
||||||
* the expressions stored in the code may reference segments or imported
|
* the expressions stored in the code may reference segments or imported
|
||||||
* symbols.
|
* symbols.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* 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);
|
void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O);
|
||||||
/* Read the assertions from a file at the given offset */
|
/* 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);
|
void ObjAdd (FILE* F, const char* Name);
|
||||||
/* Add an object file to the module list */
|
/* Add an object file to the module list */
|
||||||
|
|
||||||
|
|||||||
@@ -172,23 +172,17 @@ static const char* GetExportFlags (unsigned Flags, const unsigned char* ConDes)
|
|||||||
unsigned Count;
|
unsigned Count;
|
||||||
unsigned I;
|
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 */
|
/* Type of expression */
|
||||||
|
TypeDesc[0] = '\0';
|
||||||
switch (Flags & EXP_MASK_VAL) {
|
switch (Flags & EXP_MASK_VAL) {
|
||||||
case EXP_CONST: strcat (TypeDesc, ",EXP_CONST"); break;
|
case EXP_CONST: strcat (TypeDesc, "EXP_CONST"); break;
|
||||||
case EXP_EXPR: strcat (TypeDesc, ",EXP_EXPR"); break;
|
case EXP_EXPR: strcat (TypeDesc, "EXP_EXPR"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Constructor/destructor declarations */
|
/* Constructor/destructor declarations */
|
||||||
T = TypeDesc + strlen (TypeDesc);
|
T = TypeDesc + strlen (TypeDesc);
|
||||||
Count = GET_EXP_CONDES_COUNT (Flags);
|
Count = GET_EXP_CONDES_COUNT (Flags);
|
||||||
if (Count > 0) {
|
if (Count > 0 && ConDes) {
|
||||||
T += sprintf (T, ",EXP_CONDES=");
|
T += sprintf (T, ",EXP_CONDES=");
|
||||||
for (I = 0; I < Count; ++I) {
|
for (I = 0; I < Count; ++I) {
|
||||||
unsigned Type = CD_GET_TYPE (ConDes[I]);
|
unsigned Type = CD_GET_TYPE (ConDes[I]);
|
||||||
@@ -490,26 +484,18 @@ void DumpObjImports (FILE* F, unsigned long Offset)
|
|||||||
/* Read and print all imports */
|
/* Read and print all imports */
|
||||||
for (I = 0; I < Count; ++I) {
|
for (I = 0; I < Count; ++I) {
|
||||||
|
|
||||||
const char* TypeDesc;
|
|
||||||
|
|
||||||
/* Read the data for one import */
|
/* Read the data for one import */
|
||||||
unsigned char Type = Read8 (F);
|
unsigned char AddrSize = Read8 (F);
|
||||||
const char* Name = GetString (&StrPool, ReadVar (F));
|
const char* Name = GetString (&StrPool, ReadVar (F));
|
||||||
unsigned Len = strlen (Name);
|
unsigned Len = strlen (Name);
|
||||||
ReadFilePos (F, &Pos);
|
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 */
|
/* Print the header */
|
||||||
printf (" Index:%27u\n", I);
|
printf (" Index:%27u\n", I);
|
||||||
|
|
||||||
/* Print the data */
|
/* 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);
|
printf (" Name:%*s\"%s\"\n", 24-Len, "", Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,14 +537,14 @@ void DumpObjExports (FILE* F, unsigned long Offset)
|
|||||||
|
|
||||||
unsigned long Value = 0;
|
unsigned long Value = 0;
|
||||||
int HaveValue;
|
int HaveValue;
|
||||||
unsigned char Type;
|
|
||||||
unsigned char ConDes [CD_TYPE_COUNT];
|
unsigned char ConDes [CD_TYPE_COUNT];
|
||||||
const char* Name;
|
const char* Name;
|
||||||
unsigned Len;
|
unsigned Len;
|
||||||
|
|
||||||
|
|
||||||
/* Read the data for one export */
|
/* 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));
|
ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type));
|
||||||
Name = GetString (&StrPool, ReadVar (F));
|
Name = GetString (&StrPool, ReadVar (F));
|
||||||
Len = strlen (Name);
|
Len = strlen (Name);
|
||||||
@@ -576,6 +562,8 @@ void DumpObjExports (FILE* F, unsigned long Offset)
|
|||||||
|
|
||||||
/* Print the data */
|
/* Print the data */
|
||||||
printf (" Type:%22s0x%02X (%s)\n", "", Type, GetExportFlags (Type, ConDes));
|
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);
|
printf (" Name:%*s\"%s\"\n", 24-Len, "", Name);
|
||||||
if (HaveValue) {
|
if (HaveValue) {
|
||||||
printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value);
|
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) {
|
for (I = 0; I < Count; ++I) {
|
||||||
|
|
||||||
unsigned long Value = 0;
|
unsigned long Value = 0;
|
||||||
int HaveValue;
|
int HaveValue;
|
||||||
unsigned char Type;
|
|
||||||
unsigned char ConDes [CD_TYPE_COUNT];
|
|
||||||
const char* Name;
|
|
||||||
unsigned Len;
|
|
||||||
|
|
||||||
/* Read the data for one symbol */
|
/* Read the data for one symbol */
|
||||||
Type = Read8 (F);
|
unsigned char Type = Read8 (F);
|
||||||
ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type));
|
unsigned char AddrSize = Read8 (F);
|
||||||
Name = GetString (&StrPool, ReadVar (F));
|
const char* Name = GetString (&StrPool, ReadVar (F));
|
||||||
Len = strlen (Name);
|
unsigned Len = strlen (Name);
|
||||||
if (IS_EXP_EXPR (Type)) {
|
if (IS_EXP_EXPR (Type)) {
|
||||||
SkipExpr (F);
|
SkipExpr (F);
|
||||||
HaveValue = 0;
|
HaveValue = 0;
|
||||||
@@ -650,7 +634,9 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset)
|
|||||||
printf (" Index:%27u\n", I);
|
printf (" Index:%27u\n", I);
|
||||||
|
|
||||||
/* Print the data */
|
/* 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);
|
printf (" Name:%*s\"%s\"\n", 24-Len, "", Name);
|
||||||
if (HaveValue) {
|
if (HaveValue) {
|
||||||
printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value);
|
printf (" Value:%15s0x%08lX (%lu)\n", "", Value, Value);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* R<>merstrasse 52 */
|
/* R<>merstra<EFBFBD>e 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -227,6 +227,8 @@ void ReadObjHeader (FILE* F, ObjHeader* H)
|
|||||||
H->StrPoolSize = Read32 (F);
|
H->StrPoolSize = Read32 (F);
|
||||||
H->AssertOffs = Read32 (F);
|
H->AssertOffs = Read32 (F);
|
||||||
H->AssertSize = Read32 (F);
|
H->AssertSize = Read32 (F);
|
||||||
|
H->ScopeOffs = Read32 (F);
|
||||||
|
H->ScopeSize = Read32 (F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user