First semi-successful ld65 debug symbol import

This commit is contained in:
harry 2023-02-12 22:21:05 -05:00
parent e0aa5a71fa
commit b33b27c25b
5 changed files with 216 additions and 31 deletions

View File

@ -911,6 +911,69 @@ const char *debugSymbolTable_t::errorMessage(void)
return dbgSymTblErrMsg;
}
//--------------------------------------------------------------
static void ld65_iterate_cb( void *userData, ld65::sym *s )
{
debugSymbolTable_t *tbl = static_cast<debugSymbolTable_t*>(userData);
if (tbl)
{
tbl->ld65_SymbolLoad(s);
}
}
//--------------------------------------------------------------
void debugSymbolTable_t::ld65_SymbolLoad( ld65::sym *s )
{
int bank = -1;
debugSymbol_t *sym;
debugSymbolPage_t *page;
ld65::scope *scope = s->getScope();
ld65::segment *seg = s->getSegment();
if ( s->type() == ld65::sym::LABEL )
{
//printf("Symbol Label Load: name:\"%s\" val:%i 0x%x\n", s->name(), s->value(), s->value() );
if (seg)
{
int romAddr = seg->ofs();
bank = romAddr >= 0 ? romAddr / (1<<debuggerPageSize) : -1;
//printf(" Seg: name:'%s' ofs:%i Bank:%x\n", seg->name(), romAddr, bank );
}
printf("\n");
auto pageIt = pageMap.find(bank);
if (pageIt == pageMap.end() )
{
page = new debugSymbolPage_t(bank);
pageMap[bank] = page;
}
else
{
page = pageIt->second;
}
std::string name;
if (scope)
{
scope->getFullName(name);
}
name.append(s->name());
//printf("Creating Symbol: %s\n", name.c_str() );
sym = new debugSymbol_t( s->value(), name.c_str() );
if ( page->addSymbol( sym ) )
{
//printf("Failed to load sym: '%s'\n", s->name() );
delete sym;
}
}
}
//--------------------------------------------------------------
int debugSymbolTable_t::ld65LoadDebugFile( const char *dbgFilePath )
{
ld65::database db;
@ -919,6 +982,9 @@ int debugSymbolTable_t::ld65LoadDebugFile( const char *dbgFilePath )
{
return -1;
}
db.iterateSymbols( this, ld65_iterate_cb );
return 0;
}
//--------------------------------------------------------------

View File

@ -5,6 +5,7 @@
#include <map>
#include "utils/mutex.h"
#include "ld65dbg.h"
class debugSymbolPage_t;
class debugSymbolTable_t;
@ -155,6 +156,8 @@ class debugSymbolTable_t
int ld65LoadDebugFile( const char *dbgFilePath );
void ld65_SymbolLoad( ld65::sym *s );
private:
std::map <int, debugSymbolPage_t*> pageMap;
FCEU::mutex *cs;

View File

