Removed (pretty inconsistently used) tab chars from source code base.
This commit is contained in:
@@ -50,7 +50,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ static Collection Assertions = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ struct ObjData;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* bin.c */
|
||||
/* bin.c */
|
||||
/* */
|
||||
/* Module to handle the raw binary format */
|
||||
/* Module to handle the raw binary format */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -58,21 +58,21 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
struct BinDesc {
|
||||
unsigned Undef; /* Count of undefined externals */
|
||||
FILE* F; /* Output file */
|
||||
unsigned Undef; /* Count of undefined externals */
|
||||
FILE* F; /* Output file */
|
||||
const char* Filename; /* Name of output file */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -84,8 +84,8 @@ BinDesc* NewBinDesc (void)
|
||||
BinDesc* D = xmalloc (sizeof (BinDesc));
|
||||
|
||||
/* Initialize the fields */
|
||||
D->Undef = 0;
|
||||
D->F = 0;
|
||||
D->Undef = 0;
|
||||
D->F = 0;
|
||||
D->Filename = 0;
|
||||
|
||||
/* Return the created struct */
|
||||
@@ -103,8 +103,8 @@ void FreeBinDesc (BinDesc* D)
|
||||
|
||||
|
||||
static unsigned BinWriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
unsigned long Offs attribute ((unused)),
|
||||
void* Data)
|
||||
unsigned long Offs attribute ((unused)),
|
||||
void* Data)
|
||||
/* Called from SegWrite for an expression. Evaluate the expression, check the
|
||||
* range and write the expression value to the file.
|
||||
*/
|
||||
@@ -148,20 +148,20 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M)
|
||||
/* Walk over all segments in this memory area */
|
||||
for (I = 0; I < CollCount (&M->SegList); ++I) {
|
||||
|
||||
int DoWrite;
|
||||
int DoWrite;
|
||||
|
||||
/* Get the segment */
|
||||
SegDesc* S = CollAtUnchecked (&M->SegList, I);
|
||||
/* Get the segment */
|
||||
SegDesc* S = CollAtUnchecked (&M->SegList, I);
|
||||
|
||||
/* Keep the user happy */
|
||||
Print (stdout, 1, " Writing `%s'\n", GetString (S->Name));
|
||||
/* Keep the user happy */
|
||||
Print (stdout, 1, " Writing `%s'\n", GetString (S->Name));
|
||||
|
||||
/* Writes do only occur in the load area and not for BSS segments */
|
||||
DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */
|
||||
S->Load == M && /* LOAD segment */
|
||||
S->Seg->Dumped == 0; /* Not already written */
|
||||
/* Writes do only occur in the load area and not for BSS segments */
|
||||
DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */
|
||||
S->Load == M && /* LOAD segment */
|
||||
S->Seg->Dumped == 0; /* Not already written */
|
||||
|
||||
/* Output debugging stuff */
|
||||
/* Output debugging stuff */
|
||||
PrintBoolVal ("bss", S->Flags & SF_BSS);
|
||||
PrintBoolVal ("LoadArea", S->Load == M);
|
||||
PrintBoolVal ("Dumped", S->Seg->Dumped);
|
||||
@@ -169,17 +169,17 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M)
|
||||
PrintNumVal ("Address", Addr);
|
||||
PrintNumVal ("FileOffs", (unsigned long) ftell (D->F));
|
||||
|
||||
/* Check if the alignment for the segment from the linker config is
|
||||
/* Check if the alignment for the segment from the linker config is
|
||||
* a multiple for that of the segment.
|
||||
*/
|
||||
if ((S->RunAlignment % S->Seg->Alignment) != 0) {
|
||||
/* Segment requires another alignment than configured
|
||||
* in the linker.
|
||||
*/
|
||||
Warning ("Segment `%s' is not aligned properly. Resulting "
|
||||
/* Segment requires another alignment than configured
|
||||
* in the linker.
|
||||
*/
|
||||
Warning ("Segment `%s' is not aligned properly. Resulting "
|
||||
"executable may not be functional.",
|
||||
GetString (S->Name));
|
||||
}
|
||||
GetString (S->Name));
|
||||
}
|
||||
|
||||
/* If this is the run memory area, we must apply run alignment. If
|
||||
* this is not the run memory area but the load memory area (which
|
||||
@@ -226,31 +226,31 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M)
|
||||
|
||||
}
|
||||
|
||||
/* Now write the segment to disk if it is not a BSS type segment and
|
||||
* if the memory area is the load area.
|
||||
*/
|
||||
if (DoWrite) {
|
||||
/* Now write the segment to disk if it is not a BSS type segment and
|
||||
* if the memory area is the load area.
|
||||
*/
|
||||
if (DoWrite) {
|
||||
unsigned long P = ftell (D->F);
|
||||
SegWrite (D->Filename, D->F, S->Seg, BinWriteExpr, D);
|
||||
SegWrite (D->Filename, D->F, S->Seg, BinWriteExpr, D);
|
||||
PrintNumVal ("Wrote", (unsigned long) (ftell (D->F) - P));
|
||||
} else if (M->Flags & MF_FILL) {
|
||||
WriteMult (D->F, S->Seg->FillVal, S->Seg->Size);
|
||||
} else if (M->Flags & MF_FILL) {
|
||||
WriteMult (D->F, S->Seg->FillVal, S->Seg->Size);
|
||||
PrintNumVal ("Filled", (unsigned long) S->Seg->Size);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this was the load memory area, mark the segment as dumped */
|
||||
if (S->Load == M) {
|
||||
S->Seg->Dumped = 1;
|
||||
}
|
||||
/* If this was the load memory area, mark the segment as dumped */
|
||||
if (S->Load == M) {
|
||||
S->Seg->Dumped = 1;
|
||||
}
|
||||
|
||||
/* Calculate the new address */
|
||||
Addr += S->Seg->Size;
|
||||
/* Calculate the new address */
|
||||
Addr += S->Seg->Size;
|
||||
}
|
||||
|
||||
/* If a fill was requested, fill the remaining space */
|
||||
if ((M->Flags & MF_FILL) != 0 && M->FillLevel < M->Size) {
|
||||
unsigned long ToFill = M->Size - M->FillLevel;
|
||||
Print (stdout, 2, " Filling 0x%lx bytes with 0x%02x\n",
|
||||
Print (stdout, 2, " Filling 0x%lx bytes with 0x%02x\n",
|
||||
ToFill, M->FillVal);
|
||||
WriteMult (D->F, M->FillVal, ToFill);
|
||||
M->FillLevel = M->Size;
|
||||
@@ -283,17 +283,17 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
/* Check for unresolved symbols. The function BinUnresolved is called
|
||||
* if we get an unresolved symbol.
|
||||
*/
|
||||
D->Undef = 0; /* Reset the counter */
|
||||
D->Undef = 0; /* Reset the counter */
|
||||
CheckUnresolvedImports (BinUnresolved, D);
|
||||
if (D->Undef > 0) {
|
||||
/* We had unresolved symbols, cannot create output file */
|
||||
Error ("%u unresolved external(s) found - cannot create output file", D->Undef);
|
||||
/* We had unresolved symbols, cannot create output file */
|
||||
Error ("%u unresolved external(s) found - cannot create output file", D->Undef);
|
||||
}
|
||||
|
||||
/* Open the file */
|
||||
D->F = fopen (D->Filename, "wb");
|
||||
if (D->F == 0) {
|
||||
Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Keep the user happy */
|
||||
@@ -303,13 +303,13 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
|
||||
/* Get this entry */
|
||||
MemoryArea* M = CollAtUnchecked (&F->MemoryAreas, I);
|
||||
Print (stdout, 1, " Dumping `%s'\n", GetString (M->Name));
|
||||
BinWriteMem (D, M);
|
||||
Print (stdout, 1, " Dumping `%s'\n", GetString (M->Name));
|
||||
BinWriteMem (D, M);
|
||||
}
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (D->F) != 0) {
|
||||
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Reset the file and filename */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* bin.h */
|
||||
/* bin.h */
|
||||
/* */
|
||||
/* Module to handle the raw binary format */
|
||||
/* Module to handle the raw binary format */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ typedef struct BinDesc BinDesc;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* binfmt.c */
|
||||
/* binfmt.c */
|
||||
/* */
|
||||
/* Binary format definitions for the ld65 linker */
|
||||
/* Binary format definitions for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -43,18 +43,18 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Default format (depends on target system) */
|
||||
unsigned char DefaultBinFmt = BINFMT_BINARY;
|
||||
unsigned char DefaultBinFmt = BINFMT_BINARY;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -66,22 +66,22 @@ int RelocatableBinFmt (unsigned Format)
|
||||
|
||||
/* Resolve the default format */
|
||||
if (Format == BINFMT_DEFAULT) {
|
||||
Format = DefaultBinFmt;
|
||||
Format = DefaultBinFmt;
|
||||
}
|
||||
|
||||
/* Check the type */
|
||||
switch (Format) {
|
||||
|
||||
case BINFMT_BINARY:
|
||||
Reloc = 0;
|
||||
break;
|
||||
case BINFMT_BINARY:
|
||||
Reloc = 0;
|
||||
break;
|
||||
|
||||
case BINFMT_O65:
|
||||
Reloc = 1;
|
||||
break;
|
||||
case BINFMT_O65:
|
||||
Reloc = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid format specifier: %u", Format);
|
||||
default:
|
||||
Internal ("Invalid format specifier: %u", Format);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* binfmt.h */
|
||||
/* binfmt.h */
|
||||
/* */
|
||||
/* Binary format definitions for the ld65 linker */
|
||||
/* Binary format definitions for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ extern unsigned char DefaultBinFmt;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ static ExprNode* Factor (void)
|
||||
|
||||
switch (CfgTok) {
|
||||
|
||||
case CFGTOK_IDENT:
|
||||
case CFGTOK_IDENT:
|
||||
/* Get the name as an id */
|
||||
Name = GetStrBufId (&CfgSVal);
|
||||
|
||||
@@ -82,11 +82,11 @@ static ExprNode* Factor (void)
|
||||
CfgNextTok ();
|
||||
break;
|
||||
|
||||
case CFGTOK_INTCON:
|
||||
case CFGTOK_INTCON:
|
||||
/* An integer constant */
|
||||
N = LiteralExpr (CfgIVal, 0);
|
||||
CfgNextTok ();
|
||||
break;
|
||||
CfgNextTok ();
|
||||
break;
|
||||
|
||||
case CFGTOK_PLUS:
|
||||
/* Unary plus */
|
||||
@@ -101,16 +101,16 @@ static ExprNode* Factor (void)
|
||||
N->Left = Factor ();
|
||||
break;
|
||||
|
||||
case CFGTOK_LPAR:
|
||||
case CFGTOK_LPAR:
|
||||
/* Left parenthesis */
|
||||
CfgNextTok ();
|
||||
N = CfgExpr ();
|
||||
CfgConsume (CFGTOK_RPAR, "')' expected");
|
||||
break;
|
||||
CfgNextTok ();
|
||||
N = CfgExpr ();
|
||||
CfgConsume (CFGTOK_RPAR, "')' expected");
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid expression: %d", CfgTok);
|
||||
break;
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid expression: %d", CfgTok);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return the new expression node */
|
||||
@@ -238,7 +238,7 @@ long CfgCheckedConstExpr (long Min, long Max)
|
||||
|
||||
/* Check the range */
|
||||
if (Val < Min || Val > Max) {
|
||||
CfgError (&CfgErrorPos, "Range error");
|
||||
CfgError (&CfgErrorPos, "Range error");
|
||||
}
|
||||
|
||||
/* Return the value */
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* condes.c */
|
||||
/* condes.c */
|
||||
/* */
|
||||
/* Module constructor/destructor support */
|
||||
/* Module constructor/destructor support */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -61,11 +61,11 @@
|
||||
/* Struct describing one condes type */
|
||||
typedef struct ConDesDesc ConDesDesc;
|
||||
struct ConDesDesc {
|
||||
Collection ExpList; /* List of exported symbols */
|
||||
unsigned SegName; /* Name of segment the table is in */
|
||||
unsigned Label; /* Name of table label */
|
||||
unsigned CountSym; /* Name of symbol for entry count */
|
||||
unsigned char Order; /* Table order (increasing/decreasing) */
|
||||
Collection ExpList; /* List of exported symbols */
|
||||
unsigned SegName; /* Name of segment the table is in */
|
||||
unsigned Label; /* Name of table label */
|
||||
unsigned CountSym; /* Name of symbol for entry count */
|
||||
unsigned char Order; /* Table order (increasing/decreasing) */
|
||||
ConDesImport Import; /* Forced import if any */
|
||||
};
|
||||
|
||||
@@ -126,7 +126,7 @@ static ConDesDesc ConDes[CD_TYPE_COUNT] = {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Internally used function to create the condes tables */
|
||||
/* Internally used function to create the condes tables */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -151,19 +151,19 @@ static int ConDesCompare (void* Data, const void* E1, const void* E2)
|
||||
|
||||
/* Compare the priorities for this condes type */
|
||||
if (Prio1 < Prio2) {
|
||||
Cmp = -1;
|
||||
Cmp = -1;
|
||||
} else if (Prio1 > Prio2) {
|
||||
Cmp = 1;
|
||||
Cmp = 1;
|
||||
} else {
|
||||
/* Use the name in this case */
|
||||
Cmp = SB_Compare (GetStrBuf (Exp1->Name), GetStrBuf (Exp2->Name));
|
||||
/* Use the name in this case */
|
||||
Cmp = SB_Compare (GetStrBuf (Exp1->Name), GetStrBuf (Exp2->Name));
|
||||
}
|
||||
|
||||
/* Reverse the result for decreasing order */
|
||||
if (CD->Order == cdIncreasing) {
|
||||
return Cmp;
|
||||
return Cmp;
|
||||
} else {
|
||||
return -Cmp;
|
||||
return -Cmp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,16 +172,16 @@ static int ConDesCompare (void* Data, const void* E1, const void* E2)
|
||||
static void ConDesCreateOne (ConDesDesc* CD)
|
||||
/* Create one table if requested */
|
||||
{
|
||||
Segment* Seg; /* Segment for table */
|
||||
Section* Sec; /* Section for table */
|
||||
unsigned Count; /* Number of exports */
|
||||
unsigned I;
|
||||
Segment* Seg; /* Segment for table */
|
||||
Section* Sec; /* Section for table */
|
||||
unsigned Count; /* Number of exports */
|
||||
unsigned I;
|
||||
|
||||
/* Check if this table has a segment and table label defined. If not,
|
||||
* creation was not requested in the config file - ignore it.
|
||||
*/
|
||||
if (CD->SegName == INVALID_STRING_ID || CD->Label == INVALID_STRING_ID) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if there is an import for the table label. If not, there is no
|
||||
@@ -189,7 +189,7 @@ static void ConDesCreateOne (ConDesDesc* CD)
|
||||
* table.
|
||||
*/
|
||||
if (!IsUnresolved (CD->Label)) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Sort the collection of exports according to priority */
|
||||
@@ -209,14 +209,14 @@ static void ConDesCreateOne (ConDesDesc* CD)
|
||||
Count = CollCount (&CD->ExpList);
|
||||
for (I = 0; I < Count; ++I) {
|
||||
|
||||
/* Get the export */
|
||||
Export* E = CollAt (&CD->ExpList, I);
|
||||
/* Get the export */
|
||||
Export* E = CollAt (&CD->ExpList, I);
|
||||
|
||||
/* Create the fragment */
|
||||
Fragment* F = NewFragment (FRAG_EXPR, 2, Sec);
|
||||
/* Create the fragment */
|
||||
Fragment* F = NewFragment (FRAG_EXPR, 2, Sec);
|
||||
|
||||
/* Set the expression pointer */
|
||||
F->Expr = E->Expr;
|
||||
/* Set the expression pointer */
|
||||
F->Expr = E->Expr;
|
||||
}
|
||||
|
||||
/* Define the table start as an export, offset into section is zero
|
||||
@@ -228,14 +228,14 @@ static void ConDesCreateOne (ConDesDesc* CD)
|
||||
* with the number of elements in the table.
|
||||
*/
|
||||
if (CD->CountSym) {
|
||||
CreateConstExport (CD->CountSym, Count);
|
||||
CreateConstExport (CD->CountSym, Count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -247,10 +247,10 @@ void ConDesAddExport (struct Export* E)
|
||||
|
||||
/* Insert the export into all tables for which declarations exist */
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
unsigned Prio = E->ConDes[Type];
|
||||
if (Prio != CD_PRIO_NONE) {
|
||||
CollAppend (&ConDes[Type].ExpList, E);
|
||||
}
|
||||
unsigned Prio = E->ConDes[Type];
|
||||
if (Prio != CD_PRIO_NONE) {
|
||||
CollAppend (&ConDes[Type].ExpList, E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ void ConDesCreate (void)
|
||||
|
||||
/* Walk over the descriptor array and create a table for each entry */
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
ConDesCreateOne (ConDes + Type);
|
||||
ConDesCreateOne (ConDes + Type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,8 +385,8 @@ void ConDesDump (void)
|
||||
{
|
||||
unsigned Type;
|
||||
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
|
||||
Collection* ExpList = &ConDes[Type].ExpList;
|
||||
printf ("CONDES(%u): %u symbols\n", Type, CollCount (ExpList));
|
||||
Collection* ExpList = &ConDes[Type].ExpList;
|
||||
printf ("CONDES(%u): %u symbols\n", Type, CollCount (ExpList));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* condes.h */
|
||||
/* condes.h */
|
||||
/* */
|
||||
/* Module constructor/destructor support */
|
||||
/* Module constructor/destructor support */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Forwards */
|
||||
/* Forwards */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -54,15 +54,15 @@ struct Export;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Order of the tables */
|
||||
typedef enum {
|
||||
cdIncreasing, /* Increasing priority - default */
|
||||
cdDecreasing /* Decreasing priority */
|
||||
cdIncreasing, /* Increasing priority - default */
|
||||
cdDecreasing /* Decreasing priority */
|
||||
} ConDesOrder;
|
||||
|
||||
/* Data for a forced condes import */
|
||||
@@ -76,7 +76,7 @@ struct ConDesImport {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
1326
src/ld65/config.c
1326
src/ld65/config.c
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* config.h */
|
||||
/* config.h */
|
||||
/* */
|
||||
/* Target configuration file for the ld65 linker */
|
||||
/* Target configuration file for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@ struct MemoryArea;
|
||||
typedef struct File File;
|
||||
struct File {
|
||||
unsigned Name; /* Name index of the file */
|
||||
unsigned Flags;
|
||||
unsigned Format; /* Output format */
|
||||
unsigned Flags;
|
||||
unsigned Format; /* Output format */
|
||||
unsigned long Size; /* Size of the generated file */
|
||||
Collection MemoryAreas; /* List of memory areas in this file */
|
||||
};
|
||||
@@ -72,35 +72,35 @@ typedef struct SegDesc SegDesc;
|
||||
struct SegDesc {
|
||||
unsigned Name; /* Index of the name */
|
||||
LineInfo* LI; /* Position of definition */
|
||||
Segment* Seg; /* Pointer to segment structure */
|
||||
unsigned Attr; /* Attributes for segment */
|
||||
unsigned Flags; /* Set of bitmapped flags */
|
||||
Segment* Seg; /* Pointer to segment structure */
|
||||
unsigned Attr; /* Attributes for segment */
|
||||
unsigned Flags; /* Set of bitmapped flags */
|
||||
unsigned char FillVal; /* Fill value for this segment */
|
||||
struct MemoryArea* Load; /* Load memory section */
|
||||
struct MemoryArea* Run; /* Run memory section */
|
||||
unsigned long Addr; /* Start address or offset into segment */
|
||||
unsigned long Addr; /* Start address or offset into segment */
|
||||
unsigned long RunAlignment; /* Run area alignment if given */
|
||||
unsigned long LoadAlignment; /* Load area alignment if given */
|
||||
};
|
||||
|
||||
/* Segment flags */
|
||||
#define SF_RO 0x0001 /* Read only segment */
|
||||
#define SF_BSS 0x0002 /* Segment is BSS style segment */
|
||||
#define SF_ZP 0x0004 /* Zeropage segment (o65 only) */
|
||||
#define SF_DEFINE 0x0008 /* Define start and size */
|
||||
#define SF_ALIGN 0x0010 /* Align segment in run area */
|
||||
#define SF_RO 0x0001 /* Read only segment */
|
||||
#define SF_BSS 0x0002 /* Segment is BSS style segment */
|
||||
#define SF_ZP 0x0004 /* Zeropage segment (o65 only) */
|
||||
#define SF_DEFINE 0x0008 /* Define start and size */
|
||||
#define SF_ALIGN 0x0010 /* Align segment in run area */
|
||||
#define SF_ALIGN_LOAD 0x0020 /* Align segment in load area */
|
||||
#define SF_OFFSET 0x0040 /* Segment has offset in memory */
|
||||
#define SF_START 0x0080 /* Segment has fixed start address */
|
||||
#define SF_OFFSET 0x0040 /* Segment has offset in memory */
|
||||
#define SF_START 0x0080 /* Segment has fixed start address */
|
||||
#define SF_OPTIONAL 0x0100 /* Segment is optional (must not exist) */
|
||||
#define SF_RUN_DEF 0x0200 /* RUN symbols already defined */
|
||||
#define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */
|
||||
#define SF_RUN_DEF 0x0200 /* RUN symbols already defined */
|
||||
#define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */
|
||||
#define SF_FILLVAL 0x0800 /* Segment has separate fill value */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* dbgfile.c */
|
||||
/* dbgfile.c */
|
||||
/* */
|
||||
/* Debug file creation for the ld65 linker */
|
||||
/* */
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ void CreateDbgFile (void)
|
||||
/* Open the debug info file */
|
||||
FILE* F = fopen (DbgFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create debug file `%s': %s", DbgFileName, strerror (errno));
|
||||
Error ("Cannot create debug file `%s': %s", DbgFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Output version information */
|
||||
@@ -166,7 +166,7 @@ void CreateDbgFile (void)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing debug file `%s': %s", DbgFileName, strerror (errno));
|
||||
Error ("Error closing debug file `%s': %s", DbgFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* dbgfile.h */
|
||||
/* dbgfile.h */
|
||||
/* */
|
||||
/* Debug file creation for the ld65 linker */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* dbgsyms.c */
|
||||
/* dbgsyms.c */
|
||||
/* */
|
||||
/* Debug symbol handling for the ld65 linker */
|
||||
/* Debug symbol handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -66,16 +66,16 @@
|
||||
/* Definition of the debug symbol structure */
|
||||
struct DbgSym {
|
||||
unsigned Id; /* Id of debug symbol */
|
||||
DbgSym* Next; /* Pool linear list link */
|
||||
ObjData* Obj; /* Object file that exports the name */
|
||||
DbgSym* Next; /* Pool linear list link */
|
||||
ObjData* Obj; /* Object file that exports the name */
|
||||
Collection DefLines; /* Line infos for definition */
|
||||
Collection RefLines; /* Line infos for references */
|
||||
ExprNode* Expr; /* Expression (0 if not def'd) */
|
||||
ExprNode* Expr; /* Expression (0 if not def'd) */
|
||||
unsigned Size; /* Symbol size if any */
|
||||
unsigned OwnerId; /* Id of parent/owner */
|
||||
unsigned ImportId; /* Id of import if this is one */
|
||||
unsigned Name; /* Name */
|
||||
unsigned short Type; /* Type of symbol */
|
||||
unsigned Name; /* Name */
|
||||
unsigned short Type; /* Type of symbol */
|
||||
unsigned short AddrSize; /* Address size of symbol */
|
||||
};
|
||||
|
||||
@@ -93,12 +93,12 @@ struct HLLDbgSym {
|
||||
/* We will collect all debug symbols in the following array and remove
|
||||
* duplicates before outputing them into a label file.
|
||||
*/
|
||||
static DbgSym* DbgSymPool[256];
|
||||
static DbgSym* DbgSymPool[256];
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -116,12 +116,12 @@ static DbgSym* NewDbgSym (unsigned Id, unsigned Type, unsigned char AddrSize,
|
||||
D->Obj = O;
|
||||
D->DefLines = EmptyCollection;
|
||||
D->RefLines = EmptyCollection;
|
||||
D->Expr = 0;
|
||||
D->Expr = 0;
|
||||
D->Size = 0;
|
||||
D->OwnerId = ~0U;
|
||||
D->ImportId = ~0U;
|
||||
D->Name = 0;
|
||||
D->Type = Type;
|
||||
D->Name = 0;
|
||||
D->Type = Type;
|
||||
D->AddrSize = AddrSize;
|
||||
|
||||
/* Return the new entry */
|
||||
@@ -146,21 +146,21 @@ static DbgSym* GetDbgSym (DbgSym* D, long Val)
|
||||
{
|
||||
/* Create the hash. We hash over the symbol value */
|
||||
unsigned Hash = ((Val >> 24) & 0xFF) ^
|
||||
((Val >> 16) & 0xFF) ^
|
||||
((Val >> 8) & 0xFF) ^
|
||||
((Val >> 0) & 0xFF);
|
||||
((Val >> 16) & 0xFF) ^
|
||||
((Val >> 8) & 0xFF) ^
|
||||
((Val >> 0) & 0xFF);
|
||||
|
||||
/* Check for this symbol */
|
||||
DbgSym* Sym = DbgSymPool[Hash];
|
||||
while (Sym) {
|
||||
/* Is this symbol identical? */
|
||||
if (Sym->Name == D->Name && EqualExpr (Sym->Expr, D->Expr)) {
|
||||
/* Found */
|
||||
return Sym;
|
||||
}
|
||||
/* Is this symbol identical? */
|
||||
if (Sym->Name == D->Name && EqualExpr (Sym->Expr, D->Expr)) {
|
||||
/* Found */
|
||||
return Sym;
|
||||
}
|
||||
|
||||
/* Next symbol */
|
||||
Sym = Sym->Next;
|
||||
/* Next symbol */
|
||||
Sym = Sym->Next;
|
||||
}
|
||||
|
||||
/* This is the first symbol of it's kind */
|
||||
@@ -174,9 +174,9 @@ static void InsertDbgSym (DbgSym* D, long Val)
|
||||
{
|
||||
/* Create the hash. We hash over the symbol value */
|
||||
unsigned Hash = ((Val >> 24) & 0xFF) ^
|
||||
((Val >> 16) & 0xFF) ^
|
||||
((Val >> 8) & 0xFF) ^
|
||||
((Val >> 0) & 0xFF);
|
||||
((Val >> 16) & 0xFF) ^
|
||||
((Val >> 8) & 0xFF) ^
|
||||
((Val >> 0) & 0xFF);
|
||||
|
||||
/* Insert the symbol */
|
||||
D->Next = DbgSymPool [Hash];
|
||||
@@ -203,9 +203,9 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O, unsigned Id)
|
||||
|
||||
/* Read the value */
|
||||
if (SYM_IS_EXPR (D->Type)) {
|
||||
D->Expr = ReadExpr (F, O);
|
||||
D->Expr = ReadExpr (F, O);
|
||||
} else {
|
||||
D->Expr = LiteralExpr (Read32 (F), O);
|
||||
D->Expr = LiteralExpr (Read32 (F), O);
|
||||
}
|
||||
|
||||
/* Read the size */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* dbgsyms.h */
|
||||
/* dbgsyms.h */
|
||||
/* */
|
||||
/* Debug symbol handling for the ld65 linker */
|
||||
/* Debug symbol handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ typedef struct DbgSym DbgSym;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* error.c */
|
||||
/* error.c */
|
||||
/* */
|
||||
/* Error handling for the ld65 linker */
|
||||
/* Error handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* error.h */
|
||||
/* error.h */
|
||||
/* */
|
||||
/* Error handling for the ld65 linker */
|
||||
/* Error handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* exports.c */
|
||||
/* exports.c */
|
||||
/* */
|
||||
/* Exports handling for the ld65 linker */
|
||||
/* Exports handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -60,35 +60,35 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Hash table */
|
||||
#define HASHTAB_MASK 0x0FFFU
|
||||
#define HASHTAB_SIZE (HASHTAB_MASK + 1)
|
||||
static Export* HashTab[HASHTAB_SIZE];
|
||||
#define HASHTAB_SIZE (HASHTAB_MASK + 1)
|
||||
static Export* HashTab[HASHTAB_SIZE];
|
||||
|
||||
/* Import management variables */
|
||||
static unsigned ImpCount = 0; /* Import count */
|
||||
static unsigned ImpOpen = 0; /* Count of open imports */
|
||||
static unsigned ImpCount = 0; /* Import count */
|
||||
static unsigned ImpOpen = 0; /* Count of open imports */
|
||||
|
||||
/* Export management variables */
|
||||
static unsigned ExpCount = 0; /* Export count */
|
||||
static Export** ExpPool = 0; /* Exports array */
|
||||
static unsigned ExpCount = 0; /* Export count */
|
||||
static Export** ExpPool = 0; /* Exports array */
|
||||
|
||||
/* Defines for the flags in Import */
|
||||
#define IMP_INLIST 0x0001U /* Import is in exports list */
|
||||
|
||||
/* Defines for the flags in Export */
|
||||
#define EXP_INLIST 0x0001U /* Export is in exports list */
|
||||
#define EXP_USERMARK 0x0002U /* User setable flag */
|
||||
#define EXP_USERMARK 0x0002U /* User setable flag */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Import handling */
|
||||
/* Import handling */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ static Import* NewImport (unsigned char AddrSize, ObjData* Obj)
|
||||
Import* I = xmalloc (sizeof (Import));
|
||||
|
||||
/* Initialize the fields */
|
||||
I->Next = 0;
|
||||
I->Obj = Obj;
|
||||
I->Next = 0;
|
||||
I->Obj = Obj;
|
||||
I->DefLines = EmptyCollection;
|
||||
I->RefLines = EmptyCollection;
|
||||
I->Exp = 0;
|
||||
@@ -223,26 +223,26 @@ Import* InsertImport (Import* I)
|
||||
|
||||
/* Search through the list in that slot for a symbol with that name */
|
||||
if (HashTab[Hash] == 0) {
|
||||
/* The slot is empty, we need to insert a dummy export */
|
||||
E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
|
||||
++ExpCount;
|
||||
/* The slot is empty, we need to insert a dummy export */
|
||||
E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
|
||||
++ExpCount;
|
||||
} else {
|
||||
E = HashTab [Hash];
|
||||
while (1) {
|
||||
if (E->Name == Name) {
|
||||
/* We have an entry, L points to it */
|
||||
break;
|
||||
}
|
||||
if (E->Next == 0) {
|
||||
/* End of list an entry not found, insert a dummy */
|
||||
E->Next = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
|
||||
E = E->Next; /* Point to dummy */
|
||||
++ExpCount; /* One export more */
|
||||
break;
|
||||
} else {
|
||||
E = E->Next;
|
||||
}
|
||||
}
|
||||
E = HashTab [Hash];
|
||||
while (1) {
|
||||
if (E->Name == Name) {
|
||||
/* We have an entry, L points to it */
|
||||
break;
|
||||
}
|
||||
if (E->Next == 0) {
|
||||
/* End of list an entry not found, insert a dummy */
|
||||
E->Next = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0);
|
||||
E = E->Next; /* Point to dummy */
|
||||
++ExpCount; /* One export more */
|
||||
break;
|
||||
} else {
|
||||
E = E->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Ok, E now points to a valid exports entry for the given import. Insert
|
||||
@@ -252,10 +252,10 @@ Import* InsertImport (Import* I)
|
||||
I->Next = E->ImpList;
|
||||
E->ImpList = I;
|
||||
E->ImpCount++;
|
||||
++ImpCount; /* Total import count */
|
||||
++ImpCount; /* Total import count */
|
||||
if (E->Expr == 0) {
|
||||
/* This is a dummy export */
|
||||
++ImpOpen;
|
||||
/* This is a dummy export */
|
||||
++ImpOpen;
|
||||
}
|
||||
|
||||
/* Mark the import so we know it's in the list */
|
||||
@@ -281,7 +281,7 @@ const LineInfo* GetImportPos (const Import* Imp)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -298,16 +298,16 @@ static Export* NewExport (unsigned Type, unsigned char AddrSize,
|
||||
/* Initialize the fields */
|
||||
E->Name = Name;
|
||||
E->Next = 0;
|
||||
E->Flags = 0;
|
||||
E->Flags = 0;
|
||||
E->Obj = Obj;
|
||||
E->ImpCount = 0;
|
||||
E->ImpList = 0;
|
||||
E->Expr = 0;
|
||||
E->Expr = 0;
|
||||
E->Size = 0;
|
||||
E->DefLines = EmptyCollection;
|
||||
E->RefLines = EmptyCollection;
|
||||
E->DbgSymId = ~0U;
|
||||
E->Type = Type | SYM_EXPORT;
|
||||
E->Type = Type | SYM_EXPORT;
|
||||
E->AddrSize = AddrSize;
|
||||
for (I = 0; I < sizeof (E->ConDes) / sizeof (E->ConDes[0]); ++I) {
|
||||
E->ConDes[I] = CD_PRIO_NONE;
|
||||
@@ -361,18 +361,18 @@ Export* ReadExport (FILE* F, ObjData* O)
|
||||
ConDesCount = SYM_GET_CONDES_COUNT (Type);
|
||||
if (ConDesCount > 0) {
|
||||
|
||||
unsigned char ConDes[CD_TYPE_COUNT];
|
||||
unsigned char ConDes[CD_TYPE_COUNT];
|
||||
|
||||
/* Read the data into temp storage */
|
||||
ReadData (F, ConDes, ConDesCount);
|
||||
/* Read the data into temp storage */
|
||||
ReadData (F, ConDes, ConDesCount);
|
||||
|
||||
/* Re-order the data. In the file, each decl is encoded into a byte
|
||||
* which contains the type and the priority. In memory, we will use
|
||||
* an array of types which contain the priority.
|
||||
*/
|
||||
for (I = 0; I < ConDesCount; ++I) {
|
||||
E->ConDes[CD_GET_TYPE (ConDes[I])] = CD_GET_PRIO (ConDes[I]);
|
||||
}
|
||||
/* Re-order the data. In the file, each decl is encoded into a byte
|
||||
* which contains the type and the priority. In memory, we will use
|
||||
* an array of types which contain the priority.
|
||||
*/
|
||||
for (I = 0; I < ConDesCount; ++I) {
|
||||
E->ConDes[CD_GET_TYPE (ConDes[I])] = CD_GET_PRIO (ConDes[I]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the name */
|
||||
@@ -380,9 +380,9 @@ Export* ReadExport (FILE* F, ObjData* O)
|
||||
|
||||
/* Read the value */
|
||||
if (SYM_IS_EXPR (Type)) {
|
||||
E->Expr = ReadExpr (F, O);
|
||||
E->Expr = ReadExpr (F, O);
|
||||
} else {
|
||||
E->Expr = LiteralExpr (Read32 (F), O);
|
||||
E->Expr = LiteralExpr (Read32 (F), O);
|
||||
}
|
||||
|
||||
/* Read the size */
|
||||
@@ -440,7 +440,7 @@ void InsertExport (Export* E)
|
||||
|
||||
/* Insert the export into any condes tables if needed */
|
||||
if (SYM_IS_CONDES (E->Type)) {
|
||||
ConDesAddExport (E);
|
||||
ConDesAddExport (E);
|
||||
}
|
||||
|
||||
/* Create a hash value for the given name */
|
||||
@@ -448,54 +448,54 @@ void InsertExport (Export* E)
|
||||
|
||||
/* Search through the list in that slot */
|
||||
if (HashTab[Hash] == 0) {
|
||||
/* The slot is empty */
|
||||
HashTab[Hash] = E;
|
||||
++ExpCount;
|
||||
/* The slot is empty */
|
||||
HashTab[Hash] = E;
|
||||
++ExpCount;
|
||||
} else {
|
||||
|
||||
Last = 0;
|
||||
L = HashTab[Hash];
|
||||
do {
|
||||
if (L->Name == E->Name) {
|
||||
/* This may be an unresolved external */
|
||||
if (L->Expr == 0) {
|
||||
Last = 0;
|
||||
L = HashTab[Hash];
|
||||
do {
|
||||
if (L->Name == E->Name) {
|
||||
/* This may be an unresolved external */
|
||||
if (L->Expr == 0) {
|
||||
|
||||
/* This *is* an unresolved external. Use the actual export
|
||||
/* This *is* an unresolved external. Use the actual export
|
||||
* in E instead of the dummy one in L.
|
||||
*/
|
||||
E->Next = L->Next;
|
||||
E->ImpCount = L->ImpCount;
|
||||
E->ImpList = L->ImpList;
|
||||
if (Last) {
|
||||
Last->Next = E;
|
||||
} else {
|
||||
HashTab[Hash] = E;
|
||||
}
|
||||
ImpOpen -= E->ImpCount; /* Decrease open imports now */
|
||||
xfree (L);
|
||||
/* We must run through the import list and change the
|
||||
* export pointer now.
|
||||
*/
|
||||
Imp = E->ImpList;
|
||||
while (Imp) {
|
||||
Imp->Exp = E;
|
||||
Imp = Imp->Next;
|
||||
}
|
||||
} else {
|
||||
/* Duplicate entry, ignore it */
|
||||
Warning ("Duplicate external identifier: `%s'",
|
||||
E->Next = L->Next;
|
||||
E->ImpCount = L->ImpCount;
|
||||
E->ImpList = L->ImpList;
|
||||
if (Last) {
|
||||
Last->Next = E;
|
||||
} else {
|
||||
HashTab[Hash] = E;
|
||||
}
|
||||
ImpOpen -= E->ImpCount; /* Decrease open imports now */
|
||||
xfree (L);
|
||||
/* We must run through the import list and change the
|
||||
* export pointer now.
|
||||
*/
|
||||
Imp = E->ImpList;
|
||||
while (Imp) {
|
||||
Imp->Exp = E;
|
||||
Imp = Imp->Next;
|
||||
}
|
||||
} else {
|
||||
/* Duplicate entry, ignore it */
|
||||
Warning ("Duplicate external identifier: `%s'",
|
||||
GetString (L->Name));
|
||||
}
|
||||
return;
|
||||
}
|
||||
Last = L;
|
||||
L = L->Next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
Last = L;
|
||||
L = L->Next;
|
||||
|
||||
} while (L);
|
||||
} while (L);
|
||||
|
||||
/* Insert export at end of queue */
|
||||
Last->Next = E;
|
||||
++ExpCount;
|
||||
/* Insert export at end of queue */
|
||||
Last->Next = E;
|
||||
++ExpCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,11 +613,11 @@ Export* FindExport (unsigned Name)
|
||||
Export* L = HashTab[Name & HASHTAB_MASK];
|
||||
while (L) {
|
||||
/* Search through the list in that slot */
|
||||
if (L->Name == Name) {
|
||||
/* Entry found */
|
||||
return L;
|
||||
}
|
||||
L = L->Next;
|
||||
if (L->Name == Name) {
|
||||
/* Entry found */
|
||||
return L;
|
||||
}
|
||||
L = L->Next;
|
||||
}
|
||||
|
||||
/* Not found */
|
||||
@@ -648,8 +648,8 @@ int IsConstExport (const Export* E)
|
||||
/* Return true if the expression associated with this export is const */
|
||||
{
|
||||
if (E->Expr == 0) {
|
||||
/* External symbols cannot be const */
|
||||
return 0;
|
||||
/* External symbols cannot be const */
|
||||
return 0;
|
||||
} else {
|
||||
return IsConstExpr (E->Expr);
|
||||
}
|
||||
@@ -661,8 +661,8 @@ long GetExportVal (const Export* E)
|
||||
/* Get the value of this export */
|
||||
{
|
||||
if (E->Expr == 0) {
|
||||
/* OOPS */
|
||||
Internal ("`%s' is an undefined external", GetString (E->Name));
|
||||
/* OOPS */
|
||||
Internal ("`%s' is an undefined external", GetString (E->Name));
|
||||
}
|
||||
return GetExprVal (E->Expr);
|
||||
}
|
||||
@@ -675,8 +675,8 @@ static void CheckSymType (const Export* E)
|
||||
/* External with matching imports */
|
||||
Import* I = E->ImpList;
|
||||
while (I) {
|
||||
if (E->AddrSize != I->AddrSize) {
|
||||
/* Export and import address sizes do not match */
|
||||
if (E->AddrSize != I->AddrSize) {
|
||||
/* Export and import address sizes do not match */
|
||||
StrBuf ExportLoc = STATIC_STRBUF_INITIALIZER;
|
||||
StrBuf ImportLoc = STATIC_STRBUF_INITIALIZER;
|
||||
const char* ExpAddrSize = AddrSizeToStr ((unsigned char) E->AddrSize);
|
||||
@@ -732,8 +732,8 @@ static void CheckSymType (const Export* E)
|
||||
/* Free the temporary strings */
|
||||
SB_Done (&ExportLoc);
|
||||
SB_Done (&ImportLoc);
|
||||
}
|
||||
I = I->Next;
|
||||
}
|
||||
I = I->Next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,11 +746,11 @@ static void CheckSymTypes (void)
|
||||
|
||||
/* Print all open imports */
|
||||
for (I = 0; I < ExpCount; ++I) {
|
||||
const Export* E = ExpPool [I];
|
||||
if (E->Expr != 0 && E->ImpCount > 0) {
|
||||
/* External with matching imports */
|
||||
CheckSymType (E);
|
||||
}
|
||||
const Export* E = ExpPool [I];
|
||||
if (E->Expr != 0 && E->ImpCount > 0) {
|
||||
/* External with matching imports */
|
||||
CheckSymType (E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,14 +765,14 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
||||
|
||||
/* Print all open imports */
|
||||
for (I = 0; I < ExpCount; ++I) {
|
||||
Export* E = ExpPool [I];
|
||||
if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) {
|
||||
/* Unresolved external */
|
||||
Import* Imp = E->ImpList;
|
||||
fprintf (stderr,
|
||||
"Unresolved external `%s' referenced in:\n",
|
||||
GetString (E->Name));
|
||||
while (Imp) {
|
||||
Export* E = ExpPool [I];
|
||||
if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) {
|
||||
/* Unresolved external */
|
||||
Import* Imp = E->ImpList;
|
||||
fprintf (stderr,
|
||||
"Unresolved external `%s' referenced in:\n",
|
||||
GetString (E->Name));
|
||||
while (Imp) {
|
||||
unsigned J;
|
||||
for (J = 0; J < CollCount (&Imp->RefLines); ++J) {
|
||||
const LineInfo* LI = CollConstAt (&Imp->RefLines, J);
|
||||
@@ -781,9 +781,9 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI));
|
||||
}
|
||||
Imp = Imp->Next;
|
||||
}
|
||||
}
|
||||
Imp = Imp->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -805,18 +805,18 @@ static void CreateExportPool (void)
|
||||
|
||||
/* Allocate memory */
|
||||
if (ExpPool) {
|
||||
xfree (ExpPool);
|
||||
xfree (ExpPool);
|
||||
}
|
||||
ExpPool = xmalloc (ExpCount * sizeof (Export*));
|
||||
|
||||
/* Walk through the list and insert the exports */
|
||||
for (I = 0, J = 0; I < sizeof (HashTab) / sizeof (HashTab [0]); ++I) {
|
||||
Export* E = HashTab[I];
|
||||
while (E) {
|
||||
CHECK (J < ExpCount);
|
||||
ExpPool[J++] = E;
|
||||
E = E->Next;
|
||||
}
|
||||
Export* E = HashTab[I];
|
||||
while (E) {
|
||||
CHECK (J < ExpCount);
|
||||
ExpPool[J++] = E;
|
||||
E = E->Next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort them by name */
|
||||
@@ -846,8 +846,8 @@ void CheckUnresolvedImports (ExpCheckFunc F, void* Data)
|
||||
{
|
||||
/* Check for unresolved externals */
|
||||
if (ImpOpen != 0) {
|
||||
/* Print all open imports */
|
||||
PrintUnresolved (F, Data);
|
||||
/* Print all open imports */
|
||||
PrintUnresolved (F, Data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -863,8 +863,8 @@ static char GetAddrSizeCode (unsigned char AddrSize)
|
||||
case ADDR_SIZE_LONG: return 'L';
|
||||
default:
|
||||
Internal ("Invalid address size: %u", AddrSize);
|
||||
/* NOTREACHED */
|
||||
return '-';
|
||||
/* NOTREACHED */
|
||||
return '-';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,23 +879,23 @@ void PrintExportMap (FILE* F)
|
||||
/* Print all exports */
|
||||
Count = 0;
|
||||
for (I = 0; I < ExpCount; ++I) {
|
||||
const Export* E = ExpPool [I];
|
||||
const Export* E = ExpPool [I];
|
||||
|
||||
/* Print unreferenced symbols only if explictly requested */
|
||||
if (VerboseMap || E->ImpCount > 0 || SYM_IS_CONDES (E->Type)) {
|
||||
fprintf (F,
|
||||
"%-25s %06lX %c%c%c%c ",
|
||||
GetString (E->Name),
|
||||
GetExportVal (E),
|
||||
E->ImpCount? 'R' : ' ',
|
||||
SYM_IS_LABEL (E->Type)? 'L' : 'E',
|
||||
GetAddrSizeCode ((unsigned char) E->AddrSize),
|
||||
SYM_IS_CONDES (E->Type)? 'I' : ' ');
|
||||
if (++Count == 2) {
|
||||
Count = 0;
|
||||
fprintf (F, "\n");
|
||||
}
|
||||
}
|
||||
/* Print unreferenced symbols only if explictly requested */
|
||||
if (VerboseMap || E->ImpCount > 0 || SYM_IS_CONDES (E->Type)) {
|
||||
fprintf (F,
|
||||
"%-25s %06lX %c%c%c%c ",
|
||||
GetString (E->Name),
|
||||
GetExportVal (E),
|
||||
E->ImpCount? 'R' : ' ',
|
||||
SYM_IS_LABEL (E->Type)? 'L' : 'E',
|
||||
GetAddrSizeCode ((unsigned char) E->AddrSize),
|
||||
SYM_IS_CONDES (E->Type)? 'I' : ' ');
|
||||
if (++Count == 2) {
|
||||
Count = 0;
|
||||
fprintf (F, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf (F, "\n");
|
||||
}
|
||||
@@ -911,25 +911,25 @@ void PrintImportMap (FILE* F)
|
||||
/* Loop over all exports */
|
||||
for (I = 0; I < ExpCount; ++I) {
|
||||
|
||||
/* Get the export */
|
||||
const Export* Exp = ExpPool [I];
|
||||
/* Get the export */
|
||||
const Export* Exp = ExpPool [I];
|
||||
|
||||
/* Print the symbol only if there are imports, or if a verbose map
|
||||
* file is requested.
|
||||
*/
|
||||
if (VerboseMap || Exp->ImpCount > 0) {
|
||||
/* Print the symbol only if there are imports, or if a verbose map
|
||||
* file is requested.
|
||||
*/
|
||||
if (VerboseMap || Exp->ImpCount > 0) {
|
||||
|
||||
/* Print the export */
|
||||
fprintf (F,
|
||||
"%s (%s):\n",
|
||||
GetString (Exp->Name),
|
||||
GetObjFileName (Exp->Obj));
|
||||
/* Print the export */
|
||||
fprintf (F,
|
||||
"%s (%s):\n",
|
||||
GetString (Exp->Name),
|
||||
GetObjFileName (Exp->Obj));
|
||||
|
||||
/* Print all imports for this symbol */
|
||||
Imp = Exp->ImpList;
|
||||
while (Imp) {
|
||||
/* Print all imports for this symbol */
|
||||
Imp = Exp->ImpList;
|
||||
while (Imp) {
|
||||
|
||||
/* Print the import. Beware: The import might be linker
|
||||
/* Print the import. Beware: The import might be linker
|
||||
* generated, in which case there is no object file and
|
||||
* sometimes no line information.
|
||||
*/
|
||||
@@ -946,10 +946,10 @@ void PrintImportMap (FILE* F)
|
||||
GetObjFileName (Imp->Obj));
|
||||
}
|
||||
|
||||
/* Next import */
|
||||
Imp = Imp->Next;
|
||||
}
|
||||
}
|
||||
/* Next import */
|
||||
Imp = Imp->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf (F, "\n");
|
||||
}
|
||||
@@ -963,8 +963,8 @@ void PrintExportLabels (FILE* F)
|
||||
|
||||
/* Print all exports */
|
||||
for (I = 0; I < ExpCount; ++I) {
|
||||
const Export* E = ExpPool [I];
|
||||
fprintf (F, "al %06lX .%s\n", GetExportVal (E), GetString (E->Name));
|
||||
const Export* E = ExpPool [I];
|
||||
fprintf (F, "al %06lX .%s\n", GetExportVal (E), GetString (E->Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,7 +999,7 @@ void CircularRefError (const Export* E)
|
||||
{
|
||||
const LineInfo* LI = GetExportPos (E);
|
||||
Error ("Circular reference for symbol `%s', %s(%u)",
|
||||
GetString (E->Name),
|
||||
GetString (E->Name),
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* exports.h */
|
||||
/* exports.h */
|
||||
/* */
|
||||
/* Exports handing for the ld65 linker */
|
||||
/* Exports handing for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -62,12 +62,12 @@
|
||||
/* Import symbol structure */
|
||||
typedef struct Import Import;
|
||||
struct Import {
|
||||
Import* Next; /* Single linked list */
|
||||
ObjData* Obj; /* Object file that imports the name */
|
||||
Import* Next; /* Single linked list */
|
||||
ObjData* Obj; /* Object file that imports the name */
|
||||
Collection DefLines; /* Line infos of definition */
|
||||
Collection RefLines; /* Line infos of reference */
|
||||
struct Export* Exp; /* Matching export for this import */
|
||||
unsigned Name; /* Name if not in table */
|
||||
struct Export* Exp; /* Matching export for this import */
|
||||
unsigned Name; /* Name if not in table */
|
||||
unsigned short Flags; /* Generic flags */
|
||||
unsigned short AddrSize; /* Address size of import */
|
||||
};
|
||||
@@ -77,20 +77,20 @@ struct Import {
|
||||
/* Export symbol structure */
|
||||
typedef struct Export Export;
|
||||
struct Export {
|
||||
unsigned Name; /* Name */
|
||||
Export* Next; /* Hash table link */
|
||||
unsigned Flags; /* Generic flags */
|
||||
ObjData* Obj; /* Object file that exports the name */
|
||||
unsigned ImpCount; /* How many imports for this symbol? */
|
||||
Import* ImpList; /* List of imports for this symbol */
|
||||
ExprNode* Expr; /* Expression (0 if not def'd) */
|
||||
unsigned Name; /* Name */
|
||||
Export* Next; /* Hash table link */
|
||||
unsigned Flags; /* Generic flags */
|
||||
ObjData* Obj; /* Object file that exports the name */
|
||||
unsigned ImpCount; /* How many imports for this symbol? */
|
||||
Import* ImpList; /* List of imports for this symbol */
|
||||
ExprNode* Expr; /* Expression (0 if not def'd) */
|
||||
unsigned Size; /* Size of the symbol if any */
|
||||
Collection DefLines; /* Line infos of definition */
|
||||
Collection RefLines; /* Line infos of reference */
|
||||
unsigned DbgSymId; /* Id of debug symbol for this export */
|
||||
unsigned short Type; /* Type of export */
|
||||
unsigned short Type; /* Type of export */
|
||||
unsigned short AddrSize; /* Address size of export */
|
||||
unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */
|
||||
unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */
|
||||
};
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ typedef int (*ExpCheckFunc) (unsigned Name, void* Data);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
498
src/ld65/expr.c
498
src/ld65/expr.c
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* expr.c */
|
||||
/* expr.c */
|
||||
/* */
|
||||
/* Expression evaluation for the ld65 linker */
|
||||
/* Expression evaluation for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -59,11 +59,11 @@ ExprNode* NewExprNode (ObjData* O, unsigned char Op)
|
||||
{
|
||||
/* Allocate fresh memory */
|
||||
ExprNode* N = xmalloc (sizeof (ExprNode));
|
||||
N->Op = Op;
|
||||
N->Left = 0;
|
||||
N->Right = 0;
|
||||
N->Obj = O;
|
||||
N->V.IVal = 0;
|
||||
N->Op = Op;
|
||||
N->Left = 0;
|
||||
N->Right = 0;
|
||||
N->Obj = O;
|
||||
N->V.IVal = 0;
|
||||
|
||||
return N;
|
||||
}
|
||||
@@ -83,9 +83,9 @@ void FreeExpr (ExprNode* Root)
|
||||
/* Free the expression, Root is pointing to. */
|
||||
{
|
||||
if (Root) {
|
||||
FreeExpr (Root->Left);
|
||||
FreeExpr (Root->Right);
|
||||
FreeExprNode (Root);
|
||||
FreeExpr (Root->Left);
|
||||
FreeExpr (Root->Right);
|
||||
FreeExprNode (Root);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,27 +102,27 @@ int IsConstExpr (ExprNode* Root)
|
||||
MemoryArea* M;
|
||||
|
||||
if (EXPR_IS_LEAF (Root->Op)) {
|
||||
switch (Root->Op) {
|
||||
switch (Root->Op) {
|
||||
|
||||
case EXPR_LITERAL:
|
||||
return 1;
|
||||
case EXPR_LITERAL:
|
||||
return 1;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Root);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
case EXPR_SYMBOL:
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Root);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
Const = 0;
|
||||
} else {
|
||||
MarkExport (E);
|
||||
Const = IsConstExport (E);
|
||||
UnmarkExport (E);
|
||||
}
|
||||
return Const;
|
||||
Const = 0;
|
||||
} else {
|
||||
MarkExport (E);
|
||||
Const = IsConstExport (E);
|
||||
UnmarkExport (E);
|
||||
}
|
||||
return Const;
|
||||
|
||||
case EXPR_SECTION:
|
||||
/* A section expression is const if the segment it is in is
|
||||
@@ -142,11 +142,11 @@ int IsConstExpr (ExprNode* Root)
|
||||
return !Root->V.Mem->Relocatable &&
|
||||
(Root->V.Mem->Flags & MF_PLACED);
|
||||
|
||||
default:
|
||||
default:
|
||||
/* Anything else is not const */
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else if (EXPR_IS_UNARY (Root->Op)) {
|
||||
|
||||
@@ -177,41 +177,41 @@ int IsConstExpr (ExprNode* Root)
|
||||
|
||||
} else {
|
||||
|
||||
/* We must handle shortcut boolean expressions here */
|
||||
switch (Root->Op) {
|
||||
/* We must handle shortcut boolean expressions here */
|
||||
switch (Root->Op) {
|
||||
|
||||
case EXPR_BOOLAND:
|
||||
if (IsConstExpr (Root->Left)) {
|
||||
/* lhs is const, if it is zero, don't eval right */
|
||||
if (GetExprVal (Root->Left) == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return IsConstExpr (Root->Right);
|
||||
}
|
||||
} else {
|
||||
/* lhs not const --> tree not const */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case EXPR_BOOLAND:
|
||||
if (IsConstExpr (Root->Left)) {
|
||||
/* lhs is const, if it is zero, don't eval right */
|
||||
if (GetExprVal (Root->Left) == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return IsConstExpr (Root->Right);
|
||||
}
|
||||
} else {
|
||||
/* lhs not const --> tree not const */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case EXPR_BOOLOR:
|
||||
if (IsConstExpr (Root->Left)) {
|
||||
/* lhs is const, if it is not zero, don't eval right */
|
||||
if (GetExprVal (Root->Left) != 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return IsConstExpr (Root->Right);
|
||||
}
|
||||
} else {
|
||||
/* lhs not const --> tree not const */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case EXPR_BOOLOR:
|
||||
if (IsConstExpr (Root->Left)) {
|
||||
/* lhs is const, if it is not zero, don't eval right */
|
||||
if (GetExprVal (Root->Left) != 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return IsConstExpr (Root->Right);
|
||||
}
|
||||
} else {
|
||||
/* lhs not const --> tree not const */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* All others are handled normal */
|
||||
return IsConstExpr (Root->Left) && IsConstExpr (Root->Right);
|
||||
}
|
||||
default:
|
||||
/* All others are handled normal */
|
||||
return IsConstExpr (Root->Left) && IsConstExpr (Root->Right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,10 +228,10 @@ Import* GetExprImport (ExprNode* Expr)
|
||||
* import pointer.
|
||||
*/
|
||||
if (Expr->Obj) {
|
||||
/* Return the Import */
|
||||
return GetObjImport (Expr->Obj, Expr->V.ImpNum);
|
||||
/* Return the Import */
|
||||
return GetObjImport (Expr->Obj, Expr->V.ImpNum);
|
||||
} else {
|
||||
return Expr->V.Imp;
|
||||
return Expr->V.Imp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,10 +260,10 @@ Section* GetExprSection (ExprNode* Expr)
|
||||
* section pointer.
|
||||
*/
|
||||
if (Expr->Obj) {
|
||||
/* Return the export */
|
||||
return CollAt (&Expr->Obj->Sections, Expr->V.SecNum);
|
||||
/* Return the export */
|
||||
return CollAt (&Expr->Obj->Sections, Expr->V.SecNum);
|
||||
} else {
|
||||
return Expr->V.Sec;
|
||||
return Expr->V.Sec;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,102 +281,102 @@ long GetExprVal (ExprNode* Expr)
|
||||
|
||||
switch (Expr->Op) {
|
||||
|
||||
case EXPR_LITERAL:
|
||||
return Expr->V.IVal;
|
||||
case EXPR_LITERAL:
|
||||
return Expr->V.IVal;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Expr);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
Val = 0;
|
||||
} else {
|
||||
MarkExport (E);
|
||||
Val = GetExportVal (E);
|
||||
UnmarkExport (E);
|
||||
}
|
||||
return Val;
|
||||
case EXPR_SYMBOL:
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Expr);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
Val = 0;
|
||||
} else {
|
||||
MarkExport (E);
|
||||
Val = GetExportVal (E);
|
||||
UnmarkExport (E);
|
||||
}
|
||||
return Val;
|
||||
|
||||
case EXPR_SECTION:
|
||||
S = GetExprSection (Expr);
|
||||
return S->Offs + S->Seg->PC;
|
||||
S = GetExprSection (Expr);
|
||||
return S->Offs + S->Seg->PC;
|
||||
|
||||
case EXPR_SEGMENT:
|
||||
return Expr->V.Seg->PC;
|
||||
case EXPR_SEGMENT:
|
||||
return Expr->V.Seg->PC;
|
||||
|
||||
case EXPR_MEMAREA:
|
||||
return Expr->V.Mem->Start;
|
||||
|
||||
case EXPR_PLUS:
|
||||
return GetExprVal (Expr->Left) + GetExprVal (Expr->Right);
|
||||
case EXPR_PLUS:
|
||||
return GetExprVal (Expr->Left) + GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_MINUS:
|
||||
return GetExprVal (Expr->Left) - GetExprVal (Expr->Right);
|
||||
case EXPR_MINUS:
|
||||
return GetExprVal (Expr->Left) - GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_MUL:
|
||||
return GetExprVal (Expr->Left) * GetExprVal (Expr->Right);
|
||||
case EXPR_MUL:
|
||||
return GetExprVal (Expr->Left) * GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_DIV:
|
||||
Left = GetExprVal (Expr->Left);
|
||||
Right = GetExprVal (Expr->Right);
|
||||
if (Right == 0) {
|
||||
Error ("Division by zero");
|
||||
}
|
||||
return Left / Right;
|
||||
case EXPR_DIV:
|
||||
Left = GetExprVal (Expr->Left);
|
||||
Right = GetExprVal (Expr->Right);
|
||||
if (Right == 0) {
|
||||
Error ("Division by zero");
|
||||
}
|
||||
return Left / Right;
|
||||
|
||||
case EXPR_MOD:
|
||||
Left = GetExprVal (Expr->Left);
|
||||
Right = GetExprVal (Expr->Right);
|
||||
if (Right == 0) {
|
||||
Error ("Modulo operation with zero");
|
||||
}
|
||||
return Left % Right;
|
||||
case EXPR_MOD:
|
||||
Left = GetExprVal (Expr->Left);
|
||||
Right = GetExprVal (Expr->Right);
|
||||
if (Right == 0) {
|
||||
Error ("Modulo operation with zero");
|
||||
}
|
||||
return Left % Right;
|
||||
|
||||
case EXPR_OR:
|
||||
return GetExprVal (Expr->Left) | GetExprVal (Expr->Right);
|
||||
case EXPR_OR:
|
||||
return GetExprVal (Expr->Left) | GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_XOR:
|
||||
return GetExprVal (Expr->Left) ^ GetExprVal (Expr->Right);
|
||||
case EXPR_XOR:
|
||||
return GetExprVal (Expr->Left) ^ GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_AND:
|
||||
return GetExprVal (Expr->Left) & GetExprVal (Expr->Right);
|
||||
case EXPR_AND:
|
||||
return GetExprVal (Expr->Left) & GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_SHL:
|
||||
return GetExprVal (Expr->Left) << GetExprVal (Expr->Right);
|
||||
case EXPR_SHL:
|
||||
return GetExprVal (Expr->Left) << GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_SHR:
|
||||
return GetExprVal (Expr->Left) >> GetExprVal (Expr->Right);
|
||||
case EXPR_SHR:
|
||||
return GetExprVal (Expr->Left) >> GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_EQ:
|
||||
return (GetExprVal (Expr->Left) == GetExprVal (Expr->Right));
|
||||
case EXPR_EQ:
|
||||
return (GetExprVal (Expr->Left) == GetExprVal (Expr->Right));
|
||||
|
||||
case EXPR_NE:
|
||||
return (GetExprVal (Expr->Left) != GetExprVal (Expr->Right));
|
||||
case EXPR_NE:
|
||||
return (GetExprVal (Expr->Left) != GetExprVal (Expr->Right));
|
||||
|
||||
case EXPR_LT:
|
||||
return (GetExprVal (Expr->Left) < GetExprVal (Expr->Right));
|
||||
case EXPR_LT:
|
||||
return (GetExprVal (Expr->Left) < GetExprVal (Expr->Right));
|
||||
|
||||
case EXPR_GT:
|
||||
return (GetExprVal (Expr->Left) > GetExprVal (Expr->Right));
|
||||
case EXPR_GT:
|
||||
return (GetExprVal (Expr->Left) > GetExprVal (Expr->Right));
|
||||
|
||||
case EXPR_LE:
|
||||
return (GetExprVal (Expr->Left) <= GetExprVal (Expr->Right));
|
||||
case EXPR_LE:
|
||||
return (GetExprVal (Expr->Left) <= GetExprVal (Expr->Right));
|
||||
|
||||
case EXPR_GE:
|
||||
return (GetExprVal (Expr->Left) >= GetExprVal (Expr->Right));
|
||||
case EXPR_GE:
|
||||
return (GetExprVal (Expr->Left) >= GetExprVal (Expr->Right));
|
||||
|
||||
case EXPR_BOOLAND:
|
||||
return GetExprVal (Expr->Left) && GetExprVal (Expr->Right);
|
||||
case EXPR_BOOLAND:
|
||||
return GetExprVal (Expr->Left) && GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_BOOLOR:
|
||||
return GetExprVal (Expr->Left) || GetExprVal (Expr->Right);
|
||||
case EXPR_BOOLOR:
|
||||
return GetExprVal (Expr->Left) || GetExprVal (Expr->Right);
|
||||
|
||||
case EXPR_BOOLXOR:
|
||||
return (GetExprVal (Expr->Left) != 0) ^ (GetExprVal (Expr->Right) != 0);
|
||||
case EXPR_BOOLXOR:
|
||||
return (GetExprVal (Expr->Left) != 0) ^ (GetExprVal (Expr->Right) != 0);
|
||||
|
||||
case EXPR_MAX:
|
||||
Left = GetExprVal (Expr->Left);
|
||||
@@ -388,18 +388,18 @@ long GetExprVal (ExprNode* Expr)
|
||||
Right = GetExprVal (Expr->Right);
|
||||
return (Left < Right)? Left : Right;
|
||||
|
||||
case EXPR_UNARY_MINUS:
|
||||
return -GetExprVal (Expr->Left);
|
||||
case EXPR_UNARY_MINUS:
|
||||
return -GetExprVal (Expr->Left);
|
||||
|
||||
case EXPR_NOT:
|
||||
return ~GetExprVal (Expr->Left);
|
||||
case EXPR_NOT:
|
||||
return ~GetExprVal (Expr->Left);
|
||||
|
||||
case EXPR_SWAP:
|
||||
Left = GetExprVal (Expr->Left);
|
||||
return ((Left >> 8) & 0x00FF) | ((Left << 8) & 0xFF00);
|
||||
Left = GetExprVal (Expr->Left);
|
||||
return ((Left >> 8) & 0x00FF) | ((Left << 8) & 0xFF00);
|
||||
|
||||
case EXPR_BOOLNOT:
|
||||
return !GetExprVal (Expr->Left);
|
||||
case EXPR_BOOLNOT:
|
||||
return !GetExprVal (Expr->Left);
|
||||
|
||||
case EXPR_BANK:
|
||||
GetSegExprVal (Expr->Left, &D);
|
||||
@@ -418,23 +418,23 @@ long GetExprVal (ExprNode* Expr)
|
||||
}
|
||||
return GetExprVal (D.Seg->MemArea->BankExpr);
|
||||
|
||||
case EXPR_BYTE0:
|
||||
return GetExprVal (Expr->Left) & 0xFF;
|
||||
case EXPR_BYTE0:
|
||||
return GetExprVal (Expr->Left) & 0xFF;
|
||||
|
||||
case EXPR_BYTE1:
|
||||
return (GetExprVal (Expr->Left) >> 8) & 0xFF;
|
||||
case EXPR_BYTE1:
|
||||
return (GetExprVal (Expr->Left) >> 8) & 0xFF;
|
||||
|
||||
case EXPR_BYTE2:
|
||||
return (GetExprVal (Expr->Left) >> 16) & 0xFF;
|
||||
case EXPR_BYTE2:
|
||||
return (GetExprVal (Expr->Left) >> 16) & 0xFF;
|
||||
|
||||
case EXPR_BYTE3:
|
||||
return (GetExprVal (Expr->Left) >> 24) & 0xFF;
|
||||
case EXPR_BYTE3:
|
||||
return (GetExprVal (Expr->Left) >> 24) & 0xFF;
|
||||
|
||||
case EXPR_WORD0:
|
||||
return GetExprVal (Expr->Left) & 0xFFFF;
|
||||
case EXPR_WORD0:
|
||||
return GetExprVal (Expr->Left) & 0xFFFF;
|
||||
|
||||
case EXPR_WORD1:
|
||||
return (GetExprVal (Expr->Left) >> 16) & 0xFFFF;
|
||||
case EXPR_WORD1:
|
||||
return (GetExprVal (Expr->Left) >> 16) & 0xFFFF;
|
||||
|
||||
case EXPR_FARADDR:
|
||||
return GetExprVal (Expr->Left) & 0xFFFFFF;
|
||||
@@ -443,9 +443,9 @@ long GetExprVal (ExprNode* Expr)
|
||||
return GetExprVal (Expr->Left) & 0xFFFFFFFF;
|
||||
|
||||
default:
|
||||
Internal ("Unknown expression Op type: %u", Expr->Op);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
Internal ("Unknown expression Op type: %u", Expr->Op);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,66 +462,66 @@ static void GetSegExprValInternal (ExprNode* Expr, SegExprDesc* D, int Sign)
|
||||
|
||||
switch (Expr->Op) {
|
||||
|
||||
case EXPR_LITERAL:
|
||||
case EXPR_LITERAL:
|
||||
D->Val += (Sign * Expr->V.IVal);
|
||||
break;
|
||||
break;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Expr);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
} else {
|
||||
MarkExport (E);
|
||||
GetSegExprValInternal (E->Expr, D, Sign);
|
||||
UnmarkExport (E);
|
||||
}
|
||||
break;
|
||||
case EXPR_SYMBOL:
|
||||
/* Get the referenced export */
|
||||
E = GetExprExport (Expr);
|
||||
/* If this export has a mark set, we've already encountered it.
|
||||
* This means that the export is used to define it's own value,
|
||||
* which in turn means, that we have a circular reference.
|
||||
*/
|
||||
if (ExportHasMark (E)) {
|
||||
CircularRefError (E);
|
||||
} else {
|
||||
MarkExport (E);
|
||||
GetSegExprValInternal (E->Expr, D, Sign);
|
||||
UnmarkExport (E);
|
||||
}
|
||||
break;
|
||||
|
||||
case EXPR_SECTION:
|
||||
if (D->Seg) {
|
||||
/* We cannot handle more than one segment reference in o65 */
|
||||
D->TooComplex = 1;
|
||||
} else {
|
||||
case EXPR_SECTION:
|
||||
if (D->Seg) {
|
||||
/* We cannot handle more than one segment reference in o65 */
|
||||
D->TooComplex = 1;
|
||||
} else {
|
||||
/* Get the section from the expression */
|
||||
Section* S = GetExprSection (Expr);
|
||||
/* Remember the segment reference */
|
||||
D->Seg = S->Seg;
|
||||
/* Remember the segment reference */
|
||||
D->Seg = S->Seg;
|
||||
/* Add the offset of the section to the constant value */
|
||||
D->Val += Sign * (S->Offs + D->Seg->PC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EXPR_SEGMENT:
|
||||
if (D->Seg) {
|
||||
/* We cannot handle more than one segment reference in o65 */
|
||||
D->TooComplex = 1;
|
||||
} else {
|
||||
/* Remember the segment reference */
|
||||
D->Seg = Expr->V.Seg;
|
||||
if (D->Seg) {
|
||||
/* We cannot handle more than one segment reference in o65 */
|
||||
D->TooComplex = 1;
|
||||
} else {
|
||||
/* Remember the segment reference */
|
||||
D->Seg = Expr->V.Seg;
|
||||
/* Add the offset of the segment to the constant value */
|
||||
D->Val += (Sign * D->Seg->PC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EXPR_PLUS:
|
||||
GetSegExprValInternal (Expr->Left, D, Sign);
|
||||
GetSegExprValInternal (Expr->Right, D, Sign);
|
||||
break;
|
||||
case EXPR_PLUS:
|
||||
GetSegExprValInternal (Expr->Left, D, Sign);
|
||||
GetSegExprValInternal (Expr->Right, D, Sign);
|
||||
break;
|
||||
|
||||
case EXPR_MINUS:
|
||||
GetSegExprValInternal (Expr->Left, D, Sign);
|
||||
GetSegExprValInternal (Expr->Right, D, -Sign);
|
||||
break;
|
||||
case EXPR_MINUS:
|
||||
GetSegExprValInternal (Expr->Left, D, Sign);
|
||||
GetSegExprValInternal (Expr->Right, D, -Sign);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Expression contains illegal operators */
|
||||
D->TooComplex = 1;
|
||||
break;
|
||||
default:
|
||||
/* Expression contains illegal operators */
|
||||
D->TooComplex = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -626,7 +626,7 @@ ExprNode* ReadExpr (FILE* F, ObjData* O)
|
||||
/* Read the node tag and handle NULL nodes */
|
||||
unsigned char Op = Read8 (F);
|
||||
if (Op == EXPR_NULL) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a new node */
|
||||
@@ -634,32 +634,32 @@ ExprNode* ReadExpr (FILE* F, ObjData* O)
|
||||
|
||||
/* Check the tag and handle the different expression types */
|
||||
if (EXPR_IS_LEAF (Op)) {
|
||||
switch (Op) {
|
||||
switch (Op) {
|
||||
|
||||
case EXPR_LITERAL:
|
||||
Expr->V.IVal = Read32Signed (F);
|
||||
break;
|
||||
case EXPR_LITERAL:
|
||||
Expr->V.IVal = Read32Signed (F);
|
||||
break;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
/* Read the import number */
|
||||
Expr->V.ImpNum = ReadVar (F);
|
||||
break;
|
||||
case EXPR_SYMBOL:
|
||||
/* Read the import number */
|
||||
Expr->V.ImpNum = ReadVar (F);
|
||||
break;
|
||||
|
||||
case EXPR_SECTION:
|
||||
/* Read the section number */
|
||||
Expr->V.SecNum = ReadVar (F);
|
||||
break;
|
||||
case EXPR_SECTION:
|
||||
/* Read the section number */
|
||||
Expr->V.SecNum = ReadVar (F);
|
||||
break;
|
||||
|
||||
default:
|
||||
Error ("Invalid expression op: %02X", Op);
|
||||
default:
|
||||
Error ("Invalid expression op: %02X", Op);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Not a leaf node */
|
||||
Expr->Left = ReadExpr (F, O);
|
||||
Expr->Right = ReadExpr (F, O);
|
||||
/* Not a leaf node */
|
||||
Expr->Left = ReadExpr (F, O);
|
||||
Expr->Right = ReadExpr (F, O);
|
||||
|
||||
}
|
||||
|
||||
@@ -674,43 +674,43 @@ int EqualExpr (ExprNode* E1, ExprNode* E2)
|
||||
{
|
||||
/* If one pointer is NULL, both must be NULL */
|
||||
if ((E1 == 0) ^ (E2 == 0)) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
if (E1 == 0) {
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Both pointers not NULL, check OP */
|
||||
if (E1->Op != E2->Op) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* OPs are identical, check data for leafs, or subtrees */
|
||||
switch (E1->Op) {
|
||||
|
||||
case EXPR_LITERAL:
|
||||
/* Value must be identical */
|
||||
return (E1->V.IVal == E2->V.IVal);
|
||||
case EXPR_LITERAL:
|
||||
/* Value must be identical */
|
||||
return (E1->V.IVal == E2->V.IVal);
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
/* Import must be identical */
|
||||
return (GetExprImport (E1) == GetExprImport (E2));
|
||||
case EXPR_SYMBOL:
|
||||
/* Import must be identical */
|
||||
return (GetExprImport (E1) == GetExprImport (E2));
|
||||
|
||||
case EXPR_SECTION:
|
||||
/* Section must be identical */
|
||||
return (GetExprSection (E1) == GetExprSection (E2));
|
||||
case EXPR_SECTION:
|
||||
/* Section must be identical */
|
||||
return (GetExprSection (E1) == GetExprSection (E2));
|
||||
|
||||
case EXPR_SEGMENT:
|
||||
/* Segment must be identical */
|
||||
return (E1->V.Seg == E2->V.Seg);
|
||||
case EXPR_SEGMENT:
|
||||
/* Segment must be identical */
|
||||
return (E1->V.Seg == E2->V.Seg);
|
||||
|
||||
case EXPR_MEMAREA:
|
||||
/* Memory area must be identical */
|
||||
return (E1->V.Mem == E2->V.Mem);
|
||||
case EXPR_MEMAREA:
|
||||
/* Memory area must be identical */
|
||||
return (E1->V.Mem == E2->V.Mem);
|
||||
|
||||
default:
|
||||
/* Not a leaf node */
|
||||
return EqualExpr (E1->Left, E2->Left) && EqualExpr (E1->Right, E2->Right);
|
||||
default:
|
||||
/* Not a leaf node */
|
||||
return EqualExpr (E1->Left, E2->Left) && EqualExpr (E1->Right, E2->Right);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* expr.h */
|
||||
/* expr.h */
|
||||
/* */
|
||||
/* Expression evaluation for the ld65 linker */
|
||||
/* Expression evaluation for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -57,15 +57,15 @@
|
||||
/* Structure for parsing segment based expression trees */
|
||||
typedef struct SegExprDesc SegExprDesc;
|
||||
struct SegExprDesc {
|
||||
long Val; /* The offset value */
|
||||
int TooComplex; /* Expression too complex */
|
||||
long Val; /* The offset value */
|
||||
int TooComplex; /* Expression too complex */
|
||||
Segment* Seg; /* Segment reference if any */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* extsyms.c */
|
||||
/* extsyms.c */
|
||||
/* */
|
||||
/* Handle program external symbols for relocatable output formats */
|
||||
/* Handle program external symbols for relocatable output formats */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -47,34 +47,34 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Structure holding an external symbol */
|
||||
struct ExtSym {
|
||||
unsigned Name; /* Name index */
|
||||
ExtSym* List; /* Next entry in list of all symbols */
|
||||
ExtSym* Next; /* Next entry in hash list */
|
||||
unsigned Flags; /* Generic flags */
|
||||
unsigned Num; /* Number of external symbol */
|
||||
unsigned Name; /* Name index */
|
||||
ExtSym* List; /* Next entry in list of all symbols */
|
||||
ExtSym* Next; /* Next entry in hash list */
|
||||
unsigned Flags; /* Generic flags */
|
||||
unsigned Num; /* Number of external symbol */
|
||||
};
|
||||
|
||||
/* External symbol table structure */
|
||||
#define HASHTAB_MASK 0x3FU
|
||||
#define HASHTAB_SIZE (HASHTAB_MASK + 1)
|
||||
#define HASHTAB_SIZE (HASHTAB_MASK + 1)
|
||||
struct ExtSymTab {
|
||||
ExtSym* Root; /* List of symbols */
|
||||
ExtSym* Last; /* Pointer to last symbol */
|
||||
unsigned Count; /* Number of symbols */
|
||||
ExtSym* HashTab[HASHTAB_SIZE];
|
||||
ExtSym* Root; /* List of symbols */
|
||||
ExtSym* Last; /* Pointer to last symbol */
|
||||
unsigned Count; /* Number of symbols */
|
||||
ExtSym* HashTab[HASHTAB_SIZE];
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -86,10 +86,10 @@ ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name)
|
||||
unsigned Hash = (Name & HASHTAB_MASK);
|
||||
|
||||
/* Check for duplicates */
|
||||
ExtSym* E = GetExtSym (Tab, Name);
|
||||
ExtSym* E = GetExtSym (Tab, Name);
|
||||
if (E != 0) {
|
||||
/* We do already have a symbol with this name */
|
||||
Error ("Duplicate external symbol `%s'", GetString (Name));
|
||||
/* We do already have a symbol with this name */
|
||||
Error ("Duplicate external symbol `%s'", GetString (Name));
|
||||
}
|
||||
|
||||
/* Allocate memory for the structure */
|
||||
@@ -103,11 +103,11 @@ ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name)
|
||||
|
||||
/* Insert the entry into the list of all symbols */
|
||||
if (Tab->Last == 0) {
|
||||
/* List is empty */
|
||||
Tab->Root = E;
|
||||
/* List is empty */
|
||||
Tab->Root = E;
|
||||
} else {
|
||||
/* List not empty */
|
||||
Tab->Last->List = E;
|
||||
/* List not empty */
|
||||
Tab->Last->List = E;
|
||||
}
|
||||
Tab->Last = E;
|
||||
++Tab->Count;
|
||||
@@ -141,11 +141,11 @@ ExtSymTab* NewExtSymTab (void)
|
||||
ExtSymTab* Tab = xmalloc (sizeof (ExtSymTab));
|
||||
|
||||
/* Initialize the fields */
|
||||
Tab->Root = 0;
|
||||
Tab->Root = 0;
|
||||
Tab->Last = 0;
|
||||
Tab->Count = 0;
|
||||
for (I = 0; I < HASHTAB_SIZE; ++I) {
|
||||
Tab->HashTab [I] = 0;
|
||||
Tab->HashTab [I] = 0;
|
||||
}
|
||||
|
||||
/* Done, return the hash table */
|
||||
@@ -159,9 +159,9 @@ void FreeExtSymTab (ExtSymTab* Tab)
|
||||
{
|
||||
/* Free all entries */
|
||||
while (Tab->Root) {
|
||||
ExtSym* E = Tab->Root;
|
||||
Tab->Root = E->Next;
|
||||
FreeExtSym (E);
|
||||
ExtSym* E = Tab->Root;
|
||||
Tab->Root = E->Next;
|
||||
FreeExtSym (E);
|
||||
}
|
||||
|
||||
/* Free the struct itself */
|
||||
@@ -181,11 +181,11 @@ ExtSym* GetExtSym (const ExtSymTab* Tab, unsigned Name)
|
||||
/* Check the linked list */
|
||||
ExtSym* E = Tab->HashTab[Hash];
|
||||
while (E) {
|
||||
if (E->Name == Name) {
|
||||
/* Found it */
|
||||
break;
|
||||
}
|
||||
E = E->Next;
|
||||
if (E->Name == Name) {
|
||||
/* Found it */
|
||||
break;
|
||||
}
|
||||
E = E->Next;
|
||||
}
|
||||
|
||||
/* Return the symbol we found */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* extsyms.h */
|
||||
/* extsyms.h */
|
||||
/* */
|
||||
/* Handle program external symbols for relocatable output formats */
|
||||
/* Handle program external symbols for relocatable output formats */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ typedef struct ExtSymTab ExtSymTab;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fileinfo.c */
|
||||
/* fileinfo.c */
|
||||
/* */
|
||||
/* Source file info structure */
|
||||
/* Source file info structure */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -57,7 +57,7 @@ static Collection FileInfos = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fileinfo.h */
|
||||
/* fileinfo.h */
|
||||
/* */
|
||||
/* Source file info structure */
|
||||
/* Source file info structure */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
typedef struct FileInfo FileInfo;
|
||||
struct FileInfo {
|
||||
unsigned Id; /* Id of file for debug info */
|
||||
unsigned Name; /* File name index */
|
||||
unsigned Name; /* File name index */
|
||||
unsigned long MTime; /* Time of last modification */
|
||||
unsigned long Size; /* Size of the file */
|
||||
Collection Modules; /* Modules that use this file */
|
||||
@@ -67,7 +67,7 @@ struct FileInfo {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fileio.c */
|
||||
/* fileio.c */
|
||||
/* */
|
||||
/* File I/O for the ld65 linker */
|
||||
/* File I/O for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ void FileSetPos (FILE* F, unsigned long Pos)
|
||||
/* Seek to the given absolute position, fail on errors */
|
||||
{
|
||||
if (fseek (F, Pos, SEEK_SET) != 0) {
|
||||
Error ("Cannot seek: %s", strerror (errno));
|
||||
Error ("Cannot seek: %s", strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ unsigned long FileGetPos (FILE* F)
|
||||
{
|
||||
long Pos = ftell (F);
|
||||
if (Pos < 0) {
|
||||
Error ("Error in ftell: %s", strerror (errno));
|
||||
Error ("Error in ftell: %s", strerror (errno));
|
||||
}
|
||||
return Pos;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ void Write8 (FILE* F, unsigned Val)
|
||||
/* Write an 8 bit value to the file */
|
||||
{
|
||||
if (putc (Val, F) == EOF) {
|
||||
Error ("Write error (disk full?)");
|
||||
Error ("Write error (disk full?)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,24 +119,24 @@ void WriteVal (FILE* F, unsigned long Val, unsigned Size)
|
||||
{
|
||||
switch (Size) {
|
||||
|
||||
case 1:
|
||||
Write8 (F, Val);
|
||||
break;
|
||||
case 1:
|
||||
Write8 (F, Val);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Write16 (F, Val);
|
||||
break;
|
||||
case 2:
|
||||
Write16 (F, Val);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
Write24 (F, Val);
|
||||
break;
|
||||
case 3:
|
||||
Write24 (F, Val);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Write32 (F, Val);
|
||||
break;
|
||||
case 4:
|
||||
Write32 (F, Val);
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("WriteVal: Invalid size: %u", Size);
|
||||
default:
|
||||
Internal ("WriteVal: Invalid size: %u", Size);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -152,12 +152,12 @@ void WriteVar (FILE* F, unsigned long V)
|
||||
* needing 5 bytes if a 32 bit value is written to file.
|
||||
*/
|
||||
do {
|
||||
unsigned char C = (V & 0x7F);
|
||||
V >>= 7;
|
||||
if (V) {
|
||||
C |= 0x80;
|
||||
}
|
||||
Write8 (F, C);
|
||||
unsigned char C = (V & 0x7F);
|
||||
V >>= 7;
|
||||
if (V) {
|
||||
C |= 0x80;
|
||||
}
|
||||
Write8 (F, C);
|
||||
} while (V != 0);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ void WriteData (FILE* F, const void* Data, unsigned Size)
|
||||
/* Write data to the file */
|
||||
{
|
||||
if (fwrite (Data, 1, Size, F) != Size) {
|
||||
Error ("Write error (disk full?)");
|
||||
Error ("Write error (disk full?)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ void WriteMult (FILE* F, unsigned char Val, unsigned long Count)
|
||||
/* Write one byte several times to the file */
|
||||
{
|
||||
while (Count--) {
|
||||
Write8 (F, Val);
|
||||
Write8 (F, Val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ unsigned Read8 (FILE* F)
|
||||
int C = getc (F);
|
||||
if (C == EOF) {
|
||||
long Pos = ftell (F);
|
||||
Error ("Read error at position %ld (file corrupt?)", Pos);
|
||||
Error ("Read error at position %ld (file corrupt?)", Pos);
|
||||
}
|
||||
return C;
|
||||
}
|
||||
@@ -244,8 +244,8 @@ long Read32Signed (FILE* F)
|
||||
|
||||
/* Sign extend the value */
|
||||
if (V & 0x80000000UL) {
|
||||
/* Signed value */
|
||||
V |= ~0xFFFFFFFFUL;
|
||||
/* Signed value */
|
||||
V |= ~0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
/* Return it as a long */
|
||||
@@ -264,12 +264,12 @@ unsigned long ReadVar (FILE* F)
|
||||
unsigned long V = 0;
|
||||
unsigned Shift = 0;
|
||||
do {
|
||||
/* Read one byte */
|
||||
C = Read8 (F);
|
||||
/* Encode it into the target value */
|
||||
V |= ((unsigned long)(C & 0x7F)) << Shift;
|
||||
/* Next value */
|
||||
Shift += 7;
|
||||
/* Read one byte */
|
||||
C = Read8 (F);
|
||||
/* Encode it into the target value */
|
||||
V |= ((unsigned long)(C & 0x7F)) << Shift;
|
||||
/* Next value */
|
||||
Shift += 7;
|
||||
} while (C & 0x80);
|
||||
|
||||
/* Return the value read */
|
||||
@@ -312,7 +312,7 @@ FilePos* ReadFilePos (FILE* F, FilePos* Pos)
|
||||
/* Read a file position from the file */
|
||||
{
|
||||
/* Read the data fields */
|
||||
Pos->Line = ReadVar (F);
|
||||
Pos->Line = ReadVar (F);
|
||||
Pos->Col = ReadVar (F);
|
||||
Pos->Name = ReadVar (F);
|
||||
return Pos;
|
||||
@@ -325,10 +325,10 @@ void* ReadData (FILE* F, void* Data, unsigned Size)
|
||||
{
|
||||
/* Explicitly allow reading zero bytes */
|
||||
if (Size > 0) {
|
||||
if (fread (Data, 1, Size, F) != Size) {
|
||||
if (fread (Data, 1, Size, F) != Size) {
|
||||
long Pos = ftell (F);
|
||||
Error ("Read error at position %ld (file corrupt?)", Pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Data;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fileio.h */
|
||||
/* fileio.h */
|
||||
/* */
|
||||
/* File I/O for the ld65 linker */
|
||||
/* File I/O for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* filepath.c */
|
||||
/* filepath.c */
|
||||
/* */
|
||||
/* File search path handling for ld65 */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ SearchPath* CfgDefaultPath; /* Default Config file path */
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* filepath.h */
|
||||
/* filepath.h */
|
||||
/* */
|
||||
/* File search path handling for ld65 */
|
||||
/* */
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ extern SearchPath* CfgDefaultPath; /* Default Config file path */
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fragment.c */
|
||||
/* fragment.c */
|
||||
/* */
|
||||
/* Code/data fragment routines */
|
||||
/* Code/data fragment routines */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -78,10 +78,10 @@ Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S)
|
||||
|
||||
/* Insert the code fragment into the section */
|
||||
if (S->FragRoot == 0) {
|
||||
/* First fragment */
|
||||
S->FragRoot = F;
|
||||
/* First fragment */
|
||||
S->FragRoot = F;
|
||||
} else {
|
||||
S->FragLast->Next = F;
|
||||
S->FragLast->Next = F;
|
||||
}
|
||||
S->FragLast = F;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* fragment.h */
|
||||
/* fragment.h */
|
||||
/* */
|
||||
/* Code/data fragment routines */
|
||||
/* Code/data fragment routines */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Forwards */
|
||||
/* Forwards */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ struct Section;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -66,20 +66,20 @@ struct Section;
|
||||
/* Fragment structure */
|
||||
typedef struct Fragment Fragment;
|
||||
struct Fragment {
|
||||
Fragment* Next; /* Next fragment in list */
|
||||
struct ObjData* Obj; /* Source of fragment */
|
||||
Fragment* Next; /* Next fragment in list */
|
||||
struct ObjData* Obj; /* Source of fragment */
|
||||
struct Section* Sec; /* Section for this fragment */
|
||||
unsigned Size; /* Size of data/expression */
|
||||
struct ExprNode* Expr; /* Expression if FRAG_EXPR */
|
||||
unsigned Size; /* Size of data/expression */
|
||||
struct ExprNode* Expr; /* Expression if FRAG_EXPR */
|
||||
Collection LineInfos; /* Line info for this fragment */
|
||||
unsigned char Type; /* Type of fragment */
|
||||
unsigned char LitBuf [1]; /* Dynamically alloc'ed literal buffer */
|
||||
unsigned char Type; /* Type of fragment */
|
||||
unsigned char LitBuf [1]; /* Dynamically alloc'ed literal buffer */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* global.c */
|
||||
/* global.c */
|
||||
/* */
|
||||
/* Global variables for the ld65 linker */
|
||||
/* Global variables for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -38,12 +38,12 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
const char* OutputName = "a.out"; /* Name of output file */
|
||||
const char* OutputName = "a.out"; /* Name of output file */
|
||||
unsigned OutputNameUsed = 0; /* Output name was used by %O */
|
||||
|
||||
unsigned ModuleId = 0; /* Id for o65 module */
|
||||
@@ -52,9 +52,9 @@ unsigned ModuleId = 0; /* Id for o65 module */
|
||||
unsigned char HaveStartAddr = 0; /* Start address not given */
|
||||
unsigned long StartAddr = 0x200; /* Start address */
|
||||
|
||||
unsigned char VerboseMap = 0; /* Verbose map file */
|
||||
const char* MapFileName = 0; /* Name of the map file */
|
||||
const char* LabelFileName = 0; /* Name of the label file */
|
||||
unsigned char VerboseMap = 0; /* Verbose map file */
|
||||
const char* MapFileName = 0; /* Name of the map file */
|
||||
const char* LabelFileName = 0; /* Name of the label file */
|
||||
const char* DbgFileName = 0; /* Name of the debug file */
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* global.h */
|
||||
/* global.h */
|
||||
/* */
|
||||
/* Global variables for the ld65 linker */
|
||||
/* Global variables for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,22 +39,22 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
extern const char* OutputName; /* Name of output file */
|
||||
extern const char* OutputName; /* Name of output file */
|
||||
extern unsigned OutputNameUsed; /* Output name was used by %O */
|
||||
|
||||
extern unsigned ModuleId; /* Id for o65 module */
|
||||
|
||||
extern unsigned char HaveStartAddr; /* True if start address was given */
|
||||
extern unsigned long StartAddr; /* Start address */
|
||||
extern unsigned long StartAddr; /* Start address */
|
||||
|
||||
extern unsigned char VerboseMap; /* Verbose map file */
|
||||
extern const char* MapFileName; /* Name of the map file */
|
||||
extern const char* LabelFileName; /* Name of the label file */
|
||||
extern unsigned char VerboseMap; /* Verbose map file */
|
||||
extern const char* MapFileName; /* Name of the map file */
|
||||
extern const char* LabelFileName; /* Name of the label file */
|
||||
extern const char* DbgFileName; /* Name of the debug file */
|
||||
|
||||
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* library.c */
|
||||
/* */
|
||||
/* Library data structures and helpers for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* library.c */
|
||||
/* */
|
||||
/* Library data structures and helpers for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2011, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* 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 */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ static void FreeLibrary (Library* L)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Reading file data structures */
|
||||
/* Reading file data structures */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ static void LibReadHeader (Library* L)
|
||||
L->Header.Magic = LIB_MAGIC;
|
||||
L->Header.Version = Read16 (L->F);
|
||||
if (L->Header.Version != LIB_VERSION) {
|
||||
Error ("Wrong data version in `%s'", GetString (L->Name));
|
||||
Error ("Wrong data version in `%s'", GetString (L->Name));
|
||||
}
|
||||
L->Header.Flags = Read16 (L->F);
|
||||
L->Header.IndexOffs = Read32 (L->F);
|
||||
@@ -171,21 +171,21 @@ static void LibReadObjHeader (Library* L, ObjData* O)
|
||||
{
|
||||
O->Header.Magic = Read32 (L->F);
|
||||
if (O->Header.Magic != OBJ_MAGIC) {
|
||||
Error ("Object file `%s' in library `%s' is invalid",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
Error ("Object file `%s' in library `%s' is invalid",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
}
|
||||
O->Header.Version = Read16 (L->F);
|
||||
if (O->Header.Version != OBJ_VERSION) {
|
||||
Error ("Object file `%s' in library `%s' has wrong version",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
Error ("Object file `%s' in library `%s' has wrong version",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
}
|
||||
O->Header.Flags = Read16 (L->F);
|
||||
O->Header.Flags = Read16 (L->F);
|
||||
O->Header.OptionOffs = Read32 (L->F);
|
||||
O->Header.OptionSize = Read32 (L->F);
|
||||
O->Header.FileOffs = Read32 (L->F);
|
||||
O->Header.FileSize = Read32 (L->F);
|
||||
O->Header.SegOffs = Read32 (L->F);
|
||||
O->Header.SegSize = Read32 (L->F);
|
||||
O->Header.FileOffs = Read32 (L->F);
|
||||
O->Header.FileSize = Read32 (L->F);
|
||||
O->Header.SegOffs = Read32 (L->F);
|
||||
O->Header.SegSize = Read32 (L->F);
|
||||
O->Header.ImportOffs = Read32 (L->F);
|
||||
O->Header.ImportSize = Read32 (L->F);
|
||||
O->Header.ExportOffs = Read32 (L->F);
|
||||
@@ -210,7 +210,7 @@ static ObjData* ReadIndexEntry (Library* L)
|
||||
/* Read one entry in the index */
|
||||
{
|
||||
/* Create a new entry and insert it into the list */
|
||||
ObjData* O = NewObjData ();
|
||||
ObjData* O = NewObjData ();
|
||||
|
||||
/* Remember from which library this module is */
|
||||
O->Lib = L;
|
||||
@@ -219,10 +219,10 @@ static ObjData* ReadIndexEntry (Library* L)
|
||||
O->Name = ReadStr (L->F);
|
||||
|
||||
/* Module flags/MTime/Start/Size */
|
||||
O->Flags = Read16 (L->F);
|
||||
O->Flags = Read16 (L->F);
|
||||
O->MTime = Read32 (L->F);
|
||||
O->Start = Read32 (L->F);
|
||||
Read32 (L->F); /* Skip Size */
|
||||
O->Start = Read32 (L->F);
|
||||
Read32 (L->F); /* Skip Size */
|
||||
|
||||
/* Done */
|
||||
return O;
|
||||
@@ -271,7 +271,7 @@ static void LibReadIndex (Library* L)
|
||||
|
||||
/* Read all entries in the index */
|
||||
while (ModuleCount--) {
|
||||
CollAppend (&L->Modules, ReadIndexEntry (L));
|
||||
CollAppend (&L->Modules, ReadIndexEntry (L));
|
||||
}
|
||||
|
||||
/* Walk over the index and read basic data for all object files in the
|
||||
@@ -285,7 +285,7 @@ static void LibReadIndex (Library* L)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* High level stuff */
|
||||
/* High level stuff */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -300,12 +300,12 @@ static void LibCheckExports (ObjData* O)
|
||||
/* Check all exports */
|
||||
for (I = 0; I < CollCount (&O->Exports); ++I) {
|
||||
const Export* E = CollConstAt (&O->Exports, I);
|
||||
if (IsUnresolved (E->Name)) {
|
||||
if (IsUnresolved (E->Name)) {
|
||||
/* We need this module, insert the imports and exports */
|
||||
O->Flags |= OBJ_REF;
|
||||
O->Flags |= OBJ_REF;
|
||||
InsertObjGlobals (O);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* library.h */
|
||||
/* library.h */
|
||||
/* */
|
||||
/* Library data structures and helpers for the ld65 linker */
|
||||
/* Library data structures and helpers for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* lineinfo.h */
|
||||
/* lineinfo.h */
|
||||
/* */
|
||||
/* Source file line info structure */
|
||||
/* Source file line info structure */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* lineinfo.h */
|
||||
/* lineinfo.h */
|
||||
/* */
|
||||
/* Source file line info structure */
|
||||
/* Source file line info structure */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Forwards */
|
||||
/* Forwards */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ struct Segment;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ struct Segment;
|
||||
typedef struct LineInfo LineInfo;
|
||||
struct LineInfo {
|
||||
unsigned Id; /* Line info id */
|
||||
struct FileInfo* File; /* File struct for this line if any */
|
||||
struct FileInfo* File; /* File struct for this line if any */
|
||||
unsigned Type; /* Type of line info */
|
||||
FilePos Pos; /* Position in file */
|
||||
unsigned* Spans; /* Spans for this line */
|
||||
@@ -83,7 +83,7 @@ struct LineInfo {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
266
src/ld65/main.c
266
src/ld65/main.c
@@ -1,34 +1,34 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* main.c */
|
||||
/* */
|
||||
/* Main program for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* main.c */
|
||||
/* */
|
||||
/* Main program for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2013, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* 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 */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -72,18 +72,18 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static unsigned ObjFiles = 0; /* Count of object files linked */
|
||||
static unsigned LibFiles = 0; /* Count of library files linked */
|
||||
static unsigned ObjFiles = 0; /* Count of object files linked */
|
||||
static unsigned LibFiles = 0; /* Count of library files linked */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -139,19 +139,19 @@ static unsigned long CvtNumber (const char* Arg, const char* Number)
|
||||
*/
|
||||
{
|
||||
unsigned long Val;
|
||||
int Converted;
|
||||
int Converted;
|
||||
|
||||
/* Convert */
|
||||
if (*Number == '$') {
|
||||
++Number;
|
||||
Converted = sscanf (Number, "%lx", &Val);
|
||||
++Number;
|
||||
Converted = sscanf (Number, "%lx", &Val);
|
||||
} else {
|
||||
Converted = sscanf (Number, "%li", (long*)&Val);
|
||||
Converted = sscanf (Number, "%li", (long*)&Val);
|
||||
}
|
||||
|
||||
/* Check if we do really have a number */
|
||||
if (Converted != 1) {
|
||||
Error ("Invalid number given in argument: %s\n", Arg);
|
||||
Error ("Invalid number given in argument: %s\n", Arg);
|
||||
}
|
||||
|
||||
/* Return the result */
|
||||
@@ -217,19 +217,19 @@ static void LinkFile (const char* Name, FILETYPE Type)
|
||||
*/
|
||||
switch (Magic) {
|
||||
|
||||
case OBJ_MAGIC:
|
||||
ObjAdd (F, PathName);
|
||||
++ObjFiles;
|
||||
break;
|
||||
case OBJ_MAGIC:
|
||||
ObjAdd (F, PathName);
|
||||
++ObjFiles;
|
||||
break;
|
||||
|
||||
case LIB_MAGIC:
|
||||
LibAdd (F, PathName);
|
||||
++LibFiles;
|
||||
break;
|
||||
case LIB_MAGIC:
|
||||
LibAdd (F, PathName);
|
||||
++LibFiles;
|
||||
break;
|
||||
|
||||
default:
|
||||
fclose (F);
|
||||
Error ("File `%s' has unknown type", PathName);
|
||||
default:
|
||||
fclose (F);
|
||||
Error ("File `%s' has unknown type", PathName);
|
||||
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ static void DefineSymbol (const char* Def)
|
||||
|
||||
/* The symbol must start with a character or underline */
|
||||
if (Def [0] != '_' && !IsAlpha (Def [0])) {
|
||||
InvDef (Def);
|
||||
InvDef (Def);
|
||||
}
|
||||
P = Def;
|
||||
|
||||
@@ -263,18 +263,18 @@ static void DefineSymbol (const char* Def)
|
||||
if (*P != '=') {
|
||||
InvDef (Def);
|
||||
} else {
|
||||
/* We have a value */
|
||||
++P;
|
||||
if (*P == '$') {
|
||||
++P;
|
||||
if (sscanf (P, "%lx", &Val) != 1) {
|
||||
InvDef (Def);
|
||||
}
|
||||
} else {
|
||||
if (sscanf (P, "%li", &Val) != 1) {
|
||||
InvDef (Def);
|
||||
}
|
||||
}
|
||||
/* We have a value */
|
||||
++P;
|
||||
if (*P == '$') {
|
||||
++P;
|
||||
if (sscanf (P, "%lx", &Val) != 1) {
|
||||
InvDef (Def);
|
||||
}
|
||||
} else {
|
||||
if (sscanf (P, "%li", &Val) != 1) {
|
||||
InvDef (Def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Define the new symbol */
|
||||
@@ -297,7 +297,7 @@ static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
|
||||
char* PathName;
|
||||
|
||||
if (CfgAvail ()) {
|
||||
Error ("Cannot use -C/-t twice");
|
||||
Error ("Cannot use -C/-t twice");
|
||||
}
|
||||
/* Search for the file */
|
||||
PathName = SearchFile (CfgSearchPath, Arg);
|
||||
@@ -332,7 +332,7 @@ static void OptDefine (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
static void OptEndGroup (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* End a library group */
|
||||
{
|
||||
LibEndGroup ();
|
||||
@@ -379,7 +379,7 @@ static void OptForceImport (const char* Opt attribute ((unused)), const char* Ar
|
||||
|
||||
|
||||
static void OptHelp (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Print usage information and exit */
|
||||
{
|
||||
Usage ();
|
||||
@@ -465,7 +465,7 @@ static void OptStartAddr (const char* Opt, const char* Arg)
|
||||
|
||||
|
||||
static void OptStartGroup (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Start a library group */
|
||||
{
|
||||
LibStartGroup ();
|
||||
@@ -482,7 +482,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Map the target name to a target id */
|
||||
Target = FindTarget (Arg);
|
||||
if (Target == TGT_UNKNOWN) {
|
||||
Error ("Invalid target name: `%s'", Arg);
|
||||
Error ("Invalid target name: `%s'", Arg);
|
||||
}
|
||||
|
||||
/* Set the target binary format */
|
||||
@@ -513,7 +513,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
static void OptVersion (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Print the assembler version */
|
||||
{
|
||||
fprintf (stderr, "ld65 V%s\n", GetVersionAsString ());
|
||||
@@ -526,23 +526,23 @@ int main (int argc, char* argv [])
|
||||
{
|
||||
/* Program long options */
|
||||
static const LongOpt OptTab[] = {
|
||||
{ "--cfg-path", 1, OptCfgPath },
|
||||
{ "--config", 1, OptConfig },
|
||||
{ "--dbgfile", 1, OptDbgFile },
|
||||
{ "--cfg-path", 1, OptCfgPath },
|
||||
{ "--config", 1, OptConfig },
|
||||
{ "--dbgfile", 1, OptDbgFile },
|
||||
{ "--define", 1, OptDefine },
|
||||
{ "--end-group", 0, OptEndGroup },
|
||||
{ "--force-import", 1, OptForceImport },
|
||||
{ "--help", 0, OptHelp },
|
||||
{ "--help", 0, OptHelp },
|
||||
{ "--lib", 1, OptLib },
|
||||
{ "--lib-path", 1, OptLibPath },
|
||||
{ "--mapfile", 1, OptMapFile },
|
||||
{ "--module-id", 1, OptModuleId },
|
||||
{ "--lib-path", 1, OptLibPath },
|
||||
{ "--mapfile", 1, OptMapFile },
|
||||
{ "--module-id", 1, OptModuleId },
|
||||
{ "--obj", 1, OptObj },
|
||||
{ "--obj-path", 1, OptObjPath },
|
||||
{ "--start-addr", 1, OptStartAddr },
|
||||
{ "--obj-path", 1, OptObjPath },
|
||||
{ "--start-addr", 1, OptStartAddr },
|
||||
{ "--start-group", 0, OptStartGroup },
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--version", 0, OptVersion },
|
||||
};
|
||||
|
||||
unsigned I;
|
||||
@@ -564,18 +564,18 @@ int main (int argc, char* argv [])
|
||||
I = 1;
|
||||
while (I < ArgCount) {
|
||||
|
||||
/* Get the argument */
|
||||
const char* Arg = ArgVec[I];
|
||||
/* Get the argument */
|
||||
const char* Arg = ArgVec[I];
|
||||
|
||||
/* Check for an option */
|
||||
if (Arg [0] == '-') {
|
||||
/* Check for an option */
|
||||
if (Arg [0] == '-') {
|
||||
|
||||
/* An option */
|
||||
switch (Arg [1]) {
|
||||
/* An option */
|
||||
switch (Arg [1]) {
|
||||
|
||||
case '-':
|
||||
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
|
||||
break;
|
||||
case '-':
|
||||
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
|
||||
break;
|
||||
|
||||
case '(':
|
||||
OptStartGroup (Arg, 0);
|
||||
@@ -585,86 +585,86 @@ int main (int argc, char* argv [])
|
||||
OptEndGroup (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
OptHelp (Arg, 0);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
OptHelp (Arg, 0);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
OptMapFile (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
case 'm':
|
||||
OptMapFile (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
OptOutputName (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
case 'o':
|
||||
OptOutputName (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (CfgAvail ()) {
|
||||
Error ("Cannot use -C/-t twice");
|
||||
}
|
||||
OptTarget (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
case 't':
|
||||
if (CfgAvail ()) {
|
||||
Error ("Cannot use -C/-t twice");
|
||||
}
|
||||
OptTarget (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
OptForceImport (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
switch (Arg [2]) {
|
||||
case 'm': VerboseMap = 1; break;
|
||||
case '\0': ++Verbosity; break;
|
||||
default: UnknownOption (Arg);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
switch (Arg [2]) {
|
||||
case 'm': VerboseMap = 1; break;
|
||||
case '\0': ++Verbosity; break;
|
||||
default: UnknownOption (Arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
OptConfig (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
case 'C':
|
||||
OptConfig (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
OptDefine (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
switch (Arg [2]) {
|
||||
case 'L':
|
||||
switch (Arg [2]) {
|
||||
/* ## The first one is obsolete and will go */
|
||||
case 'n': LabelFileName = GetArg (&I, 3); break;
|
||||
default: OptLibPath (Arg, GetArg (&I, 2)); break;
|
||||
}
|
||||
break;
|
||||
case 'n': LabelFileName = GetArg (&I, 3); break;
|
||||
default: OptLibPath (Arg, GetArg (&I, 2)); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
OptStartAddr (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
case 'S':
|
||||
OptStartAddr (Arg, GetArg (&I, 2));
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
OptVersion (Arg, 0);
|
||||
break;
|
||||
case 'V':
|
||||
OptVersion (Arg, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
UnknownOption (Arg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UnknownOption (Arg);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
} else {
|
||||
|
||||
/* A filename */
|
||||
LinkFile (Arg, FILETYPE_UNKNOWN);
|
||||
/* A filename */
|
||||
LinkFile (Arg, FILETYPE_UNKNOWN);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Next argument */
|
||||
++I;
|
||||
/* Next argument */
|
||||
++I;
|
||||
}
|
||||
|
||||
/* Check if we had any object files */
|
||||
if (ObjFiles == 0) {
|
||||
Error ("No object files to link");
|
||||
Error ("No object files to link");
|
||||
}
|
||||
|
||||
/* Check if we have a valid configuration */
|
||||
if (!CfgAvail ()) {
|
||||
Error ("Memory configuration missing");
|
||||
Error ("Memory configuration missing");
|
||||
}
|
||||
|
||||
/* Check if we have open library groups */
|
||||
@@ -705,19 +705,19 @@ int main (int argc, char* argv [])
|
||||
|
||||
/* If requested, create a map file and a label file for VICE */
|
||||
if (MapFileName) {
|
||||
CreateMapFile (LONG_MAPFILE);
|
||||
CreateMapFile (LONG_MAPFILE);
|
||||
}
|
||||
if (LabelFileName) {
|
||||
CreateLabelFile ();
|
||||
CreateLabelFile ();
|
||||
}
|
||||
if (DbgFileName) {
|
||||
CreateDbgFile ();
|
||||
CreateDbgFile ();
|
||||
}
|
||||
|
||||
/* Dump the data for debugging */
|
||||
if (Verbosity > 1) {
|
||||
SegDump ();
|
||||
ConDesDump ();
|
||||
SegDump ();
|
||||
ConDesDump ();
|
||||
}
|
||||
|
||||
/* Return an apropriate exit code */
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* mapfile.c */
|
||||
/* mapfile.c */
|
||||
/* */
|
||||
/* Map file creation for the ld65 linker */
|
||||
/* Map file creation for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -67,12 +67,12 @@ void CreateMapFile (int ShortMap)
|
||||
/* Open the map file */
|
||||
FILE* F = fopen (MapFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create map file `%s': %s", MapFileName, strerror (errno));
|
||||
Error ("Cannot create map file `%s': %s", MapFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Write a modules list */
|
||||
fprintf (F, "Modules list:\n"
|
||||
"-------------\n");
|
||||
"-------------\n");
|
||||
for (I = 0; I < CollCount (&ObjDataList); ++I) {
|
||||
|
||||
unsigned J;
|
||||
@@ -104,8 +104,8 @@ void CreateMapFile (int ShortMap)
|
||||
|
||||
/* Write the segment list */
|
||||
fprintf (F, "\n\n"
|
||||
"Segment list:\n"
|
||||
"-------------\n");
|
||||
"Segment list:\n"
|
||||
"-------------\n");
|
||||
PrintSegmentMap (F);
|
||||
|
||||
/* The remainder is not written for short map files */
|
||||
@@ -126,7 +126,7 @@ void CreateMapFile (int ShortMap)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing map file `%s': %s", MapFileName, strerror (errno));
|
||||
Error ("Error closing map file `%s': %s", MapFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ void CreateLabelFile (void)
|
||||
/* Open the label file */
|
||||
FILE* F = fopen (LabelFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create label file `%s': %s", LabelFileName, strerror (errno));
|
||||
Error ("Cannot create label file `%s': %s", LabelFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Print the labels for the export symbols */
|
||||
@@ -149,7 +149,7 @@ void CreateLabelFile (void)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing label file `%s': %s", LabelFileName, strerror (errno));
|
||||
Error ("Error closing label file `%s': %s", LabelFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* mapfile.h */
|
||||
/* mapfile.h */
|
||||
/* */
|
||||
/* Map file creation for the ld65 linker */
|
||||
/* Map file creation for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ enum {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -61,32 +61,32 @@ typedef struct MemoryArea MemoryArea;
|
||||
struct MemoryArea {
|
||||
LineInfo* LI; /* Where was the area was defined? */
|
||||
unsigned Name; /* Name index of the memory area */
|
||||
unsigned Attr; /* Which values are valid? */
|
||||
unsigned Flags; /* Set of bitmapped flags */
|
||||
unsigned Attr; /* Which values are valid? */
|
||||
unsigned Flags; /* Set of bitmapped flags */
|
||||
unsigned long FileOffs; /* Offset in output file */
|
||||
struct ExprNode* StartExpr; /* Expression for start address */
|
||||
unsigned long Start; /* Start address */
|
||||
unsigned long Start; /* Start address */
|
||||
struct ExprNode* SizeExpr; /* Expression for size */
|
||||
unsigned long Size; /* Length of memory section */
|
||||
unsigned long Size; /* Length of memory section */
|
||||
struct ExprNode* BankExpr; /* Expression for bank */
|
||||
unsigned long FillLevel; /* Actual fill level of segment */
|
||||
unsigned char FillVal; /* Value used to fill rest of seg */
|
||||
unsigned long FillLevel; /* Actual fill level of segment */
|
||||
unsigned char FillVal; /* Value used to fill rest of seg */
|
||||
unsigned char Relocatable; /* Memory area is relocatable */
|
||||
Collection SegList; /* List of segments for this area */
|
||||
struct File* F; /* Output file for this area */
|
||||
Collection SegList; /* List of segments for this area */
|
||||
struct File* F; /* Output file for this area */
|
||||
};
|
||||
|
||||
/* Memory flags */
|
||||
#define MF_DEFINE 0x0001 /* Define start and size */
|
||||
#define MF_FILL 0x0002 /* Fill segment */
|
||||
#define MF_RO 0x0004 /* Read only memory area */
|
||||
#define MF_DEFINE 0x0001 /* Define start and size */
|
||||
#define MF_FILL 0x0002 /* Fill segment */
|
||||
#define MF_RO 0x0004 /* Read only memory area */
|
||||
#define MF_OVERFLOW 0x0008 /* Memory area overflow */
|
||||
#define MF_PLACED 0x0010 /* Memory area was placed */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
674
src/ld65/o65.c
674
src/ld65/o65.c
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* o65.h */
|
||||
/* o65.h */
|
||||
/* */
|
||||
/* Module to handle the o65 binary format */
|
||||
/* Module to handle the o65 binary format */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -55,16 +55,16 @@
|
||||
typedef struct O65Desc O65Desc;
|
||||
|
||||
/* Option tags */
|
||||
#define O65OPT_FILENAME 0
|
||||
#define O65OPT_OS 1
|
||||
#define O65OPT_ASM 2
|
||||
#define O65OPT_AUTHOR 3
|
||||
#define O65OPT_TIMESTAMP 4
|
||||
#define O65OPT_FILENAME 0
|
||||
#define O65OPT_OS 1
|
||||
#define O65OPT_ASM 2
|
||||
#define O65OPT_AUTHOR 3
|
||||
#define O65OPT_TIMESTAMP 4
|
||||
|
||||
/* Operating system codes for O65OPT_OS */
|
||||
#define O65OS_MIN 1
|
||||
#define O65OS_OSA65 1
|
||||
#define O65OS_LUNIX 2
|
||||
#define O65OS_OSA65 1
|
||||
#define O65OS_LUNIX 2
|
||||
#define O65OS_CC65 3
|
||||
#define O65OS_OPENCBM 4
|
||||
#define O65OS_MAX 255
|
||||
@@ -72,7 +72,7 @@ typedef struct O65Desc O65Desc;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objdata.c */
|
||||
/* objdata.c */
|
||||
/* */
|
||||
/* Handling object file data for the ld65 linker */
|
||||
/* Handling object file data for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ Collection ObjDataList = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -73,21 +73,21 @@ ObjData* NewObjData (void)
|
||||
ObjData* O = xmalloc (sizeof (ObjData));
|
||||
|
||||
/* Initialize the data */
|
||||
O->Next = 0;
|
||||
O->Name = INVALID_STRING_ID;
|
||||
O->Next = 0;
|
||||
O->Name = INVALID_STRING_ID;
|
||||
O->Lib = 0;
|
||||
O->MTime = 0;
|
||||
O->Start = 0;
|
||||
O->Flags = 0;
|
||||
O->Start = 0;
|
||||
O->Flags = 0;
|
||||
O->HLLSymBaseId = 0;
|
||||
O->SymBaseId = 0;
|
||||
O->ScopeBaseId = 0;
|
||||
O->SpanBaseId = 0;
|
||||
O->Files = EmptyCollection;
|
||||
O->Sections = EmptyCollection;
|
||||
O->Exports = EmptyCollection;
|
||||
O->Imports = EmptyCollection;
|
||||
O->DbgSyms = EmptyCollection;
|
||||
O->Exports = EmptyCollection;
|
||||
O->Imports = EmptyCollection;
|
||||
O->DbgSyms = EmptyCollection;
|
||||
O->HLLDbgSyms = EmptyCollection;
|
||||
O->LineInfos = EmptyCollection;
|
||||
O->StringCount = 0;
|
||||
@@ -184,8 +184,8 @@ unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
|
||||
/* Convert a local string id into a global one and return it. */
|
||||
{
|
||||
if (Index >= O->StringCount) {
|
||||
Error ("Invalid string index (%u) in module `%s'",
|
||||
Index, GetObjFileName (O));
|
||||
Error ("Invalid string index (%u) in module `%s'",
|
||||
Index, GetObjFileName (O));
|
||||
}
|
||||
return O->Strings[Index];
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objdata.h */
|
||||
/* objdata.h */
|
||||
/* */
|
||||
/* Handling object file data for the ld65 linker */
|
||||
/* Handling object file data for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -60,30 +60,30 @@ struct Section;
|
||||
struct StrBuf;
|
||||
|
||||
/* Values for the Flags field */
|
||||
#define OBJ_REF 0x0001 /* We have a reference to this file */
|
||||
#define OBJ_REF 0x0001 /* We have a reference to this file */
|
||||
|
||||
/* Internal structure holding object file data */
|
||||
typedef struct ObjData ObjData;
|
||||
struct ObjData {
|
||||
ObjData* Next; /* Linked list of all objects */
|
||||
ObjData* Next; /* Linked list of all objects */
|
||||
unsigned Id; /* Id of this module */
|
||||
unsigned Name; /* Module name */
|
||||
unsigned Name; /* Module name */
|
||||
struct Library* Lib; /* Library where module comes from */
|
||||
unsigned long MTime; /* Time of last modification */
|
||||
ObjHeader Header; /* Header of file */
|
||||
unsigned long Start; /* Start offset of data in library */
|
||||
unsigned Flags;
|
||||
ObjHeader Header; /* Header of file */
|
||||
unsigned long Start; /* Start offset of data in library */
|
||||
unsigned Flags;
|
||||
|
||||
unsigned HLLSymBaseId; /* Debug info base id for hll symbols */
|
||||
unsigned SymBaseId; /* Debug info base id for symbols */
|
||||
unsigned ScopeBaseId; /* Debug info base id for scopes */
|
||||
unsigned SpanBaseId; /* Debug info base id for spans */
|
||||
|
||||
Collection Files; /* List of input files */
|
||||
Collection Sections; /* List of all sections */
|
||||
Collection Exports; /* List of all exports */
|
||||
Collection Imports; /* List of all imports */
|
||||
Collection DbgSyms; /* List of debug symbols */
|
||||
Collection Files; /* List of input files */
|
||||
Collection Sections; /* List of all sections */
|
||||
Collection Exports; /* List of all exports */
|
||||
Collection Imports; /* List of all imports */
|
||||
Collection DbgSyms; /* List of debug symbols */
|
||||
Collection HLLDbgSyms; /* List of hll debug symbols */
|
||||
Collection LineInfos; /* List of line infos */
|
||||
unsigned StringCount; /* Count of strings */
|
||||
@@ -101,7 +101,7 @@ extern Collection ObjDataList;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objfile.c */
|
||||
/* */
|
||||
/* Object file handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* objfile.c */
|
||||
/* */
|
||||
/* Object file handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* 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 */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ static unsigned GetModule (const char* Name)
|
||||
/* Make a module name from the file name */
|
||||
const char* Module = FindName (Name);
|
||||
if (*Module == 0) {
|
||||
Error ("Cannot make module name from `%s'", Name);
|
||||
Error ("Cannot make module name from `%s'", Name);
|
||||
}
|
||||
return GetStringId (Module);
|
||||
}
|
||||
@@ -77,18 +77,18 @@ static unsigned GetModule (const char* Name)
|
||||
static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
||||
/* Read the header of the object file checking the signature */
|
||||
{
|
||||
H->Version = Read16 (Obj);
|
||||
H->Version = Read16 (Obj);
|
||||
if (H->Version != OBJ_VERSION) {
|
||||
Error ("Object file `%s' has wrong version, expected %08X, got %08X",
|
||||
Error ("Object file `%s' has wrong version, expected %08X, got %08X",
|
||||
Name, OBJ_VERSION, H->Version);
|
||||
}
|
||||
H->Flags = Read16 (Obj);
|
||||
H->Flags = Read16 (Obj);
|
||||
H->OptionOffs = Read32 (Obj);
|
||||
H->OptionSize = Read32 (Obj);
|
||||
H->FileOffs = Read32 (Obj);
|
||||
H->FileSize = Read32 (Obj);
|
||||
H->SegOffs = Read32 (Obj);
|
||||
H->SegSize = Read32 (Obj);
|
||||
H->SegOffs = Read32 (Obj);
|
||||
H->SegSize = Read32 (Obj);
|
||||
H->ImportOffs = Read32 (Obj);
|
||||
H->ImportSize = Read32 (Obj);
|
||||
H->ExportOffs = Read32 (Obj);
|
||||
@@ -122,7 +122,7 @@ void ObjReadFiles (FILE* F, unsigned long Pos, ObjData* O)
|
||||
FileCount = ReadVar (F);
|
||||
CollGrow (&O->Files, FileCount);
|
||||
for (I = 0; I < FileCount; ++I) {
|
||||
CollAppend (&O->Files, ReadFileInfo (F, O));
|
||||
CollAppend (&O->Files, ReadFileInfo (F, O));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ void ObjReadSections (FILE* F, unsigned long Pos, ObjData* O)
|
||||
SectionCount = ReadVar (F);
|
||||
CollGrow (&O->Sections, SectionCount);
|
||||
for (I = 0; I < SectionCount; ++I) {
|
||||
CollAppend (&O->Sections, ReadSection (F, O));
|
||||
CollAppend (&O->Sections, ReadSection (F, O));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ void ObjReadImports (FILE* F, unsigned long Pos, ObjData* O)
|
||||
ImportCount = ReadVar (F);
|
||||
CollGrow (&O->Imports, ImportCount);
|
||||
for (I = 0; I < ImportCount; ++I) {
|
||||
CollAppend (&O->Imports, ReadImport (F, O));
|
||||
CollAppend (&O->Imports, ReadImport (F, O));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ void ObjReadExports (FILE* F, unsigned long Pos, ObjData* O)
|
||||
ExportCount = ReadVar (F);
|
||||
CollGrow (&O->Exports, ExportCount);
|
||||
for (I = 0; I < ExportCount; ++I) {
|
||||
CollAppend (&O->Exports, ReadExport (F, O));
|
||||
CollAppend (&O->Exports, ReadExport (F, O));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,14 +198,14 @@ void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O)
|
||||
DbgSymCount = ReadVar (F);
|
||||
CollGrow (&O->DbgSyms, DbgSymCount);
|
||||
for (I = 0; I < DbgSymCount; ++I) {
|
||||
CollAppend (&O->DbgSyms, ReadDbgSym (F, O, I));
|
||||
CollAppend (&O->DbgSyms, ReadDbgSym (F, O, I));
|
||||
}
|
||||
|
||||
/* Read the hll debug symbols */
|
||||
DbgSymCount = ReadVar (F);
|
||||
CollGrow (&O->HLLDbgSyms, DbgSymCount);
|
||||
for (I = 0; I < DbgSymCount; ++I) {
|
||||
CollAppend (&O->HLLDbgSyms, ReadHLLDbgSym (F, O, I));
|
||||
CollAppend (&O->HLLDbgSyms, ReadHLLDbgSym (F, O, I));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ void ObjReadLineInfos (FILE* F, unsigned long Pos, ObjData* O)
|
||||
LineInfoCount = ReadVar (F);
|
||||
CollGrow (&O->LineInfos, LineInfoCount);
|
||||
for (I = 0; I < LineInfoCount; ++I) {
|
||||
CollAppend (&O->LineInfos, ReadLineInfo (F, O));
|
||||
CollAppend (&O->LineInfos, ReadLineInfo (F, O));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* objfile.h */
|
||||
/* objfile.h */
|
||||
/* */
|
||||
/* Object file handling for the ld65 linker */
|
||||
/* Object file handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* scanner.c */
|
||||
/* scanner.c */
|
||||
/* */
|
||||
/* Configuration file scanner for the ld65 linker */
|
||||
/* Configuration file scanner for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -53,13 +53,13 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Current token and attributes */
|
||||
cfgtok_t CfgTok;
|
||||
cfgtok_t CfgTok;
|
||||
StrBuf CfgSVal = STATIC_STRBUF_INITIALIZER;
|
||||
unsigned long CfgIVal;
|
||||
|
||||
@@ -67,17 +67,17 @@ unsigned long CfgIVal;
|
||||
FilePos CfgErrorPos;
|
||||
|
||||
/* Input source for the configuration */
|
||||
static const char* CfgName = 0;
|
||||
static const char* CfgName = 0;
|
||||
|
||||
/* Other input stuff */
|
||||
static int C = ' ';
|
||||
static int C = ' ';
|
||||
static FilePos InputPos;
|
||||
static FILE* InputFile = 0;
|
||||
static FILE* InputFile = 0;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Error handling */
|
||||
/* Error handling */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ void CfgError (const FilePos* Pos, const char* Format, ...)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -130,13 +130,13 @@ static void NextChar (void)
|
||||
|
||||
/* Count columns */
|
||||
if (C != EOF) {
|
||||
++InputPos.Col;
|
||||
++InputPos.Col;
|
||||
}
|
||||
|
||||
/* Count lines */
|
||||
if (C == '\n') {
|
||||
++InputPos.Line;
|
||||
InputPos.Col = 0;
|
||||
++InputPos.Line;
|
||||
InputPos.Col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,9 +146,9 @@ static unsigned DigitVal (int C)
|
||||
/* Return the value for a numeric digit */
|
||||
{
|
||||
if (isdigit (C)) {
|
||||
return C - '0';
|
||||
return C - '0';
|
||||
} else {
|
||||
return toupper (C) - 'A' + 10;
|
||||
return toupper (C) - 'A' + 10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ void CfgNextTok (void)
|
||||
Again:
|
||||
/* Skip whitespace */
|
||||
while (isspace (C)) {
|
||||
NextChar ();
|
||||
NextChar ();
|
||||
}
|
||||
|
||||
/* Remember the current position */
|
||||
@@ -237,41 +237,41 @@ Again:
|
||||
/* Identifier? */
|
||||
if (C == '_' || IsAlpha (C)) {
|
||||
|
||||
/* Read the identifier */
|
||||
SB_Clear (&CfgSVal);
|
||||
while (C == '_' || IsAlNum (C)) {
|
||||
/* Read the identifier */
|
||||
SB_Clear (&CfgSVal);
|
||||
while (C == '_' || IsAlNum (C)) {
|
||||
SB_AppendChar (&CfgSVal, C);
|
||||
NextChar ();
|
||||
}
|
||||
SB_Terminate (&CfgSVal);
|
||||
CfgTok = CFGTOK_IDENT;
|
||||
return;
|
||||
NextChar ();
|
||||
}
|
||||
SB_Terminate (&CfgSVal);
|
||||
CfgTok = CFGTOK_IDENT;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Hex number? */
|
||||
if (C == '$') {
|
||||
NextChar ();
|
||||
if (!isxdigit (C)) {
|
||||
CfgError (&CfgErrorPos, "Hex digit expected");
|
||||
}
|
||||
CfgIVal = 0;
|
||||
while (isxdigit (C)) {
|
||||
CfgIVal = CfgIVal * 16 + DigitVal (C);
|
||||
NextChar ();
|
||||
}
|
||||
CfgTok = CFGTOK_INTCON;
|
||||
return;
|
||||
NextChar ();
|
||||
if (!isxdigit (C)) {
|
||||
CfgError (&CfgErrorPos, "Hex digit expected");
|
||||
}
|
||||
CfgIVal = 0;
|
||||
while (isxdigit (C)) {
|
||||
CfgIVal = CfgIVal * 16 + DigitVal (C);
|
||||
NextChar ();
|
||||
}
|
||||
CfgTok = CFGTOK_INTCON;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decimal number? */
|
||||
if (isdigit (C)) {
|
||||
CfgIVal = 0;
|
||||
while (isdigit (C)) {
|
||||
CfgIVal = CfgIVal * 10 + DigitVal (C);
|
||||
NextChar ();
|
||||
}
|
||||
CfgTok = CFGTOK_INTCON;
|
||||
return;
|
||||
CfgIVal = 0;
|
||||
while (isdigit (C)) {
|
||||
CfgIVal = CfgIVal * 10 + DigitVal (C);
|
||||
NextChar ();
|
||||
}
|
||||
CfgTok = CFGTOK_INTCON;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Other characters */
|
||||
@@ -297,99 +297,99 @@ Again:
|
||||
CfgTok = CFGTOK_DIV;
|
||||
break;
|
||||
|
||||
case '(':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_LPAR;
|
||||
break;
|
||||
case '(':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_LPAR;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_RPAR;
|
||||
break;
|
||||
case ')':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_RPAR;
|
||||
break;
|
||||
|
||||
case '{':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_LCURLY;
|
||||
break;
|
||||
case '{':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_LCURLY;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_RCURLY;
|
||||
break;
|
||||
case '}':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_RCURLY;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_SEMI;
|
||||
break;
|
||||
case ';':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_SEMI;
|
||||
break;
|
||||
|
||||
case '.':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_DOT;
|
||||
break;
|
||||
case '.':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_DOT;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_COMMA;
|
||||
break;
|
||||
case ',':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_COMMA;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_EQ;
|
||||
break;
|
||||
case '=':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_EQ;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_COLON;
|
||||
break;
|
||||
NextChar ();
|
||||
CfgTok = CFGTOK_COLON;
|
||||
break;
|
||||
|
||||
case '\"':
|
||||
StrVal ();
|
||||
break;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
/* Comment */
|
||||
while (C != '\n' && C != EOF) {
|
||||
NextChar ();
|
||||
}
|
||||
if (C != EOF) {
|
||||
goto Again;
|
||||
}
|
||||
CfgTok = CFGTOK_EOF;
|
||||
break;
|
||||
/* Comment */
|
||||
while (C != '\n' && C != EOF) {
|
||||
NextChar ();
|
||||
}
|
||||
if (C != EOF) {
|
||||
goto Again;
|
||||
}
|
||||
CfgTok = CFGTOK_EOF;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
NextChar ();
|
||||
switch (C) {
|
||||
NextChar ();
|
||||
switch (C) {
|
||||
|
||||
case 'O':
|
||||
NextChar ();
|
||||
if (OutputName) {
|
||||
case 'O':
|
||||
NextChar ();
|
||||
if (OutputName) {
|
||||
SB_CopyStr (&CfgSVal, OutputName);
|
||||
} else {
|
||||
SB_Clear (&CfgSVal);
|
||||
}
|
||||
} else {
|
||||
SB_Clear (&CfgSVal);
|
||||
}
|
||||
SB_Terminate (&CfgSVal);
|
||||
OutputNameUsed = 1;
|
||||
CfgTok = CFGTOK_STRCON;
|
||||
break;
|
||||
CfgTok = CFGTOK_STRCON;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
NextChar ();
|
||||
CfgIVal = StartAddr;
|
||||
CfgTok = CFGTOK_INTCON;
|
||||
break;
|
||||
case 'S':
|
||||
NextChar ();
|
||||
CfgIVal = StartAddr;
|
||||
CfgTok = CFGTOK_INTCON;
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid format specification");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid format specification");
|
||||
}
|
||||
break;
|
||||
|
||||
case EOF:
|
||||
CfgTok = CFGTOK_EOF;
|
||||
break;
|
||||
CfgTok = CFGTOK_EOF;
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid character `%c'", C);
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid character `%c'", C);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -400,7 +400,7 @@ void CfgConsume (cfgtok_t T, const char* Msg)
|
||||
/* Skip a token, print an error message if not found */
|
||||
{
|
||||
if (CfgTok != T) {
|
||||
CfgError (&CfgErrorPos, "%s", Msg);
|
||||
CfgError (&CfgErrorPos, "%s", Msg);
|
||||
}
|
||||
CfgNextTok ();
|
||||
}
|
||||
@@ -427,7 +427,7 @@ void CfgOptionalComma (void)
|
||||
/* Consume a comma if there is one */
|
||||
{
|
||||
if (CfgTok == CFGTOK_COMMA) {
|
||||
CfgNextTok ();
|
||||
CfgNextTok ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ void CfgOptionalAssign (void)
|
||||
/* Consume an equal sign if there is one */
|
||||
{
|
||||
if (CfgTok == CFGTOK_EQ) {
|
||||
CfgNextTok ();
|
||||
CfgNextTok ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +447,7 @@ void CfgAssureInt (void)
|
||||
/* Make sure the next token is an integer */
|
||||
{
|
||||
if (CfgTok != CFGTOK_INTCON) {
|
||||
CfgError (&CfgErrorPos, "Integer constant expected");
|
||||
CfgError (&CfgErrorPos, "Integer constant expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,7 +457,7 @@ void CfgAssureStr (void)
|
||||
/* Make sure the next token is a string constant */
|
||||
{
|
||||
if (CfgTok != CFGTOK_STRCON) {
|
||||
CfgError (&CfgErrorPos, "String constant expected");
|
||||
CfgError (&CfgErrorPos, "String constant expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ void CfgAssureIdent (void)
|
||||
/* Make sure the next token is an identifier */
|
||||
{
|
||||
if (CfgTok != CFGTOK_IDENT) {
|
||||
CfgError (&CfgErrorPos, "Identifier expected");
|
||||
CfgError (&CfgErrorPos, "Identifier expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ void CfgRangeCheck (unsigned long Lo, unsigned long Hi)
|
||||
/* Check the range of CfgIVal */
|
||||
{
|
||||
if (CfgIVal < Lo || CfgIVal > Hi) {
|
||||
CfgError (&CfgErrorPos, "Range error");
|
||||
CfgError (&CfgErrorPos, "Range error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,16 +491,16 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
|
||||
/* We need an identifier */
|
||||
if (CfgTok == CFGTOK_IDENT) {
|
||||
|
||||
/* Make it upper case */
|
||||
/* Make it upper case */
|
||||
SB_ToUpper (&CfgSVal);
|
||||
|
||||
/* Linear search */
|
||||
for (I = 0; I < Size; ++I) {
|
||||
if (SB_CompareStr (&CfgSVal, Table[I].Ident) == 0) {
|
||||
CfgTok = Table[I].Tok;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Linear search */
|
||||
for (I = 0; I < Size; ++I) {
|
||||
if (SB_CompareStr (&CfgSVal, Table[I].Ident) == 0) {
|
||||
CfgTok = Table[I].Tok;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -514,21 +514,21 @@ void CfgBoolToken (void)
|
||||
/* Map an identifier or integer to a boolean token */
|
||||
{
|
||||
static const IdentTok Booleans [] = {
|
||||
{ "YES", CFGTOK_TRUE },
|
||||
{ "NO", CFGTOK_FALSE },
|
||||
{ "YES", CFGTOK_TRUE },
|
||||
{ "NO", CFGTOK_FALSE },
|
||||
{ "TRUE", CFGTOK_TRUE },
|
||||
{ "FALSE", CFGTOK_FALSE },
|
||||
};
|
||||
|
||||
/* If we have an identifier, map it to a boolean token */
|
||||
if (CfgTok == CFGTOK_IDENT) {
|
||||
CfgSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
|
||||
CfgSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
|
||||
} else {
|
||||
/* We expected an integer here */
|
||||
if (CfgTok != CFGTOK_INTCON) {
|
||||
CfgError (&CfgErrorPos, "Boolean value expected");
|
||||
}
|
||||
CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE;
|
||||
/* We expected an integer here */
|
||||
if (CfgTok != CFGTOK_INTCON) {
|
||||
CfgError (&CfgErrorPos, "Boolean value expected");
|
||||
}
|
||||
CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,7 +577,7 @@ void CfgCloseInput (void)
|
||||
/* Close the input file if we had one */
|
||||
if (InputFile) {
|
||||
(void) fclose (InputFile);
|
||||
InputFile = 0;
|
||||
InputFile = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* scanner.h */
|
||||
/* scanner.h */
|
||||
/* */
|
||||
/* Configuration file scanner for the ld65 linker */
|
||||
/* Configuration file scanner for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -153,17 +153,17 @@ typedef enum {
|
||||
/* Mapping table entry, special identifier --> token */
|
||||
typedef struct IdentTok IdentTok;
|
||||
struct IdentTok {
|
||||
const char* Ident; /* Identifier */
|
||||
cfgtok_t Tok; /* Token for identifier */
|
||||
const char* Ident; /* Identifier */
|
||||
cfgtok_t Tok; /* Token for identifier */
|
||||
};
|
||||
#define ENTRY_COUNT(s) (sizeof (s) / sizeof (s [0]))
|
||||
#define ENTRY_COUNT(s) (sizeof (s) / sizeof (s [0]))
|
||||
|
||||
|
||||
|
||||
/* Current token and attributes */
|
||||
extern cfgtok_t CfgTok;
|
||||
extern cfgtok_t CfgTok;
|
||||
extern StrBuf CfgSVal;
|
||||
extern unsigned long CfgIVal;
|
||||
extern unsigned long CfgIVal;
|
||||
|
||||
/* Error location. PLEASE NOTE: I'm abusing the FilePos structure to some
|
||||
* degree. It is used mostly to hold a file position, where the Name member
|
||||
@@ -177,7 +177,7 @@ extern FilePos CfgErrorPos;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
typedef struct Scope Scope;
|
||||
struct Scope {
|
||||
unsigned Id; /* Id of scope */
|
||||
ObjData* Obj; /* Object file that contains the scope */
|
||||
ObjData* Obj; /* Object file that contains the scope */
|
||||
unsigned ParentId; /* Id of parent scope */
|
||||
unsigned LabelId; /* Id of the scope label if any */
|
||||
unsigned LexicalLevel; /* Lexical level */
|
||||
@@ -73,7 +73,7 @@ struct Scope {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* segments.c */
|
||||
/* segments.c */
|
||||
/* */
|
||||
/* Segment handling for the ld65 linker */
|
||||
/* Segment handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -62,15 +62,15 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Hash table */
|
||||
#define HASHTAB_MASK 0x3FU
|
||||
#define HASHTAB_SIZE (HASHTAB_MASK + 1)
|
||||
static Segment* HashTab[HASHTAB_SIZE];
|
||||
#define HASHTAB_SIZE (HASHTAB_MASK + 1)
|
||||
static Segment* HashTab[HASHTAB_SIZE];
|
||||
|
||||
/* List of all segments */
|
||||
static Collection SegmentList = STATIC_COLLECTION_INITIALIZER;
|
||||
@@ -78,7 +78,7 @@ static Collection SegmentList = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -93,16 +93,16 @@ static Segment* NewSegment (unsigned Name, unsigned char AddrSize)
|
||||
|
||||
/* Initialize the fields */
|
||||
S->Name = Name;
|
||||
S->Next = 0;
|
||||
S->Next = 0;
|
||||
S->Flags = SEG_FLAG_NONE;
|
||||
S->Sections = EmptyCollection;
|
||||
S->MemArea = 0;
|
||||
S->PC = 0;
|
||||
S->Size = 0;
|
||||
S->PC = 0;
|
||||
S->Size = 0;
|
||||
S->OutputName = 0;
|
||||
S->OutputOffs = 0;
|
||||
S->Alignment = 1;
|
||||
S->FillVal = 0;
|
||||
S->FillVal = 0;
|
||||
S->AddrSize = AddrSize;
|
||||
S->ReadOnly = 0;
|
||||
S->Dumped = 0;
|
||||
@@ -135,18 +135,18 @@ Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName)
|
||||
* the first section.
|
||||
*/
|
||||
if (S == 0) {
|
||||
/* Create a new segment */
|
||||
S = NewSegment (Name, AddrSize);
|
||||
/* Create a new segment */
|
||||
S = NewSegment (Name, AddrSize);
|
||||
} else {
|
||||
/* Check if the existing segment has the requested address size */
|
||||
if (S->AddrSize != AddrSize) {
|
||||
/* Allow an empty object name */
|
||||
if (ObjName == 0) {
|
||||
ObjName = "[linker generated]";
|
||||
}
|
||||
Error ("Module `%s': Type mismatch for segment `%s'", ObjName,
|
||||
/* Check if the existing segment has the requested address size */
|
||||
if (S->AddrSize != AddrSize) {
|
||||
/* Allow an empty object name */
|
||||
if (ObjName == 0) {
|
||||
ObjName = "[linker generated]";
|
||||
}
|
||||
Error ("Module `%s': Type mismatch for segment `%s'", ObjName,
|
||||
GetString (Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the segment */
|
||||
@@ -162,12 +162,12 @@ Section* NewSection (Segment* Seg, unsigned long Alignment, unsigned char AddrSi
|
||||
Section* S = xmalloc (sizeof (Section));
|
||||
|
||||
/* Initialize the data */
|
||||
S->Next = 0;
|
||||
S->Seg = Seg;
|
||||
S->Next = 0;
|
||||
S->Seg = Seg;
|
||||
S->Obj = 0;
|
||||
S->FragRoot = 0;
|
||||
S->FragLast = 0;
|
||||
S->Size = 0;
|
||||
S->Size = 0;
|
||||
S->Alignment= Alignment;
|
||||
S->AddrSize = AddrSize;
|
||||
|
||||
@@ -176,7 +176,7 @@ Section* NewSection (Segment* Seg, unsigned long Alignment, unsigned char AddrSi
|
||||
|
||||
/* Adjust the segment size and set the section offset */
|
||||
Seg->Size += S->Fill;
|
||||
S->Offs = Seg->Size; /* Current size is offset */
|
||||
S->Offs = Seg->Size; /* Current size is offset */
|
||||
|
||||
/* Insert the section into the segment */
|
||||
CollAppend (&Seg->Sections, S);
|
||||
@@ -211,7 +211,7 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||
/* Print some data */
|
||||
Print (stdout, 2,
|
||||
"Module `%s': Found segment `%s', size = %u, alignment = %lu, type = %u\n",
|
||||
GetObjFileName (O), GetString (Name), Size, Alignment, Type);
|
||||
GetObjFileName (O), GetString (Name), Size, Alignment, Type);
|
||||
|
||||
/* Get the segment for this section */
|
||||
S = GetSegment (Name, Type, GetObjFileName (O));
|
||||
@@ -241,46 +241,46 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||
/* Start reading fragments from the file and insert them into the section . */
|
||||
while (FragCount--) {
|
||||
|
||||
Fragment* Frag;
|
||||
Fragment* Frag;
|
||||
|
||||
/* Read the fragment type */
|
||||
unsigned char Type = Read8 (F);
|
||||
/* Read the fragment type */
|
||||
unsigned char Type = Read8 (F);
|
||||
|
||||
/* Extract the check mask from the type */
|
||||
unsigned char Bytes = Type & FRAG_BYTEMASK;
|
||||
Type &= FRAG_TYPEMASK;
|
||||
|
||||
/* Handle the different fragment types */
|
||||
switch (Type) {
|
||||
/* Handle the different fragment types */
|
||||
switch (Type) {
|
||||
|
||||
case FRAG_LITERAL:
|
||||
Frag = NewFragment (Type, ReadVar (F), Sec);
|
||||
ReadData (F, Frag->LitBuf, Frag->Size);
|
||||
break;
|
||||
case FRAG_LITERAL:
|
||||
Frag = NewFragment (Type, ReadVar (F), Sec);
|
||||
ReadData (F, Frag->LitBuf, Frag->Size);
|
||||
break;
|
||||
|
||||
case FRAG_EXPR:
|
||||
case FRAG_SEXPR:
|
||||
Frag = NewFragment (Type, Bytes, Sec);
|
||||
Frag->Expr = ReadExpr (F, O);
|
||||
break;
|
||||
case FRAG_EXPR:
|
||||
case FRAG_SEXPR:
|
||||
Frag = NewFragment (Type, Bytes, Sec);
|
||||
Frag->Expr = ReadExpr (F, O);
|
||||
break;
|
||||
|
||||
case FRAG_FILL:
|
||||
/* Will allocate memory, but we don't care... */
|
||||
Frag = NewFragment (Type, ReadVar (F), Sec);
|
||||
break;
|
||||
case FRAG_FILL:
|
||||
/* Will allocate memory, but we don't care... */
|
||||
Frag = NewFragment (Type, ReadVar (F), Sec);
|
||||
break;
|
||||
|
||||
default:
|
||||
Error ("Unknown fragment type in module `%s', segment `%s': %02X",
|
||||
GetObjFileName (O), GetString (S->Name), Type);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
Error ("Unknown fragment type in module `%s', segment `%s': %02X",
|
||||
GetObjFileName (O), GetString (S->Name), Type);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read the line infos into the list of the fragment */
|
||||
ReadLineInfoList (F, O, &Frag->LineInfos);
|
||||
|
||||
/* Remember the module we had this fragment from */
|
||||
Frag->Obj = O;
|
||||
/* Remember the module we had this fragment from */
|
||||
Frag->Obj = O;
|
||||
}
|
||||
|
||||
/* Return the section */
|
||||
@@ -294,11 +294,11 @@ Segment* SegFind (unsigned Name)
|
||||
{
|
||||
Segment* S = HashTab[Name & HASHTAB_MASK];
|
||||
while (S) {
|
||||
if (Name == S->Name) {
|
||||
/* Found */
|
||||
break;
|
||||
}
|
||||
S = S->Next;
|
||||
if (Name == S->Name) {
|
||||
/* Found */
|
||||
break;
|
||||
}
|
||||
S = S->Next;
|
||||
}
|
||||
/* Not found */
|
||||
return S;
|
||||
@@ -318,24 +318,24 @@ int IsBSSType (Segment* S)
|
||||
/* Get the next section */
|
||||
Section* Sec = CollAtUnchecked (&S->Sections, I);
|
||||
|
||||
/* Loop over all fragments */
|
||||
Fragment* F = Sec->FragRoot;
|
||||
while (F) {
|
||||
if (F->Type == FRAG_LITERAL) {
|
||||
unsigned char* Data = F->LitBuf;
|
||||
unsigned long Count = F->Size;
|
||||
while (Count--) {
|
||||
if (*Data++ != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
|
||||
if (GetExprVal (F->Expr) != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
/* Loop over all fragments */
|
||||
Fragment* F = Sec->FragRoot;
|
||||
while (F) {
|
||||
if (F->Type == FRAG_LITERAL) {
|
||||
unsigned char* Data = F->LitBuf;
|
||||
unsigned long Count = F->Size;
|
||||
while (Count--) {
|
||||
if (*Data++ != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
|
||||
if (GetExprVal (F->Expr) != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -351,53 +351,53 @@ void SegDump (void)
|
||||
|
||||
for (I = 0; I < CollCount (&SegmentList); ++I) {
|
||||
Segment* Seg = CollAtUnchecked (&SegmentList, I);
|
||||
printf ("Segment: %s (%lu)\n", GetString (Seg->Name), Seg->Size);
|
||||
printf ("Segment: %s (%lu)\n", GetString (Seg->Name), Seg->Size);
|
||||
for (J = 0; J < CollCount (&Seg->Sections); ++J) {
|
||||
Section* S = CollAtUnchecked (&Seg->Sections, J);
|
||||
unsigned J;
|
||||
Fragment* F = S->FragRoot;
|
||||
printf (" Section:\n");
|
||||
while (F) {
|
||||
switch (F->Type) {
|
||||
Fragment* F = S->FragRoot;
|
||||
printf (" Section:\n");
|
||||
while (F) {
|
||||
switch (F->Type) {
|
||||
|
||||
case FRAG_LITERAL:
|
||||
printf (" Literal (%u bytes):", F->Size);
|
||||
Count = F->Size;
|
||||
Data = F->LitBuf;
|
||||
J = 100;
|
||||
while (Count--) {
|
||||
if (J > 75) {
|
||||
printf ("\n ");
|
||||
J = 3;
|
||||
}
|
||||
printf (" %02X", *Data++);
|
||||
J += 3;
|
||||
}
|
||||
printf ("\n");
|
||||
break;
|
||||
case FRAG_LITERAL:
|
||||
printf (" Literal (%u bytes):", F->Size);
|
||||
Count = F->Size;
|
||||
Data = F->LitBuf;
|
||||
J = 100;
|
||||
while (Count--) {
|
||||
if (J > 75) {
|
||||
printf ("\n ");
|
||||
J = 3;
|
||||
}
|
||||
printf (" %02X", *Data++);
|
||||
J += 3;
|
||||
}
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case FRAG_EXPR:
|
||||
printf (" Expression (%u bytes):\n", F->Size);
|
||||
printf (" ");
|
||||
DumpExpr (F->Expr, 0);
|
||||
break;
|
||||
case FRAG_EXPR:
|
||||
printf (" Expression (%u bytes):\n", F->Size);
|
||||
printf (" ");
|
||||
DumpExpr (F->Expr, 0);
|
||||
break;
|
||||
|
||||
case FRAG_SEXPR:
|
||||
printf (" Signed expression (%u bytes):\n", F->Size);
|
||||
printf (" ");
|
||||
DumpExpr (F->Expr, 0);
|
||||
break;
|
||||
case FRAG_SEXPR:
|
||||
printf (" Signed expression (%u bytes):\n", F->Size);
|
||||
printf (" ");
|
||||
DumpExpr (F->Expr, 0);
|
||||
break;
|
||||
|
||||
case FRAG_FILL:
|
||||
printf (" Empty space (%u bytes)\n", F->Size);
|
||||
break;
|
||||
case FRAG_FILL:
|
||||
printf (" Empty space (%u bytes)\n", F->Size);
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid fragment type: %02X", F->Type);
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
}
|
||||
default:
|
||||
Internal ("Invalid fragment type: %02X", F->Type);
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,13 +409,13 @@ unsigned SegWriteConstExpr (FILE* F, ExprNode* E, int Signed, unsigned Size)
|
||||
*/
|
||||
{
|
||||
static const unsigned long U_Hi[4] = {
|
||||
0x000000FFUL, 0x0000FFFFUL, 0x00FFFFFFUL, 0xFFFFFFFFUL
|
||||
0x000000FFUL, 0x0000FFFFUL, 0x00FFFFFFUL, 0xFFFFFFFFUL
|
||||
};
|
||||
static const long S_Hi[4] = {
|
||||
0x0000007FL, 0x00007FFFL, 0x007FFFFFL, 0x7FFFFFFFL
|
||||
0x0000007FL, 0x00007FFFL, 0x007FFFFFL, 0x7FFFFFFFL
|
||||
};
|
||||
static const long S_Lo[4] = {
|
||||
~0x0000007FL, ~0x00007FFFL, ~0x007FFFFFL, ~0x7FFFFFFFL
|
||||
~0x0000007FL, ~0x00007FFFL, ~0x007FFFFFL, ~0x7FFFFFFFL
|
||||
};
|
||||
|
||||
|
||||
@@ -427,15 +427,15 @@ unsigned SegWriteConstExpr (FILE* F, ExprNode* E, int Signed, unsigned Size)
|
||||
|
||||
/* Check for a range error */
|
||||
if (Signed) {
|
||||
if (Val > S_Hi[Size-1] || Val < S_Lo[Size-1]) {
|
||||
/* Range error */
|
||||
return SEG_EXPR_RANGE_ERROR;
|
||||
}
|
||||
if (Val > S_Hi[Size-1] || Val < S_Lo[Size-1]) {
|
||||
/* Range error */
|
||||
return SEG_EXPR_RANGE_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (((unsigned long)Val) > U_Hi[Size-1]) {
|
||||
/* Range error */
|
||||
return SEG_EXPR_RANGE_ERROR;
|
||||
}
|
||||
if (((unsigned long)Val) > U_Hi[Size-1]) {
|
||||
/* Range error */
|
||||
return SEG_EXPR_RANGE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the value to the file */
|
||||
@@ -465,81 +465,81 @@ void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void*
|
||||
for (I = 0; I < CollCount (&S->Sections); ++I) {
|
||||
|
||||
Section* Sec = CollAtUnchecked (&S->Sections, I);
|
||||
Fragment* Frag;
|
||||
Fragment* Frag;
|
||||
unsigned char FillVal;
|
||||
|
||||
/* Output were this section is from */
|
||||
Print (stdout, 2, " Section from \"%s\"\n", GetObjFileName (Sec->Obj));
|
||||
|
||||
/* If we have fill bytes, write them now. Beware: If this is the
|
||||
/* If we have fill bytes, write them now. Beware: If this is the
|
||||
* first section, the fill value is not considered part of the segment
|
||||
* and therefore taken from the memory area.
|
||||
*/
|
||||
FillVal = (I == 0)? S->MemArea->FillVal : S->FillVal;
|
||||
Print (stdout, 2, " Filling 0x%lx bytes with 0x%02x\n",
|
||||
Print (stdout, 2, " Filling 0x%lx bytes with 0x%02x\n",
|
||||
Sec->Fill, FillVal);
|
||||
WriteMult (Tgt, FillVal, Sec->Fill);
|
||||
Offs += Sec->Fill;
|
||||
WriteMult (Tgt, FillVal, Sec->Fill);
|
||||
Offs += Sec->Fill;
|
||||
|
||||
/* Loop over all fragments in this section */
|
||||
Frag = Sec->FragRoot;
|
||||
while (Frag) {
|
||||
/* Loop over all fragments in this section */
|
||||
Frag = Sec->FragRoot;
|
||||
while (Frag) {
|
||||
|
||||
/* Output fragment data */
|
||||
switch (Frag->Type) {
|
||||
switch (Frag->Type) {
|
||||
|
||||
case FRAG_LITERAL:
|
||||
WriteData (Tgt, Frag->LitBuf, Frag->Size);
|
||||
break;
|
||||
case FRAG_LITERAL:
|
||||
WriteData (Tgt, Frag->LitBuf, Frag->Size);
|
||||
break;
|
||||
|
||||
case FRAG_EXPR:
|
||||
case FRAG_SEXPR:
|
||||
Sign = (Frag->Type == FRAG_SEXPR);
|
||||
/* Call the users function and evaluate the result */
|
||||
switch (F (Frag->Expr, Sign, Frag->Size, Offs, Data)) {
|
||||
case FRAG_EXPR:
|
||||
case FRAG_SEXPR:
|
||||
Sign = (Frag->Type == FRAG_SEXPR);
|
||||
/* Call the users function and evaluate the result */
|
||||
switch (F (Frag->Expr, Sign, Frag->Size, Offs, Data)) {
|
||||
|
||||
case SEG_EXPR_OK:
|
||||
break;
|
||||
case SEG_EXPR_OK:
|
||||
break;
|
||||
|
||||
case SEG_EXPR_RANGE_ERROR:
|
||||
Error ("Range error in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
case SEG_EXPR_RANGE_ERROR:
|
||||
Error ("Range error in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
|
||||
case SEG_EXPR_TOO_COMPLEX:
|
||||
Error ("Expression too complex in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
case SEG_EXPR_TOO_COMPLEX:
|
||||
Error ("Expression too complex in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
|
||||
case SEG_EXPR_INVALID:
|
||||
Error ("Invalid expression in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
case SEG_EXPR_INVALID:
|
||||
Error ("Invalid expression in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid return code from SegWriteFunc");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Internal ("Invalid return code from SegWriteFunc");
|
||||
}
|
||||
break;
|
||||
|
||||
case FRAG_FILL:
|
||||
WriteMult (Tgt, S->FillVal, Frag->Size);
|
||||
break;
|
||||
case FRAG_FILL:
|
||||
WriteMult (Tgt, S->FillVal, Frag->Size);
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid fragment type: %02X", Frag->Type);
|
||||
}
|
||||
default:
|
||||
Internal ("Invalid fragment type: %02X", Frag->Type);
|
||||
}
|
||||
|
||||
/* Update the offset */
|
||||
/* Update the offset */
|
||||
Print (stdout, 2, " Fragment with 0x%x bytes\n",
|
||||
Frag->Size);
|
||||
Offs += Frag->Size;
|
||||
Offs += Frag->Size;
|
||||
|
||||
/* Next fragment */
|
||||
Frag = Frag->Next;
|
||||
}
|
||||
/* Next fragment */
|
||||
Frag = Frag->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,12 +562,12 @@ static int CmpSegStart (const void* K1, const void* K2)
|
||||
|
||||
/* Compare the start addresses */
|
||||
if (S1->PC > S2->PC) {
|
||||
return 1;
|
||||
return 1;
|
||||
} else if (S1->PC < S2->PC) {
|
||||
return -1;
|
||||
return -1;
|
||||
} else {
|
||||
/* Sort segments with equal starts by name */
|
||||
return strcmp (GetString (S1->Name), GetString (S2->Name));
|
||||
/* Sort segments with equal starts by name */
|
||||
return strcmp (GetString (S1->Name), GetString (S2->Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,25 +591,25 @@ void PrintSegmentMap (FILE* F)
|
||||
|
||||
/* Print a header */
|
||||
fprintf (F, "Name Start End Size Align\n"
|
||||
"----------------------------------------------------\n");
|
||||
"----------------------------------------------------\n");
|
||||
|
||||
/* Print the segments */
|
||||
for (I = 0; I < CollCount (&SegmentList); ++I) {
|
||||
|
||||
/* Get a pointer to the segment */
|
||||
Segment* S = SegPool[I];
|
||||
/* Get a pointer to the segment */
|
||||
Segment* S = SegPool[I];
|
||||
|
||||
/* Print empty segments only if explicitly requested */
|
||||
if (VerboseMap || S->Size > 0) {
|
||||
/* Print the segment data */
|
||||
long End = S->PC + S->Size;
|
||||
if (S->Size > 0) {
|
||||
/* Point to last element addressed */
|
||||
--End;
|
||||
}
|
||||
fprintf (F, "%-20s %06lX %06lX %06lX %05lX\n",
|
||||
GetString (S->Name), S->PC, End, S->Size, S->Alignment);
|
||||
}
|
||||
/* Print empty segments only if explicitly requested */
|
||||
if (VerboseMap || S->Size > 0) {
|
||||
/* Print the segment data */
|
||||
long End = S->PC + S->Size;
|
||||
if (S->Size > 0) {
|
||||
/* Point to last element addressed */
|
||||
--End;
|
||||
}
|
||||
fprintf (F, "%-20s %06lX %06lX %06lX %05lX\n",
|
||||
GetString (S->Name), S->PC, End, S->Size, S->Alignment);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the segment pool */
|
||||
@@ -656,10 +656,10 @@ void CheckSegments (void)
|
||||
const Segment* S = CollAtUnchecked (&SegmentList, I);
|
||||
|
||||
/* Check it */
|
||||
if (S->Size > 0 && S->Dumped == 0) {
|
||||
Error ("Missing memory area assignment for segment `%s'",
|
||||
if (S->Size > 0 && S->Dumped == 0) {
|
||||
Error ("Missing memory area assignment for segment `%s'",
|
||||
GetString (S->Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* segments.h */
|
||||
/* segments.h */
|
||||
/* */
|
||||
/* Segment handling for the ld65 linker */
|
||||
/* Segment handling for the ld65 linker */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -60,19 +60,19 @@ typedef struct Segment Segment;
|
||||
struct Segment {
|
||||
unsigned Name; /* Name index of the segment */
|
||||
unsigned Id; /* Segment id for debug info */
|
||||
Segment* Next; /* Hash list */
|
||||
Segment* Next; /* Hash list */
|
||||
unsigned Flags; /* Segment flags */
|
||||
Collection Sections; /* Sections in this segment */
|
||||
struct MemoryArea* MemArea; /* Run memory area once placed */
|
||||
unsigned long PC; /* PC were this segment is located */
|
||||
unsigned long Size; /* Size of data so far */
|
||||
unsigned long PC; /* PC were this segment is located */
|
||||
unsigned long Size; /* Size of data so far */
|
||||
const char* OutputName; /* Name of output file or NULL */
|
||||
unsigned long OutputOffs; /* Offset in output file */
|
||||
unsigned long Alignment; /* Alignment needed */
|
||||
unsigned char FillVal; /* Value to use for fill bytes */
|
||||
unsigned char AddrSize; /* Address size of segment */
|
||||
unsigned char FillVal; /* Value to use for fill bytes */
|
||||
unsigned char AddrSize; /* Address size of segment */
|
||||
unsigned char ReadOnly; /* True for readonly segments (config) */
|
||||
unsigned char Dumped; /* Did we dump this segment? */
|
||||
unsigned char Dumped; /* Did we dump this segment? */
|
||||
};
|
||||
|
||||
|
||||
@@ -80,16 +80,16 @@ struct Segment {
|
||||
/* Section structure (a section is a part of a segment) */
|
||||
typedef struct Section Section;
|
||||
struct Section {
|
||||
Section* Next; /* List of sections in a segment */
|
||||
Segment* Seg; /* Segment that contains the section */
|
||||
Section* Next; /* List of sections in a segment */
|
||||
Segment* Seg; /* Segment that contains the section */
|
||||
struct ObjData* Obj; /* Object file this section comes from */
|
||||
struct Fragment* FragRoot; /* Fragment list */
|
||||
struct Fragment* FragLast; /* Pointer to last fragment */
|
||||
unsigned long Offs; /* Offset into the segment */
|
||||
unsigned long Size; /* Size of the section */
|
||||
struct Fragment* FragRoot; /* Fragment list */
|
||||
struct Fragment* FragLast; /* Pointer to last fragment */
|
||||
unsigned long Offs; /* Offset into the segment */
|
||||
unsigned long Size; /* Size of the section */
|
||||
unsigned long Fill; /* Fill bytes for alignment */
|
||||
unsigned long Alignment; /* Alignment */
|
||||
unsigned char AddrSize; /* Address size of segment */
|
||||
unsigned char AddrSize; /* Address size of segment */
|
||||
};
|
||||
|
||||
|
||||
@@ -97,21 +97,21 @@ struct Section {
|
||||
/* Prototype for a function that is used to write expressions to the target
|
||||
* file (used in SegWrite). It returns one of the following values:
|
||||
*/
|
||||
#define SEG_EXPR_OK 0U /* Ok */
|
||||
#define SEG_EXPR_RANGE_ERROR 1U /* Range error */
|
||||
#define SEG_EXPR_TOO_COMPLEX 2U /* Expression too complex */
|
||||
#define SEG_EXPR_OK 0U /* Ok */
|
||||
#define SEG_EXPR_RANGE_ERROR 1U /* Range error */
|
||||
#define SEG_EXPR_TOO_COMPLEX 2U /* Expression too complex */
|
||||
#define SEG_EXPR_INVALID 3U /* Expression is invalid (e.g. unmapped segment) */
|
||||
|
||||
typedef unsigned (*SegWriteFunc) (ExprNode* E, /* The expression to write */
|
||||
int Signed, /* Signed expression? */
|
||||
unsigned Size, /* Size (=range) */
|
||||
unsigned long Offs, /* File offset */
|
||||
void* Data); /* Callers data */
|
||||
typedef unsigned (*SegWriteFunc) (ExprNode* E, /* The expression to write */
|
||||
int Signed, /* Signed expression? */
|
||||
unsigned Size, /* Size (=range) */
|
||||
unsigned long Offs, /* File offset */
|
||||
void* Data); /* Callers data */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
/* Definition of a span */
|
||||
struct Span {
|
||||
unsigned Id; /* Id of the span */
|
||||
unsigned Id; /* Id of the span */
|
||||
unsigned Sec; /* Section id of this span */
|
||||
unsigned long Offs; /* Offset of span within segment */
|
||||
unsigned long Size; /* Size of span */
|
||||
@@ -64,7 +64,7 @@ struct Span {
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Forwards */
|
||||
/* Forwards */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ struct Segment;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ typedef struct Span Span;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ StringPool* StrPool = 0;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ extern StringPool* StrPool;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ StringPool* TypePool = 0;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ extern StringPool* TypePool;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user