From 17972357946aa829674175d1df76b2bf2b0486e1 Mon Sep 17 00:00:00 2001 From: uz Date: Thu, 18 Aug 2011 16:27:18 +0000 Subject: [PATCH] Read and manage additional line information for symbols. git-svn-id: svn://svn.cc65.org/cc65/trunk@5215 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ld65/cfgexpr.c | 4 ++-- src/ld65/config.c | 20 +++++++++--------- src/ld65/dbgfile.c | 11 ++++++---- src/ld65/dbgsyms.c | 20 +++++++++++++++--- src/ld65/exports.c | 46 +++++++++++++++++++++------------------- src/ld65/exports.h | 6 ++++-- src/ld65/lineinfo.c | 51 +++++++++++++++++++++++++++++++++++++++++++-- src/ld65/lineinfo.h | 9 ++++++++ 8 files changed, 123 insertions(+), 44 deletions(-) diff --git a/src/ld65/cfgexpr.c b/src/ld65/cfgexpr.c index 3057e054c..17f9cb57d 100644 --- a/src/ld65/cfgexpr.c +++ b/src/ld65/cfgexpr.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2005-2010, Ullrich von Bassewitz */ +/* (C) 2005-2011, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -75,7 +75,7 @@ static ExprNode* Factor (void) } else { N = NewExprNode (0, EXPR_SYMBOL); N->V.Imp = InsertImport (GenImport (Name, ADDR_SIZE_ABS)); - CollAppend (&N->V.Imp->LineInfos, GenLineInfo (&CfgErrorPos)); + CollAppend (&N->V.Imp->RefLines, GenLineInfo (&CfgErrorPos)); } /* Skip the symbol name */ diff --git a/src/ld65/config.c b/src/ld65/config.c index f3e6bf6a1..96baf392c 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -358,7 +358,7 @@ static SegDesc* NewSegDesc (unsigned Name) static void FreeSegDesc (SegDesc* S) /* Free a segment descriptor */ -{ +{ FreeLineInfo (S->LI); xfree (S); } @@ -1418,7 +1418,7 @@ static void ParseSymbols (void) AttrCheck (AttrFlags, atType, "TYPE"); /* Create the export */ Exp = CreateExprExport (Name, Value, AddrSize); - CollAppend (&Exp->LineInfos, GenLineInfo (&CfgErrorPos)); + CollAppend (&Exp->DefLines, GenLineInfo (&CfgErrorPos)); break; case CfgSymImport: @@ -1429,7 +1429,7 @@ static void ParseSymbols (void) /* Generate the import */ Imp = InsertImport (GenImport (Name, AddrSize)); /* Remember the file position */ - CollAppend (&Imp->LineInfos, GenLineInfo (&CfgErrorPos)); + CollAppend (&Imp->DefLines, GenLineInfo (&CfgErrorPos)); break; case CfgSymWeak: @@ -1679,7 +1679,7 @@ static void ProcessSymbols (void) if ((E = FindExport (Sym->Name)) == 0 || IsUnresolvedExport (E)) { /* The symbol is undefined, generate an export */ E = CreateExprExport (Sym->Name, Sym->Value, Sym->AddrSize); - CollAppend (&E->LineInfos, Sym->LI); + CollAppend (&E->DefLines, Sym->LI); } break; @@ -1702,12 +1702,12 @@ static void CreateRunDefines (SegDesc* S, unsigned long SegAddr) /* Define the run address of the segment */ SB_Printf (&Buf, "__%s_RUN__", GetString (S->Name)); E = CreateMemoryExport (GetStrBufId (&Buf), S->Run, SegAddr - S->Run->Start); - CollAppend (&E->LineInfos, S->LI); + CollAppend (&E->DefLines, S->LI); /* Define the size of the segment */ SB_Printf (&Buf, "__%s_SIZE__", GetString (S->Name)); E = CreateConstExport (GetStrBufId (&Buf), S->Seg->Size); - CollAppend (&E->LineInfos, S->LI); + CollAppend (&E->DefLines, S->LI); S->Flags |= SF_RUN_DEF; SB_Done (&Buf); @@ -1724,7 +1724,7 @@ static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr) /* Define the load address of the segment */ SB_Printf (&Buf, "__%s_LOAD__", GetString (S->Name)); E = CreateMemoryExport (GetStrBufId (&Buf), S->Load, SegAddr - S->Load->Start); - CollAppend (&E->LineInfos, S->LI); + CollAppend (&E->DefLines, S->LI); S->Flags |= SF_LOAD_DEF; SB_Done (&Buf); @@ -1789,7 +1789,7 @@ unsigned CfgProcess (void) /* Define the start of the memory area */ SB_Printf (&Buf, "__%s_START__", GetString (M->Name)); E = CreateMemoryExport (GetStrBufId (&Buf), M, 0); - CollAppend (&E->LineInfos, M->LI); + CollAppend (&E->DefLines, M->LI); SB_Done (&Buf); } @@ -1906,12 +1906,12 @@ unsigned CfgProcess (void) /* Define the size of the memory area */ SB_Printf (&Buf, "__%s_SIZE__", GetString (M->Name)); E = CreateConstExport (GetStrBufId (&Buf), M->Size); - CollAppend (&E->LineInfos, M->LI); + CollAppend (&E->DefLines, M->LI); /* Define the fill level of the memory area */ SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name)); E = CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel); - CollAppend (&E->LineInfos, M->LI); + CollAppend (&E->DefLines, M->LI); SB_Done (&Buf); } diff --git a/src/ld65/dbgfile.c b/src/ld65/dbgfile.c index 1412d1b3f..5f56460b5 100644 --- a/src/ld65/dbgfile.c +++ b/src/ld65/dbgfile.c @@ -66,9 +66,9 @@ static void AssignIds (void) { /* Walk over all modules */ unsigned I; - unsigned SymBaseId = 0; unsigned ScopeBaseId = 0; unsigned SpanBaseId = 0; + unsigned SymBaseId = 0; for (I = 0; I < CollCount (&ObjDataList); ++I) { /* Get this module */ @@ -78,18 +78,21 @@ static void AssignIds (void) O->Id = I; /* Assign base ids */ - O->SymBaseId = SymBaseId; O->ScopeBaseId = ScopeBaseId; O->SpanBaseId = SpanBaseId; + O->SymBaseId = SymBaseId; /* Bump the base ids */ - SymBaseId += CollCount (&O->DbgSyms); ScopeBaseId += CollCount (&O->Scopes); SpanBaseId += CollCount (&O->Spans); + SymBaseId += CollCount (&O->DbgSyms); } /* Assign the ids to the file infos */ AssignFileInfoIds (); + + /* Assign the ids to line infos */ + AssignLineInfoIds (); } @@ -105,7 +108,7 @@ void CreateDbgFile (void) /* Output version information */ fprintf (F, "version\tmajor=2,minor=0\n"); - + /* Output a line with the item numbers so the debug info module is able * to preallocate the required memory. */ diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index 50c9c654c..7c018461b 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -65,7 +65,8 @@ struct DbgSym { unsigned Id; /* Id of debug symbol */ DbgSym* Next; /* Pool linear list link */ ObjData* Obj; /* Object file that exports the name */ - Collection LineInfos; /* Line infos of definition */ + Collection DefLines; /* Line infos for definition */ + Collection RefLines; /* Line infos for references */ ExprNode* Expr; /* Expression (0 if not def'd) */ unsigned Size; /* Symbol size if any */ unsigned OwnerId; /* Id of parent/owner */ @@ -99,7 +100,8 @@ static DbgSym* NewDbgSym (unsigned Id, unsigned Type, unsigned char AddrSize, D->Id = Id; D->Next = 0; D->Obj = O; - D->LineInfos = EmptyCollection; + D->DefLines = EmptyCollection; + D->RefLines = EmptyCollection; D->Expr = 0; D->Size = 0; D->OwnerId = ~0U; @@ -202,7 +204,8 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O, unsigned Id) } /* Last is the list of line infos for this symbol */ - ReadLineInfoList (F, O, &D->LineInfos); + ReadLineInfoList (F, O, &D->DefLines); + ReadLineInfoList (F, O, &D->RefLines); /* Return the new DbgSym */ return D; @@ -273,6 +276,17 @@ void PrintDbgSyms (FILE* F) fprintf (F, ",parent=%u", O->SymBaseId + S->OwnerId); } + /* Output line infos */ + if (CollCount (&S->DefLines) > 0) { + unsigned K; + const LineInfo* LI = CollConstAt (&S->DefLines, 0); + fprintf (F, ",line=%u", LI->Id); + for (K = 1; K < CollCount (&S->DefLines); ++K) { + LI = CollConstAt (&S->DefLines, K); + fprintf (F, "+%u", LI->Id); + } + } + /* If this is an import, output the id of the matching export. * If this is not an import, output its value and - if we have * it - the segment. diff --git a/src/ld65/exports.c b/src/ld65/exports.c index e1571d782..405bf5407 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -108,7 +108,8 @@ static Import* NewImport (unsigned char AddrSize, ObjData* Obj) /* Initialize the fields */ I->Next = 0; I->Obj = Obj; - I->LineInfos = EmptyCollection; + I->DefLines = EmptyCollection; + I->RefLines = EmptyCollection; I->Exp = 0; I->Name = INVALID_STRING_ID; I->Flags = 0; @@ -129,8 +130,9 @@ void FreeImport (Import* I) /* Safety */ PRECONDITION ((I->Flags & IMP_INLIST) == 0); - /* Free the line info collection */ - DoneCollection (&I->LineInfos); + /* Free the line info collections */ + DoneCollection (&I->DefLines); + DoneCollection (&I->RefLines); /* Free the struct */ xfree (I); @@ -153,7 +155,8 @@ Import* ReadImport (FILE* F, ObjData* Obj) I->Name = MakeGlobalStringId (Obj, ReadVar (F)); /* Read the line infos */ - ReadLineInfoList (F, Obj, &I->LineInfos); + ReadLineInfoList (F, Obj, &I->DefLines); + ReadLineInfoList (F, Obj, &I->RefLines); /* Check the address size */ if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) { @@ -278,18 +281,12 @@ Import* InsertImport (Import* I) const LineInfo* GetImportPos (const Import* Imp) /* Return the basic line info of an import */ { - unsigned I; - - /* Search for a line info of LI_TYPE_ASM */ - for (I = 0; I < CollCount (&Imp->LineInfos); ++I) { - const LineInfo* LI = CollConstAt (&Imp->LineInfos, I); - if (LI_GET_TYPE (LI->Type) == LI_TYPE_ASM) { - return LI; - } + /* Search in DefLines, then in RefLines */ + const LineInfo* LI = GetAsmLineInfo (&Imp->DefLines); + if (LI == 0) { + LI = GetAsmLineInfo (&Imp->RefLines); } - - /* Not found - return the one in slot zero */ - return CollConstAt (&Imp->LineInfos, 0); + return LI; } @@ -316,7 +313,8 @@ static Export* NewExport (unsigned Type, unsigned char AddrSize, E->ImpList = 0; E->Expr = 0; E->Size = 0; - E->LineInfos = EmptyCollection; + E->DefLines = EmptyCollection; + E->RefLines = EmptyCollection; E->DbgSymId = ~0U; E->Type = Type | SYM_EXPORT; E->AddrSize = AddrSize; @@ -338,7 +336,8 @@ void FreeExport (Export* E) PRECONDITION ((E->Flags & EXP_INLIST) == 0); /* Free the line infos */ - DoneCollection (&E->LineInfos); + DoneCollection (&E->DefLines); + DoneCollection (&E->RefLines); /* Free the export expression */ FreeExpr (E->Expr); @@ -402,8 +401,9 @@ Export* ReadExport (FILE* F, ObjData* O) E->Size = ReadVar (F); } - /* Last is the file position where the definition was done */ - ReadLineInfoList (F, O, &E->LineInfos); + /* Last are the locations */ + ReadLineInfoList (F, O, &E->DefLines); + ReadLineInfoList (F, O, &E->RefLines); /* Return the new export */ return E; @@ -488,8 +488,12 @@ void InsertExport (Export* E) const LineInfo* GetExportPos (const Export* E) /* Return the basic line info of an export */ { - /* Source file position is always in slot zero */ - return CollConstAt (&E->LineInfos, 0); + /* Search in DefLines, then in RefLines */ + const LineInfo* LI = GetAsmLineInfo (&E->DefLines); + if (LI == 0) { + LI = GetAsmLineInfo (&E->RefLines); + } + return LI; } diff --git a/src/ld65/exports.h b/src/ld65/exports.h index d71e5d533..973156865 100644 --- a/src/ld65/exports.h +++ b/src/ld65/exports.h @@ -64,7 +64,8 @@ typedef struct Import Import; struct Import { Import* Next; /* Single linked list */ ObjData* Obj; /* Object file that imports the name */ - Collection LineInfos; /* Line info of reference */ + Collection DefLines; /* Line infos of definition */ + Collection RefLines; /* Line infos of reference */ struct Export* Exp; /* Matching export for this import */ unsigned Name; /* Name if not in table */ unsigned short Flags; /* Generic flags */ @@ -84,7 +85,8 @@ struct Export { Import* ImpList; /* List of imports for this symbol */ ExprNode* Expr; /* Expression (0 if not def'd) */ unsigned Size; /* Size of the symbol if any */ - Collection LineInfos; /* Line info of definition */ + Collection DefLines; /* Line infos of definition */ + Collection RefLines; /* Line infos of reference */ unsigned DbgSymId; /* Id of debug symbol for this export */ unsigned short Type; /* Type of export */ unsigned short AddrSize; /* Address size of export */ diff --git a/src/ld65/lineinfo.c b/src/ld65/lineinfo.c index 1320c24ef..aa5d99741 100644 --- a/src/ld65/lineinfo.c +++ b/src/ld65/lineinfo.c @@ -61,6 +61,7 @@ static LineInfo* NewLineInfo (void) LineInfo* LI = xmalloc (sizeof (LineInfo)); /* Initialize the fields */ + LI->Id = ~0U; LI->File = 0; LI->Type = LI_MAKE_TYPE (LI_TYPE_ASM, 0); LI->Pos.Name = INVALID_STRING_ID; @@ -155,13 +156,59 @@ void ReadLineInfoList (FILE* F, ObjData* O, Collection* LineInfos) +const LineInfo* GetAsmLineInfo (const Collection* LineInfos) +/* Find a line info of type LI_TYPE_ASM in the given collection and return it. + * Return NULL if no such line info was found. + */ +{ + unsigned I; + + /* Search for a line info of LI_TYPE_ASM */ + for (I = 0; I < CollCount (LineInfos); ++I) { + const LineInfo* LI = CollConstAt (LineInfos, I); + if (LI_GET_TYPE (LI->Type) == LI_TYPE_ASM) { + return LI; + } + } + + /* Not found */ + return 0; +} + + + +void AssignLineInfoIds (void) +/* Assign the ids to the line infos */ +{ + unsigned I, J; + + /* Walk over all line infos */ + unsigned Id = 0; + for (I = 0; I < CollCount (&ObjDataList); ++I) { + + /* Get the object file */ + ObjData* O = CollAtUnchecked (&ObjDataList, I); + + /* Output the line infos */ + for (J = 0; J < CollCount (&O->LineInfos); ++J) { + + /* Get this line info */ + LineInfo* LI = CollAtUnchecked (&O->LineInfos, J); + + /* Assign the id */ + LI->Id = Id++; + } + } +} + + + void PrintDbgLineInfo (FILE* F) /* Output the line infos to a debug info file */ { unsigned I, J, K; /* Print line infos from all modules we have linked into the output file */ - unsigned Id = 0; for (I = 0; I < CollCount (&ObjDataList); ++I) { /* Get the object file */ @@ -183,7 +230,7 @@ void PrintDbgLineInfo (FILE* F) /* Print the start of the line */ fprintf (F, "line\tid=%u,file=%u,line=%lu", - Id++, LI->File->Id, GetSourceLine (LI)); + LI->Id, LI->File->Id, GetSourceLine (LI)); /* Print type if not LI_TYPE_ASM and count if not zero */ if (Type != LI_TYPE_ASM) { diff --git a/src/ld65/lineinfo.h b/src/ld65/lineinfo.h index 54e40861c..6a04a4a37 100644 --- a/src/ld65/lineinfo.h +++ b/src/ld65/lineinfo.h @@ -73,6 +73,7 @@ struct Segment; */ typedef struct LineInfo LineInfo; struct LineInfo { + unsigned Id; /* Line info id */ struct FileInfo* File; /* File struct for this line if any */ unsigned Type; /* Type of line info */ FilePos Pos; /* Position in file */ @@ -101,6 +102,11 @@ void ReadLineInfoList (FILE* F, struct ObjData* O, Collection* LineInfos); * make real line infos from them and place them into the passed collection. */ +const LineInfo* GetAsmLineInfo (const Collection* LineInfos); +/* Find a line info of type LI_TYPE_ASM in the given collection and return it. + * Return NULL if no such line info was found. + */ + #if defined(HAVE_INLINE) INLINE const FilePos* GetSourcePos (const LineInfo* LI) /* Return the source file position from the given line info */ @@ -165,6 +171,9 @@ INLINE unsigned long GetSourceLineFromList (const Collection* LineInfos) GetSourceLine ((const LineInfo*) CollConstAt ((LineInfos), 0)) #endif +void AssignLineInfoIds (void); +/* Assign the ids to the line infos */ + void PrintDbgLineInfo (FILE* F); /* Output the line infos to a debug info file */ -- 2.39.5