Fixing breakpoints.
This commit is contained in:
parent
5d033f9cb3
commit
4c8634bc31
|
@ -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
|
||||
|
|
|
@ -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)]);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue