XThread: Update the PC when we step out of an export!

This commit is contained in:
Dr. Chat 2015-12-08 00:35:38 -06:00 committed by Ben Vanik
parent ee0a41aa2c
commit 606aa9af6f
1 changed files with 10 additions and 8 deletions

View File

@ -40,8 +40,7 @@ uint32_t next_xthread_id_ = 0;
thread_local XThread* current_thread_tls_ = nullptr; thread_local XThread* current_thread_tls_ = nullptr;
XThread::XThread(KernelState* kernel_state) XThread::XThread(KernelState* kernel_state)
: XObject(kernel_state, kTypeThread), : XObject(kernel_state, kTypeThread), guest_thread_(true) {}
guest_thread_(true) {}
XThread::XThread(KernelState* kernel_state, uint32_t stack_size, XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
uint32_t xapi_thread_startup, uint32_t start_address, uint32_t xapi_thread_startup, uint32_t start_address,
@ -803,8 +802,7 @@ uint32_t XThread::StepIntoBranch(uint32_t pc) {
if (i.I.AA) { if (i.I.AA) {
nia = (uint32_t)cpu::frontend::XEEXTS26(i.I.LI << 2); nia = (uint32_t)cpu::frontend::XEEXTS26(i.I.LI << 2);
} else { } else {
nia = nia = i.address + (uint32_t)cpu::frontend::XEEXTS26(i.I.LI << 2);
i.address + (uint32_t)cpu::frontend::XEEXTS26(i.I.LI << 2);
} }
StepToAddress(nia); StepToAddress(nia);
@ -901,8 +899,8 @@ uint32_t XThread::StepToSafePoint() {
uint64_t frame_host_pcs[64]; uint64_t frame_host_pcs[64];
cpu::StackFrame cpu_frames[64]; cpu::StackFrame cpu_frames[64];
size_t count = stack_walker->CaptureStackTrace( size_t count = stack_walker->CaptureStackTrace(
thread_->native_handle(), frame_host_pcs, 0, xe::countof(frame_host_pcs), thread_->native_handle(), frame_host_pcs, 0, xe::countof(frame_host_pcs),
nullptr, nullptr); nullptr, nullptr);
stack_walker->ResolveStack(frame_host_pcs, cpu_frames, count); stack_walker->ResolveStack(frame_host_pcs, cpu_frames, count);
if (count == 0) { if (count == 0) {
return 0; return 0;
@ -975,7 +973,8 @@ uint32_t XThread::StepToSafePoint() {
pc = thunk_func->address(); pc = thunk_func->address();
} else if (export_data) { } else if (export_data) {
// Non-blocking. Run until we return from the thunk. // Non-blocking. Run until we return from the thunk.
StepToAddress(uint32_t(thread_state_->context()->lr)); pc = uint32_t(thread_state_->context()->lr);
StepToAddress(pc);
} else if (first_pc) { } else if (first_pc) {
// We're in the MMIO handler/mfmsr/something calling out of the guest // We're in the MMIO handler/mfmsr/something calling out of the guest
// that doesn't use an export. If the current instruction is // that doesn't use an export. If the current instruction is
@ -990,7 +989,9 @@ uint32_t XThread::StepToSafePoint() {
// Good to go. // Good to go.
pc = first_pc; pc = first_pc;
} else { } else {
// Step forward. // Step forward and run this logic again.
// FIXME: This is broken. Runs this code in an infinite loop because
// breakpoints call out of the guest.
StepToAddress(first_pc + 4); StepToAddress(first_pc + 4);
return StepToSafePoint(); return StepToSafePoint();
} }
@ -1045,6 +1046,7 @@ bool XThread::Save(ByteStream* stream) {
if (!pc) { if (!pc) {
XELOGE("XThread %.8X failed to save: could not step to a safe point!", XELOGE("XThread %.8X failed to save: could not step to a safe point!",
handle()); handle());
assert_always();
return false; return false;
} }