From 5d8aa56de5d20fcbcd200bb99a21afe0bccb7ba0 Mon Sep 17 00:00:00 2001 From: peace-maker Date: Sun, 5 Jan 2025 22:47:06 +0100 Subject: [PATCH] Add functions to iterate function names to IPluginDebugInfo Allow to inspect the list of functions defined in a plugin as well as the corresponding source filename if available and requested. --- include/sp_vm_api.h | 16 +++++++++++++++- vm/legacy-image.h | 8 ++++++++ vm/plugin-runtime.cpp | 10 ++++++++++ vm/plugin-runtime.h | 2 ++ vm/smx-v1-image.cpp | 22 ++++++++++++++++++++++ vm/smx-v1-image.h | 2 ++ 6 files changed, 59 insertions(+), 1 deletion(-) diff --git a/include/sp_vm_api.h b/include/sp_vm_api.h index 4ad040866..6e312a0c2 100644 --- a/include/sp_vm_api.h +++ b/include/sp_vm_api.h @@ -24,7 +24,7 @@ /** SourcePawn Engine API Versions */ #define SOURCEPAWN_ENGINE2_API_VERSION 0x10 -#define SOURCEPAWN_API_VERSION 0x0213 +#define SOURCEPAWN_API_VERSION 0x0214 namespace SourceMod { struct IdentityToken_t; @@ -365,6 +365,20 @@ class IPluginDebugInfo * @return Full file name of source file or NULL if not found. */ virtual const char* GetFileName(size_t index) = 0; + + /** + * @brief Returns the number of functions defined in this plugin. + */ + virtual size_t NumFunctions() = 0; + + /** + * @brief Returns the function name at the given index. + * + * @param index Index of the function in the list of functions. + * @param file Output pointer to store filename where the function is defined in. + * @return Name of the function or NULL if not found. + */ + virtual const char* GetFunctionName(size_t index, const char** file) = 0; }; class ICompilation; diff --git a/vm/legacy-image.h b/vm/legacy-image.h index 24a4668ec..d6c61c92a 100644 --- a/vm/legacy-image.h +++ b/vm/legacy-image.h @@ -59,6 +59,8 @@ class LegacyImage virtual bool LookupLineAddress(const uint32_t line, const char* file, ucell_t* addr) const = 0; virtual size_t NumFiles() const = 0; virtual const char* GetFileName(size_t index) const = 0; + virtual size_t NumFunctions() const = 0; + virtual const char* GetFunctionName(size_t index, const char** filename) const = 0; virtual bool HasRtti() const = 0; virtual const smx_rtti_method* GetMethodRttiByOffset(uint32_t pcode_offset) const = 0; }; @@ -141,6 +143,12 @@ class EmptyImage : public LegacyImage const char* GetFileName(size_t index) const override { return nullptr; } + size_t NumFunctions() const override { + return 0; + } + const char* GetFunctionName(size_t index, const char** filename) const override { + return nullptr; + } const smx_rtti_method* GetMethodRttiByOffset(uint32_t pcode_offset) const override { return nullptr; } diff --git a/vm/plugin-runtime.cpp b/vm/plugin-runtime.cpp index 73bd37c08..733868470 100644 --- a/vm/plugin-runtime.cpp +++ b/vm/plugin-runtime.cpp @@ -598,6 +598,16 @@ PluginRuntime::GetFileName(size_t index) return image_->GetFileName(index); } +size_t +PluginRuntime::NumFunctions() { + return image_->NumFunctions(); +} + +const char* +PluginRuntime::GetFunctionName(size_t index, const char** filename) { + return image_->GetFunctionName(index, filename); +} + int PluginRuntime::LookupFunctionAddress(const char* function, const char* file, ucell_t* addr) { diff --git a/vm/plugin-runtime.h b/vm/plugin-runtime.h index 638cfc2c2..f70abbe16 100644 --- a/vm/plugin-runtime.h +++ b/vm/plugin-runtime.h @@ -84,6 +84,8 @@ class PluginRuntime int LookupFile(ucell_t addr, const char** filename) override; size_t NumFiles() override; const char* GetFileName(size_t index) override; + size_t NumFunctions() override; + const char* GetFunctionName(size_t index, const char** filename) override; int LookupFunctionAddress(const char* function, const char* file, ucell_t* addr) override; int LookupLineAddress(const uint32_t line, const char* file, ucell_t* addr) override; const char* GetFilename() override { diff --git a/vm/smx-v1-image.cpp b/vm/smx-v1-image.cpp index 83c591319..fe5e3f274 100644 --- a/vm/smx-v1-image.cpp +++ b/vm/smx-v1-image.cpp @@ -1060,6 +1060,28 @@ SmxV1Image::GetFileName(size_t index) const return debug_names_ + debug_files_[index].name; } +size_t +SmxV1Image::NumFunctions() const { + if (rtti_methods_) { + return rtti_methods_->row_count; + } + return 0; +} + +const char* +SmxV1Image::GetFunctionName(size_t index, const char** filename) const { + if (rtti_methods_) { + if (index >= rtti_methods_->row_count) + return nullptr; + + const smx_rtti_method* method = getRttiRow(rtti_methods_, index); + if (filename) + *filename = LookupFile(method->pcode_start); + return names_ + method->name; + } + return nullptr; +} + template bool SmxV1Image::getFunctionAddress(const SymbolType* syms, const char* function, ucell_t* funcaddr, uint32_t& index) const diff --git a/vm/smx-v1-image.h b/vm/smx-v1-image.h index 99ef6105a..454b33c72 100644 --- a/vm/smx-v1-image.h +++ b/vm/smx-v1-image.h @@ -69,6 +69,8 @@ class SmxV1Image bool LookupLineAddress(const uint32_t line, const char* file, ucell_t* addr) const override; size_t NumFiles() const override; const char* GetFileName(size_t index) const override; + size_t NumFunctions() const override; + const char* GetFunctionName(size_t index, const char** filename) const override; bool HasRtti() const override; const smx_rtti_method* GetMethodRttiByOffset(uint32_t pcode_offset) const override;