Converting addresses in xe::cpu to 32bit.
This commit is contained in:
parent
3279776a80
commit
281abea955
|
@ -229,7 +229,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) {
|
|||
|
||||
void X64Emitter::MarkSourceOffset(const Instr* i) {
|
||||
auto entry = source_map_arena_.Alloc<SourceMapEntry>();
|
||||
entry->source_offset = 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->code_offset = getSize();
|
||||
source_map_count_++;
|
||||
|
@ -477,12 +477,11 @@ const int kICSlotCount = 4;
|
|||
const int kICSlotSize = 23;
|
||||
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?
|
||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
||||
|
||||
// TODO(benvanik): required?
|
||||
target_address &= 0xFFFFFFFF;
|
||||
assert_not_zero(target_address);
|
||||
|
||||
Function* fn = NULL;
|
||||
|
|
|
@ -34,10 +34,11 @@ int X64Function::AddBreakpointImpl(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 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class X64Function : public Function {
|
|||
protected:
|
||||
virtual int AddBreakpointImpl(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:
|
||||
void* machine_code_;
|
||||
|
|
|
@ -38,7 +38,7 @@ void DebugInfo::InitializeSourceMap(size_t source_map_count,
|
|||
// 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.
|
||||
for (size_t n = 0; n < source_map_count_; n++) {
|
||||
auto entry = &source_map_[n];
|
||||
|
|
|
@ -37,7 +37,7 @@ enum TraceFlags {
|
|||
};
|
||||
|
||||
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 code_offset; // Offset from emitted code start.
|
||||
} SourceMapEntry;
|
||||
|
@ -57,7 +57,7 @@ class DebugInfo {
|
|||
void set_machine_code_disasm(char* value) { machine_code_disasm_ = value; }
|
||||
|
||||
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* LookupCodeOffset(uint64_t offset);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
namespace xe {
|
||||
namespace cpu {
|
||||
|
||||
Breakpoint::Breakpoint(Type type, uint64_t address)
|
||||
Breakpoint::Breakpoint(Type type, uint32_t address)
|
||||
: type_(type), address_(address) {}
|
||||
|
||||
Breakpoint::~Breakpoint() = default;
|
||||
|
@ -78,7 +78,7 @@ int Debugger::AddBreakpoint(Breakpoint* breakpoint) {
|
|||
{
|
||||
std::lock_guard<std::mutex> guard(breakpoints_lock_);
|
||||
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.
|
||||
|
@ -126,7 +126,7 @@ int Debugger::RemoveBreakpoint(Breakpoint* breakpoint) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Debugger::FindBreakpoints(uint64_t address,
|
||||
void Debugger::FindBreakpoints(uint32_t address,
|
||||
std::vector<Breakpoint*>& out_breakpoints) {
|
||||
std::lock_guard<std::mutex> guard(breakpoints_lock_);
|
||||
|
||||
|
@ -162,7 +162,7 @@ void Debugger::OnFunctionDefined(FunctionInfo* symbol_info,
|
|||
std::vector<Breakpoint*> breakpoints;
|
||||
{
|
||||
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) {
|
||||
auto range = breakpoints_.equal_range(address);
|
||||
if (range.first == range.second) {
|
||||
|
|
|
@ -34,18 +34,18 @@ class Breakpoint {
|
|||
};
|
||||
|
||||
public:
|
||||
Breakpoint(Type type, uint64_t address);
|
||||
Breakpoint(Type type, uint32_t address);
|
||||
~Breakpoint();
|
||||
|
||||
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(); }
|
||||
void set_id(const char* id) { id_ = std::string(id); }
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
uint64_t address_;
|
||||
uint32_t address_;
|
||||
|
||||
std::string id_;
|
||||
};
|
||||
|
@ -91,7 +91,7 @@ class Debugger {
|
|||
|
||||
int AddBreakpoint(Breakpoint* breakpoint);
|
||||
int RemoveBreakpoint(Breakpoint* breakpoint);
|
||||
void FindBreakpoints(uint64_t address,
|
||||
void FindBreakpoints(uint32_t address,
|
||||
std::vector<Breakpoint*>& out_breakpoints);
|
||||
|
||||
// TODO(benvanik): utility functions for modification (make function ignored,
|
||||
|
@ -113,7 +113,7 @@ class Debugger {
|
|||
std::unordered_map<uint32_t, ThreadState*> threads_;
|
||||
|
||||
std::mutex breakpoints_lock_;
|
||||
std::multimap<uint64_t, Breakpoint*> breakpoints_;
|
||||
std::multimap<uint32_t, Breakpoint*> breakpoints_;
|
||||
};
|
||||
|
||||
} // namespace cpu
|
||||
|
|
|
@ -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_);
|
||||
const auto& it = map_.find(address);
|
||||
Entry* entry = it != map_.end() ? it->second : nullptr;
|
||||
|
@ -38,7 +38,7 @@ Entry* EntryTable::Get(uint64_t address) {
|
|||
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.
|
||||
// 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;
|
||||
}
|
||||
|
||||
std::vector<Function*> EntryTable::FindWithAddress(uint64_t address) {
|
||||
std::vector<Function*> EntryTable::FindWithAddress(uint32_t address) {
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
std::vector<Function*> fns;
|
||||
for (auto& it : map_) {
|
||||
|
|
|
@ -27,8 +27,8 @@ typedef struct Entry_t {
|
|||
STATUS_FAILED,
|
||||
} Status;
|
||||
|
||||
uint64_t address;
|
||||
uint64_t end_address;
|
||||
uint32_t address;
|
||||
uint32_t end_address;
|
||||
Status status;
|
||||
Function* function;
|
||||
} Entry;
|
||||
|
@ -38,15 +38,15 @@ class EntryTable {
|
|||
EntryTable();
|
||||
~EntryTable();
|
||||
|
||||
Entry* Get(uint64_t address);
|
||||
Entry::Status GetOrCreate(uint64_t address, Entry** out_entry);
|
||||
Entry* Get(uint32_t address);
|
||||
Entry::Status GetOrCreate(uint32_t address, Entry** out_entry);
|
||||
|
||||
std::vector<Function*> FindWithAddress(uint64_t address);
|
||||
std::vector<Function*> FindWithAddress(uint32_t address);
|
||||
|
||||
private:
|
||||
// TODO(benvanik): replace with a better data structure.
|
||||
std::mutex lock_;
|
||||
std::unordered_map<uint64_t, Entry*> map_;
|
||||
std::unordered_map<uint32_t, Entry*> map_;
|
||||
};
|
||||
|
||||
} // namespace cpu
|
||||
|
|
|
@ -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.
|
||||
// Unless it's to ourselves directly, in which case it's
|
||||
// recursion.
|
||||
uint64_t nia_value = nia->AsUint64() & 0xFFFFFFFF;
|
||||
uint32_t nia_value = nia->AsUint64() & 0xFFFFFFFF;
|
||||
bool is_recursion = false;
|
||||
if (nia_value == f.symbol_info()->address() && lk) {
|
||||
is_recursion = true;
|
||||
|
|
|
@ -74,10 +74,10 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
|
|||
// Always mark entry with label.
|
||||
label_list_[0] = NewLabel();
|
||||
|
||||
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;
|
||||
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);
|
||||
|
@ -166,15 +166,14 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
|
|||
return Finalize();
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) {
|
||||
void PPCHIRBuilder::AnnotateLabel(uint32_t address, Label* label) {
|
||||
char name_buffer[13];
|
||||
snprintf(name_buffer, poly::countof(name_buffer), "loc_%.8X",
|
||||
(uint32_t)address);
|
||||
snprintf(name_buffer, poly::countof(name_buffer), "loc_%.8X", address);
|
||||
label->name = (char*)arena_->Alloc(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();
|
||||
FunctionInfo* symbol_info;
|
||||
if (runtime->LookupFunctionInfo(address, &symbol_info)) {
|
||||
|
@ -183,7 +182,7 @@ FunctionInfo* PPCHIRBuilder::LookupFunction(uint64_t address) {
|
|||
return symbol_info;
|
||||
}
|
||||
|
||||
Label* PPCHIRBuilder::LookupLabel(uint64_t address) {
|
||||
Label* PPCHIRBuilder::LookupLabel(uint32_t address) {
|
||||
if (address < start_address_) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ class PPCHIRBuilder : public hir::HIRBuilder {
|
|||
int Emit(FunctionInfo* symbol_info, uint32_t flags);
|
||||
|
||||
FunctionInfo* symbol_info() const { return symbol_info_; }
|
||||
FunctionInfo* LookupFunction(uint64_t address);
|
||||
Label* LookupLabel(uint64_t address);
|
||||
FunctionInfo* LookupFunction(uint32_t address);
|
||||
Label* LookupLabel(uint32_t address);
|
||||
|
||||
Value* LoadLR();
|
||||
void StoreLR(Value* value);
|
||||
|
@ -85,7 +85,7 @@ class PPCHIRBuilder : public hir::HIRBuilder {
|
|||
Value* StoreRelease(Value* address, Value* value, uint32_t store_flags = 0);
|
||||
|
||||
private:
|
||||
void AnnotateLabel(uint64_t address, Label* label);
|
||||
void AnnotateLabel(uint32_t address, Label* label);
|
||||
|
||||
private:
|
||||
PPCFrontend* frontend_;
|
||||
|
|
|
@ -33,7 +33,7 @@ PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {}
|
|||
|
||||
PPCScanner::~PPCScanner() {}
|
||||
|
||||
bool PPCScanner::IsRestGprLr(uint64_t address) {
|
||||
bool PPCScanner::IsRestGprLr(uint32_t address) {
|
||||
FunctionInfo* symbol_info;
|
||||
if (frontend_->runtime()->LookupFunctionInfo(address, &symbol_info)) {
|
||||
return false;
|
||||
|
@ -283,14 +283,14 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
|
|||
Memory* memory = frontend_->memory();
|
||||
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();
|
||||
uint64_t end_address = symbol_info->end_address();
|
||||
uint32_t start_address = symbol_info->address();
|
||||
uint32_t end_address = symbol_info->end_address();
|
||||
bool in_block = false;
|
||||
uint64_t block_start = 0;
|
||||
uint32_t block_start = 0;
|
||||
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.code = poly::load_and_swap<uint32_t>(p + address);
|
||||
if (!i.code) {
|
||||
|
|
|
@ -21,8 +21,8 @@ namespace frontend {
|
|||
class PPCFrontend;
|
||||
|
||||
typedef struct BlockInfo_t {
|
||||
uint64_t start_address;
|
||||
uint64_t end_address;
|
||||
uint32_t start_address;
|
||||
uint32_t end_address;
|
||||
} BlockInfo;
|
||||
|
||||
class PPCScanner {
|
||||
|
@ -35,7 +35,7 @@ class PPCScanner {
|
|||
std::vector<BlockInfo> FindBlocks(FunctionInfo* symbol_info);
|
||||
|
||||
private:
|
||||
bool IsRestGprLr(uint64_t address);
|
||||
bool IsRestGprLr(uint32_t address);
|
||||
|
||||
private:
|
||||
PPCFrontend* frontend_;
|
||||
|
|
|
@ -37,9 +37,9 @@ typedef std::vector<std::pair<std::string, std::string>> AnnotationList;
|
|||
const uint32_t START_ADDRESS = 0x100000;
|
||||
|
||||
struct TestCase {
|
||||
TestCase(uint64_t address, std::string& name)
|
||||
TestCase(uint32_t address, std::string& name)
|
||||
: address(address), name(name) {}
|
||||
uint64_t address;
|
||||
uint32_t address;
|
||||
std::string name;
|
||||
AnnotationList annotations;
|
||||
};
|
||||
|
@ -111,8 +111,7 @@ class TestSuite {
|
|||
}
|
||||
std::string address(line_buffer, t_test_ - line_buffer);
|
||||
std::string name(t_test_ + strlen(" t test_"));
|
||||
test_cases.emplace_back(START_ADDRESS + std::stoull(address, 0, 16),
|
||||
name);
|
||||
test_cases.emplace_back(START_ADDRESS + std::stoul(address, 0, 16), name);
|
||||
}
|
||||
fclose(f);
|
||||
return true;
|
||||
|
@ -195,9 +194,9 @@ class TestRunner {
|
|||
runtime->AddModule(std::move(module));
|
||||
|
||||
// Simulate a thread.
|
||||
uint64_t stack_size = 64 * 1024;
|
||||
uint64_t stack_address = START_ADDRESS - stack_size;
|
||||
uint64_t thread_state_address = stack_address - 0x1000;
|
||||
uint32_t stack_size = 64 * 1024;
|
||||
uint32_t stack_address = START_ADDRESS - stack_size;
|
||||
uint32_t thread_state_address = stack_address - 0x1000;
|
||||
thread_state.reset(new ThreadState(runtime.get(), 0x100, stack_address,
|
||||
stack_size, thread_state_address));
|
||||
|
||||
|
@ -221,7 +220,7 @@ class TestRunner {
|
|||
|
||||
auto ctx = thread_state->context();
|
||||
ctx->lr = 0xBEBEBEBE;
|
||||
fn->Call(thread_state.get(), ctx->lr);
|
||||
fn->Call(thread_state.get(), uint32_t(ctx->lr));
|
||||
|
||||
// Assert test state expectations.
|
||||
bool result = CheckTestResults(test_case);
|
||||
|
|
|
@ -53,7 +53,7 @@ int Function::RemoveBreakpoint(Breakpoint* breakpoint) {
|
|||
return found ? 0 : 1;
|
||||
}
|
||||
|
||||
Breakpoint* Function::FindBreakpoint(uint64_t address) {
|
||||
Breakpoint* Function::FindBreakpoint(uint32_t address) {
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
Breakpoint* result = nullptr;
|
||||
for (auto breakpoint : breakpoints_) {
|
||||
|
@ -65,7 +65,7 @@ Breakpoint* Function::FindBreakpoint(uint64_t address) {
|
|||
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");
|
||||
|
||||
ThreadState* original_thread_state = ThreadState::Get();
|
||||
|
|
|
@ -28,7 +28,7 @@ class Function {
|
|||
Function(FunctionInfo* symbol_info);
|
||||
virtual ~Function();
|
||||
|
||||
uint64_t address() const { return address_; }
|
||||
uint32_t address() const { return address_; }
|
||||
FunctionInfo* symbol_info() const { return symbol_info_; }
|
||||
|
||||
DebugInfo* debug_info() const { return debug_info_.get(); }
|
||||
|
@ -39,16 +39,16 @@ class Function {
|
|||
int AddBreakpoint(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:
|
||||
Breakpoint* FindBreakpoint(uint64_t address);
|
||||
Breakpoint* FindBreakpoint(uint32_t address);
|
||||
virtual int AddBreakpointImpl(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:
|
||||
uint64_t address_;
|
||||
uint32_t address_;
|
||||
FunctionInfo* symbol_info_;
|
||||
std::unique_ptr<DebugInfo> debug_info_;
|
||||
|
||||
|
|
|
@ -78,8 +78,8 @@ void FunctionInstrument::Exit(ThreadState* thread_state) {
|
|||
//
|
||||
}
|
||||
|
||||
MemoryInstrument::MemoryInstrument(Runtime* runtime, uint64_t address,
|
||||
uint64_t end_address)
|
||||
MemoryInstrument::MemoryInstrument(Runtime* runtime, uint32_t address,
|
||||
uint32_t end_address)
|
||||
: Instrument(runtime), address_(address), end_address_(end_address) {}
|
||||
|
||||
bool MemoryInstrument::Attach() {
|
||||
|
@ -103,7 +103,7 @@ bool MemoryInstrument::Detach() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void MemoryInstrument::Access(ThreadState* thread_state, uint64_t address,
|
||||
void MemoryInstrument::Access(ThreadState* thread_state, uint32_t address,
|
||||
AccessType type) {
|
||||
// TODO(benvanik): get thread local instance
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ class FunctionInstrument : public Instrument {
|
|||
|
||||
class MemoryInstrument : public Instrument {
|
||||
public:
|
||||
MemoryInstrument(Runtime* runtime, uint64_t address, uint64_t end_address);
|
||||
MemoryInstrument(Runtime* runtime, uint32_t address, uint32_t end_address);
|
||||
virtual ~MemoryInstrument() {}
|
||||
|
||||
uint64_t address() const { return address_; }
|
||||
|
@ -100,7 +100,7 @@ class MemoryInstrument : public Instrument {
|
|||
ACCESS_READ = (1 << 1),
|
||||
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:
|
||||
class Instance {
|
||||
|
@ -110,7 +110,7 @@ class MemoryInstrument : public 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;
|
||||
|
||||
private:
|
||||
|
@ -118,8 +118,8 @@ class MemoryInstrument : public Instrument {
|
|||
};
|
||||
|
||||
private:
|
||||
uint64_t address_;
|
||||
uint64_t end_address_;
|
||||
uint32_t address_;
|
||||
uint32_t end_address_;
|
||||
};
|
||||
|
||||
// ThreadInstrument
|
||||
|
|
|
@ -24,9 +24,9 @@ Module::Module(Runtime* runtime)
|
|||
|
||||
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();
|
||||
const auto it = map_.find(address);
|
||||
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,
|
||||
uint64_t address,
|
||||
uint32_t address,
|
||||
SymbolInfo** out_symbol_info) {
|
||||
*out_symbol_info = nullptr;
|
||||
lock_.lock();
|
||||
|
@ -100,7 +100,7 @@ SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type,
|
|||
return status;
|
||||
}
|
||||
|
||||
SymbolInfo::Status Module::DeclareFunction(uint64_t address,
|
||||
SymbolInfo::Status Module::DeclareFunction(uint32_t address,
|
||||
FunctionInfo** out_symbol_info) {
|
||||
SymbolInfo* symbol_info;
|
||||
SymbolInfo::Status status =
|
||||
|
@ -109,7 +109,7 @@ SymbolInfo::Status Module::DeclareFunction(uint64_t address,
|
|||
return status;
|
||||
}
|
||||
|
||||
SymbolInfo::Status Module::DeclareVariable(uint64_t address,
|
||||
SymbolInfo::Status Module::DeclareVariable(uint32_t address,
|
||||
VariableInfo** out_symbol_info) {
|
||||
SymbolInfo* symbol_info;
|
||||
SymbolInfo::Status status =
|
||||
|
|
|
@ -34,12 +34,12 @@ class Module {
|
|||
|
||||
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);
|
||||
virtual SymbolInfo::Status DeclareFunction(uint64_t address,
|
||||
SymbolInfo* LookupSymbol(uint32_t address, bool wait = true);
|
||||
virtual SymbolInfo::Status DeclareFunction(uint32_t address,
|
||||
FunctionInfo** out_symbol_info);
|
||||
virtual SymbolInfo::Status DeclareVariable(uint64_t address,
|
||||
virtual SymbolInfo::Status DeclareVariable(uint32_t address,
|
||||
VariableInfo** out_symbol_info);
|
||||
|
||||
SymbolInfo::Status DefineFunction(FunctionInfo* symbol_info);
|
||||
|
@ -52,7 +52,7 @@ class Module {
|
|||
int ReadMap(const char* file_name);
|
||||
|
||||
private:
|
||||
SymbolInfo::Status DeclareSymbol(SymbolInfo::Type type, uint64_t address,
|
||||
SymbolInfo::Status DeclareSymbol(SymbolInfo::Type type, uint32_t address,
|
||||
SymbolInfo** out_symbol_info);
|
||||
SymbolInfo::Status DefineSymbol(SymbolInfo* symbol_info);
|
||||
|
||||
|
@ -63,7 +63,7 @@ class Module {
|
|||
private:
|
||||
// TODO(benvanik): replace with a better data structure.
|
||||
std::mutex lock_;
|
||||
std::unordered_map<uint64_t, SymbolInfo*> map_;
|
||||
std::unordered_map<uint32_t, SymbolInfo*> map_;
|
||||
std::vector<std::unique_ptr<SymbolInfo>> list_;
|
||||
};
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ int Processor::Setup() {
|
|||
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");
|
||||
|
||||
// Attempt to get the function.
|
||||
|
@ -129,7 +129,7 @@ int Processor::Execute(ThreadState* thread_state, uint64_t address) {
|
|||
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) {
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
|
@ -155,7 +155,7 @@ void Processor::LowerIrql(Irql old_value) {
|
|||
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) {
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
|
|
|
@ -42,14 +42,14 @@ class Processor {
|
|||
|
||||
int Setup();
|
||||
|
||||
int Execute(ThreadState* thread_state, uint64_t address);
|
||||
uint64_t Execute(ThreadState* thread_state, uint64_t address, uint64_t args[],
|
||||
int Execute(ThreadState* thread_state, uint32_t address);
|
||||
uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t args[],
|
||||
size_t arg_count);
|
||||
|
||||
Irql RaiseIrql(Irql new_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);
|
||||
|
||||
private:
|
||||
|
@ -61,7 +61,7 @@ class Processor {
|
|||
Irql irql_;
|
||||
std::mutex interrupt_thread_lock_;
|
||||
ThreadState* interrupt_thread_state_;
|
||||
uint64_t interrupt_thread_block_;
|
||||
uint32_t interrupt_thread_block_;
|
||||
};
|
||||
|
||||
} // namespace cpu
|
||||
|
|
|
@ -20,11 +20,11 @@ RawModule::RawModule(Runtime* runtime)
|
|||
|
||||
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));
|
||||
FILE* file = fopen(fixed_path.c_str(), "rb");
|
||||
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);
|
||||
|
||||
// Allocate memory.
|
||||
|
@ -52,7 +52,7 @@ int RawModule::LoadFile(uint64_t base_address, const std::wstring& path) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool RawModule::ContainsAddress(uint64_t address) {
|
||||
bool RawModule::ContainsAddress(uint32_t address) {
|
||||
return address >= low_address_ && address < high_address_;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,17 +22,17 @@ class RawModule : public Module {
|
|||
RawModule(Runtime* runtime);
|
||||
~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_; }
|
||||
|
||||
bool ContainsAddress(uint64_t address) override;
|
||||
bool ContainsAddress(uint32_t address) override;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
uint64_t base_address_;
|
||||
uint64_t low_address_;
|
||||
uint64_t high_address_;
|
||||
uint32_t base_address_;
|
||||
uint32_t low_address_;
|
||||
uint32_t high_address_;
|
||||
};
|
||||
|
||||
} // namespace cpu
|
||||
|
|
|
@ -29,7 +29,7 @@ class BuiltinModule : public Module {
|
|||
public:
|
||||
BuiltinModule(Runtime* runtime) : Module(runtime), name_("builtin") {}
|
||||
const std::string& name() const override { return name_; }
|
||||
bool ContainsAddress(uint64_t address) override {
|
||||
bool ContainsAddress(uint32_t address) override {
|
||||
return (address & 0x1FFFFFFF0) == 0x100000000;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ Runtime::Runtime(Memory* memory, ExportResolver* export_resolver,
|
|||
debug_info_flags_(debug_info_flags),
|
||||
trace_flags_(trace_flags),
|
||||
builtin_module_(nullptr),
|
||||
next_builtin_address_(0x100000000ull),
|
||||
next_builtin_address_(0xFFFF0000ul),
|
||||
export_resolver_(export_resolver) {}
|
||||
|
||||
Runtime::~Runtime() {
|
||||
|
@ -138,7 +138,7 @@ std::vector<Module*> Runtime::GetModules() {
|
|||
FunctionInfo* Runtime::DefineBuiltin(const std::string& name,
|
||||
FunctionInfo::ExternHandler handler,
|
||||
void* arg0, void* arg1) {
|
||||
uint64_t address = next_builtin_address_;
|
||||
uint32_t address = next_builtin_address_;
|
||||
next_builtin_address_ += 4;
|
||||
|
||||
FunctionInfo* fn_info;
|
||||
|
@ -151,11 +151,11 @@ FunctionInfo* Runtime::DefineBuiltin(const std::string& name,
|
|||
return fn_info;
|
||||
}
|
||||
|
||||
std::vector<Function*> Runtime::FindFunctionsWithAddress(uint64_t address) {
|
||||
std::vector<Function*> Runtime::FindFunctionsWithAddress(uint32_t 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;
|
||||
Entry* 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) {
|
||||
*out_symbol_info = nullptr;
|
||||
|
||||
|
@ -214,7 +214,7 @@ int Runtime::LookupFunctionInfo(uint64_t address,
|
|||
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) {
|
||||
// Atomic create/lookup symbol in module.
|
||||
// If we get back the NEW flag we must declare it now.
|
||||
|
|
|
@ -48,12 +48,12 @@ class Runtime {
|
|||
FunctionInfo::ExternHandler handler, void* arg0,
|
||||
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(Module* module, uint64_t address,
|
||||
int LookupFunctionInfo(uint32_t address, FunctionInfo** out_symbol_info);
|
||||
int LookupFunctionInfo(Module* module, uint32_t address,
|
||||
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);
|
||||
|
||||
|
@ -75,7 +75,7 @@ class Runtime {
|
|||
std::mutex modules_lock_;
|
||||
std::vector<std::unique_ptr<Module>> modules_;
|
||||
Module* builtin_module_;
|
||||
uint64_t next_builtin_address_;
|
||||
uint32_t next_builtin_address_;
|
||||
};
|
||||
|
||||
} // namespace cpu
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
namespace xe {
|
||||
namespace cpu {
|
||||
|
||||
SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address)
|
||||
SymbolInfo::SymbolInfo(Type type, Module* module, uint32_t address)
|
||||
: type_(type),
|
||||
module_(module),
|
||||
status_(STATUS_DEFINING),
|
||||
|
@ -21,7 +21,7 @@ SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address)
|
|||
|
||||
SymbolInfo::~SymbolInfo() = default;
|
||||
|
||||
FunctionInfo::FunctionInfo(Module* module, uint64_t address)
|
||||
FunctionInfo::FunctionInfo(Module* module, uint32_t address)
|
||||
: SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address),
|
||||
end_address_(0),
|
||||
behavior_(BEHAVIOR_DEFAULT),
|
||||
|
@ -38,7 +38,7 @@ void FunctionInfo::SetupExtern(ExternHandler handler, void* arg0, void* 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) {}
|
||||
|
||||
VariableInfo::~VariableInfo() = default;
|
||||
|
|
|
@ -35,14 +35,14 @@ class SymbolInfo {
|
|||
};
|
||||
|
||||
public:
|
||||
SymbolInfo(Type type, Module* module, uint64_t address);
|
||||
SymbolInfo(Type type, Module* module, uint32_t address);
|
||||
virtual ~SymbolInfo();
|
||||
|
||||
Type type() const { return type_; }
|
||||
Module* module() const { return module_; }
|
||||
Status status() const { return status_; }
|
||||
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_; }
|
||||
void set_name(const std::string& value) { name_ = value; }
|
||||
|
@ -51,7 +51,7 @@ class SymbolInfo {
|
|||
Type type_;
|
||||
Module* module_;
|
||||
Status status_;
|
||||
uint64_t address_;
|
||||
uint32_t address_;
|
||||
|
||||
std::string name_;
|
||||
};
|
||||
|
@ -67,12 +67,12 @@ class FunctionInfo : public SymbolInfo {
|
|||
};
|
||||
|
||||
public:
|
||||
FunctionInfo(Module* module, uint64_t address);
|
||||
FunctionInfo(Module* module, uint32_t address);
|
||||
~FunctionInfo() override;
|
||||
|
||||
bool has_end_address() const { return end_address_ > 0; }
|
||||
uint64_t end_address() const { return end_address_; }
|
||||
void set_end_address(uint64_t value) { end_address_ = value; }
|
||||
uint32_t end_address() const { return end_address_; }
|
||||
void set_end_address(uint32_t value) { end_address_ = value; }
|
||||
|
||||
Behavior behavior() const { return behavior_; }
|
||||
void set_behavior(Behavior value) { behavior_ = value; }
|
||||
|
@ -87,7 +87,7 @@ class FunctionInfo : public SymbolInfo {
|
|||
void* extern_arg1() const { return extern_info_.arg1; }
|
||||
|
||||
private:
|
||||
uint64_t end_address_;
|
||||
uint32_t end_address_;
|
||||
Behavior behavior_;
|
||||
Function* function_;
|
||||
struct {
|
||||
|
@ -99,7 +99,7 @@ class FunctionInfo : public SymbolInfo {
|
|||
|
||||
class VariableInfo : public SymbolInfo {
|
||||
public:
|
||||
VariableInfo(Module* module, uint64_t address);
|
||||
VariableInfo(Module* module, uint32_t address);
|
||||
~VariableInfo() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -72,9 +72,9 @@ class TestFunction {
|
|||
xe::cpu::Function* fn;
|
||||
runtime->ResolveFunction(0x1000, &fn);
|
||||
|
||||
uint64_t stack_size = 64 * 1024;
|
||||
uint64_t stack_address = memory_size - stack_size;
|
||||
uint64_t thread_state_address = stack_address - 0x1000;
|
||||
uint32_t stack_size = 64 * 1024;
|
||||
uint32_t stack_address = memory_size - stack_size;
|
||||
uint32_t thread_state_address = stack_address - 0x1000;
|
||||
auto thread_state =
|
||||
std::make_unique<ThreadState>(runtime.get(), 0x100, stack_address,
|
||||
stack_size, thread_state_address);
|
||||
|
@ -83,13 +83,13 @@ class TestFunction {
|
|||
|
||||
pre_call(ctx);
|
||||
|
||||
fn->Call(thread_state.get(), ctx->lr);
|
||||
fn->Call(thread_state.get(), uint32_t(ctx->lr));
|
||||
|
||||
post_call(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
size_t memory_size;
|
||||
uint32_t memory_size;
|
||||
std::unique_ptr<Memory> memory;
|
||||
std::vector<std::unique_ptr<Runtime>> runtimes;
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ using xe::cpu::hir::HIRBuilder;
|
|||
namespace passes = xe::cpu::compiler::passes;
|
||||
|
||||
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)
|
||||
: Module(runtime),
|
||||
name_(name),
|
||||
|
@ -66,11 +66,11 @@ TestModule::TestModule(Runtime* runtime, const std::string& name,
|
|||
|
||||
TestModule::~TestModule() = default;
|
||||
|
||||
bool TestModule::ContainsAddress(uint64_t address) {
|
||||
bool TestModule::ContainsAddress(uint32_t address) {
|
||||
return contains_address_(address);
|
||||
}
|
||||
|
||||
SymbolInfo::Status TestModule::DeclareFunction(uint64_t address,
|
||||
SymbolInfo::Status TestModule::DeclareFunction(uint32_t address,
|
||||
FunctionInfo** out_symbol_info) {
|
||||
SymbolInfo::Status status = Module::DeclareFunction(address, out_symbol_info);
|
||||
if (status == SymbolInfo::STATUS_NEW) {
|
||||
|
|
|
@ -25,20 +25,20 @@ namespace cpu {
|
|||
class TestModule : public Module {
|
||||
public:
|
||||
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);
|
||||
~TestModule() override;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
std::function<bool(uint64_t)> contains_address_;
|
||||
std::function<bool(uint32_t)> contains_address_;
|
||||
std::function<bool(hir::HIRBuilder&)> generate_;
|
||||
|
||||
std::unique_ptr<hir::HIRBuilder> builder_;
|
||||
|
|
|
@ -22,8 +22,8 @@ using PPCContext = xe::cpu::frontend::PPCContext;
|
|||
thread_local ThreadState* thread_state_ = nullptr;
|
||||
|
||||
ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id,
|
||||
uint64_t stack_address, size_t stack_size,
|
||||
uint64_t thread_state_address)
|
||||
uint32_t stack_address, uint32_t stack_size,
|
||||
uint32_t thread_state_address)
|
||||
: runtime_(runtime),
|
||||
memory_(runtime->memory()),
|
||||
thread_id_(thread_id),
|
||||
|
|
|
@ -28,8 +28,8 @@ class Runtime;
|
|||
|
||||
class ThreadState {
|
||||
public:
|
||||
ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address,
|
||||
size_t stack_size, uint64_t thread_state_address);
|
||||
ThreadState(Runtime* runtime, uint32_t thread_id, uint32_t stack_address,
|
||||
uint32_t stack_size, uint32_t thread_state_address);
|
||||
~ThreadState();
|
||||
|
||||
Runtime* runtime() const { return runtime_; }
|
||||
|
@ -39,9 +39,9 @@ class ThreadState {
|
|||
void set_name(const std::string& value) { name_ = value; }
|
||||
void* backend_data() const { return backend_data_; }
|
||||
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_; }
|
||||
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_; }
|
||||
|
||||
int Suspend() { return Suspend(~0); }
|
||||
|
@ -61,10 +61,10 @@ class ThreadState {
|
|||
std::string name_;
|
||||
void* backend_data_;
|
||||
void* raw_context_;
|
||||
uint64_t stack_address_;
|
||||
uint32_t stack_address_;
|
||||
bool stack_allocated_;
|
||||
size_t stack_size_;
|
||||
uint64_t thread_state_address_;
|
||||
uint32_t stack_size_;
|
||||
uint32_t thread_state_address_;
|
||||
|
||||
// NOTE: must be 64b aligned for SSE ops.
|
||||
xe::cpu::frontend::PPCContext* context_;
|
||||
|
|
|
@ -35,11 +35,10 @@ XexModule::XexModule(Runtime* runtime)
|
|||
low_address_(0),
|
||||
high_address_(0) {}
|
||||
|
||||
XexModule::~XexModule() {
|
||||
xe_xex2_dealloc(xex_);
|
||||
}
|
||||
XexModule::~XexModule() { 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;
|
||||
|
||||
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.
|
||||
low_address_ = UINT_MAX;
|
||||
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 size_t start_address = header->exe_address + (i * section->page_size);
|
||||
const size_t end_address =
|
||||
const uint32_t start_address =
|
||||
header->exe_address + (i * section->page_size);
|
||||
const uint32_t end_address =
|
||||
start_address + (section->info.page_count * section->page_size);
|
||||
if (section->info.type == XEX_SECTION_CODE) {
|
||||
low_address_ =
|
||||
static_cast<uint32_t>(std::min(low_address_, start_address));
|
||||
high_address_ =
|
||||
static_cast<uint32_t>(std::max(high_address_, end_address));
|
||||
low_address_ = std::min(low_address_, start_address);
|
||||
high_address_ = std::max(high_address_, end_address);
|
||||
}
|
||||
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;
|
||||
size_t import_info_count;
|
||||
if (xe_xex2_get_import_infos(
|
||||
xex_, library, &import_infos, &import_info_count)) {
|
||||
if (xe_xex2_get_import_infos(xex_, library, &import_infos,
|
||||
&import_info_count)) {
|
||||
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++) {
|
||||
const xe_xex2_import_info_t* info = &import_infos[n];
|
||||
|
||||
KernelExport* kernel_export = export_resolver->GetExportByOrdinal(
|
||||
library->name, info->ordinal);
|
||||
KernelExport* kernel_export =
|
||||
export_resolver->GetExportByOrdinal(library->name, info->ordinal);
|
||||
|
||||
if (kernel_export) {
|
||||
if (info->thunk_address) {
|
||||
|
@ -118,15 +116,15 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
|
|||
}
|
||||
} else {
|
||||
snprintf(name, poly::countof(name), "__imp_%s_%.3X", library->name,
|
||||
info->ordinal);
|
||||
info->ordinal);
|
||||
}
|
||||
|
||||
VariableInfo* var_info;
|
||||
DeclareVariable(info->value_address, &var_info);
|
||||
//var->set_name(name);
|
||||
// var->set_name(name);
|
||||
var_info->set_status(SymbolInfo::STATUS_DECLARED);
|
||||
DefineVariable(var_info);
|
||||
//var->kernel_export = kernel_export;
|
||||
// var->kernel_export = kernel_export;
|
||||
var_info->set_status(SymbolInfo::STATUS_DEFINED);
|
||||
|
||||
// Grab, if available.
|
||||
|
@ -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);
|
||||
} else {
|
||||
// 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",
|
||||
kernel_export->name);
|
||||
}
|
||||
|
@ -186,7 +185,8 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
|
|||
FunctionInfo::ExternHandler handler = 0;
|
||||
void* handler_data = 0;
|
||||
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;
|
||||
} else {
|
||||
handler = (FunctionInfo::ExternHandler)UndefinedImport;
|
||||
|
@ -205,7 +205,7 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool XexModule::ContainsAddress(uint64_t address) {
|
||||
bool XexModule::ContainsAddress(uint32_t address) {
|
||||
return address >= low_address_ && address < high_address_;
|
||||
}
|
||||
|
||||
|
@ -217,180 +217,173 @@ int XexModule::FindSaveRest() {
|
|||
// __savegprlr_14 to __savegprlr_31
|
||||
// __restgprlr_14 to __restgprlr_31
|
||||
static const uint32_t gprlr_code_values[] = {
|
||||
0x68FFC1F9, // __savegprlr_14
|
||||
0x70FFE1F9, // __savegprlr_15
|
||||
0x78FF01FA, // __savegprlr_16
|
||||
0x80FF21FA, // __savegprlr_17
|
||||
0x88FF41FA, // __savegprlr_18
|
||||
0x90FF61FA, // __savegprlr_19
|
||||
0x98FF81FA, // __savegprlr_20
|
||||
0xA0FFA1FA, // __savegprlr_21
|
||||
0xA8FFC1FA, // __savegprlr_22
|
||||
0xB0FFE1FA, // __savegprlr_23
|
||||
0xB8FF01FB, // __savegprlr_24
|
||||
0xC0FF21FB, // __savegprlr_25
|
||||
0xC8FF41FB, // __savegprlr_26
|
||||
0xD0FF61FB, // __savegprlr_27
|
||||
0xD8FF81FB, // __savegprlr_28
|
||||
0xE0FFA1FB, // __savegprlr_29
|
||||
0xE8FFC1FB, // __savegprlr_30
|
||||
0xF0FFE1FB, // __savegprlr_31
|
||||
0xF8FF8191,
|
||||
0x2000804E,
|
||||
0x68FFC1E9, // __restgprlr_14
|
||||
0x70FFE1E9, // __restgprlr_15
|
||||
0x78FF01EA, // __restgprlr_16
|
||||
0x80FF21EA, // __restgprlr_17
|
||||
0x88FF41EA, // __restgprlr_18
|
||||
0x90FF61EA, // __restgprlr_19
|
||||
0x98FF81EA, // __restgprlr_20
|
||||
0xA0FFA1EA, // __restgprlr_21
|
||||
0xA8FFC1EA, // __restgprlr_22
|
||||
0xB0FFE1EA, // __restgprlr_23
|
||||
0xB8FF01EB, // __restgprlr_24
|
||||
0xC0FF21EB, // __restgprlr_25
|
||||
0xC8FF41EB, // __restgprlr_26
|
||||
0xD0FF61EB, // __restgprlr_27
|
||||
0xD8FF81EB, // __restgprlr_28
|
||||
0xE0FFA1EB, // __restgprlr_29
|
||||
0xE8FFC1EB, // __restgprlr_30
|
||||
0xF0FFE1EB, // __restgprlr_31
|
||||
0xF8FF8181,
|
||||
0xA603887D,
|
||||
0x2000804E,
|
||||
0x68FFC1F9, // __savegprlr_14
|
||||
0x70FFE1F9, // __savegprlr_15
|
||||
0x78FF01FA, // __savegprlr_16
|
||||
0x80FF21FA, // __savegprlr_17
|
||||
0x88FF41FA, // __savegprlr_18
|
||||
0x90FF61FA, // __savegprlr_19
|
||||
0x98FF81FA, // __savegprlr_20
|
||||
0xA0FFA1FA, // __savegprlr_21
|
||||
0xA8FFC1FA, // __savegprlr_22
|
||||
0xB0FFE1FA, // __savegprlr_23
|
||||
0xB8FF01FB, // __savegprlr_24
|
||||
0xC0FF21FB, // __savegprlr_25
|
||||
0xC8FF41FB, // __savegprlr_26
|
||||
0xD0FF61FB, // __savegprlr_27
|
||||
0xD8FF81FB, // __savegprlr_28
|
||||
0xE0FFA1FB, // __savegprlr_29
|
||||
0xE8FFC1FB, // __savegprlr_30
|
||||
0xF0FFE1FB, // __savegprlr_31
|
||||
0xF8FF8191, 0x2000804E,
|
||||
0x68FFC1E9, // __restgprlr_14
|
||||
0x70FFE1E9, // __restgprlr_15
|
||||
0x78FF01EA, // __restgprlr_16
|
||||
0x80FF21EA, // __restgprlr_17
|
||||
0x88FF41EA, // __restgprlr_18
|
||||
0x90FF61EA, // __restgprlr_19
|
||||
0x98FF81EA, // __restgprlr_20
|
||||
0xA0FFA1EA, // __restgprlr_21
|
||||
0xA8FFC1EA, // __restgprlr_22
|
||||
0xB0FFE1EA, // __restgprlr_23
|
||||
0xB8FF01EB, // __restgprlr_24
|
||||
0xC0FF21EB, // __restgprlr_25
|
||||
0xC8FF41EB, // __restgprlr_26
|
||||
0xD0FF61EB, // __restgprlr_27
|
||||
0xD8FF81EB, // __restgprlr_28
|
||||
0xE0FFA1EB, // __restgprlr_29
|
||||
0xE8FFC1EB, // __restgprlr_30
|
||||
0xF0FFE1EB, // __restgprlr_31
|
||||
0xF8FF8181, 0xA603887D, 0x2000804E,
|
||||
};
|
||||
// __savefpr_14 to __savefpr_31
|
||||
// __restfpr_14 to __restfpr_31
|
||||
static const uint32_t fpr_code_values[] = {
|
||||
0x70FFCCD9, // __savefpr_14
|
||||
0x78FFECD9, // __savefpr_15
|
||||
0x80FF0CDA, // __savefpr_16
|
||||
0x88FF2CDA, // __savefpr_17
|
||||
0x90FF4CDA, // __savefpr_18
|
||||
0x98FF6CDA, // __savefpr_19
|
||||
0xA0FF8CDA, // __savefpr_20
|
||||
0xA8FFACDA, // __savefpr_21
|
||||
0xB0FFCCDA, // __savefpr_22
|
||||
0xB8FFECDA, // __savefpr_23
|
||||
0xC0FF0CDB, // __savefpr_24
|
||||
0xC8FF2CDB, // __savefpr_25
|
||||
0xD0FF4CDB, // __savefpr_26
|
||||
0xD8FF6CDB, // __savefpr_27
|
||||
0xE0FF8CDB, // __savefpr_28
|
||||
0xE8FFACDB, // __savefpr_29
|
||||
0xF0FFCCDB, // __savefpr_30
|
||||
0xF8FFECDB, // __savefpr_31
|
||||
0x2000804E,
|
||||
0x70FFCCC9, // __restfpr_14
|
||||
0x78FFECC9, // __restfpr_15
|
||||
0x80FF0CCA, // __restfpr_16
|
||||
0x88FF2CCA, // __restfpr_17
|
||||
0x90FF4CCA, // __restfpr_18
|
||||
0x98FF6CCA, // __restfpr_19
|
||||
0xA0FF8CCA, // __restfpr_20
|
||||
0xA8FFACCA, // __restfpr_21
|
||||
0xB0FFCCCA, // __restfpr_22
|
||||
0xB8FFECCA, // __restfpr_23
|
||||
0xC0FF0CCB, // __restfpr_24
|
||||
0xC8FF2CCB, // __restfpr_25
|
||||
0xD0FF4CCB, // __restfpr_26
|
||||
0xD8FF6CCB, // __restfpr_27
|
||||
0xE0FF8CCB, // __restfpr_28
|
||||
0xE8FFACCB, // __restfpr_29
|
||||
0xF0FFCCCB, // __restfpr_30
|
||||
0xF8FFECCB, // __restfpr_31
|
||||
0x2000804E,
|
||||
0x70FFCCD9, // __savefpr_14
|
||||
0x78FFECD9, // __savefpr_15
|
||||
0x80FF0CDA, // __savefpr_16
|
||||
0x88FF2CDA, // __savefpr_17
|
||||
0x90FF4CDA, // __savefpr_18
|
||||
0x98FF6CDA, // __savefpr_19
|
||||
0xA0FF8CDA, // __savefpr_20
|
||||
0xA8FFACDA, // __savefpr_21
|
||||
0xB0FFCCDA, // __savefpr_22
|
||||
0xB8FFECDA, // __savefpr_23
|
||||
0xC0FF0CDB, // __savefpr_24
|
||||
0xC8FF2CDB, // __savefpr_25
|
||||
0xD0FF4CDB, // __savefpr_26
|
||||
0xD8FF6CDB, // __savefpr_27
|
||||
0xE0FF8CDB, // __savefpr_28
|
||||
0xE8FFACDB, // __savefpr_29
|
||||
0xF0FFCCDB, // __savefpr_30
|
||||
0xF8FFECDB, // __savefpr_31
|
||||
0x2000804E,
|
||||
0x70FFCCC9, // __restfpr_14
|
||||
0x78FFECC9, // __restfpr_15
|
||||
0x80FF0CCA, // __restfpr_16
|
||||
0x88FF2CCA, // __restfpr_17
|
||||
0x90FF4CCA, // __restfpr_18
|
||||
0x98FF6CCA, // __restfpr_19
|
||||
0xA0FF8CCA, // __restfpr_20
|
||||
0xA8FFACCA, // __restfpr_21
|
||||
0xB0FFCCCA, // __restfpr_22
|
||||
0xB8FFECCA, // __restfpr_23
|
||||
0xC0FF0CCB, // __restfpr_24
|
||||
0xC8FF2CCB, // __restfpr_25
|
||||
0xD0FF4CCB, // __restfpr_26
|
||||
0xD8FF6CCB, // __restfpr_27
|
||||
0xE0FF8CCB, // __restfpr_28
|
||||
0xE8FFACCB, // __restfpr_29
|
||||
0xF0FFCCCB, // __restfpr_30
|
||||
0xF8FFECCB, // __restfpr_31
|
||||
0x2000804E,
|
||||
};
|
||||
// __savevmx_14 to __savevmx_31
|
||||
// __savevmx_64 to __savevmx_127
|
||||
// __restvmx_14 to __restvmx_31
|
||||
// __restvmx_64 to __restvmx_127
|
||||
static const uint32_t vmx_code_values[] = {
|
||||
0xE0FE6039, // __savevmx_14
|
||||
0xCE61CB7D, 0xF0FE6039, 0xCE61EB7D, 0x00FF6039, 0xCE610B7E, 0x10FF6039,
|
||||
0xCE612B7E, 0x20FF6039, 0xCE614B7E, 0x30FF6039, 0xCE616B7E, 0x40FF6039,
|
||||
0xCE618B7E, 0x50FF6039, 0xCE61AB7E, 0x60FF6039, 0xCE61CB7E, 0x70FF6039,
|
||||
0xCE61EB7E, 0x80FF6039, 0xCE610B7F, 0x90FF6039, 0xCE612B7F, 0xA0FF6039,
|
||||
0xCE614B7F, 0xB0FF6039, 0xCE616B7F, 0xC0FF6039, 0xCE618B7F, 0xD0FF6039,
|
||||
0xCE61AB7F, 0xE0FF6039, 0xCE61CB7F,
|
||||
0xF0FF6039, // __savevmx_31
|
||||
0xCE61EB7F,
|
||||
0x2000804E,
|
||||
0xE0FE6039, // __savevmx_14
|
||||
0xCE61CB7D, 0xF0FE6039, 0xCE61EB7D, 0x00FF6039, 0xCE610B7E, 0x10FF6039,
|
||||
0xCE612B7E, 0x20FF6039, 0xCE614B7E, 0x30FF6039, 0xCE616B7E, 0x40FF6039,
|
||||
0xCE618B7E, 0x50FF6039, 0xCE61AB7E, 0x60FF6039, 0xCE61CB7E, 0x70FF6039,
|
||||
0xCE61EB7E, 0x80FF6039, 0xCE610B7F, 0x90FF6039, 0xCE612B7F, 0xA0FF6039,
|
||||
0xCE614B7F, 0xB0FF6039, 0xCE616B7F, 0xC0FF6039, 0xCE618B7F, 0xD0FF6039,
|
||||
0xCE61AB7F, 0xE0FF6039, 0xCE61CB7F, 0xF0FF6039, // __savevmx_31
|
||||
0xCE61EB7F, 0x2000804E,
|
||||
|
||||
0x00FC6039, // __savevmx_64
|
||||
0xCB610B10, 0x10FC6039, 0xCB612B10, 0x20FC6039, 0xCB614B10, 0x30FC6039,
|
||||
0xCB616B10, 0x40FC6039, 0xCB618B10, 0x50FC6039, 0xCB61AB10, 0x60FC6039,
|
||||
0xCB61CB10, 0x70FC6039, 0xCB61EB10, 0x80FC6039, 0xCB610B11, 0x90FC6039,
|
||||
0xCB612B11, 0xA0FC6039, 0xCB614B11, 0xB0FC6039, 0xCB616B11, 0xC0FC6039,
|
||||
0xCB618B11, 0xD0FC6039, 0xCB61AB11, 0xE0FC6039, 0xCB61CB11, 0xF0FC6039,
|
||||
0xCB61EB11, 0x00FD6039, 0xCB610B12, 0x10FD6039, 0xCB612B12, 0x20FD6039,
|
||||
0xCB614B12, 0x30FD6039, 0xCB616B12, 0x40FD6039, 0xCB618B12, 0x50FD6039,
|
||||
0xCB61AB12, 0x60FD6039, 0xCB61CB12, 0x70FD6039, 0xCB61EB12, 0x80FD6039,
|
||||
0xCB610B13, 0x90FD6039, 0xCB612B13, 0xA0FD6039, 0xCB614B13, 0xB0FD6039,
|
||||
0xCB616B13, 0xC0FD6039, 0xCB618B13, 0xD0FD6039, 0xCB61AB13, 0xE0FD6039,
|
||||
0xCB61CB13, 0xF0FD6039, 0xCB61EB13, 0x00FE6039, 0xCF610B10, 0x10FE6039,
|
||||
0xCF612B10, 0x20FE6039, 0xCF614B10, 0x30FE6039, 0xCF616B10, 0x40FE6039,
|
||||
0xCF618B10, 0x50FE6039, 0xCF61AB10, 0x60FE6039, 0xCF61CB10, 0x70FE6039,
|
||||
0xCF61EB10, 0x80FE6039, 0xCF610B11, 0x90FE6039, 0xCF612B11, 0xA0FE6039,
|
||||
0xCF614B11, 0xB0FE6039, 0xCF616B11, 0xC0FE6039, 0xCF618B11, 0xD0FE6039,
|
||||
0xCF61AB11, 0xE0FE6039, 0xCF61CB11, 0xF0FE6039, 0xCF61EB11, 0x00FF6039,
|
||||
0xCF610B12, 0x10FF6039, 0xCF612B12, 0x20FF6039, 0xCF614B12, 0x30FF6039,
|
||||
0xCF616B12, 0x40FF6039, 0xCF618B12, 0x50FF6039, 0xCF61AB12, 0x60FF6039,
|
||||
0xCF61CB12, 0x70FF6039, 0xCF61EB12, 0x80FF6039, 0xCF610B13, 0x90FF6039,
|
||||
0xCF612B13, 0xA0FF6039, 0xCF614B13, 0xB0FF6039, 0xCF616B13, 0xC0FF6039,
|
||||
0xCF618B13, 0xD0FF6039, 0xCF61AB13, 0xE0FF6039, 0xCF61CB13,
|
||||
0xF0FF6039, // __savevmx_127
|
||||
0xCF61EB13,
|
||||
0x2000804E,
|
||||
0x00FC6039, // __savevmx_64
|
||||
0xCB610B10, 0x10FC6039, 0xCB612B10, 0x20FC6039, 0xCB614B10, 0x30FC6039,
|
||||
0xCB616B10, 0x40FC6039, 0xCB618B10, 0x50FC6039, 0xCB61AB10, 0x60FC6039,
|
||||
0xCB61CB10, 0x70FC6039, 0xCB61EB10, 0x80FC6039, 0xCB610B11, 0x90FC6039,
|
||||
0xCB612B11, 0xA0FC6039, 0xCB614B11, 0xB0FC6039, 0xCB616B11, 0xC0FC6039,
|
||||
0xCB618B11, 0xD0FC6039, 0xCB61AB11, 0xE0FC6039, 0xCB61CB11, 0xF0FC6039,
|
||||
0xCB61EB11, 0x00FD6039, 0xCB610B12, 0x10FD6039, 0xCB612B12, 0x20FD6039,
|
||||
0xCB614B12, 0x30FD6039, 0xCB616B12, 0x40FD6039, 0xCB618B12, 0x50FD6039,
|
||||
0xCB61AB12, 0x60FD6039, 0xCB61CB12, 0x70FD6039, 0xCB61EB12, 0x80FD6039,
|
||||
0xCB610B13, 0x90FD6039, 0xCB612B13, 0xA0FD6039, 0xCB614B13, 0xB0FD6039,
|
||||
0xCB616B13, 0xC0FD6039, 0xCB618B13, 0xD0FD6039, 0xCB61AB13, 0xE0FD6039,
|
||||
0xCB61CB13, 0xF0FD6039, 0xCB61EB13, 0x00FE6039, 0xCF610B10, 0x10FE6039,
|
||||
0xCF612B10, 0x20FE6039, 0xCF614B10, 0x30FE6039, 0xCF616B10, 0x40FE6039,
|
||||
0xCF618B10, 0x50FE6039, 0xCF61AB10, 0x60FE6039, 0xCF61CB10, 0x70FE6039,
|
||||
0xCF61EB10, 0x80FE6039, 0xCF610B11, 0x90FE6039, 0xCF612B11, 0xA0FE6039,
|
||||
0xCF614B11, 0xB0FE6039, 0xCF616B11, 0xC0FE6039, 0xCF618B11, 0xD0FE6039,
|
||||
0xCF61AB11, 0xE0FE6039, 0xCF61CB11, 0xF0FE6039, 0xCF61EB11, 0x00FF6039,
|
||||
0xCF610B12, 0x10FF6039, 0xCF612B12, 0x20FF6039, 0xCF614B12, 0x30FF6039,
|
||||
0xCF616B12, 0x40FF6039, 0xCF618B12, 0x50FF6039, 0xCF61AB12, 0x60FF6039,
|
||||
0xCF61CB12, 0x70FF6039, 0xCF61EB12, 0x80FF6039, 0xCF610B13, 0x90FF6039,
|
||||
0xCF612B13, 0xA0FF6039, 0xCF614B13, 0xB0FF6039, 0xCF616B13, 0xC0FF6039,
|
||||
0xCF618B13, 0xD0FF6039, 0xCF61AB13, 0xE0FF6039, 0xCF61CB13,
|
||||
0xF0FF6039, // __savevmx_127
|
||||
0xCF61EB13, 0x2000804E,
|
||||
|
||||
0xE0FE6039, // __restvmx_14
|
||||
0xCE60CB7D, 0xF0FE6039, 0xCE60EB7D, 0x00FF6039, 0xCE600B7E, 0x10FF6039,
|
||||
0xCE602B7E, 0x20FF6039, 0xCE604B7E, 0x30FF6039, 0xCE606B7E, 0x40FF6039,
|
||||
0xCE608B7E, 0x50FF6039, 0xCE60AB7E, 0x60FF6039, 0xCE60CB7E, 0x70FF6039,
|
||||
0xCE60EB7E, 0x80FF6039, 0xCE600B7F, 0x90FF6039, 0xCE602B7F, 0xA0FF6039,
|
||||
0xCE604B7F, 0xB0FF6039, 0xCE606B7F, 0xC0FF6039, 0xCE608B7F, 0xD0FF6039,
|
||||
0xCE60AB7F, 0xE0FF6039, 0xCE60CB7F, 0xF0FF6039, // __restvmx_31
|
||||
0xCE60EB7F,
|
||||
0x2000804E,
|
||||
0xE0FE6039, // __restvmx_14
|
||||
0xCE60CB7D, 0xF0FE6039, 0xCE60EB7D, 0x00FF6039, 0xCE600B7E, 0x10FF6039,
|
||||
0xCE602B7E, 0x20FF6039, 0xCE604B7E, 0x30FF6039, 0xCE606B7E, 0x40FF6039,
|
||||
0xCE608B7E, 0x50FF6039, 0xCE60AB7E, 0x60FF6039, 0xCE60CB7E, 0x70FF6039,
|
||||
0xCE60EB7E, 0x80FF6039, 0xCE600B7F, 0x90FF6039, 0xCE602B7F, 0xA0FF6039,
|
||||
0xCE604B7F, 0xB0FF6039, 0xCE606B7F, 0xC0FF6039, 0xCE608B7F, 0xD0FF6039,
|
||||
0xCE60AB7F, 0xE0FF6039, 0xCE60CB7F, 0xF0FF6039, // __restvmx_31
|
||||
0xCE60EB7F, 0x2000804E,
|
||||
|
||||
0x00FC6039, // __restvmx_64
|
||||
0xCB600B10, 0x10FC6039, 0xCB602B10, 0x20FC6039, 0xCB604B10, 0x30FC6039,
|
||||
0xCB606B10, 0x40FC6039, 0xCB608B10, 0x50FC6039, 0xCB60AB10, 0x60FC6039,
|
||||
0xCB60CB10, 0x70FC6039, 0xCB60EB10, 0x80FC6039, 0xCB600B11, 0x90FC6039,
|
||||
0xCB602B11, 0xA0FC6039, 0xCB604B11, 0xB0FC6039, 0xCB606B11, 0xC0FC6039,
|
||||
0xCB608B11, 0xD0FC6039, 0xCB60AB11, 0xE0FC6039, 0xCB60CB11, 0xF0FC6039,
|
||||
0xCB60EB11, 0x00FD6039, 0xCB600B12, 0x10FD6039, 0xCB602B12, 0x20FD6039,
|
||||
0xCB604B12, 0x30FD6039, 0xCB606B12, 0x40FD6039, 0xCB608B12, 0x50FD6039,
|
||||
0xCB60AB12, 0x60FD6039, 0xCB60CB12, 0x70FD6039, 0xCB60EB12, 0x80FD6039,
|
||||
0xCB600B13, 0x90FD6039, 0xCB602B13, 0xA0FD6039, 0xCB604B13, 0xB0FD6039,
|
||||
0xCB606B13, 0xC0FD6039, 0xCB608B13, 0xD0FD6039, 0xCB60AB13, 0xE0FD6039,
|
||||
0xCB60CB13, 0xF0FD6039, 0xCB60EB13, 0x00FE6039, 0xCF600B10, 0x10FE6039,
|
||||
0xCF602B10, 0x20FE6039, 0xCF604B10, 0x30FE6039, 0xCF606B10, 0x40FE6039,
|
||||
0xCF608B10, 0x50FE6039, 0xCF60AB10, 0x60FE6039, 0xCF60CB10, 0x70FE6039,
|
||||
0xCF60EB10, 0x80FE6039, 0xCF600B11, 0x90FE6039, 0xCF602B11, 0xA0FE6039,
|
||||
0xCF604B11, 0xB0FE6039, 0xCF606B11, 0xC0FE6039, 0xCF608B11, 0xD0FE6039,
|
||||
0xCF60AB11, 0xE0FE6039, 0xCF60CB11, 0xF0FE6039, 0xCF60EB11, 0x00FF6039,
|
||||
0xCF600B12, 0x10FF6039, 0xCF602B12, 0x20FF6039, 0xCF604B12, 0x30FF6039,
|
||||
0xCF606B12, 0x40FF6039, 0xCF608B12, 0x50FF6039, 0xCF60AB12, 0x60FF6039,
|
||||
0xCF60CB12, 0x70FF6039, 0xCF60EB12, 0x80FF6039, 0xCF600B13, 0x90FF6039,
|
||||
0xCF602B13, 0xA0FF6039, 0xCF604B13, 0xB0FF6039, 0xCF606B13, 0xC0FF6039,
|
||||
0xCF608B13, 0xD0FF6039, 0xCF60AB13, 0xE0FF6039, 0xCF60CB13,
|
||||
0xF0FF6039, // __restvmx_127
|
||||
0xCF60EB13,
|
||||
0x2000804E,
|
||||
0x00FC6039, // __restvmx_64
|
||||
0xCB600B10, 0x10FC6039, 0xCB602B10, 0x20FC6039, 0xCB604B10, 0x30FC6039,
|
||||
0xCB606B10, 0x40FC6039, 0xCB608B10, 0x50FC6039, 0xCB60AB10, 0x60FC6039,
|
||||
0xCB60CB10, 0x70FC6039, 0xCB60EB10, 0x80FC6039, 0xCB600B11, 0x90FC6039,
|
||||
0xCB602B11, 0xA0FC6039, 0xCB604B11, 0xB0FC6039, 0xCB606B11, 0xC0FC6039,
|
||||
0xCB608B11, 0xD0FC6039, 0xCB60AB11, 0xE0FC6039, 0xCB60CB11, 0xF0FC6039,
|
||||
0xCB60EB11, 0x00FD6039, 0xCB600B12, 0x10FD6039, 0xCB602B12, 0x20FD6039,
|
||||
0xCB604B12, 0x30FD6039, 0xCB606B12, 0x40FD6039, 0xCB608B12, 0x50FD6039,
|
||||
0xCB60AB12, 0x60FD6039, 0xCB60CB12, 0x70FD6039, 0xCB60EB12, 0x80FD6039,
|
||||
0xCB600B13, 0x90FD6039, 0xCB602B13, 0xA0FD6039, 0xCB604B13, 0xB0FD6039,
|
||||
0xCB606B13, 0xC0FD6039, 0xCB608B13, 0xD0FD6039, 0xCB60AB13, 0xE0FD6039,
|
||||
0xCB60CB13, 0xF0FD6039, 0xCB60EB13, 0x00FE6039, 0xCF600B10, 0x10FE6039,
|
||||
0xCF602B10, 0x20FE6039, 0xCF604B10, 0x30FE6039, 0xCF606B10, 0x40FE6039,
|
||||
0xCF608B10, 0x50FE6039, 0xCF60AB10, 0x60FE6039, 0xCF60CB10, 0x70FE6039,
|
||||
0xCF60EB10, 0x80FE6039, 0xCF600B11, 0x90FE6039, 0xCF602B11, 0xA0FE6039,
|
||||
0xCF604B11, 0xB0FE6039, 0xCF606B11, 0xC0FE6039, 0xCF608B11, 0xD0FE6039,
|
||||
0xCF60AB11, 0xE0FE6039, 0xCF60CB11, 0xF0FE6039, 0xCF60EB11, 0x00FF6039,
|
||||
0xCF600B12, 0x10FF6039, 0xCF602B12, 0x20FF6039, 0xCF604B12, 0x30FF6039,
|
||||
0xCF606B12, 0x40FF6039, 0xCF608B12, 0x50FF6039, 0xCF60AB12, 0x60FF6039,
|
||||
0xCF60CB12, 0x70FF6039, 0xCF60EB12, 0x80FF6039, 0xCF600B13, 0x90FF6039,
|
||||
0xCF602B13, 0xA0FF6039, 0xCF604B13, 0xB0FF6039, 0xCF606B13, 0xC0FF6039,
|
||||
0xCF608B13, 0xD0FF6039, 0xCF60AB13, 0xE0FF6039, 0xCF60CB13,
|
||||
0xF0FF6039, // __restvmx_127
|
||||
0xCF60EB13, 0x2000804E,
|
||||
};
|
||||
|
||||
// TODO(benvanik): these are almost always sequential, if present.
|
||||
// It'd be smarter to search around the other ones to prevent
|
||||
// 3 full module scans.
|
||||
uint64_t gplr_start = 0;
|
||||
uint64_t fpr_start = 0;
|
||||
uint64_t vmx_start = 0;
|
||||
uint32_t gplr_start = 0;
|
||||
uint32_t fpr_start = 0;
|
||||
uint32_t vmx_start = 0;
|
||||
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 size_t start_address = header->exe_address + (i * section->page_size);
|
||||
const size_t end_address =
|
||||
const uint32_t start_address =
|
||||
header->exe_address + (i * section->page_size);
|
||||
const uint32_t end_address =
|
||||
start_address + (section->info.page_count * section->page_size);
|
||||
if (section->info.type == XEX_SECTION_CODE) {
|
||||
if (!gplr_start) {
|
||||
|
@ -418,7 +411,7 @@ int XexModule::FindSaveRest() {
|
|||
// Add function stubs.
|
||||
char name[32];
|
||||
if (gplr_start) {
|
||||
uint64_t address = gplr_start;
|
||||
uint32_t address = gplr_start;
|
||||
for (int n = 14; n <= 31; n++) {
|
||||
snprintf(name, poly::countof(name), "__savegprlr_%d", n);
|
||||
FunctionInfo* symbol_info;
|
||||
|
@ -446,7 +439,7 @@ int XexModule::FindSaveRest() {
|
|||
}
|
||||
}
|
||||
if (fpr_start) {
|
||||
uint64_t address = fpr_start;
|
||||
uint32_t address = fpr_start;
|
||||
for (int n = 14; n <= 31; n++) {
|
||||
snprintf(name, poly::countof(name), "__savefpr_%d", n);
|
||||
FunctionInfo* symbol_info;
|
||||
|
@ -479,7 +472,7 @@ int XexModule::FindSaveRest() {
|
|||
// 64-127 save
|
||||
// 14-31 rest
|
||||
// 64-127 rest
|
||||
uint64_t address = vmx_start;
|
||||
uint32_t address = vmx_start;
|
||||
for (int n = 14; n <= 31; n++) {
|
||||
snprintf(name, poly::countof(name), "__savevmx_%d", n);
|
||||
FunctionInfo* symbol_info;
|
||||
|
|
|
@ -22,8 +22,8 @@ namespace cpu {
|
|||
class Runtime;
|
||||
|
||||
class XexModule : public xe::cpu::Module {
|
||||
public:
|
||||
XexModule(Runtime* runtime);
|
||||
public:
|
||||
XexModule(Runtime* runtime);
|
||||
virtual ~XexModule();
|
||||
|
||||
xe_xex2_ref xex() const { return xex_; }
|
||||
|
@ -32,22 +32,22 @@ public:
|
|||
|
||||
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 SetupLibraryImports(const xe_xex2_import_library_t* library);
|
||||
int FindSaveRest();
|
||||
|
||||
private:
|
||||
Runtime* runtime_;
|
||||
std::string name_;
|
||||
std::string path_;
|
||||
xe_xex2_ref xex_;
|
||||
private:
|
||||
Runtime* runtime_;
|
||||
std::string name_;
|
||||
std::string path_;
|
||||
xe_xex2_ref xex_;
|
||||
|
||||
uint64_t base_address_;
|
||||
uint64_t low_address_;
|
||||
uint64_t high_address_;
|
||||
uint32_t base_address_;
|
||||
uint32_t low_address_;
|
||||
uint32_t high_address_;
|
||||
};
|
||||
|
||||
} // namespace cpu
|
||||
|
|
|
@ -15,11 +15,9 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef struct xe_ppc_state xe_ppc_state_t;
|
||||
|
||||
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 {
|
||||
public:
|
||||
|
|
|
@ -50,7 +50,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
|||
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,
|
||||
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_find_import_infos(xe_xex2_ref xex,
|
||||
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_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));
|
||||
|
||||
|
@ -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,
|
||||
const uint8_t *xex_addr,
|
||||
const size_t xex_length,
|
||||
const uint32_t xex_length,
|
||||
xe::Memory *memory) {
|
||||
// Allocate in-place the XEX memory.
|
||||
const size_t exe_length = xex_length - header->exe_offset;
|
||||
size_t uncompressed_size = exe_length;
|
||||
uint32_t alloc_result = (uint32_t)memory->HeapAlloc(
|
||||
const uint32_t exe_length = xex_length - header->exe_offset;
|
||||
uint32_t uncompressed_size = exe_length;
|
||||
uint32_t alloc_result = memory->HeapAlloc(
|
||||
header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO);
|
||||
if (!alloc_result) {
|
||||
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,
|
||||
const uint8_t *xex_addr,
|
||||
const size_t xex_length,
|
||||
const uint32_t xex_length,
|
||||
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 *p = source_buffer;
|
||||
|
||||
// Calculate uncompressed length.
|
||||
size_t uncompressed_size = 0;
|
||||
uint32_t uncompressed_size = 0;
|
||||
const xe_xex2_file_basic_compression_info_t *comp_info =
|
||||
&header->file_format_info.compression_info.basic;
|
||||
for (size_t n = 0; n < comp_info->block_count; n++) {
|
||||
const size_t data_size = comp_info->blocks[n].data_size;
|
||||
const size_t zero_size = comp_info->blocks[n].zero_size;
|
||||
for (uint32_t n = 0; n < comp_info->block_count; n++) {
|
||||
const uint32_t data_size = comp_info->blocks[n].data_size;
|
||||
const uint32_t zero_size = comp_info->blocks[n].zero_size;
|
||||
uncompressed_size += data_size + zero_size;
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (!alloc_result) {
|
||||
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);
|
||||
|
||||
for (size_t n = 0; n < comp_info->block_count; n++) {
|
||||
const size_t data_size = comp_info->blocks[n].data_size;
|
||||
const size_t zero_size = comp_info->blocks[n].zero_size;
|
||||
const uint32_t data_size = comp_info->blocks[n].data_size;
|
||||
const uint32_t zero_size = comp_info->blocks[n].zero_size;
|
||||
|
||||
switch (header->file_format_info.encryption_type) {
|
||||
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,
|
||||
const uint8_t *xex_addr,
|
||||
const size_t xex_length, xe::Memory *memory) {
|
||||
const size_t exe_length = xex_length - header->exe_offset;
|
||||
const uint32_t xex_length,
|
||||
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;
|
||||
|
||||
// src -> dest:
|
||||
|
@ -653,7 +655,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header,
|
|||
uint8_t *d = NULL;
|
||||
uint8_t *deblock_buffer = NULL;
|
||||
size_t block_size = 0;
|
||||
size_t uncompressed_size = 0;
|
||||
uint32_t uncompressed_size = 0;
|
||||
struct mspack_system *sys = NULL;
|
||||
mspack_memory_file *lzxsrc = 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.
|
||||
uint32_t alloc_result = (uint32_t)memory->HeapAlloc(
|
||||
uint32_t alloc_result = memory->HeapAlloc(
|
||||
header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO);
|
||||
if (!alloc_result) {
|
||||
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,
|
||||
const size_t xex_length, xe::Memory *memory) {
|
||||
const uint32_t xex_length, xe::Memory *memory) {
|
||||
const xe_xex2_header_t *header = &xex->header;
|
||||
switch (header->file_format_info.compression_type) {
|
||||
case XEX_COMPRESSION_NONE:
|
||||
|
|
|
@ -410,7 +410,7 @@ typedef enum {
|
|||
} xe_xex2_section_type;
|
||||
|
||||
typedef struct {
|
||||
size_t page_size;
|
||||
uint32_t page_size;
|
||||
union {
|
||||
struct {
|
||||
xe_xex2_section_type type : 4;
|
||||
|
|
|
@ -292,7 +292,8 @@ SHIM_CALL RtlUnicodeStringToAnsiString_shim(PPCContext* ppc_state,
|
|||
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
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);
|
||||
SHIM_SET_MEM_16(destination_ptr + 0,
|
||||
static_cast<uint16_t>(ansi_str.size()));
|
||||
|
|
|
@ -80,22 +80,22 @@ DEFINE_bool(scribble_heap, false,
|
|||
* this.
|
||||
*/
|
||||
|
||||
#define MEMORY_PHYSICAL_HEAP_LOW 0x00010000
|
||||
#define MEMORY_PHYSICAL_HEAP_HIGH 0x20000000
|
||||
#define MEMORY_VIRTUAL_HEAP_LOW 0x20000000
|
||||
#define MEMORY_VIRTUAL_HEAP_HIGH 0x40000000
|
||||
const uint32_t kMemoryPhysicalHeapLow = 0x00010000;
|
||||
const uint32_t kMemoryPhysicalHeapHigh = 0x20000000;
|
||||
const uint32_t kMemoryVirtualHeapLow = 0x20000000;
|
||||
const uint32_t kMemoryVirtualHeapHigh = 0x40000000;
|
||||
|
||||
class xe::MemoryHeap {
|
||||
public:
|
||||
MemoryHeap(Memory* memory, bool is_physical);
|
||||
~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);
|
||||
uint64_t Free(uint64_t address, size_t size);
|
||||
size_t QuerySize(uint64_t base_address);
|
||||
uint32_t Free(uint32_t address, uint32_t size);
|
||||
uint32_t QuerySize(uint32_t base_address);
|
||||
|
||||
void Dump();
|
||||
|
||||
|
@ -109,7 +109,7 @@ class xe::MemoryHeap {
|
|||
uint32_t heap_id_;
|
||||
bool is_physical_;
|
||||
std::mutex lock_;
|
||||
size_t size_;
|
||||
uint32_t size_;
|
||||
uint8_t* ptr_;
|
||||
mspace space_;
|
||||
};
|
||||
|
@ -122,7 +122,7 @@ Memory::Memory()
|
|||
trace_base_(0),
|
||||
mapping_(0),
|
||||
mapping_base_(nullptr) {
|
||||
system_page_size_ = poly::page_size();
|
||||
system_page_size_ = uint32_t(poly::page_size());
|
||||
virtual_heap_ = new MemoryHeap(this, false);
|
||||
physical_heap_ = new MemoryHeap(this, true);
|
||||
}
|
||||
|
@ -187,9 +187,9 @@ int Memory::Initialize() {
|
|||
membase_ = mapping_base_;
|
||||
|
||||
// Prepare heaps.
|
||||
virtual_heap_->Initialize(MEMORY_VIRTUAL_HEAP_LOW, MEMORY_VIRTUAL_HEAP_HIGH);
|
||||
physical_heap_->Initialize(MEMORY_PHYSICAL_HEAP_LOW,
|
||||
MEMORY_PHYSICAL_HEAP_HIGH - 0x1000);
|
||||
virtual_heap_->Initialize(kMemoryVirtualHeapLow, kMemoryVirtualHeapHigh);
|
||||
physical_heap_->Initialize(kMemoryPhysicalHeapLow,
|
||||
kMemoryPhysicalHeapHigh - 0x1000);
|
||||
|
||||
// GPU writeback.
|
||||
// 0xC... is physical, 0x7F... is virtual. We may need to overlay these.
|
||||
|
@ -212,9 +212,9 @@ int Memory::Initialize() {
|
|||
}
|
||||
|
||||
const static struct {
|
||||
uint64_t virtual_address_start;
|
||||
uint64_t virtual_address_end;
|
||||
uint64_t target_address;
|
||||
uint32_t virtual_address_start;
|
||||
uint32_t virtual_address_end;
|
||||
uint32_t target_address;
|
||||
} map_info[] = {
|
||||
0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
const uint8_t* psrc = membase_ + src;
|
||||
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) {
|
||||
assert_true(start <= end);
|
||||
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++;
|
||||
}
|
||||
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++;
|
||||
|
@ -305,7 +305,7 @@ uint64_t Memory::SearchAligned(uint64_t start, uint64_t end,
|
|||
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,
|
||||
cpu::MMIOWriteCallback write_callback) {
|
||||
DWORD protect = PAGE_NOACCESS;
|
||||
|
@ -317,7 +317,7 @@ bool Memory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size,
|
|||
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,
|
||||
void* callback_context, void* callback_data) {
|
||||
return mmio_handler_->AddWriteWatch(guest_address, length, callback,
|
||||
|
@ -328,13 +328,13 @@ void Memory::CancelWriteWatch(uintptr_t 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) {
|
||||
// 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).
|
||||
if (!base_address) {
|
||||
// Normal allocation from the managed heap.
|
||||
uint64_t result;
|
||||
uint32_t result;
|
||||
if (flags & MEMORY_FLAG_PHYSICAL) {
|
||||
result = physical_heap_->Alloc(base_address, size, flags, alignment);
|
||||
} else {
|
||||
|
@ -347,14 +347,14 @@ uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags,
|
|||
}
|
||||
return result;
|
||||
} else {
|
||||
if (base_address >= MEMORY_VIRTUAL_HEAP_LOW &&
|
||||
base_address < MEMORY_VIRTUAL_HEAP_HIGH) {
|
||||
if (base_address >= kMemoryVirtualHeapLow &&
|
||||
base_address < kMemoryVirtualHeapHigh) {
|
||||
// Overlapping managed heap.
|
||||
assert_always();
|
||||
return 0;
|
||||
}
|
||||
if (base_address >= MEMORY_PHYSICAL_HEAP_LOW &&
|
||||
base_address < MEMORY_PHYSICAL_HEAP_HIGH) {
|
||||
if (base_address >= kMemoryPhysicalHeapLow &&
|
||||
base_address < kMemoryPhysicalHeapHigh) {
|
||||
// Overlapping managed heap.
|
||||
assert_always();
|
||||
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) {
|
||||
if (address >= MEMORY_VIRTUAL_HEAP_LOW &&
|
||||
address < MEMORY_VIRTUAL_HEAP_HIGH) {
|
||||
int Memory::HeapFree(uint32_t address, uint32_t size) {
|
||||
if (address >= kMemoryVirtualHeapLow && address < kMemoryVirtualHeapHigh) {
|
||||
return virtual_heap_->Free(address, size) ? 0 : 1;
|
||||
} else if (address >= MEMORY_PHYSICAL_HEAP_LOW &&
|
||||
address < MEMORY_PHYSICAL_HEAP_HIGH) {
|
||||
} else if (address >= kMemoryPhysicalHeapLow &&
|
||||
address < kMemoryPhysicalHeapHigh) {
|
||||
return physical_heap_->Free(address, size) ? 0 : 1;
|
||||
} else {
|
||||
// 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);
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
if (!VirtualQuery(p, &mbi, sizeof(mbi))) {
|
||||
return false;
|
||||
}
|
||||
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_);
|
||||
mem_info->allocation_protect = mbi.AllocationProtect;
|
||||
mem_info->region_size = mbi.RegionSize;
|
||||
|
@ -409,19 +408,19 @@ bool Memory::QueryInformation(uint64_t base_address, AllocationInfo* mem_info) {
|
|||
return true;
|
||||
}
|
||||
|
||||
size_t Memory::QuerySize(uint64_t base_address) {
|
||||
if (base_address >= MEMORY_VIRTUAL_HEAP_LOW &&
|
||||
base_address < MEMORY_VIRTUAL_HEAP_HIGH) {
|
||||
uint32_t Memory::QuerySize(uint32_t base_address) {
|
||||
if (base_address >= kMemoryVirtualHeapLow &&
|
||||
base_address < kMemoryVirtualHeapHigh) {
|
||||
return virtual_heap_->QuerySize(base_address);
|
||||
} else if (base_address >= MEMORY_PHYSICAL_HEAP_LOW &&
|
||||
base_address < MEMORY_PHYSICAL_HEAP_HIGH) {
|
||||
} else if (base_address >= kMemoryPhysicalHeapLow &&
|
||||
base_address < kMemoryPhysicalHeapHigh) {
|
||||
return physical_heap_->QuerySize(base_address);
|
||||
} else {
|
||||
// A placed address.
|
||||
uint8_t* p = Translate(base_address);
|
||||
MEMORY_BASIC_INFORMATION mem_info;
|
||||
if (VirtualQuery(p, &mem_info, sizeof(mem_info))) {
|
||||
return mem_info.RegionSize;
|
||||
return uint32_t(mem_info.RegionSize);
|
||||
} else {
|
||||
// Error.
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint32_t Memory::QueryProtect(uint64_t address) {
|
||||
uint32_t Memory::QueryProtect(uint32_t address) {
|
||||
uint8_t* p = Translate(address);
|
||||
MEMORY_BASIC_INFORMATION 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.
|
||||
// TODO(benvanik): replace dlmalloc with an implementation that can commit
|
||||
// as it goes.
|
||||
|
@ -487,7 +486,7 @@ int MemoryHeap::Initialize(uint64_t low, uint64_t high) {
|
|||
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) {
|
||||
size_t alloc_size = size;
|
||||
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);
|
||||
}
|
||||
|
||||
uint64_t address =
|
||||
(uint64_t)((uintptr_t)p - (uintptr_t)memory_->mapping_base_);
|
||||
uint32_t address =
|
||||
(uint32_t)((uintptr_t)p - (uintptr_t)memory_->mapping_base_);
|
||||
|
||||
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);
|
||||
|
||||
// Heap allocated address.
|
||||
|
@ -584,16 +583,16 @@ uint64_t MemoryHeap::Free(uint64_t address, size_t size) {
|
|||
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);
|
||||
|
||||
// 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;
|
||||
size_t real_size = mspace_usable_size(p);
|
||||
uint32_t real_size = uint32_t(mspace_usable_size(p));
|
||||
real_size -= heap_guard_size * 2;
|
||||
if (!real_size) {
|
||||
return 0;
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
#include "xenia/common.h"
|
||||
#include "xenia/cpu/mmio_handler.h"
|
||||
|
||||
typedef struct xe_ppc_state xe_ppc_state_t;
|
||||
|
||||
namespace xe {
|
||||
|
||||
class MemoryHeap;
|
||||
|
@ -35,8 +33,8 @@ enum {
|
|||
// TODO(benvanik): move to heap.
|
||||
// Equivalent to the Win32 MEMORY_BASIC_INFORMATION struct.
|
||||
struct AllocationInfo {
|
||||
uint64_t base_address;
|
||||
uint64_t allocation_base;
|
||||
uint32_t base_address;
|
||||
uint32_t allocation_base;
|
||||
uint32_t allocation_protect; // TBD
|
||||
size_t region_size;
|
||||
uint32_t state; // TBD
|
||||
|
@ -62,37 +60,37 @@ class Memory {
|
|||
void set_trace_base(uint64_t value) { trace_base_ = value; }
|
||||
|
||||
// TODO(benvanik): make poly memory utils for these.
|
||||
void Zero(uint64_t address, size_t size);
|
||||
void Fill(uint64_t address, size_t size, uint8_t value);
|
||||
void Copy(uint64_t dest, uint64_t src, size_t size);
|
||||
uint64_t SearchAligned(uint64_t start, uint64_t end, const uint32_t* values,
|
||||
void Zero(uint32_t address, uint32_t size);
|
||||
void Fill(uint32_t address, uint32_t size, uint8_t value);
|
||||
void Copy(uint32_t dest, uint32_t src, uint32_t size);
|
||||
uint32_t SearchAligned(uint32_t start, uint32_t end, const uint32_t* values,
|
||||
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,
|
||||
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,
|
||||
void* callback_context, void* callback_data);
|
||||
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);
|
||||
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);
|
||||
size_t QuerySize(uint64_t base_address);
|
||||
bool QueryInformation(uint32_t base_address, AllocationInfo* mem_info);
|
||||
uint32_t QuerySize(uint32_t base_address);
|
||||
|
||||
int Protect(uint64_t address, size_t size, uint32_t access);
|
||||
uint32_t QueryProtect(uint64_t address);
|
||||
int Protect(uint32_t address, uint32_t size, uint32_t access);
|
||||
uint32_t QueryProtect(uint32_t address);
|
||||
|
||||
private:
|
||||
int MapViews(uint8_t* mapping_base);
|
||||
void UnmapViews();
|
||||
|
||||
private:
|
||||
size_t system_page_size_;
|
||||
uint32_t system_page_size_;
|
||||
uint8_t* membase_;
|
||||
uint64_t reserve_address_;
|
||||
uint64_t reserve_value_;
|
||||
|
|
Loading…
Reference in New Issue