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) {
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;

View File

@ -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;
}

View File

@ -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_;

View File

@ -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];

View File

@ -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);

View File

@ -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) {

View File

@ -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

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_);
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_) {

View File

@ -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

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.
// 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;

View File

@ -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;
}

View File

@ -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_;

View File

@ -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) {

View File

@ -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_;

View File

@ -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);

View File

@ -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();

View File

@ -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_;

View File

@ -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
}

View File

@ -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

View File

@ -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 =

View File

@ -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_;
};

View File

@ -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");

View File

@ -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

View File

@ -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_;
}

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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;
};

View File

@ -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;
};

View File

@ -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) {

View File

@ -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_;

View File

@ -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),

View File

@ -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_;

View File

@ -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) {
@ -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_;
}
@ -235,8 +235,7 @@ int XexModule::FindSaveRest() {
0xE0FFA1FB, // __savegprlr_29
0xE8FFC1FB, // __savegprlr_30
0xF0FFE1FB, // __savegprlr_31
0xF8FF8191,
0x2000804E,
0xF8FF8191, 0x2000804E,
0x68FFC1E9, // __restgprlr_14
0x70FFE1E9, // __restgprlr_15
0x78FF01EA, // __restgprlr_16
@ -255,9 +254,7 @@ int XexModule::FindSaveRest() {
0xE0FFA1EB, // __restgprlr_29
0xE8FFC1EB, // __restgprlr_30
0xF0FFE1EB, // __restgprlr_31
0xF8FF8181,
0xA603887D,
0x2000804E,
0xF8FF8181, 0xA603887D, 0x2000804E,
};
// __savefpr_14 to __savefpr_31
// __restfpr_14 to __restfpr_31
@ -312,10 +309,8 @@ int XexModule::FindSaveRest() {
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,
0xCE61AB7F, 0xE0FF6039, 0xCE61CB7F, 0xF0FF6039, // __savevmx_31
0xCE61EB7F, 0x2000804E,
0x00FC6039, // __savevmx_64
0xCB610B10, 0x10FC6039, 0xCB612B10, 0x20FC6039, 0xCB614B10, 0x30FC6039,
@ -340,8 +335,7 @@ int XexModule::FindSaveRest() {
0xCF612B13, 0xA0FF6039, 0xCF614B13, 0xB0FF6039, 0xCF616B13, 0xC0FF6039,
0xCF618B13, 0xD0FF6039, 0xCF61AB13, 0xE0FF6039, 0xCF61CB13,
0xF0FF6039, // __savevmx_127
0xCF61EB13,
0x2000804E,
0xCF61EB13, 0x2000804E,
0xE0FE6039, // __restvmx_14
0xCE60CB7D, 0xF0FE6039, 0xCE60EB7D, 0x00FF6039, 0xCE600B7E, 0x10FF6039,
@ -350,8 +344,7 @@ int XexModule::FindSaveRest() {
0xCE60EB7E, 0x80FF6039, 0xCE600B7F, 0x90FF6039, 0xCE602B7F, 0xA0FF6039,
0xCE604B7F, 0xB0FF6039, 0xCE606B7F, 0xC0FF6039, 0xCE608B7F, 0xD0FF6039,
0xCE60AB7F, 0xE0FF6039, 0xCE60CB7F, 0xF0FF6039, // __restvmx_31
0xCE60EB7F,
0x2000804E,
0xCE60EB7F, 0x2000804E,
0x00FC6039, // __restvmx_64
0xCB600B10, 0x10FC6039, 0xCB602B10, 0x20FC6039, 0xCB604B10, 0x30FC6039,
@ -376,21 +369,21 @@ int XexModule::FindSaveRest() {
0xCF602B13, 0xA0FF6039, 0xCF604B13, 0xB0FF6039, 0xCF606B13, 0xC0FF6039,
0xCF608B13, 0xD0FF6039, 0xCF60AB13, 0xE0FF6039, 0xCF60CB13,
0xF0FF6039, // __restvmx_127
0xCF60EB13,
0x2000804E,
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;

View File

@ -32,7 +32,7 @@ public:
const std::string& name() const override { return name_; }
bool ContainsAddress(uint64_t address) override;
bool ContainsAddress(uint32_t address) override;
private:
int SetupImports(xe_xex2_ref xex);
@ -45,9 +45,9 @@ private:
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

View File

@ -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:

View File

@ -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:

View File

@ -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;

View File

@ -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()));

View File

@ -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;

View File

@ -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_;