Check for and allow null critical sections, but log them.

stub XeKeysGetConsoleType
Removed the breakpoints in HandleCppException and RtlRaiseException until we have a real implementation of them. Some apps can continue fine afterwards.
Stub version of HalGetCurrentAVPack
Implement MmIsAddressValid
Implement RtlGetStackLimits
This commit is contained in:
chss95cs@gmail.com 2023-04-16 17:34:46 -04:00
parent 779be8283d
commit 1f86dc0454
6 changed files with 80 additions and 4 deletions

View File

@ -686,6 +686,16 @@ dword_result_t XeKeysHmacShaUsingKey_entry(lpvoid_t obscured_key,
}
DECLARE_XBOXKRNL_EXPORT1(XeKeysHmacShaUsingKey, kNone, kImplemented);
//going off of usage in some hbrew xex
//0 and 1 appear to be devkit, 2 is retail
//we default to saying we're retail
dword_result_t XeKeysGetConsoleType_entry(lpdword_t type_out) {
*type_out = 2;
return 0;
}
DECLARE_XBOXKRNL_EXPORT1(XeKeysGetConsoleType, kNone, kImplemented);
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe

View File

@ -120,7 +120,8 @@ void HandleCppException(pointer_t<X_EXCEPTION_RECORD> record) {
kernel_memory()->TranslateVirtual<x_s__CatchableTypeArray*>(
throw_info->catchable_type_array_ptr);
xe::debugging::Break();
//xe::debugging::Break();
XELOGE("Guest attempted to throw a C++ exception!");
}
void RtlRaiseException_entry(pointer_t<X_EXCEPTION_RECORD> record) {
@ -137,7 +138,10 @@ void RtlRaiseException_entry(pointer_t<X_EXCEPTION_RECORD> record) {
// TODO(benvanik): unwinding.
// This is going to suck.
xe::debugging::Break();
// xe::debugging::Break();
//RtlRaiseException definitely wasn't a noreturn function, we can return safe-ish
XELOGE("Guest attempted to trigger a breakpoint!");
}
DECLARE_XBOXKRNL_EXPORT2(RtlRaiseException, kDebug, kStub, kImportant);

View File

@ -31,6 +31,13 @@ void HalReturnToFirmware_entry(dword_t routine) {
}
DECLARE_XBOXKRNL_EXPORT2(HalReturnToFirmware, kNone, kStub, kImportant);
// this seems to be able to return a number of different values in the range 0
// - 8. just returning four for now, because thats probably a better option than
// returning whatever was in r3 to begin with
dword_result_t HalGetCurrentAVPack_entry() { return 4; }
DECLARE_XBOXKRNL_EXPORT1(HalGetCurrentAVPack, kNone, kStub);
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe

View File

@ -675,6 +675,22 @@ dword_result_t MmDeleteKernelStack_entry(lpvoid_t stack_base,
}
DECLARE_XBOXKRNL_EXPORT1(MmDeleteKernelStack, kMemory, kImplemented);
dword_result_t MmIsAddressValid_entry(dword_t address,
const ppc_context_t& ctx) {
auto kernel = ctx->kernel_state;
auto memory = kernel->memory();
auto heap = memory->LookupHeap(address);
if (!heap) {
return 0;
}
return heap->QueryRangeAccess(address, address) !=
memory::PageAccess::kNoAccess;
}
DECLARE_XBOXKRNL_EXPORT1(MmIsAddressValid, kMemory, kImplemented);
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe

View File

@ -517,6 +517,10 @@ static void CriticalSectionPrefetchW(const void* vp) {
}
void RtlEnterCriticalSection_entry(pointer_t<X_RTL_CRITICAL_SECTION> cs) {
if (!cs.guest_address()) {
XELOGE("Null critical section in RtlEnterCriticalSection!");
return;
}
CriticalSectionPrefetchW(&cs->lock_count);
uint32_t cur_thread = XThread::GetCurrentThread()->guest_object();
uint32_t spin_count = cs->header.absolute * 256;
@ -553,6 +557,10 @@ DECLARE_XBOXKRNL_EXPORT2(RtlEnterCriticalSection, kNone, kImplemented,
dword_result_t RtlTryEnterCriticalSection_entry(
pointer_t<X_RTL_CRITICAL_SECTION> cs) {
if (!cs.guest_address()) {
XELOGE("Null critical section in RtlTryEnterCriticalSection!");
return 1; // pretend we got the critical section.
}
CriticalSectionPrefetchW(&cs->lock_count);
uint32_t thread = XThread::GetCurrentThread()->guest_object();
@ -575,6 +583,10 @@ DECLARE_XBOXKRNL_EXPORT2(RtlTryEnterCriticalSection, kNone, kImplemented,
kHighFrequency);
void RtlLeaveCriticalSection_entry(pointer_t<X_RTL_CRITICAL_SECTION> cs) {
if (!cs.guest_address()) {
XELOGE("Null critical section in RtlLeaveCriticalSection!");
return;
}
assert_true(cs->owning_thread == XThread::GetCurrentThread()->guest_object());
// Drop recursion count - if it isn't zero we still have the lock.
@ -748,6 +760,26 @@ static void RtlRip_entry(const ppc_context_t& ctx) {
//we should break here... not sure what to do exactly
}
DECLARE_XBOXKRNL_EXPORT1(RtlRip, kNone, kImportant);
void RtlGetStackLimits_entry(lpdword_t out_end, lpdword_t out_base,
const ppc_context_t& ctx) {
auto kpcr = ctx->TranslateVirtualGPR<X_KPCR*>(ctx->r[13]);
uint32_t stack_base;
uint32_t stack_end;
if (kpcr->use_alternative_stack) {
stack_base = kpcr->alt_stack_base_ptr;
stack_end = kpcr->alt_stack_end_ptr;
} else {
stack_base = kpcr->stack_base_ptr;
stack_end = kpcr->stack_end_ptr;
}
*out_base = stack_base;
*out_end = stack_end;
}
DECLARE_XBOXKRNL_EXPORT1(RtlGetStackLimits, kNone, kImplemented);
} // namespace xboxkrnl
} // namespace kernel
} // namespace xe

View File

@ -73,10 +73,17 @@ struct X_KPCR {
xe::be<uint32_t> msr_mask; // 0x4
uint8_t unk_08[0x28]; // 0x8
xe::be<uint32_t> pcr_ptr; // 0x30
uint8_t unk_34[0x3C]; // 0x34
uint8_t unk_34[0x38]; // 0x34
xe::be<uint32_t> use_alternative_stack; //0x6C
xe::be<uint32_t> stack_base_ptr; // 0x70 Stack base address (high addr)
xe::be<uint32_t> stack_end_ptr; // 0x74 Stack end (low addr)
uint8_t unk_78[0x88]; // 0x78
//maybe these are the stacks used in apcs?
//i know they're stacks, RtlGetStackLimits returns them if another var here is set
xe::be<uint32_t> alt_stack_base_ptr; // 0x78
xe::be<uint32_t> alt_stack_end_ptr; // 0x7C
uint8_t unk_80[0x80]; // 0x80
xe::be<uint32_t> current_thread; // 0x100
uint8_t unk_104[0x8]; // 0x104
uint8_t current_cpu; // 0x10C