H->LineInfoSize = Read32 (Obj);
H->StrPoolOffs = Read32 (Obj);
H->StrPoolSize = Read32 (Obj);
+ H->AssertOffs = Read32 (Obj);
+ H->AssertSize = Read32 (Obj);
}
Write32 (Obj, H->LineInfoSize);
Write32 (Obj, H->StrPoolOffs);
Write32 (Obj, H->StrPoolSize);
+ Write32 (Obj, H->AssertOffs);
+ Write32 (Obj, H->AssertSize);
}
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 */
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;
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 */
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 */
"Illegal macro package name",
"Illegal emulation feature",
"Illegal scope specifier",
+ "Illegal assert action",
"Syntax error",
"Symbol `%s' is already defined",
"Undefined symbol `%s'",
ERR_ILLEGAL_MACPACK,
ERR_ILLEGAL_FEATURE,
ERR_ILLEGAL_SCOPE,
+ ERR_ILLEGAL_ASSERT_ACTION,
ERR_SYNTAX,
ERR_SYM_ALREADY_DEFINED,
ERR_SYM_UNDEFINED,
#include "incpath.h"
#include "instr.h"
#include "istack.h"
+#include "ldassert.h"
#include "lineinfo.h"
#include "listing.h"
#include "macro.h"
/* Write the string pool */
WriteStrPool ();
+ /* Write the assertions */
+ WriteAssertions ();
+
/* Write an updated header and close the file */
ObjClose ();
}
incpath.o \
instr.o \
istack.o \
+ ldassert.o \
lineinfo.o \
listing.o \
macpack.o \
incpath.obj \
instr.obj \
istack.obj \
+ ldassert.obj \
lineinfo.obj \
listing.obj \
macpack.obj \
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 */
};
ObjWrite32 (Header.LineInfoSize);
ObjWrite32 (Header.StrPoolOffs);
ObjWrite32 (Header.StrPoolSize);
+ ObjWrite32 (Header.AssertOffs);
+ ObjWrite32 (Header.AssertSize);
}
+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;
+}
+
+
+
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 */
#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 "pseudo.h"
#include "repeat.h"
+#include "spool.h"
#include "symtab.h"
-#include "pseudo.h"
+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 */
{
/* Insert the package */
InsertMacPack (Package);
-}
+}
};
/* 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 [] = {
{ ccNone, DoAddr }, /* .ADDR */
{ ccNone, DoAlign },
{ ccNone, DoASCIIZ },
+ { ccNone, DoAssert },
{ ccNone, DoAutoImport },
{ ccNone, DoUnexpected }, /* .BLANK */
{ ccNone, DoBss },
{ ".ALIGN", TOK_ALIGN },
{ ".AND", TOK_BAND },
{ ".ASCIIZ", TOK_ASCIIZ },
+ { ".ASSERT", TOK_ASSERT },
{ ".AUTOIMPORT", TOK_AUTOIMPORT },
{ ".BITAND", TOK_AND },
{ ".BITNOT", TOK_NOT },
TOK_ADDR,
TOK_ALIGN,
TOK_ASCIIZ,
+ TOK_ASSERT,
TOK_AUTOIMPORT,
TOK_BLANK,
TOK_BSS,
/*****************************************************************************/
-
+
void NewInputFile (const char* Name);
/* Open a new input file */
#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 */
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 */
};
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) {
/* 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 ();
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 */
/* 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
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 */
* 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) {
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;
}
*/
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;
}
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");
}
-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);
#include <string.h>
+#include <errno.h>
/* common */
#include "xmalloc.h"
+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 */
{
+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 */
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);
}
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 ();
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;
/* 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) {
/* 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);
}
}
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;
#include "xmalloc.h"
/* ld65 */
+#include "asserts.h"
#include "binfmt.h"
#include "condes.h"
#include "config.h"
/* Assign start addresses for the segments, define linker symbols */
CfgAssignSegments ();
+ /* Check module assertions */
+ CheckAssertions ();
+
/* Create the output file */
CfgWriteTarget ();
# -----------------------------------------------------------------------------
# List of all object files
-OBJS = bin.o \
+OBJS = asserts.o \
+ bin.o \
binfmt.o \
condes.o \
config.o \
# ------------------------------------------------------------------------------
# All OBJ files
-OBJS = bin.obj \
+OBJS = asserts.obj \
+ bin.obj \
binfmt.obj \
condes.obj \
config.obj \
O->LineInfos = 0;
O->StringCount = 0;
O->Strings = 0;
+ O->AssertionCount = 0;
+ O->Assertions = 0;
/* Return the new entry */
return 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. */
{
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 */
};
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. */
#include "xmalloc.h"
/* ld65 */
+#include "asserts.h"
#include "dbgsyms.h"
#include "error.h"
#include "exports.h"
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) {
-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) {
-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) {
-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) {
-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);
}
}
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;
/* 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);
}
-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 */
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;
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? */
};
#endif
-
+
H->LineInfoSize = Read32 (F);
H->StrPoolOffs = Read32 (F);
H->StrPoolSize = Read32 (F);
+ H->AssertOffs = Read32 (F);
+ H->AssertSize = Read32 (F);
}