/* */
/* */
/* */
-/* (C) 2005-2010, Ullrich von Bassewitz */
+/* (C) 2005-2011, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
} 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 */
static void FreeSegDesc (SegDesc* S)
/* Free a segment descriptor */
-{
+{
FreeLineInfo (S->LI);
xfree (S);
}
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:
/* 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:
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;
/* 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);
/* 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);
/* 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);
}
/* 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);
}
{
/* 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 */
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 ();
}
/* 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.
*/
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 */
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;
}
/* 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;
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.
/* 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;
/* 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);
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) {
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;
}
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;
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);
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;
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;
}
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 */
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 */
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;
+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 */
/* 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) {
*/
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 */
* 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 */
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 */