1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-25 13:29:41 +00:00

Postprocess and cross-reference C symbol infos.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5293 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-09-01 10:21:25 +00:00
parent e63dcb46f1
commit 8504f42497

View File

@ -199,6 +199,7 @@ struct DbgInfo {
Collection TypeInfoById; /* Type infos sorted by id */
/* Collections with other sort criteria */
Collection CSymFuncByName; /* C functions sorted by name */
Collection FileInfoByName; /* File infos sorted by name */
Collection ModInfoByName; /* Module info sorted by name */
Collection ScopeInfoByName;/* Scope infos sorted by name */
@ -264,6 +265,7 @@ struct CSymInfo {
unsigned Id; /* Id of scope */
ScopeInfo* Info; /* Pointer to scope */
} Scope;
Collection* LocalsByName; /* Locals if this is a function */
char Name[1]; /* Name of file with full path */
};
@ -308,6 +310,7 @@ struct ModInfo {
LibInfo* Info; /* Pointer to library info */
} Lib;
ScopeInfo* MainScope; /* Pointer to main scope */
Collection CSymFuncByName; /* C functions by name */
Collection FileInfoByName; /* Files for this module */
Collection ScopeInfoByName;/* Scopes for this module */
char Name[1]; /* Name of module with path */
@ -330,8 +333,10 @@ struct ScopeInfo {
unsigned Id; /* Id of label symbol */
SymInfo* Info; /* Pointer to label symbol */
} Label;
CSymInfo* CSymFunc; /* C function for this scope */
Collection SpanInfoList; /* List of spans for this scope */
Collection SymInfoByName; /* Symbols in this scope */
Collection* CSymInfoByName; /* C symbols for this scope */
Collection* ChildScopeList; /* Child scopes of this scope */
char Name[1]; /* Name of scope */
};
@ -385,6 +390,7 @@ struct SymInfo {
unsigned Id; /* Parent symbol if any */
SymInfo* Info; /* Pointer to parent symbol if any */
} Parent;
CSymInfo* CSym; /* Corresponding C symbol */
Collection* ImportList; /* List of imports if this is an export */
Collection* CheapLocals; /* List of cheap local symbols */
Collection DefLineInfoList;/* Line info of symbol definition */
@ -1176,6 +1182,7 @@ static CSymInfo* NewCSymInfo (const StrBuf* Name)
CSymInfo* S = xmalloc (sizeof (CSymInfo) + SB_GetLen (Name));
/* Initialize it */
S->LocalsByName = 0;
memcpy (S->Name, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
/* Return it */
@ -1187,6 +1194,9 @@ static CSymInfo* NewCSymInfo (const StrBuf* Name)
static void FreeCSymInfo (CSymInfo* S)
/* Free a CSymInfo struct */
{
/* Free collections */
CollFree (S->LocalsByName);
/* Free the structure itself */
xfree (S);
}
@ -1196,9 +1206,12 @@ static void FreeCSymInfo (CSymInfo* S)
static int CompareCSymInfoByName (const void* L, const void* R)
/* Helper function to sort c symbol infos in a collection by name */
{
/* Sort by symbol name */
return strcmp (((const CSymInfo*) L)->Name,
((const CSymInfo*) R)->Name);
/* Sort by symbol name, then by id */
int Res = strcmp (((const CSymInfo*) L)->Name, ((const CSymInfo*) R)->Name);
if (Res == 0) {
Res = (int)((const CSymInfo*) L)->Id - (int)((const CSymInfo*) R)->Id;
}
return Res;
}
@ -1419,6 +1432,7 @@ static ModInfo* NewModInfo (const StrBuf* Name)
/* Initialize it */
M->MainScope = 0;
CollInit (&M->CSymFuncByName);
CollInit (&M->FileInfoByName);
CollInit (&M->ScopeInfoByName);
memcpy (M->Name, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
@ -1433,6 +1447,7 @@ static void FreeModInfo (ModInfo* M)
/* Free a ModInfo struct */
{
/* Free the collections */
CollDone (&M->CSymFuncByName);
CollDone (&M->FileInfoByName);
CollDone (&M->ScopeInfoByName);
@ -1497,8 +1512,10 @@ static ScopeInfo* NewScopeInfo (const StrBuf* Name)
ScopeInfo* S = xmalloc (sizeof (ScopeInfo) + SB_GetLen (Name));
/* Initialize the fields as necessary */
S->CSymFunc = 0;
CollInit (&S->SpanInfoList);
CollInit (&S->SymInfoByName);
S->CSymInfoByName = 0;
S->ChildScopeList = 0;
memcpy (S->Name, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
@ -1513,6 +1530,7 @@ static void FreeScopeInfo (ScopeInfo* S)
{
CollDone (&S->SpanInfoList);
CollDone (&S->SymInfoByName);
CollFree (S->CSymInfoByName);
CollFree (S->ChildScopeList);
xfree (S);
}
@ -1757,7 +1775,8 @@ static SymInfo* NewSymInfo (const StrBuf* Name)
SymInfo* S = xmalloc (sizeof (SymInfo) + SB_GetLen (Name));
/* Initialize it as necessary */
S->ImportList = 0;
S->CSym = 0;
S->ImportList = 0;
S->CheapLocals = 0;
CollInit (&S->DefLineInfoList);
CollInit (&S->RefLineInfoList);
@ -2365,6 +2384,7 @@ static DbgInfo* NewDbgInfo (const char* FileName)
CollInit (&Info->SymInfoById);
CollInit (&Info->TypeInfoById);
CollInit (&Info->CSymFuncByName);
CollInit (&Info->FileInfoByName);
CollInit (&Info->ModInfoByName);
CollInit (&Info->ScopeInfoByName);
@ -2435,6 +2455,7 @@ static void FreeDbgInfo (DbgInfo* Info)
CollDone (&Info->TypeInfoById);
/* Free the memory used by the other collections */
CollDone (&Info->CSymFuncByName);
CollDone (&Info->FileInfoByName);
CollDone (&Info->ModInfoByName);
CollDone (&Info->ScopeInfoByName);
@ -4859,6 +4880,110 @@ static int FindSymInfoByValue (const Collection* SymInfos, long Value,
static void ProcessCSymInfo (InputData* D)
/* Postprocess c symbol infos */
{
unsigned I;
/* Walk over all c symbols. Resolve the ids and add the c symbols to the
* corresponding asm symbols.
*/
for (I = 0; I < CollCount (&D->Info->CSymInfoById); ++I) {
/* Get this c symbol info */
CSymInfo* S = CollAt (&D->Info->CSymInfoById, I);
/* Resolve the asm symbol */
if (S->Sym.Id == CC65_INV_ID) {
S->Sym.Info = 0;
} else if (S->Sym.Id >= CollCount (&D->Info->SymInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid symbol id %u for c symbol with id %u",
S->Sym.Id, S->Id);
S->Sym.Info = 0;
} else {
S->Sym.Info = CollAt (&D->Info->SymInfoById, S->Sym.Id);
/* For normal (=static) symbols, add a backlink to the symbol but
* check that there is not more than one.
*/
if (S->SC != CC65_CSYM_AUTO && S->SC != CC65_CSYM_REG) {
if (S->Sym.Info->CSym) {
ParseError (D,
CC65_ERROR,
"Asm symbol id %u has more than one C symbol attached",
S->Sym.Info->Id);
S->Sym.Info = 0;
} else {
S->Sym.Info->CSym = S;
}
}
}
/* Resolve the type */
if (S->Type.Id >= CollCount (&D->Info->TypeInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid type id %u for c symbol with id %u",
S->Type.Id, S->Id);
S->Type.Info = 0;
} else {
S->Type.Info = CollAt (&D->Info->TypeInfoById, S->Type.Id);
}
/* Resolve the scope */
if (S->Scope.Id >= CollCount (&D->Info->ScopeInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid scope id %u for c symbol with id %u",
S->Scope.Id, S->Id);
S->Scope.Info = 0;
} else {
S->Scope.Info = CollAt (&D->Info->ScopeInfoById, S->Scope.Id);
/* Add the c symbol to the list of all c symbols for this scope */
if (S->Scope.Info->CSymInfoByName == 0) {
S->Scope.Info->CSymInfoByName = CollNew ();
}
CollAppend (S->Scope.Info->CSymInfoByName, S);
/* If the scope has an owner symbol, it's a .PROC scope. If this
* symbol is identical to the one attached to the C symbol, this
* is actuallay a C function and the scope is the matching scope.
* Remember the C symbol in the scope in this case.
* Beware: Scopes haven't been postprocessed, so we don't have a
* pointer but just an id.
*/
if (S->Sym.Info && S->Scope.Info->Label.Id == S->Sym.Info->Id) {
/* This scope is our function scope */
S->Scope.Info->CSymFunc = S;
/* Add it to the list of all c functions */
CollAppend (&D->Info->CSymFuncByName, S);
}
}
}
/* Walk over all scopes and sort the c symbols by name */
for (I = 0; I < CollCount (&D->Info->ScopeInfoById); ++I) {
/* Get this scope */
ScopeInfo* S = CollAt (&D->Info->ScopeInfoById, I);
/* Ignore scopes without C symbols */
if (S->CSymInfoByName && CollCount (S->CSymInfoByName) > 1) {
/* Sort the c symbols for this scope by name */
CollSort (S->CSymInfoByName, CompareCSymInfoByName);
}
}
/* Sort the main list of all C functions by name */
CollSort (&D->Info->CSymFuncByName, CompareCSymInfoByName);
}
static void ProcessFileInfo (InputData* D)
/* Postprocess file infos */
{
@ -5067,6 +5192,13 @@ static void ProcessScopeInfo (InputData* D)
/* No parent means main scope */
S->Mod.Info->MainScope = S;
}
/* If this is the scope that implements a C function, add the
* function to the list of all functions in this module.
*/
if (S->CSymFunc) {
CollAppend (&S->Mod.Info->CSymFuncByName, S->CSymFunc);
}
}
/* Resolve the parent scope */
@ -5131,7 +5263,8 @@ static void ProcessScopeInfo (InputData* D)
/* Walk over all modules. If a module doesn't have scopes, it wasn't
* compiled with debug info which is ok. If it has debug info, it must
* also have a main scope. If there are scopes, sort them by name.
* also have a main scope. If there are scopes, sort them by name. Do
* also sort C functions in this module by name.
*/
for (I = 0; I < CollCount (&D->Info->ModInfoById); ++I) {
@ -5153,6 +5286,9 @@ static void ProcessScopeInfo (InputData* D)
/* Sort the scopes for this module by name */
CollSort (&M->ScopeInfoByName, CompareScopeInfoByName);
/* Sort the C functions in this module by name */
CollSort (&M->CSymFuncByName, CompareCSymInfoByName);
}
/* Sort the scope infos */
@ -5572,8 +5708,10 @@ CloseAndExit:
}
/* We do now have all the information from the input file. Do
* postprocessing.
* postprocessing. Beware: Some of the following postprocessing
* depends on the order of the calls.
*/
ProcessCSymInfo (&D);
ProcessFileInfo (&D);
ProcessLineInfo (&D);
ProcessModInfo (&D);