1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-28 19:29:53 +00:00

Added assertions

git-svn-id: svn://svn.cc65.org/cc65/trunk@2202 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-06-06 12:45:19 +00:00
parent 0aa75f12d6
commit bb24d025f6
29 changed files with 405 additions and 183 deletions

View File

@ -111,6 +111,8 @@ void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
H->LineInfoSize = Read32 (Obj);
H->StrPoolOffs = Read32 (Obj);
H->StrPoolSize = Read32 (Obj);
H->AssertOffs = Read32 (Obj);
H->AssertSize = Read32 (Obj);
}
@ -137,6 +139,8 @@ void ObjWriteHeader (FILE* Obj, ObjHeader* H)
Write32 (Obj, H->LineInfoSize);
Write32 (Obj, H->StrPoolOffs);
Write32 (Obj, H->StrPoolSize);
Write32 (Obj, H->AssertOffs);
Write32 (Obj, H->AssertSize);
}
@ -201,7 +205,7 @@ void ObjAdd (const char* Name)
O->StringCount = ReadVar (Obj);
O->Strings = xmalloc (O->StringCount * sizeof (char*));
for (I = 0; I < O->StringCount; ++I) {
O->Strings[I] = ReadStr (Obj);
O->Strings[I] = ReadStr (Obj);
}
/* Skip the object file header */
@ -219,6 +223,8 @@ void ObjAdd (const char* Name)
H.FileOffs = LibCopyTo (Obj, H.FileSize) - O->Start;
fseek (Obj, H.LineInfoOffs, SEEK_SET);
H.LineInfoOffs = LibCopyTo (Obj, H.LineInfoSize) - O->Start;
fseek (Obj, H.AssertOffs, SEEK_SET);
H.AssertOffs = LibCopyTo (Obj, H.AssertSize) - O->Start;
/* Calculate the amount of data written */
O->Size = ftell (NewLib) - O->Start;
@ -270,7 +276,7 @@ void ObjExtract (const char* Name)
Error ("Cannot open target file `%s': %s", Name, strerror (errno));
}
/* Copy the first four segments including the header to the new file */
/* Copy anything to the new file that has no special handling */
LibCopyFrom (O->Start, O->Size, Obj);
/* Write imports and exports */
@ -284,7 +290,7 @@ void ObjExtract (const char* Name)
WriteVar (Obj, O->StringCount);
for (I = 0; I < O->StringCount; ++I) {
WriteStr (Obj, O->Strings[I]);
}
}
StrPoolSize = ftell (Obj) - StrPoolStart;
/* Seek back and read the header */

View File

@ -162,6 +162,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
"Illegal macro package name",
"Illegal emulation feature",
"Illegal scope specifier",
"Illegal assert action",
"Syntax error",
"Symbol `%s' is already defined",
"Undefined symbol `%s'",

View File

@ -103,6 +103,7 @@ enum Errors {
ERR_ILLEGAL_MACPACK,
ERR_ILLEGAL_FEATURE,
ERR_ILLEGAL_SCOPE,
ERR_ILLEGAL_ASSERT_ACTION,
ERR_SYNTAX,
ERR_SYM_ALREADY_DEFINED,
ERR_SYM_UNDEFINED,

View File

@ -56,6 +56,7 @@
#include "incpath.h"
#include "instr.h"
#include "istack.h"
#include "ldassert.h"
#include "lineinfo.h"
#include "listing.h"
#include "macro.h"
@ -484,6 +485,9 @@ static void CreateObjFile (void)
/* Write the string pool */
WriteStrPool ();
/* Write the assertions */
WriteAssertions ();
/* Write an updated header and close the file */
ObjClose ();
}

View File

@ -22,6 +22,7 @@ OBJS = condasm.o \
incpath.o \
instr.o \
istack.o \
ldassert.o \
lineinfo.o \
listing.o \
macpack.o \

View File

@ -55,6 +55,7 @@ OBJS = condasm.obj \
incpath.obj \
instr.obj \
istack.obj \
ldassert.obj \
lineinfo.obj \
listing.obj \
macpack.obj \

View File

@ -81,7 +81,9 @@ static ObjHeader Header = {
0, /* 32: Offset to list of line infos */
0, /* 32: Size of line infos */
0, /* 32: Offset to string pool */
0 /* 32: Size of string pool */
0, /* 32: Size of string pool */
0, /* 32: Offset to assertion table */
0 /* 32: Size of assertion table */
};
@ -134,6 +136,8 @@ static void ObjWriteHeader (void)
ObjWrite32 (Header.LineInfoSize);
ObjWrite32 (Header.StrPoolOffs);
ObjWrite32 (Header.StrPoolSize);
ObjWrite32 (Header.AssertOffs);
ObjWrite32 (Header.AssertSize);
}
@ -442,3 +446,19 @@ void ObjEndStrPool (void)
void ObjStartAssertions (void)
/* Mark the start of the assertion table */
{
Header.AssertOffs = ftell (F);
}
void ObjEndAssertions (void)
/* Mark the end of the assertion table */
{
Header.AssertSize = ftell (F) - Header.AssertOffs;
}

View File

@ -133,6 +133,12 @@ void ObjStartStrPool (void);
void ObjEndStrPool (void);
/* Mark the end of the string pool section */
void ObjStartAssertions (void);
/* Mark the start of the assertion table */
void ObjEndAssertions (void);
/* Mark the end of the assertion table */
/* End of objfile.h */

View File

