diff --git a/vm/smx-v1-image.cpp b/vm/smx-v1-image.cpp index fe5e3f27..35449c5e 100644 --- a/vm/smx-v1-image.cpp +++ b/vm/smx-v1-image.cpp @@ -1060,12 +1060,71 @@ SmxV1Image::GetFileName(size_t index) const return debug_names_ + debug_files_[index].name; } +template +uint32_t +SmxV1Image::getFunctionCount(const SymbolType* syms) const { + const uint8_t* cursor = reinterpret_cast(syms); + const uint8_t* cursor_end = cursor + debug_symbols_section_->size; + uint32_t func_count = 0; + for (uint32_t i = 0; i < debug_info_->num_syms; i++) { + if (cursor + sizeof(SymbolType) > cursor_end) + break; + + const SymbolType* sym = reinterpret_cast(cursor); + if (sym->ident == sp::IDENT_FUNCTION) + func_count++; + + if (sym->dimcount > 0) + cursor += sizeof(DimType) * sym->dimcount; + cursor += sizeof(SymbolType); + } + return func_count; +} + size_t SmxV1Image::NumFunctions() const { if (rtti_methods_) { return rtti_methods_->row_count; } - return 0; + + // Count function symbols once. + static uint32_t num_debug_functions = 0; + if (num_debug_functions == 0) { + if (debug_syms_) + num_debug_functions = getFunctionCount(debug_syms_); + else + num_debug_functions = getFunctionCount(debug_syms_unpacked_); + } + return num_debug_functions; +} + +template +const char* +SmxV1Image::getFunctionName(const SymbolType* syms, const char** filename, uint32_t index) const { + const uint8_t* cursor = reinterpret_cast(syms); + const uint8_t* cursor_end = cursor + debug_symbols_section_->size; + uint32_t func_count = 0; + for (uint32_t i = 0; i < debug_info_->num_syms; i++) { + if (cursor + sizeof(SymbolType) > cursor_end) + break; + + const SymbolType* sym = reinterpret_cast(cursor); + if (sym->ident == sp::IDENT_FUNCTION) { + if (func_count == index) { + if (filename) + *filename = LookupFile(sym->addr); + if (sym->name < debug_names_section_->size) + return debug_names_ + sym->name; + return nullptr; + } + func_count++; + } + + if (sym->dimcount > 0) + cursor += sizeof(DimType) * sym->dimcount; + cursor += sizeof(SymbolType); + } + return nullptr; } const char* @@ -1079,7 +1138,12 @@ SmxV1Image::GetFunctionName(size_t index, const char** filename) const { *filename = LookupFile(method->pcode_start); return names_ + method->name; } - return nullptr; + + if (debug_syms_) { + return getFunctionName(debug_syms_, filename, index); + } else { + return getFunctionName(debug_syms_unpacked_, filename, index); + } } template diff --git a/vm/smx-v1-image.h b/vm/smx-v1-image.h index 454b33c7..6764196d 100644 --- a/vm/smx-v1-image.h +++ b/vm/smx-v1-image.h @@ -221,6 +221,10 @@ class SmxV1Image template const char* lookupFunction(const SymbolType* syms, uint32_t addr) const; template + uint32_t getFunctionCount(const SymbolType* syms) const; + template + const char* getFunctionName(const SymbolType* syms, const char** filename, uint32_t index) const; + template bool getFunctionAddress(const SymbolType* syms, const char* function, ucell_t* funcaddr, uint32_t& index) const; const smx_rtti_table_header* findRttiSection(const char* name) const {