Fixing breakpoints.

This commit is contained in:
Ben Vanik 2015-09-21 21:10:57 -07:00
parent 5d033f9cb3
commit 4c8634bc31
7 changed files with 42 additions and 32 deletions

View File

@ -126,7 +126,7 @@ void X64Assembler::DumpMachineCode(
if (code_offset >= next_code_offset && if (code_offset >= next_code_offset &&
source_map_index < source_map.size()) { source_map_index < source_map.size()) {
auto& source_map_entry = source_map[source_map_index]; 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; ++source_map_index;
next_code_offset = source_map_index < source_map.size() next_code_offset = source_map_index < source_map.size()
? source_map[source_map_index].code_offset ? source_map[source_map_index].code_offset

View File

@ -254,21 +254,21 @@ bool X64Emitter::Emit(HIRBuilder* builder, size_t* out_stack_size) {
void X64Emitter::MarkSourceOffset(const Instr* i) { void X64Emitter::MarkSourceOffset(const Instr* i) {
auto entry = source_map_arena_.Alloc<SourceMapEntry>(); auto entry = source_map_arena_.Alloc<SourceMapEntry>();
entry->source_offset = static_cast<uint32_t>(i->src1.offset); entry->guest_address = static_cast<uint32_t>(i->src1.offset);
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal; entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
entry->code_offset = static_cast<uint32_t>(getSize()); entry->code_offset = static_cast<uint32_t>(getSize());
if (FLAGS_emit_source_annotations) { if (FLAGS_emit_source_annotations) {
nop(); nop();
nop(); nop();
mov(eax, entry->source_offset); mov(eax, entry->guest_address);
nop(); nop();
nop(); nop();
} }
if (debug_info_flags_ & DebugInfoFlags::kDebugInfoTraceFunctionCoverage) { if (debug_info_flags_ & DebugInfoFlags::kDebugInfoTraceFunctionCoverage) {
uint32_t instruction_index = uint32_t instruction_index =
(entry->source_offset - trace_data_->start_address()) / 4; (entry->guest_address - trace_data_->start_address()) / 4;
lock(); lock();
inc(qword[low_address(trace_data_->instruction_execute_counts() + inc(qword[low_address(trace_data_->instruction_execute_counts() +
instruction_index * 8)]); instruction_index * 8)]);

View File

@ -65,11 +65,12 @@ void GuestFunction::SetupExtern(ExternHandler handler) {
extern_handler_ = 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. // TODO(benvanik): binary search? We know the list is sorted by code order.
for (size_t i = 0; i < source_map_.size(); ++i) { for (size_t i = 0; i < source_map_.size(); ++i) {
const auto& entry = source_map_[i]; const auto& entry = source_map_[i];
if (entry.source_offset == offset) { if (entry.guest_address == guest_address) {
return &entry; return &entry;
} }
} }
@ -87,7 +88,8 @@ const SourceMapEntry* GuestFunction::LookupHIROffset(uint32_t offset) const {
return nullptr; 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. // TODO(benvanik): binary search? We know the list is sorted by code order.
for (int64_t i = source_map_.size() - 1; i >= 0; --i) { for (int64_t i = source_map_.size() - 1; i >= 0; --i) {
const auto& entry = source_map_[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]; return source_map_.empty() ? nullptr : &source_map_[0];
} }
uintptr_t GuestFunction::MapSourceToCode(uint32_t source_address) const { uint32_t GuestFunction::MapGuestAddressToMachineCodeOffset(
auto entry = LookupSourceOffset(source_address - address()); uint32_t guest_address) const {
return entry ? entry->code_offset auto entry = LookupGuestAddress(guest_address);
: reinterpret_cast<uintptr_t>(machine_code()); return entry ? entry->code_offset : 0;
} }
uint32_t GuestFunction::MapCodeToSource(uintptr_t host_address) const { uintptr_t GuestFunction::MapGuestAddressToMachineCode(
auto entry = LookupCodeOffset(static_cast<uint32_t>( uint32_t guest_address) const {
auto entry = LookupGuestAddress(guest_address);
return reinterpret_cast<uintptr_t>(machine_code()) +
(entry ? entry->code_offset : 0);
}
uint32_t GuestFunction::MapMachineCodeToGuestAddress(
uintptr_t host_address) const {
auto entry = LookupMachineCodeOffset(static_cast<uint32_t>(
host_address - reinterpret_cast<uintptr_t>(machine_code()))); host_address - reinterpret_cast<uintptr_t>(machine_code())));
return entry ? entry->source_offset : address(); return entry ? entry->guest_address : address();
} }
bool GuestFunction::Call(ThreadState* thread_state, uint32_t return_address) { bool GuestFunction::Call(ThreadState* thread_state, uint32_t return_address) {

View File

@ -23,7 +23,7 @@ namespace xe {
namespace cpu { namespace cpu {
struct SourceMapEntry { 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 hir_offset; // Block ordinal (16b) | Instr ordinal (16b)
uint32_t code_offset; // Offset from emitted code start. uint32_t code_offset; // Offset from emitted code start.
}; };
@ -106,12 +106,13 @@ class GuestFunction : public Function {
ExternHandler extern_handler() const { return extern_handler_; } ExternHandler extern_handler() const { return extern_handler_; }
void SetupExtern(ExternHandler 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* 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 MapGuestAddressToMachineCodeOffset(uint32_t guest_address) const;
uint32_t MapCodeToSource(uintptr_t host_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; bool Call(ThreadState* thread_state, uint32_t return_address) override;

View File

@ -239,11 +239,8 @@ class Win32StackWalker : public StackWalker {
// displacement in x64 from the JIT'ed code start to the PC. // displacement in x64 from the JIT'ed code start to the PC.
if (function->is_guest()) { if (function->is_guest()) {
auto guest_function = static_cast<GuestFunction*>(function); auto guest_function = static_cast<GuestFunction*>(function);
uint32_t host_displacement = frame.guest_pc =
uint32_t(frame.host_pc) - guest_function->MapMachineCodeToGuestAddress(frame.host_pc);
uint32_t(uint64_t(guest_function->machine_code()));
auto entry = guest_function->LookupCodeOffset(host_displacement);
frame.guest_pc = entry->source_offset;
} }
} else { } else {
frame.guest_symbol.function = nullptr; frame.guest_symbol.function = nullptr;

View File

@ -45,7 +45,8 @@ void CodeBreakpoint::ForEachHostAddress(
// TODO(benvanik): other function types. // TODO(benvanik): other function types.
assert_true(function->is_guest()); assert_true(function->is_guest());
auto guest_function = reinterpret_cast<cpu::GuestFunction*>(function); auto guest_function = reinterpret_cast<cpu::GuestFunction*>(function);
uintptr_t host_address = guest_function->MapSourceToCode(guest_address); uintptr_t host_address =
guest_function->MapGuestAddressToMachineCode(guest_address);
assert_not_zero(host_address); assert_not_zero(host_address);
callback(host_address); callback(host_address);
} }

View File

@ -608,7 +608,7 @@ void DebugWindow::DrawGuestFunctionSource() {
} }
while (source_map_index < source_map.size() && 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; ++source_map_index;
} }
if (source_map_index < source_map.size()) { if (source_map_index < source_map.size()) {
@ -1423,13 +1423,14 @@ void DebugWindow::DrawBreakpointsPane() {
assert_not_null(function); assert_not_null(function);
if (code_breakpoint->address_type() == if (code_breakpoint->address_type() ==
CodeBreakpoint::AddressType::kGuest) { CodeBreakpoint::AddressType::kGuest) {
NavigateToFunction( NavigateToFunction(code_breakpoint->guest_function(),
code_breakpoint->guest_function(), code_breakpoint->guest_address(),
code_breakpoint->guest_address(), function->MapGuestAddressToMachineCode(
function->MapSourceToCode(code_breakpoint->guest_address())); code_breakpoint->guest_address()));
} else { } else {
NavigateToFunction(function, function->MapCodeToSource( NavigateToFunction(function,
code_breakpoint->host_address()), function->MapMachineCodeToGuestAddress(
code_breakpoint->host_address()),
code_breakpoint->host_address()); code_breakpoint->host_address());
} }
break; break;