/* */
/* */
/* */
-/* (C) 2003-2009, Ullrich von Bassewitz */
+/* (C) 2003-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* ld65 */
#include "asserts.h"
#include "error.h"
-#include "expr.h"
+#include "expr.h"
#include "fileio.h"
+#include "lineinfo.h"
#include "objdata.h"
#include "spool.h"
/* Assertion struct decl */
struct Assertion {
- FilePos Pos; /* File position of assertion */
+ Collection LineInfos; /* File position of assertion */
ExprNode* Expr; /* Expression to evaluate */
AssertAction Action; /* What to do */
unsigned Msg; /* Message to print */
+static const char* GetAssertionSourceName (const Assertion* A)
+/* Return the name of the source file for this assertion */
+{
+ /* Each assertion has the basic info in line info #0 */
+ const LineInfo* LI = CollConstAt (&A->LineInfos, 0);
+
+ /* Return the source file name */
+ return GetSourceFileName (A->Obj, LI->Pos.Name);
+}
+
+
+
+static unsigned long GetAssertionSourceLine (const Assertion* A)
+/* Return the source file line for this fragment */
+{
+ /* Each assertion has the basic info in line info #0 */
+ const LineInfo* LI = CollConstAt (&A->LineInfos, 0);
+
+ /* Return the source file line */
+ return LI->Pos.Line;
+}
+
+
+
Assertion* ReadAssertion (FILE* F, struct ObjData* O)
/* Read an assertion from the given file */
{
A->Expr = ReadExpr (F, O);
A->Action = (AssertAction) ReadVar (F);
A->Msg = MakeGlobalStringId (O, ReadVar (F));
- ReadFilePos (F, &A->Pos);
+ ReadLineInfoList (F, O, &A->LineInfos);
/* Set remaining fields */
A->Obj = O;
/* Walk over all assertions */
for (I = 0; I < CollCount (&Assertions); ++I) {
+ const char* Module;
+ unsigned long Line;
+
/* Get the assertion */
Assertion* A = CollAtUnchecked (&Assertions, I);
continue;
}
+ /* Retrieve module name and line number */
+ Module = GetAssertionSourceName (A);
+ Line = GetAssertionSourceLine (A);
+
/* If the expression is not constant, we're not able to handle it */
if (!IsConstExpr (A->Expr)) {
Warning ("Cannot evaluate assertion in module `%s', line %lu",
- GetSourceFileName (A->Obj, A->Pos.Name), A->Pos.Line);
+ Module, Line);
} else if (GetExprVal (A->Expr) == 0) {
/* Assertion failed */
- const char* Module = GetSourceFileName (A->Obj, A->Pos.Name);
const char* Message = GetString (A->Msg);
switch (A->Action) {
case ASSERT_ACT_WARN:
case ASSERT_ACT_LDWARN:
- Warning ("%s(%lu): %s", Module, A->Pos.Line, Message);
+ Warning ("%s(%lu): %s", Module, Line, Message);
break;
case ASSERT_ACT_ERROR:
case ASSERT_ACT_LDERROR:
- Error ("%s(%lu): %s", Module, A->Pos.Line, Message);
+ Error ("%s(%lu): %s", Module, Line, Message);
break;
default:
Internal ("Invalid assertion action (%u) in module `%s', "
"line %lu (file corrupt?)",
- A->Action, Module, A->Pos.Line);
+ A->Action, Module, Line);
break;
}
}
-void AddLineInfo (Fragment* F, LineInfo* LI)
-/* Add the line info to the given fragment */
+void FragResolveLineInfos (Fragment* F)
+/* Resolve the back pointers for the line infos */
{
- /* Point from the fragment to the line info ... */
- CollAppend (&F->LineInfos, LI);
+ unsigned I;
- /* ... and back from the line info to the fragment */
- CollAppend (&LI->Fragments, F);
+ /* Walk over all line infos for this fragment */
+ for (I = 0; I < CollCount (&F->LineInfos); ++I) {
+ /* Get a pointer to this line info */
+ LineInfo* LI = CollAtUnchecked (&F->LineInfos, I);
+
+ /* Add the back pointer to the line info */
+ CollAppend (&LI->Fragments, F);
+ }
}
Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
/* Create a new fragment and insert it into the section S */
-void AddLineInfo (Fragment* F, struct LineInfo* LI);
-/* Add the line info to the given fragment */
+void FragResolveLineInfos (Fragment* F);
+/* Resolve the back pointers for the line infos */
const char* GetFragmentSourceName (const Fragment* F);
/* Return the name of the source file for this fragment */
/* */
/* */
/* */
-/* (C) 2001-2010, Ullrich von Bassewitz */
+/* (C) 2001-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-LineInfo* NewLineInfo (ObjData* O, const FilePos* Pos)
+static LineInfo* NewLineInfo (ObjData* O, const FilePos* Pos)
/* Create and return a new LineInfo struct */
{
/* Allocate memory */
+void ReadLineInfoList (FILE* F, ObjData* O, Collection* LineInfos)
+/* Read a list of line infos stored as a list of indices in the object file,
+ * make real line infos from them and place them into the passed collection.
+ */
+{
+ /* Read the number of line info indices that follow */
+ unsigned LineInfoCount = ReadVar (F);
+
+ /* Read the line infos and resolve them */
+ while (LineInfoCount--) {
+
+ /* Read an index */
+ unsigned LineInfoIndex = ReadVar (F);
+
+ /* The line info index was written by the assembler and must
+ * therefore be part of the line infos read from the object file.
+ */
+ if (LineInfoIndex >= CollCount (&O->LineInfos)) {
+ Internal ("Invalid line info index %u in module `%s'",
+ LineInfoIndex,
+ GetObjFileName (O));
+ }
+
+ /* Add the line info to the collection */
+ CollAppend (LineInfos, CollAt (&O->LineInfos, LineInfoIndex));
+ }
+}
+
+
+
static void AddCodeRange (LineInfo* LI, Segment* Seg, unsigned long Offs,
unsigned long Size)
/* Add a range of code to this line */
/* */
/* */
/* */
-/* (C) 2001-2010, Ullrich von Bassewitz */
+/* (C) 2001-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-LineInfo* NewLineInfo (struct ObjData* O, const FilePos* Pos);
-/* Create and return a new LineInfo struct */
-
LineInfo* ReadLineInfo (FILE* F, struct ObjData* O);
/* Read a line info from a file and return it */
+void ReadLineInfoList (FILE* F, struct ObjData* O, Collection* LineInfos);
+/* Read a list of line infos stored as a list of indices in the object file,
+ * make real line infos from them and place them into the passed collection.
+ */
+
void RelocLineInfo (struct Segment* S);
/* Relocate the line info for a segment. */
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
O->MTime = 0;
O->Start = 0;
O->Flags = 0;
- O->FileCount = 0;
O->Files = EmptyCollection;
- O->SectionCount = 0;
O->Sections = EmptyCollection;
- O->ExportCount = 0;
O->Exports = EmptyCollection;
- O->ImportCount = 0;
O->Imports = EmptyCollection;
- O->DbgSymCount = 0;
O->DbgSyms = EmptyCollection;
- O->LineInfoCount = 0;
O->LineInfos = EmptyCollection;
O->StringCount = 0;
O->Strings = 0;
- O->AssertionCount = 0;
O->Assertions = EmptyCollection;
- O->ScopeCount = 0;
O->Scopes = EmptyCollection;
/* Return the new entry */
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
ObjHeader Header; /* Header of file */
unsigned long Start; /* Start offset of data in library */
unsigned Flags;
- unsigned FileCount; /* Input file count */
Collection Files; /* List of input files */
- unsigned SectionCount; /* Count of sections in this object */
Collection Sections; /* List of all sections */
- unsigned ExportCount; /* Count of exports */
Collection Exports; /* List of all exports */
- unsigned ImportCount; /* Count of imports */
Collection Imports; /* List of all imports */
- unsigned DbgSymCount; /* Count of debug symbols */
Collection DbgSyms; /* List of debug symbols */
- unsigned LineInfoCount; /* Count of additional line infos */
- Collection LineInfos; /* List of additional line infos */
+ Collection LineInfos; /* List of line infos */
unsigned StringCount; /* Count of strings */
unsigned* Strings; /* List of global string indices */
- unsigned AssertionCount; /* Count of module assertions */
Collection Assertions; /* List of module assertions */
- unsigned ScopeCount; /* Count of scopes */
Collection Scopes; /* List of scopes */
};
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* Read the files list from a file at the given position */
{
unsigned I;
+ unsigned FileCount;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
- O->FileCount = ReadVar (F);
- CollGrow (&O->Files, O->FileCount);
- for (I = 0; I < O->FileCount; ++I) {
+ FileCount = ReadVar (F);
+ CollGrow (&O->Files, FileCount);
+ for (I = 0; I < FileCount; ++I) {
CollAppend (&O->Files, ReadFileInfo (F, O));
}
}
void ObjReadSections (FILE* F, unsigned long Pos, ObjData* O)
/* Read the section data from a file at the given position */
{
- unsigned I;
+ unsigned I;
+ unsigned SectionCount;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
- O->SectionCount = ReadVar (F);
- CollGrow (&O->Sections, O->SectionCount);
- for (I = 0; I < O->SectionCount; ++I) {
+ SectionCount = ReadVar (F);
+ CollGrow (&O->Sections, SectionCount);
+ for (I = 0; I < SectionCount; ++I) {
CollAppend (&O->Sections, ReadSection (F, O));
}
}
void ObjReadImports (FILE* F, unsigned long Pos, ObjData* O)
/* Read the imports from a file at the given position */
{
- unsigned I;
+ unsigned I;
+ unsigned ImportCount;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
- O->ImportCount = ReadVar (F);
- CollGrow (&O->Imports, O->ImportCount);
- for (I = 0; I < O->ImportCount; ++I) {
+ ImportCount = ReadVar (F);
+ CollGrow (&O->Imports, ImportCount);
+ for (I = 0; I < ImportCount; ++I) {
CollAppend (&O->Imports, ReadImport (F, O));
}
}
void ObjReadExports (FILE* F, unsigned long Pos, ObjData* O)
/* Read the exports from a file at the given position */
{
- unsigned I;
+ unsigned I;
+ unsigned ExportCount;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
- O->ExportCount = ReadVar (F);
- CollGrow (&O->Exports, O->ExportCount);
- for (I = 0; I < O->ExportCount; ++I) {
+ ExportCount = ReadVar (F);
+ CollGrow (&O->Exports, ExportCount);
+ for (I = 0; I < ExportCount; ++I) {
CollAppend (&O->Exports, ReadExport (F, O));
}
}
/* Read the debug symbols from a file at the given position */
{
unsigned I;
+ unsigned DbgSymCount;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
- O->DbgSymCount = ReadVar (F);
- CollGrow (&O->DbgSyms, O->DbgSymCount);
- for (I = 0; I < O->DbgSymCount; ++I) {
+ DbgSymCount = ReadVar (F);
+ CollGrow (&O->DbgSyms, DbgSymCount);
+ for (I = 0; I < DbgSymCount; ++I) {
CollAppend (&O->DbgSyms, ReadDbgSym (F, O));
}
}
/* Read the line infos from a file at the given position */
{
unsigned I;
+ unsigned LineInfoCount;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
- O->LineInfoCount = ReadVar (F);
- CollGrow (&O->LineInfos, O->LineInfoCount);
- for (I = 0; I < O->LineInfoCount; ++I) {
+ LineInfoCount = ReadVar (F);
+ CollGrow (&O->LineInfos, LineInfoCount);
+ for (I = 0; I < LineInfoCount; ++I) {
CollAppend (&O->LineInfos, ReadLineInfo (F, O));
}
}
void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O)
/* Read the assertions from a file at the given offset */
{
- unsigned I;
+ unsigned I;
+ unsigned AssertionCount;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
- O->AssertionCount = ReadVar (F);
- CollGrow (&O->Assertions, O->AssertionCount);
- for (I = 0; I < O->AssertionCount; ++I) {
+ AssertionCount = ReadVar (F);
+ CollGrow (&O->Assertions, AssertionCount);
+ for (I = 0; I < AssertionCount; ++I) {
CollAppend (&O->Assertions, ReadAssertion (F, O));
}
}
void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O)
/* Read the scope table from a file at the given offset */
{
- unsigned I;
+ unsigned I;
+ unsigned ScopeCount;
/* Seek to the correct position */
FileSetPos (F, Pos);
/* Read the data */
- O->ScopeCount = ReadVar (F);
- CollGrow (&O->Scopes, O->ScopeCount);
- for (I = 0; I < O->ScopeCount; ++I) {
+ ScopeCount = ReadVar (F);
+ CollGrow (&O->Scopes, ScopeCount);
+ for (I = 0; I < ScopeCount; ++I) {
CollAppend (&O->Scopes, 0); /* ReadScope (F, O); ### not implemented */
}
}
/* */
/* */
/* */
-/* (C) 1998-2010, Ullrich von Bassewitz */
+/* (C) 1998-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
unsigned FragCount;
Segment* S;
Section* Sec;
- LineInfo* LI;
/* Read the segment data */
(void) Read32 (F); /* File size of data */
}
/* Start reading fragments from the file and insert them into the section . */
- LI = 0;
while (FragCount--) {
Fragment* Frag;
- FilePos Pos;
- unsigned LineInfoIndex;
/* Read the fragment type */
unsigned char Type = Read8 (F);
return 0;
}
- /* Read the file position of the fragment */
- ReadFilePos (F, &Pos);
-
- /* Generate a LineInfo for this fragment. First check if this fragment
- * was generated by the same line than that before. If not, generate
- * a new LineInfo.
- */
- if (LI == 0 || LI->Pos.Line != Pos.Line || LI->Pos.Col != Pos.Col ||
- LI->Pos.Name != Pos.Name) {
- /* We don't have a previous line info or this one is different */
- LI = NewLineInfo (O, &Pos);
- CollAppend (&O->LineInfos, LI);
- }
- AddLineInfo (Frag, LI);
-
- /* Read additional line info and resolve it */
- LineInfoIndex = ReadVar (F);
- if (LineInfoIndex) {
- --LineInfoIndex;
- /* The line info index was written by the assembler and must
- * therefore be part of the line infos read from the object file.
- * To make sure this is true, don't compare against the count
- * of line infos in the collection (which grows) but against the
- * count initialized when reading from the file.
- */
- if (LineInfoIndex >= O->LineInfoCount) {
- Internal ("In module `%s', file `%s', line %lu: Invalid line "
- "info with index %u (max count %u)",
- GetObjFileName (O),
- GetFragmentSourceName (Frag),
- GetFragmentSourceLine (Frag),
- LineInfoIndex,
- O->LineInfoCount);
- }
- /* Add line info to the fragment */
- AddLineInfo (Frag, CollAt (&O->LineInfos, LineInfoIndex));
- }
+ /* Read the line infos into the list of the fragment */
+ ReadLineInfoList (F, O, &Frag->LineInfos);
+
+ /* Resolve the back pointers */
+ FragResolveLineInfos (Frag);
/* Remember the module we had this fragment from */
Frag->Obj = O;