From 3996725f44d4b0137be5f69b892d309d585e4406 Mon Sep 17 00:00:00 2001 From: uz Date: Tue, 16 Aug 2011 13:58:59 +0000 Subject: [PATCH] Write imports out to the debug info file. Add the id of the corresponding export. git-svn-id: svn://svn.cc65.org/cc65/trunk@5186 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ld65/dbgsyms.c | 153 ++++++++++++++++++++++++++++++++------------- src/ld65/dbgsyms.h | 20 +----- src/ld65/exports.c | 20 ++++-- src/ld65/exports.h | 1 + src/ld65/expr.c | 4 +- src/ld65/objdata.c | 24 +++++++ src/ld65/objdata.h | 8 +++ src/ld65/objfile.c | 4 +- 8 files changed, 165 insertions(+), 69 deletions(-) diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index 445167818..084e54592 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -44,6 +44,7 @@ /* ld65 */ #include "dbgsyms.h" #include "error.h" +#include "exports.h" #include "expr.h" #include "fileio.h" #include "global.h" @@ -59,6 +60,21 @@ +/* Definition of the debug symbol structure */ +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 */ + ExprNode* Expr; /* Expression (0 if not def'd) */ + unsigned Size; /* Symbol size if any */ + unsigned OwnerId; /* Id of parent/owner */ + unsigned ImportId; /* Id of import if this is one */ + unsigned Name; /* Name */ + unsigned short Type; /* Type of symbol */ + unsigned short AddrSize; /* Address size of symbol */ +}; + /* We will collect all debug symbols in the following array and remove * duplicates before outputing them. */ @@ -72,22 +88,25 @@ static DbgSym* DbgSymPool[256]; -static DbgSym* NewDbgSym (unsigned Type, unsigned char AddrSize, ObjData* O) +static DbgSym* NewDbgSym (unsigned Id, unsigned Type, unsigned char AddrSize, + ObjData* O) /* Create a new DbgSym and return it */ { /* Allocate memory */ - DbgSym* D = xmalloc (sizeof (DbgSym)); + DbgSym* D = xmalloc (sizeof (DbgSym)); /* Initialize the fields */ - D->Next = 0; - D->Obj = O; - D->LineInfos = EmptyCollection; - D->Expr = 0; - D->Size = 0; - D->OwnerId = ~0U; - D->Name = 0; - D->Type = Type; - D->AddrSize = AddrSize; + D->Id = Id; + D->Next = 0; + D->Obj = O; + D->LineInfos = EmptyCollection; + D->Expr = 0; + D->Size = 0; + D->OwnerId = ~0U; + D->ImportId = ~0U; + D->Name = 0; + D->Type = Type; + D->AddrSize = AddrSize; /* Return the new entry */ return D; @@ -141,7 +160,7 @@ static void InsertDbgSym (DbgSym* D, long Val) -DbgSym* ReadDbgSym (FILE* F, ObjData* O) +DbgSym* ReadDbgSym (FILE* F, ObjData* O, unsigned Id) /* Read a debug symbol from a file, insert and return it */ { /* Read the type and address size */ @@ -149,7 +168,7 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O) unsigned char AddrSize = Read8 (F); /* Create a new debug symbol */ - DbgSym* D = NewDbgSym (Type, AddrSize, O); + DbgSym* D = NewDbgSym (Id, Type, AddrSize, O); /* Read the id of the owner scope/symbol */ D->OwnerId = ReadVar (F); @@ -169,6 +188,19 @@ DbgSym* ReadDbgSym (FILE* F, ObjData* O) D->Size = ReadVar (F); } + /* If this is an import, the file contains its id */ + if (SYM_IS_IMPORT (D->Type)) { + D->ImportId = ReadVar (F); + } + + /* If its an exports, there's also the export id, but we don't remember + * it but use it to let the export point back to us. + */ + if (SYM_IS_EXPORT (D->Type)) { + /* Get the export from the export id, then set the our id */ + GetObjExport (O, ReadVar (F))->DbgSymId = Id; + } + /* Last is the list of line infos for this symbol */ ReadLineInfoList (F, O, &D->LineInfos); @@ -195,7 +227,7 @@ void ClearDbgSymTable (void) -long GetDbgSymVal (const DbgSym* D) +static long GetDbgSymVal (const DbgSym* D) /* Get the value of this symbol */ { CHECK (D->Expr != 0); @@ -203,7 +235,7 @@ long GetDbgSymVal (const DbgSym* D) } - + void PrintDbgSyms (FILE* F) /* Print the debug symbols in a debug file */ { @@ -212,40 +244,56 @@ void PrintDbgSyms (FILE* F) for (I = 0; I < CollCount (&ObjDataList); ++I) { /* Get the object file */ - const ObjData* O = CollAtUnchecked (&ObjDataList, I); + ObjData* O = CollAtUnchecked (&ObjDataList, I); /* Walk through all debug symbols in this module */ for (J = 0; J < CollCount (&O->DbgSyms); ++J) { - long Val; - SegExprDesc D; - /* Get the next debug symbol */ const DbgSym* S = CollConstAt (&O->DbgSyms, J); - /* Get the symbol value */ - Val = GetDbgSymVal (S); - /* Emit the base data for the entry */ fprintf (F, - "sym\tid=%u,name=\"%s\",val=0x%lX,addrsize=%s,type=%s", + "sym\tid=%u,name=\"%s\",addrsize=%s,type=%s", O->SymBaseId + J, GetString (S->Name), - Val, AddrSizeToStr (S->AddrSize), SYM_IS_LABEL (S->Type)? "lab" : "equ"); - /* Emit the size only if we know it */ - if (S->Size != 0) { - fprintf (F, ",size=%lu", S->Size); + /* If this is not an import, output its value and - if we have + * it - the segment. + */ + if (!SYM_IS_IMPORT (S->Type)) { + + SegExprDesc D; + + /* Get the symbol value */ + long Val = GetDbgSymVal (S); + + /* Output it */ + fprintf (F, ",val=0x%lX", Val); + + /* Check for a segmented expression and add the segment id to + * the debug info if we have one. + */ + GetSegExprVal (S->Expr, &D); + if (!D.TooComplex && D.Seg != 0) { + fprintf (F, ",seg=%u", D.Seg->Id); + } + + /* Output the type */ + fprintf (F, ",type=%s", SYM_IS_LABEL (S->Type)? "lab" : "equ"); + + } else { + + /* Output the type */ + fputs (",type=imp", F); + } - /* Check for a segmented expression and add the segment id to the - * debug info if we have one. - */ - GetSegExprVal (S->Expr, &D); - if (!D.TooComplex && D.Seg != 0) { - fprintf (F, ",seg=%u", D.Seg->Id); + /* Emit the size only if we know it */ + if (S->Size != 0) { + fprintf (F, ",size=%u", S->Size); } /* For cheap local symbols, add the owner symbol, for others, @@ -257,6 +305,23 @@ void PrintDbgSyms (FILE* F) fprintf (F, ",parent=%u", O->SymBaseId + S->OwnerId); } + /* If this is an import, output the id of the matching export */ + if (SYM_IS_IMPORT (S->Type)) { + + /* Get the import */ + const Import* Imp = GetObjImport (O, S->ImportId); + + /* Get the export from the import */ + const Export* Exp = Imp->Exp; + + /* If this is not a linker generated symbol, output the debug + * symbol id for the export + */ + if (Exp->Obj) { + fprintf (F, ",exp=%u", Exp->Obj->SymBaseId + Exp->DbgSymId); + } + } + /* Terminate the output line */ fputc ('\n', F); } @@ -278,25 +343,25 @@ void PrintDbgSymLabels (ObjData* O, FILE* F) /* Get the next debug symbol */ DbgSym* D = CollAt (&O->DbgSyms, I); - /* Emit this symbol only if it is a label (ignore equates) */ - if (SYM_IS_EQUATE (D->Type)) { + /* Emit this symbol only if it is a label (ignore equates and imports) */ + if (SYM_IS_EQUATE (D->Type) || SYM_IS_IMPORT (D->Type)) { continue; } - /* Get the symbol value */ - Val = GetDbgSymVal (D); + /* Get the symbol value */ + Val = GetDbgSymVal (D); - /* Lookup this symbol in the table. If it is found in the table, it was - * already written to the file, so don't emit it twice. If it is not in - * the table, insert and output it. - */ + /* Lookup this symbol in the table. If it is found in the table, it was + * already written to the file, so don't emit it twice. If it is not in + * the table, insert and output it. + */ if (GetDbgSym (D, Val) == 0) { - /* Emit the VICE label line */ + /* Emit the VICE label line */ fprintf (F, "al %06lX .%s\n", Val, GetString (D->Name)); - /* Insert the symbol into the table */ - InsertDbgSym (D, Val); + /* Insert the symbol into the table */ + InsertDbgSym (D, Val); } } } diff --git a/src/ld65/dbgsyms.h b/src/ld65/dbgsyms.h index 209d78f4a..fd6b9a37d 100644 --- a/src/ld65/dbgsyms.h +++ b/src/ld65/dbgsyms.h @@ -58,34 +58,20 @@ /* Forwards */ struct Scope; -/* Debug symbol structure */ +/* Opaque debug symbol structure */ typedef struct DbgSym DbgSym; -struct DbgSym { - DbgSym* Next; /* Pool linear list link */ - ObjData* Obj; /* Object file that exports the name */ - Collection LineInfos; /* Line infos of definition */ - ExprNode* Expr; /* Expression (0 if not def'd) */ - unsigned Size; /* Symbol size if any */ - unsigned OwnerId; /* Id of parent/owner */ - unsigned Name; /* Name */ - unsigned short Type; /* Type of symbol */ - unsigned short AddrSize; /* Address size of symbol */ -}; /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ -DbgSym* ReadDbgSym (FILE* F, ObjData* Obj); +DbgSym* ReadDbgSym (FILE* F, ObjData* Obj, unsigned Id); /* Read a debug symbol from a file, insert and return it */ -long GetDbgSymVal (const DbgSym* D); -/* Get the value of this symbol */ - void ClearDbgSymTable (void); /* Clear the debug symbol table. Must be called before outputting debug syms * or debug labels the first time. diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 9be4e22fb..e1571d782 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -41,6 +41,7 @@ #include "addrsize.h" #include "check.h" #include "hashfunc.h" +#include "lidefs.h" #include "symdefs.h" #include "xmalloc.h" @@ -232,7 +233,7 @@ Import* InsertImport (Import* I) if (HashTab[Hash] == 0) { /* The slot is empty, we need to insert a dummy export */ E = HashTab[Hash] = NewExport (0, ADDR_SIZE_DEFAULT, Name, 0); - ++ExpCount; + ++ExpCount; } else { E = HashTab [Hash]; while (1) { @@ -274,11 +275,21 @@ Import* InsertImport (Import* I) -const LineInfo* GetImportPos (const Import* I) +const LineInfo* GetImportPos (const Import* Imp) /* Return the basic line info of an import */ { - /* Source file position is always in slot zero */ - return CollConstAt (&I->LineInfos, 0); + 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; + } + } + + /* Not found - return the one in slot zero */ + return CollConstAt (&Imp->LineInfos, 0); } @@ -306,6 +317,7 @@ static Export* NewExport (unsigned Type, unsigned char AddrSize, E->Expr = 0; E->Size = 0; E->LineInfos = EmptyCollection; + E->DbgSymId = ~0U; E->Type = Type | SYM_EXPORT; E->AddrSize = AddrSize; memset (E->ConDes, 0, sizeof (E->ConDes)); diff --git a/src/ld65/exports.h b/src/ld65/exports.h index 535e7b24c..d71e5d533 100644 --- a/src/ld65/exports.h +++ b/src/ld65/exports.h @@ -85,6 +85,7 @@ struct Export { ExprNode* Expr; /* Expression (0 if not def'd) */ unsigned Size; /* Size of the symbol if any */ Collection LineInfos; /* Line info of definition */ + unsigned DbgSymId; /* Id of debug symbol for this export */ unsigned short Type; /* Type of export */ unsigned short AddrSize; /* Address size of export */ unsigned char ConDes[CD_TYPE_COUNT]; /* Constructor/destructor decls */ diff --git a/src/ld65/expr.c b/src/ld65/expr.c index c6d3c7ef3..d671914b7 100644 --- a/src/ld65/expr.c +++ b/src/ld65/expr.c @@ -201,8 +201,8 @@ Import* GetExprImport (ExprNode* Expr) * import pointer. */ if (Expr->Obj) { - /* Return the export */ - return CollAt (&Expr->Obj->Imports, Expr->V.ImpNum); + /* Return the Import */ + return GetObjImport (Expr->Obj, Expr->V.ImpNum); } else { return Expr->V.Imp; } diff --git a/src/ld65/objdata.c b/src/ld65/objdata.c index 21b75e1e8..b0a17d0e9 100644 --- a/src/ld65/objdata.c +++ b/src/ld65/objdata.c @@ -211,6 +211,30 @@ struct Section* GetObjSection (ObjData* O, unsigned Id) +struct Import* GetObjImport (ObjData* O, unsigned Id) +/* Get an import from an object file checking for a valid index */ +{ + if (Id >= CollCount (&O->Imports)) { + Error ("Invalid import index (%u) in module `%s'", + Id, GetObjFileName (O)); + } + return CollAtUnchecked (&O->Imports, Id); +} + + + +struct Export* GetObjExport (ObjData* O, unsigned Id) +/* Get an export from an object file checking for a valid index */ +{ + if (Id >= CollCount (&O->Exports)) { + Error ("Invalid export index (%u) in module `%s'", + Id, GetObjFileName (O)); + } + return CollAtUnchecked (&O->Exports, Id); +} + + + struct Scope* GetObjScope (ObjData* O, unsigned Id) /* Get a scope from an object file checking for a valid index */ { diff --git a/src/ld65/objdata.h b/src/ld65/objdata.h index b892f9f6e..77d75f064 100644 --- a/src/ld65/objdata.h +++ b/src/ld65/objdata.h @@ -52,6 +52,8 @@ /* Forwards */ +struct Export; +struct Import; struct Library; struct Scope; struct Section; @@ -144,6 +146,12 @@ INLINE int ObjHasFiles (const ObjData* O) struct Section* GetObjSection (ObjData* Obj, unsigned Id); /* Get a section from an object file checking for a valid index */ +struct Import* GetObjImport (ObjData* Obj, unsigned Id); +/* Get an import from an object file checking for a valid index */ + +struct Export* GetObjExport (ObjData* Obj, unsigned Id); +/* Get an export from an object file checking for a valid index */ + struct Scope* GetObjScope (ObjData* Obj, unsigned Id); /* Get a scope from an object file checking for a valid index */ diff --git a/src/ld65/objfile.c b/src/ld65/objfile.c index 8b85e2cfa..66bcc64fe 100644 --- a/src/ld65/objfile.c +++ b/src/ld65/objfile.c @@ -200,7 +200,7 @@ void ObjReadDbgSyms (FILE* F, unsigned long Pos, ObjData* O) DbgSymCount = ReadVar (F); CollGrow (&O->DbgSyms, DbgSymCount); for (I = 0; I < DbgSymCount; ++I) { - CollAppend (&O->DbgSyms, ReadDbgSym (F, O)); + CollAppend (&O->DbgSyms, ReadDbgSym (F, O, I)); } } @@ -276,7 +276,7 @@ void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O) CollGrow (&O->Scopes, ScopeCount); for (I = 0; I < ScopeCount; ++I) { CollAppend (&O->Scopes, ReadScope (F, O, I)); - } + } }