@ -21,8 +21,21 @@ namespace ld65
{
}
//---------------------------------------------------------------------------------------------------
sym::sym(int id, const char *name, int size)
: _name(name ? name : ""), _id(id), _size(size), _scope(nullptr)
void scope::getFullName(std::string &out)
{
if ( _parent )
{
_parent->getFullName(out);
}
if (!_name.empty())
{
out.append(_name);
out.append("::");
}
}
//---------------------------------------------------------------------------------------------------
sym::sym(int id, const char *name, int size, int value, int type)
: _name(name ? name : ""), _id(id), _size(size), _value(value), _type(type), _scope(nullptr), _segment(nullptr)
{
}
//---------------------------------------------------------------------------------------------------
@ -253,7 +266,7 @@ namespace ld65
FILE *fp;
dbgLine line( lineSize );
char lineType[64];
fceuScopedPtr <char> keyValueBuffer( new char[ lineSize ], fceuScopedPtr<char>::NewArray );
fceuScopedPtr <char> keyValueBuffer( new char[ lineSize ], FCEU_ALLOC_TYPE_NEW_ARRAY );
fp = ::fopen( dbgFilePath, "r");
@ -264,14 +277,18 @@ namespace ld65
while ( line.readFromFile(fp) != NULL )
{
printf("%s", line.getLine());
//printf("%s", line.getLine());
if ( line.readToken( lineType, sizeof(lineType) ) )
{
int id = -1, size = 0, parentID = -1, scopeID = -1;
int id = -1, size = 0, startAddr = 0, ofs = -1, parentID = -1, scopeID = -1, segmentID = -1;
int value = 0;
unsigned char segType = segment::READ;
char name[256];
char type[32];
name[0] = 0;
type[0] = 0;
while ( line.readKeyValuePair( keyValueBuffer.get(), lineSize) )
{
@ -279,7 +296,7 @@ namespace ld65
line.splitKeyValuePair( keyValueBuffer.get(), &key, &val );
printf(" Key '%s' -> Value '%s' \n", key, val );
//printf(" Key '%s' -> Value '%s' \n", key, val );
if ( strcmp( key, "id") == 0 )
{
@ -293,17 +310,42 @@ namespace ld65
{
size = strtol( val, nullptr, 0 );
}
else if ( strcmp( key, "val") == 0 )
{
value = strtol( val, nullptr, 0 );
}
else if ( strcmp( key, "scope") == 0 )
{
scopeID = strtol( val, nullptr, 0 );
}
else if ( strcmp( key, "scope") == 0 )
else if ( strcmp( key, "parent") == 0 )
{
parentID = strtol( val, nullptr, 0 );
}
else if ( strcmp( key, "seg") == 0 )
{
segmentID = strtol( val, nullptr, 0 );
}
else if ( strcmp( key, "ooffs") == 0 )
{
ofs = strtol( val, nullptr, 0 );
}
else if ( strcmp( key, "type") == 0 )
{
strncpy( type, val, sizeof(type));
}
}
if ( strcmp( lineType, "scope" ) == 0 )
if ( strcmp( lineType, "seg" ) == 0 )
{
if ( id >= 0 )
{
segment *s = new segment( id, name, startAddr, size, ofs, segType );
segmentMap[id] = s;
}
}
else if ( strcmp( lineType, "scope" ) == 0 )
{
if ( id >= 0 )
{
@ -315,7 +357,7 @@ namespace ld65
if ( it != scopeMap.end() )
{
printf("Found Parent:%i for %i\n", parentID, id );
//printf("Found Parent:%i for %i\n", parentID, id );
s->_parent = it->second;
}
}
@ -324,15 +366,34 @@ namespace ld65
{
if ( id >= 0 )
{
sym *s = new sym( id, name, size );
int symType = sym::IMPORT;
if ( strcmp( type, "lab") == 0)
{
symType = sym::LABEL;
}
else if ( strcmp( type, "equ") == 0)
{
symType = sym::EQU;
}
sym *s = new sym( id, name, size, value, symType );
auto it = scopeMap.find( scopeID );
if ( it != scopeMap.end() )
{
printf("Found Scope:%i for %s\n", scopeID, name );
//printf("Found Scope:%i for %s\n", scopeID, name );
s->_scope = it->second;
}
auto itSeg = segmentMap.find( segmentID );
if ( itSeg != segmentMap.end() )
{
//printf("Found Segment:%i for %s\n", segmentID, name );
s->_segment = itSeg->second;
}
symMap[id] = s;
}
}
@ -343,4 +404,16 @@ namespace ld65
return 0;
}
//---------------------------------------------------------------------------------------------------
int database::iterateSymbols( void *userData, void (*cb)( void *userData, sym *s ) )
{
int numSyms = 0;
for (auto it = symMap.begin(); it != symMap.end(); it++)
{
cb( userData, it->second );
numSyms++;
}
return numSyms;
}
//---------------------------------------------------------------------------------------------------
}

View File

@ -17,6 +17,12 @@ namespace ld65
segment( int id, const char *name = nullptr, int startAddr = 0, int size = 0, int ofs = -1, unsigned char type = READ );
const char *name(void){ return _name.c_str(); };
int addr(void){ return _startAddr; };
int ofs(void){ return _ofs; };
private:
std::string _name; // Segment Name
int _id; // Debug ID
@ -34,7 +40,12 @@ namespace ld65
public:
scope( int id, const char *name = nullptr, int size = 0, int parentID = -1);
const char *name(void){ return _name.c_str(); };
scope *getParent(void){ return _parent; };
void getFullName( std::string &out );
private:
std::string _name; // Scope Name
int _id; // Debug ID
@ -50,14 +61,36 @@ namespace ld65
class sym
{
public:
sym( int id, const char *name = nullptr, int size = 0);
enum
{
IMPORT = 0,
LABEL,
EQU
};
sym( int id, const char *name = nullptr, int size = 0, int value = 0, int type = IMPORT);
const char *name(void){ return _name.c_str(); };
int size(void){ return _size; };
int value(void){ return _value; };
int type(void){ return _type; };
scope *getScope(void){ return _scope; };
segment *getSegment(void){ return _segment; };
private:
std::string _name; // Scope Name
int _id; // Debug ID
int _size;
int _value;
int _type;
scope *_scope;
scope *_scope;
segment *_segment;
friend class database;
};
@ -70,6 +103,8 @@ namespace ld65
int dbgFileLoad( const char *dbgFilePath );
int iterateSymbols( void *userData, void (*cb)( void *userData, sym *s ) );
private:
std::map<int, scope*> scopeMap;
std::map<int, segment*> segmentMap;

View File

@ -185,17 +185,18 @@ typedef uint8 (*readfunc)(uint32 A);
// Scoped pointer ensures that memory pointed to by this object gets cleaned up
// and deallocated when this object goes out of scope. Helps prevent memory leaks
// on temporary memory allocations in functions with early outs.
enum fceuAllocType
{
FCEU_ALLOC_TYPE_NEW = 0,
FCEU_ALLOC_TYPE_NEW_ARRAY,
FCEU_ALLOC_TYPE_MALLOC
};
template <typename T>
class fceuScopedPtr
{
public:
enum
{
New = 0,
NewArray,
Malloc
};
fceuScopedPtr( T *ptrIn = nullptr, int allocType = New )
fceuScopedPtr( T *ptrIn = nullptr, enum fceuAllocType allocType = FCEU_ALLOC_TYPE_NEW )
{
//printf("Scoped Pointer Constructor <%s>: %p\n", typeid(T).name(), ptrIn );
ptr = ptrIn;
@ -223,17 +224,24 @@ class fceuScopedPtr
{
if (ptr)
{
if (_allocType == Malloc)
switch (_allocType)
{
::free(ptr);
}
else if (_allocType == NewArray)
{
delete [] ptr;
}
else
{
delete ptr;
case FCEU_ALLOC_TYPE_MALLOC:
{
::free(ptr);
}
break;
case FCEU_ALLOC_TYPE_NEW_ARRAY:
{
delete [] ptr;
}
break;
default:
case FCEU_ALLOC_TYPE_NEW:
{
delete ptr;
}
break;
}
ptr = nullptr;
}
@ -241,7 +249,7 @@ class fceuScopedPtr
private:
T *ptr;
int _allocType;
enum fceuAllocType _allocType;
};