1
0
mirror of https://github.com/cc65/cc65.git synced 2024-09-29 02:55:20 +00:00

Read and allow access to the segment for (segment based) symbols.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5063 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-06-14 21:18:44 +00:00
parent c768fc7373
commit 44b829cc01
3 changed files with 229 additions and 45 deletions

View File

@ -224,6 +224,7 @@ struct SymInfo {
cc65_symbol_type Type; /* Type of symbol */ cc65_symbol_type Type; /* Type of symbol */
long Value; /* Value of symbol */ long Value; /* Value of symbol */
cc65_size Size; /* Size of symbol */ cc65_size Size; /* Size of symbol */
unsigned Segment; /* Id of segment if any */
char SymName[1]; /* Name of symbol */ char SymName[1]; /* Name of symbol */
}; };
@ -1038,17 +1039,19 @@ static int CompareFileInfoById (const void* L, const void* R)
static SymInfo* NewSymInfo (const StrBuf* Name, long Val, static SymInfo* NewSymInfo (const StrBuf* Name, long Val,
cc65_symbol_type Type, cc65_size Size) cc65_symbol_type Type, cc65_size Size,
unsigned Segment)
/* Create a new SymInfo struct, intialize and return it */ /* Create a new SymInfo struct, intialize and return it */
{ {
/* Allocate memory */ /* Allocate memory */
SymInfo* S = xmalloc (sizeof (SymInfo) + SB_GetLen (Name)); SymInfo* S = xmalloc (sizeof (SymInfo) + SB_GetLen (Name));
/* Initialize it */ /* Initialize it */
S->Type = Type; S->Type = Type;
S->Value = Val; S->Value = Val;
S->Size = Size; S->Size = Size;
S->Segment = Segment;
memcpy (S->SymName, SB_GetConstBuf (Name), SB_GetLen (Name) + 1); memcpy (S->SymName, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
/* Return it */ /* Return it */
@ -1357,9 +1360,7 @@ static void FreeDbgInfo (DbgInfo* Info)
static void CopyLineInfo (cc65_linedata* D, const LineInfo* L) static void CopyLineInfo (cc65_linedata* D, const LineInfo* L)
/* Copy data from a LineInfo struct to the cc65_linedata struct returned to /* Copy data from a LineInfo struct to a cc65_linedata struct */
* the caller.
*/
{ {
D->source_name = L->File.Info->FileName; D->source_name = L->File.Info->FileName;
D->source_size = L->File.Info->Size; D->source_size = L->File.Info->Size;
@ -1380,15 +1381,38 @@ static void CopyLineInfo (cc65_linedata* D, const LineInfo* L)
static void CopySymInfo (cc65_symboldata* D, const SymInfo* S) static void CopyFileInfo (cc65_sourcedata* D, const FileInfo* F)
/* Copy data from a SymInfo struct to the cc65_symboldata struct returned to /* Copy data from a FileInfo struct to a cc65_sourcedata struct */
* the caller.
*/
{ {
D->symbol_name = S->SymName; D->id = F->Id;
D->symbol_type = S->Type; D->source_name = F->FileName;
D->symbol_size = S->Size; D->source_size = F->Size;
D->symbol_value = S->Value; D->source_mtime = F->MTime;
}
static void CopySegInfo (cc65_segmentdata* D, const SegInfo* S)
/* Copy data from a SegInfo struct to a cc65_segmentdata struct */
{
D->id = S->Id;
D->segment_name = S->SegName;
D->segment_start = S->Start;
D->segment_size = S->Size;
D->output_name = S->OutputName;
D->output_offs = S->OutputOffs;
}
static void CopySymInfo (cc65_symboldata* D, const SymInfo* S)
/* Copy data from a SymInfo struct to a cc65_symboldata struct */
{
D->symbol_name = S->SymName;
D->symbol_type = S->Type;
D->symbol_size = S->Size;
D->symbol_value = S->Value;
D->symbol_segment = S->Segment;
} }
@ -1459,7 +1483,7 @@ static void UnknownKeyword (InputData* D)
/* Output a warning */ /* Output a warning */
ParseError (D, CC65_WARNING, "Unknown keyword \"%s\" - skipping", ParseError (D, CC65_WARNING, "Unknown keyword \"%s\" - skipping",
SB_GetConstBuf (&D->SVal)); SB_GetConstBuf (&D->SVal));
/* Skip the identifier */ /* Skip the identifier */
NextToken (D); NextToken (D);
@ -2211,6 +2235,7 @@ static void ParseSym (InputData* D)
long Value; long Value;
cc65_size Size = 0; cc65_size Size = 0;
StrBuf SymName = STRBUF_INITIALIZER; StrBuf SymName = STRBUF_INITIALIZER;
unsigned Segment = CC65_INV_ID;
SymInfo* S; SymInfo* S;
enum { enum {
ibNone = 0x00, ibNone = 0x00,
@ -2234,8 +2259,8 @@ static void ParseSym (InputData* D)
/* Something we know? */ /* Something we know? */
if (D->Tok != TOK_ADDRSIZE && D->Tok != TOK_FILE && if (D->Tok != TOK_ADDRSIZE && D->Tok != TOK_FILE &&
D->Tok != TOK_NAME && D->Tok != TOK_SEGMENT&& D->Tok != TOK_NAME && D->Tok != TOK_SEGMENT&&
D->Tok != TOK_SIZE && D->Tok != TOK_TYPE && D->Tok != TOK_SIZE && D->Tok != TOK_TYPE &&
D->Tok != TOK_VALUE) { D->Tok != TOK_VALUE) {
/* Try smart error recovery */ /* Try smart error recovery */
@ -2286,7 +2311,7 @@ static void ParseSym (InputData* D)
if (!IntConstFollows (D)) { if (!IntConstFollows (D)) {
goto ErrorExit; goto ErrorExit;
} }
/* ### Drop value for now */ Segment = (unsigned) D->IVal;
InfoBits |= ibSegment; InfoBits |= ibSegment;
NextToken (D); NextToken (D);
break; break;
@ -2355,7 +2380,7 @@ static void ParseSym (InputData* D)
} }
/* Create the symbol info and remember it */ /* Create the symbol info and remember it */
S = NewSymInfo (&SymName, Value, Type, Size); S = NewSymInfo (&SymName, Value, Type, Size, Segment);
CollAppend (&D->Info->SymInfoByName, S); CollAppend (&D->Info->SymInfoByName, S);
CollAppend (&D->Info->SymInfoByVal, S); CollAppend (&D->Info->SymInfoByVal, S);
@ -2454,11 +2479,11 @@ ErrorExit:
static SegInfo* FindSegInfoById (InputData* D, unsigned Id) static SegInfo* FindSegInfoById (DbgInfo* D, unsigned Id)
/* Find the SegInfo with a given Id */ /* Find the SegInfo with a given Id */
{ {
/* Get a pointer to the segment info collection */ /* Get a pointer to the segment info collection */
Collection* SegInfos = &D->Info->SegInfoById; Collection* SegInfos = &D->SegInfoById;
/* Do a binary search */ /* Do a binary search */
int Lo = 0; int Lo = 0;
@ -2532,9 +2557,12 @@ static int FindFileInfoByName (Collection* FileInfos, const char* FileName,
static FileInfo* FindFileInfoById (Collection* FileInfos, unsigned Id) static FileInfo* FindFileInfoById (DbgInfo* D, unsigned Id)
/* Find the FileInfo with a given Id */ /* Find the FileInfo with a given Id */
{ {
/* Get a pointer to the collection */
Collection* FileInfos = &D->FileInfoById;
/* Do a binary search */ /* Do a binary search */
int Lo = 0; int Lo = 0;
int Hi = (int) CollCount (FileInfos) - 1; int Hi = (int) CollCount (FileInfos) - 1;
@ -2637,7 +2665,7 @@ static void ProcessLineInfo (InputData* D)
if (LastFileInfo && LastFileInfo->Id == L->File.Id) { if (LastFileInfo && LastFileInfo->Id == L->File.Id) {
F = LastFileInfo; F = LastFileInfo;
} else { } else {
F = FindFileInfoById (&D->Info->FileInfoById, L->File.Id); F = FindFileInfoById (D->Info, L->File.Id);
/* If we have no corresponding file info, print a warning and /* If we have no corresponding file info, print a warning and
* remove the line info. * remove the line info.
@ -2665,7 +2693,7 @@ static void ProcessLineInfo (InputData* D)
if (LastSegInfo && LastSegInfo->Id == L->Seg.Id) { if (LastSegInfo && LastSegInfo->Id == L->Seg.Id) {
S = LastSegInfo; S = LastSegInfo;
} else { } else {
S = FindSegInfoById (D, L->Seg.Id); S = FindSegInfoById (D->Info, L->Seg.Id);
/* If we have no corresponding segment info, print a warning and /* If we have no corresponding segment info, print a warning and
* remove the line info. * remove the line info.
@ -2884,7 +2912,7 @@ static int FindSymInfoByValue (Collection* SymInfos, long Value, unsigned* Index
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Debug info files */
/*****************************************************************************/ /*****************************************************************************/
@ -3065,6 +3093,12 @@ void cc65_free_dbginfo (cc65_dbginfo Handle)
/*****************************************************************************/
/* Line info */
/*****************************************************************************/
cc65_lineinfo* cc65_lineinfo_byaddr (cc65_dbginfo Handle, unsigned long Addr) cc65_lineinfo* cc65_lineinfo_byaddr (cc65_dbginfo Handle, unsigned long Addr)
/* Return line information for the given address. The function returns 0 /* Return line information for the given address. The function returns 0
* if no line information was found. * if no line information was found.
@ -3187,6 +3221,12 @@ void cc65_free_lineinfo (cc65_dbginfo Handle, cc65_lineinfo* Info)
/*****************************************************************************/
/* Source files */
/*****************************************************************************/
cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo Handle) cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo Handle)
/* Return a list of all source files */ /* Return a list of all source files */
{ {
@ -3226,9 +3266,7 @@ cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo Handle)
} }
/* Copy the data */ /* Copy the data */
D->data[D->count].source_name = F->FileName; CopyFileInfo (D->data + D->count, F);
D->data[D->count].source_size = F->Size;
D->data[D->count].source_mtime = F->MTime;
/* One more valid entry */ /* One more valid entry */
++D->count; ++D->count;
@ -3240,6 +3278,44 @@ cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo Handle)
cc65_sourceinfo* cc65_sourceinfo_byid (cc65_dbginfo Handle, unsigned Id)
/* Return information about a source file with a specific id. The function
* returns NULL if the id is invalid (no such source file) and otherwise a
* cc65_sourceinfo structure with one entry that contains the requested
* source file information.
*/
{
DbgInfo* Info;
const FileInfo* F;
cc65_sourceinfo* D;
/* Check the parameter */
assert (Handle != 0);
/* The handle is actually a pointer to a debug info struct */
Info = (DbgInfo*) Handle;
/* Search for the Id */
F = FindFileInfoById (Info, Id);
/* If not found return NULL */
if (F == 0) {
return 0;
}
/* Allocate memory for the data structure returned to the caller */
D = new_cc65_sourceinfo (1);
/* Fill in the data */
CopyFileInfo (D->data, F);
/* Return the result */
return D;
}
void cc65_free_sourceinfo (cc65_dbginfo Handle, cc65_sourceinfo* Info) void cc65_free_sourceinfo (cc65_dbginfo Handle, cc65_sourceinfo* Info)
/* Free a source info record */ /* Free a source info record */
{ {
@ -3252,6 +3328,12 @@ void cc65_free_sourceinfo (cc65_dbginfo Handle, cc65_sourceinfo* Info)
/*****************************************************************************/
/* Segments */
/*****************************************************************************/
cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo Handle) cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo Handle)
/* Return a list of all segments referenced in the debug information */ /* Return a list of all segments referenced in the debug information */
{ {
@ -3275,16 +3357,8 @@ cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo Handle)
/* Fill in the data */ /* Fill in the data */
D->count = CollCount (SegInfoByName); D->count = CollCount (SegInfoByName);
for (I = 0; I < CollCount (SegInfoByName); ++I) { for (I = 0; I < CollCount (SegInfoByName); ++I) {
/* Get this item */
const SegInfo* S = CollAt (SegInfoByName, I);
/* Copy the data */ /* Copy the data */
D->data[I].segment_name = S->SegName; CopySegInfo (D->data + I, CollAt (SegInfoByName, I));
D->data[I].segment_start = S->Start;
D->data[I].segment_size = S->Size;
D->data[I].output_name = S->OutputName;
D->data[I].output_offs = S->OutputOffs;
} }
/* Return the result */ /* Return the result */
@ -3293,6 +3367,42 @@ cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo Handle)
cc65_segmentinfo* cc65_segmentinfo_byid (cc65_dbginfo Handle, unsigned Id)
/* Return information about a segment with a specific id. The function returns
* NULL if the id is invalid (no such segment) and otherwise a segmentinfo
* structure with one entry that contains the requested segment information.
*/
{
DbgInfo* Info;
const SegInfo* S;
cc65_segmentinfo* D;
/* Check the parameter */
assert (Handle != 0);
/* The handle is actually a pointer to a debug info struct */
Info = (DbgInfo*) Handle;
/* Search for the Id */
S = FindSegInfoById (Info, Id);
/* If not found return NULL */
if (S == 0) {
return 0;
}
/* Allocate memory for the data structure returned to the caller */
D = new_cc65_segmentinfo (1);
/* Fill in the data */
CopySegInfo (D->data, S);
/* Return the result */
return D;
}
void cc65_free_segmentinfo (cc65_dbginfo Handle, cc65_segmentinfo* Info) void cc65_free_segmentinfo (cc65_dbginfo Handle, cc65_segmentinfo* Info)
/* Free a segment info record */ /* Free a segment info record */
{ {
@ -3305,6 +3415,12 @@ void cc65_free_segmentinfo (cc65_dbginfo Handle, cc65_segmentinfo* Info)
/*****************************************************************************/
/* Symbols */
/*****************************************************************************/
cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo Handle, const char* Name) cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo Handle, const char* Name)
/* Return a list of symbols with a given name. The function returns NULL if /* Return a list of symbols with a given name. The function returns NULL if
* no symbol with this name was found. * no symbol with this name was found.

View File

@ -46,12 +46,12 @@ extern "C" {
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
/* Data types used for addresses, sizes and line numbers. Change to "unsigned /* Data types used for addresses, sizes and line numbers. Change to "unsigned
* long" if you ever want to run the code on a 16-bit machine. * long" if you ever want to run the code on a 16-bit machine.
*/ */
typedef unsigned cc65_line; /* Used to store line numbers */ typedef unsigned cc65_line; /* Used to store line numbers */
@ -63,6 +63,9 @@ typedef unsigned cc65_size; /* Used to store (65xx) sizes */
*/ */
typedef void* cc65_dbginfo; typedef void* cc65_dbginfo;
/* A value that is used to mark invalid ids */
#define CC65_INV_ID (~0U)
/* Severity for cc65_parseerror */ /* Severity for cc65_parseerror */
typedef enum { typedef enum {
CC65_WARNING, CC65_WARNING,
@ -120,6 +123,7 @@ struct cc65_lineinfo {
/* Source file information */ /* Source file information */
typedef struct cc65_sourcedata cc65_sourcedata; typedef struct cc65_sourcedata cc65_sourcedata;
struct cc65_sourcedata { struct cc65_sourcedata {
unsigned id; /* The internal file id */
const char* source_name; /* Name of the file */ const char* source_name; /* Name of the file */
unsigned long source_size; /* Size of file */ unsigned long source_size; /* Size of file */
unsigned long source_mtime; /* Modification time */ unsigned long source_mtime; /* Modification time */
@ -140,6 +144,7 @@ struct cc65_sourceinfo {
*/ */
typedef struct cc65_segmentdata cc65_segmentdata; typedef struct cc65_segmentdata cc65_segmentdata;
struct cc65_segmentdata { struct cc65_segmentdata {
unsigned id; /* The internal segment id */
const char* segment_name; /* Name of the segment */ const char* segment_name; /* Name of the segment */
cc65_addr segment_start; /* Start address of segment */ cc65_addr segment_start; /* Start address of segment */
cc65_addr segment_size; /* Size of segment */ cc65_addr segment_size; /* Size of segment */
@ -165,6 +170,10 @@ struct cc65_symboldata {
cc65_symbol_type symbol_type; /* Type of symbol */ cc65_symbol_type symbol_type; /* Type of symbol */
cc65_size symbol_size; /* Size of symbol, 0 if unknown */ cc65_size symbol_size; /* Size of symbol, 0 if unknown */
long symbol_value; /* Value of symbol */ long symbol_value; /* Value of symbol */
unsigned symbol_segment; /* If the symbol is segment relative,
* this contains the id of segment,
* otherwise CC65_INV_ID
*/
}; };
typedef struct cc65_symbolinfo cc65_symbolinfo; typedef struct cc65_symbolinfo cc65_symbolinfo;
@ -176,7 +185,7 @@ struct cc65_symbolinfo {
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Debug info files */
/*****************************************************************************/ /*****************************************************************************/
@ -192,6 +201,14 @@ cc65_dbginfo cc65_read_dbginfo (const char* filename, cc65_errorfunc errorfunc);
void cc65_free_dbginfo (cc65_dbginfo Handle); void cc65_free_dbginfo (cc65_dbginfo Handle);
/* Free debug information read from a file */ /* Free debug information read from a file */
/*****************************************************************************/
/* Line info */
/*****************************************************************************/
cc65_lineinfo* cc65_lineinfo_byaddr (cc65_dbginfo handle, unsigned long addr); cc65_lineinfo* cc65_lineinfo_byaddr (cc65_dbginfo handle, unsigned long addr);
/* Return line information for the given address. The function returns NULL /* Return line information for the given address. The function returns NULL
* if no line information was found. * if no line information was found.
@ -206,18 +223,55 @@ cc65_lineinfo* cc65_lineinfo_byname (cc65_dbginfo handle, const char* filename,
void cc65_free_lineinfo (cc65_dbginfo handle, cc65_lineinfo* info); void cc65_free_lineinfo (cc65_dbginfo handle, cc65_lineinfo* info);
/* Free line info returned by one of the other functions */ /* Free line info returned by one of the other functions */
/*****************************************************************************/
/* Source files */
/*****************************************************************************/
cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo handle); cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo handle);
/* Return a list of all source files */ /* Return a list of all source files */
cc65_sourceinfo* cc65_sourceinfo_byid (cc65_dbginfo handle, unsigned id);
/* Return information about a source file with a specific id. The function
* returns NULL if the id is invalid (no such source file) and otherwise a
* cc65_sourceinfo structure with one entry that contains the requested
* source file information.
*/
void cc65_free_sourceinfo (cc65_dbginfo handle, cc65_sourceinfo* info); void cc65_free_sourceinfo (cc65_dbginfo handle, cc65_sourceinfo* info);
/* Free a source info record */ /* Free a source info record */
/*****************************************************************************/
/* Segments */
/*****************************************************************************/
cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo handle); cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo handle);
/* Return a list of all segments referenced in the debug information */ /* Return a list of all segments referenced in the debug information */
cc65_segmentinfo* cc65_segmentinfo_byid (cc65_dbginfo handle, unsigned id);
/* Return information about a segment with a specific id. The function returns
* NULL if the id is invalid (no such segment) and otherwise a cc65_segmentinfo
* structure with one entry that contains the requested segment information.
*/
void cc65_free_segmentinfo (cc65_dbginfo handle, cc65_segmentinfo* info); void cc65_free_segmentinfo (cc65_dbginfo handle, cc65_segmentinfo* info);
/* Free a segment info record */ /* Free a segment info record */
/*****************************************************************************/
/* Symbols */
/*****************************************************************************/
cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo handle, const char* name); cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo handle, const char* name);
/* Return a list of symbols with a given name. The function returns NULL if /* Return a list of symbols with a given name. The function returns NULL if
* no symbol with this name was found. * no symbol with this name was found.

View File

@ -39,6 +39,10 @@
static cc65_dbginfo Info;
static void ErrorFunc (const struct cc65_parseerror* E) static void ErrorFunc (const struct cc65_parseerror* E)
/* Handle errors or warnings that occur while parsing a debug file */ /* Handle errors or warnings that occur while parsing a debug file */
{ {
@ -113,9 +117,20 @@ static void PrintLineData (const cc65_linedata* D)
static void PrintSymbolData (const cc65_symboldata* D) static void PrintSymbolData (const cc65_symboldata* D)
/* Print the data for one symbol */ /* Print the data for one symbol */
{ {
printf (" %-20s = %04lX (size %u)\n", char Segment[256] = { 0 }; /* Needs dynamic alloc ### */
D->symbol_name, if (D->symbol_segment != CC65_INV_ID) {
cc65_segmentinfo* I = cc65_segmentinfo_byid (Info, D->symbol_segment);
if (I && I->count == 1) {
sprintf (Segment, "segment=%s,", I->data[0].segment_name);
cc65_free_segmentinfo (Info, I);
}
}
printf (" %-20s = %04lX (%ssize=%u)\n",
D->symbol_name,
D->symbol_value, D->symbol_value,
Segment,
D->symbol_size); D->symbol_size);
} }
@ -176,7 +191,6 @@ static void PrintSymbolInfo (const cc65_symbolinfo* Symbols)
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
const char* Input; const char* Input;
cc65_dbginfo Info;
cc65_sourceinfo* Sources; cc65_sourceinfo* Sources;
cc65_segmentinfo* Segments; cc65_segmentinfo* Segments;
cc65_lineinfo* Lines; cc65_lineinfo* Lines;