Move the debug return stack into PluginContext.
This commit is contained in:
parent
8c35d79576
commit
37af05c456
@ -18,7 +18,10 @@ def setup(binary):
|
||||
compiler = binary.compiler
|
||||
compiler.includes += Includes
|
||||
if compiler.vendor == 'gcc' or compiler.vendor == 'clang':
|
||||
compiler.cxxflags += ['-fno-rtti']
|
||||
compiler.cxxflags += [
|
||||
'-fno-rtti',
|
||||
'-Wno-invalid-offsetof',
|
||||
]
|
||||
elif binary.compiler.vendor == 'msvc':
|
||||
compiler.cxxflags += ['/GR-']
|
||||
|
||||
|
@ -20,6 +20,7 @@ using namespace SourcePawn;
|
||||
|
||||
CContextTrace::CContextTrace(PluginRuntime *pRuntime, int err, const char *errstr, cell_t start_rp)
|
||||
: m_pRuntime(pRuntime),
|
||||
context_(pRuntime->GetBaseContext()),
|
||||
m_Error(err),
|
||||
m_pMsg(errstr),
|
||||
m_StartRp(start_rp),
|
||||
@ -66,20 +67,18 @@ CContextTrace::GetTraceInfo(CallStackInfo *trace)
|
||||
|
||||
if (m_Level == 0) {
|
||||
cip = m_ctx->cip;
|
||||
} else if (m_ctx->rp > 0) {
|
||||
} else if (context_->rp() > 0) {
|
||||
/* Entries go from ctx.rp - 1 to m_StartRp */
|
||||
cell_t offs, start, end;
|
||||
|
||||
offs = m_Level - 1;
|
||||
start = m_ctx->rp - 1;
|
||||
start = context_->rp() - 1;
|
||||
end = m_StartRp;
|
||||
|
||||
if (start - offs < end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cip = m_ctx->rstk_cips[start - offs];
|
||||
cip = context_->getReturnStackCip(start - offs);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <sp_vm_api.h>
|
||||
|
||||
class PluginRuntime;
|
||||
class PluginContext;
|
||||
|
||||
namespace sp {
|
||||
|
||||
@ -37,6 +38,7 @@ class CContextTrace : public IContextTrace
|
||||
|
||||
private:
|
||||
PluginRuntime *m_pRuntime;
|
||||
PluginContext *context_;
|
||||
sp_context_t *m_ctx;
|
||||
int m_Error;
|
||||
const char *m_pMsg;
|
||||
|
@ -236,7 +236,8 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
|
||||
if (!IsValidOffset(aCodeStart) || aCodeStart > plugin->pcode_size)
|
||||
return SP_ERROR_INVALID_INSTRUCTION;
|
||||
|
||||
sp_context_t *ctx = rt->GetBaseContext()->GetCtx();
|
||||
PluginContext *cx = rt->GetBaseContext();
|
||||
sp_context_t *ctx = cx->GetCtx();
|
||||
ctx->err = SP_ERROR_NONE;
|
||||
|
||||
// Save the original frm. BaseContext won't, and if we error, we won't hit
|
||||
@ -889,14 +890,12 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ctx->rp >= SP_MAX_RETURN_STACK) {
|
||||
// For debugging.
|
||||
uintptr_t rcip = uintptr_t(cip - 2) - uintptr_t(plugin->pcode);
|
||||
if (!cx->pushReturnCip(rcip)) {
|
||||
ctx->err = SP_ERROR_STACKLOW;
|
||||
goto error;
|
||||
}
|
||||
|
||||
// For debugging.
|
||||
uintptr_t rcip = uintptr_t(cip - 2) - uintptr_t(plugin->pcode);
|
||||
ctx->rstk_cips[ctx->rp++] = rcip;
|
||||
ctx->cip = offset;
|
||||
ctx->sp = uintptr_t(stk) - uintptr_t(plugin->memory);
|
||||
|
||||
@ -904,7 +903,7 @@ Interpret(PluginRuntime *rt, uint32_t aCodeStart, cell_t *rval)
|
||||
|
||||
stk = reinterpret_cast<cell_t *>(plugin->memory + ctx->sp);
|
||||
ctx->cip = rcip;
|
||||
ctx->rp--;
|
||||
cx->popReturnCip();
|
||||
|
||||
if (err != SP_ERROR_NONE)
|
||||
goto error;
|
||||
|
@ -85,8 +85,6 @@ typedef struct sp_context_s
|
||||
sp_plugin_t *plugin;
|
||||
PluginContext *basecx;
|
||||
void * vm[8]; /**< VM-specific pointers */
|
||||
cell_t rp; /**< Return stack pointer */
|
||||
cell_t rstk_cips[SP_MAX_RETURN_STACK];
|
||||
} sp_context_t;
|
||||
|
||||
//#define SPFLAG_PLUGIN_DEBUG (1<<0)
|
||||
|
@ -56,7 +56,7 @@ PluginContext::PluginContext(PluginRuntime *pRuntime)
|
||||
m_ctx.frm = m_ctx.sp;
|
||||
m_ctx.n_err = SP_ERROR_NONE;
|
||||
m_ctx.n_idx = SP_ERROR_NONE;
|
||||
m_ctx.rp = 0;
|
||||
rp_ = 0;
|
||||
|
||||
m_ctx.tracker = new tracker_t;
|
||||
m_ctx.tracker->pBase = (ucell_t *)malloc(1024);
|
||||
@ -584,7 +584,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
|
||||
save_hp = m_ctx.hp;
|
||||
save_exec = m_InExec;
|
||||
save_n_idx = m_ctx.n_idx;
|
||||
save_rp = m_ctx.rp;
|
||||
save_rp = rp_;
|
||||
save_cip = m_ctx.cip;
|
||||
|
||||
/* Push parameters */
|
||||
@ -628,10 +628,10 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
|
||||
m_ctx.hp,
|
||||
save_hp);
|
||||
}
|
||||
if (m_ctx.rp != save_rp) {
|
||||
if (rp_ != save_rp) {
|
||||
ir = SP_ERROR_STACKLEAK;
|
||||
_SetErrorMessage("Return stack leak detected: rp:%d should be %d!",
|
||||
m_ctx.rp,
|
||||
rp_,
|
||||
save_rp);
|
||||
}
|
||||
}
|
||||
@ -644,7 +644,7 @@ PluginContext::Execute2(IPluginFunction *function, const cell_t *params, unsigne
|
||||
|
||||
m_ctx.sp = save_sp;
|
||||
m_ctx.hp = save_hp;
|
||||
m_ctx.rp = save_rp;
|
||||
rp_ = save_rp;
|
||||
|
||||
m_ctx.cip = save_cip;
|
||||
m_ctx.n_idx = save_n_idx;
|
||||
|
@ -76,6 +76,31 @@ class PluginContext : public IPluginContext
|
||||
public:
|
||||
bool IsInExec();
|
||||
|
||||
static inline size_t offsetOfRp() {
|
||||
return offsetof(PluginContext, rp_);
|
||||
}
|
||||
static inline size_t offsetOfRstkCips() {
|
||||
return offsetof(PluginContext, rstk_cips_);
|
||||
}
|
||||
|
||||
bool pushReturnCip(cell_t cip) {
|
||||
if (rp_ >= SP_MAX_RETURN_STACK)
|
||||
return false;
|
||||
rstk_cips_[rp_++] = cip;
|
||||
return true;
|
||||
}
|
||||
void popReturnCip() {
|
||||
assert(rp_ > 0);
|
||||
rp_--;
|
||||
}
|
||||
cell_t rp() const {
|
||||
return rp_;
|
||||
}
|
||||
cell_t getReturnStackCip(int index) {
|
||||
assert(index >= 0 && index < SP_MAX_RETURN_STACK);
|
||||
return rstk_cips_[index];
|
||||
}
|
||||
|
||||
private:
|
||||
void SetErrorMessage(const char *msg, va_list ap);
|
||||
void _SetErrorMessage(const char *msg, ...);
|
||||
@ -90,6 +115,10 @@ class PluginContext : public IPluginContext
|
||||
sp_context_t m_ctx;
|
||||
void *m_keys[4];
|
||||
bool m_keys_set[4];
|
||||
|
||||
// Return stack.
|
||||
cell_t rp_;
|
||||
cell_t rstk_cips_[SP_MAX_RETURN_STACK];
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEPAWN_BASECONTEXT_H_
|
||||
|
@ -1462,8 +1462,8 @@ Compiler::emitCall()
|
||||
|
||||
// eax = context
|
||||
// ecx = rp
|
||||
__ movl(eax, intptr_t(rt_->GetBaseContext()->GetCtx()));
|
||||
__ movl(ecx, Operand(eax, offsetof(sp_context_t, rp)));
|
||||
__ movl(eax, intptr_t(rt_->GetBaseContext()));
|
||||
__ movl(ecx, Operand(eax, PluginContext::offsetOfRp()));
|
||||
|
||||
// Check if the return stack is used up.
|
||||
__ cmpl(ecx, SP_MAX_RETURN_STACK);
|
||||
@ -1471,10 +1471,10 @@ Compiler::emitCall()
|
||||
|
||||
// Add to the return stack.
|
||||
uintptr_t cip = uintptr_t(cip_ - 2) - uintptr_t(plugin_->pcode);
|
||||
__ movl(Operand(eax, ecx, ScaleFour, offsetof(sp_context_t, rstk_cips)), cip);
|
||||
__ movl(Operand(eax, ecx, ScaleFour, PluginContext::offsetOfRstkCips()), cip);
|
||||
|
||||
// Increment the return stack pointer.
|
||||
__ addl(Operand(eax, offsetof(sp_context_t, rp)), 1);
|
||||
__ addl(Operand(eax, PluginContext::offsetOfRp()), 1);
|
||||
|
||||
// Store the CIP of the function we're about to call.
|
||||
__ movl(Operand(cipAddr()), offset);
|
||||
@ -1495,8 +1495,8 @@ Compiler::emitCall()
|
||||
__ movl(Operand(cipAddr()), cip);
|
||||
|
||||
// Mark us as leaving the last frame.
|
||||
__ movl(tmp, intptr_t(rt_->GetBaseContext()->GetCtx()));
|
||||
__ subl(Operand(tmp, offsetof(sp_context_t, rp)), 1);
|
||||
__ movl(tmp, intptr_t(rt_->GetBaseContext()));
|
||||
__ subl(Operand(tmp, PluginContext::offsetOfRp()), 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user