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