mirror of
https://github.com/cc65/cc65.git
synced 2024-11-19 06:31:31 +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:
parent
c768fc7373
commit
44b829cc01
@ -224,6 +224,7 @@ struct SymInfo {
|
||||
cc65_symbol_type Type; /* Type of symbol */
|
||||
long Value; /* Value of symbol */
|
||||
cc65_size Size; /* Size of symbol */
|
||||
unsigned Segment; /* Id of segment if any */
|
||||
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,
|
||||
cc65_symbol_type Type, cc65_size Size)
|
||||
static SymInfo* NewSymInfo (const StrBuf* Name, long Val,
|
||||
cc65_symbol_type Type, cc65_size Size,
|
||||
unsigned Segment)
|
||||
/* Create a new SymInfo struct, intialize and return it */
|
||||
{
|
||||
/* Allocate memory */
|
||||
SymInfo* S = xmalloc (sizeof (SymInfo) + SB_GetLen (Name));
|
||||
|
||||
/* Initialize it */
|
||||
S->Type = Type;
|
||||
S->Value = Val;
|
||||
S->Size = Size;
|
||||
S->Type = Type;
|
||||
S->Value = Val;
|
||||
S->Size = Size;
|
||||
S->Segment = Segment;
|
||||
memcpy (S->SymName, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
|
||||
|
||||
/* Return it */
|
||||
@ -1357,9 +1360,7 @@ static void FreeDbgInfo (DbgInfo* Info)
|
||||
|
||||
|
||||
static void CopyLineInfo (cc65_linedata* D, const LineInfo* L)
|
||||
/* Copy data from a LineInfo struct to the cc65_linedata struct returned to
|
||||
* the caller.
|
||||
*/
|
||||
/* Copy data from a LineInfo struct to a cc65_linedata struct */
|
||||
{
|
||||
D->source_name = L->File.Info->FileName;
|
||||
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)
|
||||
/* Copy data from a SymInfo struct to the cc65_symboldata struct returned to
|
||||
* the caller.
|
||||
*/
|
||||
static void CopyFileInfo (cc65_sourcedata* D, const FileInfo* F)
|
||||
/* Copy data from a FileInfo struct to a cc65_sourcedata struct */
|
||||
{
|
||||
D->symbol_name = S->SymName;
|
||||
D->symbol_type = S->Type;
|
||||
D->symbol_size = S->Size;
|
||||
D->symbol_value = S->Value;
|
||||
D->id = F->Id;
|
||||
D->source_name = F->FileName;
|
||||
D->source_size = F->Size;
|
||||
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 */
|
||||
ParseError (D, CC65_WARNING, "Unknown keyword \"%s\" - skipping",
|
||||
SB_GetConstBuf (&D->SVal));
|
||||
|
||||
|
||||
/* Skip the identifier */
|
||||
NextToken (D);
|
||||
|
||||
@ -2211,6 +2235,7 @@ static void ParseSym (InputData* D)
|
||||
long Value;
|
||||
cc65_size Size = 0;
|
||||
StrBuf SymName = STRBUF_INITIALIZER;
|
||||
unsigned Segment = CC65_INV_ID;
|
||||
SymInfo* S;
|
||||
enum {
|
||||
ibNone = 0x00,
|
||||
@ -2234,8 +2259,8 @@ static void ParseSym (InputData* D)
|
||||
|
||||
/* Something we know? */
|
||||
if (D->Tok != TOK_ADDRSIZE && D->Tok != TOK_FILE &&
|
||||
D->Tok != TOK_NAME && D->Tok != TOK_SEGMENT&&
|
||||
D->Tok != TOK_SIZE && D->Tok != TOK_TYPE &&
|
||||
D->Tok != TOK_NAME && D->Tok != TOK_SEGMENT&&
|
||||
D->Tok != TOK_SIZE && D->Tok != TOK_TYPE &&
|
||||
D->Tok != TOK_VALUE) {
|
||||
|
||||
/* Try smart error recovery */
|
||||
@ -2286,7 +2311,7 @@ static void ParseSym (InputData* D)
|
||||
if (!IntConstFollows (D)) {
|
||||
goto ErrorExit;
|
||||
}
|
||||
/* ### Drop value for now */
|
||||
Segment = (unsigned) D->IVal;
|
||||
InfoBits |= ibSegment;
|
||||
NextToken (D);
|
||||
break;
|
||||
@ -2355,7 +2380,7 @@ static void ParseSym (InputData* D)
|
||||
}
|
||||
|
||||
/* 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->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 */
|
||||
{
|
||||
/* Get a pointer to the segment info collection */
|
||||
Collection* SegInfos = &D->Info->SegInfoById;
|
||||
Collection* SegInfos = &D->SegInfoById;
|
||||
|
||||
/* Do a binary search */
|
||||
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 */
|
||||
{
|
||||
/* Get a pointer to the collection */
|
||||
Collection* FileInfos = &D->FileInfoById;
|
||||
|
||||
/* Do a binary search */
|
||||
int Lo = 0;
|
||||
int Hi = (int) CollCount (FileInfos) - 1;
|
||||
@ -2637,7 +2665,7 @@ static void ProcessLineInfo (InputData* D)
|
||||
if (LastFileInfo && LastFileInfo->Id == L->File.Id) {
|
||||
F = LastFileInfo;
|
||||
} 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
|
||||
* remove the line info.
|
||||
@ -2665,7 +2693,7 @@ static void ProcessLineInfo (InputData* D)
|
||||
if (LastSegInfo && LastSegInfo->Id == L->Seg.Id) {
|
||||
S = LastSegInfo;
|
||||
} 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
|
||||
* 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)
|
||||
/* Return line information for the given address. The function returns 0
|
||||
* 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)
|
||||
/* Return a list of all source files */
|
||||
{
|
||||
@ -3226,9 +3266,7 @@ cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo Handle)
|
||||
}
|
||||
|
||||
/* Copy the data */
|
||||
D->data[D->count].source_name = F->FileName;
|
||||
D->data[D->count].source_size = F->Size;
|
||||
D->data[D->count].source_mtime = F->MTime;
|
||||
CopyFileInfo (D->data + D->count, F);
|
||||
|
||||
/* One more valid entry */
|
||||
++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)
|
||||
/* 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)
|
||||
/* 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 */
|
||||
D->count = CollCount (SegInfoByName);
|
||||
for (I = 0; I < CollCount (SegInfoByName); ++I) {
|
||||
|
||||
/* Get this item */
|
||||
const SegInfo* S = CollAt (SegInfoByName, I);
|
||||
|
||||
/* Copy the data */
|
||||
D->data[I].segment_name = S->SegName;
|
||||
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;
|
||||
CopySegInfo (D->data + I, CollAt (SegInfoByName, I));
|
||||
}
|
||||
|
||||
/* 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)
|
||||
/* 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)
|
||||
/* Return a list of symbols with a given name. The function returns NULL if
|
||||
* no symbol with this name was found.
|
||||
|
@ -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.
|
||||
*/
|
||||
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;
|
||||
|
||||
/* A value that is used to mark invalid ids */
|
||||
#define CC65_INV_ID (~0U)
|
||||
|
||||
/* Severity for cc65_parseerror */
|
||||
typedef enum {
|
||||
CC65_WARNING,
|
||||
@ -120,6 +123,7 @@ struct cc65_lineinfo {
|
||||
/* Source file information */
|
||||
typedef struct cc65_sourcedata cc65_sourcedata;
|
||||
struct cc65_sourcedata {
|
||||
unsigned id; /* The internal file id */
|
||||
const char* source_name; /* Name of the file */
|
||||
unsigned long source_size; /* Size of file */
|
||||
unsigned long source_mtime; /* Modification time */
|
||||
@ -140,6 +144,7 @@ struct cc65_sourceinfo {
|
||||
*/
|
||||
typedef struct cc65_segmentdata cc65_segmentdata;
|
||||
struct cc65_segmentdata {
|
||||
unsigned id; /* The internal segment id */
|
||||
const char* segment_name; /* Name of the segment */
|
||||
cc65_addr segment_start; /* Start address 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_size symbol_size; /* Size of symbol, 0 if unknown */
|
||||
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;
|
||||
@ -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);
|
||||
/* Free debug information read from a file */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Line info */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
cc65_lineinfo* cc65_lineinfo_byaddr (cc65_dbginfo handle, unsigned long addr);
|
||||
/* Return line information for the given address. The function returns NULL
|
||||
* 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);
|
||||
/* Free line info returned by one of the other functions */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Source files */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
cc65_sourceinfo* cc65_get_sourcelist (cc65_dbginfo handle);
|
||||
/* 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);
|
||||
/* Free a source info record */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Segments */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo handle);
|
||||
/* 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);
|
||||
/* Free a segment info record */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Symbols */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
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
|
||||
* no symbol with this name was found.
|
||||
|
@ -39,6 +39,10 @@
|
||||
|
||||
|
||||
|
||||
static cc65_dbginfo Info;
|
||||
|
||||
|
||||
|
||||
static void ErrorFunc (const struct cc65_parseerror* E)
|
||||
/* 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)
|
||||
/* Print the data for one symbol */
|
||||
{
|
||||
printf (" %-20s = %04lX (size %u)\n",
|
||||
D->symbol_name,
|
||||
char Segment[256] = { 0 }; /* Needs dynamic alloc ### */
|
||||
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,
|
||||
Segment,
|
||||
D->symbol_size);
|
||||
}
|
||||
|
||||
@ -176,7 +191,6 @@ static void PrintSymbolInfo (const cc65_symbolinfo* Symbols)
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
const char* Input;
|
||||
cc65_dbginfo Info;
|
||||
cc65_sourceinfo* Sources;
|
||||
cc65_segmentinfo* Segments;
|
||||
cc65_lineinfo* Lines;
|
||||
|
Loading…
Reference in New Issue
Block a user