From: uz Date: Fri, 30 Jul 2010 22:44:09 +0000 (+0000) Subject: Handle file position information for fragments differently: Instead of X-Git-Tag: V2.13.3~677 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=23b867b7a4ee466062e4e6538d3f2de6c83d2ac4;p=cc65 Handle file position information for fragments differently: Instead of handling them separately (which has historic reasons), generate real line info information. This means that line info for the assembler source will be part of the debug info file. git-svn-id: svn://svn.cc65.org/cc65/trunk@4774 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/ld65/fragment.c b/src/ld65/fragment.c index 3f543b33d..c3f902c75 100644 --- a/src/ld65/fragment.c +++ b/src/ld65/fragment.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2010, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -40,6 +40,8 @@ /* ld65 */ #include "error.h" #include "fragment.h" +#include "lineinfo.h" +#include "objdata.h" #include "segments.h" @@ -71,8 +73,7 @@ Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S) F->Obj = 0; F->Size = Size; F->Expr = 0; - InitFilePos (&F->Pos); - F->LI = 0; + F->LineInfos = EmptyCollection; F->Type = Type; /* Insert the code fragment into the section */ @@ -96,3 +97,39 @@ Fragment* NewFragment (unsigned char Type, unsigned Size, Section* S) +void AddLineInfo (Fragment* F, LineInfo* LI) +/* Add the line info to the given fragment */ +{ + /* Point from the fragment to the line info ... */ + CollAppend (&F->LineInfos, LI); + + /* ... and back from the line info to the fragment */ + CollAppend (&LI->Fragments, F); +} + + + +const char* GetFragmentSourceName (const Fragment* F) +/* Return the name of the source file for this fragment */ +{ + /* Each fragment has the basic info in line info #0 */ + const LineInfo* LI = CollConstAt (&F->LineInfos, 0); + + /* Return the source file name */ + return GetSourceFileName (F->Obj, LI->Pos.Name); +} + + + +unsigned long GetFragmentSourceLine (const Fragment* F) +/* Return the source file line for this fragment */ +{ + /* Each fragment has the basic info in line info #0 */ + const LineInfo* LI = CollConstAt (&F->LineInfos, 0); + + /* Return the source file line */ + return LI->Pos.Line; +} + + + diff --git a/src/ld65/fragment.h b/src/ld65/fragment.h index d6a6233cb..94e40656b 100644 --- a/src/ld65/fragment.h +++ b/src/ld65/fragment.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2010, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -39,6 +39,7 @@ /* common */ +#include "coll.h" #include "filepos.h" @@ -68,8 +69,7 @@ struct Fragment { struct ObjData* Obj; /* Source of fragment */ unsigned Size; /* Size of data/expression */ struct ExprNode* Expr; /* Expression if FRAG_EXPR */ - FilePos Pos; /* File position in source */ - struct LineInfo* LI; /* Additional line info */ + Collection LineInfos; /* Line info for this fragment */ unsigned char Type; /* Type of fragment */ unsigned char LitBuf [1]; /* Dynamically alloc'ed literal buffer */ }; @@ -85,6 +85,15 @@ struct Fragment { 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 */ + +const char* GetFragmentSourceName (const Fragment* F); +/* Return the name of the source file for this fragment */ + +unsigned long GetFragmentSourceLine (const Fragment* F); +/* Return the source file line for this fragment */ + /* End of fragment.h */ diff --git a/src/ld65/lineinfo.c b/src/ld65/lineinfo.c index 2db205782..2cc4d86ac 100644 --- a/src/ld65/lineinfo.c +++ b/src/ld65/lineinfo.c @@ -40,6 +40,7 @@ /* ld65 */ #include "fileio.h" #include "fragment.h" +#include "objdata.h" #include "segments.h" #include "lineinfo.h" @@ -67,15 +68,18 @@ static CodeRange* NewCodeRange (unsigned long Offs, unsigned long Size) -static LineInfo* NewLineInfo (void) +LineInfo* NewLineInfo (ObjData* O, const FilePos* Pos) /* Create and return a new LineInfo struct */ { /* Allocate memory */ LineInfo* LI = xmalloc (sizeof (LineInfo)); + /* Make sure the name index is valid */ + CHECK (Pos->Name < CollCount (&O->Files)); + /* Initialize the fields */ - LI->File = 0; - InitFilePos (&LI->Pos); + LI->File = CollAt (&O->Files, Pos->Name); + LI->Pos = *Pos; InitCollection (&LI->Fragments); InitCollection (&LI->CodeRanges); @@ -88,18 +92,12 @@ static LineInfo* NewLineInfo (void) LineInfo* ReadLineInfo (FILE* F, ObjData* O) /* Read a line info from a file and return it */ { - /* Allocate a new LineInfo struct and initialize it */ - LineInfo* LI = NewLineInfo (); - /* Read the file position */ - ReadFilePos (F, &LI->Pos); - - /* Resolve the file index to a pointer to FileInfo struct */ - CHECK (LI->Pos.Name < CollCount (&O->Files)); - LI->File = CollAt (&O->Files, LI->Pos.Name); + FilePos Pos; + ReadFilePos (F, &Pos); - /* Return the new LineInfo */ - return LI; + /* Allocate a new LineInfo struct, initialize and return it */ + return NewLineInfo (O, &Pos); } @@ -168,11 +166,11 @@ void RelocLineInfo (Segment* S) Frag = Sec->FragRoot; while (Frag) { - /* Add the range for this fragment to the line info if there - * is any - */ - if (Frag->LI) { - AddCodeRange (Frag->LI, Offs, Frag->Size); + unsigned I; + + /* Add the range for this fragment to all line infos */ + for (I = 0; I < CollCount (&Frag->LineInfos); ++I) { + AddCodeRange (CollAt (&Frag->LineInfos, I), Offs, Frag->Size); } /* Update the offset */ diff --git a/src/ld65/lineinfo.h b/src/ld65/lineinfo.h index 6d02504af..7ef66d6d4 100644 --- a/src/ld65/lineinfo.h +++ b/src/ld65/lineinfo.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2001 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 2001-2010, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -38,21 +38,21 @@ +#include + /* common */ #include "coll.h" #include "filepos.h" -/* ld65 */ -#include "objdata.h" - /*****************************************************************************/ -/* Forwards */ +/* Forwards */ /*****************************************************************************/ +struct ObjData; struct Segment; @@ -87,7 +87,10 @@ struct LineInfo { -LineInfo* ReadLineInfo (FILE* F, ObjData* O); +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 RelocLineInfo (struct Segment* S); diff --git a/src/ld65/objdata.c b/src/ld65/objdata.c index 3365b665f..ade6192a7 100644 --- a/src/ld65/objdata.c +++ b/src/ld65/objdata.c @@ -208,7 +208,7 @@ const char* GetSourceFileName (const ObjData* O, unsigned Index) } else { /* Get a pointer to the file info struct */ - const FileInfo* FI = CollAt (&O->Files, Index); + const FileInfo* FI = CollConstAt (&O->Files, Index); /* Return the name */ return GetString (FI->Name); diff --git a/src/ld65/segments.c b/src/ld65/segments.c index 11943dc77..ca99e4403 100644 --- a/src/ld65/segments.c +++ b/src/ld65/segments.c @@ -203,6 +203,7 @@ Section* ReadSection (FILE* F, ObjData* O) unsigned FragCount; Segment* S; Section* Sec; + LineInfo* LI; /* Read the segment data */ (void) Read32 (F); /* File size of data */ @@ -231,9 +232,11 @@ Section* ReadSection (FILE* F, ObjData* O) } /* 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 */ @@ -270,24 +273,41 @@ Section* ReadSection (FILE* F, ObjData* O) } /* Read the file position of the fragment */ - ReadFilePos (F, &Frag->Pos); + 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 the additional line info and resolve it */ LineInfoIndex = ReadVar (F); if (LineInfoIndex) { --LineInfoIndex; - if (LineInfoIndex >= CollCount (&O->LineInfos)) { + /* 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), - GetSourceFileName (O, Frag->Pos.Name), - Frag->Pos.Line, LineInfoIndex, - CollCount (&O->LineInfos)); + "info with index %u (max count %u)", + GetObjFileName (O), + GetFragmentSourceName (Frag), + GetFragmentSourceLine (Frag), + LineInfoIndex, + O->LineInfoCount); } - /* Point from the fragment to the line info... */ - Frag->LI = CollAt (&O->LineInfos, LineInfoIndex); - /* ...and back from the line info to the fragment */ - CollAppend (&Frag->LI->Fragments, Frag); + /* Add line info to the fragment */ + AddLineInfo (Frag, CollAt (&O->LineInfos, LineInfoIndex)); } /* Remember the module we had this fragment from */ @@ -499,20 +519,20 @@ void SegWrite (FILE* Tgt, Segment* S, SegWriteFunc F, void* Data) case SEG_EXPR_RANGE_ERROR: Error ("Range error in module `%s', line %lu", - GetSourceFileName (Frag->Obj, Frag->Pos.Name), - Frag->Pos.Line); + GetFragmentSourceName (Frag), + GetFragmentSourceLine (Frag)); break; case SEG_EXPR_TOO_COMPLEX: Error ("Expression too complex in module `%s', line %lu", - GetSourceFileName (Frag->Obj, Frag->Pos.Name), - Frag->Pos.Line); + GetFragmentSourceName (Frag), + GetFragmentSourceLine (Frag)); break; case SEG_EXPR_INVALID: Error ("Invalid expression in module `%s', line %lu", - GetSourceFileName (Frag->Obj, Frag->Pos.Name), - Frag->Pos.Line); + GetFragmentSourceName (Frag), + GetFragmentSourceLine (Frag)); break; default: