Fixing breakpoints.
This commit is contained in:
parent
5d033f9cb3
commit
4c8634bc31
|
@ -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
|
||||||
|
|
|
@ -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)]);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,12 +1423,13 @@ 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->MapSourceToCode(code_breakpoint->guest_address()));
|
function->MapGuestAddressToMachineCode(
|
||||||
|
code_breakpoint->guest_address()));
|
||||||
} else {
|
} else {
|
||||||
NavigateToFunction(function, function->MapCodeToSource(
|
NavigateToFunction(function,
|
||||||
|
function->MapMachineCodeToGuestAddress(
|
||||||
code_breakpoint->host_address()),
|
code_breakpoint->host_address()),
|
||||||
code_breakpoint->host_address());
|
code_breakpoint->host_address());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue