mirror of
https://github.com/cc65/cc65.git
synced 2025-01-13 09:31:53 +00:00
Added functions to access the c symbols in the debug info file.
git-svn-id: svn://svn.cc65.org/cc65/trunk@5294 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
8504f42497
commit
3ec4b296ba
@ -265,7 +265,6 @@ struct CSymInfo {
|
|||||||
unsigned Id; /* Id of scope */
|
unsigned Id; /* Id of scope */
|
||||||
ScopeInfo* Info; /* Pointer to scope */
|
ScopeInfo* Info; /* Pointer to scope */
|
||||||
} Scope;
|
} Scope;
|
||||||
Collection* LocalsByName; /* Locals if this is a function */
|
|
||||||
char Name[1]; /* Name of file with full path */
|
char Name[1]; /* Name of file with full path */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -731,9 +730,9 @@ static void CollFree (Collection* C)
|
|||||||
|
|
||||||
|
|
||||||
static unsigned CollCount (const Collection* C)
|
static unsigned CollCount (const Collection* C)
|
||||||
/* Return the number of items in the collection */
|
/* Return the number of items in the collection. Return 0 if C is NULL. */
|
||||||
{
|
{
|
||||||
return C->Count;
|
return C? C->Count : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1069,6 +1068,21 @@ static void DBGPRINT(const char* format, ...) {}
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned GetId (const void* Data)
|
||||||
|
/* Return the id of one of the info structures. All structures have the Id
|
||||||
|
* field as first member, and the C standard allows converting a union pointer
|
||||||
|
* to the data type of the first member, so this is safe and portable.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
if (Data) {
|
||||||
|
return *(const unsigned*)Data;
|
||||||
|
} else {
|
||||||
|
return CC65_INV_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned HexValue (char C)
|
static unsigned HexValue (char C)
|
||||||
/* Convert the ascii representation of a hex nibble into the hex nibble */
|
/* Convert the ascii representation of a hex nibble into the hex nibble */
|
||||||
{
|
{
|
||||||
@ -1182,7 +1196,6 @@ static CSymInfo* NewCSymInfo (const StrBuf* Name)
|
|||||||
CSymInfo* S = xmalloc (sizeof (CSymInfo) + SB_GetLen (Name));
|
CSymInfo* S = xmalloc (sizeof (CSymInfo) + SB_GetLen (Name));
|
||||||
|
|
||||||
/* Initialize it */
|
/* Initialize it */
|
||||||
S->LocalsByName = 0;
|
|
||||||
memcpy (S->Name, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
|
memcpy (S->Name, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
|
||||||
|
|
||||||
/* Return it */
|
/* Return it */
|
||||||
@ -1194,15 +1207,39 @@ static CSymInfo* NewCSymInfo (const StrBuf* Name)
|
|||||||
static void FreeCSymInfo (CSymInfo* S)
|
static void FreeCSymInfo (CSymInfo* S)
|
||||||
/* Free a CSymInfo struct */
|
/* Free a CSymInfo struct */
|
||||||
{
|
{
|
||||||
/* Free collections */
|
|
||||||
CollFree (S->LocalsByName);
|
|
||||||
|
|
||||||
/* Free the structure itself */
|
/* Free the structure itself */
|
||||||
xfree (S);
|
xfree (S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static cc65_csyminfo* new_cc65_csyminfo (unsigned Count)
|
||||||
|
/* Allocate and return a cc65_csyminfo struct that is able to hold Count
|
||||||
|
* entries. Initialize the count field of the returned struct.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
cc65_csyminfo* S = xmalloc (sizeof (*S) - sizeof (S->data[0]) +
|
||||||
|
Count * sizeof (S->data[0]));
|
||||||
|
S->count = Count;
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void CopyCSymInfo (cc65_csymdata* D, const CSymInfo* S)
|
||||||
|
/* Copy data from a CSymInfo struct to a cc65_csymdata struct */
|
||||||
|
{
|
||||||
|
D->csym_id = S->Id;
|
||||||
|
D->csym_kind = S->Kind;
|
||||||
|
D->csym_sc = S->SC;
|
||||||
|
D->csym_offs = S->Offs;
|
||||||
|
D->symbol_id = GetId (S->Sym.Info);
|
||||||
|
D->scope_id = GetId (S->Scope.Info);
|
||||||
|
D->csym_name = S->Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int CompareCSymInfoByName (const void* L, const void* R)
|
static int CompareCSymInfoByName (const void* L, const void* R)
|
||||||
/* Helper function to sort c symbol infos in a collection by name */
|
/* Helper function to sort c symbol infos in a collection by name */
|
||||||
{
|
{
|
||||||
@ -1476,16 +1513,8 @@ static void CopyModInfo (cc65_moduledata* D, const ModInfo* M)
|
|||||||
D->module_id = M->Id;
|
D->module_id = M->Id;
|
||||||
D->module_name = M->Name;
|
D->module_name = M->Name;
|
||||||
D->source_id = M->File.Info->Id;
|
D->source_id = M->File.Info->Id;
|
||||||
if (M->Lib.Info) {
|
D->library_id = GetId (M->Lib.Info);
|
||||||
D->library_id = M->Lib.Info->Id;
|
D->scope_id = GetId (M->MainScope);
|
||||||
} else {
|
|
||||||
D->library_id = CC65_INV_ID;
|
|
||||||
}
|
|
||||||
if (M->MainScope) {
|
|
||||||
D->scope_id = M->MainScope->Id;
|
|
||||||
} else {
|
|
||||||
D->scope_id = CC65_INV_ID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1557,16 +1586,8 @@ static void CopyScopeInfo (cc65_scopedata* D, const ScopeInfo* S)
|
|||||||
D->scope_name = S->Name;
|
D->scope_name = S->Name;
|
||||||
D->scope_type = S->Type;
|
D->scope_type = S->Type;
|
||||||
D->scope_size = S->Size;
|
D->scope_size = S->Size;
|
||||||
if (S->Parent.Info) {
|
D->parent_id = GetId (S->Parent.Info);
|
||||||
D->parent_id = S->Parent.Info->Id;
|
D->symbol_id = GetId (S->Label.Info);
|
||||||
} else {
|
|
||||||
D->parent_id = CC65_INV_ID;
|
|
||||||
}
|
|
||||||
if (S->Label.Info) {
|
|
||||||
D->symbol_id = S->Label.Info->Id;
|
|
||||||
} else {
|
|
||||||
D->symbol_id = CC65_INV_ID;
|
|
||||||
}
|
|
||||||
D->module_id = S->Mod.Info->Id;
|
D->module_id = S->Mod.Info->Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1718,21 +1739,9 @@ static void CopySpanInfo (cc65_spandata* D, const SpanInfo* S)
|
|||||||
D->span_start = S->Start;
|
D->span_start = S->Start;
|
||||||
D->span_end = S->End;
|
D->span_end = S->End;
|
||||||
D->segment_id = S->Seg.Info->Id;
|
D->segment_id = S->Seg.Info->Id;
|
||||||
if (S->Type.Info) {
|
D->type_id = GetId (S->Type.Info);
|
||||||
D->type_id = S->Type.Info->Id;
|
|
||||||
} else {
|
|
||||||
D->type_id = CC65_INV_ID;
|
|
||||||
}
|
|
||||||
if (S->ScopeInfoList) {
|
|
||||||
D->scope_count = CollCount (S->ScopeInfoList);
|
D->scope_count = CollCount (S->ScopeInfoList);
|
||||||
} else {
|
|
||||||
D->scope_count = 0;
|
|
||||||
}
|
|
||||||
if (S->LineInfoList) {
|
|
||||||
D->line_count = CollCount (S->LineInfoList);
|
D->line_count = CollCount (S->LineInfoList);
|
||||||
} else {
|
|
||||||
D->line_count = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4605,7 +4614,51 @@ ErrorExit:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int FindFileInfoByName (Collection* FileInfos, const char* Name,
|
static int FindCSymInfoByName (const Collection* CSymInfos, const char* Name,
|
||||||
|
unsigned* Index)
|
||||||
|
/* Find the C symbol info with a given file name. The function returns true if
|
||||||
|
* the name was found. In this case, Index contains the index of the first item
|
||||||
|
* that matches. If the item wasn't found, the function returns false and
|
||||||
|
* Index contains the insert position for Name.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Do a binary search */
|
||||||
|
int Lo = 0;
|
||||||
|
int Hi = (int) CollCount (CSymInfos) - 1;
|
||||||
|
int Found = 0;
|
||||||
|
while (Lo <= Hi) {
|
||||||
|
|
||||||
|
/* Mid of range */
|
||||||
|
int Cur = (Lo + Hi) / 2;
|
||||||
|
|
||||||
|
/* Get item */
|
||||||
|
const CSymInfo* CurItem = CollAt (CSymInfos, Cur);
|
||||||
|
|
||||||
|
/* Compare */
|
||||||
|
int Res = strcmp (CurItem->Name, Name);
|
||||||
|
|
||||||
|
/* Found? */
|
||||||
|
if (Res < 0) {
|
||||||
|
Lo = Cur + 1;
|
||||||
|
} else {
|
||||||
|
Hi = Cur - 1;
|
||||||
|
/* Since we may have duplicates, repeat the search until we've
|
||||||
|
* the first item that has a match.
|
||||||
|
*/
|
||||||
|
if (Res == 0) {
|
||||||
|
Found = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pass back the index. This is also the insert position */
|
||||||
|
*Index = Lo;
|
||||||
|
return Found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int FindFileInfoByName (const Collection* FileInfos, const char* Name,
|
||||||
unsigned* Index)
|
unsigned* Index)
|
||||||
/* Find the FileInfo for a given file name. The function returns true if the
|
/* Find the FileInfo for a given file name. The function returns true if the
|
||||||
* name was found. In this case, Index contains the index of the first item
|
* name was found. In this case, Index contains the index of the first item
|
||||||
@ -4623,7 +4676,7 @@ static int FindFileInfoByName (Collection* FileInfos, const char* Name,
|
|||||||
int Cur = (Lo + Hi) / 2;
|
int Cur = (Lo + Hi) / 2;
|
||||||
|
|
||||||
/* Get item */
|
/* Get item */
|
||||||
FileInfo* CurItem = CollAt (FileInfos, Cur);
|
const FileInfo* CurItem = CollAt (FileInfos, Cur);
|
||||||
|
|
||||||
/* Compare */
|
/* Compare */
|
||||||
int Res = strcmp (CurItem->Name, Name);
|
int Res = strcmp (CurItem->Name, Name);
|
||||||
@ -4965,14 +5018,14 @@ static void ProcessCSymInfo (InputData* D)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Walk over all scopes and sort the c symbols by name */
|
/* Walk over all scopes and sort the c symbols by name. */
|
||||||
for (I = 0; I < CollCount (&D->Info->ScopeInfoById); ++I) {
|
for (I = 0; I < CollCount (&D->Info->ScopeInfoById); ++I) {
|
||||||
|
|
||||||
/* Get this scope */
|
/* Get this scope */
|
||||||
ScopeInfo* S = CollAt (&D->Info->ScopeInfoById, I);
|
ScopeInfo* S = CollAt (&D->Info->ScopeInfoById, I);
|
||||||
|
|
||||||
/* Ignore scopes without C symbols */
|
/* Ignore scopes without C symbols */
|
||||||
if (S->CSymInfoByName && CollCount (S->CSymInfoByName) > 1) {
|
if (CollCount (S->CSymInfoByName) > 1) {
|
||||||
/* Sort the c symbols for this scope by name */
|
/* Sort the c symbols for this scope by name */
|
||||||
CollSort (S->CSymInfoByName, CompareCSymInfoByName);
|
CollSort (S->CSymInfoByName, CompareCSymInfoByName);
|
||||||
}
|
}
|
||||||
@ -5741,6 +5794,217 @@ void cc65_free_dbginfo (cc65_dbginfo Handle)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* C symbols */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cc65_csyminfo* cc65_get_csymlist (cc65_dbginfo Handle)
|
||||||
|
/* Return a list of all c symbols */
|
||||||
|
{
|
||||||
|
const DbgInfo* Info;
|
||||||
|
cc65_csyminfo* S;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
/* Check the parameter */
|
||||||
|
assert (Handle != 0);
|
||||||
|
|
||||||
|
/* The handle is actually a pointer to a debug info struct */
|
||||||
|
Info = Handle;
|
||||||
|
|
||||||
|
/* Allocate memory for the data structure returned to the caller */
|
||||||
|
S = new_cc65_csyminfo (CollCount (&Info->CSymInfoById));
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
for (I = 0; I < CollCount (&Info->CSymInfoById); ++I) {
|
||||||
|
/* Copy the data */
|
||||||
|
CopyCSymInfo (S->data + I, CollAt (&Info->CSymInfoById, I));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cc65_csyminfo* cc65_csym_byid (cc65_dbginfo Handle, unsigned Id)
|
||||||
|
/* Return information about a c symbol with a specific id. The function
|
||||||
|
* returns NULL if the id is invalid (no such c symbol) and otherwise a
|
||||||
|
* cc65_csyminfo structure with one entry that contains the requested
|
||||||
|
* symbol information.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
const DbgInfo* Info;
|
||||||
|
cc65_csyminfo* S;
|
||||||
|
|
||||||
|
/* Check the parameter */
|
||||||
|
assert (Handle != 0);
|
||||||
|
|
||||||
|
/* The handle is actually a pointer to a debug info struct */
|
||||||
|
Info = Handle;
|
||||||
|
|
||||||
|
/* Check if the id is valid */
|
||||||
|
if (Id >= CollCount (&Info->CSymInfoById)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for the data structure returned to the caller */
|
||||||
|
S = new_cc65_csyminfo (1);
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
CopyCSymInfo (S->data, CollAt (&Info->CSymInfoById, Id));
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cc65_csyminfo* cc65_cfunc_bymodule (cc65_dbginfo Handle, unsigned ModId)
|
||||||
|
/* Return the list of C functions (not symbols!) for a specific module. If
|
||||||
|
* the module id is invalid, the function will return NULL, otherwise a
|
||||||
|
* (possibly empty) c symbol list.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
const DbgInfo* Info;
|
||||||
|
const ModInfo* M;
|
||||||
|
cc65_csyminfo* D;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check the parameter */
|
||||||
|
assert (Handle != 0);
|
||||||
|
|
||||||
|
/* The handle is actually a pointer to a debug info struct */
|
||||||
|
Info = Handle;
|
||||||
|
|
||||||
|
/* Check if the module id is valid */
|
||||||
|
if (ModId >= CollCount (&Info->ModInfoById)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a pointer to the module info */
|
||||||
|
M = CollAt (&Info->ModInfoById, ModId);
|
||||||
|
|
||||||
|
/* Allocate memory for the data structure returned to the caller */
|
||||||
|
D = new_cc65_csyminfo (CollCount (&M->CSymFuncByName));
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
for (I = 0; I < CollCount (&M->CSymFuncByName); ++I) {
|
||||||
|
CopyCSymInfo (D->data + I, CollAt (&M->CSymFuncByName, I));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
return D;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cc65_csyminfo* cc65_cfunc_byname (cc65_dbginfo Handle, const char* Name)
|
||||||
|
/* Return a list of all C functions with the given name that have a
|
||||||
|
* definition.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
const DbgInfo* Info;
|
||||||
|
unsigned Index;
|
||||||
|
unsigned Count;
|
||||||
|
const CSymInfo* S;
|
||||||
|
cc65_csyminfo* D;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check the parameter */
|
||||||
|
assert (Handle != 0);
|
||||||
|
|
||||||
|
/* The handle is actually a pointer to a debug info struct */
|
||||||
|
Info = Handle;
|
||||||
|
|
||||||
|
/* Search for a function with the given name */
|
||||||
|
if (!FindCSymInfoByName (&Info->CSymFuncByName, Name, &Index)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count functions with this name */
|
||||||
|
Count = 1;
|
||||||
|
I = Index;
|
||||||
|
while (1) {
|
||||||
|
if (++I >= CollCount (&Info->CSymFuncByName)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
S = CollAt (&Info->CSymFuncByName, I);
|
||||||
|
if (strcmp (S->Name, Name) != 0) {
|
||||||
|
/* Next symbol has another name */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for the data structure returned to the caller */
|
||||||
|
D = new_cc65_csyminfo (Count);
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
for (I = 0; I < Count; ++I, ++Index) {
|
||||||
|
CopyCSymInfo (D->data + I, CollAt (&Info->CSymFuncByName, Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
return D;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cc65_csyminfo* cc65_csym_byscope (cc65_dbginfo Handle, unsigned ScopeId)
|
||||||
|
/* Return all C symbols for a scope. The function will return NULL if the
|
||||||
|
* given id is invalid.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
const DbgInfo* Info;
|
||||||
|
const ScopeInfo* S;
|
||||||
|
cc65_csyminfo* D;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check the parameter */
|
||||||
|
assert (Handle != 0);
|
||||||
|
|
||||||
|
/* The handle is actually a pointer to a debug info struct */
|
||||||
|
Info = Handle;
|
||||||
|
|
||||||
|
/* Check if the scope id is valid */
|
||||||
|
if (ScopeId >= CollCount (&Info->ScopeInfoById)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a pointer to the scope */
|
||||||
|
S = CollAt (&Info->ScopeInfoById, ScopeId);
|
||||||
|
|
||||||
|
/* Allocate memory for the data structure returned to the caller */
|
||||||
|
D = new_cc65_csyminfo (CollCount (S->CSymInfoByName));
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
for (I = 0; I < CollCount (S->CSymInfoByName); ++I) {
|
||||||
|
CopyCSymInfo (D->data + I, CollAt (S->CSymInfoByName, I));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
return D;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cc65_free_csyminfo (cc65_dbginfo Handle, const cc65_csyminfo* Info)
|
||||||
|
/* Free a c symbol info record */
|
||||||
|
{
|
||||||
|
/* Just for completeness, check the handle */
|
||||||
|
assert (Handle != 0);
|
||||||
|
|
||||||
|
/* Just free the memory */
|
||||||
|
xfree ((cc65_csyminfo*) Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Libraries */
|
/* Libraries */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -6046,9 +6310,9 @@ const cc65_lineinfo* cc65_line_byspan (cc65_dbginfo Handle, unsigned SpanId)
|
|||||||
S = CollAt (&Info->SpanInfoById, SpanId);
|
S = CollAt (&Info->SpanInfoById, SpanId);
|
||||||
|
|
||||||
/* Prepare the struct we will return to the caller */
|
/* Prepare the struct we will return to the caller */
|
||||||
D = new_cc65_lineinfo (S->LineInfoList? CollCount (S->LineInfoList) : 0);
|
D = new_cc65_lineinfo (CollCount (S->LineInfoList));
|
||||||
|
|
||||||
/* Fill in the data. Since D->LineInfoList may be NULL, we will use the
|
/* Fill in the data. Since S->LineInfoList may be NULL, we will use the
|
||||||
* count field of the returned data struct instead.
|
* count field of the returned data struct instead.
|
||||||
*/
|
*/
|
||||||
for (I = 0; I < D->count; ++I) {
|
for (I = 0; I < D->count; ++I) {
|
||||||
@ -6652,7 +6916,7 @@ const cc65_scopeinfo* cc65_scope_byspan (cc65_dbginfo Handle, unsigned SpanId)
|
|||||||
S = CollAt (&Info->SpanInfoById, SpanId);
|
S = CollAt (&Info->SpanInfoById, SpanId);
|
||||||
|
|
||||||
/* Prepare the struct we will return to the caller */
|
/* Prepare the struct we will return to the caller */
|
||||||
D = new_cc65_scopeinfo (S->ScopeInfoList? CollCount (S->ScopeInfoList) : 0);
|
D = new_cc65_scopeinfo (CollCount (S->ScopeInfoList));
|
||||||
|
|
||||||
/* Fill in the data. Since D->ScopeInfoList may be NULL, we will use the
|
/* Fill in the data. Since D->ScopeInfoList may be NULL, we will use the
|
||||||
* count field of the returned data struct instead.
|
* count field of the returned data struct instead.
|
||||||
@ -6694,7 +6958,7 @@ const cc65_scopeinfo* cc65_childscopes_byid (cc65_dbginfo Handle, unsigned Id)
|
|||||||
S = CollAt (&Info->ScopeInfoById, Id);
|
S = CollAt (&Info->ScopeInfoById, Id);
|
||||||
|
|
||||||
/* Allocate memory for the data structure returned to the caller */
|
/* Allocate memory for the data structure returned to the caller */
|
||||||
D = new_cc65_scopeinfo (S->ChildScopeList? CollCount (S->ChildScopeList) : 0);
|
D = new_cc65_scopeinfo (CollCount (S->ChildScopeList));
|
||||||
|
|
||||||
/* Fill in the data */
|
/* Fill in the data */
|
||||||
for (I = 0; I < D->count; ++I) {
|
for (I = 0; I < D->count; ++I) {
|
||||||
|
@ -158,6 +158,22 @@ const cc65_csyminfo* cc65_csym_byid (cc65_dbginfo handle, unsigned id);
|
|||||||
* symbol information.
|
* symbol information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const cc65_csyminfo* cc65_cfunc_bymodule (cc65_dbginfo handle, unsigned module_id);
|
||||||
|
/* Return the list of C functions (not symbols!) for a specific module. If
|
||||||
|
* the module id is invalid, the function will return NULL, otherwise a
|
||||||
|
* (possibly empty) c symbol list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const cc65_csyminfo* cc65_cfunc_byname (cc65_dbginfo handle, const char* name);
|
||||||
|
/* Return a list of all C functions with the given name that have a
|
||||||
|
* definition.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const cc65_csyminfo* cc65_csym_byscope (cc65_dbginfo handle, unsigned scope_id);
|
||||||
|
/* Return all C symbols for a scope. The function will return NULL if the
|
||||||
|
* given id is invalid.
|
||||||
|
*/
|
||||||
|
|
||||||
void cc65_free_csyminfo (cc65_dbginfo handle, const cc65_csyminfo* info);
|
void cc65_free_csyminfo (cc65_dbginfo handle, const cc65_csyminfo* info);
|
||||||
/* Free a c symbol info record */
|
/* Free a c symbol info record */
|
||||||
|
|
||||||
|
@ -75,6 +75,12 @@ static void CmdShowHelp (Collection* Args);
|
|||||||
static void CmdShowChildScopes (Collection* Args);
|
static void CmdShowChildScopes (Collection* Args);
|
||||||
/* Show child scopes from the debug info file */
|
/* Show child scopes from the debug info file */
|
||||||
|
|
||||||
|
static void CmdShowCSymbol (Collection* Args);
|
||||||
|
/* Show c symbols from the debug info file */
|
||||||
|
|
||||||
|
static void CmdShowFunction (Collection* Args);
|
||||||
|
/* Show C functions from the debug info file */
|
||||||
|
|
||||||
static void CmdShowLibrary (Collection* Args);
|
static void CmdShowLibrary (Collection* Args);
|
||||||
/* Show libraries from the debug info file */
|
/* Show libraries from the debug info file */
|
||||||
|
|
||||||
@ -132,6 +138,7 @@ static unsigned FileWarnings = 0;
|
|||||||
/* Type of an id */
|
/* Type of an id */
|
||||||
enum {
|
enum {
|
||||||
InvalidId,
|
InvalidId,
|
||||||
|
CSymbolId,
|
||||||
LibraryId,
|
LibraryId,
|
||||||
LineId,
|
LineId,
|
||||||
ModuleId,
|
ModuleId,
|
||||||
@ -194,9 +201,29 @@ static const CmdEntry ShowCmds[] = {
|
|||||||
"Show child scopes of other scopes.",
|
"Show child scopes of other scopes.",
|
||||||
-2,
|
-2,
|
||||||
CmdShowChildScopes
|
CmdShowChildScopes
|
||||||
|
}, {
|
||||||
|
"csym",
|
||||||
|
0,
|
||||||
|
-1,
|
||||||
|
CmdShowCSymbol
|
||||||
|
}, {
|
||||||
|
"csymbol",
|
||||||
|
"Show c symbols.",
|
||||||
|
-1,
|
||||||
|
CmdShowCSymbol
|
||||||
|
}, {
|
||||||
|
"func",
|
||||||
|
0,
|
||||||
|
-2,
|
||||||
|
CmdShowFunction
|
||||||
|
}, {
|
||||||
|
"function",
|
||||||
|
"Show c functions.",
|
||||||
|
-2,
|
||||||
|
CmdShowFunction
|
||||||
}, {
|
}, {
|
||||||
"help",
|
"help",
|
||||||
"Show available subcommands",
|
"Show available subcommands.",
|
||||||
1,
|
1,
|
||||||
CmdShowHelp
|
CmdShowHelp
|
||||||
}, {
|
}, {
|
||||||
@ -491,10 +518,10 @@ static void PrintAddr (cc65_addr Addr, unsigned FieldWidth)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void PrintNumber (unsigned long Num, unsigned Width, unsigned FieldWidth)
|
static void PrintNumber (long Num, unsigned Width, unsigned FieldWidth)
|
||||||
/* Output a number */
|
/* Output a number */
|
||||||
{
|
{
|
||||||
Print ("%*lu", Width, Num);
|
Print ("%*ld", Width, Num);
|
||||||
if (FieldWidth > Width) {
|
if (FieldWidth > Width) {
|
||||||
Print ("%*s", FieldWidth - Width, "");
|
Print ("%*s", FieldWidth - Width, "");
|
||||||
}
|
}
|
||||||
@ -544,6 +571,38 @@ static void PrintTime (time_t T, unsigned FieldWidth)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void PrintCSymbolHeader (void)
|
||||||
|
/* Output a header for a list of C symbols */
|
||||||
|
{
|
||||||
|
/* Header */
|
||||||
|
PrintLine (" id name type kind sc offs symbol scope");
|
||||||
|
PrintSeparator ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void PrintCSymbols (const cc65_csyminfo* S)
|
||||||
|
/* Output a list of C symbols */
|
||||||
|
{
|
||||||
|
unsigned I;
|
||||||
|
const cc65_csymdata* D;
|
||||||
|
|
||||||
|
/* Segments */
|
||||||
|
for (I = 0, D = S->data; I < S->count; ++I, ++D) {
|
||||||
|
PrintId (D->csym_id, 6);
|
||||||
|
Print ("%-28s", D->csym_name);
|
||||||
|
PrintId (0, 6);
|
||||||
|
PrintNumber (D->csym_kind, 4, 6);
|
||||||
|
PrintNumber (D->csym_sc, 4, 6);
|
||||||
|
PrintNumber (D->csym_offs, 4, 8);
|
||||||
|
PrintId (D->symbol_id, 6);
|
||||||
|
PrintId (D->scope_id, 0);
|
||||||
|
NewLine ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void PrintLibraryHeader (void)
|
static void PrintLibraryHeader (void)
|
||||||
/* Output the header for a library list */
|
/* Output the header for a library list */
|
||||||
{
|
{
|
||||||
@ -1002,6 +1061,116 @@ static void CmdShowChildScopes (Collection* Args)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void CmdShowCSymbol (Collection* Args)
|
||||||
|
/* Show C symbols from the debug info file */
|
||||||
|
{
|
||||||
|
const cc65_csyminfo* S;
|
||||||
|
|
||||||
|
/* Be sure a file is loaded */
|
||||||
|
if (!FileIsLoaded ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output the header */
|
||||||
|
PrintCSymbolHeader ();
|
||||||
|
|
||||||
|
/* No arguments means show all libraries */
|
||||||
|
if (CollCount (Args) == 0) {
|
||||||
|
|
||||||
|
/* Fetch the list of c symbols */
|
||||||
|
S = cc65_get_csymlist (Info);
|
||||||
|
|
||||||
|
/* Output the c symbols */
|
||||||
|
PrintCSymbols (S);
|
||||||
|
|
||||||
|
/* Free the list */
|
||||||
|
cc65_free_csyminfo (Info, S);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Output c symbols for all arguments */
|
||||||
|
unsigned I;
|
||||||
|
for (I = 0; I < CollCount (Args); ++I) {
|
||||||
|
|
||||||
|
/* Parse the argument */
|
||||||
|
unsigned Id;
|
||||||
|
unsigned IdType = CSymbolId;
|
||||||
|
if (GetId (CollConstAt (Args, I), &Id, &IdType)) {
|
||||||
|
/* Fetch list depending on type */
|
||||||
|
switch (IdType) {
|
||||||
|
case CSymbolId:
|
||||||
|
S = cc65_csym_byid (Info, Id);
|
||||||
|
break;
|
||||||
|
case ScopeId:
|
||||||
|
S = cc65_csym_byscope (Info, Id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
S = 0;
|
||||||
|
PrintLine ("Invalid id type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Invalid id */
|
||||||
|
S = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output the list */
|
||||||
|
if (S) {
|
||||||
|
PrintCSymbols (S);
|
||||||
|
cc65_free_csyminfo (Info, S);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void CmdShowFunction (Collection* Args)
|
||||||
|
/* Show C functions from the debug info file */
|
||||||
|
{
|
||||||
|
const cc65_csyminfo* S;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
/* Be sure a file is loaded */
|
||||||
|
if (!FileIsLoaded ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output the header */
|
||||||
|
PrintCSymbolHeader ();
|
||||||
|
|
||||||
|
/* Output c symbols for all arguments */
|
||||||
|
for (I = 0; I < CollCount (Args); ++I) {
|
||||||
|
|
||||||
|
/* Parse the argument */
|
||||||
|
unsigned Id;
|
||||||
|
unsigned IdType = ModuleId;
|
||||||
|
if (GetId (CollConstAt (Args, I), &Id, &IdType)) {
|
||||||
|
/* Fetch list depending on type */
|
||||||
|
switch (IdType) {
|
||||||
|
case ModuleId:
|
||||||
|
S = cc65_cfunc_bymodule (Info, Id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
S = 0;
|
||||||
|
PrintLine ("Invalid id type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* An invalid id may be a function name */
|
||||||
|
S = cc65_cfunc_byname (Info, CollConstAt (Args, I));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output the list */
|
||||||
|
if (S) {
|
||||||
|
PrintCSymbols (S);
|
||||||
|
cc65_free_csyminfo (Info, S);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void CmdShowLine (Collection* Args)
|
static void CmdShowLine (Collection* Args)
|
||||||
/* Show lines from the debug info file */
|
/* Show lines from the debug info file */
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user