1
0
mirror of https://github.com/cc65/cc65.git synced 2024-09-28 10:55:43 +00:00

Read and manage additional line information for symbols.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5215 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-08-18 16:27:18 +00:00
parent f8e5463278
commit 1797235794
8 changed files with 123 additions and 44 deletions

View File

@ -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 */

View File

@ -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);
}

View File

@ -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.
*/

View File

@ -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.

View File

@ -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;
}

View File

@ -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 */

View File

@ -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) {

View File

@ -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 */