diff --git a/src/xenia/cpu/backend/x64/x64_assembler.cc b/src/xenia/cpu/backend/x64/x64_assembler.cc index ab6d121e3..dff7477b6 100644 --- a/src/xenia/cpu/backend/x64/x64_assembler.cc +++ b/src/xenia/cpu/backend/x64/x64_assembler.cc @@ -126,7 +126,7 @@ void X64Assembler::DumpMachineCode( if (code_offset >= next_code_offset && source_map_index < source_map.size()) { auto& source_map_entry = source_map[source_map_index]; - str->AppendFormat("%.8X ", source_map_entry.source_offset); + str->AppendFormat("%.8X ", source_map_entry.guest_address); ++source_map_index; next_code_offset = source_map_index < source_map.size() ? source_map[source_map_index].code_offset diff --git a/src/xenia/cpu/backend/x64/x64_emitter.cc b/src/xenia/cpu/backend/x64/x64_emitter.cc index c4661376c..b4517bfe5 100644 --- a/src/xenia/cpu/backend/x64/x64_emitter.cc +++ b/src/xenia/cpu/backend/x64/x64_emitter.cc @@ -254,21 +254,21 @@ bool X64Emitter::Emit(HIRBuilder* builder, size_t* out_stack_size) { void X64Emitter::MarkSourceOffset(const Instr* i) { auto entry = source_map_arena_.Alloc(); - entry->source_offset = static_cast(i->src1.offset); + entry->guest_address = static_cast(i->src1.offset); entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal; entry->code_offset = static_cast(getSize()); if (FLAGS_emit_source_annotations) { nop(); nop(); - mov(eax, entry->source_offset); + mov(eax, entry->guest_address); nop(); nop(); } if (debug_info_flags_ & DebugInfoFlags::kDebugInfoTraceFunctionCoverage) { uint32_t instruction_index = - (entry->source_offset - trace_data_->start_address()) / 4; + (entry->guest_address - trace_data_->start_address()) / 4; lock(); inc(qword[low_address(trace_data_->instruction_execute_counts() + instruction_index * 8)]); diff --git a/src/xenia/cpu/function.cc b/src/xenia/cpu/function.cc index 768f10474..ce063d917 100644 --- a/src/xenia/cpu/function.cc +++ b/src/xenia/cpu/function.cc @@ -65,11 +65,12 @@ void GuestFunction::SetupExtern(ExternHandler handler) { extern_handler_ = handler; } -const SourceMapEntry* GuestFunction::LookupSourceOffset(uint32_t offset) const { +const SourceMapEntry* GuestFunction::LookupGuestAddress( + uint32_t guest_address) const { // TODO(benvanik): binary search? We know the list is sorted by code order. for (size_t i = 0; i < source_map_.size(); ++i) { const auto& entry = source_map_[i]; - if (entry.source_offset == offset) { + if (entry.guest_address == guest_address) { return &entry; } } @@ -87,7 +88,8 @@ const SourceMapEntry* GuestFunction::LookupHIROffset(uint32_t offset) const { return nullptr; } -const SourceMapEntry* GuestFunction::LookupCodeOffset(uint32_t offset) const { +const SourceMapEntry* GuestFunction::LookupMachineCodeOffset( + uint32_t offset) const { // TODO(benvanik): binary search? We know the list is sorted by code order. for (int64_t i = source_map_.size() - 1; i >= 0; --i) { const auto& entry = source_map_[i]; @@ -98,16 +100,24 @@ const SourceMapEntry* GuestFunction::LookupCodeOffset(uint32_t offset) const { return source_map_.empty() ? nullptr : &source_map_[0]; } -uintptr_t GuestFunction::MapSourceToCode(uint32_t source_address) const { - auto entry = LookupSourceOffset(source_address - address()); - return entry ? entry->code_offset - : reinterpret_cast(machine_code()); +uint32_t GuestFunction::MapGuestAddressToMachineCodeOffset( + uint32_t guest_address) const { + auto entry = LookupGuestAddress(guest_address); + return entry ? entry->code_offset : 0; } -uint32_t GuestFunction::MapCodeToSource(uintptr_t host_address) const { - auto entry = LookupCodeOffset(static_cast( +uintptr_t GuestFunction::MapGuestAddressToMachineCode( + uint32_t guest_address) const { + auto entry = LookupGuestAddress(guest_address); + return reinterpret_cast(machine_code()) + + (entry ? entry->code_offset : 0); +} + +uint32_t GuestFunction::MapMachineCodeToGuestAddress( + uintptr_t host_address) const { + auto entry = LookupMachineCodeOffset(static_cast( host_address - reinterpret_cast(machine_code()))); - return entry ? entry->source_offset : address(); + return entry ? entry->guest_address : address(); } bool GuestFunction::Call(ThreadState* thread_state, uint32_t return_address) { diff --git a/src/xenia/cpu/function.h b/src/xenia/cpu/function.h index 0688da17c..19963e25d 100644 --- a/src/xenia/cpu/function.h +++ b/src/xenia/cpu/function.h @@ -23,7 +23,7 @@ namespace xe { namespace cpu { struct SourceMapEntry { - uint32_t source_offset; // Original source address/offset. + uint32_t guest_address; // PPC guest address (0x82....). uint32_t hir_offset; // Block ordinal (16b) | Instr ordinal (16b) uint32_t code_offset; // Offset from emitted code start. }; @@ -106,12 +106,13 @@ class GuestFunction : public Function { ExternHandler extern_handler() const { return extern_handler_; } void SetupExtern(ExternHandler handler); - const SourceMapEntry* LookupSourceOffset(uint32_t offset) const; + const SourceMapEntry* LookupGuestAddress(uint32_t guest_address) const; const SourceMapEntry* LookupHIROffset(uint32_t offset) const; - const SourceMapEntry* LookupCodeOffset(uint32_t offset) const; + const SourceMapEntry* LookupMachineCodeOffset(uint32_t offset) const; - uintptr_t MapSourceToCode(uint32_t source_address) const; - uint32_t MapCodeToSource(uintptr_t host_address) const; + uint32_t MapGuestAddressToMachineCodeOffset(uint32_t guest_address) const; + uintptr_t MapGuestAddressToMachineCode(uint32_t guest_address) const; + uint32_t MapMachineCodeToGuestAddress(uintptr_t host_address) const; bool Call(ThreadState* thread_state, uint32_t return_address) override; diff --git a/src/xenia/cpu/stack_walker_win.cc b/src/xenia/cpu/stack_walker_win.cc index f80108bed..0902c167e 100644 --- a/src/xenia/cpu/stack_walker_win.cc +++ b/src/xenia/cpu/stack_walker_win.cc @@ -239,11 +239,8 @@ class Win32StackWalker : public StackWalker { // displacement in x64 from the JIT'ed code start to the PC. if (function->is_guest()) { auto guest_function = static_cast(function); - uint32_t host_displacement = - uint32_t(frame.host_pc) - - uint32_t(uint64_t(guest_function->machine_code())); - auto entry = guest_function->LookupCodeOffset(host_displacement); - frame.guest_pc = entry->source_offset; + frame.guest_pc = + guest_function->MapMachineCodeToGuestAddress(frame.host_pc); } } else { frame.guest_symbol.function = nullptr; diff --git a/src/xenia/debug/breakpoint.cc b/src/xenia/debug/breakpoint.cc index 9b96d1f22..08b740257 100644 --- a/src/xenia/debug/breakpoint.cc +++ b/src/xenia/debug/breakpoint.cc @@ -45,7 +45,8 @@ void CodeBreakpoint::ForEachHostAddress( // TODO(benvanik): other function types. assert_true(function->is_guest()); auto guest_function = reinterpret_cast(function); - uintptr_t host_address = guest_function->MapSourceToCode(guest_address); + uintptr_t host_address = + guest_function->MapGuestAddressToMachineCode(guest_address); assert_not_zero(host_address); callback(host_address); } diff --git a/src/xenia/debug/ui/debug_window.cc b/src/xenia/debug/ui/debug_window.cc index d72908cf1..2869ce891 100644 --- a/src/xenia/debug/ui/debug_window.cc +++ b/src/xenia/debug/ui/debug_window.cc @@ -608,7 +608,7 @@ void DebugWindow::DrawGuestFunctionSource() { } while (source_map_index < source_map.size() && - source_map[source_map_index].source_offset != address) { + source_map[source_map_index].guest_address != address) { ++source_map_index; } if (source_map_index < source_map.size()) { @@ -1423,13 +1423,14 @@ void DebugWindow::DrawBreakpointsPane() { assert_not_null(function); if (code_breakpoint->address_type() == CodeBreakpoint::AddressType::kGuest) { - NavigateToFunction( - code_breakpoint->guest_function(), - code_breakpoint->guest_address(), - function->MapSourceToCode(code_breakpoint->guest_address())); + NavigateToFunction(code_breakpoint->guest_function(), + code_breakpoint->guest_address(), + function->MapGuestAddressToMachineCode( + code_breakpoint->guest_address())); } else { - NavigateToFunction(function, function->MapCodeToSource( - code_breakpoint->host_address()), + NavigateToFunction(function, + function->MapMachineCodeToGuestAddress( + code_breakpoint->host_address()), code_breakpoint->host_address()); } break;