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 &&
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

View File

@ -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<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->code_offset = static_cast<uint32_t>(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)]);

View File

@ -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<uintptr_t>(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<uint32_t>(
uintptr_t GuestFunction::MapGuestAddressToMachineCode(
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())));
return entry ? entry->source_offset : address();
return entry ? entry->guest_address : address();
}
bool GuestFunction::Call(ThreadState* thread_state, uint32_t return_address) {

View File

@ -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;

View File

@ -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<GuestFunction*>(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;

View File

@ -45,7 +45,8 @@ void CodeBreakpoint::ForEachHostAddress(
// TODO(benvanik): other function types.
assert_true(function->is_guest());
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);
callback(host_address);
}

View File

@ -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;