Starting to properly attribute virtual vs. physical memory accesses.

This commit is contained in:
Ben Vanik
2015-03-29 11:11:35 -07:00
parent ab90e0932b
commit ec84a688e9
42 changed files with 346 additions and 372 deletions

View File

@@ -368,8 +368,7 @@ uint64_t TrapDebugPrint(void* raw_context, uint64_t address) {
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
uint32_t str_ptr = uint32_t(thread_state->context()->r[3]);
uint16_t str_len = uint16_t(thread_state->context()->r[4]);
const char* str =
reinterpret_cast<const char*>(thread_state->memory()->Translate(str_ptr));
auto str = thread_state->memory()->TranslateVirtual<const char*>(str_ptr);
// TODO(benvanik): truncate to length?
PLOGD("(DebugPrint) %s", str);
return 0;

View File

@@ -37,7 +37,7 @@ int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; }
int X64Function::CallImpl(ThreadState* thread_state, uint32_t return_address) {
auto backend = (X64Backend*)thread_state->runtime()->backend();
auto thunk = backend->host_to_guest_thunk();
thunk(machine_code_, thread_state->raw_context(),
thunk(machine_code_, thread_state->context(),
reinterpret_cast<void*>(uintptr_t(return_address)));
return 0;
}

View File

@@ -44,7 +44,7 @@ typedef struct alignas(64) PPCContext_s {
// TODO(benvanik): find a nice way to describe this to the JIT.
ThreadState* thread_state;
// TODO(benvanik): this is getting nasty. Must be here.
uint8_t* membase;
uint8_t* virtual_membase;
// Most frequently used registers first.
uint64_t r[32]; // General purpose registers
@@ -210,6 +210,8 @@ typedef struct alignas(64) PPCContext_s {
// current runtime and its data.
Runtime* runtime;
uint8_t* physical_membase;
void SetRegFromString(const char* name, const char* value);
bool CompareRegWithString(const char* name, const char* value,
char* out_value, size_t out_value_size);

View File

@@ -46,7 +46,6 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
SCOPE_profile_cpu_f("cpu");
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
symbol_info_ = symbol_info;
start_address_ = symbol_info->address();
@@ -80,7 +79,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
for (uint32_t address = start_address, offset = 0; address <= end_address;
address += 4, offset++) {
i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address);
i.code = poly::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
// TODO(benvanik): find a way to avoid using the opcode tables.
i.type = GetInstrType(i.code);
trace_info_.dest_count = 0;

View File

@@ -50,7 +50,6 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// split up and the second half is treated as another function.
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
LOGPPC("Analyzing function %.8X...", symbol_info->address());
@@ -64,7 +63,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
InstrData i;
while (true) {
i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address);
i.code = poly::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
// If we fetched 0 assume that we somehow hit one of the awesome
// 'no really we meant to end after that bl' functions.
@@ -281,7 +280,6 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
std::map<uint32_t, BlockInfo> block_map;
@@ -292,7 +290,7 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
InstrData i;
for (uint32_t address = start_address; address <= end_address; address += 4) {
i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address);
i.code = poly::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
if (!i.code) {
continue;
}

View File

@@ -175,7 +175,6 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
void PPCTranslator::DumpSource(FunctionInfo* symbol_info,
poly::StringBuffer* string_buffer) {
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
string_buffer->Append("%s fn %.8X-%.8X %s\n",
symbol_info->module()->name().c_str(),
@@ -184,14 +183,14 @@ void PPCTranslator::DumpSource(FunctionInfo* symbol_info,
auto blocks = scanner_->FindBlocks(symbol_info);
uint64_t start_address = symbol_info->address();
uint64_t end_address = symbol_info->end_address();
uint32_t start_address = symbol_info->address();
uint32_t end_address = symbol_info->end_address();
InstrData i;
auto block_it = blocks.begin();
for (uint64_t address = start_address, offset = 0; address <= end_address;
for (uint32_t address = start_address, offset = 0; address <= end_address;
address += 4, offset++) {
i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address);
i.code = poly::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
// TODO(benvanik): find a way to avoid using the opcode tables.
i.type = GetInstrType(i.code);

View File

@@ -241,7 +241,7 @@ class TestRunner {
auto address_str = it.second.substr(0, space_pos);
auto bytes_str = it.second.substr(space_pos + 1);
uint32_t address = std::strtoul(address_str.c_str(), nullptr, 16);
auto p = memory->Translate(address);
auto p = memory->TranslateVirtual(address);
const char* c = bytes_str.c_str();
while (*c) {
while (*c == ' ') ++c;
@@ -283,7 +283,7 @@ class TestRunner {
auto address_str = it.second.substr(0, space_pos);
auto bytes_str = it.second.substr(space_pos + 1);
uint32_t address = std::strtoul(address_str.c_str(), nullptr, 16);
auto base_address = memory->Translate(address);
auto base_address = memory->TranslateVirtual(address);
auto p = base_address;
const char* c = bytes_str.c_str();
while (*c) {

View File

@@ -88,7 +88,7 @@ int Function::Call(ThreadState* thread_state, uint32_t return_address) {
}
if (handler) {
handler(thread_state->raw_context(), symbol_info_->extern_arg0(),
handler(thread_state->context(), symbol_info_->extern_arg0(),
symbol_info_->extern_arg1());
} else {
PLOGW("undefined extern call to %.8llX %s", symbol_info_->address(),

View File

@@ -163,8 +163,8 @@ uint64_t Processor::ExecuteInterrupt(uint32_t cpu, uint32_t address,
std::lock_guard<std::mutex> lock(interrupt_thread_lock_);
// Set 0x10C(r13) to the current CPU ID.
uint8_t* p = memory_->membase();
poly::store_and_swap<uint8_t>(p + interrupt_thread_block_ + 0x10C, cpu);
poly::store_and_swap<uint8_t>(
memory_->TranslateVirtual(interrupt_thread_block_ + 0x10C), cpu);
// Execute interrupt.
uint64_t result = Execute(interrupt_thread_state_, address, args, arg_count);

View File

@@ -30,8 +30,8 @@ int RawModule::LoadFile(uint32_t base_address, const std::wstring& path) {
// Allocate memory.
// Since we have no real heap just load it wherever.
base_address_ = base_address;
uint8_t* p = memory_->Translate(base_address_);
memset(p, 0, file_length);
uint8_t* p = memory_->TranslateVirtual(base_address_);
std::memset(p, 0, file_length);
// Read into memory.
fread(p, file_length, 1, file);

View File

@@ -29,7 +29,6 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
thread_id_(thread_id),
name_(""),
backend_data_(0),
raw_context_(0),
stack_size_(stack_size),
thread_state_address_(thread_state_address) {
if (thread_id_ == UINT_MAX) {
@@ -50,13 +49,16 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
assert_not_zero(stack_address_);
// Allocate with 64b alignment.
context_ = (PPCContext*)calloc(1, sizeof(PPCContext));
assert_true(((uint64_t)context_ & 0xF) == 0);
context_ =
reinterpret_cast<PPCContext*>(_aligned_malloc(sizeof(PPCContext), 64));
assert_true(((uint64_t)context_ & 0x3F) == 0);
std::memset(context_, 0, sizeof(PPCContext));
// Stash pointers to common structures that callbacks may need.
context_->reserve_address = memory_->reserve_address();
context_->reserve_value = memory_->reserve_value();
context_->membase = memory_->membase();
context_->virtual_membase = memory_->virtual_membase();
context_->physical_membase = memory_->physical_membase();
context_->runtime = runtime;
context_->thread_state = this;
context_->thread_id = thread_id_;
@@ -69,8 +71,6 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
// 16 to 32b.
context_->r[1] -= 64;
raw_context_ = context_;
runtime_->debugger()->OnThreadCreated(this);
}
@@ -84,7 +84,7 @@ ThreadState::~ThreadState() {
thread_state_ = nullptr;
}
free(context_);
_aligned_free(context_);
if (stack_allocated_) {
memory()->SystemHeapFree(stack_address_);
}

View File

@@ -38,7 +38,6 @@ class ThreadState {
const std::string& name() const { return name_; }
void set_name(const std::string& value) { name_ = value; }
void* backend_data() const { return backend_data_; }
void* raw_context() const { return raw_context_; }
uint32_t stack_address() const { return stack_address_; }
size_t stack_size() const { return stack_size_; }
uint32_t thread_state_address() const { return thread_state_address_; }
@@ -60,7 +59,6 @@ class ThreadState {
uint32_t thread_id_;
std::string name_;
void* backend_data_;
void* raw_context_;
uint32_t stack_address_;
bool stack_allocated_;
uint32_t stack_size_;

View File

@@ -99,8 +99,6 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
return 1;
}
uint8_t* membase = memory_->membase();
char name[128];
for (size_t n = 0; n < import_info_count; n++) {
const xe_xex2_import_info_t* info = &import_infos[n];
@@ -129,7 +127,7 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
// Grab, if available.
if (kernel_export) {
uint32_t* slot = (uint32_t*)(membase + info->value_address);
auto slot = memory_->TranslateVirtual<uint32_t*>(info->value_address);
if (kernel_export->type == KernelExport::Function) {
// Not exactly sure what this should be...
if (info->thunk_address) {
@@ -176,7 +174,7 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
// blr
// nop
// nop
uint8_t* p = memory()->Translate(info->thunk_address);
uint8_t* p = memory()->TranslateVirtual(info->thunk_address);
poly::store_and_swap<uint32_t>(p + 0x0, 0x44000002);
poly::store_and_swap<uint32_t>(p + 0x4, 0x4E800020);
poly::store_and_swap<uint32_t>(p + 0x8, 0x60000000);