First semi-successful ld65 debug symbol import
This commit is contained in:
parent
e0aa5a71fa
commit
b33b27c25b
|
@ -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;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
44
src/types.h
44
src/types.h
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue