diff --git a/public/sourcepawn/sp_file_headers.h b/public/sourcepawn/sp_file_headers.h index 05d157f2..d1a411a8 100644 --- a/public/sourcepawn/sp_file_headers.h +++ b/public/sourcepawn/sp_file_headers.h @@ -57,7 +57,7 @@ #endif #define SPFILE_MAGIC 0x53504646 /**< Source Pawn File Format (SPFF) */ -#define SPFILE_VERSION 0x0101 /**< Uncompressed bytecode */ +#define SPFILE_VERSION 0x0102 /**< File format version */ //:TODO: better compiler/nix support #if defined __linux__ @@ -266,4 +266,40 @@ typedef struct fp_fdbg_ntvarg_s #pragma pack(pop) /* reset previous packing */ #endif +/** + * Okay, my mistake here. I apologize. I changed the packing by accident and there is no + * version bump aside from the presence of the native debug table. Cat's out of the bag + * for SourceMod and we have no choice but to shim compat for the old version. For people + * parsing plugins on their own, use the presence of the native debug table to decide this. + * If there are no natives (really, there is a very very low chance of this), heuristics + * might be necessary. I've bumped the version to 0x0102 but there may have been plugins + * in the 0x0101 window with no natives. + */ + +/** + * @brief Unpacked file-encoded debug symbol array dimension info. + */ +typedef struct sp_u_fdbg_arraydim_s +{ + int16_t tagid; /**< Tag id */ + uint32_t size; /**< Size of dimension */ +} sp_u_fdbg_arraydim_t; + +/** + * @brief Unpacked file-encoded debug symbol information. + */ +typedef struct sp_u_fdbg_symbol_s +{ + int32_t addr; /**< Address rel to DAT or stack frame */ + int16_t tagid; /**< Tag id */ + uint32_t codestart; /**< Start scope validity in code */ + uint32_t codeend; /**< End scope validity in code */ + uint8_t ident; /**< Variable type */ + uint8_t vclass; /**< Scope class (local vs global) */ + uint16_t dimcount; /**< Dimension count (for arrays) */ + uint32_t name; /**< Offset into debug nametable */ +} sp_u_fdbg_symbol_t; + + #endif //_INCLUDE_SPFILE_HEADERS_H + diff --git a/sourcepawn/jit/BaseRuntime.cpp b/sourcepawn/jit/BaseRuntime.cpp index c3956eff..a4d88def 100644 --- a/sourcepawn/jit/BaseRuntime.cpp +++ b/sourcepawn/jit/BaseRuntime.cpp @@ -69,6 +69,11 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base) plugin->base_size = hdr->imagesize; set_err = SP_ERROR_NONE; + if (hdr->version == 0x0101) + { + plugin->debug.unpacked = true; + } + /* We have to read the name section first */ for (sectnum = 0; sectnum < hdr->sections; sectnum++) { @@ -195,6 +200,10 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base) { plugin->debug.stringbase = (const char *)(base + secptr->dataoffs); } + else if (strcmp(nameptr, ".dbg.natives") == 0) + { + plugin->debug.unpacked = false; + } secptr++; sectnum++; diff --git a/sourcepawn/jit/engine2.cpp b/sourcepawn/jit/engine2.cpp index 43aeff68..4793611c 100644 --- a/sourcepawn/jit/engine2.cpp +++ b/sourcepawn/jit/engine2.cpp @@ -88,7 +88,6 @@ IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file } } - pRuntime = new BaseRuntime(); if ((error = pRuntime->CreateFromMemory(&hdr, base)) != SP_ERROR_NONE) { diff --git a/sourcepawn/jit/jit_shared.h b/sourcepawn/jit/jit_shared.h index 14b32940..59dc780e 100644 --- a/sourcepawn/jit/jit_shared.h +++ b/sourcepawn/jit/jit_shared.h @@ -19,6 +19,7 @@ typedef struct sp_plugin_debug_s sp_fdbg_line_t *lines; /**< lines table */ uint32_t syms_num; /**< number of symbols */ sp_fdbg_symbol_t *symbols; /**< symbol table */ + bool unpacked; /**< Whether debug structures are unpacked */ } sp_plugin_debug_t; class BaseContext; diff --git a/sourcepawn/jit/sp_vm_basecontext.cpp b/sourcepawn/jit/sp_vm_basecontext.cpp index 929c08cc..7fa902fe 100644 --- a/sourcepawn/jit/sp_vm_basecontext.cpp +++ b/sourcepawn/jit/sp_vm_basecontext.cpp @@ -742,37 +742,72 @@ int DebugInfo::LookupFile(ucell_t addr, const char **filename) int DebugInfo::LookupFunction(ucell_t addr, const char **name) { - uint32_t max, iter; - sp_fdbg_symbol_t *sym; - sp_fdbg_arraydim_t *arr; - uint8_t *cursor = (uint8_t *)(m_pPlugin->debug.symbols); - - max = m_pPlugin->debug.syms_num; - for (iter = 0; iter < max; iter++) + if (!m_pPlugin->debug.unpacked) { - sym = (sp_fdbg_symbol_t *)cursor; + uint32_t max, iter; + sp_fdbg_symbol_t *sym; + sp_fdbg_arraydim_t *arr; + uint8_t *cursor = (uint8_t *)(m_pPlugin->debug.symbols); - if (sym->ident == SP_SYM_FUNCTION - && sym->codestart <= addr - && sym->codeend > addr) + max = m_pPlugin->debug.syms_num; + for (iter = 0; iter < max; iter++) { - *name = m_pPlugin->debug.stringbase + sym->name; - return SP_ERROR_NONE; - } + sym = (sp_fdbg_symbol_t *)cursor; + + if (sym->ident == SP_SYM_FUNCTION + && sym->codestart <= addr + && sym->codeend > addr) + { + *name = m_pPlugin->debug.stringbase + sym->name; + return SP_ERROR_NONE; + } + + if (sym->dimcount > 0) + { + cursor += sizeof(sp_fdbg_symbol_t); + arr = (sp_fdbg_arraydim_t *)cursor; + cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount; + continue; + } - if (sym->dimcount > 0) - { cursor += sizeof(sp_fdbg_symbol_t); - arr = (sp_fdbg_arraydim_t *)cursor; - cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount; - continue; } - cursor += sizeof(sp_fdbg_symbol_t); + return SP_ERROR_NOT_FOUND; } + else + { + uint32_t max, iter; + sp_u_fdbg_symbol_t *sym; + sp_u_fdbg_arraydim_t *arr; + uint8_t *cursor = (uint8_t *)(m_pPlugin->debug.symbols); - return SP_ERROR_NOT_FOUND; + max = m_pPlugin->debug.syms_num; + for (iter = 0; iter < max; iter++) + { + sym = (sp_u_fdbg_symbol_t *)cursor; + if (sym->ident == SP_SYM_FUNCTION + && sym->codestart <= addr + && sym->codeend > addr) + { + *name = m_pPlugin->debug.stringbase + sym->name; + return SP_ERROR_NONE; + } + + if (sym->dimcount > 0) + { + cursor += sizeof(sp_u_fdbg_symbol_t); + arr = (sp_u_fdbg_arraydim_t *)cursor; + cursor += sizeof(sp_u_fdbg_arraydim_t) * sym->dimcount; + continue; + } + + cursor += sizeof(sp_u_fdbg_symbol_t); + } + + return SP_ERROR_NOT_FOUND; + } } int DebugInfo::LookupLine(ucell_t addr, uint32_t *line) diff --git a/sourcepawn/jit/x86/jit_x86.cpp b/sourcepawn/jit/x86/jit_x86.cpp index eeada3f2..27ad9e09 100644 --- a/sourcepawn/jit/x86/jit_x86.cpp +++ b/sourcepawn/jit/x86/jit_x86.cpp @@ -1344,32 +1344,65 @@ void ProfCallGate_End(sp_context_t *ctx) const char *find_func_name(sp_plugin_t *plugin, uint32_t offs) { - uint32_t max, iter; - sp_fdbg_symbol_t *sym; - sp_fdbg_arraydim_t *arr; - uint8_t *cursor = (uint8_t *)(plugin->debug.symbols); - - max = plugin->debug.syms_num; - for (iter = 0; iter < max; iter++) + if (!plugin->debug.unpacked) { - sym = (sp_fdbg_symbol_t *)cursor; + uint32_t max, iter; + sp_fdbg_symbol_t *sym; + sp_fdbg_arraydim_t *arr; + uint8_t *cursor = (uint8_t *)(plugin->debug.symbols); - if (sym->ident == SP_SYM_FUNCTION - && sym->codestart <= offs - && sym->codeend > offs) + max = plugin->debug.syms_num; + for (iter = 0; iter < max; iter++) { - return plugin->debug.stringbase + sym->name; - } + sym = (sp_fdbg_symbol_t *)cursor; + + if (sym->ident == SP_SYM_FUNCTION + && sym->codestart <= offs + && sym->codeend > offs) + { + return plugin->debug.stringbase + sym->name; + } + + if (sym->dimcount > 0) + { + cursor += sizeof(sp_fdbg_symbol_t); + arr = (sp_fdbg_arraydim_t *)cursor; + cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount; + continue; + } - if (sym->dimcount > 0) - { cursor += sizeof(sp_fdbg_symbol_t); - arr = (sp_fdbg_arraydim_t *)cursor; - cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount; - continue; } + } + else + { + uint32_t max, iter; + sp_u_fdbg_symbol_t *sym; + sp_u_fdbg_arraydim_t *arr; + uint8_t *cursor = (uint8_t *)(plugin->debug.symbols); - cursor += sizeof(sp_fdbg_symbol_t); + max = plugin->debug.syms_num; + for (iter = 0; iter < max; iter++) + { + sym = (sp_u_fdbg_symbol_t *)cursor; + + if (sym->ident == SP_SYM_FUNCTION + && sym->codestart <= offs + && sym->codeend > offs) + { + return plugin->debug.stringbase + sym->name; + } + + if (sym->dimcount > 0) + { + cursor += sizeof(sp_u_fdbg_symbol_t); + arr = (sp_u_fdbg_arraydim_t *)cursor; + cursor += sizeof(sp_u_fdbg_arraydim_t) * sym->dimcount; + continue; + } + + cursor += sizeof(sp_u_fdbg_symbol_t); + } } return NULL;