Working on the condes feature

git-svn-id: svn://svn.cc65.org/cc65/trunk@451 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2000-11-20 15:22:57 +00:00
parent 9c35f5278a
commit b9970cb7da
35 changed files with 1029 additions and 388 deletions

188
src/ld65/condes.c Normal file
View File

@@ -0,0 +1,188 @@
/*****************************************************************************/
/* */
/* condes.h */
/* */
/* Module constructor/destructor support */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
/* common */
#include "check.h"
#include "coll.h"
#include "xmalloc.h"
/* ld65 */
#include "exports.h"
#include "segments.h"
#include "condes.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Struct describing one condes type */
typedef struct ConDesDesc ConDesDesc;
struct ConDesDesc {
Collection ExpList; /* List of exported symbols */
char* Label; /* Name of table label */
char* SegName; /* Name of segment the table is in */
unsigned char Enable; /* Table enabled */
};
/* Array for all types */
static ConDesDesc ConDes[CD_TYPE_COUNT] = {
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
{ STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
};
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void ConDesAddExport (struct Export* E)
/* Add the given export to the list of constructors/destructor */
{
unsigned Type;
/* 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);
}
}
}
void ConDesSetSegName (unsigned Type, const char* SegName)
/* Set the segment name where the table should go */
{
/* Check the parameters */
PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && SegName != 0);
/* Setting the segment name twice is bad */
CHECK (ConDes[Type].SegName == 0);
/* Set the name */
ConDes[Type].SegName = xstrdup (SegName);
}
void ConDesSetLabel (unsigned Type, const char* Name)
/* Set the label for the given ConDes type */
{
/* Check the parameters */
PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && Name != 0);
/* Setting the label twice is bad */
CHECK (ConDes[Type].Label == 0);
/* Set the name */
ConDes[Type].Label = xstrdup (Name);
}
const char* ConDesGetSegName (unsigned Type)
/* Return the segment name for the given ConDes type */
{
/* Check the parameters */
PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
/* Return the name */
return ConDes[Type].SegName;
}
const char* ConDesGetLabel (unsigned Type)
/* Return the label for the given ConDes type */
{
/* Check the parameters */
PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
/* Return the name */
return ConDes[Type].Label;
}
int ConDesHasSegName (unsigned Type)
/* Return true if a segment name is already defined for this ConDes type */
{
return (ConDesGetSegName(Type) != 0);
}
int ConDesHasLabel (unsigned Type)
/* Return true if a label is already defined for this ConDes type */
{
return (ConDesGetLabel(Type) != 0);
}
void ConDesCreate (void)
/* Create the condes tables if requested */
{
}
void ConDesDump (void)
/* Dump ConDes data to stdout for debugging */
{
unsigned Type;
for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
Collection* ExpList = &ConDes[Type].ExpList;
printf ("CONDES(%u): %u symbols\n", Type, CollCount (ExpList));
}
}

View File

@@ -1,8 +1,8 @@
/*****************************************************************************/
/* */
/* initfunc.h */
/* condes.h */
/* */
/* Init/cleanup function handling */
/* Module constructor/destructor support */
/* */
/* */
/* */
@@ -33,13 +33,13 @@
#ifndef INITFUNC_H
#define INITFUNC_H
#ifndef CONDES_H
#define CONDES_H
/*****************************************************************************/
/* Forwards */
/* Forwards */
/*****************************************************************************/
@@ -54,15 +54,36 @@ struct Export;
void AddInitFunc (struct Export* E);
/* Add the given export to the list of initializers */
void ConDesAddExport (struct Export* E);
/* Add the given export to the list of constructors/destructor */
void AddCleanupFunc (struct Export* E);
/* Add the given export to the list of cleanup functions */
void ConDesSetSegName (unsigned Type, const char* SegName);
/* Set the segment name where the table should go */
void ConDesSetLabel (unsigned Type, const char* Name);
/* Set the label for the given ConDes type */
const char* ConDesGetSegName (unsigned Type);
/* Return the segment name for the given ConDes type */
const char* ConDesGetLabel (unsigned Type);
/* Return the label for the given ConDes type */
int ConDesHasSegName (unsigned Type);
/* Return true if a segment name is already defined for this ConDes type */
int ConDesHasLabel (unsigned Type);
/* Return true if a label is already defined for this ConDes type */
void ConDesCreate (void);
/* Create the condes tables if requested */
void ConDesDump (void);
/* Dump ConDes data to stdout for debugging */
/* End of initfunc.h */
/* End of condes.h */
#endif

