コード例 #1
0
void sigsegv_handler(int signal, siginfo_t *info, void *raw_context)
{
#ifndef _M_GENERIC
	if (signal != SIGSEGV)
	{
		// We are not interested in other signals - handle it as usual.
		return;
	}
	ucontext_t *context = (ucontext_t *)raw_context;
	int sicode = info->si_code;
	if (sicode != SEGV_MAPERR && sicode != SEGV_ACCERR)
	{
		// Huh? Return.
		return;
	}
	void *fault_memory_ptr = (void *)info->si_addr;

	// Get all the information we can out of the context.
	mcontext_t *ctx = &context->uc_mcontext;
#ifdef _M_X64
	u8 *fault_instruction_ptr = (u8 *)CREG_RIP(ctx);
#else
	u8 *fault_instruction_ptr = (u8 *)CREG_EIP(ctx);
#endif
	if (!JitInterface::IsInCodeSpace(fault_instruction_ptr)) {
		// Let's not prevent debugging.
		return;
	}
	
	u64 bad_address = (u64)fault_memory_ptr;
	u64 memspace_bottom = (u64)Memory::base;
	if (bad_address < memspace_bottom) {
		PanicAlertT("Exception handler - access below memory space. %08llx%08llx",
			bad_address >> 32, bad_address);
	}
コード例 #2
0
ファイル: x64MemTools.cpp プロジェクト: Annovae/Dolphin-Core
	if (bad_address < memspace_bottom) {
		PanicAlertT("Exception handler - access below memory space. %08llx%08llx",
			bad_address >> 32, bad_address);
	}
	u32 em_address = (u32)(bad_address - memspace_bottom);

	// Backpatch time.
	// Seems we'll need to disassemble to get access_type - that work is probably
	// best done and debugged on the Windows side.
	int access_type = 0;

	CONTEXT fake_ctx;

#ifdef _M_X64
	fake_ctx.Rax = CREG_RAX(ctx);
	fake_ctx.Rip = CREG_RIP(ctx);
#else
	fake_ctx.Eax = CREG_EAX(ctx);
	fake_ctx.Eip = CREG_EIP(ctx);
#endif
	const u8 *new_rip = jit->BackPatch(fault_instruction_ptr, access_type, em_address, &fake_ctx);
	if (new_rip)
	{
#ifdef _M_X64
		CREG_RAX(ctx) = fake_ctx.Rax;
		CREG_RIP(ctx) = fake_ctx.Rip;
#else
		CREG_EAX(ctx) = fake_ctx.Eax;
		CREG_EIP(ctx) = fake_ctx.Eip;
#endif
	}