Directly check PEB for IsDebuggerAttached
Add constexpr getters to magicdiv class so it can be used from jitted x64/dxbc Track the guest return address as well for guest/host sync, if multiple entries have the same guest stack find the first one with a matching guest retaddr. this fixes epic mickey 2 (which the previous guest-stack change had allowed to go ingame for a bit) and potentially also a crash in fable3. Break if under debugger when stackpoints are overflowed Add much more useful output for host exceptions, print out xenia_canary.exe relative offsets if exception is in module, formatmessage for ntstatus/win32err, strerror Minor d3d12 microoptimization, instead of doing SetEventOnCompletion + WaitForSingleObject do SetEventOnCompletion w/ nullptr so that the wait happens in kernel mode, avoiding two extra context switches add unimplemented kernel functions: ExAllocatePoolWithTag ObReferenceObject ObDereferenceObject has no return value. Log a message when ObDereferenceObject/Reference receive unregistered guest kernel objects gave ObLookupThreadByThreadId its correct error status hoist object_types initialization out of ObReferenceObjectByHandle Fix out parameter values on error for a few kernel funcs add note about msr to KeSetCurrentStackPointers add X_STATUS_OBJECT_TYPE_MISMATCH check for xeNtSetEvent add msr_mask field to X_KPCR
This commit is contained in:
@@ -725,10 +725,11 @@ ResolveFunctionThunk X64HelperEmitter::EmitResolveFunctionThunk() {
|
||||
return (ResolveFunctionThunk)fn;
|
||||
}
|
||||
// r11 = size of callers stack, r8 = return address w/ adjustment
|
||||
//i'm not proud of this code, but it shouldn't be executed frequently at all
|
||||
// i'm not proud of this code, but it shouldn't be executed frequently at all
|
||||
void* X64HelperEmitter::EmitGuestAndHostSynchronizeStackHelper() {
|
||||
_code_offsets code_offsets = {};
|
||||
code_offsets.prolog = getSize();
|
||||
push(rbx);
|
||||
mov(rbx, GetBackendCtxPtr(offsetof(X64BackendContext, stackpoints)));
|
||||
mov(eax,
|
||||
GetBackendCtxPtr(offsetof(X64BackendContext, current_stackpoint_depth)));
|
||||
@@ -741,8 +742,9 @@ void* X64HelperEmitter::EmitGuestAndHostSynchronizeStackHelper() {
|
||||
Xbyak::Label signed_underflow{};
|
||||
xor_(r12d, r12d);
|
||||
|
||||
//todo: should use Loop instruction here if hasFastLoop,
|
||||
//currently xbyak does not support it but its super easy to modify xbyak to have it
|
||||
// todo: should use Loop instruction here if hasFastLoop,
|
||||
// currently xbyak does not support it but its super easy to modify xbyak to
|
||||
// have it
|
||||
L(looper);
|
||||
imul(edx, ecx, sizeof(X64BackendStackpoint));
|
||||
mov(r10d, ptr[rbx + rdx + offsetof(X64BackendStackpoint, guest_stack_)]);
|
||||
@@ -760,12 +762,47 @@ void* X64HelperEmitter::EmitGuestAndHostSynchronizeStackHelper() {
|
||||
}
|
||||
js(signed_underflow, T_NEAR); // should be impossible!!
|
||||
|
||||
|
||||
jmp(looper, T_NEAR);
|
||||
L(loopout);
|
||||
Xbyak::Label skip_adjust{};
|
||||
cmp(r12d, 1);//should never happen?
|
||||
cmp(r12d, 1); // should never happen?
|
||||
jle(skip_adjust, T_NEAR);
|
||||
Xbyak::Label we_good{};
|
||||
|
||||
// now we need to make sure that the return address matches
|
||||
|
||||
// mov(r9d, ptr[GetContextReg() + offsetof(ppc::PPCContext, lr)]);
|
||||
pop(r9); // guest retaddr
|
||||
// r10d = the guest_stack
|
||||
// while guest_stack is equal and return address is not equal, decrement
|
||||
|
||||
Xbyak::Label search_for_retaddr{};
|
||||
Xbyak::Label we_good_but_increment{};
|
||||
L(search_for_retaddr);
|
||||
|
||||
imul(edx, ecx, sizeof(X64BackendStackpoint));
|
||||
|
||||
cmp(r10d, ptr[rbx + rdx + offsetof(X64BackendStackpoint, guest_stack_)]);
|
||||
|
||||
jnz(we_good_but_increment, T_NEAR);
|
||||
|
||||
cmp(r9d,
|
||||
ptr[rbx + rdx + offsetof(X64BackendStackpoint, guest_return_address_)]);
|
||||
jz(we_good, T_NEAR); // stack is equal, return address is equal, we've got
|
||||
// our destination stack
|
||||
dec(ecx);
|
||||
jmp(search_for_retaddr, T_NEAR);
|
||||
Xbyak::Label checkbp{};
|
||||
|
||||
L(we_good_but_increment);
|
||||
add(edx, sizeof(X64BackendStackpoint));
|
||||
inc(ecx);
|
||||
jmp(checkbp, T_NEAR);
|
||||
L(we_good);
|
||||
//we're popping this return address, so go down by one
|
||||
sub(edx, sizeof(X64BackendStackpoint));
|
||||
dec(ecx);
|
||||
L(checkbp);
|
||||
mov(rsp, ptr[rbx + rdx + offsetof(X64BackendStackpoint, host_stack_)]);
|
||||
if (IsFeatureEnabled(kX64FlagsIndependentVars)) {
|
||||
inc(ecx);
|
||||
@@ -773,13 +810,13 @@ void* X64HelperEmitter::EmitGuestAndHostSynchronizeStackHelper() {
|
||||
add(ecx, 1);
|
||||
}
|
||||
|
||||
// this->DebugBreak();
|
||||
sub(rsp, r11); // adjust stack
|
||||
|
||||
mov(GetBackendCtxPtr(offsetof(X64BackendContext, current_stackpoint_depth)),
|
||||
ecx); // set next stackpoint index to be after the one we restored to
|
||||
jmp(r8);
|
||||
L(skip_adjust);
|
||||
|
||||
pop(rbx);
|
||||
jmp(r8); // return to caller
|
||||
code_offsets.prolog_stack_alloc = getSize();
|
||||
code_offsets.body = getSize();
|
||||
@@ -787,24 +824,11 @@ void* X64HelperEmitter::EmitGuestAndHostSynchronizeStackHelper() {
|
||||
code_offsets.tail = getSize();
|
||||
|
||||
L(signed_underflow);
|
||||
//find a good, compact way to signal error here
|
||||
// maybe an invalid opcode that we execute, then detect in an exception handler?
|
||||
|
||||
// find a good, compact way to signal error here
|
||||
// maybe an invalid opcode that we execute, then detect in an exception
|
||||
// handler?
|
||||
|
||||
this->DebugBreak();
|
||||
// stack unwinding, take first entry
|
||||
//actually, no reason to have this
|
||||
|
||||
/*mov(rsp, ptr[rbx + offsetof(X64BackendStackpoint, host_stack_)]);
|
||||
mov(ptr[rbx + offsetof(X64BackendStackpoint, guest_stack_)], r9d);
|
||||
sub(rsp, r11);
|
||||
xor_(eax, eax);
|
||||
inc(eax);
|
||||
mov(GetBackendCtxPtr(offsetof(X64BackendContext, current_stackpoint_depth)),
|
||||
eax);
|
||||
|
||||
jmp(r8);*/
|
||||
// this->DebugBreak(); // err, add an xe::FatalError to call for this
|
||||
|
||||
return EmitCurrentForOffsets(code_offsets);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user