View File

@@ -42,14 +42,15 @@
#include "check.h"
#include "bitops.h"
#include "xmalloc.h"
/* ld65 */
#include "error.h"
#include "global.h"
#include "bin.h"
#include "o65.h"
#include "binfmt.h"
#include "condes.h"
#include "error.h"
#include "exports.h"
#include "global.h"
#include "o65.h"
#include "scanner.h"
#include "config.h"
@@ -115,6 +116,141 @@ static unsigned O65Attr = 0;
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
static File* NewFile (const char* Name);
/* Create a new file descriptor and insert it into the list */
/*****************************************************************************/
/* List management */
/*****************************************************************************/
static File* FindFile (const char* Name)
/* Find a file with a given name. */
{
File* F = FileList;
while (F) {
if (strcmp (F->Name, Name) == 0) {
return F;
}
F = F->Next;
}
return 0;
}
static File* GetFile (const char* Name)
/* Get a file entry with the given name. Create a new one if needed. */
{
File* F = FindFile (Name);
if (F == 0) {
/* Create a new one */
F = NewFile (Name);
}
return F;
}
static void FileInsert (File* F, Memory* M)
/* Insert the memory area into the files list */
{
M->F = F;
if (F->MemList == 0) {
/* First entry */
F->MemList = M;
} else {
F->MemLast->FNext = M;
}
F->MemLast = M;
}
static Memory* CfgFindMemory (const char* Name)
/* Find the memory are with the given name. Return NULL if not found */
{
Memory* M = MemoryList;
while (M) {
if (strcmp (M->Name, Name) == 0) {
return M;
}
M = M->Next;
}
return 0;
}
static Memory* CfgGetMemory (const char* Name)
/* Find the memory are with the given name. Print an error on an invalid name */
{
Memory* M = CfgFindMemory (Name);
if (M == 0) {
CfgError ("Invalid memory area `%s'", Name);
}
return M;
}
static SegDesc* CfgFindSegDesc (const char* Name)
/* Find the segment descriptor with the given name, return NULL if not found. */
{
SegDesc* S = SegDescList;
while (S) {
if (strcmp (S->Name, Name) == 0) {
/* Found */
return S;
}
S = S->Next;
}
/* Not found */
return 0;
}
static void SegDescInsert (SegDesc* S)
/* Insert a segment descriptor into the list of segment descriptors */
{
/* Insert the struct into the list */
S->Next = SegDescList;
SegDescList = S;
++SegDescCount;
}
static void MemoryInsert (Memory* M, SegDesc* S)
/* Insert the segment descriptor into the memory area list */
{
/* Create a new node for the entry */
MemListNode* N = xmalloc (sizeof (MemListNode));
N->Seg = S;
N->Next = 0;
if (M->SegLast == 0) {
/* First entry */
M->SegList = N;
} else {
M->SegLast->Next = N;
}
M->SegLast = N;
}
/*****************************************************************************/
/* Constructors/Destructors */
/*****************************************************************************/
@@ -156,13 +292,9 @@ static Memory* NewMemory (const char* Name)
unsigned Len = strlen (Name);
/* Check for duplicate names */
Memory* M = MemoryList;
while (M) {
if (strcmp (M->Name, Name) == 0) {
CfgError ("Memory area `%s' defined twice", Name);
break;
}
M = M->Next;
Memory* M = CfgFindMemory (Name);
if (M) {
CfgError ("Memory area `%s' defined twice", Name);
}
/* Allocate memory */
@@ -208,13 +340,9 @@ static SegDesc* NewSegDesc (const char* Name)
unsigned Len = strlen (Name);
/* Check for duplicate names */
SegDesc* S = SegDescList;
while (S) {
if (strcmp (S->Name, Name) == 0) {
CfgError ("Segment `%s' defined twice", Name);
break;
}
S = S->Next;
SegDesc* S = CfgFindSegDesc (Name);
if (S) {
CfgError ("Segment `%s' defined twice", Name);
}
/* Verify that the given segment does really exist */
@@ -278,49 +406,6 @@ static void AttrCheck (unsigned Attr, unsigned Mask, const char* Name)
static File* FindFile (const char* Name)
/* Find a file with a given name. */
{
File* F = FileList;
while (F) {
if (strcmp (F->Name, Name) == 0) {
return F;
}
F = F->Next;
}
return 0;
}
static File* GetFile (const char* Name)
/* Get a file entry with the given name. Create a new one if needed. */
{
File* F = FindFile (Name);
if (F == 0) {
/* Create a new one */
F = NewFile (Name);
}
return F;
}
static void FileInsert (File* F, Memory* M)
/* Insert the memory area into the files list */
{
M->F = F;
if (F->MemList == 0) {
/* First entry */
F->MemList = M;
} else {
F->MemLast->FNext = M;
}
F->MemLast = M;
}
static void ParseMemory (void)
/* Parse a MEMORY section */
{
@@ -351,7 +436,7 @@ static void ParseMemory (void)
while (CfgTok == CFGTOK_IDENT) {
/* Map the identifier to a token */
unsigned AttrTok;
cfgtok_t AttrTok;
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
AttrTok = CfgTok;
@@ -477,7 +562,7 @@ static void ParseFiles (void)
while (CfgTok == CFGTOK_IDENT) {
/* Map the identifier to a token */
unsigned AttrTok;
cfgtok_t AttrTok;
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
AttrTok = CfgTok;
@@ -528,63 +613,6 @@ static void ParseFiles (void)
static Memory* CfgFindMemory (const char* Name)
/* Find the memory are with the given name. Return NULL if not found */
{
Memory* M = MemoryList;
while (M) {
if (strcmp (M->Name, Name) == 0) {
return M;
}
M = M->Next;
}
return 0;
}
static Memory* CfgGetMemory (const char* Name)
/* Find the memory are with the given name. Print an error on an invalid name */
{
Memory* M = CfgFindMemory (Name);
if (M == 0) {
CfgError ("Invalid memory area `%s'", Name);
}
return M;
}
static void SegDescInsert (SegDesc* S)
/* Insert a segment descriptor into the list of segment descriptors */
{
/* Insert the struct into the list */
S->Next = SegDescList;
SegDescList = S;
++SegDescCount;
}
static void MemoryInsert (Memory* M, SegDesc* S)
/* Insert the segment descriptor into the memory area list */
{
/* Create a new node for the entry */
MemListNode* N = xmalloc (sizeof (MemListNode));
N->Seg = S;
N->Next = 0;
if (M->SegLast == 0) {
/* First entry */
M->SegList = N;
} else {
M->SegLast->Next = N;
}
M->SegLast = N;
}
static void ParseSegments (void)
/* Parse a SEGMENTS section */
{
@@ -623,7 +651,7 @@ static void ParseSegments (void)
while (CfgTok == CFGTOK_IDENT) {
/* Map the identifier to a token */
unsigned AttrTok;
cfgtok_t AttrTok;
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
AttrTok = CfgTok;
@@ -649,9 +677,11 @@ static void ParseSegments (void)
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
switch (CfgTok) {
case CFGTOK_RO: S->Flags |= SF_RO; break;
case CFGTOK_RW: /* Default */ break;
case CFGTOK_BSS: S->Flags |= SF_BSS; break;
case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break;
case CFGTOK_WPROT: S->Flags |= (SF_RO | SF_WPROT); break;
default: Internal ("Unexpected token: %d", CfgTok);
}
break;
@@ -788,7 +818,7 @@ static void ParseO65 (void)
while (CfgTok == CFGTOK_IDENT) {
/* Map the identifier to a token */
unsigned AttrTok;
cfgtok_t AttrTok;
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
AttrTok = CfgTok;
@@ -843,7 +873,7 @@ static void ParseO65 (void)
break;
default:
Error ("Unexpected type token");
CfgError ("Unexpected type token");
}
break;
@@ -863,7 +893,7 @@ static void ParseO65 (void)
break;
default:
Error ("Unexpected OS token");
CfgError ("Unexpected OS token");
}
break;
@@ -892,7 +922,7 @@ static void ParseFormats (void)
while (CfgTok == CFGTOK_IDENT) {
/* Map the identifier to a token */
unsigned FormatTok;
cfgtok_t FormatTok;
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
FormatTok = CfgTok;
@@ -922,16 +952,165 @@ static void ParseFormats (void)
static void ParseConDes (void)
/* Parse the CONDES feature */
{
static const IdentTok Attributes [] = {
{ "SEGMENT", CFGTOK_SEGMENT },
{ "LABEL", CFGTOK_LABEL },
{ "TYPE", CFGTOK_TYPE },
};
static const IdentTok Types [] = {
{ "CONSTRUCTOR", CFGTOK_CONSTRUCTOR },
{ "DESTRUCTOR", CFGTOK_DESTRUCTOR },
};
/* Attribute values. */
char SegName[sizeof (CfgSVal)];
char Label[sizeof (CfgSVal)];
int Type = -1; /* Initialize to avoid gcc warnings */
/* Bitmask to remember the attributes we got already */
enum {
atNone = 0x0000,
atSegName = 0x0001,
atLabel = 0x0002,
atType = 0x0004
};
unsigned AttrFlags = atNone;
/* Parse the attributes */
while (1) {
/* Map the identifier to a token */
cfgtok_t AttrTok;
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
AttrTok = CfgTok;
/* An optional assignment follows */
CfgNextTok ();
CfgOptionalAssign ();
/* Check which attribute was given */
switch (AttrTok) {
case CFGTOK_SEGMENT:
/* Don't allow this twice */
FlagAttr (&AttrFlags, atSegName, "SEGMENT");
/* We expect an identifier */
CfgAssureIdent ();
/* Remember the value for later */
strcpy (SegName, CfgSVal);
break;
case CFGTOK_LABEL:
/* Don't allow this twice */
FlagAttr (&AttrFlags, atLabel, "LABEL");
/* We expect an identifier */
CfgAssureIdent ();
/* Remember the value for later */
strcpy (Label, CfgSVal);
break;
case CFGTOK_TYPE:
/* Don't allow this twice */
FlagAttr (&AttrFlags, atType, "TYPE");
/* The type may be given as id or numerical */
if (CfgTok == CFGTOK_INTCON) {
CfgRangeCheck (CD_TYPE_MIN, CD_TYPE_MAX);
Type = (int) CfgIVal;
} else {
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
switch (CfgTok) {
case CFGTOK_CONSTRUCTOR: Type = CD_TYPE_CON; break;
case CFGTOK_DESTRUCTOR: Type = CD_TYPE_DES; break;
default: FAIL ("Unexpected type token");
}
}
break;
default:
FAIL ("Unexpected attribute token");
}
/* Skip the attribute value */
CfgNextTok ();
/* Semicolon ends the ConDes decl, otherwise accept an optional comma */
if (CfgTok == CFGTOK_SEMI) {
break;
} else if (CfgTok == CFGTOK_COMMA) {
CfgNextTok ();
}
}
/* Check if we have all mandatory attributes */
AttrCheck (AttrFlags, atSegName, "SEGMENT");
AttrCheck (AttrFlags, atLabel, "LABEL");
AttrCheck (AttrFlags, atType, "TYPE");
/* Check if the condes has already attributes defined */
if (ConDesHasSegName(Type) || ConDesHasLabel(Type)) {
CfgError ("CONDES attributes for type %d are already defined", Type);
}
/* Define the attributes */
ConDesSetSegName (Type, SegName);
ConDesSetLabel (Type, Label);
}
static void ParseFeatures (void)
/* Parse a features section */
{
static const IdentTok Features [] = {
{ "CONDES", CFGTOK_CONDES },
};
while (CfgTok == CFGTOK_IDENT) {
/* Map the identifier to a token */
cfgtok_t FeatureTok;
CfgSpecialToken (Features, ENTRY_COUNT (Features), "Feature");
FeatureTok = CfgTok;
/* Skip the name and the following colon */
CfgNextTok ();
CfgConsumeColon ();
/* Parse the format options */
switch (FeatureTok) {
case CFGTOK_CONDES:
ParseConDes ();
break;
default:
Error ("Unexpected feature token");
}
/* Skip the semicolon */
CfgConsumeSemi ();
}
}
static void ParseConfig (void)
/* Parse the config file */
{
static const IdentTok BlockNames [] = {
{ "MEMORY", CFGTOK_MEMORY },
{ "FILES", CFGTOK_FILES },
{ "SEGMENTS", CFGTOK_SEGMENTS },
{ "FORMATS", CFGTOK_FORMATS },
{ "MEMORY", CFGTOK_MEMORY },
{ "FILES", CFGTOK_FILES },
{ "SEGMENTS", CFGTOK_SEGMENTS },
{ "FORMATS", CFGTOK_FORMATS },
{ "FEATURES", CFGTOK_FEATURES },
};
unsigned BlockTok;
cfgtok_t BlockTok;
do {
@@ -947,23 +1126,27 @@ static void ParseConfig (void)
switch (BlockTok) {
case CFGTOK_MEMORY:
ParseMemory ();
break;
ParseMemory ();
break;
case CFGTOK_FILES:
ParseFiles ();
break;
ParseFiles ();
break;
case CFGTOK_SEGMENTS:
ParseSegments ();
break;
ParseSegments ();
break;
case CFGTOK_FORMATS:
ParseFormats ();
ParseFormats ();
break;
case CFGTOK_FEATURES:
ParseFeatures ();
break;
default:
FAIL ("Unexpected block token");
FAIL ("Unexpected block token");
}

View File

@@ -45,10 +45,10 @@
#include "xmalloc.h"
/* ld65 */
#include "global.h"
#include "condes.h"
#include "error.h"
#include "fileio.h"
#include "initfunc.h"
#include "global.h"
#include "objdata.h"
#include "expr.h"
#include "exports.h"
@@ -202,17 +202,18 @@ static Export* NewExport (unsigned char Type, const char* Name, ObjData* Obj)
/* Initialize the fields */
E->Next = 0;
E->Flags = 0;
E->Flags = 0;
E->Obj = Obj;
E->ImpCount = 0;
E->ImpList = 0;
E->Expr = 0;
E->Type = Type;
memset (E->ConDes, 0, sizeof (E->ConDes));
if (Name) {
E->Name = xstrdup (Name);
} else {
/* Name will get added later */
E->Name = 0;
/* Name will get added later */
E->Name = 0;
}
/* Return the new entry */
@@ -229,9 +230,9 @@ void InsertExport (Export* E)
Import* Imp;
unsigned HashVal;
/* If this is an initializer, insert it into the initializer list */
if (IS_EXP_INIT (E->Type)) {
AddInitFunc (E);
/* Insert the export into any condes tables if needed */
if (IS_EXP_CONDES (E->Type)) {
ConDesAddExport (E);
}
/* Create a hash value for the given name */
@@ -272,7 +273,7 @@ void InsertExport (Export* E)
}
} else {
/* Duplicate entry, ignore it */
Warning ("Duplicate external identifier: `%s'", L->Name);
Warning ("Duplicate external identifier: `%s'", L->Name);
}
return;
}
@@ -293,6 +294,7 @@ Export* ReadExport (FILE* F, ObjData* O)
/* Read an export from a file */
{
unsigned char Type;
unsigned ConDesCount;
Export* E;
/* Read the type */
@@ -301,6 +303,29 @@ Export* ReadExport (FILE* F, ObjData* O)
/* Create a new export without a name */
E = NewExport (Type, 0, O);
/* Read the constructor/destructor decls if we have any */
ConDesCount = GET_EXP_CONDES_COUNT (Type);
if (ConDesCount > 0) {
unsigned char ConDes[CD_TYPE_COUNT];
unsigned I;
/* 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. This array was
* cleared by the constructor (NewExport), so we must only set the
* fields that contain values.
*/
for (I = 0; I < ConDesCount; ++I) {
unsigned ConDesType = CD_GET_TYPE (ConDes[I]);
unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]);
E->ConDes[ConDesType] = ConDesPrio;
}
}
/* Read the name */
E->Name = ReadStr (F);
@@ -562,7 +587,7 @@ void PrintExportMap (FILE* F)
GetExportVal (E),
E->ImpCount? 'R' : ' ',
IS_EXP_ZP (E->Type)? 'Z' : ' ',
IS_EXP_INIT (E->Type)? 'I' : ' ');
IS_EXP_CONDES (E->Type)? 'I' : ' ');
if (++Count == 2) {
Count = 0;
fprintf (F, "\n");

View File

@@ -41,6 +41,7 @@
#include <stdio.h>
/* common */
#include "cddefs.h"
#include "exprdefs.h"
#include "filepos.h"
@@ -81,7 +82,8 @@ struct Export {
Import* ImpList; /* List of imports for this symbol */
FilePos Pos; /* File position of definition */
ExprNode* Expr; /* Expression (0 if not def'd) */
unsigned char Type; /* Type of export */
unsigned char Type; /* Type of export */
unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */
char* Name; /* Name - dynamically allocated */
};
@@ -157,7 +159,7 @@ void CircularRefError (const Export* E);
/* Print an error about a circular reference using to define the given export */
/* End of exports.h */
#endif

View File

@@ -284,9 +284,12 @@ FilePos* ReadFilePos (FILE* F, FilePos* Pos)
void* ReadData (FILE* F, void* Data, unsigned Size)
/* Read data from the file */
{
if (fread (Data, 1, Size, F) != Size) {
Error ("Read error (file corrupt?)");
{
/* Explicitly allow reading zero bytes */
if (Size > 0) {
if (fread (Data, 1, Size, F) != Size) {
Error ("Read error (file corrupt?)");
}
}
return Data;
}

View File

@@ -1,79 +0,0 @@
/*****************************************************************************/
/* */
/* initfunc.c */
/* */
/* Init/cleanup function handling */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
/* common */
#include "coll.h"
/* ld65 */
#include "exports.h"
#include "segments.h"
#include "initfunc.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* List of all exports that are also initializers/cleanup functions */
static Collection InitFunctions = STATIC_COLLECTION_INITIALIZER;
static Collection CleanupFunctions = STATIC_COLLECTION_INITIALIZER;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void AddInitFunc (Export* E)
/* Add the given export to the list of initializers */
{
CollAppend (&InitFunctions, E);
}
void AddCleanupFunc (Export* E)
/* Add the given export to the list of cleanup functions */
{
CollAppend (&CleanupFunctions, E);
}

View File

@@ -48,6 +48,7 @@
/* ld65 */
#include "binfmt.h"
#include "condes.h"
#include "config.h"
#include "error.h"
#include "exports.h"
@@ -404,6 +405,9 @@ int main (int argc, char* argv [])
/* Read the config file */
CfgRead ();
/* Create the condes tables if requested */
ConDesCreate ();
/* Assign start addresses for the segments, define linker symbols */
CfgAssignSegments ();
@@ -424,6 +428,7 @@ int main (int argc, char* argv [])
/* Dump the data for debugging */
if (Verbose > 1) {
SegDump ();
ConDesDump ();
}
/* Return an apropriate exit code */

View File

@@ -19,6 +19,7 @@ CVT=cfg/cvt-cfg.pl
OBJS = bin.o \
binfmt.o \
condes.o \
config.o \
dbgsyms.o \
error.o \
@@ -28,7 +29,6 @@ OBJS = bin.o \
fileio.o \
fragment.o \
global.o \
initfunc.o \
library.o \
main.o \
mapfile.o \

View File

@@ -56,7 +56,7 @@
/* Current token and attributes */
unsigned CfgTok;
cfgtok_t CfgTok;
char CfgSVal [CFG_MAX_IDENT_LEN+1];
unsigned long CfgIVal;
@@ -322,7 +322,7 @@ Again:
void CfgConsume (unsigned T, const char* Msg)
void CfgConsume (cfgtok_t T, const char* Msg)
/* Skip a token, print an error message if not found */
{
if (CfgTok != T) {
@@ -535,3 +535,4 @@ void CfgCloseInput (void)

View File

@@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@@ -45,67 +45,77 @@
/* Config file tokens */
#define CFGTOK_NONE 0
#define CFGTOK_INTCON 1
#define CFGTOK_STRCON 2
#define CFGTOK_IDENT 3
#define CFGTOK_LCURLY 4
#define CFGTOK_RCURLY 5
#define CFGTOK_SEMI 6
#define CFGTOK_COMMA 7
#define CFGTOK_EQ 8
#define CFGTOK_COLON 9
#define CFGTOK_DOT 10
#define CFGTOK_EOF 11
typedef enum {
CFGTOK_NONE,
CFGTOK_INTCON,
CFGTOK_STRCON,
CFGTOK_IDENT,
CFGTOK_LCURLY,
CFGTOK_RCURLY,
CFGTOK_SEMI,
CFGTOK_COMMA,
CFGTOK_EQ,
CFGTOK_COLON,
CFGTOK_DOT,
CFGTOK_EOF,
/* Special identifiers */
#define CFGTOK_MEMORY 20
#define CFGTOK_FILES 21
#define CFGTOK_SEGMENTS 22
#define CFGTOK_FORMATS 23
/* Special identifiers */
CFGTOK_MEMORY,
CFGTOK_FILES,
CFGTOK_SEGMENTS,
CFGTOK_FORMATS,
CFGTOK_FEATURES,
#define CFGTOK_START 30
#define CFGTOK_SIZE 31
#define CFGTOK_TYPE 32
#define CFGTOK_FILE 33
#define CFGTOK_DEFINE 34
#define CFGTOK_FILL 35
#define CFGTOK_FILLVAL 36
#define CFGTOK_EXPORT 37
#define CFGTOK_IMPORT 38
#define CFGTOK_OS 39
#define CFGTOK_FORMAT 40
CFGTOK_START,
CFGTOK_SIZE,
CFGTOK_TYPE,
CFGTOK_FILE,
CFGTOK_DEFINE,
CFGTOK_FILL,
CFGTOK_FILLVAL,
CFGTOK_EXPORT,
CFGTOK_IMPORT,
CFGTOK_OS,
CFGTOK_FORMAT,
#define CFGTOK_LOAD 50
#define CFGTOK_RUN 51
#define CFGTOK_ALIGN 52
#define CFGTOK_OFFSET 53
CFGTOK_LOAD,
CFGTOK_RUN,
CFGTOK_ALIGN,
CFGTOK_OFFSET,
#define CFGTOK_RO 60
#define CFGTOK_RW 61
#define CFGTOK_BSS 62
#define CFGTOK_ZP 63
#define CFGTOK_WPROT 64
CFGTOK_RO,
CFGTOK_RW,
CFGTOK_BSS,
CFGTOK_ZP,
CFGTOK_WPROT,
#define CFGTOK_O65 70
#define CFGTOK_BIN 71
CFGTOK_O65,
CFGTOK_BIN,
#define CFGTOK_SMALL 80
#define CFGTOK_LARGE 81
CFGTOK_SMALL,
CFGTOK_LARGE,
#define CFGTOK_TRUE 90
#define CFGTOK_FALSE 91
CFGTOK_TRUE,
CFGTOK_FALSE,
#define CFGTOK_LUNIX 100
#define CFGTOK_OSA65 101
CFGTOK_LUNIX,
CFGTOK_OSA65,
CFGTOK_CONDES,
CFGTOK_SEGMENT,
CFGTOK_LABEL,
CFGTOK_CONSTRUCTOR,
CFGTOK_DESTRUCTOR
} cfgtok_t;
/* Mapping table entry, special identifier --> token */
typedef struct IdentTok_ IdentTok;
struct IdentTok_ {
const char* Ident; /* Identifier */
unsigned Tok; /* Token for identifier */
const char* Ident; /* Identifier */
cfgtok_t Tok; /* Token for identifier */
};
#define ENTRY_COUNT(s) (sizeof (s) / sizeof (s [0]))
@@ -113,7 +123,7 @@ struct IdentTok_ {
/* Current token and attributes */
#define CFG_MAX_IDENT_LEN 255
extern unsigned CfgTok;
extern cfgtok_t CfgTok;
extern char CfgSVal [CFG_MAX_IDENT_LEN+1];
extern unsigned long CfgIVal;
@@ -138,7 +148,7 @@ void CfgError (const char* Format, ...) attribute((format(printf,1,2)));
void CfgNextTok (void);
/* Read the next token from the input stream */
void CfgConsume (unsigned T, const char* Msg);
void CfgConsume (cfgtok_t T, const char* Msg);
/* Skip a token, print an error message if not found */
void CfgConsumeSemi (void);
@@ -196,4 +206,4 @@ void CfgCloseInput (void);