@ -56,15 +56,17 @@
#include "global.h"
#include "incpath.h"
#include "instr.h"
#include "ldassert.h"
#include "listing.h"
#include "macpack.h"
#include "macro.h"
#include "nexttok.h"
#include "objcode.h"
#include "options.h"
#include "repeat.h"
#include "symtab.h"
#include "pseudo.h"
#include "repeat.h"
#include "spool.h"
#include "symtab.h"
@ -326,6 +328,55 @@ static void DoASCIIZ (void)
static void DoAssert (void)
/* Add an assertion */
{
static const char* ActionTab [] = {
"WARN", "WARNING",
"ERROR"
};
int Action;
/* First we have the expression that has to evaluated */
ExprNode* Expr = Expression ();
ConsumeComma ();
/* Action follows */
if (Tok != TOK_IDENT) {
ErrorSkip (ERR_IDENT_EXPECTED);
return;
}
Action = GetSubKey (ActionTab, sizeof (ActionTab) / sizeof (ActionTab[0]));
switch (Action) {
case 0:
case 1:
/* Warning */
break;
case 2:
/* Error */
break;
default:
Error (ERR_ILLEGAL_SEG_ATTR);
}
NextTok ();
ConsumeComma ();
/* Read the message */
if (Tok != TOK_STRCON) {
ErrorSkip (ERR_STRCON_EXPECTED);
} else {
AddAssertion (Expr, Action, GetStringId (SVal));
NextTok ();
}
}
static void DoAutoImport (void)
/* Mark unresolved symbols as imported */
{
@ -1078,7 +1129,7 @@ static void DoMacPack (void)
/* Insert the package */
InsertMacPack (Package);
}
}
@ -1403,11 +1454,11 @@ enum {
};
/* Control command table */
struct CtrlDesc_ {
typedef struct CtrlDesc CtrlDesc;
struct CtrlDesc {
unsigned Flags; /* Flags for this directive */
void (*Handler) (void); /* Command handler */
};
typedef struct CtrlDesc_ CtrlDesc;
#define PSEUDO_COUNT (sizeof (CtrlCmdTab) / sizeof (CtrlCmdTab [0]))
static CtrlDesc CtrlCmdTab [] = {
@ -1416,6 +1467,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoAddr }, /* .ADDR */
{ ccNone, DoAlign },
{ ccNone, DoASCIIZ },
{ ccNone, DoAssert },
{ ccNone, DoAutoImport },
{ ccNone, DoUnexpected }, /* .BLANK */
{ ccNone, DoBss },

View File

@ -123,6 +123,7 @@ struct DotKeyword {
{ ".ALIGN", TOK_ALIGN },
{ ".AND", TOK_BAND },
{ ".ASCIIZ", TOK_ASCIIZ },
{ ".ASSERT", TOK_ASSERT },
{ ".AUTOIMPORT", TOK_AUTOIMPORT },
{ ".BITAND", TOK_AND },
{ ".BITNOT", TOK_NOT },

View File

@ -115,6 +115,7 @@ enum Token {
TOK_ADDR,
TOK_ALIGN,
TOK_ASCIIZ,
TOK_ASSERT,
TOK_AUTOIMPORT,
TOK_BLANK,
TOK_BSS,
@ -235,7 +236,7 @@ extern int ForcedEnd; /* Force end of assembly */
/*****************************************************************************/
void NewInputFile (const char* Name);
/* Open a new input file */

View File

@ -49,7 +49,7 @@
#define OBJ_VERSION 0x000A
/* Size of an object file header */
#define OBJ_HDR_SIZE 72
#define OBJ_HDR_SIZE (20*4)
/* Flag bits */
#define OBJ_FLAGS_DBGINFO 0x0001 /* File has debug info */
@ -78,6 +78,8 @@ struct ObjHeader {
unsigned long LineInfoSize; /* 32: Size of line infos */
unsigned long StrPoolOffs; /* 32: Offset to string pool */
unsigned long StrPoolSize; /* 32: Size of string pool */
unsigned long AssertOffs; /* 32: Offset to assertion table */
unsigned long AssertSize; /* 32: Size of assertion table */
};

View File

@ -287,18 +287,19 @@ static Memory* NewMemory (unsigned Name)
M = xmalloc (sizeof (Memory));
/* Initialize the fields */
M->Name = Name;
M->Next = 0;
M->FNext = 0;
M->Attr = 0;
M->Flags = 0;
M->Start = 0;
M->Size = 0;
M->FillLevel = 0;
M->FillVal = 0;
M->SegList = 0;
M->SegLast = 0;
M->F = 0;
M->Name = Name;
M->Next = 0;
M->FNext = 0;
M->Attr = 0;
M->Flags = 0;
M->Start = 0;
M->Size = 0;
M->FillLevel = 0;
M->FillVal = 0;
M->Relocatable = 0;
M->SegList = 0;
M->SegLast = 0;
M->F = 0;
/* Insert the struct into the list */
if (MemoryLast == 0) {
@ -992,7 +993,7 @@ static void ParseFormats (void)
/* Map the identifier to a token */
cfgtok_t FormatTok;
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
FormatTok = CfgTok;
FormatTok = CfgTok;
/* Skip the name and the following colon */
CfgNextTok ();
@ -1432,11 +1433,16 @@ void CfgAssignSegments (void)
Memory* M = MemoryList;
while (M) {
MemListNode* N;
/* Get the start address of this memory area */
unsigned long Addr = M->Start;
/* Remember if this is a relocatable memory area */
M->Relocatable = RelocatableBinFmt (M->F->Format);
/* Walk through the segments in this memory area */
MemListNode* N = M->SegList;
N = M->SegList;
while (N) {
/* Get the segment from the node */
@ -1444,32 +1450,35 @@ void CfgAssignSegments (void)
/* Handle ALIGN and OFFSET/START */
if (S->Flags & SF_ALIGN) {
/* Align the address */
unsigned long Val = (0x01UL << S->Align) - 1;
Addr = (Addr + Val) & ~Val;
/* Align the address */
unsigned long Val = (0x01UL << S->Align) - 1;
Addr = (Addr + Val) & ~Val;
} else if (S->Flags & (SF_OFFSET | SF_START)) {
/* Give the segment a fixed starting address */
unsigned long NewAddr = S->Addr;
if (S->Flags & SF_OFFSET) {
/* An offset was given, no address, make an address */
NewAddr += M->Start;
}
/* Give the segment a fixed starting address */
unsigned long NewAddr = S->Addr;
if (S->Flags & SF_OFFSET) {
/* An offset was given, no address, make an address */
NewAddr += M->Start;
}
if (Addr > NewAddr) {
/* Offset already too large */
if (S->Flags & SF_OFFSET) {
Error ("Offset too small in `%s', segment `%s'",
GetString (M->Name), GetString (S->Name));
} else {
Error ("Start address too low in `%s', segment `%s'",
GetString (M->Name), GetString (S->Name));
}
}
Addr = NewAddr;
/* Offset already too large */
if (S->Flags & SF_OFFSET) {
Error ("Offset too small in `%s', segment `%s'",
GetString (M->Name), GetString (S->Name));
} else {
Error ("Start address too low in `%s', segment `%s'",
GetString (M->Name), GetString (S->Name));
}
}
Addr = NewAddr;
}
/* If this is the run area, set the start address of this segment */
/* If this is the run area, set the start address of this segment
* and remember if the segment is in a relocatable file or not.
*/
if (S->Run == M) {
S->Seg->PC = Addr;
S->Seg->Relocatable = M->Relocatable;
}
/* Increment the fill level of the memory area and check for an

View File

@ -78,6 +78,7 @@ struct Memory {
unsigned long Size; /* Length of memory section */
unsigned long FillLevel; /* Actual fill level of segment */
unsigned char FillVal; /* Value used to fill rest of seg */
unsigned char Relocatable; /* Memory are is relocatable */
MemListNode* SegList; /* List of segments for this section */
MemListNode* SegLast; /* Last segment in this section */
File* F; /* File that contains the entry */

View File

@ -101,8 +101,9 @@ int IsConstExpr (ExprNode* Root)
* with no references to external symbols.
*/
{
int Const;
Export* E;
int Const;
Export* E;
Section* S;
if (EXPR_IS_LEAF (Root->Op)) {
switch (Root->Op) {
@ -111,23 +112,39 @@ int IsConstExpr (ExprNode* Root)
return 1;
case EXPR_SYMBOL:
/* Get the referenced export */
/* 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)) {
/* 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
* not relocatable.
*/
S = GetExprSection (Root);
return !S->Seg->Relocatable;
case EXPR_SEGMENT:
/* A segment is const if it is not relocatable */
return !Root->V.Seg->Relocatable;
case EXPR_MEMAREA:
/* A memory area is const if it is not relocatable */
return !Root->V.Mem->Relocatable;
default:
/* Anything else is not const */
return 0;
}
@ -213,7 +230,7 @@ Section* GetExprSection (ExprNode* Expr)
*/
if (Expr->Obj) {
/* Return the export */
return Expr->Obj->Sections [Expr->V.SegNum];
return Expr->Obj->Sections[Expr->V.SegNum];
} else {
return Expr->V.Sec;
}
@ -231,47 +248,47 @@ long GetExprVal (ExprNode* Expr)
switch (Expr->Op) {
case EXPR_LITERAL:
return Expr->V.Val;
return Expr->V.Val;
case EXPR_SYMBOL:
/* Get the referenced export */
/* 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;
/* 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;
return S->Offs + S->Seg->PC;
case EXPR_SEGMENT:
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);
return GetExprVal (Expr->Left) + GetExprVal (Expr->Right);
case EXPR_MINUS:
return GetExprVal (Expr->Left) - GetExprVal (Expr->Right);
return GetExprVal (Expr->Left) - GetExprVal (Expr->Right);
case EXPR_MUL:
return GetExprVal (Expr->Left) * GetExprVal (Expr->Right);
return GetExprVal (Expr->Left) * GetExprVal (Expr->Right);
case EXPR_DIV:
Left = GetExprVal (Expr->Left);
Right = GetExprVal (Expr->Right);
Left = GetExprVal (Expr->Left);
Right = GetExprVal (Expr->Right);
if (Right == 0) {
Error ("Division by zero");
}

View File

@ -60,14 +60,14 @@ static FileInfo* NewFileInfo (void)
FileInfo* ReadFileInfo (FILE* F, ObjData* O attribute ((unused)))
FileInfo* ReadFileInfo (FILE* F, ObjData* O)
/* Read a file info from a file and return it */
{
/* Allocate a new FileInfo structure */
FileInfo* FI = NewFileInfo ();
/* Read the fields from the file */
FI->Name = ReadVar (F);
FI->Name = MakeGlobalStringId (O, ReadVar (F));
FI->MTime = Read32 (F);
FI->Size = Read32 (F);

View File

@ -34,6 +34,7 @@
#include <string.h>
#include <errno.h>
/* common */
#include "xmalloc.h"
@ -51,6 +52,28 @@
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));
}
}
unsigned long FileGetPos (FILE* F)
/* Return the current file position, fail on errors */
{
long Pos = ftell (F);
if (Pos < 0) {
Error ("Error in ftell: %s", strerror (errno));
}
return Pos;
}
void Write8 (FILE* F, unsigned Val)
/* Write an 8 bit value to the file */
{

View File

@ -51,6 +51,12 @@
void FileSetPos (FILE* F, unsigned long Pos);
/* Seek to the given absolute position, fail on errors */
unsigned long FileGetPos (FILE* F);
/* Return the current file position, fail on errors */
void Write8 (FILE* F, unsigned Val);
/* Write an 8 bit value to the file */

View File

@ -105,6 +105,8 @@ static void LibReadObjHeader (ObjData* O, const char* LibName)
O->Header.LineInfoSize = Read32 (Lib);
O->Header.StrPoolOffs = Read32 (Lib);
O->Header.StrPoolSize = Read32 (Lib);
O->Header.AssertOffs = Read32 (Lib);
O->Header.AssertSize = Read32 (Lib);
}
@ -112,8 +114,6 @@ static void LibReadObjHeader (ObjData* O, const char* LibName)
static ObjData* ReadIndexEntry (void)
/* Read one entry in the index */
{
unsigned I;
/* Create a new entry and insert it into the list */
ObjData* O = NewObjData ();
@ -127,23 +127,15 @@ static ObjData* ReadIndexEntry (void)
Read32 (Lib); /* Skip Size */
/* Read the string pool */
ObjReadStrPool (Lib, O);
ObjReadStrPool (Lib, FileGetPos (Lib), O);
/* Skip the export size, then read the exports */
(void) ReadVar (Lib);
O->ExportCount = ReadVar (Lib);
O->Exports = xmalloc (O->ExportCount * sizeof (Export*));
for (I = 0; I < O->ExportCount; ++I) {
O->Exports[I] = ReadExport (Lib, O);
}
ObjReadExports (Lib, FileGetPos (Lib), O);
/* Skip the import size, then read the imports */
(void) ReadVar (Lib);
O->ImportCount = ReadVar (Lib);
O->Imports = xmalloc (O->ImportCount * sizeof (Import*));
for (I = 0; I < O->ImportCount; ++I) {
O->Imports[I] = ReadImport (Lib, O);
}
ObjReadImports (Lib, FileGetPos (Lib), O);
/* Done */
return O;
@ -158,7 +150,7 @@ static void ReadIndex (void)
/* Read the object file count and allocate memory */
ModuleCount = ReadVar (Lib);
Index = xmalloc (ModuleCount * sizeof (ObjData*));
Index = xmalloc (ModuleCount * sizeof (Index[0]));
/* Read all entries in the index */
for (I = 0; I < ModuleCount; ++I) {
@ -192,14 +184,7 @@ static void LibCheckExports (ObjData* O)
/* If we need this module, insert the imports and exports */
if (O->Flags & OBJ_REF) {
/* Insert the exports */
for (I = 0; I < O->ExportCount; ++I) {
InsertExport (O->Exports[I]);
}
/* Insert the imports */
for (I = 0; I < O->ImportCount; ++I) {
InsertImport (O->Imports[I]);
}
InsertObjGlobals (O);
}
}
@ -265,23 +250,22 @@ void LibAdd (FILE* F, const char* Name)
LibReadObjHeader (O, Name);
/* Seek to the start of the files list and read the files list */
fseek (Lib, O->Start + O->Header.FileOffs, SEEK_SET);
ObjReadFiles (Lib, O);
ObjReadFiles (Lib, O->Start + O->Header.FileOffs, O);
/* Seek to the start of the debug info and read the debug info */
fseek (Lib, O->Start + O->Header.DbgSymOffs, SEEK_SET);
ObjReadDbgSyms (Lib, O);
ObjReadDbgSyms (Lib, O->Start + O->Header.DbgSymOffs, O);
/* Seek to the start of the line infos and read them */
fseek (Lib, O->Start + O->Header.LineInfoOffs, SEEK_SET);
ObjReadLineInfos (Lib, O);
ObjReadLineInfos (Lib, O->Start + O->Header.LineInfoOffs, O);
/* Read the assertions from the object file */
ObjReadAssertions (Lib, O->Start + O->Header.AssertOffs, O);
/* Seek to the start of the segment list and read the segments.
* This must be last, since the data here may reference other
* stuff.
*/
fseek (Lib, O->Start + O->Header.SegOffs, SEEK_SET);
ObjReadSections (Lib, O);
ObjReadSections (Lib, O->Start + O->Header.SegOffs, O);
/* Add a pointer to the library name */
O->LibName = LibName;

View File

@ -49,6 +49,7 @@
#include "xmalloc.h"
/* ld65 */
#include "asserts.h"
#include "binfmt.h"
#include "condes.h"
#include "config.h"
@ -509,6 +510,9 @@ int main (int argc, char* argv [])
/* Assign start addresses for the segments, define linker symbols */
CfgAssignSegments ();
/* Check module assertions */
CheckAssertions ();
/* Create the output file */
CfgWriteTarget ();

View File

@ -18,7 +18,8 @@ CVT=cfg/cvt-cfg.pl
# -----------------------------------------------------------------------------
# List of all object files
OBJS = bin.o \
OBJS = asserts.o \
bin.o \
binfmt.o \
condes.o \
config.o \

View File

@ -43,7 +43,8 @@ CFLAGS += -i=..\common
# ------------------------------------------------------------------------------
# All OBJ files
OBJS = bin.obj \
OBJS = asserts.obj \
bin.obj \
binfmt.obj \
condes.obj \
config.obj \

View File

@ -88,6 +88,8 @@ ObjData* NewObjData (void)
O->LineInfos = 0;
O->StringCount = 0;
O->Strings = 0;
O->AssertionCount = 0;
O->Assertions = 0;
/* Return the new entry */
return O;
@ -135,6 +137,24 @@ void InsertObjData (ObjData* O)
void InsertObjGlobals (ObjData* O)
/* Insert imports and exports from the object file into the global import and
* export lists.
*/
{
unsigned I;
/* Insert exports and imports */
for (I = 0; I < O->ExportCount; ++I) {
InsertExport (O->Exports[I]);
}
for (I = 0; I < O->ImportCount; ++I) {
InsertImport (O->Imports[I]);
}
}
unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
/* Convert a local string id into a global one and return it. */
{

View File

@ -66,17 +66,19 @@ struct ObjData {
unsigned FileCount; /* Input file count */
struct FileInfo** Files; /* List of input files */
unsigned SectionCount; /* Count of sections in this object */
struct Section** Sections; /* List of all sections */
struct Section** Sections; /* List of all sections */
unsigned ExportCount; /* Count of exports */
struct Export** Exports; /* List of all exports */
unsigned ImportCount; /* Count of imports */
struct Import** Imports; /* List of all imports */
struct Import** Imports; /* List of all imports */
unsigned DbgSymCount; /* Count of debug symbols */
struct DbgSym** DbgSyms; /* List of debug symbols */
unsigned LineInfoCount; /* Count of additional line infos */
struct LineInfo** LineInfos; /* List of additional line infos */
unsigned StringCount; /* Count of strings */
unsigned* Strings; /* List of global string indices */
unsigned AssertionCount; /* Count of module assertions */
struct Assertion** Assertions; /* List of module assertions */
};
@ -109,6 +111,11 @@ void FreeObjStrings (ObjData* O);
void InsertObjData (ObjData* O);
/* Insert the ObjData object into the collection of used ObjData objects. */
void InsertObjGlobals (ObjData* O);
/* Insert imports and exports from the object file into the global import and
* export lists.
*/
unsigned MakeGlobalStringId (const ObjData* O, unsigned Index);
/* Convert a local string id into a global one and return it. */

View File

@ -44,6 +44,7 @@
#include "xmalloc.h"
/* ld65 */
#include "asserts.h"
#include "dbgsyms.h"
#include "error.h"
#include "exports.h"
@ -101,15 +102,21 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
H->LineInfoSize = Read32 (Obj);
H->StrPoolOffs = Read32 (Obj);
H->StrPoolSize = Read32 (Obj);
H->AssertOffs = Read32 (Obj);
H->AssertSize = Read32 (Obj);
}
void ObjReadFiles (FILE* F, ObjData* O)
/* Read the files list from a file at the current position */
void ObjReadFiles (FILE* F, unsigned long Pos, ObjData* O)
/* Read the files list from a file at the given position */
{
unsigned I;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
O->FileCount = ReadVar (F);
O->Files = xmalloc (O->FileCount * sizeof (O->Files[0]));
for (I = 0; I < O->FileCount; ++I) {
@ -119,41 +126,69 @@ void ObjReadFiles (FILE* F, ObjData* O)
void ObjReadImports (FILE* F, ObjData* O)
/* Read the imports from a file at the current position */
void ObjReadSections (FILE* F, unsigned long Pos, ObjData* O)
/* Read the section data from a file at the given position */
{
unsigned I;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
O->SectionCount = ReadVar (F);
O->Sections = xmalloc (O->SectionCount * sizeof (O->Sections[0]));
for (I = 0; I < O->SectionCount; ++I) {
O->Sections [I] = ReadSection (F, O);
}
}
void ObjReadImports (FILE* F, unsigned long Pos, ObjData* O)
/* Read the imports from a file at the given position */
{
unsigned I;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
O->ImportCount = ReadVar (F);
O->Imports = xmalloc (O->ImportCount * sizeof (O->Imports[0]));
for (I = 0; I < O->ImportCount; ++I) {
O->Imports [I] = ReadImport (F, O);
InsertImport (O->Imports [I]);
}
}
void ObjReadExports (FILE* F, ObjData* O)
/* Read the exports from a file at the current position */
void ObjReadExports (FILE* F, unsigned long Pos, ObjData* O)
/* Read the exports from a file at the given position */
{
unsigned I;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
O->ExportCount = ReadVar (F);
O->Exports = xmalloc (O->ExportCount * sizeof (O->Exports[0]));
for (I = 0; I < O->ExportCount; ++I) {
O->Exports [I] = ReadExport (F, O);
InsertExport (O->Exports [I]);
}
}
void ObjReadDbgSyms (FILE* F, ObjData* O)
/* Read the debug symbols from a file at the current position */
void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O)
/* Read the debug symbols from a file at the given position */
{
unsigned I;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
O->DbgSymCount = ReadVar (F);
O->DbgSyms = xmalloc (O->DbgSymCount * sizeof (O->DbgSyms[0]));
for (I = 0; I < O->DbgSymCount; ++I) {
@ -163,11 +198,15 @@ void ObjReadDbgSyms (FILE* F, ObjData* O)
void ObjReadLineInfos (FILE* F, ObjData* O)
/* Read the line infos from a file at the current position */
void ObjReadLineInfos (FILE* F, unsigned long Pos, ObjData* O)
/* Read the line infos from a file at the given position */
{
unsigned I;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
O->LineInfoCount = ReadVar (F);
O->LineInfos = xmalloc (O->LineInfoCount * sizeof (O->LineInfos[0]));
for (I = 0; I < O->LineInfoCount; ++I) {
@ -177,11 +216,15 @@ void ObjReadLineInfos (FILE* F, ObjData* O)
void ObjReadStrPool (FILE* F, ObjData* O)
/* Read the string pool from a file at the current position */
void ObjReadStrPool (FILE* F, unsigned long Pos, ObjData* O)
/* Read the string pool from a file at the given position */
{
unsigned I;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
O->StringCount = ReadVar (F);
O->Strings = xmalloc (O->StringCount * sizeof (O->Strings[0]));
for (I = 0; I < O->StringCount; ++I) {
@ -191,15 +234,19 @@ void ObjReadStrPool (FILE* F, ObjData* O)
void ObjReadSections (FILE* F, ObjData* O)
/* Read the section data from a file at the current position */
void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O)
/* Read the assertions from a file at the given offset */
{
unsigned I;
O->SectionCount = ReadVar (F);
O->Sections = xmalloc (O->SectionCount * sizeof (O->Sections[0]));
for (I = 0; I < O->SectionCount; ++I) {
O->Sections [I] = ReadSection (F, O);
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
O->AssertionCount = ReadVar (F);
O->Assertions = xmalloc (O->AssertionCount * sizeof (O->Assertions[0]));
for (I = 0; I < O->AssertionCount; ++I) {
O->Assertions[I] = ReadAssertion (F, O);
}
}
@ -221,35 +268,31 @@ void ObjAdd (FILE* Obj, const char* Name)
O->Name = GetModule (Name);
/* Read the string pool from the object file */
fseek (Obj, O->Header.StrPoolOffs, SEEK_SET);
ObjReadStrPool (Obj, O);
ObjReadStrPool (Obj, O->Header.StrPoolOffs, O);
/* Read the files list from the object file */
fseek (Obj, O->Header.FileOffs, SEEK_SET);
ObjReadFiles (Obj, O);
ObjReadFiles (Obj, O->Header.FileOffs, O);
/* Read the imports list from the object file */
fseek (Obj, O->Header.ImportOffs, SEEK_SET);
ObjReadImports (Obj, O);
ObjReadImports (Obj, O->Header.ImportOffs, O);
/* Read the object file exports and insert them into the exports list */
fseek (Obj, O->Header.ExportOffs, SEEK_SET);
ObjReadExports (Obj, O);
ObjReadExports (Obj, O->Header.ExportOffs, O);
/* Read the object debug symbols from the object file */
fseek (Obj, O->Header.DbgSymOffs, SEEK_SET);
ObjReadDbgSyms (Obj, O);
ObjReadDbgSyms (Obj, O->Header.DbgSymOffs, O);
/* Read the line infos from the object file */
fseek (Obj, O->Header.LineInfoOffs, SEEK_SET);
ObjReadLineInfos (Obj, O);
ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O);
/* Read the assertions from the object file */
ObjReadAssertions (Obj, O->Header.AssertOffs, O);
/* Read the segment list from the object file. This must be last, since
* the expressions stored in the code may reference segments or imported
* symbols.
*/
fseek (Obj, O->Header.SegOffs, SEEK_SET);
ObjReadSections (Obj, O);
ObjReadSections (Obj, O->Header.SegOffs, O);
/* Mark this object file as needed */
O->Flags |= OBJ_REF;
@ -257,13 +300,16 @@ void ObjAdd (FILE* Obj, const char* Name)
/* Done, close the file (we read it only, so no error check) */
fclose (Obj);
/* Insert the imports and exports to the global lists */
InsertObjGlobals (O);
/* Insert the object into the list of all used object files */
InsertObjData (O);
/* All references to strings are now resolved, so we can delete the module
* string pool.
*/
FreeObjStrings (O);
/* Insert the object into the list of all used object files */
InsertObjData (O);
}

View File

@ -54,26 +54,29 @@
void ObjReadFiles (FILE* F, ObjData* O);
/* Read the files list from a file at the current position */
void ObjReadFiles (FILE* F, unsigned long Pos, ObjData* O);
/* Read the files list from a file at the given position */
void ObjReadImports (FILE* F, ObjData* O);
/* Read the imports from a file at the current position */
void ObjReadSections (FILE* F, unsigned long Pos, ObjData* O);
/* Read the section data from a file at the given position */
void ObjReadExports (FILE* F, ObjData* O);
/* Read the exports from a file at the current position */
void ObjReadImports (FILE* F, unsigned long Pos, ObjData* O);
/* Read the imports from a file at the given position */
void ObjReadDbgSyms (FILE* F, ObjData* O);
/* Read the debug symbols from a file at the current position */
void ObjReadExports (FILE* F, unsigned long Pos, ObjData* O);
/* Read the exports from a file at the given position */
void ObjReadLineInfos (FILE* F, ObjData* O);
/* Read the line infos from a file at the current position */
void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O);
/* Read the debug symbols from a file at the given position */
void ObjReadStrPool (FILE* F, ObjData* O);
/* Read the string pool from a file at the current position */
void ObjReadLineInfos (FILE* F, unsigned long Pos, ObjData* O);
/* Read the line infos from a file at the given position */
void ObjReadSections (FILE* F, ObjData* O);
/* Read the section data from a file at the current position */
void ObjReadStrPool (FILE* F, unsigned long Pos, ObjData* O);
/* Read the string pool from a file at the given position */
void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O);
/* Read the assertions from a file at the given offset */
void ObjAdd (FILE* F, const char* Name);
/* Add an object file to the module list */

View File

@ -89,17 +89,18 @@ static Segment* NewSegment (unsigned Name, unsigned char Type)
Segment* S = xmalloc (sizeof (Segment));
/* Initialize the fields */
S->Name = Name;
S->Next = 0;
S->SecRoot = 0;
S->SecLast = 0;
S->PC = 0;
S->Size = 0;
S->AlignObj = 0;
S->Align = 0;
S->FillVal = 0;
S->Type = Type;
S->Dumped = 0;
S->Name = Name;
S->Next = 0;
S->SecRoot = 0;
S->SecLast = 0;
S->PC = 0;
S->Size = 0;
S->AlignObj = 0;
S->Align = 0;
S->FillVal = 0;
S->Type = Type;
S->Relocatable = 0;
S->Dumped = 0;
/* Insert the segment into the segment list */
S->List = SegRoot;

View File

@ -65,7 +65,8 @@ struct Segment {
unsigned char Align; /* Alignment needed */
unsigned char FillVal; /* Value to use for fill bytes */
unsigned char Type; /* Type of segment */
char Dumped; /* Did we dump this segment? */
unsigned char Relocatable; /* True if the segment is relocatable */
unsigned char Dumped; /* Did we dump this segment? */
};
@ -156,5 +157,5 @@ void CheckSegments (void);
#endif

View File

@ -225,6 +225,8 @@ void ReadObjHeader (FILE* F, ObjHeader* H)
H->LineInfoSize = Read32 (F);
H->StrPoolOffs = Read32 (F);
H->StrPoolSize = Read32 (F);
H->AssertOffs = Read32 (F);
H->AssertSize = Read32 (F);
}