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