From 5185822dcfcff08d63695633b281e1bbe7325958 Mon Sep 17 00:00:00 2001 From: peace-maker Date: Sun, 5 Jan 2025 22:51:00 +0100 Subject: [PATCH] Support pre-RTTI debug symbol information Allow to use the API on old .smx binaries too. --- vm/smx-v1-image.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++-- vm/smx-v1-image.h | 4 +++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/vm/smx-v1-image.cpp b/vm/smx-v1-image.cpp index bdabc60e..5a5ae0f5 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 {