diff --git a/src/debugsymboltable.cpp b/src/debugsymboltable.cpp index 062660aa..7d52d1be 100644 --- a/src/debugsymboltable.cpp +++ b/src/debugsymboltable.cpp @@ -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(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<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; } //-------------------------------------------------------------- diff --git a/src/debugsymboltable.h b/src/debugsymboltable.h index 7deb4586..dbe3052b 100644 --- a/src/debugsymboltable.h +++ b/src/debugsymboltable.h @@ -5,6 +5,7 @@ #include #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 pageMap; FCEU::mutex *cs; diff --git a/src/ld65dbg.cpp b/src/ld65dbg.cpp index 4055b063..7e93417d 100644 --- a/src/ld65dbg.cpp +++ b/src/ld65dbg.cpp @@ -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 keyValueBuffer( new char[ lineSize ], fceuScopedPtr::NewArray ); + fceuScopedPtr 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; + } + //--------------------------------------------------------------------------------------------------- } diff --git a/src/ld65dbg.h b/src/ld65dbg.h index 82b577f1..968adbed 100644 --- a/src/ld65dbg.h +++ b/src/ld65dbg.h @@ -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 scopeMap; std::map segmentMap; diff --git a/src/types.h b/src/types.h index 916ee8bd..61ab0bfa 100644 --- a/src/types.h +++ b/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 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; };