Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functions to iterate function names to IPluginDebugInfo #1019

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion include/sp_vm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions vm/legacy-image.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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;
}
Expand Down
10 changes: 10 additions & 0 deletions vm/plugin-runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
2 changes: 2 additions & 0 deletions vm/plugin-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
86 changes: 86 additions & 0 deletions vm/smx-v1-image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,92 @@ SmxV1Image::GetFileName(size_t index) const
return debug_names_ + debug_files_[index].name;
}

template <typename SymbolType, typename DimType>
uint32_t
SmxV1Image::getFunctionCount(const SymbolType* syms) const {
const uint8_t* cursor = reinterpret_cast<const uint8_t*>(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<const SymbolType*>(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;
}

// Count function symbols once.
static uint32_t num_debug_functions = 0;
if (num_debug_functions == 0) {
if (debug_syms_)
num_debug_functions = getFunctionCount<sp_fdbg_symbol_t, sp_fdbg_arraydim_t>(debug_syms_);
else
num_debug_functions = getFunctionCount<sp_u_fdbg_symbol_t, sp_u_fdbg_arraydim_t>(debug_syms_unpacked_);
}
return num_debug_functions;
}

template <typename SymbolType, typename DimType>
const char*
SmxV1Image::getFunctionName(const SymbolType* syms, const char** filename, uint32_t index) const {
const uint8_t* cursor = reinterpret_cast<const uint8_t*>(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<const SymbolType*>(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*
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<smx_rtti_method>(rtti_methods_, index);
if (filename)
*filename = LookupFile(method->pcode_start);
return names_ + method->name;
}

if (debug_syms_) {
return getFunctionName<sp_fdbg_symbol_t, sp_fdbg_arraydim_t>(debug_syms_, filename, index);
} else {
return getFunctionName<sp_u_fdbg_symbol_t, sp_u_fdbg_arraydim_t>(debug_syms_unpacked_, filename, index);
}
}

template <typename SymbolType, typename DimType>
bool
SmxV1Image::getFunctionAddress(const SymbolType* syms, const char* function, ucell_t* funcaddr, uint32_t& index) const
Expand Down
6 changes: 6 additions & 0 deletions vm/smx-v1-image.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -219,6 +221,10 @@ class SmxV1Image
template <typename SymbolType, typename DimType>
const char* lookupFunction(const SymbolType* syms, uint32_t addr) const;
template <typename SymbolType, typename DimType>
uint32_t getFunctionCount(const SymbolType* syms) const;
template <typename SymbolType, typename DimType>
const char* getFunctionName(const SymbolType* syms, const char** filename, uint32_t index) const;
template <typename SymbolType, typename DimType>
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 {
Expand Down
Loading