update Windows' SEH, fix overflow exception, and non-Windows platform support
This commit is contained in:
parent
64f69f78ae
commit
b5358508d6
|
@ -986,15 +986,8 @@ typedef struct {
|
|||
|
||||
void WINAPI EmuFiberStartup(fiber_context_t* context)
|
||||
{
|
||||
__try
|
||||
{
|
||||
LPFIBER_START_ROUTINE pfStartRoutine = (LPFIBER_START_ROUTINE)context->lpStartRoutine;
|
||||
pfStartRoutine(context->lpParameter);
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter");
|
||||
}
|
||||
LPFIBER_START_ROUTINE pfStartRoutine = (LPFIBER_START_ROUTINE)context->lpStartRoutine;
|
||||
pfStartRoutine(context->lpParameter);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -88,14 +88,8 @@ public:
|
|||
m_Pending = false;
|
||||
}
|
||||
|
||||
__try {
|
||||
BOOLEAN(__stdcall *ServiceRoutine)(xboxkrnl::PKINTERRUPT, void*) = (BOOLEAN(__stdcall *)(xboxkrnl::PKINTERRUPT, void*))Interrupt->ServiceRoutine;
|
||||
BOOLEAN result = ServiceRoutine(Interrupt, Interrupt->ServiceContext);
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLogEx(CXBXR_MODULE::KRNL, LOG_LEVEL::WARNING, "Problem with ExceptionFilter!");
|
||||
}
|
||||
BOOLEAN(__stdcall *ServiceRoutine)(xboxkrnl::PKINTERRUPT, void*) = (BOOLEAN(__stdcall *)(xboxkrnl::PKINTERRUPT, void*))Interrupt->ServiceRoutine;
|
||||
BOOLEAN result = ServiceRoutine(Interrupt, Interrupt->ServiceContext);
|
||||
}
|
||||
private:
|
||||
bool m_Asserted = false;
|
||||
|
|
|
@ -301,17 +301,13 @@ void ExecuteDpcQueue()
|
|||
// Set DpcRoutineActive to support KeIsExecutingDpc:
|
||||
KeGetCurrentPrcb()->DpcRoutineActive = TRUE; // Experimental
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Global DpcQueue, calling DPC at 0x%.8X", pkdpc->DeferredRoutine);
|
||||
__try {
|
||||
// Call the Deferred Procedure :
|
||||
pkdpc->DeferredRoutine(
|
||||
pkdpc,
|
||||
pkdpc->DeferredContext,
|
||||
pkdpc->SystemArgument1,
|
||||
pkdpc->SystemArgument2);
|
||||
} __except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter!");
|
||||
}
|
||||
|
||||
// Call the Deferred Procedure :
|
||||
pkdpc->DeferredRoutine(
|
||||
pkdpc,
|
||||
pkdpc->DeferredContext,
|
||||
pkdpc->SystemArgument1,
|
||||
pkdpc->SystemArgument2);
|
||||
|
||||
KeGetCurrentPrcb()->DpcRoutineActive = FALSE; // Experimental
|
||||
}
|
||||
|
|
|
@ -643,19 +643,14 @@ xboxkrnl::VOID NTAPI xboxkrnl::KiTimerExpiration
|
|||
{
|
||||
/* Call the DPC */
|
||||
EmuLog(LOG_LEVEL::DEBUG, "%s, calling DPC at 0x%.8X", __func__, DpcEntry[i].Routine);
|
||||
__try {
|
||||
// Call the Deferred Procedure :
|
||||
DpcEntry[i].Routine(
|
||||
DpcEntry[i].Dpc,
|
||||
DpcEntry[i].Context,
|
||||
UlongToPtr(SystemTime.u.LowPart),
|
||||
UlongToPtr(SystemTime.u.HighPart)
|
||||
);
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter!");
|
||||
}
|
||||
|
||||
// Call the Deferred Procedure :
|
||||
DpcEntry[i].Routine(
|
||||
DpcEntry[i].Dpc,
|
||||
DpcEntry[i].Context,
|
||||
UlongToPtr(SystemTime.u.LowPart),
|
||||
UlongToPtr(SystemTime.u.HighPart)
|
||||
);
|
||||
}
|
||||
|
||||
/* Reset accounting */
|
||||
|
@ -691,19 +686,14 @@ xboxkrnl::VOID NTAPI xboxkrnl::KiTimerExpiration
|
|||
{
|
||||
/* Call the DPC */
|
||||
EmuLog(LOG_LEVEL::DEBUG, "%s, calling DPC at 0x%.8X", __func__, DpcEntry[i].Routine);
|
||||
__try {
|
||||
// Call the Deferred Procedure :
|
||||
DpcEntry[i].Routine(
|
||||
DpcEntry[i].Dpc,
|
||||
DpcEntry[i].Context,
|
||||
UlongToPtr(SystemTime.u.LowPart),
|
||||
UlongToPtr(SystemTime.u.HighPart)
|
||||
);
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter!");
|
||||
}
|
||||
|
||||
// Call the Deferred Procedure :
|
||||
DpcEntry[i].Routine(
|
||||
DpcEntry[i].Dpc,
|
||||
DpcEntry[i].Context,
|
||||
UlongToPtr(SystemTime.u.LowPart),
|
||||
UlongToPtr(SystemTime.u.HighPart)
|
||||
);
|
||||
}
|
||||
|
||||
/* Reset accounting */
|
||||
|
@ -736,19 +726,14 @@ xboxkrnl::VOID NTAPI xboxkrnl::KiTimerExpiration
|
|||
{
|
||||
/* Call the DPC */
|
||||
EmuLog(LOG_LEVEL::DEBUG, "%s, calling DPC at 0x%.8X", __func__, DpcEntry[i].Routine);
|
||||
__try {
|
||||
// Call the Deferred Procedure :
|
||||
DpcEntry[i].Routine(
|
||||
DpcEntry[i].Dpc,
|
||||
DpcEntry[i].Context,
|
||||
UlongToPtr(SystemTime.u.LowPart),
|
||||
UlongToPtr(SystemTime.u.HighPart)
|
||||
);
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter!");
|
||||
}
|
||||
|
||||
// Call the Deferred Procedure :
|
||||
DpcEntry[i].Routine(
|
||||
DpcEntry[i].Dpc,
|
||||
DpcEntry[i].Context,
|
||||
UlongToPtr(SystemTime.u.LowPart),
|
||||
UlongToPtr(SystemTime.u.HighPart)
|
||||
);
|
||||
}
|
||||
|
||||
/* Lower IRQL if we need to */
|
||||
|
@ -851,19 +836,14 @@ xboxkrnl::VOID FASTCALL xboxkrnl::KiTimerListExpire
|
|||
{
|
||||
/* Call the DPC */
|
||||
EmuLog(LOG_LEVEL::DEBUG, "%s, calling DPC at 0x%.8X", __func__, DpcEntry[i].Routine);
|
||||
__try {
|
||||
// Call the Deferred Procedure :
|
||||
DpcEntry[i].Routine(
|
||||
DpcEntry[i].Dpc,
|
||||
DpcEntry[i].Context,
|
||||
UlongToPtr(SystemTime.u.LowPart),
|
||||
UlongToPtr(SystemTime.u.HighPart)
|
||||
);
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter!");
|
||||
}
|
||||
|
||||
// Call the Deferred Procedure :
|
||||
DpcEntry[i].Routine(
|
||||
DpcEntry[i].Dpc,
|
||||
DpcEntry[i].Context,
|
||||
UlongToPtr(SystemTime.u.LowPart),
|
||||
UlongToPtr(SystemTime.u.HighPart)
|
||||
);
|
||||
}
|
||||
|
||||
/* Lower IRQL */
|
||||
|
|
|
@ -137,19 +137,12 @@ static unsigned int WINAPI PCSTProxy
|
|||
SuspendThread(GetCurrentThread());
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
auto routine = (xboxkrnl::PKSYSTEM_ROUTINE)SystemRoutine;
|
||||
// Debugging notice : When the below line shows up with an Exception dialog and a
|
||||
// message like: "Exception thrown at 0x00026190 in cxbx.exe: 0xC0000005: Access
|
||||
// violation reading location 0xFD001804.", then this is AS-DESIGNED behaviour!
|
||||
// (To avoid repetitions, uncheck "Break when this exception type is thrown").
|
||||
routine(xboxkrnl::PKSTART_ROUTINE(StartRoutine), StartContext);
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter!");
|
||||
}
|
||||
auto routine = (xboxkrnl::PKSYSTEM_ROUTINE)SystemRoutine;
|
||||
// Debugging notice : When the below line shows up with an Exception dialog and a
|
||||
// message like: "Exception thrown at 0x00026190 in cxbx.exe: 0xC0000005: Access
|
||||
// violation reading location 0xFD001804.", then this is AS-DESIGNED behaviour!
|
||||
// (To avoid repetitions, uncheck "Break when this exception type is thrown").
|
||||
routine(xboxkrnl::PKSTART_ROUTINE(StartRoutine), StartContext);
|
||||
|
||||
// This will also handle thread notification :
|
||||
LOG_TEST_CASE("Thread returned from SystemRoutine");
|
||||
|
@ -165,15 +158,8 @@ void PspSystemThreadStartup
|
|||
IN PVOID StartContext
|
||||
)
|
||||
{
|
||||
__try
|
||||
{
|
||||
(StartRoutine)(StartContext);
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
// TODO : Call PspUnhandledExceptionInSystemThread(GetExceptionInformation())
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter!"); // TODO : Disable?
|
||||
}
|
||||
(StartRoutine)(StartContext);
|
||||
|
||||
xboxkrnl::PsTerminateSystemThread(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -171,14 +171,7 @@ void SetupPerTitleKeys()
|
|||
|
||||
void CxbxLaunchXbe(void(*Entry)())
|
||||
{
|
||||
__try
|
||||
{
|
||||
Entry();
|
||||
}
|
||||
__except (EmuException(GetExceptionInformation()))
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Problem with ExceptionFilter");
|
||||
}
|
||||
Entry();
|
||||
}
|
||||
|
||||
// Entry point address XOR keys per Xbe type (Retail, Debug or Chihiro) :
|
||||
|
@ -1205,6 +1198,8 @@ void CxbxKrnlEmulate(unsigned int reserved_systems, blocks_reserved_t blocks_res
|
|||
ImportLibraries((XbeImportEntry*)CxbxKrnl_Xbe->m_Header.dwNonKernelImportDirAddr);
|
||||
}
|
||||
|
||||
g_ExceptionManager = new ExceptionManager(); // If in need to add VEHs, move this line earlier. (just in case)
|
||||
|
||||
// Launch the XBE :
|
||||
{
|
||||
// Load TLS
|
||||
|
@ -1822,6 +1817,12 @@ void CxbxKrnlShutDown()
|
|||
}
|
||||
|
||||
EmuShared::Cleanup();
|
||||
|
||||
if (g_ExceptionManager) {
|
||||
delete g_ExceptionManager;
|
||||
g_ExceptionManager = nullptr;
|
||||
}
|
||||
|
||||
TerminateProcess(g_CurrentProcessHandle, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,14 @@ bool IsXboxCodeAddress(xbaddr addr)
|
|||
// Note : Not IS_USER_ADDRESS(), that would include host DLL code
|
||||
}
|
||||
|
||||
#include "distorm.h"
|
||||
bool EmuX86_DecodeOpcode(const uint8_t* Eip, _DInst& info);
|
||||
void EmuX86_DistormLogInstruction(const uint8_t* Eip, _DInst& info, LOG_LEVEL log_level);
|
||||
void genericException(EXCEPTION_POINTERS *e) {
|
||||
_DInst info;
|
||||
if (EmuX86_DecodeOpcode((uint8_t*)e->ContextRecord->Eip, info)) {
|
||||
EmuX86_DistormLogInstruction((uint8_t*)e->ContextRecord->Eip, info, LOG_LEVEL::FATAL);
|
||||
}
|
||||
// Try to report this exception to the debugger, which may allow handling of this exception
|
||||
if (CxbxDebugger::CanReport()) {
|
||||
bool DebuggerHandled = false;
|
||||
|
@ -278,8 +285,6 @@ bool lleTryHandleException(EXCEPTION_POINTERS *e)
|
|||
return true;
|
||||
}
|
||||
|
||||
genericException(e);
|
||||
|
||||
// We do not need EmuException to handle it again.
|
||||
bOverrideException = true;
|
||||
|
||||
|
@ -288,7 +293,7 @@ bool lleTryHandleException(EXCEPTION_POINTERS *e)
|
|||
}
|
||||
|
||||
// Only for LLE emulation coding (to help performance a little bit better)
|
||||
LONG NTAPI lleException(EXCEPTION_POINTERS *e)
|
||||
LONG WINAPI lleException(EXCEPTION_POINTERS *e)
|
||||
{
|
||||
g_bEmuException = true;
|
||||
LONG result = lleTryHandleException(e) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
|
||||
|
@ -302,6 +307,7 @@ bool EmuTryHandleException(EXCEPTION_POINTERS *e)
|
|||
|
||||
// Check if lle exception is already called first before emu exception.
|
||||
if (bOverrideException) {
|
||||
genericException(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -346,7 +352,7 @@ bool EmuTryHandleException(EXCEPTION_POINTERS *e)
|
|||
return false;
|
||||
}
|
||||
|
||||
int EmuException(EXCEPTION_POINTERS *e)
|
||||
long WINAPI EmuException(struct _EXCEPTION_POINTERS* e)
|
||||
{
|
||||
g_bEmuException = true;
|
||||
LONG result = EmuTryHandleException(e) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH;
|
||||
|
@ -355,6 +361,7 @@ int EmuException(EXCEPTION_POINTERS *e)
|
|||
}
|
||||
|
||||
// exception handle for that tough final exit :)
|
||||
// TODO: We might just well as delete this, duplicate of EmuExceptionNonBreakpointUnhandledShow
|
||||
int ExitException(LPEXCEPTION_POINTERS e)
|
||||
{
|
||||
static int count = 0;
|
||||
|
@ -395,15 +402,25 @@ ExceptionManager::ExceptionManager()
|
|||
ExceptionManager::~ExceptionManager()
|
||||
{
|
||||
for (auto i_handle : veh_handles) {
|
||||
RemoveVectoredExceptionHandler(i_handle);
|
||||
(void)RemoveVectoredExceptionHandler(i_handle);
|
||||
}
|
||||
veh_handles.clear();
|
||||
#ifdef _MSC_VER // Windows' C++ exception is using SEH, we cannot use VEH for error reporter system.
|
||||
(void)SetUnhandledExceptionFilter(nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Require to be set right before we call xbe's entry point.
|
||||
void ExceptionManager::EmuX86_Init()
|
||||
{
|
||||
accept_request = false; // Do not allow add VEH during emulation.
|
||||
AddVEH(1, lleException, true); // Front line call
|
||||
// Last call plus show exception error than terminate early.
|
||||
#ifdef _MSC_VER // Windows' C++ exception is using SEH, we cannot use VEH for error reporter system.
|
||||
(void)SetUnhandledExceptionFilter(EmuException);
|
||||
#else // Untested for other platforms, may will behave as expected.
|
||||
AddVEH(0, EmuException, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ExceptionManager::AddVEH(unsigned long first, PVECTORED_EXCEPTION_HANDLER veh_handler)
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
std::string FormatTitleId(uint32_t title_id);
|
||||
|
||||
// exception handler
|
||||
extern LONG NTAPI lleException(EXCEPTION_POINTERS *e);
|
||||
int EmuException(EXCEPTION_POINTERS *e);
|
||||
class ExceptionManager {
|
||||
public:
|
||||
ExceptionManager();
|
||||
|
|
|
@ -57,6 +57,8 @@ extern std::atomic_bool g_bEnableAllInterrupts;
|
|||
|
||||
static int field_pin = 0;
|
||||
|
||||
static thread_local bool g_tls_isEmuX86Managed;
|
||||
|
||||
uint32_t EmuX86_IORead(xbaddr addr, int size)
|
||||
{
|
||||
switch (addr) {
|
||||
|
@ -110,48 +112,36 @@ void EmuX86_IOWrite(xbaddr addr, uint32_t value, int size)
|
|||
|
||||
uint32_t EmuX86_Mem_Read(xbaddr addr, int size)
|
||||
{
|
||||
__try {
|
||||
|
||||
switch (size) {
|
||||
case sizeof(uint32_t) :
|
||||
return *(uint32_t*)addr;
|
||||
case sizeof(uint16_t) :
|
||||
return *(uint16_t*)addr;
|
||||
case sizeof(uint8_t) :
|
||||
return *(uint8_t*)addr;
|
||||
default:
|
||||
// UNREACHABLE(size);
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
__except (true) { // TODO : EXCEPTION_EXECUTE_HANDLER instead of true?
|
||||
EmuLog(LOG_LEVEL::WARNING, "EmuX86_Mem_Read Failed (0x%08X, %d)", addr, size);
|
||||
switch (size) {
|
||||
case sizeof(uint32_t) :
|
||||
return *(uint32_t*)addr;
|
||||
case sizeof(uint16_t) :
|
||||
return *(uint16_t*)addr;
|
||||
case sizeof(uint8_t) :
|
||||
return *(uint8_t*)addr;
|
||||
default:
|
||||
// UNREACHABLE(size);
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void EmuX86_Mem_Write(xbaddr addr, uint32_t value, int size)
|
||||
{
|
||||
__try {
|
||||
switch (size) {
|
||||
case sizeof(uint32_t) :
|
||||
*(uint32_t*)addr = (uint32_t)value;
|
||||
break;
|
||||
case sizeof(uint16_t) :
|
||||
*(uint16_t*)addr = (uint16_t)value;
|
||||
break;
|
||||
case sizeof(uint8_t) :
|
||||
*(uint8_t*)addr = (uint8_t)value;
|
||||
break;
|
||||
default:
|
||||
// UNREACHABLE(size);
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
__except (true) { // TODO : EXCEPTION_EXECUTE_HANDLER instead of true?
|
||||
EmuLog(LOG_LEVEL::WARNING, "EmuX86_Mem_Write Failed (0x%08X, 0x%08X, %d)", addr, value, size);
|
||||
switch (size) {
|
||||
case sizeof(uint32_t) :
|
||||
*(uint32_t*)addr = (uint32_t)value;
|
||||
break;
|
||||
case sizeof(uint16_t) :
|
||||
*(uint16_t*)addr = (uint16_t)value;
|
||||
break;
|
||||
case sizeof(uint8_t) :
|
||||
*(uint8_t*)addr = (uint8_t)value;
|
||||
break;
|
||||
default:
|
||||
// UNREACHABLE(size);
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,23 +177,25 @@ uint32_t EmuX86_Read(xbaddr addr, int size)
|
|||
uint32_t value;
|
||||
|
||||
if (addr >= XBOX_FLASH_ROM_BASE) { // 0xFFF00000 - 0xFFFFFFF
|
||||
value = EmuFlash_Read32(addr - XBOX_FLASH_ROM_BASE); // TODO : Make flash access size-aware
|
||||
} else if(addr == 0xFE80200C) {
|
||||
// TODO: Remove this once we have an LLE APU Device
|
||||
return GetAPUTime();
|
||||
} else {
|
||||
// Pass the Read to the PCI Bus, this will handle devices with BARs set to MMIO addresses
|
||||
if (g_PCIBus->MMIORead(addr, &value, size)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
//pass the memory-access through to normal memory :
|
||||
value = EmuX86_Mem_Read(addr, size);
|
||||
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Read(0x%08X, %d) = 0x%08X", addr, size, value);
|
||||
return EmuFlash_Read32(addr - XBOX_FLASH_ROM_BASE); // TODO : Make flash access size-aware
|
||||
}
|
||||
|
||||
return value;
|
||||
// TODO: Remove this once we have an LLE APU Device
|
||||
if(addr == 0xFE80200C) {
|
||||
return GetAPUTime();
|
||||
}
|
||||
|
||||
// Pass the Read to the PCI Bus, this will handle devices with BARs set to MMIO addresses
|
||||
if (g_PCIBus->MMIORead(addr, &value, size)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// EmuX86 is not suppose to do direct read to host memory and should be handle from
|
||||
// redirect from above statements. If it doesn't meet any requirement, then should be
|
||||
// handle as possible fatal crash instead of return corrupt value.
|
||||
g_tls_isEmuX86Managed = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EmuX86_Write(xbaddr addr, uint32_t value, int size)
|
||||
|
@ -224,9 +216,10 @@ void EmuX86_Write(xbaddr addr, uint32_t value, int size)
|
|||
return;
|
||||
}
|
||||
|
||||
// Pass the memory-access through to normal memory :
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Write(0x%.8X, 0x%.8X, %d)", addr, value, size);
|
||||
EmuX86_Mem_Write(addr, value, size);
|
||||
// EmuX86 is not suppose to do direct write to host memory and should be handle from
|
||||
// redirect from above statements. If it doesn't meet any requirement, then should be
|
||||
// handle as possible fatal crash instead of set corrupt value.
|
||||
g_tls_isEmuX86Managed = false;
|
||||
}
|
||||
|
||||
int ContextRecordOffsetByRegisterType[/*_RegisterType*/R_DR7 + 1] = { 0 };
|
||||
|
@ -2786,7 +2779,7 @@ void output_segment(std::stringstream &output, _DInst &info)
|
|||
output << Distorm_RegStrings[SEGMENT_GET(info.segment)] << ":";
|
||||
}
|
||||
|
||||
void EmuX86_DistormLogInstruction(const uint8_t *Eip, _DInst &info)
|
||||
void EmuX86_DistormLogInstruction(const uint8_t *Eip, _DInst &info, LOG_LEVEL log_level)
|
||||
{
|
||||
std::stringstream output;
|
||||
|
||||
|
@ -2907,7 +2900,7 @@ void EmuX86_DistormLogInstruction(const uint8_t *Eip, _DInst &info)
|
|||
#define FLAG_GET_PREFIX(flags) ((flags) & 7) // To get the LOCK/REPNZ/REP prefixes.
|
||||
*/
|
||||
|
||||
EmuLog(LOG_LEVEL::DEBUG, output.str().c_str());
|
||||
EmuLog(log_level, output.str().c_str());
|
||||
}
|
||||
|
||||
int EmuX86_OpcodeSize(uint8_t *Eip)
|
||||
|
@ -2928,10 +2921,9 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e)
|
|||
// However, if for any reason, an opcode operand cannot be read from or written to,
|
||||
// that case may be logged, but it shouldn't fail the opcode handler.
|
||||
_DInst info;
|
||||
g_tls_isEmuX86Managed = true;
|
||||
DWORD StartingEip = e->ContextRecord->Eip;
|
||||
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) {
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Starting instruction emulation from 0x%08X", e->ContextRecord->Eip);
|
||||
}
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Starting instruction emulation from 0x%08X", e->ContextRecord->Eip);
|
||||
|
||||
// Execute op-codes until we hit an unhandled instruction, or an error occurs
|
||||
//while (true)
|
||||
|
@ -2947,7 +2939,7 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e)
|
|||
}
|
||||
|
||||
LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) {
|
||||
EmuX86_DistormLogInstruction((uint8_t*)e->ContextRecord->Eip, info);
|
||||
EmuX86_DistormLogInstruction((uint8_t*)e->ContextRecord->Eip, info, LOG_LEVEL::DEBUG);
|
||||
}
|
||||
|
||||
switch (info.opcode) { // Keep these cases alphabetically ordered and condensed
|
||||
|
@ -3295,10 +3287,15 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e)
|
|||
return true;
|
||||
} // switch info.opcode
|
||||
|
||||
e->ContextRecord->Eip += info.size;
|
||||
if (g_tls_isEmuX86Managed) {
|
||||
e->ContextRecord->Eip += info.size;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} // while true
|
||||
|
||||
return true;
|
||||
return g_tls_isEmuX86Managed;
|
||||
|
||||
opcode_error:
|
||||
EmuLog(LOG_LEVEL::WARNING, "0x%08X: Error while handling instruction %s (%u)", e->ContextRecord->Eip, Distorm_OpcodeString(info.opcode), info.opcode);
|
||||
|
@ -3310,7 +3307,8 @@ void EmuX86_Init()
|
|||
{
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Initializing distorm version %d", distorm_version());
|
||||
|
||||
AddVectoredExceptionHandler(/*FirstHandler=*/ULONG(true), lleException);
|
||||
// Initialize emulation exception to ensure they are front and last line of exception.
|
||||
g_ExceptionManager->EmuX86_Init();
|
||||
|
||||
EmuX86_InitContextRecordOffsetByRegisterType();
|
||||
EmuX86_InitMemoryBackedRegisters();
|
||||
|
|
Loading…
Reference in New Issue