Converting addresses in xe::cpu to 32bit.

This commit is contained in:
Ben Vanik 2015-03-24 19:41:29 -07:00
parent 3279776a80
commit 281abea955
42 changed files with 415 additions and 426 deletions

View File

@ -229,7 +229,7 @@ int 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 = i->src1.offset; entry->source_offset = 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 = getSize(); entry->code_offset = getSize();
source_map_count_++; source_map_count_++;
@ -477,12 +477,11 @@ const int kICSlotCount = 4;
const int kICSlotSize = 23; const int kICSlotSize = 23;
const uint64_t kICSlotInvalidTargetAddress = 0x0F0F0F0F0F0F0F0F; const uint64_t kICSlotInvalidTargetAddress = 0x0F0F0F0F0F0F0F0F;
uint64_t ResolveFunctionAddress(void* raw_context, uint64_t target_address) { uint64_t ResolveFunctionAddress(void* raw_context, uint32_t target_address) {
// TODO(benvanik): generate this thunk at runtime? or a shim? // TODO(benvanik): generate this thunk at runtime? or a shim?
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context); auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
// TODO(benvanik): required? // TODO(benvanik): required?
target_address &= 0xFFFFFFFF;
assert_not_zero(target_address); assert_not_zero(target_address);
Function* fn = NULL; Function* fn = NULL;

View File

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

View File

@ -32,7 +32,7 @@ class X64Function : public Function {
protected: protected:
virtual int AddBreakpointImpl(Breakpoint* breakpoint); virtual int AddBreakpointImpl(Breakpoint* breakpoint);
virtual int RemoveBreakpointImpl(Breakpoint* breakpoint); virtual int RemoveBreakpointImpl(Breakpoint* breakpoint);
virtual int CallImpl(ThreadState* thread_state, uint64_t return_address); virtual int CallImpl(ThreadState* thread_state, uint32_t return_address);
private: private:
void* machine_code_; void* machine_code_;

View File

@ -38,7 +38,7 @@ void DebugInfo::InitializeSourceMap(size_t source_map_count,
// TODO(benvanik): ensure sorted in some way? MC offset? // TODO(benvanik): ensure sorted in some way? MC offset?
} }
SourceMapEntry* DebugInfo::LookupSourceOffset(uint64_t offset) { SourceMapEntry* DebugInfo::LookupSourceOffset(uint32_t offset) {
// 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 n = 0; n < source_map_count_; n++) { for (size_t n = 0; n < source_map_count_; n++) {
auto entry = &source_map_[n]; auto entry = &source_map_[n];

View File

@ -37,7 +37,7 @@ enum TraceFlags {
}; };
typedef struct SourceMapEntry_s { typedef struct SourceMapEntry_s {
uint64_t source_offset; // Original source address/offset. uint32_t source_offset; // Original source address/offset.
uint64_t hir_offset; // Block ordinal (16b) | Instr ordinal (16b) uint64_t hir_offset; // Block ordinal (16b) | Instr ordinal (16b)
uint64_t code_offset; // Offset from emitted code start. uint64_t code_offset; // Offset from emitted code start.
} SourceMapEntry; } SourceMapEntry;
@ -57,7 +57,7 @@ class DebugInfo {
void set_machine_code_disasm(char* value) { machine_code_disasm_ = value; } void set_machine_code_disasm(char* value) { machine_code_disasm_ = value; }
void InitializeSourceMap(size_t source_map_count, SourceMapEntry* source_map); void InitializeSourceMap(size_t source_map_count, SourceMapEntry* source_map);
SourceMapEntry* LookupSourceOffset(uint64_t offset); SourceMapEntry* LookupSourceOffset(uint32_t offset);
SourceMapEntry* LookupHIROffset(uint64_t offset); SourceMapEntry* LookupHIROffset(uint64_t offset);
SourceMapEntry* LookupCodeOffset(uint64_t offset); SourceMapEntry* LookupCodeOffset(uint64_t offset);

View File

@ -17,7 +17,7 @@
namespace xe { namespace xe {
namespace cpu { namespace cpu {
Breakpoint::Breakpoint(Type type, uint64_t address) Breakpoint::Breakpoint(Type type, uint32_t address)
: type_(type), address_(address) {} : type_(type), address_(address) {}
Breakpoint::~Breakpoint() = default; Breakpoint::~Breakpoint() = default;
@ -78,7 +78,7 @@ int Debugger::AddBreakpoint(Breakpoint* breakpoint) {
{ {
std::lock_guard<std::mutex> guard(breakpoints_lock_); std::lock_guard<std::mutex> guard(breakpoints_lock_);
breakpoints_.insert( breakpoints_.insert(
std::pair<uint64_t, Breakpoint*>(breakpoint->address(), breakpoint)); std::pair<uint32_t, Breakpoint*>(breakpoint->address(), breakpoint));
} }
// Find all functions that contain the breakpoint address. // Find all functions that contain the breakpoint address.
@ -126,7 +126,7 @@ int Debugger::RemoveBreakpoint(Breakpoint* breakpoint) {
return 0; return 0;
} }
void Debugger::FindBreakpoints(uint64_t address, void Debugger::FindBreakpoints(uint32_t address,
std::vector<Breakpoint*>& out_breakpoints) { std::vector<Breakpoint*>& out_breakpoints) {
std::lock_guard<std::mutex> guard(breakpoints_lock_); std::lock_guard<std::mutex> guard(breakpoints_lock_);
@ -162,7 +162,7 @@ void Debugger::OnFunctionDefined(FunctionInfo* symbol_info,
std::vector<Breakpoint*> breakpoints; std::vector<Breakpoint*> breakpoints;
{ {
std::lock_guard<std::mutex> guard(breakpoints_lock_); std::lock_guard<std::mutex> guard(breakpoints_lock_);
for (uint64_t address = symbol_info->address(); for (uint32_t address = symbol_info->address();
address <= symbol_info->end_address(); address += 4) { address <= symbol_info->end_address(); address += 4) {
auto range = breakpoints_.equal_range(address); auto range = breakpoints_.equal_range(address);
if (range.first == range.second) { if (range.first == range.second) {

View File

@ -34,18 +34,18 @@ class Breakpoint {
}; };
public: public:
Breakpoint(Type type, uint64_t address); Breakpoint(Type type, uint32_t address);
~Breakpoint(); ~Breakpoint();
Type type() const { return type_; } Type type() const { return type_; }
uint64_t address() const { return address_; } uint32_t address() const { return address_; }
const char* id() const { return id_.c_str(); } const char* id() const { return id_.c_str(); }
void set_id(const char* id) { id_ = std::string(id); } void set_id(const char* id) { id_ = std::string(id); }
private: private:
Type type_; Type type_;
uint64_t address_; uint32_t address_;
std::string id_; std::string id_;
}; };
@ -91,7 +91,7 @@ class Debugger {
int AddBreakpoint(Breakpoint* breakpoint); int AddBreakpoint(Breakpoint* breakpoint);
int RemoveBreakpoint(Breakpoint* breakpoint); int RemoveBreakpoint(Breakpoint* breakpoint);
void FindBreakpoints(uint64_t address, void FindBreakpoints(uint32_t address,
std::vector<Breakpoint*>& out_breakpoints); std::vector<Breakpoint*>& out_breakpoints);
// TODO(benvanik): utility functions for modification (make function ignored, // TODO(benvanik): utility functions for modification (make function ignored,
@ -113,7 +113,7 @@ class Debugger {
std::unordered_map<uint32_t, ThreadState*> threads_; std::unordered_map<uint32_t, ThreadState*> threads_;
std::mutex breakpoints_lock_; std::mutex breakpoints_lock_;
std::multimap<uint64_t, Breakpoint*> breakpoints_; std::multimap<uint32_t, Breakpoint*> breakpoints_;
}; };
} // namespace cpu } // namespace cpu

View File

@ -25,7 +25,7 @@ EntryTable::~EntryTable() {
} }
} }
Entry* EntryTable::Get(uint64_t address) { Entry* EntryTable::Get(uint32_t address) {
std::lock_guard<std::mutex> guard(lock_); std::lock_guard<std::mutex> guard(lock_);
const auto& it = map_.find(address); const auto& it = map_.find(address);
Entry* entry = it != map_.end() ? it->second : nullptr; Entry* entry = it != map_.end() ? it->second : nullptr;
@ -38,7 +38,7 @@ Entry* EntryTable::Get(uint64_t address) {
return entry; return entry;
} }
Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { Entry::Status EntryTable::GetOrCreate(uint32_t address, Entry** out_entry) {
// TODO(benvanik): replace with a map with wait-free for find. // TODO(benvanik): replace with a map with wait-free for find.
// https://github.com/facebook/folly/blob/master/folly/AtomicHashMap.h // https://github.com/facebook/folly/blob/master/folly/AtomicHashMap.h
@ -73,7 +73,7 @@ Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) {
return status; return status;
} }
std::vector<Function*> EntryTable::FindWithAddress(uint64_t address) { std::vector<Function*> EntryTable::FindWithAddress(uint32_t address) {
std::lock_guard<std::mutex> guard(lock_); std::lock_guard<std::mutex> guard(lock_);
std::vector<Function*> fns; std::vector<Function*> fns;
for (auto& it : map_) { for (auto& it : map_) {

View File

@ -27,8 +27,8 @@ typedef struct Entry_t {
STATUS_FAILED, STATUS_FAILED,
} Status; } Status;
uint64_t address; uint32_t address;
uint64_t end_address; uint32_t end_address;
Status status; Status status;
Function* function; Function* function;
} Entry; } Entry;
@ -38,15 +38,15 @@ class EntryTable {
EntryTable(); EntryTable();
~EntryTable(); ~EntryTable();
Entry* Get(uint64_t address); Entry* Get(uint32_t address);
Entry::Status GetOrCreate(uint64_t address, Entry** out_entry); Entry::Status GetOrCreate(uint32_t address, Entry** out_entry);
std::vector<Function*> FindWithAddress(uint64_t address); std::vector<Function*> FindWithAddress(uint32_t address);
private: private:
// TODO(benvanik): replace with a better data structure. // TODO(benvanik): replace with a better data structure.
std::mutex lock_; std::mutex lock_;
std::unordered_map<uint64_t, Entry*> map_; std::unordered_map<uint32_t, Entry*> map_;
}; };
} // namespace cpu } // namespace cpu

View File

@ -50,7 +50,7 @@ int InstrEmit_branch(PPCHIRBuilder& f, const char* src, uint64_t cia,
// If it's a block inside of ourself, setup a fast jump. // If it's a block inside of ourself, setup a fast jump.
// Unless it's to ourselves directly, in which case it's // Unless it's to ourselves directly, in which case it's
// recursion. // recursion.
uint64_t nia_value = nia->AsUint64() & 0xFFFFFFFF; uint32_t nia_value = nia->AsUint64() & 0xFFFFFFFF;
bool is_recursion = false; bool is_recursion = false;
if (nia_value == f.symbol_info()->address() && lk) { if (nia_value == f.symbol_info()->address() && lk) {
is_recursion = true; is_recursion = true;

View File

@ -74,10 +74,10 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
// Always mark entry with label. // Always mark entry with label.
label_list_[0] = NewLabel(); label_list_[0] = NewLabel();
uint64_t start_address = symbol_info->address(); uint32_t start_address = symbol_info->address();
uint64_t end_address = symbol_info->end_address(); uint32_t end_address = symbol_info->end_address();
InstrData i; InstrData i;
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++) { address += 4, offset++) {
i.address = address; i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address); i.code = poly::load_and_swap<uint32_t>(p + address);
@ -166,15 +166,14 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
return Finalize(); return Finalize();
} }
void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) { void PPCHIRBuilder::AnnotateLabel(uint32_t address, Label* label) {
char name_buffer[13]; char name_buffer[13];
snprintf(name_buffer, poly::countof(name_buffer), "loc_%.8X", snprintf(name_buffer, poly::countof(name_buffer), "loc_%.8X", address);
(uint32_t)address);
label->name = (char*)arena_->Alloc(sizeof(name_buffer)); label->name = (char*)arena_->Alloc(sizeof(name_buffer));
memcpy(label->name, name_buffer, sizeof(name_buffer)); memcpy(label->name, name_buffer, sizeof(name_buffer));
} }
FunctionInfo* PPCHIRBuilder::LookupFunction(uint64_t address) { FunctionInfo* PPCHIRBuilder::LookupFunction(uint32_t address) {
Runtime* runtime = frontend_->runtime(); Runtime* runtime = frontend_->runtime();
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
if (runtime->LookupFunctionInfo(address, &symbol_info)) { if (runtime->LookupFunctionInfo(address, &symbol_info)) {
@ -183,7 +182,7 @@ FunctionInfo* PPCHIRBuilder::LookupFunction(uint64_t address) {
return symbol_info; return symbol_info;
} }
Label* PPCHIRBuilder::LookupLabel(uint64_t address) { Label* PPCHIRBuilder::LookupLabel(uint32_t address) {
if (address < start_address_) { if (address < start_address_) {
return NULL; return NULL;
} }

View File

@ -43,8 +43,8 @@ class PPCHIRBuilder : public hir::HIRBuilder {
int Emit(FunctionInfo* symbol_info, uint32_t flags); int Emit(FunctionInfo* symbol_info, uint32_t flags);
FunctionInfo* symbol_info() const { return symbol_info_; } FunctionInfo* symbol_info() const { return symbol_info_; }
FunctionInfo* LookupFunction(uint64_t address); FunctionInfo* LookupFunction(uint32_t address);
Label* LookupLabel(uint64_t address); Label* LookupLabel(uint32_t address);
Value* LoadLR(); Value* LoadLR();
void StoreLR(Value* value); void StoreLR(Value* value);
@ -85,7 +85,7 @@ class PPCHIRBuilder : public hir::HIRBuilder {
Value* StoreRelease(Value* address, Value* value, uint32_t store_flags = 0); Value* StoreRelease(Value* address, Value* value, uint32_t store_flags = 0);
private: private:
void AnnotateLabel(uint64_t address, Label* label); void AnnotateLabel(uint32_t address, Label* label);
private: private:
PPCFrontend* frontend_; PPCFrontend* frontend_;

View File

@ -33,7 +33,7 @@ PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {}
PPCScanner::~PPCScanner() {} PPCScanner::~PPCScanner() {}
bool PPCScanner::IsRestGprLr(uint64_t address) { bool PPCScanner::IsRestGprLr(uint32_t address) {
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
if (frontend_->runtime()->LookupFunctionInfo(address, &symbol_info)) { if (frontend_->runtime()->LookupFunctionInfo(address, &symbol_info)) {
return false; return false;
@ -283,14 +283,14 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
Memory* memory = frontend_->memory(); Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase(); const uint8_t* p = memory->membase();
std::map<uint64_t, BlockInfo> block_map; std::map<uint32_t, BlockInfo> block_map;
uint64_t start_address = symbol_info->address(); uint32_t start_address = symbol_info->address();
uint64_t end_address = symbol_info->end_address(); uint32_t end_address = symbol_info->end_address();
bool in_block = false; bool in_block = false;
uint64_t block_start = 0; uint32_t block_start = 0;
InstrData i; InstrData i;
for (uint64_t address = start_address; address <= end_address; address += 4) { for (uint32_t address = start_address; address <= end_address; address += 4) {
i.address = address; i.address = address;
i.code = poly::load_and_swap<uint32_t>(p + address); i.code = poly::load_and_swap<uint32_t>(p + address);
if (!i.code) { if (!i.code) {

View File

@ -21,8 +21,8 @@ namespace frontend {
class PPCFrontend; class PPCFrontend;
typedef struct BlockInfo_t { typedef struct BlockInfo_t {
uint64_t start_address; uint32_t start_address;
uint64_t end_address; uint32_t end_address;
} BlockInfo; } BlockInfo;
class PPCScanner { class PPCScanner {
@ -35,7 +35,7 @@ class PPCScanner {
std::vector<BlockInfo> FindBlocks(FunctionInfo* symbol_info); std::vector<BlockInfo> FindBlocks(FunctionInfo* symbol_info);
private: private:
bool IsRestGprLr(uint64_t address); bool IsRestGprLr(uint32_t address);
private: private:
PPCFrontend* frontend_; PPCFrontend* frontend_;

View File

@ -37,9 +37,9 @@ typedef std::vector<std::pair<std::string, std::string>> AnnotationList;
const uint32_t START_ADDRESS = 0x100000; const uint32_t START_ADDRESS = 0x100000;
struct TestCase { struct TestCase {
TestCase(uint64_t address, std::string& name) TestCase(uint32_t address, std::string& name)
: address(address), name(name) {} : address(address), name(name) {}
uint64_t address; uint32_t address;
std::string name; std::string name;
AnnotationList annotations; AnnotationList annotations;
}; };
@ -111,8 +111,7 @@ class TestSuite {
} }
std::string address(line_buffer, t_test_ - line_buffer); std::string address(line_buffer, t_test_ - line_buffer);
std::string name(t_test_ + strlen(" t test_")); std::string name(t_test_ + strlen(" t test_"));
test_cases.emplace_back(START_ADDRESS + std::stoull(address, 0, 16), test_cases.emplace_back(START_ADDRESS + std::stoul(address, 0, 16), name);
name);
} }
fclose(f); fclose(f);
return true; return true;
@ -195,9 +194,9 @@ class TestRunner {
runtime->AddModule(std::move(module)); runtime->AddModule(std::move(module));
// Simulate a thread. // Simulate a thread.
uint64_t stack_size = 64 * 1024; uint32_t stack_size = 64 * 1024;
uint64_t stack_address = START_ADDRESS - stack_size; uint32_t stack_address = START_ADDRESS - stack_size;
uint64_t thread_state_address = stack_address - 0x1000; uint32_t thread_state_address = stack_address - 0x1000;
thread_state.reset(new ThreadState(runtime.get(), 0x100, stack_address, thread_state.reset(new ThreadState(runtime.get(), 0x100, stack_address,
stack_size, thread_state_address)); stack_size, thread_state_address));
@ -221,7 +220,7 @@ class TestRunner {
auto ctx = thread_state->context(); auto ctx = thread_state->context();
ctx->lr = 0xBEBEBEBE; ctx->lr = 0xBEBEBEBE;
fn->Call(thread_state.get(), ctx->lr); fn->Call(thread_state.get(), uint32_t(ctx->lr));
// Assert test state expectations. // Assert test state expectations.
bool result = CheckTestResults(test_case); bool result = CheckTestResults(test_case);

View File

@ -53,7 +53,7 @@ int Function::RemoveBreakpoint(Breakpoint* breakpoint) {
return found ? 0 : 1; return found ? 0 : 1;
} }
Breakpoint* Function::FindBreakpoint(uint64_t address) { Breakpoint* Function::FindBreakpoint(uint32_t address) {
std::lock_guard<std::mutex> guard(lock_); std::lock_guard<std::mutex> guard(lock_);
Breakpoint* result = nullptr; Breakpoint* result = nullptr;
for (auto breakpoint : breakpoints_) { for (auto breakpoint : breakpoints_) {
@ -65,7 +65,7 @@ Breakpoint* Function::FindBreakpoint(uint64_t address) {
return result; return result;
} }
int Function::Call(ThreadState* thread_state, uint64_t return_address) { int Function::Call(ThreadState* thread_state, uint32_t return_address) {
// SCOPE_profile_cpu_f("cpu"); // SCOPE_profile_cpu_f("cpu");
ThreadState* original_thread_state = ThreadState::Get(); ThreadState* original_thread_state = ThreadState::Get();

View File

@ -28,7 +28,7 @@ class Function {
Function(FunctionInfo* symbol_info); Function(FunctionInfo* symbol_info);
virtual ~Function(); virtual ~Function();
uint64_t address() const { return address_; } uint32_t address() const { return address_; }
FunctionInfo* symbol_info() const { return symbol_info_; } FunctionInfo* symbol_info() const { return symbol_info_; }
DebugInfo* debug_info() const { return debug_info_.get(); } DebugInfo* debug_info() const { return debug_info_.get(); }
@ -39,16 +39,16 @@ class Function {
int AddBreakpoint(Breakpoint* breakpoint); int AddBreakpoint(Breakpoint* breakpoint);
int RemoveBreakpoint(Breakpoint* breakpoint); int RemoveBreakpoint(Breakpoint* breakpoint);
int Call(ThreadState* thread_state, uint64_t return_address); int Call(ThreadState* thread_state, uint32_t return_address);
protected: protected:
Breakpoint* FindBreakpoint(uint64_t address); Breakpoint* FindBreakpoint(uint32_t address);
virtual int AddBreakpointImpl(Breakpoint* breakpoint) { return 0; } virtual int AddBreakpointImpl(Breakpoint* breakpoint) { return 0; }
virtual int RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; } virtual int RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; }
virtual int CallImpl(ThreadState* thread_state, uint64_t return_address) = 0; virtual int CallImpl(ThreadState* thread_state, uint32_t return_address) = 0;
protected: protected:
uint64_t address_; uint32_t address_;
FunctionInfo* symbol_info_; FunctionInfo* symbol_info_;
std::unique_ptr<DebugInfo> debug_info_; std::unique_ptr<DebugInfo> debug_info_;

View File

@ -78,8 +78,8 @@ void FunctionInstrument::Exit(ThreadState* thread_state) {
// //
} }
MemoryInstrument::MemoryInstrument(Runtime* runtime, uint64_t address, MemoryInstrument::MemoryInstrument(Runtime* runtime, uint32_t address,
uint64_t end_address) uint32_t end_address)
: Instrument(runtime), address_(address), end_address_(end_address) {} : Instrument(runtime), address_(address), end_address_(end_address) {}
bool MemoryInstrument::Attach() { bool MemoryInstrument::Attach() {
@ -103,7 +103,7 @@ bool MemoryInstrument::Detach() {
return true; return true;
} }
void MemoryInstrument::Access(ThreadState* thread_state, uint64_t address, void MemoryInstrument::Access(ThreadState* thread_state, uint32_t address,
AccessType type) { AccessType type) {
// TODO(benvanik): get thread local instance // TODO(benvanik): get thread local instance
} }

View File

@ -86,7 +86,7 @@ class FunctionInstrument : public Instrument {
class MemoryInstrument : public Instrument { class MemoryInstrument : public Instrument {
public: public:
MemoryInstrument(Runtime* runtime, uint64_t address, uint64_t end_address); MemoryInstrument(Runtime* runtime, uint32_t address, uint32_t end_address);
virtual ~MemoryInstrument() {} virtual ~MemoryInstrument() {}
uint64_t address() const { return address_; } uint64_t address() const { return address_; }
@ -100,7 +100,7 @@ class MemoryInstrument : public Instrument {
ACCESS_READ = (1 << 1), ACCESS_READ = (1 << 1),
ACCESS_WRITE = (1 << 2), ACCESS_WRITE = (1 << 2),
}; };
void Access(ThreadState* thread_state, uint64_t address, AccessType type); void Access(ThreadState* thread_state, uint32_t address, AccessType type);
protected: protected:
class Instance { class Instance {
@ -110,7 +110,7 @@ class MemoryInstrument : public Instrument {
MemoryInstrument* instrument() const { return instrument_; } MemoryInstrument* instrument() const { return instrument_; }
virtual void OnAccess(ThreadState* thread_state, uint64_t address, virtual void OnAccess(ThreadState* thread_state, uint32_t address,
AccessType type) = 0; AccessType type) = 0;
private: private:
@ -118,8 +118,8 @@ class MemoryInstrument : public Instrument {
}; };
private: private:
uint64_t address_; uint32_t address_;
uint64_t end_address_; uint32_t end_address_;
}; };
// ThreadInstrument // ThreadInstrument

View File

@ -24,9 +24,9 @@ Module::Module(Runtime* runtime)
Module::~Module() = default; Module::~Module() = default;
bool Module::ContainsAddress(uint64_t address) { return true; } bool Module::ContainsAddress(uint32_t address) { return true; }
SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { SymbolInfo* Module::LookupSymbol(uint32_t address, bool wait) {
lock_.lock(); lock_.lock();
const auto it = map_.find(address); const auto it = map_.find(address);
SymbolInfo* symbol_info = it != map_.end() ? it->second : nullptr; SymbolInfo* symbol_info = it != map_.end() ? it->second : nullptr;
@ -51,7 +51,7 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) {
} }
SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type, SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type,
uint64_t address, uint32_t address,
SymbolInfo** out_symbol_info) { SymbolInfo** out_symbol_info) {
*out_symbol_info = nullptr; *out_symbol_info = nullptr;
lock_.lock(); lock_.lock();
@ -100,7 +100,7 @@ SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type,
return status; return status;
} }
SymbolInfo::Status Module::DeclareFunction(uint64_t address, SymbolInfo::Status Module::DeclareFunction(uint32_t address,
FunctionInfo** out_symbol_info) { FunctionInfo** out_symbol_info) {
SymbolInfo* symbol_info; SymbolInfo* symbol_info;
SymbolInfo::Status status = SymbolInfo::Status status =
@ -109,7 +109,7 @@ SymbolInfo::Status Module::DeclareFunction(uint64_t address,
return status; return status;
} }
SymbolInfo::Status Module::DeclareVariable(uint64_t address, SymbolInfo::Status Module::DeclareVariable(uint32_t address,
VariableInfo** out_symbol_info) { VariableInfo** out_symbol_info) {
SymbolInfo* symbol_info; SymbolInfo* symbol_info;
SymbolInfo::Status status = SymbolInfo::Status status =

View File

@ -34,12 +34,12 @@ class Module {
virtual const std::string& name() const = 0; virtual const std::string& name() const = 0;
virtual bool ContainsAddress(uint64_t address); virtual bool ContainsAddress(uint32_t address);
SymbolInfo* LookupSymbol(uint64_t address, bool wait = true); SymbolInfo* LookupSymbol(uint32_t address, bool wait = true);
virtual SymbolInfo::Status DeclareFunction(uint64_t address, virtual SymbolInfo::Status DeclareFunction(uint32_t address,
FunctionInfo** out_symbol_info); FunctionInfo** out_symbol_info);
virtual SymbolInfo::Status DeclareVariable(uint64_t address, virtual SymbolInfo::Status DeclareVariable(uint32_t address,
VariableInfo** out_symbol_info); VariableInfo** out_symbol_info);
SymbolInfo::Status DefineFunction(FunctionInfo* symbol_info); SymbolInfo::Status DefineFunction(FunctionInfo* symbol_info);
@ -52,7 +52,7 @@ class Module {
int ReadMap(const char* file_name); int ReadMap(const char* file_name);
private: private:
SymbolInfo::Status DeclareSymbol(SymbolInfo::Type type, uint64_t address, SymbolInfo::Status DeclareSymbol(SymbolInfo::Type type, uint32_t address,
SymbolInfo** out_symbol_info); SymbolInfo** out_symbol_info);
SymbolInfo::Status DefineSymbol(SymbolInfo* symbol_info); SymbolInfo::Status DefineSymbol(SymbolInfo* symbol_info);
@ -63,7 +63,7 @@ class Module {
private: private:
// TODO(benvanik): replace with a better data structure. // TODO(benvanik): replace with a better data structure.
std::mutex lock_; std::mutex lock_;
std::unordered_map<uint64_t, SymbolInfo*> map_; std::unordered_map<uint32_t, SymbolInfo*> map_;
std::vector<std::unique_ptr<SymbolInfo>> list_; std::vector<std::unique_ptr<SymbolInfo>> list_;
}; };

View File

@ -104,7 +104,7 @@ int Processor::Setup() {
return 0; return 0;
} }
int Processor::Execute(ThreadState* thread_state, uint64_t address) { int Processor::Execute(ThreadState* thread_state, uint32_t address) {
SCOPE_profile_cpu_f("cpu"); SCOPE_profile_cpu_f("cpu");
// Attempt to get the function. // Attempt to get the function.
@ -129,7 +129,7 @@ int Processor::Execute(ThreadState* thread_state, uint64_t address) {
return 0; return 0;
} }
uint64_t Processor::Execute(ThreadState* thread_state, uint64_t address, uint64_t Processor::Execute(ThreadState* thread_state, uint32_t address,
uint64_t args[], size_t arg_count) { uint64_t args[], size_t arg_count) {
SCOPE_profile_cpu_f("cpu"); SCOPE_profile_cpu_f("cpu");
@ -155,7 +155,7 @@ void Processor::LowerIrql(Irql old_value) {
reinterpret_cast<volatile uint32_t*>(&irql_)); reinterpret_cast<volatile uint32_t*>(&irql_));
} }
uint64_t Processor::ExecuteInterrupt(uint32_t cpu, uint64_t address, uint64_t Processor::ExecuteInterrupt(uint32_t cpu, uint32_t address,
uint64_t args[], size_t arg_count) { uint64_t args[], size_t arg_count) {
SCOPE_profile_cpu_f("cpu"); SCOPE_profile_cpu_f("cpu");

View File

@ -42,14 +42,14 @@ class Processor {
int Setup(); int Setup();
int Execute(ThreadState* thread_state, uint64_t address); int Execute(ThreadState* thread_state, uint32_t address);
uint64_t Execute(ThreadState* thread_state, uint64_t address, uint64_t args[], uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t args[],
size_t arg_count); size_t arg_count);
Irql RaiseIrql(Irql new_value); Irql RaiseIrql(Irql new_value);
void LowerIrql(Irql old_value); void LowerIrql(Irql old_value);
uint64_t ExecuteInterrupt(uint32_t cpu, uint64_t address, uint64_t args[], uint64_t ExecuteInterrupt(uint32_t cpu, uint32_t address, uint64_t args[],
size_t arg_count); size_t arg_count);
private: private:
@ -61,7 +61,7 @@ class Processor {
Irql irql_; Irql irql_;
std::mutex interrupt_thread_lock_; std::mutex interrupt_thread_lock_;
ThreadState* interrupt_thread_state_; ThreadState* interrupt_thread_state_;
uint64_t interrupt_thread_block_; uint32_t interrupt_thread_block_;
}; };
} // namespace cpu } // namespace cpu

View File

@ -20,11 +20,11 @@ RawModule::RawModule(Runtime* runtime)
RawModule::~RawModule() {} RawModule::~RawModule() {}
int RawModule::LoadFile(uint64_t base_address, const std::wstring& path) { int RawModule::LoadFile(uint32_t base_address, const std::wstring& path) {
auto fixed_path = poly::to_string(poly::fix_path_separators(path)); auto fixed_path = poly::to_string(poly::fix_path_separators(path));
FILE* file = fopen(fixed_path.c_str(), "rb"); FILE* file = fopen(fixed_path.c_str(), "rb");
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
size_t file_length = ftell(file); uint32_t file_length = static_cast<uint32_t>(ftell(file));
fseek(file, 0, SEEK_SET); fseek(file, 0, SEEK_SET);
// Allocate memory. // Allocate memory.
@ -52,7 +52,7 @@ int RawModule::LoadFile(uint64_t base_address, const std::wstring& path) {
return 0; return 0;
} }
bool RawModule::ContainsAddress(uint64_t address) { bool RawModule::ContainsAddress(uint32_t address) {
return address >= low_address_ && address < high_address_; return address >= low_address_ && address < high_address_;
} }

View File

@ -22,17 +22,17 @@ class RawModule : public Module {
RawModule(Runtime* runtime); RawModule(Runtime* runtime);
~RawModule() override; ~RawModule() override;
int LoadFile(uint64_t base_address, const std::wstring& path); int LoadFile(uint32_t base_address, const std::wstring& path);
const std::string& name() const override { return name_; } const std::string& name() const override { return name_; }
bool ContainsAddress(uint64_t address) override; bool ContainsAddress(uint32_t address) override;
private: private:
std::string name_; std::string name_;
uint64_t base_address_; uint32_t base_address_;
uint64_t low_address_; uint32_t low_address_;
uint64_t high_address_; uint32_t high_address_;
}; };
} // namespace cpu } // namespace cpu

View File

@ -29,7 +29,7 @@ class BuiltinModule : public Module {
public: public:
BuiltinModule(Runtime* runtime) : Module(runtime), name_("builtin") {} BuiltinModule(Runtime* runtime) : Module(runtime), name_("builtin") {}
const std::string& name() const override { return name_; } const std::string& name() const override { return name_; }
bool ContainsAddress(uint64_t address) override { bool ContainsAddress(uint32_t address) override {
return (address & 0x1FFFFFFF0) == 0x100000000; return (address & 0x1FFFFFFF0) == 0x100000000;
} }
@ -43,7 +43,7 @@ Runtime::Runtime(Memory* memory, ExportResolver* export_resolver,
debug_info_flags_(debug_info_flags), debug_info_flags_(debug_info_flags),
trace_flags_(trace_flags), trace_flags_(trace_flags),
builtin_module_(nullptr), builtin_module_(nullptr),
next_builtin_address_(0x100000000ull), next_builtin_address_(0xFFFF0000ul),
export_resolver_(export_resolver) {} export_resolver_(export_resolver) {}
Runtime::~Runtime() { Runtime::~Runtime() {
@ -138,7 +138,7 @@ std::vector<Module*> Runtime::GetModules() {
FunctionInfo* Runtime::DefineBuiltin(const std::string& name, FunctionInfo* Runtime::DefineBuiltin(const std::string& name,
FunctionInfo::ExternHandler handler, FunctionInfo::ExternHandler handler,
void* arg0, void* arg1) { void* arg0, void* arg1) {
uint64_t address = next_builtin_address_; uint32_t address = next_builtin_address_;
next_builtin_address_ += 4; next_builtin_address_ += 4;
FunctionInfo* fn_info; FunctionInfo* fn_info;
@ -151,11 +151,11 @@ FunctionInfo* Runtime::DefineBuiltin(const std::string& name,
return fn_info; return fn_info;
} }
std::vector<Function*> Runtime::FindFunctionsWithAddress(uint64_t address) { std::vector<Function*> Runtime::FindFunctionsWithAddress(uint32_t address) {
return entry_table_.FindWithAddress(address); return entry_table_.FindWithAddress(address);
} }
int Runtime::ResolveFunction(uint64_t address, Function** out_function) { int Runtime::ResolveFunction(uint32_t address, Function** out_function) {
*out_function = nullptr; *out_function = nullptr;
Entry* entry; Entry* entry;
Entry::Status status = entry_table_.GetOrCreate(address, &entry); Entry::Status status = entry_table_.GetOrCreate(address, &entry);
@ -187,7 +187,7 @@ int Runtime::ResolveFunction(uint64_t address, Function** out_function) {
} }
} }
int Runtime::LookupFunctionInfo(uint64_t address, int Runtime::LookupFunctionInfo(uint32_t address,
FunctionInfo** out_symbol_info) { FunctionInfo** out_symbol_info) {
*out_symbol_info = nullptr; *out_symbol_info = nullptr;
@ -214,7 +214,7 @@ int Runtime::LookupFunctionInfo(uint64_t address,
return LookupFunctionInfo(code_module, address, out_symbol_info); return LookupFunctionInfo(code_module, address, out_symbol_info);
} }
int Runtime::LookupFunctionInfo(Module* module, uint64_t address, int Runtime::LookupFunctionInfo(Module* module, uint32_t address,
FunctionInfo** out_symbol_info) { FunctionInfo** out_symbol_info) {
// Atomic create/lookup symbol in module. // Atomic create/lookup symbol in module.
// If we get back the NEW flag we must declare it now. // If we get back the NEW flag we must declare it now.

View File

@ -48,12 +48,12 @@ class Runtime {
FunctionInfo::ExternHandler handler, void* arg0, FunctionInfo::ExternHandler handler, void* arg0,
void* arg1); void* arg1);
std::vector<Function*> FindFunctionsWithAddress(uint64_t address); std::vector<Function*> FindFunctionsWithAddress(uint32_t address);
int LookupFunctionInfo(uint64_t address, FunctionInfo** out_symbol_info); int LookupFunctionInfo(uint32_t address, FunctionInfo** out_symbol_info);
int LookupFunctionInfo(Module* module, uint64_t address, int LookupFunctionInfo(Module* module, uint32_t address,
FunctionInfo** out_symbol_info); FunctionInfo** out_symbol_info);
int ResolveFunction(uint64_t address, Function** out_function); int ResolveFunction(uint32_t address, Function** out_function);
// uint32_t CreateCallback(void (*callback)(void* data), void* data); // uint32_t CreateCallback(void (*callback)(void* data), void* data);
@ -75,7 +75,7 @@ class Runtime {
std::mutex modules_lock_; std::mutex modules_lock_;
std::vector<std::unique_ptr<Module>> modules_; std::vector<std::unique_ptr<Module>> modules_;
Module* builtin_module_; Module* builtin_module_;
uint64_t next_builtin_address_; uint32_t next_builtin_address_;
}; };
} // namespace cpu } // namespace cpu

View File

@ -12,7 +12,7 @@
namespace xe { namespace xe {
namespace cpu { namespace cpu {
SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address) SymbolInfo::SymbolInfo(Type type, Module* module, uint32_t address)
: type_(type), : type_(type),
module_(module), module_(module),
status_(STATUS_DEFINING), status_(STATUS_DEFINING),
@ -21,7 +21,7 @@ SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address)
SymbolInfo::~SymbolInfo() = default; SymbolInfo::~SymbolInfo() = default;
FunctionInfo::FunctionInfo(Module* module, uint64_t address) FunctionInfo::FunctionInfo(Module* module, uint32_t address)
: SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address), : SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address),
end_address_(0), end_address_(0),
behavior_(BEHAVIOR_DEFAULT), behavior_(BEHAVIOR_DEFAULT),
@ -38,7 +38,7 @@ void FunctionInfo::SetupExtern(ExternHandler handler, void* arg0, void* arg1) {
extern_info_.arg1 = arg1; extern_info_.arg1 = arg1;
} }
VariableInfo::VariableInfo(Module* module, uint64_t address) VariableInfo::VariableInfo(Module* module, uint32_t address)
: SymbolInfo(SymbolInfo::TYPE_VARIABLE, module, address) {} : SymbolInfo(SymbolInfo::TYPE_VARIABLE, module, address) {}
VariableInfo::~VariableInfo() = default; VariableInfo::~VariableInfo() = default;

View File

@ -35,14 +35,14 @@ class SymbolInfo {
}; };
public: public:
SymbolInfo(Type type, Module* module, uint64_t address); SymbolInfo(Type type, Module* module, uint32_t address);
virtual ~SymbolInfo(); virtual ~SymbolInfo();
Type type() const { return type_; } Type type() const { return type_; }
Module* module() const { return module_; } Module* module() const { return module_; }
Status status() const { return status_; } Status status() const { return status_; }
void set_status(Status value) { status_ = value; } void set_status(Status value) { status_ = value; }
uint64_t address() const { return address_; } uint32_t address() const { return address_; }
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
void set_name(const std::string& value) { name_ = value; } void set_name(const std::string& value) { name_ = value; }
@ -51,7 +51,7 @@ class SymbolInfo {
Type type_; Type type_;
Module* module_; Module* module_;
Status status_; Status status_;
uint64_t address_; uint32_t address_;
std::string name_; std::string name_;
}; };
@ -67,12 +67,12 @@ class FunctionInfo : public SymbolInfo {
}; };
public: public:
FunctionInfo(Module* module, uint64_t address); FunctionInfo(Module* module, uint32_t address);
~FunctionInfo() override; ~FunctionInfo() override;
bool has_end_address() const { return end_address_ > 0; } bool has_end_address() const { return end_address_ > 0; }
uint64_t end_address() const { return end_address_; } uint32_t end_address() const { return end_address_; }
void set_end_address(uint64_t value) { end_address_ = value; } void set_end_address(uint32_t value) { end_address_ = value; }
Behavior behavior() const { return behavior_; } Behavior behavior() const { return behavior_; }
void set_behavior(Behavior value) { behavior_ = value; } void set_behavior(Behavior value) { behavior_ = value; }
@ -87,7 +87,7 @@ class FunctionInfo : public SymbolInfo {
void* extern_arg1() const { return extern_info_.arg1; } void* extern_arg1() const { return extern_info_.arg1; }
private: private:
uint64_t end_address_; uint32_t end_address_;
Behavior behavior_; Behavior behavior_;
Function* function_; Function* function_;
struct { struct {
@ -99,7 +99,7 @@ class FunctionInfo : public SymbolInfo {
class VariableInfo : public SymbolInfo { class VariableInfo : public SymbolInfo {
public: public:
VariableInfo(Module* module, uint64_t address); VariableInfo(Module* module, uint32_t address);
~VariableInfo() override; ~VariableInfo() override;
}; };

View File

@ -72,9 +72,9 @@ class TestFunction {
xe::cpu::Function* fn; xe::cpu::Function* fn;
runtime->ResolveFunction(0x1000, &fn); runtime->ResolveFunction(0x1000, &fn);
uint64_t stack_size = 64 * 1024; uint32_t stack_size = 64 * 1024;
uint64_t stack_address = memory_size - stack_size; uint32_t stack_address = memory_size - stack_size;
uint64_t thread_state_address = stack_address - 0x1000; uint32_t thread_state_address = stack_address - 0x1000;
auto thread_state = auto thread_state =
std::make_unique<ThreadState>(runtime.get(), 0x100, stack_address, std::make_unique<ThreadState>(runtime.get(), 0x100, stack_address,
stack_size, thread_state_address); stack_size, thread_state_address);
@ -83,13 +83,13 @@ class TestFunction {
pre_call(ctx); pre_call(ctx);
fn->Call(thread_state.get(), ctx->lr); fn->Call(thread_state.get(), uint32_t(ctx->lr));
post_call(ctx); post_call(ctx);
} }
} }
size_t memory_size; uint32_t memory_size;
std::unique_ptr<Memory> memory; std::unique_ptr<Memory> memory;
std::vector<std::unique_ptr<Runtime>> runtimes; std::vector<std::unique_ptr<Runtime>> runtimes;
}; };

View File

@ -24,7 +24,7 @@ using xe::cpu::hir::HIRBuilder;
namespace passes = xe::cpu::compiler::passes; namespace passes = xe::cpu::compiler::passes;
TestModule::TestModule(Runtime* runtime, const std::string& name, TestModule::TestModule(Runtime* runtime, const std::string& name,
std::function<bool(uint64_t)> contains_address, std::function<bool(uint32_t)> contains_address,
std::function<bool(hir::HIRBuilder&)> generate) std::function<bool(hir::HIRBuilder&)> generate)
: Module(runtime), : Module(runtime),
name_(name), name_(name),
@ -66,11 +66,11 @@ TestModule::TestModule(Runtime* runtime, const std::string& name,
TestModule::~TestModule() = default; TestModule::~TestModule() = default;
bool TestModule::ContainsAddress(uint64_t address) { bool TestModule::ContainsAddress(uint32_t address) {
return contains_address_(address); return contains_address_(address);
} }
SymbolInfo::Status TestModule::DeclareFunction(uint64_t address, SymbolInfo::Status TestModule::DeclareFunction(uint32_t address,
FunctionInfo** out_symbol_info) { FunctionInfo** out_symbol_info) {
SymbolInfo::Status status = Module::DeclareFunction(address, out_symbol_info); SymbolInfo::Status status = Module::DeclareFunction(address, out_symbol_info);
if (status == SymbolInfo::STATUS_NEW) { if (status == SymbolInfo::STATUS_NEW) {

View File

@ -25,20 +25,20 @@ namespace cpu {
class TestModule : public Module { class TestModule : public Module {
public: public:
TestModule(Runtime* runtime, const std::string& name, TestModule(Runtime* runtime, const std::string& name,
std::function<bool(uint64_t)> contains_address, std::function<bool(uint32_t)> contains_address,
std::function<bool(hir::HIRBuilder&)> generate); std::function<bool(hir::HIRBuilder&)> generate);
~TestModule() override; ~TestModule() override;
const std::string& name() const override { return name_; } const std::string& name() const override { return name_; }
bool ContainsAddress(uint64_t address) override; bool ContainsAddress(uint32_t address) override;
SymbolInfo::Status DeclareFunction(uint64_t address, SymbolInfo::Status DeclareFunction(uint32_t address,
FunctionInfo** out_symbol_info) override; FunctionInfo** out_symbol_info) override;
private: private:
std::string name_; std::string name_;
std::function<bool(uint64_t)> contains_address_; std::function<bool(uint32_t)> contains_address_;
std::function<bool(hir::HIRBuilder&)> generate_; std::function<bool(hir::HIRBuilder&)> generate_;
std::unique_ptr<hir::HIRBuilder> builder_; std::unique_ptr<hir::HIRBuilder> builder_;

View File

@ -22,8 +22,8 @@ using PPCContext = xe::cpu::frontend::PPCContext;
thread_local ThreadState* thread_state_ = nullptr; thread_local ThreadState* thread_state_ = nullptr;
ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id, ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
uint64_t stack_address, size_t stack_size, uint32_t stack_address, uint32_t stack_size,
uint64_t thread_state_address) uint32_t thread_state_address)
: runtime_(runtime), : runtime_(runtime),
memory_(runtime->memory()), memory_(runtime->memory()),
thread_id_(thread_id), thread_id_(thread_id),

View File

@ -28,8 +28,8 @@ class Runtime;
class ThreadState { class ThreadState {
public: public:
ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address, ThreadState(Runtime* runtime, uint32_t thread_id, uint32_t stack_address,
size_t stack_size, uint64_t thread_state_address); uint32_t stack_size, uint32_t thread_state_address);
~ThreadState(); ~ThreadState();
Runtime* runtime() const { return runtime_; } Runtime* runtime() const { return runtime_; }
@ -39,9 +39,9 @@ class ThreadState {
void set_name(const std::string& value) { name_ = value; } void set_name(const std::string& value) { name_ = value; }
void* backend_data() const { return backend_data_; } void* backend_data() const { return backend_data_; }
void* raw_context() const { return raw_context_; } void* raw_context() const { return raw_context_; }
uint64_t stack_address() const { return stack_address_; } uint32_t stack_address() const { return stack_address_; }
size_t stack_size() const { return stack_size_; } size_t stack_size() const { return stack_size_; }
uint64_t thread_state_address() const { return thread_state_address_; } uint32_t thread_state_address() const { return thread_state_address_; }
xe::cpu::frontend::PPCContext* context() const { return context_; } xe::cpu::frontend::PPCContext* context() const { return context_; }
int Suspend() { return Suspend(~0); } int Suspend() { return Suspend(~0); }
@ -61,10 +61,10 @@ class ThreadState {
std::string name_; std::string name_;
void* backend_data_; void* backend_data_;
void* raw_context_; void* raw_context_;
uint64_t stack_address_; uint32_t stack_address_;
bool stack_allocated_; bool stack_allocated_;
size_t stack_size_; uint32_t stack_size_;
uint64_t thread_state_address_; uint32_t thread_state_address_;
// NOTE: must be 64b aligned for SSE ops. // NOTE: must be 64b aligned for SSE ops.
xe::cpu::frontend::PPCContext* context_; xe::cpu::frontend::PPCContext* context_;

View File

@ -35,11 +35,10 @@ XexModule::XexModule(Runtime* runtime)
low_address_(0), low_address_(0),
high_address_(0) {} high_address_(0) {}
XexModule::~XexModule() { XexModule::~XexModule() { xe_xex2_dealloc(xex_); }
xe_xex2_dealloc(xex_);
}
int XexModule::Load(const std::string& name, const std::string& path, xe_xex2_ref xex) { int XexModule::Load(const std::string& name, const std::string& path,
xe_xex2_ref xex) {
int result; int result;
xex_ = xex; xex_ = xex;
@ -49,16 +48,15 @@ int XexModule::Load(const std::string& name, const std::string& path, xe_xex2_re
// All code sections are continuous, so this should be easy. // All code sections are continuous, so this should be easy.
low_address_ = UINT_MAX; low_address_ = UINT_MAX;
high_address_ = 0; high_address_ = 0;
for (size_t n = 0, i = 0; n < header->section_count; n++) { for (uint32_t n = 0, i = 0; n < header->section_count; n++) {
const xe_xex2_section_t* section = &header->sections[n]; const xe_xex2_section_t* section = &header->sections[n];
const size_t start_address = header->exe_address + (i * section->page_size); const uint32_t start_address =
const size_t end_address = header->exe_address + (i * section->page_size);
const uint32_t end_address =
start_address + (section->info.page_count * section->page_size); start_address + (section->info.page_count * section->page_size);
if (section->info.type == XEX_SECTION_CODE) { if (section->info.type == XEX_SECTION_CODE) {
low_address_ = low_address_ = std::min(low_address_, start_address);
static_cast<uint32_t>(std::min(low_address_, start_address)); high_address_ = std::max(high_address_, end_address);
high_address_ =
static_cast<uint32_t>(std::max(high_address_, end_address));
} }
i += section->info.page_count; i += section->info.page_count;
} }
@ -96,8 +94,8 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
xe_xex2_import_info_t* import_infos; xe_xex2_import_info_t* import_infos;
size_t import_info_count; size_t import_info_count;
if (xe_xex2_get_import_infos( if (xe_xex2_get_import_infos(xex_, library, &import_infos,
xex_, library, &import_infos, &import_info_count)) { &import_info_count)) {
return 1; return 1;
} }
@ -107,8 +105,8 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
for (size_t n = 0; n < import_info_count; n++) { for (size_t n = 0; n < import_info_count; n++) {
const xe_xex2_import_info_t* info = &import_infos[n]; const xe_xex2_import_info_t* info = &import_infos[n];
KernelExport* kernel_export = export_resolver->GetExportByOrdinal( KernelExport* kernel_export =
library->name, info->ordinal); export_resolver->GetExportByOrdinal(library->name, info->ordinal);
if (kernel_export) { if (kernel_export) {
if (info->thunk_address) { if (info->thunk_address) {
@ -148,7 +146,8 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
poly::store_and_swap<uint32_t>(slot, kernel_export->variable_ptr); poly::store_and_swap<uint32_t>(slot, kernel_export->variable_ptr);
} else { } else {
// Not implemented - write with a dummy value. // Not implemented - write with a dummy value.
poly::store_and_swap<uint32_t>(slot, 0xD000BEEF | (kernel_export->ordinal & 0xFFF) << 16); poly::store_and_swap<uint32_t>(
slot, 0xD000BEEF | (kernel_export->ordinal & 0xFFF) << 16);
XELOGCPU("WARNING: imported a variable with no value: %s", XELOGCPU("WARNING: imported a variable with no value: %s",
kernel_export->name); kernel_export->name);
} }
@ -186,7 +185,8 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
FunctionInfo::ExternHandler handler = 0; FunctionInfo::ExternHandler handler = 0;
void* handler_data = 0; void* handler_data = 0;
if (kernel_export) { if (kernel_export) {
handler = (FunctionInfo::ExternHandler)kernel_export->function_data.shim; handler =
(FunctionInfo::ExternHandler)kernel_export->function_data.shim;
handler_data = kernel_export->function_data.shim_data; handler_data = kernel_export->function_data.shim_data;
} else { } else {
handler = (FunctionInfo::ExternHandler)UndefinedImport; handler = (FunctionInfo::ExternHandler)UndefinedImport;
@ -205,7 +205,7 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
return 0; return 0;
} }
bool XexModule::ContainsAddress(uint64_t address) { bool XexModule::ContainsAddress(uint32_t address) {
return address >= low_address_ && address < high_address_; return address >= low_address_ && address < high_address_;
} }
@ -235,8 +235,7 @@ int XexModule::FindSaveRest() {
0xE0FFA1FB, // __savegprlr_29 0xE0FFA1FB, // __savegprlr_29
0xE8FFC1FB, // __savegprlr_30 0xE8FFC1FB, // __savegprlr_30
0xF0FFE1FB, // __savegprlr_31 0xF0FFE1FB, // __savegprlr_31
0xF8FF8191, 0xF8FF8191, 0x2000804E,
0x2000804E,
0x68FFC1E9, // __restgprlr_14 0x68FFC1E9, // __restgprlr_14
0x70FFE1E9, // __restgprlr_15 0x70FFE1E9, // __restgprlr_15
0x78FF01EA, // __restgprlr_16 0x78FF01EA, // __restgprlr_16
@ -255,9 +254,7 @@ int XexModule::FindSaveRest() {
0xE0FFA1EB, // __restgprlr_29 0xE0FFA1EB, // __restgprlr_29
0xE8FFC1EB, // __restgprlr_30 0xE8FFC1EB, // __restgprlr_30
0xF0FFE1EB, // __restgprlr_31 0xF0FFE1EB, // __restgprlr_31
0xF8FF8181, 0xF8FF8181, 0xA603887D, 0x2000804E,
0xA603887D,
0x2000804E,
}; };
// __savefpr_14 to __savefpr_31 // __savefpr_14 to __savefpr_31
// __restfpr_14 to __restfpr_31 // __restfpr_14 to __restfpr_31
@ -312,10 +309,8 @@ int XexModule::FindSaveRest() {
0xCE618B7E, 0x50FF6039, 0xCE61AB7E, 0x60FF6039, 0xCE61CB7E, 0x70FF6039, 0xCE618B7E, 0x50FF6039, 0xCE61AB7E, 0x60FF6039, 0xCE61CB7E, 0x70FF6039,
0xCE61EB7E, 0x80FF6039, 0xCE610B7F, 0x90FF6039, 0xCE612B7F, 0xA0FF6039, 0xCE61EB7E, 0x80FF6039, 0xCE610B7F, 0x90FF6039, 0xCE612B7F, 0xA0FF6039,
0xCE614B7F, 0xB0FF6039, 0xCE616B7F, 0xC0FF6039, 0xCE618B7F, 0xD0FF6039, 0xCE614B7F, 0xB0FF6039, 0xCE616B7F, 0xC0FF6039, 0xCE618B7F, 0xD0FF6039,
0xCE61AB7F, 0xE0FF6039, 0xCE61CB7F, 0xCE61AB7F, 0xE0FF6039, 0xCE61CB7F, 0xF0FF6039, // __savevmx_31
0xF0FF6039, // __savevmx_31 0xCE61EB7F, 0x2000804E,
0xCE61EB7F,
0x2000804E,
0x00FC6039, // __savevmx_64 0x00FC6039, // __savevmx_64
0xCB610B10, 0x10FC6039, 0xCB612B10, 0x20FC6039, 0xCB614B10, 0x30FC6039, 0xCB610B10, 0x10FC6039, 0xCB612B10, 0x20FC6039, 0xCB614B10, 0x30FC6039,
@ -340,8 +335,7 @@ int XexModule::FindSaveRest() {
0xCF612B13, 0xA0FF6039, 0xCF614B13, 0xB0FF6039, 0xCF616B13, 0xC0FF6039, 0xCF612B13, 0xA0FF6039, 0xCF614B13, 0xB0FF6039, 0xCF616B13, 0xC0FF6039,
0xCF618B13, 0xD0FF6039, 0xCF61AB13, 0xE0FF6039, 0xCF61CB13, 0xCF618B13, 0xD0FF6039, 0xCF61AB13, 0xE0FF6039, 0xCF61CB13,
0xF0FF6039, // __savevmx_127 0xF0FF6039, // __savevmx_127
0xCF61EB13, 0xCF61EB13, 0x2000804E,
0x2000804E,
0xE0FE6039, // __restvmx_14 0xE0FE6039, // __restvmx_14
0xCE60CB7D, 0xF0FE6039, 0xCE60EB7D, 0x00FF6039, 0xCE600B7E, 0x10FF6039, 0xCE60CB7D, 0xF0FE6039, 0xCE60EB7D, 0x00FF6039, 0xCE600B7E, 0x10FF6039,
@ -350,8 +344,7 @@ int XexModule::FindSaveRest() {
0xCE60EB7E, 0x80FF6039, 0xCE600B7F, 0x90FF6039, 0xCE602B7F, 0xA0FF6039, 0xCE60EB7E, 0x80FF6039, 0xCE600B7F, 0x90FF6039, 0xCE602B7F, 0xA0FF6039,
0xCE604B7F, 0xB0FF6039, 0xCE606B7F, 0xC0FF6039, 0xCE608B7F, 0xD0FF6039, 0xCE604B7F, 0xB0FF6039, 0xCE606B7F, 0xC0FF6039, 0xCE608B7F, 0xD0FF6039,
0xCE60AB7F, 0xE0FF6039, 0xCE60CB7F, 0xF0FF6039, // __restvmx_31 0xCE60AB7F, 0xE0FF6039, 0xCE60CB7F, 0xF0FF6039, // __restvmx_31
0xCE60EB7F, 0xCE60EB7F, 0x2000804E,
0x2000804E,
0x00FC6039, // __restvmx_64 0x00FC6039, // __restvmx_64
0xCB600B10, 0x10FC6039, 0xCB602B10, 0x20FC6039, 0xCB604B10, 0x30FC6039, 0xCB600B10, 0x10FC6039, 0xCB602B10, 0x20FC6039, 0xCB604B10, 0x30FC6039,
@ -376,21 +369,21 @@ int XexModule::FindSaveRest() {
0xCF602B13, 0xA0FF6039, 0xCF604B13, 0xB0FF6039, 0xCF606B13, 0xC0FF6039, 0xCF602B13, 0xA0FF6039, 0xCF604B13, 0xB0FF6039, 0xCF606B13, 0xC0FF6039,
0xCF608B13, 0xD0FF6039, 0xCF60AB13, 0xE0FF6039, 0xCF60CB13, 0xCF608B13, 0xD0FF6039, 0xCF60AB13, 0xE0FF6039, 0xCF60CB13,
0xF0FF6039, // __restvmx_127 0xF0FF6039, // __restvmx_127
0xCF60EB13, 0xCF60EB13, 0x2000804E,
0x2000804E,
}; };
// TODO(benvanik): these are almost always sequential, if present. // TODO(benvanik): these are almost always sequential, if present.
// It'd be smarter to search around the other ones to prevent // It'd be smarter to search around the other ones to prevent
// 3 full module scans. // 3 full module scans.
uint64_t gplr_start = 0; uint32_t gplr_start = 0;
uint64_t fpr_start = 0; uint32_t fpr_start = 0;
uint64_t vmx_start = 0; uint32_t vmx_start = 0;
const xe_xex2_header_t* header = xe_xex2_get_header(xex_); const xe_xex2_header_t* header = xe_xex2_get_header(xex_);
for (size_t n = 0, i = 0; n < header->section_count; n++) { for (uint32_t n = 0, i = 0; n < header->section_count; n++) {
const xe_xex2_section_t* section = &header->sections[n]; const xe_xex2_section_t* section = &header->sections[n];
const size_t start_address = header->exe_address + (i * section->page_size); const uint32_t start_address =
const size_t end_address = header->exe_address + (i * section->page_size);
const uint32_t end_address =
start_address + (section->info.page_count * section->page_size); start_address + (section->info.page_count * section->page_size);
if (section->info.type == XEX_SECTION_CODE) { if (section->info.type == XEX_SECTION_CODE) {
if (!gplr_start) { if (!gplr_start) {
@ -418,7 +411,7 @@ int XexModule::FindSaveRest() {
// Add function stubs. // Add function stubs.
char name[32]; char name[32];
if (gplr_start) { if (gplr_start) {
uint64_t address = gplr_start; uint32_t address = gplr_start;
for (int n = 14; n <= 31; n++) { for (int n = 14; n <= 31; n++) {
snprintf(name, poly::countof(name), "__savegprlr_%d", n); snprintf(name, poly::countof(name), "__savegprlr_%d", n);
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
@ -446,7 +439,7 @@ int XexModule::FindSaveRest() {
} }
} }
if (fpr_start) { if (fpr_start) {
uint64_t address = fpr_start; uint32_t address = fpr_start;
for (int n = 14; n <= 31; n++) { for (int n = 14; n <= 31; n++) {
snprintf(name, poly::countof(name), "__savefpr_%d", n); snprintf(name, poly::countof(name), "__savefpr_%d", n);
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
@ -479,7 +472,7 @@ int XexModule::FindSaveRest() {
// 64-127 save // 64-127 save
// 14-31 rest // 14-31 rest
// 64-127 rest // 64-127 rest
uint64_t address = vmx_start; uint32_t address = vmx_start;
for (int n = 14; n <= 31; n++) { for (int n = 14; n <= 31; n++) {
snprintf(name, poly::countof(name), "__savevmx_%d", n); snprintf(name, poly::countof(name), "__savevmx_%d", n);
FunctionInfo* symbol_info; FunctionInfo* symbol_info;

View File

@ -32,7 +32,7 @@ public:
const std::string& name() const override { return name_; } const std::string& name() const override { return name_; }
bool ContainsAddress(uint64_t address) override; bool ContainsAddress(uint32_t address) override;
private: private:
int SetupImports(xe_xex2_ref xex); int SetupImports(xe_xex2_ref xex);
@ -45,9 +45,9 @@ private:
std::string path_; std::string path_;
xe_xex2_ref xex_; xe_xex2_ref xex_;
uint64_t base_address_; uint32_t base_address_;
uint64_t low_address_; uint32_t low_address_;
uint64_t high_address_; uint32_t high_address_;
}; };
} // namespace cpu } // namespace cpu

View File

@ -15,11 +15,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
typedef struct xe_ppc_state xe_ppc_state_t;
namespace xe { namespace xe {
typedef void (*xe_kernel_export_shim_fn)(xe_ppc_state_t*, void*); typedef void (*xe_kernel_export_shim_fn)(void*, void*);
class KernelExport { class KernelExport {
public: public:

View File

@ -50,7 +50,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
xe_xex2_header_t *header); xe_xex2_header_t *header);
int xe_xex2_decrypt_key(xe_xex2_header_t *header); int xe_xex2_decrypt_key(xe_xex2_header_t *header);
int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr, int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr,
const size_t xex_length, xe::Memory *memory); const uint32_t xex_length, xe::Memory *memory);
int xe_xex2_load_pe(xe_xex2_ref xex); int xe_xex2_load_pe(xe_xex2_ref xex);
int xe_xex2_find_import_infos(xe_xex2_ref xex, int xe_xex2_find_import_infos(xe_xex2_ref xex,
const xe_xex2_import_library_t *library); const xe_xex2_import_library_t *library);
@ -67,7 +67,8 @@ xe_xex2_ref xe_xex2_load(xe::Memory *memory, const void *addr,
XEEXPECTZERO(xe_xex2_decrypt_key(&xex->header)); XEEXPECTZERO(xe_xex2_decrypt_key(&xex->header));
XEEXPECTZERO(xe_xex2_read_image(xex, (const uint8_t *)addr, length, memory)); XEEXPECTZERO(
xe_xex2_read_image(xex, (const uint8_t *)addr, uint32_t(length), memory));
XEEXPECTZERO(xe_xex2_load_pe(xex)); XEEXPECTZERO(xe_xex2_load_pe(xex));
@ -525,12 +526,12 @@ void xe_xex2_decrypt_buffer(const uint8_t *session_key,
int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header, int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header,
const uint8_t *xex_addr, const uint8_t *xex_addr,
const size_t xex_length, const uint32_t xex_length,
xe::Memory *memory) { xe::Memory *memory) {
// Allocate in-place the XEX memory. // Allocate in-place the XEX memory.
const size_t exe_length = xex_length - header->exe_offset; const uint32_t exe_length = xex_length - header->exe_offset;
size_t uncompressed_size = exe_length; uint32_t uncompressed_size = exe_length;
uint32_t alloc_result = (uint32_t)memory->HeapAlloc( uint32_t alloc_result = memory->HeapAlloc(
header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO); header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO);
if (!alloc_result) { if (!alloc_result) {
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address,
@ -562,24 +563,24 @@ int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header,
int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
const uint8_t *xex_addr, const uint8_t *xex_addr,
const size_t xex_length, const uint32_t xex_length,
xe::Memory *memory) { xe::Memory *memory) {
const size_t exe_length = xex_length - header->exe_offset; const uint32_t exe_length = xex_length - header->exe_offset;
const uint8_t *source_buffer = (const uint8_t *)xex_addr + header->exe_offset; const uint8_t *source_buffer = (const uint8_t *)xex_addr + header->exe_offset;
const uint8_t *p = source_buffer; const uint8_t *p = source_buffer;
// Calculate uncompressed length. // Calculate uncompressed length.
size_t uncompressed_size = 0; uint32_t uncompressed_size = 0;
const xe_xex2_file_basic_compression_info_t *comp_info = const xe_xex2_file_basic_compression_info_t *comp_info =
&header->file_format_info.compression_info.basic; &header->file_format_info.compression_info.basic;
for (size_t n = 0; n < comp_info->block_count; n++) { for (uint32_t n = 0; n < comp_info->block_count; n++) {
const size_t data_size = comp_info->blocks[n].data_size; const uint32_t data_size = comp_info->blocks[n].data_size;
const size_t zero_size = comp_info->blocks[n].zero_size; const uint32_t zero_size = comp_info->blocks[n].zero_size;
uncompressed_size += data_size + zero_size; uncompressed_size += data_size + zero_size;
} }
// Allocate in-place the XEX memory. // Allocate in-place the XEX memory.
uint32_t alloc_result = (uint32_t)memory->HeapAlloc( uint32_t alloc_result = memory->HeapAlloc(
header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO); header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO);
if (!alloc_result) { if (!alloc_result) {
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address,
@ -594,8 +595,8 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
int32_t Nr = rijndaelKeySetupDec(rk, header->session_key, 128); int32_t Nr = rijndaelKeySetupDec(rk, header->session_key, 128);
for (size_t n = 0; n < comp_info->block_count; n++) { for (size_t n = 0; n < comp_info->block_count; n++) {
const size_t data_size = comp_info->blocks[n].data_size; const uint32_t data_size = comp_info->blocks[n].data_size;
const size_t zero_size = comp_info->blocks[n].zero_size; const uint32_t zero_size = comp_info->blocks[n].zero_size;
switch (header->file_format_info.encryption_type) { switch (header->file_format_info.encryption_type) {
case XEX_ENCRYPTION_NONE: case XEX_ENCRYPTION_NONE:
@ -634,8 +635,9 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header,
int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
const uint8_t *xex_addr, const uint8_t *xex_addr,
const size_t xex_length, xe::Memory *memory) { const uint32_t xex_length,
const size_t exe_length = xex_length - header->exe_offset; xe::Memory *memory) {
const uint32_t exe_length = xex_length - header->exe_offset;
const uint8_t *exe_buffer = (const uint8_t *)xex_addr + header->exe_offset; const uint8_t *exe_buffer = (const uint8_t *)xex_addr + header->exe_offset;
// src -> dest: // src -> dest:
@ -653,7 +655,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
uint8_t *d = NULL; uint8_t *d = NULL;
uint8_t *deblock_buffer = NULL; uint8_t *deblock_buffer = NULL;
size_t block_size = 0; size_t block_size = 0;
size_t uncompressed_size = 0; uint32_t uncompressed_size = 0;
struct mspack_system *sys = NULL; struct mspack_system *sys = NULL;
mspack_memory_file *lzxsrc = NULL; mspack_memory_file *lzxsrc = NULL;
mspack_memory_file *lzxdst = NULL; mspack_memory_file *lzxdst = NULL;
@ -714,7 +716,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
} }
// Allocate in-place the XEX memory. // Allocate in-place the XEX memory.
uint32_t alloc_result = (uint32_t)memory->HeapAlloc( uint32_t alloc_result = memory->HeapAlloc(
header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO); header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO);
if (!alloc_result) { if (!alloc_result) {
XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address,
@ -767,7 +769,7 @@ XECLEANUP:
} }
int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr, int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr,
const size_t xex_length, xe::Memory *memory) { const uint32_t xex_length, xe::Memory *memory) {
const xe_xex2_header_t *header = &xex->header; const xe_xex2_header_t *header = &xex->header;
switch (header->file_format_info.compression_type) { switch (header->file_format_info.compression_type) {
case XEX_COMPRESSION_NONE: case XEX_COMPRESSION_NONE:

View File

@ -410,7 +410,7 @@ typedef enum {
} xe_xex2_section_type; } xe_xex2_section_type;
typedef struct { typedef struct {
size_t page_size; uint32_t page_size;
union { union {
struct { struct {
xe_xex2_section_type type : 4; xe_xex2_section_type type : 4;

View File

@ -292,7 +292,8 @@ SHIM_CALL RtlUnicodeStringToAnsiString_shim(PPCContext* ppc_state,
X_STATUS result = X_STATUS_SUCCESS; X_STATUS result = X_STATUS_SUCCESS;
if (alloc_dest) { if (alloc_dest) {
auto buffer_ptr = state->memory()->HeapAlloc(0, ansi_str.size() + 1, 0); auto buffer_ptr =
state->memory()->HeapAlloc(0, uint32_t(ansi_str.size() + 1), 0);
memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1);
SHIM_SET_MEM_16(destination_ptr + 0, SHIM_SET_MEM_16(destination_ptr + 0,
static_cast<uint16_t>(ansi_str.size())); static_cast<uint16_t>(ansi_str.size()));

View File

@ -80,22 +80,22 @@ DEFINE_bool(scribble_heap, false,
* this. * this.
*/ */
#define MEMORY_PHYSICAL_HEAP_LOW 0x00010000 const uint32_t kMemoryPhysicalHeapLow = 0x00010000;
#define MEMORY_PHYSICAL_HEAP_HIGH 0x20000000 const uint32_t kMemoryPhysicalHeapHigh = 0x20000000;
#define MEMORY_VIRTUAL_HEAP_LOW 0x20000000 const uint32_t kMemoryVirtualHeapLow = 0x20000000;
#define MEMORY_VIRTUAL_HEAP_HIGH 0x40000000 const uint32_t kMemoryVirtualHeapHigh = 0x40000000;
class xe::MemoryHeap { class xe::MemoryHeap {
public: public:
MemoryHeap(Memory* memory, bool is_physical); MemoryHeap(Memory* memory, bool is_physical);
~MemoryHeap(); ~MemoryHeap();
int Initialize(uint64_t low, uint64_t high); int Initialize(uint32_t low, uint32_t high);
uint64_t Alloc(uint64_t base_address, size_t size, uint32_t flags, uint32_t Alloc(uint32_t base_address, uint32_t size, uint32_t flags,
uint32_t alignment); uint32_t alignment);
uint64_t Free(uint64_t address, size_t size); uint32_t Free(uint32_t address, uint32_t size);
size_t QuerySize(uint64_t base_address); uint32_t QuerySize(uint32_t base_address);
void Dump(); void Dump();
@ -109,7 +109,7 @@ class xe::MemoryHeap {
uint32_t heap_id_; uint32_t heap_id_;
bool is_physical_; bool is_physical_;
std::mutex lock_; std::mutex lock_;
size_t size_; uint32_t size_;
uint8_t* ptr_; uint8_t* ptr_;
mspace space_; mspace space_;
}; };
@ -122,7 +122,7 @@ Memory::Memory()
trace_base_(0), trace_base_(0),
mapping_(0), mapping_(0),
mapping_base_(nullptr) { mapping_base_(nullptr) {
system_page_size_ = poly::page_size(); system_page_size_ = uint32_t(poly::page_size());
virtual_heap_ = new MemoryHeap(this, false); virtual_heap_ = new MemoryHeap(this, false);
physical_heap_ = new MemoryHeap(this, true); physical_heap_ = new MemoryHeap(this, true);
} }
@ -187,9 +187,9 @@ int Memory::Initialize() {
membase_ = mapping_base_; membase_ = mapping_base_;
// Prepare heaps. // Prepare heaps.
virtual_heap_->Initialize(MEMORY_VIRTUAL_HEAP_LOW, MEMORY_VIRTUAL_HEAP_HIGH); virtual_heap_->Initialize(kMemoryVirtualHeapLow, kMemoryVirtualHeapHigh);
physical_heap_->Initialize(MEMORY_PHYSICAL_HEAP_LOW, physical_heap_->Initialize(kMemoryPhysicalHeapLow,
MEMORY_PHYSICAL_HEAP_HIGH - 0x1000); kMemoryPhysicalHeapHigh - 0x1000);
// GPU writeback. // GPU writeback.
// 0xC... is physical, 0x7F... is virtual. We may need to overlay these. // 0xC... is physical, 0x7F... is virtual. We may need to overlay these.
@ -212,9 +212,9 @@ int Memory::Initialize() {
} }
const static struct { const static struct {
uint64_t virtual_address_start; uint32_t virtual_address_start;
uint64_t virtual_address_end; uint32_t virtual_address_end;
uint64_t target_address; uint32_t target_address;
} map_info[] = { } map_info[] = {
0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages 0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages
0x40000000, 0x7EFFFFFF, 0x40000000, // (1024mb) - virtual 64k pages (cont) 0x40000000, 0x7EFFFFFF, 0x40000000, // (1024mb) - virtual 64k pages (cont)
@ -265,23 +265,23 @@ void Memory::UnmapViews() {
} }
} }
void Memory::Zero(uint64_t address, size_t size) { void Memory::Zero(uint32_t address, uint32_t size) {
uint8_t* p = membase_ + address; uint8_t* p = membase_ + address;
memset(p, 0, size); memset(p, 0, size);
} }
void Memory::Fill(uint64_t address, size_t size, uint8_t value) { void Memory::Fill(uint32_t address, uint32_t size, uint8_t value) {
uint8_t* p = membase_ + address; uint8_t* p = membase_ + address;
memset(p, value, size); memset(p, value, size);
} }
void Memory::Copy(uint64_t dest, uint64_t src, size_t size) { void Memory::Copy(uint32_t dest, uint32_t src, uint32_t size) {
uint8_t* pdest = membase_ + dest; uint8_t* pdest = membase_ + dest;
const uint8_t* psrc = membase_ + src; const uint8_t* psrc = membase_ + src;
memcpy(pdest, psrc, size); memcpy(pdest, psrc, size);
} }
uint64_t Memory::SearchAligned(uint64_t start, uint64_t end, uint32_t Memory::SearchAligned(uint32_t start, uint32_t end,
const uint32_t* values, size_t value_count) { const uint32_t* values, size_t value_count) {
assert_true(start <= end); assert_true(start <= end);
const uint32_t* p = reinterpret_cast<const uint32_t*>(membase_ + start); const uint32_t* p = reinterpret_cast<const uint32_t*>(membase_ + start);
@ -297,7 +297,7 @@ uint64_t Memory::SearchAligned(uint64_t start, uint64_t end,
matched++; matched++;
} }
if (matched == value_count) { if (matched == value_count) {
return uint64_t(reinterpret_cast<const uint8_t*>(p) - membase_); return uint32_t(reinterpret_cast<const uint8_t*>(p) - membase_);
} }
} }
p++; p++;
@ -305,7 +305,7 @@ uint64_t Memory::SearchAligned(uint64_t start, uint64_t end,
return 0; return 0;
} }
bool Memory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, bool Memory::AddMappedRange(uint32_t address, uint32_t mask, uint32_t size,
void* context, cpu::MMIOReadCallback read_callback, void* context, cpu::MMIOReadCallback read_callback,
cpu::MMIOWriteCallback write_callback) { cpu::MMIOWriteCallback write_callback) {
DWORD protect = PAGE_NOACCESS; DWORD protect = PAGE_NOACCESS;
@ -317,7 +317,7 @@ bool Memory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size,
read_callback, write_callback); read_callback, write_callback);
} }
uintptr_t Memory::AddWriteWatch(uint32_t guest_address, size_t length, uintptr_t Memory::AddWriteWatch(uint32_t guest_address, uint32_t length,
cpu::WriteWatchCallback callback, cpu::WriteWatchCallback callback,
void* callback_context, void* callback_data) { void* callback_context, void* callback_data) {
return mmio_handler_->AddWriteWatch(guest_address, length, callback, return mmio_handler_->AddWriteWatch(guest_address, length, callback,
@ -328,13 +328,13 @@ void Memory::CancelWriteWatch(uintptr_t watch_handle) {
mmio_handler_->CancelWriteWatch(watch_handle); mmio_handler_->CancelWriteWatch(watch_handle);
} }
uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, uint32_t Memory::HeapAlloc(uint32_t base_address, uint32_t size, uint32_t flags,
uint32_t alignment) { uint32_t alignment) {
// If we were given a base address we are outside of the normal heap and // If we were given a base address we are outside of the normal heap and
// will place wherever asked (so long as it doesn't overlap the heap). // will place wherever asked (so long as it doesn't overlap the heap).
if (!base_address) { if (!base_address) {
// Normal allocation from the managed heap. // Normal allocation from the managed heap.
uint64_t result; uint32_t result;
if (flags & MEMORY_FLAG_PHYSICAL) { if (flags & MEMORY_FLAG_PHYSICAL) {
result = physical_heap_->Alloc(base_address, size, flags, alignment); result = physical_heap_->Alloc(base_address, size, flags, alignment);
} else { } else {
@ -347,14 +347,14 @@ uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags,
} }
return result; return result;
} else { } else {
if (base_address >= MEMORY_VIRTUAL_HEAP_LOW && if (base_address >= kMemoryVirtualHeapLow &&
base_address < MEMORY_VIRTUAL_HEAP_HIGH) { base_address < kMemoryVirtualHeapHigh) {
// Overlapping managed heap. // Overlapping managed heap.
assert_always(); assert_always();
return 0; return 0;
} }
if (base_address >= MEMORY_PHYSICAL_HEAP_LOW && if (base_address >= kMemoryPhysicalHeapLow &&
base_address < MEMORY_PHYSICAL_HEAP_HIGH) { base_address < kMemoryPhysicalHeapHigh) {
// Overlapping managed heap. // Overlapping managed heap.
assert_always(); assert_always();
return 0; return 0;
@ -378,12 +378,11 @@ uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags,
} }
} }
int Memory::HeapFree(uint64_t address, size_t size) { int Memory::HeapFree(uint32_t address, uint32_t size) {
if (address >= MEMORY_VIRTUAL_HEAP_LOW && if (address >= kMemoryVirtualHeapLow && address < kMemoryVirtualHeapHigh) {
address < MEMORY_VIRTUAL_HEAP_HIGH) {
return virtual_heap_->Free(address, size) ? 0 : 1; return virtual_heap_->Free(address, size) ? 0 : 1;
} else if (address >= MEMORY_PHYSICAL_HEAP_LOW && } else if (address >= kMemoryPhysicalHeapLow &&
address < MEMORY_PHYSICAL_HEAP_HIGH) { address < kMemoryPhysicalHeapHigh) {
return physical_heap_->Free(address, size) ? 0 : 1; return physical_heap_->Free(address, size) ? 0 : 1;
} else { } else {
// A placed address. Decommit. // A placed address. Decommit.
@ -392,14 +391,14 @@ int Memory::HeapFree(uint64_t address, size_t size) {
} }
} }
bool Memory::QueryInformation(uint64_t base_address, AllocationInfo* mem_info) { bool Memory::QueryInformation(uint32_t base_address, AllocationInfo* mem_info) {
uint8_t* p = Translate(base_address); uint8_t* p = Translate(base_address);
MEMORY_BASIC_INFORMATION mbi; MEMORY_BASIC_INFORMATION mbi;
if (!VirtualQuery(p, &mbi, sizeof(mbi))) { if (!VirtualQuery(p, &mbi, sizeof(mbi))) {
return false; return false;
} }
mem_info->base_address = base_address; mem_info->base_address = base_address;
mem_info->allocation_base = static_cast<uint64_t>( mem_info->allocation_base = static_cast<uint32_t>(
reinterpret_cast<uint8_t*>(mbi.AllocationBase) - membase_); reinterpret_cast<uint8_t*>(mbi.AllocationBase) - membase_);
mem_info->allocation_protect = mbi.AllocationProtect; mem_info->allocation_protect = mbi.AllocationProtect;
mem_info->region_size = mbi.RegionSize; mem_info->region_size = mbi.RegionSize;
@ -409,19 +408,19 @@ bool Memory::QueryInformation(uint64_t base_address, AllocationInfo* mem_info) {
return true; return true;
} }
size_t Memory::QuerySize(uint64_t base_address) { uint32_t Memory::QuerySize(uint32_t base_address) {
if (base_address >= MEMORY_VIRTUAL_HEAP_LOW && if (base_address >= kMemoryVirtualHeapLow &&
base_address < MEMORY_VIRTUAL_HEAP_HIGH) { base_address < kMemoryVirtualHeapHigh) {
return virtual_heap_->QuerySize(base_address); return virtual_heap_->QuerySize(base_address);
} else if (base_address >= MEMORY_PHYSICAL_HEAP_LOW && } else if (base_address >= kMemoryPhysicalHeapLow &&
base_address < MEMORY_PHYSICAL_HEAP_HIGH) { base_address < kMemoryPhysicalHeapHigh) {
return physical_heap_->QuerySize(base_address); return physical_heap_->QuerySize(base_address);
} else { } else {
// A placed address. // A placed address.
uint8_t* p = Translate(base_address); uint8_t* p = Translate(base_address);
MEMORY_BASIC_INFORMATION mem_info; MEMORY_BASIC_INFORMATION mem_info;
if (VirtualQuery(p, &mem_info, sizeof(mem_info))) { if (VirtualQuery(p, &mem_info, sizeof(mem_info))) {
return mem_info.RegionSize; return uint32_t(mem_info.RegionSize);
} else { } else {
// Error. // Error.
return 0; return 0;
@ -429,7 +428,7 @@ size_t Memory::QuerySize(uint64_t base_address) {
} }
} }
int Memory::Protect(uint64_t address, size_t size, uint32_t access) { int Memory::Protect(uint32_t address, uint32_t size, uint32_t access) {
uint8_t* p = Translate(address); uint8_t* p = Translate(address);
size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; size_t heap_guard_size = FLAGS_heap_guard_pages * 4096;
@ -445,7 +444,7 @@ int Memory::Protect(uint64_t address, size_t size, uint32_t access) {
return VirtualProtect(p, size, new_protect, &old_protect) == TRUE ? 0 : 1; return VirtualProtect(p, size, new_protect, &old_protect) == TRUE ? 0 : 1;
} }
uint32_t Memory::QueryProtect(uint64_t address) { uint32_t Memory::QueryProtect(uint32_t address) {
uint8_t* p = Translate(address); uint8_t* p = Translate(address);
MEMORY_BASIC_INFORMATION info; MEMORY_BASIC_INFORMATION info;
size_t info_size = VirtualQuery((void*)p, &info, sizeof(info)); size_t info_size = VirtualQuery((void*)p, &info, sizeof(info));
@ -472,7 +471,7 @@ MemoryHeap::~MemoryHeap() {
} }
} }
int MemoryHeap::Initialize(uint64_t low, uint64_t high) { int MemoryHeap::Initialize(uint32_t low, uint32_t high) {
// Commit the memory where our heap will live and allocate it. // Commit the memory where our heap will live and allocate it.
// TODO(benvanik): replace dlmalloc with an implementation that can commit // TODO(benvanik): replace dlmalloc with an implementation that can commit
// as it goes. // as it goes.
@ -487,7 +486,7 @@ int MemoryHeap::Initialize(uint64_t low, uint64_t high) {
return 0; return 0;
} }
uint64_t MemoryHeap::Alloc(uint64_t base_address, size_t size, uint32_t flags, uint32_t MemoryHeap::Alloc(uint32_t base_address, uint32_t size, uint32_t flags,
uint32_t alignment) { uint32_t alignment) {
size_t alloc_size = size; size_t alloc_size = size;
if (int32_t(alloc_size) < 0) { if (int32_t(alloc_size) < 0) {
@ -538,13 +537,13 @@ uint64_t MemoryHeap::Alloc(uint64_t base_address, size_t size, uint32_t flags,
memset(p, 0xCD, alloc_size); memset(p, 0xCD, alloc_size);
} }
uint64_t address = uint32_t address =
(uint64_t)((uintptr_t)p - (uintptr_t)memory_->mapping_base_); (uint32_t)((uintptr_t)p - (uintptr_t)memory_->mapping_base_);
return address; return address;
} }
uint64_t MemoryHeap::Free(uint64_t address, size_t size) { uint32_t MemoryHeap::Free(uint32_t address, uint32_t size) {
uint8_t* p = memory_->Translate(address); uint8_t* p = memory_->Translate(address);
// Heap allocated address. // Heap allocated address.
@ -584,16 +583,16 @@ uint64_t MemoryHeap::Free(uint64_t address, size_t size) {
size, MEM_DECOMMIT); size, MEM_DECOMMIT);
} }
return (uint64_t)real_size; return static_cast<uint32_t>(real_size);
} }
size_t MemoryHeap::QuerySize(uint64_t base_address) { uint32_t MemoryHeap::QuerySize(uint32_t base_address) {
uint8_t* p = memory_->Translate(base_address); uint8_t* p = memory_->Translate(base_address);
// Heap allocated address. // Heap allocated address.
size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; uint32_t heap_guard_size = uint32_t(FLAGS_heap_guard_pages * 4096);
p -= heap_guard_size; p -= heap_guard_size;
size_t real_size = mspace_usable_size(p); uint32_t real_size = uint32_t(mspace_usable_size(p));
real_size -= heap_guard_size * 2; real_size -= heap_guard_size * 2;
if (!real_size) { if (!real_size) {
return 0; return 0;

View File

@ -19,8 +19,6 @@
#include "xenia/common.h" #include "xenia/common.h"
#include "xenia/cpu/mmio_handler.h" #include "xenia/cpu/mmio_handler.h"
typedef struct xe_ppc_state xe_ppc_state_t;
namespace xe { namespace xe {
class MemoryHeap; class MemoryHeap;
@ -35,8 +33,8 @@ enum {
// TODO(benvanik): move to heap. // TODO(benvanik): move to heap.
// Equivalent to the Win32 MEMORY_BASIC_INFORMATION struct. // Equivalent to the Win32 MEMORY_BASIC_INFORMATION struct.
struct AllocationInfo { struct AllocationInfo {
uint64_t base_address; uint32_t base_address;
uint64_t allocation_base; uint32_t allocation_base;
uint32_t allocation_protect; // TBD uint32_t allocation_protect; // TBD
size_t region_size; size_t region_size;
uint32_t state; // TBD uint32_t state; // TBD
@ -62,37 +60,37 @@ class Memory {
void set_trace_base(uint64_t value) { trace_base_ = value; } void set_trace_base(uint64_t value) { trace_base_ = value; }
// TODO(benvanik): make poly memory utils for these. // TODO(benvanik): make poly memory utils for these.
void Zero(uint64_t address, size_t size); void Zero(uint32_t address, uint32_t size);
void Fill(uint64_t address, size_t size, uint8_t value); void Fill(uint32_t address, uint32_t size, uint8_t value);
void Copy(uint64_t dest, uint64_t src, size_t size); void Copy(uint32_t dest, uint32_t src, uint32_t size);
uint64_t SearchAligned(uint64_t start, uint64_t end, const uint32_t* values, uint32_t SearchAligned(uint32_t start, uint32_t end, const uint32_t* values,
size_t value_count); size_t value_count);
bool AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, bool AddMappedRange(uint32_t address, uint32_t mask, uint32_t size,
void* context, cpu::MMIOReadCallback read_callback, void* context, cpu::MMIOReadCallback read_callback,
cpu::MMIOWriteCallback write_callback); cpu::MMIOWriteCallback write_callback);
uintptr_t AddWriteWatch(uint32_t guest_address, size_t length, uintptr_t AddWriteWatch(uint32_t guest_address, uint32_t length,
cpu::WriteWatchCallback callback, cpu::WriteWatchCallback callback,
void* callback_context, void* callback_data); void* callback_context, void* callback_data);
void CancelWriteWatch(uintptr_t watch_handle); void CancelWriteWatch(uintptr_t watch_handle);
uint64_t HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, uint32_t HeapAlloc(uint32_t base_address, uint32_t size, uint32_t flags,
uint32_t alignment = 0x20); uint32_t alignment = 0x20);
int HeapFree(uint64_t address, size_t size); int HeapFree(uint32_t address, uint32_t size);
bool QueryInformation(uint64_t base_address, AllocationInfo* mem_info); bool QueryInformation(uint32_t base_address, AllocationInfo* mem_info);
size_t QuerySize(uint64_t base_address); uint32_t QuerySize(uint32_t base_address);
int Protect(uint64_t address, size_t size, uint32_t access); int Protect(uint32_t address, uint32_t size, uint32_t access);
uint32_t QueryProtect(uint64_t address); uint32_t QueryProtect(uint32_t address);
private: private:
int MapViews(uint8_t* mapping_base); int MapViews(uint8_t* mapping_base);
void UnmapViews(); void UnmapViews();
private: private:
size_t system_page_size_; uint32_t system_page_size_;
uint8_t* membase_; uint8_t* membase_;
uint64_t reserve_address_; uint64_t reserve_address_;
uint64_t reserve_value_; uint64_t reserve_value_;