Converting logging to ASCII and other Windows fixes.
This commit is contained in:
parent
fa16593ab6
commit
3cae7ed714
|
@ -84,10 +84,6 @@
|
||||||
'__STDC_LIMIT_MACROS=1',
|
'__STDC_LIMIT_MACROS=1',
|
||||||
'__STDC_CONSTANT_MACROS=1',
|
'__STDC_CONSTANT_MACROS=1',
|
||||||
'_ISOC99_SOURCE=1',
|
'_ISOC99_SOURCE=1',
|
||||||
|
|
||||||
# Force xechar_t to char on Win32 (and use all the A functions).
|
|
||||||
# This makes life easier when string formatting/etc.
|
|
||||||
'XE_CHAR=1',
|
|
||||||
],
|
],
|
||||||
|
|
||||||
'conditions': [
|
'conditions': [
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <xenia/types.h>
|
#include <xenia/types.h>
|
||||||
|
|
||||||
|
|
||||||
#if XE_COMPILER(MSVC) && XE_WCHAR
|
#if 0 && XE_COMPILER(MSVC) && defined(UNICODE) && UNICODE
|
||||||
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
|
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
|
||||||
#if !defined(__WFILE__)
|
#if !defined(__WFILE__)
|
||||||
#define WIDEN2(x) L##x
|
#define WIDEN2(x) L##x
|
||||||
|
|
|
@ -83,3 +83,27 @@ size_t xe_file_read(xe_file_ref file, const size_t offset,
|
||||||
|
|
||||||
return fread(buffer, 1, buffer_size, handle);
|
return fread(buffer, 1, buffer_size, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xe_path_join(const xechar_t* left, const xechar_t* right,
|
||||||
|
xechar_t* out_path, size_t out_path_size) {
|
||||||
|
#if XE_WCHAR
|
||||||
|
xesnprintf(out_path, out_path_size, XT("%ls%c%ls"),
|
||||||
|
left, XE_PATH_SEPARATOR, right);
|
||||||
|
#else
|
||||||
|
xesnprintf(out_path, out_path_size, XT("%s%c%s"),
|
||||||
|
left, XE_PATH_SEPARATOR, right);
|
||||||
|
#endif // XE_WCHAR
|
||||||
|
}
|
||||||
|
|
||||||
|
void xe_path_get_absolute(const xechar_t* path, xechar_t* out_abs_path,
|
||||||
|
size_t abs_path_size) {
|
||||||
|
#if XE_PLATFORM(WIN32)
|
||||||
|
#if XE_WCHAR
|
||||||
|
_wfullpath(out_abs_path, path, abs_path_size);
|
||||||
|
#else
|
||||||
|
_fullpath(out_abs_path, path, abs_path_size);
|
||||||
|
#endif // XE_WCHAR
|
||||||
|
#else
|
||||||
|
realpath(path, out_abs_path);
|
||||||
|
#endif // WIN32
|
||||||
|
}
|
||||||
|
|
|
@ -33,5 +33,10 @@ size_t xe_file_get_length(xe_file_ref file);
|
||||||
size_t xe_file_read(xe_file_ref file, const size_t offset,
|
size_t xe_file_read(xe_file_ref file, const size_t offset,
|
||||||
uint8_t *buffer, const size_t buffer_size);
|
uint8_t *buffer, const size_t buffer_size);
|
||||||
|
|
||||||
|
void xe_path_join(const xechar_t* left, const xechar_t* right,
|
||||||
|
xechar_t* out_path, size_t out_path_size);
|
||||||
|
void xe_path_get_absolute(const xechar_t* path, xechar_t* out_abs_path,
|
||||||
|
size_t abs_path_size);
|
||||||
|
|
||||||
|
|
||||||
#endif // XENIA_CORE_FILE_H_
|
#endif // XENIA_CORE_FILE_H_
|
||||||
|
|
|
@ -83,10 +83,12 @@ xe_mmap_ref xe_mmap_open(xe_pal_ref pal, const xe_file_mode mode,
|
||||||
mmap->file_handle = file_handle;
|
mmap->file_handle = file_handle;
|
||||||
mmap->mmap_handle = handle;
|
mmap->mmap_handle = handle;
|
||||||
mmap->addr = address;
|
mmap->addr = address;
|
||||||
if (!length) {
|
if (length) {
|
||||||
mmap->length = length;
|
mmap->length = length;
|
||||||
} else {
|
} else {
|
||||||
size_t map_length = GetFileSize(file_handle, NULL);
|
DWORD length_high;
|
||||||
|
size_t map_length = GetFileSize(file_handle, &length_high);
|
||||||
|
map_length |= ((uint64_t)length_high) << 32;
|
||||||
mmap->length = map_length;
|
mmap->length = map_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ int xe_thread_start(xe_thread_ref thread) {
|
||||||
if (!thread_handle) {
|
if (!thread_handle) {
|
||||||
uint32_t last_error = GetLastError();
|
uint32_t last_error = GetLastError();
|
||||||
// TODO(benvanik): translate?
|
// TODO(benvanik): translate?
|
||||||
XELOGE(XT("CreateThread failed with %d"), last_error);
|
XELOGE("CreateThread failed with %d", last_error);
|
||||||
return last_error;
|
return last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -311,7 +311,7 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i.type) {
|
if (!i.type) {
|
||||||
XELOGCPU(XT("Invalid instruction %.8X %.8X"), ia, i.code);
|
XELOGCPU("Invalid instruction %.8X %.8X", ia, i.code);
|
||||||
SpillRegisters();
|
SpillRegisters();
|
||||||
b.CreateCall3(
|
b.CreateCall3(
|
||||||
invalidInstruction,
|
invalidInstruction,
|
||||||
|
@ -344,7 +344,7 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block) {
|
||||||
// This printf is handy for sort/uniquify to find instructions.
|
// This printf is handy for sort/uniquify to find instructions.
|
||||||
//printf("unimplinstr %s\n", i.type->name);
|
//printf("unimplinstr %s\n", i.type->name);
|
||||||
|
|
||||||
XELOGCPU(XT("Unimplemented instr %.8X %.8X %s"),
|
XELOGCPU("Unimplemented instr %.8X %.8X %s",
|
||||||
ia, i.code, i.type->name);
|
ia, i.code, i.type->name);
|
||||||
SpillRegisters();
|
SpillRegisters();
|
||||||
b.CreateCall3(
|
b.CreateCall3(
|
||||||
|
@ -363,7 +363,7 @@ void FunctionGenerator::GenerateBasicBlock(FunctionBlock* block) {
|
||||||
} else if (block->outgoing_type == FunctionBlock::kTargetUnknown) {
|
} else if (block->outgoing_type == FunctionBlock::kTargetUnknown) {
|
||||||
// Hrm.
|
// Hrm.
|
||||||
// TODO(benvanik): assert this doesn't occur - means a bad sdb run!
|
// TODO(benvanik): assert this doesn't occur - means a bad sdb run!
|
||||||
XELOGCPU(XT("SDB function scan error in %.8X: bb %.8X has unknown exit"),
|
XELOGCPU("SDB function scan error in %.8X: bb %.8X has unknown exit",
|
||||||
fn_->start_address, block->start_address);
|
fn_->start_address, block->start_address);
|
||||||
b.CreateRetVoid();
|
b.CreateRetVoid();
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ BasicBlock* FunctionGenerator::GetReturnBasicBlock() {
|
||||||
Function* FunctionGenerator::GetFunction(FunctionSymbol* fn) {
|
Function* FunctionGenerator::GetFunction(FunctionSymbol* fn) {
|
||||||
Function* result = gen_module_->getFunction(StringRef(fn->name()));
|
Function* result = gen_module_->getFunction(StringRef(fn->name()));
|
||||||
if (!result) {
|
if (!result) {
|
||||||
XELOGE(XT("Static function not found: %.8X %s"),
|
XELOGE("Static function not found: %.8X %s",
|
||||||
fn->start_address, fn->name());
|
fn->start_address, fn->name());
|
||||||
}
|
}
|
||||||
XEASSERTNOTNULL(result);
|
XEASSERTNOTNULL(result);
|
||||||
|
|
|
@ -95,7 +95,7 @@ int ModuleGenerator::Generate() {
|
||||||
// value (so that we can call it), the second actually builds the function.
|
// value (so that we can call it), the second actually builds the function.
|
||||||
std::vector<FunctionSymbol*> functions;
|
std::vector<FunctionSymbol*> functions;
|
||||||
if (!sdb_->GetAllFunctions(functions)) {
|
if (!sdb_->GetAllFunctions(functions)) {
|
||||||
XELOGI(XT("Beginning prep of %ld functions..."), functions.size());
|
XELOGI("Beginning prep of %ld functions...", functions.size());
|
||||||
for (std::vector<FunctionSymbol*>::iterator it = functions.begin();
|
for (std::vector<FunctionSymbol*>::iterator it = functions.begin();
|
||||||
it != functions.end(); ++it) {
|
it != functions.end(); ++it) {
|
||||||
FunctionSymbol* fn = *it;
|
FunctionSymbol* fn = *it;
|
||||||
|
@ -115,20 +115,20 @@ int ModuleGenerator::Generate() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XELOGI(XT("Function prep complete"));
|
XELOGI("Function prep complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build out all the user functions.
|
// Build out all the user functions.
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
XELOGI(XT("Beginning generation of %ld functions..."), functions.size());
|
XELOGI("Beginning generation of %ld functions...", functions.size());
|
||||||
for (std::map<uint32_t, CodegenFunction*>::iterator it =
|
for (std::map<uint32_t, CodegenFunction*>::iterator it =
|
||||||
functions_.begin(); it != functions_.end(); ++it, ++n) {
|
functions_.begin(); it != functions_.end(); ++it, ++n) {
|
||||||
FunctionSymbol* symbol = it->second->symbol;
|
FunctionSymbol* symbol = it->second->symbol;
|
||||||
XELOGI(XT("Generating %ld/%ld %.8X %s"),
|
XELOGI("Generating %ld/%ld %.8X %s",
|
||||||
n, functions_.size(), symbol->start_address, symbol->name());
|
n, functions_.size(), symbol->start_address, symbol->name());
|
||||||
BuildFunction(it->second);
|
BuildFunction(it->second);
|
||||||
}
|
}
|
||||||
XELOGI(XT("Function generation complete"));
|
XELOGI("Function generation complete");
|
||||||
|
|
||||||
di_builder_->finalize();
|
di_builder_->finalize();
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ int ExecModule::Init() {
|
||||||
} else {
|
} else {
|
||||||
// Not implemented - write with a dummy value.
|
// Not implemented - write with a dummy value.
|
||||||
*slot = XESWAP32BE(0xDEADBEEF);
|
*slot = XESWAP32BE(0xDEADBEEF);
|
||||||
XELOGCPU(XT("WARNING: imported a variable with no value: %s"),
|
XELOGCPU("WARNING: imported a variable with no value: %s",
|
||||||
kernel_export->name);
|
kernel_export->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,12 @@ namespace {
|
||||||
|
|
||||||
|
|
||||||
void XeTrap(xe_ppc_state_t* state, uint32_t cia) {
|
void XeTrap(xe_ppc_state_t* state, uint32_t cia) {
|
||||||
XELOGE(XT("TRAP"));
|
XELOGE("TRAP");
|
||||||
XEASSERTALWAYS();
|
XEASSERTALWAYS();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeIndirectBranch(xe_ppc_state_t* state, uint64_t target, uint64_t br_ia) {
|
void XeIndirectBranch(xe_ppc_state_t* state, uint64_t target, uint64_t br_ia) {
|
||||||
XELOGCPU(XT("INDIRECT BRANCH %.8X -> %.8X"),
|
XELOGCPU("INDIRECT BRANCH %.8X -> %.8X",
|
||||||
(uint32_t)br_ia, (uint32_t)target);
|
(uint32_t)br_ia, (uint32_t)target);
|
||||||
XEASSERTALWAYS();
|
XEASSERTALWAYS();
|
||||||
}
|
}
|
||||||
|
@ -50,43 +50,43 @@ void XeInvalidInstruction(xe_ppc_state_t* state, uint32_t cia, uint32_t data) {
|
||||||
i.type = ppc::GetInstrType(i.code);
|
i.type = ppc::GetInstrType(i.code);
|
||||||
|
|
||||||
if (!i.type) {
|
if (!i.type) {
|
||||||
XELOGCPU(XT("INVALID INSTRUCTION %.8X: %.8X ???"),
|
XELOGCPU("INVALID INSTRUCTION %.8X: %.8X ???",
|
||||||
i.address, i.code);
|
i.address, i.code);
|
||||||
} else if (i.type->disassemble) {
|
} else if (i.type->disassemble) {
|
||||||
ppc::InstrDisasm d;
|
ppc::InstrDisasm d;
|
||||||
i.type->disassemble(i, d);
|
i.type->disassemble(i, d);
|
||||||
std::string disasm;
|
std::string disasm;
|
||||||
d.Dump(disasm);
|
d.Dump(disasm);
|
||||||
XELOGCPU(XT("INVALID INSTRUCTION %.8X: %.8X %s"),
|
XELOGCPU("INVALID INSTRUCTION %.8X: %.8X %s",
|
||||||
i.address, i.code, disasm.c_str());
|
i.address, i.code, disasm.c_str());
|
||||||
} else {
|
} else {
|
||||||
XELOGCPU(XT("INVALID INSTRUCTION %.8X: %.8X %s"),
|
XELOGCPU("INVALID INSTRUCTION %.8X: %.8X %s",
|
||||||
i.address, i.code, i.type->name);
|
i.address, i.code, i.type->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeAccessViolation(xe_ppc_state_t* state, uint32_t cia, uint64_t ea) {
|
void XeAccessViolation(xe_ppc_state_t* state, uint32_t cia, uint64_t ea) {
|
||||||
XELOGE(XT("INVALID ACCESS %.8X: tried to touch %.8X"),
|
XELOGE("INVALID ACCESS %.8X: tried to touch %.8X",
|
||||||
cia, (uint32_t)ea);
|
cia, (uint32_t)ea);
|
||||||
XEASSERTALWAYS();
|
XEASSERTALWAYS();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeTraceKernelCall(xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
void XeTraceKernelCall(xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
||||||
KernelExport* kernel_export) {
|
KernelExport* kernel_export) {
|
||||||
XELOGCPU(XT("TRACE: %.8X -> k.%.8X (%s)"),
|
XELOGCPU("TRACE: %.8X -> k.%.8X (%s)",
|
||||||
(uint32_t)call_ia - 4, (uint32_t)cia,
|
(uint32_t)call_ia - 4, (uint32_t)cia,
|
||||||
kernel_export ? kernel_export->name : "unknown");
|
kernel_export ? kernel_export->name : "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeTraceUserCall(xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
void XeTraceUserCall(xe_ppc_state_t* state, uint64_t cia, uint64_t call_ia,
|
||||||
FunctionSymbol* fn) {
|
FunctionSymbol* fn) {
|
||||||
XELOGCPU(XT("TRACE: %.8X -> u.%.8X (%s)"),
|
XELOGCPU("TRACE: %.8X -> u.%.8X (%s)",
|
||||||
(uint32_t)call_ia - 4, (uint32_t)cia, fn->name());
|
(uint32_t)call_ia - 4, (uint32_t)cia, fn->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void XeTraceInstruction(xe_ppc_state_t* state, uint32_t cia, uint32_t data) {
|
void XeTraceInstruction(xe_ppc_state_t* state, uint32_t cia, uint32_t data) {
|
||||||
ppc::InstrType* type = ppc::GetInstrType(data);
|
ppc::InstrType* type = ppc::GetInstrType(data);
|
||||||
XELOGCPU(XT("TRACE: %.8X %.8X %s %s"),
|
XELOGCPU("TRACE: %.8X %.8X %s %s",
|
||||||
cia, data,
|
cia, data,
|
||||||
type && type->emit ? " " : "X",
|
type && type->emit ? " " : "X",
|
||||||
type ? type->name : "<unknown>");
|
type ? type->name : "<unknown>");
|
||||||
|
|
|
@ -199,7 +199,7 @@ int Processor::Execute(ThreadState* thread_state, uint32_t address) {
|
||||||
// Find the function to execute.
|
// Find the function to execute.
|
||||||
Function* f = GetFunction(address);
|
Function* f = GetFunction(address);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
XELOGCPU(XT("Failed to find function %.8X to execute."), address);
|
XELOGCPU("Failed to find function %.8X to execute.", address);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ int SymbolDatabase::Analyze() {
|
||||||
++it) {
|
++it) {
|
||||||
if (it->second->symbol_type == Symbol::Function) {
|
if (it->second->symbol_type == Symbol::Function) {
|
||||||
if (fn->type == FunctionSymbol::Unknown) {
|
if (fn->type == FunctionSymbol::Unknown) {
|
||||||
XELOGE(XT("UNKNOWN FN %.8X"), fn->start_address);
|
XELOGE("UNKNOWN FN %.8X", fn->start_address);
|
||||||
}
|
}
|
||||||
if (CompleteFunctionGraph(static_cast<FunctionSymbol*>(it->second))) {
|
if (CompleteFunctionGraph(static_cast<FunctionSymbol*>(it->second))) {
|
||||||
needs_another_pass = true;
|
needs_another_pass = true;
|
||||||
|
@ -111,7 +111,7 @@ FunctionSymbol* SymbolDatabase::GetOrInsertFunction(uint32_t address) {
|
||||||
|
|
||||||
// Ignore values outside of the .text range.
|
// Ignore values outside of the .text range.
|
||||||
if (!IsValueInTextRange(address)) {
|
if (!IsValueInTextRange(address)) {
|
||||||
XELOGSDB(XT("Ignoring function outside of .text: %.8X"), address);
|
XELOGSDB("Ignoring function outside of .text: %.8X", address);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
XELOGSDB(XT("Analyzing function %.8X..."), fn->start_address);
|
XELOGSDB("Analyzing function %.8X...", fn->start_address);
|
||||||
|
|
||||||
// Set a default name, if it hasn't been named already.
|
// Set a default name, if it hasn't been named already.
|
||||||
if (!fn->name()) {
|
if (!fn->name()) {
|
||||||
|
@ -258,7 +258,7 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
// If we fetched 0 assume that we somehow hit one of the awesome
|
// If we fetched 0 assume that we somehow hit one of the awesome
|
||||||
// 'no really we meant to end after that bl' functions.
|
// 'no really we meant to end after that bl' functions.
|
||||||
if (!i.code) {
|
if (!i.code) {
|
||||||
XELOGSDB(XT("function end %.8X (0x00000000 read)"), addr);
|
XELOGSDB("function end %.8X (0x00000000 read)", addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,18 +277,17 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
// Invalid instruction.
|
// Invalid instruction.
|
||||||
// We can just ignore it because there's (very little)/no chance it'll
|
// We can just ignore it because there's (very little)/no chance it'll
|
||||||
// affect flow control.
|
// affect flow control.
|
||||||
XELOGSDB(XT("Invalid instruction at %.8X: %.8X"), addr, i.code);
|
XELOGSDB("Invalid instruction at %.8X: %.8X", addr, i.code);
|
||||||
} else if (i.code == 0x4E800020) {
|
} else if (i.code == 0x4E800020) {
|
||||||
// blr -- unconditional branch to LR.
|
// blr -- unconditional branch to LR.
|
||||||
// This is generally a return.
|
// This is generally a return.
|
||||||
block->outgoing_type = FunctionBlock::kTargetLR;
|
block->outgoing_type = FunctionBlock::kTargetLR;
|
||||||
if (furthest_target > addr) {
|
if (furthest_target > addr) {
|
||||||
// Remaining targets within function, not end.
|
// Remaining targets within function, not end.
|
||||||
XELOGSDB(XT("ignoring blr %.8X (branch to %.8X)"), addr,
|
XELOGSDB("ignoring blr %.8X (branch to %.8X)", addr, furthest_target);
|
||||||
furthest_target);
|
|
||||||
} else {
|
} else {
|
||||||
// Function end point.
|
// Function end point.
|
||||||
XELOGSDB(XT("function end %.8X"), addr);
|
XELOGSDB("function end %.8X", addr);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
|
@ -298,11 +297,11 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
block->outgoing_type = FunctionBlock::kTargetCTR;
|
block->outgoing_type = FunctionBlock::kTargetCTR;
|
||||||
if (furthest_target > addr) {
|
if (furthest_target > addr) {
|
||||||
// Remaining targets within function, not end.
|
// Remaining targets within function, not end.
|
||||||
XELOGSDB(XT("ignoring bctr %.8X (branch to %.8X)"), addr,
|
XELOGSDB("ignoring bctr %.8X (branch to %.8X)", addr,
|
||||||
furthest_target);
|
furthest_target);
|
||||||
} else {
|
} else {
|
||||||
// Function end point.
|
// Function end point.
|
||||||
XELOGSDB(XT("function end %.8X"), addr);
|
XELOGSDB("function end %.8X", addr);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
|
@ -312,17 +311,17 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
block->outgoing_address = target;
|
block->outgoing_address = target;
|
||||||
|
|
||||||
if (i.I.LK) {
|
if (i.I.LK) {
|
||||||
XELOGSDB(XT("bl %.8X -> %.8X"), addr, target);
|
XELOGSDB("bl %.8X -> %.8X", addr, target);
|
||||||
|
|
||||||
// Queue call target if needed.
|
// Queue call target if needed.
|
||||||
GetOrInsertFunction(target);
|
GetOrInsertFunction(target);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB(XT("b %.8X -> %.8X"), addr, target);
|
XELOGSDB("b %.8X -> %.8X", addr, target);
|
||||||
// If the target is back into the function and there's no further target
|
// If the target is back into the function and there's no further target
|
||||||
// we are at the end of a function.
|
// we are at the end of a function.
|
||||||
if (target >= fn->start_address &&
|
if (target >= fn->start_address &&
|
||||||
target < addr && furthest_target <= addr) {
|
target < addr && furthest_target <= addr) {
|
||||||
XELOGSDB(XT("function end %.8X (back b)"), addr);
|
XELOGSDB("function end %.8X (back b)", addr);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +331,7 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
// it.
|
// it.
|
||||||
if (!ends_fn &&
|
if (!ends_fn &&
|
||||||
furthest_target <= addr && IsRestGprLr(target)) {
|
furthest_target <= addr && IsRestGprLr(target)) {
|
||||||
XELOGSDB(XT("function end %.8X (__restgprlr_*)"), addr);
|
XELOGSDB("function end %.8X (__restgprlr_*)", addr);
|
||||||
ends_fn = true;
|
ends_fn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,14 +350,14 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
uint32_t target = XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)addr);
|
uint32_t target = XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)addr);
|
||||||
block->outgoing_address = target;
|
block->outgoing_address = target;
|
||||||
if (i.B.LK) {
|
if (i.B.LK) {
|
||||||
XELOGSDB(XT("bcl %.8X -> %.8X"), addr, target);
|
XELOGSDB("bcl %.8X -> %.8X", addr, target);
|
||||||
|
|
||||||
// Queue call target if needed.
|
// Queue call target if needed.
|
||||||
// TODO(benvanik): see if this is correct - not sure anyone makes
|
// TODO(benvanik): see if this is correct - not sure anyone makes
|
||||||
// function calls with bcl.
|
// function calls with bcl.
|
||||||
//GetOrInsertFunction(target);
|
//GetOrInsertFunction(target);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB(XT("bc %.8X -> %.8X"), addr, target);
|
XELOGSDB("bc %.8X -> %.8X", addr, target);
|
||||||
|
|
||||||
// TODO(benvanik): GetOrInsertFunction? it's likely a BB
|
// TODO(benvanik): GetOrInsertFunction? it's likely a BB
|
||||||
|
|
||||||
|
@ -369,18 +368,18 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
// bclr/bclrl
|
// bclr/bclrl
|
||||||
block->outgoing_type = FunctionBlock::kTargetLR;
|
block->outgoing_type = FunctionBlock::kTargetLR;
|
||||||
if (i.XL.LK) {
|
if (i.XL.LK) {
|
||||||
XELOGSDB(XT("bclrl %.8X"), addr);
|
XELOGSDB("bclrl %.8X", addr);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB(XT("bclr %.8X"), addr);
|
XELOGSDB("bclr %.8X", addr);
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
} else if (i.type->opcode == 0x4C000420) {
|
} else if (i.type->opcode == 0x4C000420) {
|
||||||
// bcctr/bcctrl
|
// bcctr/bcctrl
|
||||||
block->outgoing_type = FunctionBlock::kTargetCTR;
|
block->outgoing_type = FunctionBlock::kTargetCTR;
|
||||||
if (i.XL.LK) {
|
if (i.XL.LK) {
|
||||||
XELOGSDB(XT("bcctrl %.8X"), addr);
|
XELOGSDB("bcctrl %.8X", addr);
|
||||||
} else {
|
} else {
|
||||||
XELOGSDB(XT("bcctr %.8X"), addr);
|
XELOGSDB("bcctr %.8X", addr);
|
||||||
}
|
}
|
||||||
ends_block = true;
|
ends_block = true;
|
||||||
}
|
}
|
||||||
|
@ -400,7 +399,7 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
addr += 4;
|
addr += 4;
|
||||||
if (fn->end_address && addr > fn->end_address) {
|
if (fn->end_address && addr > fn->end_address) {
|
||||||
// Hmm....
|
// Hmm....
|
||||||
XELOGSDB(XT("Ran over function bounds! %.8X-%.8X"),
|
XELOGSDB("Ran over function bounds! %.8X-%.8X",
|
||||||
fn->start_address, fn->end_address);
|
fn->start_address, fn->end_address);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -411,7 +410,7 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
// from someplace valid (like method hints) this may indicate an error.
|
// from someplace valid (like method hints) this may indicate an error.
|
||||||
// It's also possible that we guessed in hole-filling and there's another
|
// It's also possible that we guessed in hole-filling and there's another
|
||||||
// function below this one.
|
// function below this one.
|
||||||
XELOGSDB(XT("Function ran under: %.8X-%.8X ended at %.8X"),
|
XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X",
|
||||||
fn->start_address, fn->end_address, addr + 4);
|
fn->start_address, fn->end_address, addr + 4);
|
||||||
}
|
}
|
||||||
fn->end_address = addr;
|
fn->end_address = addr;
|
||||||
|
@ -424,7 +423,7 @@ int SymbolDatabase::AnalyzeFunction(FunctionSymbol* fn) {
|
||||||
// - if present, flag function as needing a stack
|
// - if present, flag function as needing a stack
|
||||||
// - record prolog/epilog lengths/stack size/etc
|
// - record prolog/epilog lengths/stack size/etc
|
||||||
|
|
||||||
XELOGSDB(XT("Finished analyzing %.8X"), fn->start_address);
|
XELOGSDB("Finished analyzing %.8X", fn->start_address);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +453,7 @@ int SymbolDatabase::CompleteFunctionGraph(FunctionSymbol* fn) {
|
||||||
block->outgoing_block = fn->SplitBlock(block->outgoing_address);
|
block->outgoing_block = fn->SplitBlock(block->outgoing_address);
|
||||||
}
|
}
|
||||||
if (!block->outgoing_block) {
|
if (!block->outgoing_block) {
|
||||||
XELOGE(XT("block target not found: %.8X"), block->outgoing_address);
|
XELOGE("block target not found: %.8X", block->outgoing_address);
|
||||||
XEASSERTALWAYS();
|
XEASSERTALWAYS();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -462,7 +461,7 @@ int SymbolDatabase::CompleteFunctionGraph(FunctionSymbol* fn) {
|
||||||
block->outgoing_type = FunctionBlock::kTargetFunction;
|
block->outgoing_type = FunctionBlock::kTargetFunction;
|
||||||
block->outgoing_function = GetFunction(block->outgoing_address);
|
block->outgoing_function = GetFunction(block->outgoing_address);
|
||||||
if (!block->outgoing_function) {
|
if (!block->outgoing_function) {
|
||||||
XELOGE(XT("call target not found: %.8X -> %.8X"),
|
XELOGE("call target not found: %.8X -> %.8X",
|
||||||
block->end_address, block->outgoing_address);
|
block->end_address, block->outgoing_address);
|
||||||
new_fns.push_back(block->outgoing_address);
|
new_fns.push_back(block->outgoing_address);
|
||||||
}
|
}
|
||||||
|
@ -471,7 +470,7 @@ int SymbolDatabase::CompleteFunctionGraph(FunctionSymbol* fn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_fns.size()) {
|
if (new_fns.size()) {
|
||||||
XELOGW(XT("Repeat analysis required to find %d new functions"),
|
XELOGW("Repeat analysis required to find %d new functions",
|
||||||
(uint32_t)new_fns.size());
|
(uint32_t)new_fns.size());
|
||||||
for (std::vector<uint32_t>::iterator it = new_fns.begin();
|
for (std::vector<uint32_t>::iterator it = new_fns.begin();
|
||||||
it != new_fns.end(); ++it) {
|
it != new_fns.end(); ++it) {
|
||||||
|
@ -584,7 +583,7 @@ int SymbolDatabase::FlushQueue() {
|
||||||
FunctionSymbol* fn = scan_queue_.front();
|
FunctionSymbol* fn = scan_queue_.front();
|
||||||
scan_queue_.pop_front();
|
scan_queue_.pop_front();
|
||||||
if (AnalyzeFunction(fn)) {
|
if (AnalyzeFunction(fn)) {
|
||||||
XELOGSDB(XT("Aborting analysis!"));
|
XELOGSDB("Aborting analysis!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -654,7 +653,7 @@ void SymbolDatabase::ReadMap(const char* file_name) {
|
||||||
// Function was not found via analysis.
|
// Function was not found via analysis.
|
||||||
// We don't want to add it here as that would make us require maps to
|
// We don't want to add it here as that would make us require maps to
|
||||||
// get working.
|
// get working.
|
||||||
XELOGSDB(XT("MAP DIFF: function %.8X %s not found during analysis"),
|
XELOGSDB("MAP DIFF: function %.8X %s not found during analysis",
|
||||||
addr, name.c_str());
|
addr, name.c_str());
|
||||||
} else {
|
} else {
|
||||||
// Add a new variable.
|
// Add a new variable.
|
||||||
|
|
|
@ -67,11 +67,11 @@ int Debugger::Startup() {
|
||||||
|
|
||||||
// If desired, wait until the first client connects.
|
// If desired, wait until the first client connects.
|
||||||
if (FLAGS_wait_for_debugger) {
|
if (FLAGS_wait_for_debugger) {
|
||||||
XELOGI(XT("Waiting for debugger on port %d..."), FLAGS_remote_debug_port);
|
XELOGI("Waiting for debugger on port %d...", FLAGS_remote_debug_port);
|
||||||
if (listener_->WaitForClient()) {
|
if (listener_->WaitForClient()) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
XELOGI(XT("Debugger attached, continuing..."));
|
XELOGI("Debugger attached, continuing...");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -123,7 +123,7 @@ int Debugger::Dispatch(Client* client, const uint8_t* data, size_t length) {
|
||||||
std::map<uint32_t, ContentSource*>::iterator it =
|
std::map<uint32_t, ContentSource*>::iterator it =
|
||||||
content_sources_.find(source_id);
|
content_sources_.find(source_id);
|
||||||
if (it == content_sources_.end()) {
|
if (it == content_sources_.end()) {
|
||||||
XELOGW(XT("Content source %d not found, ignoring message"), source_id);
|
XELOGW("Content source %d not found, ignoring message", source_id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return it->second->Dispatch(client, type, request_id, data + 16, size);
|
return it->second->Dispatch(client, type, request_id, data + 16, size);
|
||||||
|
|
|
@ -126,7 +126,7 @@ void WsClientOnMsgCallback(wslay_event_context_ptr ctx,
|
||||||
WsClient* client = reinterpret_cast<WsClient*>(user_data);
|
WsClient* client = reinterpret_cast<WsClient*>(user_data);
|
||||||
switch (arg->opcode) {
|
switch (arg->opcode) {
|
||||||
case WSLAY_TEXT_FRAME:
|
case WSLAY_TEXT_FRAME:
|
||||||
XELOGW(XT("Text frame ignored; use binary messages"));
|
XELOGW("Text frame ignored; use binary messages");
|
||||||
break;
|
break;
|
||||||
case WSLAY_BINARY_FRAME:
|
case WSLAY_BINARY_FRAME:
|
||||||
client->OnMessage(arg->msg, arg->msg_length);
|
client->OnMessage(arg->msg, arg->msg_length);
|
||||||
|
@ -184,24 +184,24 @@ int WsClient::PerformHandshake() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
XELOGE(XT("HTTP header read failure"));
|
XELOGE("HTTP header read failure");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if (r == 0) {
|
} else if (r == 0) {
|
||||||
// EOF.
|
// EOF.
|
||||||
XELOGE(XT("HTTP header EOF"));
|
XELOGE("HTTP header EOF");
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
headers.append(buffer, buffer + r);
|
headers.append(buffer, buffer + r);
|
||||||
if (headers.size() > 8192) {
|
if (headers.size() > 8192) {
|
||||||
XELOGE(XT("HTTP headers exceeded max buffer size"));
|
XELOGE("HTTP headers exceeded max buffer size");
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headers.find("\r\n\r\n") == std::string::npos) {
|
if (headers.find("\r\n\r\n") == std::string::npos) {
|
||||||
XELOGE(XT("Incomplete HTTP headers: %s"), headers.c_str());
|
XELOGE("Incomplete HTTP headers: %s", headers.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ int WsClient::PerformHandshake() {
|
||||||
headers.find("Connection: Upgrade\r\n") == std::string::npos ||
|
headers.find("Connection: Upgrade\r\n") == std::string::npos ||
|
||||||
(keyhdstart = headers.find("Sec-WebSocket-Key: ")) ==
|
(keyhdstart = headers.find("Sec-WebSocket-Key: ")) ==
|
||||||
std::string::npos) {
|
std::string::npos) {
|
||||||
XELOGW(XT("HTTP connection does not contain websocket headers"));
|
XELOGW("HTTP connection does not contain websocket headers");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
keyhdstart += 19;
|
keyhdstart += 19;
|
||||||
|
@ -240,7 +240,7 @@ int WsClient::PerformHandshake() {
|
||||||
if (error_code == EAGAIN || error_code == EWOULDBLOCK) {
|
if (error_code == EAGAIN || error_code == EWOULDBLOCK) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
XELOGE(XT("HTTP response write failure"));
|
XELOGE("HTTP response write failure");
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -305,7 +305,7 @@ void WsClient::EventThread() {
|
||||||
if ((xe_socket_loop_check_socket_recv(loop_) && wslay_event_recv(ctx)) ||
|
if ((xe_socket_loop_check_socket_recv(loop_) && wslay_event_recv(ctx)) ||
|
||||||
(xe_socket_loop_check_socket_send(loop_) && wslay_event_send(ctx))) {
|
(xe_socket_loop_check_socket_send(loop_) && wslay_event_send(ctx))) {
|
||||||
// Error handling the event.
|
// Error handling the event.
|
||||||
XELOGE(XT("Error handling WebSocket data"));
|
XELOGE("Error handling WebSocket data");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ int WsListener::Setup() {
|
||||||
xe_socket_set_nodelay(socket_id_, true);
|
xe_socket_set_nodelay(socket_id_, true);
|
||||||
|
|
||||||
if (xe_socket_bind(socket_id_, port_)) {
|
if (xe_socket_bind(socket_id_, port_)) {
|
||||||
XELOGE(XT("Could not bind listen socket: %d"), errno);
|
XELOGE("Could not bind listen socket: %d", errno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ int WsListener::WaitForClient() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XELOGI(XT("Debugger connected from %s"), client_info.addr);
|
XELOGI("Debugger connected from %s", client_info.addr);
|
||||||
|
|
||||||
// Create the client object.
|
// Create the client object.
|
||||||
// Note that the client will delete itself when done.
|
// Note that the client will delete itself when done.
|
||||||
|
|
|
@ -11,5 +11,5 @@
|
||||||
|
|
||||||
|
|
||||||
void do_gpu_stuff() {
|
void do_gpu_stuff() {
|
||||||
XELOGGPU(XT("gpu"));
|
XELOGGPU("gpu");
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,14 +91,14 @@ DiscImageDevice::~DiscImageDevice() {
|
||||||
int DiscImageDevice::Init() {
|
int DiscImageDevice::Init() {
|
||||||
mmap_ = xe_mmap_open(pal_, kXEFileModeRead, local_path_, 0, 0);
|
mmap_ = xe_mmap_open(pal_, kXEFileModeRead, local_path_, 0, 0);
|
||||||
if (!mmap_) {
|
if (!mmap_) {
|
||||||
XELOGE(XT("Disc image could not be mapped"));
|
XELOGE("Disc image could not be mapped");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gdfx_ = new GDFX(mmap_);
|
gdfx_ = new GDFX(mmap_);
|
||||||
GDFX::Error error = gdfx_->Load();
|
GDFX::Error error = gdfx_->Load();
|
||||||
if (error != GDFX::kSuccess) {
|
if (error != GDFX::kSuccess) {
|
||||||
XELOGE(XT("GDFX init failed: %d"), error);
|
XELOGE("GDFX init failed: %d", error);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ Entry* DiscImageDevice::ResolvePath(const char* path) {
|
||||||
// be in the form:
|
// be in the form:
|
||||||
// some\PATH.foo
|
// some\PATH.foo
|
||||||
|
|
||||||
XELOGFS(XT("DiscImageDevice::ResolvePath(%s)"), path);
|
XELOGFS("DiscImageDevice::ResolvePath(%s)", path);
|
||||||
|
|
||||||
GDFXEntry* gdfx_entry = gdfx_->root_entry();
|
GDFXEntry* gdfx_entry = gdfx_->root_entry();
|
||||||
|
|
||||||
|
|
|
@ -85,16 +85,17 @@ Entry* LocalDirectoryDevice::ResolvePath(const char* path) {
|
||||||
// be in the form:
|
// be in the form:
|
||||||
// some\PATH.foo
|
// some\PATH.foo
|
||||||
|
|
||||||
XELOGFS(XT("LocalDirectoryDevice::ResolvePath(%s)"), path);
|
XELOGFS("LocalDirectoryDevice::ResolvePath(%s)", path);
|
||||||
|
|
||||||
|
#if XE_WCHAR
|
||||||
|
xechar_t rel_path[XE_MAX_PATH];
|
||||||
|
XEIGNORE(xestrwiden(rel_path, XECOUNT(rel_path), path));
|
||||||
|
#else
|
||||||
|
const xechar_t* rel_path = path;
|
||||||
|
#endif
|
||||||
|
|
||||||
xechar_t full_path[XE_MAX_PATH];
|
xechar_t full_path[XE_MAX_PATH];
|
||||||
#if XE_WCHAR
|
xe_path_join(local_path_, rel_path, full_path, XECOUNT(full_path));
|
||||||
xesnprintf(full_path, XECOUNT(full_path), XT("%ls%c%hs"),
|
|
||||||
local_path_, XE_PATH_SEPARATOR, path);
|
|
||||||
#else
|
|
||||||
xesnprintf(full_path, XECOUNT(full_path), XT("%s%c%s"),
|
|
||||||
local_path_, XE_PATH_SEPARATOR, path);
|
|
||||||
#endif // XE_WCHAR
|
|
||||||
|
|
||||||
// Swap around path separators.
|
// Swap around path separators.
|
||||||
if (XE_PATH_SEPARATOR != '\\') {
|
if (XE_PATH_SEPARATOR != '\\') {
|
||||||
|
|
|
@ -111,6 +111,6 @@ Entry* FileSystem::ResolvePath(const char* path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XELOGE(XT("ResolvePath(%s) failed - no root found"), path);
|
XELOGE("ResolvePath(%s) failed - no root found", path);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ void XGetAVPack_shim(
|
||||||
|
|
||||||
void XGetGameRegion_shim(
|
void XGetGameRegion_shim(
|
||||||
xe_ppc_state_t* ppc_state, XamState* state) {
|
xe_ppc_state_t* ppc_state, XamState* state) {
|
||||||
XELOGD(XT("XGetGameRegion()"));
|
XELOGD("XGetGameRegion()");
|
||||||
|
|
||||||
SHIM_SET_RETURN(XEX_REGION_ALL);
|
SHIM_SET_RETURN(XEX_REGION_ALL);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ void XGetGameRegion_shim(
|
||||||
|
|
||||||
void XGetLanguage_shim(
|
void XGetLanguage_shim(
|
||||||
xe_ppc_state_t* ppc_state, XamState* state) {
|
xe_ppc_state_t* ppc_state, XamState* state) {
|
||||||
XELOGD(XT("XGetLanguage()"));
|
XELOGD("XGetLanguage()");
|
||||||
|
|
||||||
uint32_t desired_language = X_LANGUAGE_ENGLISH;
|
uint32_t desired_language = X_LANGUAGE_ENGLISH;
|
||||||
|
|
||||||
|
|
|
@ -117,13 +117,13 @@ int XboxkrnlModule::LaunchModule(const char* path) {
|
||||||
// Load the module into memory from the filesystem.
|
// Load the module into memory from the filesystem.
|
||||||
X_STATUS result_code = module->LoadFromFile(path);
|
X_STATUS result_code = module->LoadFromFile(path);
|
||||||
if (XFAILED(result_code)) {
|
if (XFAILED(result_code)) {
|
||||||
XELOGE(XT("Failed to load module %s: %.8X"), path, result_code);
|
XELOGE("Failed to load module %s: %.8X", path, result_code);
|
||||||
module->Release();
|
module->Release();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_abort_before_entry) {
|
if (FLAGS_abort_before_entry) {
|
||||||
XELOGI(XT("--abort_before_entry causing an early exit"));
|
XELOGI("--abort_before_entry causing an early exit");
|
||||||
module->Release();
|
module->Release();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ int XboxkrnlModule::LaunchModule(const char* path) {
|
||||||
// NOTE: this won't return until the module exits.
|
// NOTE: this won't return until the module exits.
|
||||||
result_code = module->Launch(0);
|
result_code = module->Launch(0);
|
||||||
if (XFAILED(result_code)) {
|
if (XFAILED(result_code)) {
|
||||||
XELOGE(XT("Failed to launch module %s: %.8X"), path, result_code);
|
XELOGE("Failed to launch module %s: %.8X", path, result_code);
|
||||||
module->Release();
|
module->Release();
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,11 +59,11 @@ X_STATUS XModule::LoadFromFile(const char* path) {
|
||||||
// TODO(benvanik): make this code shared?
|
// TODO(benvanik): make this code shared?
|
||||||
fs::Entry* fs_entry = kernel_state()->filesystem()->ResolvePath(path);
|
fs::Entry* fs_entry = kernel_state()->filesystem()->ResolvePath(path);
|
||||||
if (!fs_entry) {
|
if (!fs_entry) {
|
||||||
XELOGE(XT("File not found: %s"), path);
|
XELOGE("File not found: %s", path);
|
||||||
return X_STATUS_NO_SUCH_FILE;
|
return X_STATUS_NO_SUCH_FILE;
|
||||||
}
|
}
|
||||||
if (fs_entry->type() != fs::Entry::kTypeFile) {
|
if (fs_entry->type() != fs::Entry::kTypeFile) {
|
||||||
XELOGE(XT("Invalid file type: %s"), path);
|
XELOGE("Invalid file type: %s", path);
|
||||||
return X_STATUS_NO_SUCH_FILE;
|
return X_STATUS_NO_SUCH_FILE;
|
||||||
}
|
}
|
||||||
fs::FileEntry* fs_file = static_cast<fs::FileEntry*>(fs_entry);
|
fs::FileEntry* fs_file = static_cast<fs::FileEntry*>(fs_entry);
|
||||||
|
@ -114,14 +114,14 @@ X_STATUS XModule::GetSection(const char* name,
|
||||||
|
|
||||||
void* XModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
void* XModule::GetProcAddressByOrdinal(uint16_t ordinal) {
|
||||||
// TODO(benvanik): check export tables.
|
// TODO(benvanik): check export tables.
|
||||||
XELOGE(XT("GetProcAddressByOrdinal not implemented"));
|
XELOGE("GetProcAddressByOrdinal not implemented");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XModule::Launch(uint32_t flags) {
|
X_STATUS XModule::Launch(uint32_t flags) {
|
||||||
const xe_xex2_header_t* header = xex_header();
|
const xe_xex2_header_t* header = xex_header();
|
||||||
|
|
||||||
XELOGI(XT("Launching module..."));
|
XELOGI("Launching module...");
|
||||||
|
|
||||||
// Set as the main module, while running.
|
// Set as the main module, while running.
|
||||||
kernel_state()->SetExecutableModule(this);
|
kernel_state()->SetExecutableModule(this);
|
||||||
|
@ -137,7 +137,7 @@ X_STATUS XModule::Launch(uint32_t flags) {
|
||||||
|
|
||||||
X_STATUS result = thread->Create();
|
X_STATUS result = thread->Create();
|
||||||
if (XFAILED(result)) {
|
if (XFAILED(result)) {
|
||||||
XELOGE(XT("Could not create launch thread: %.8X"), result);
|
XELOGE("Could not create launch thread: %.8X", result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ XThread::~XThread() {
|
||||||
|
|
||||||
if (thread_handle_) {
|
if (thread_handle_) {
|
||||||
// TODO(benvanik): platform kill
|
// TODO(benvanik): platform kill
|
||||||
XELOGE(XT("Thread disposed without exiting"));
|
XELOGE("Thread disposed without exiting");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ X_STATUS XThread::Create() {
|
||||||
// consistent.
|
// consistent.
|
||||||
thread_state_address_ = xe_memory_heap_alloc(memory(), 0, 2048, 0);
|
thread_state_address_ = xe_memory_heap_alloc(memory(), 0, 2048, 0);
|
||||||
if (!thread_state_address_) {
|
if (!thread_state_address_) {
|
||||||
XELOGW(XT("Unable to allocate thread state block"));
|
XELOGW("Unable to allocate thread state block");
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,13 +106,13 @@ X_STATUS XThread::Create() {
|
||||||
processor_state_ = kernel_state()->processor()->AllocThread(
|
processor_state_ = kernel_state()->processor()->AllocThread(
|
||||||
creation_params_.stack_size, thread_state_address_);
|
creation_params_.stack_size, thread_state_address_);
|
||||||
if (!processor_state_) {
|
if (!processor_state_) {
|
||||||
XELOGW(XT("Unable to allocate processor thread state"));
|
XELOGW("Unable to allocate processor thread state");
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS return_code = PlatformCreate();
|
X_STATUS return_code = PlatformCreate();
|
||||||
if (XFAILED(return_code)) {
|
if (XFAILED(return_code)) {
|
||||||
XELOGW(XT("Unable to create platform thread (%.8X)"), return_code);
|
XELOGW("Unable to create platform thread (%.8X)", return_code);
|
||||||
return return_code;
|
return return_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ X_STATUS XThread::PlatformCreate() {
|
||||||
if (!thread_handle_) {
|
if (!thread_handle_) {
|
||||||
uint32_t last_error = GetLastError();
|
uint32_t last_error = GetLastError();
|
||||||
// TODO(benvanik): translate?
|
// TODO(benvanik): translate?
|
||||||
XELOGE(XT("CreateThread failed with %d"), last_error);
|
XELOGE("CreateThread failed with %d", last_error);
|
||||||
return last_error;
|
return last_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ X_STATUS XThread::PlatformExit(int exit_code) {
|
||||||
void XThread::Execute() {
|
void XThread::Execute() {
|
||||||
// Run XapiThreadStartup first, if present.
|
// Run XapiThreadStartup first, if present.
|
||||||
if (creation_params_.xapi_thread_startup) {
|
if (creation_params_.xapi_thread_startup) {
|
||||||
XELOGE(XT("xapi_thread_startup not implemented"));
|
XELOGE("xapi_thread_startup not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run user code.
|
// Run user code.
|
||||||
|
|
|
@ -30,12 +30,12 @@ void HalReturnToFirmware_shim(
|
||||||
uint32_t routine = SHIM_GET_ARG_32(0);
|
uint32_t routine = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("HalReturnToFirmware(%d)"),
|
"HalReturnToFirmware(%d)",
|
||||||
routine);
|
routine);
|
||||||
|
|
||||||
// TODO(benvank): diediedie much more gracefully
|
// TODO(benvank): diediedie much more gracefully
|
||||||
// Not sure how to blast back up the stack in LLVM without exceptions, though.
|
// Not sure how to blast back up the stack in LLVM without exceptions, though.
|
||||||
XELOGE(XT("Game requested shutdown via HalReturnToFirmware"));
|
XELOGE("Game requested shutdown via HalReturnToFirmware");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ void NtAllocateVirtualMemory_shim(
|
||||||
XEASSERT(unknown == 0);
|
XEASSERT(unknown == 0);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)"),
|
"NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)",
|
||||||
base_addr_ptr, base_addr_value,
|
base_addr_ptr, base_addr_value,
|
||||||
region_size_ptr, region_size_value,
|
region_size_ptr, region_size_value,
|
||||||
allocation_type, protect_bits, unknown);
|
allocation_type, protect_bits, unknown);
|
||||||
|
@ -116,7 +116,7 @@ void NtFreeVirtualMemory_shim(
|
||||||
XEASSERT(unknown == 0);
|
XEASSERT(unknown == 0);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)"),
|
"NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)",
|
||||||
base_addr_ptr, base_addr_value,
|
base_addr_ptr, base_addr_value,
|
||||||
region_size_ptr, region_size_value,
|
region_size_ptr, region_size_value,
|
||||||
free_type, unknown);
|
free_type, unknown);
|
||||||
|
|
|
@ -38,7 +38,7 @@ void XexCheckExecutablePrivilege_shim(
|
||||||
uint32_t privilege = SHIM_GET_ARG_32(0);
|
uint32_t privilege = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("XexCheckExecutablePrivilege(%.8X)"),
|
"XexCheckExecutablePrivilege(%.8X)",
|
||||||
privilege);
|
privilege);
|
||||||
|
|
||||||
// Privilege is bit position in xe_xex2_system_flags enum - so:
|
// Privilege is bit position in xe_xex2_system_flags enum - so:
|
||||||
|
@ -73,7 +73,7 @@ void XexGetModuleHandle_shim(
|
||||||
uint32_t module_handle_ptr = SHIM_GET_ARG_32(1);
|
uint32_t module_handle_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("XexGetModuleHandle(%s, %.8X)"),
|
"XexGetModuleHandle(%s, %.8X)",
|
||||||
module_name, module_handle_ptr);
|
module_name, module_handle_ptr);
|
||||||
|
|
||||||
XModule* module = state->GetModule(module_name);
|
XModule* module = state->GetModule(module_name);
|
||||||
|
|
|
@ -36,7 +36,7 @@ void RtlCompareMemory_shim(
|
||||||
uint32_t length = SHIM_GET_ARG_32(2);
|
uint32_t length = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("RtlCompareMemory(%.8X, %.8X, %d)"),
|
"RtlCompareMemory(%.8X, %.8X, %d)",
|
||||||
source1, source2, length);
|
source1, source2, length);
|
||||||
|
|
||||||
uint8_t* p1 = SHIM_MEM_ADDR(source1);
|
uint8_t* p1 = SHIM_MEM_ADDR(source1);
|
||||||
|
@ -69,7 +69,7 @@ void RtlCompareMemoryUlong_shim(
|
||||||
uint32_t pattern = SHIM_GET_ARG_32(2);
|
uint32_t pattern = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("RtlCompareMemoryUlong(%.8X, %d, %.8X)"),
|
"RtlCompareMemoryUlong(%.8X, %d, %.8X)",
|
||||||
source, length, pattern);
|
source, length, pattern);
|
||||||
|
|
||||||
if ((source % 4) || (length % 4)) {
|
if ((source % 4) || (length % 4)) {
|
||||||
|
@ -109,7 +109,7 @@ void RtlFillMemoryUlong_shim(
|
||||||
uint32_t pattern = SHIM_GET_ARG_32(2);
|
uint32_t pattern = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("RtlFillMemoryUlong(%.8X, %d, %.8X)"),
|
"RtlFillMemoryUlong(%.8X, %d, %.8X)",
|
||||||
destination, length, pattern);
|
destination, length, pattern);
|
||||||
|
|
||||||
// NOTE: length must be % 4, so we can work on uint32s.
|
// NOTE: length must be % 4, so we can work on uint32s.
|
||||||
|
@ -142,7 +142,7 @@ void RtlInitAnsiString_shim(
|
||||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
const char* source = source_ptr ? (char*)SHIM_MEM_ADDR(source_ptr) : NULL;
|
const char* source = source_ptr ? (char*)SHIM_MEM_ADDR(source_ptr) : NULL;
|
||||||
XELOGD(XT("RtlInitAnsiString(%.8X, %.8X = %s)"),
|
XELOGD("RtlInitAnsiString(%.8X, %.8X = %s)",
|
||||||
destination_ptr, source_ptr, source ? source : "<null>");
|
destination_ptr, source_ptr, source ? source : "<null>");
|
||||||
|
|
||||||
uint16_t length = source ? (uint16_t)xestrlena(source) : 0;
|
uint16_t length = source ? (uint16_t)xestrlena(source) : 0;
|
||||||
|
@ -160,11 +160,11 @@ void RtlFreeAnsiString_shim(
|
||||||
|
|
||||||
uint32_t string_ptr = SHIM_GET_ARG_32(0);
|
uint32_t string_ptr = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(XT("RtlFreeAnsiString(%.8X)"), string_ptr);
|
XELOGD("RtlFreeAnsiString(%.8X)", string_ptr);
|
||||||
|
|
||||||
//uint32_t buffer = SHIM_MEM_32(string_ptr + 4);
|
//uint32_t buffer = SHIM_MEM_32(string_ptr + 4);
|
||||||
// TODO(benvanik): free the buffer
|
// TODO(benvanik): free the buffer
|
||||||
XELOGE(XT("RtlFreeAnsiString leaking buffer"));
|
XELOGE("RtlFreeAnsiString leaking buffer");
|
||||||
|
|
||||||
SHIM_SET_MEM_16(string_ptr + 0, 0);
|
SHIM_SET_MEM_16(string_ptr + 0, 0);
|
||||||
SHIM_SET_MEM_16(string_ptr + 2, 0);
|
SHIM_SET_MEM_16(string_ptr + 2, 0);
|
||||||
|
@ -191,7 +191,7 @@ void RtlInitUnicodeString_shim(
|
||||||
|
|
||||||
const wchar_t* source =
|
const wchar_t* source =
|
||||||
source_ptr ? (const wchar_t*)SHIM_MEM_ADDR(source_ptr) : NULL;
|
source_ptr ? (const wchar_t*)SHIM_MEM_ADDR(source_ptr) : NULL;
|
||||||
XELOGD(XT("RtlInitUnicodeString(%.8X, %.8X = %ls)"),
|
XELOGD("RtlInitUnicodeString(%.8X, %.8X = %ls)",
|
||||||
destination_ptr, source_ptr, source ? source : L"<null>");
|
destination_ptr, source_ptr, source ? source : L"<null>");
|
||||||
|
|
||||||
uint16_t length = source ? (uint16_t)xestrlenw(source) : 0;
|
uint16_t length = source ? (uint16_t)xestrlenw(source) : 0;
|
||||||
|
@ -209,11 +209,11 @@ void RtlFreeUnicodeString_shim(
|
||||||
|
|
||||||
uint32_t string_ptr = SHIM_GET_ARG_32(0);
|
uint32_t string_ptr = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(XT("RtlFreeUnicodeString(%.8X)"), string_ptr);
|
XELOGD("RtlFreeUnicodeString(%.8X)", string_ptr);
|
||||||
|
|
||||||
//uint32_t buffer = SHIM_MEM_32(string_ptr + 4);
|
//uint32_t buffer = SHIM_MEM_32(string_ptr + 4);
|
||||||
// TODO(benvanik): free the buffer
|
// TODO(benvanik): free the buffer
|
||||||
XELOGE(XT("RtlFreeUnicodeString leaking buffer"));
|
XELOGE("RtlFreeUnicodeString leaking buffer");
|
||||||
|
|
||||||
SHIM_SET_MEM_16(string_ptr + 0, 0);
|
SHIM_SET_MEM_16(string_ptr + 0, 0);
|
||||||
SHIM_SET_MEM_16(string_ptr + 2, 0);
|
SHIM_SET_MEM_16(string_ptr + 2, 0);
|
||||||
|
@ -233,10 +233,10 @@ void RtlUnicodeStringToAnsiString_shim(
|
||||||
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
uint32_t source_ptr = SHIM_GET_ARG_32(1);
|
||||||
uint32_t alloc_dest = SHIM_GET_ARG_32(2);
|
uint32_t alloc_dest = SHIM_GET_ARG_32(2);
|
||||||
|
|
||||||
XELOGD(XT("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)"),
|
XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)",
|
||||||
destination_ptr, source_ptr, alloc_dest);
|
destination_ptr, source_ptr, alloc_dest);
|
||||||
|
|
||||||
XELOGE(XT("RtlUnicodeStringToAnsiString not yet implemented"));
|
XELOGE("RtlUnicodeStringToAnsiString not yet implemented");
|
||||||
|
|
||||||
if (alloc_dest) {
|
if (alloc_dest) {
|
||||||
// Allocate a new buffer to place the string into.
|
// Allocate a new buffer to place the string into.
|
||||||
|
@ -267,11 +267,11 @@ void RtlImageXexHeaderField_shim(
|
||||||
// 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support.
|
// 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support.
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("RtlImageXexHeaderField(%.8X, %.8X)"),
|
"RtlImageXexHeaderField(%.8X, %.8X)",
|
||||||
xex_header_base, image_field);
|
xex_header_base, image_field);
|
||||||
|
|
||||||
if (xex_header_base != 0x80101100) {
|
if (xex_header_base != 0x80101100) {
|
||||||
XELOGE(XT("RtlImageXexHeaderField with non-magic base NOT IMPLEMENTED"));
|
XELOGE("RtlImageXexHeaderField with non-magic base NOT IMPLEMENTED");
|
||||||
SHIM_SET_RETURN(0);
|
SHIM_SET_RETURN(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ void RtlImageXexHeaderField_shim(
|
||||||
return_value = 0;
|
return_value = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
XELOGE(XT("RtlImageXexHeaderField header field %.8X NOT IMPLEMENTED"),
|
XELOGE("RtlImageXexHeaderField header field %.8X NOT IMPLEMENTED",
|
||||||
image_field);
|
image_field);
|
||||||
SHIM_SET_RETURN(0);
|
SHIM_SET_RETURN(0);
|
||||||
return;
|
return;
|
||||||
|
@ -349,7 +349,7 @@ void RtlInitializeCriticalSection_shim(
|
||||||
|
|
||||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(XT("RtlInitializeCriticalSection(%.8X)"), cs_ptr);
|
XELOGD("RtlInitializeCriticalSection(%.8X)", cs_ptr);
|
||||||
|
|
||||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||||
cs->spin_count_div_256 = 0;
|
cs->spin_count_div_256 = 0;
|
||||||
|
@ -368,7 +368,7 @@ void RtlInitializeCriticalSectionAndSpinCount_shim(
|
||||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||||
uint32_t spin_count = SHIM_GET_ARG_32(1);
|
uint32_t spin_count = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
XELOGD(XT("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)"),
|
XELOGD("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)",
|
||||||
cs_ptr, spin_count);
|
cs_ptr, spin_count);
|
||||||
|
|
||||||
// Spin count is rouned up to 256 intervals then packed in.
|
// Spin count is rouned up to 256 intervals then packed in.
|
||||||
|
@ -391,7 +391,7 @@ void RtlEnterCriticalSection_shim(
|
||||||
|
|
||||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(XT("RtlEnterCriticalSection(%.8X)"), cs_ptr);
|
XELOGD("RtlEnterCriticalSection(%.8X)", cs_ptr);
|
||||||
|
|
||||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||||
|
|
||||||
|
@ -414,7 +414,7 @@ spin:
|
||||||
|
|
||||||
// All out of spin waits, create a full waiter.
|
// All out of spin waits, create a full waiter.
|
||||||
// TODO(benvanik): contention - do a real wait!
|
// TODO(benvanik): contention - do a real wait!
|
||||||
XELOGE(XT("RtlEnterCriticalSection tried to really lock!"));
|
XELOGE("RtlEnterCriticalSection tried to really lock!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now own the lock.
|
// Now own the lock.
|
||||||
|
@ -430,7 +430,7 @@ void RtlTryEnterCriticalSection_shim(
|
||||||
|
|
||||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(XT("RtlTryEnterCriticalSection(%.8X)"), cs_ptr);
|
XELOGD("RtlTryEnterCriticalSection(%.8X)", cs_ptr);
|
||||||
|
|
||||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||||
|
|
||||||
|
@ -461,7 +461,7 @@ void RtlLeaveCriticalSection_shim(
|
||||||
|
|
||||||
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
uint32_t cs_ptr = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(XT("RtlLeaveCriticalSection(%.8X)"), cs_ptr);
|
XELOGD("RtlLeaveCriticalSection(%.8X)", cs_ptr);
|
||||||
|
|
||||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr);
|
||||||
|
|
||||||
|
@ -477,7 +477,7 @@ void RtlLeaveCriticalSection_shim(
|
||||||
if (xe_atomic_dec_32(&cs->lock_count) != -1) {
|
if (xe_atomic_dec_32(&cs->lock_count) != -1) {
|
||||||
// There were waiters - wake one of them.
|
// There were waiters - wake one of them.
|
||||||
// TODO(benvanik): wake a waiter.
|
// TODO(benvanik): wake a waiter.
|
||||||
XELOGE(XT("RtlLeaveCriticalSection would have woken a waiter"));
|
XELOGE("RtlLeaveCriticalSection would have woken a waiter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ void ExCreateThread_shim(
|
||||||
uint32_t creation_flags = SHIM_GET_ARG_32(6);
|
uint32_t creation_flags = SHIM_GET_ARG_32(6);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("ExCreateThread(%.8X, %d, %.8X, %.8X, %.8X, %.8X, %.8X)"),
|
"ExCreateThread(%.8X, %d, %.8X, %.8X, %.8X, %.8X, %.8X)",
|
||||||
handle_ptr,
|
handle_ptr,
|
||||||
stack_size,
|
stack_size,
|
||||||
thread_id_ptr,
|
thread_id_ptr,
|
||||||
|
@ -92,7 +92,7 @@ void ExCreateThread_shim(
|
||||||
if (XFAILED(result_code)) {
|
if (XFAILED(result_code)) {
|
||||||
// Failed!
|
// Failed!
|
||||||
thread->Release();
|
thread->Release();
|
||||||
XELOGE(XT("Thread creation failed: %.8X"), result_code);
|
XELOGE("Thread creation failed: %.8X", result_code);
|
||||||
SHIM_SET_RETURN(result_code);
|
SHIM_SET_RETURN(result_code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ void KeGetCurrentProcessType_shim(
|
||||||
// DWORD
|
// DWORD
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("KeGetCurrentProcessType()"));
|
"KeGetCurrentProcessType()");
|
||||||
|
|
||||||
SHIM_SET_RETURN(X_PROCTYPE_USER);
|
SHIM_SET_RETURN(X_PROCTYPE_USER);
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ void KeTlsAlloc_shim(
|
||||||
// DWORD
|
// DWORD
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("KeTlsAlloc()"));
|
"KeTlsAlloc()");
|
||||||
|
|
||||||
uint32_t tls_index;
|
uint32_t tls_index;
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ void KeTlsFree_shim(
|
||||||
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("KeTlsFree(%.8X)"),
|
"KeTlsFree(%.8X)",
|
||||||
tls_index);
|
tls_index);
|
||||||
|
|
||||||
if (tls_index == X_TLS_OUT_OF_INDEXES) {
|
if (tls_index == X_TLS_OUT_OF_INDEXES) {
|
||||||
|
@ -187,7 +187,7 @@ void KeTlsGetValue_shim(
|
||||||
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
uint32_t tls_index = SHIM_GET_ARG_32(0);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("KeTlsGetValue(%.8X)"),
|
"KeTlsGetValue(%.8X)",
|
||||||
tls_index);
|
tls_index);
|
||||||
|
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
|
@ -199,7 +199,7 @@ void KeTlsGetValue_shim(
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
XELOGW(XT("KeTlsGetValue should SetLastError if result is NULL"));
|
XELOGW("KeTlsGetValue should SetLastError if result is NULL");
|
||||||
// TODO(benvanik): SetLastError
|
// TODO(benvanik): SetLastError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ void KeTlsSetValue_shim(
|
||||||
uint32_t tls_value = SHIM_GET_ARG_32(1);
|
uint32_t tls_value = SHIM_GET_ARG_32(1);
|
||||||
|
|
||||||
XELOGD(
|
XELOGD(
|
||||||
XT("KeTlsSetValue(%.8X, %.8X)"),
|
"KeTlsSetValue(%.8X, %.8X)",
|
||||||
tls_index, tls_value);
|
tls_index, tls_value);
|
||||||
|
|
||||||
int result_code = 0;
|
int result_code = 0;
|
||||||
|
|
|
@ -92,7 +92,7 @@ int Runtime::LaunchXexFile(const xechar_t* path) {
|
||||||
result_code = filesystem_->RegisterLocalDirectoryDevice(
|
result_code = filesystem_->RegisterLocalDirectoryDevice(
|
||||||
"\\Device\\Harddisk1\\Partition0", parent_path);
|
"\\Device\\Harddisk1\\Partition0", parent_path);
|
||||||
if (result_code) {
|
if (result_code) {
|
||||||
XELOGE(XT("Unable to mount local directory %s"), parent_path);
|
XELOGE("Unable to mount local directory");
|
||||||
return result_code;
|
return result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ int Runtime::LaunchDiscImage(const xechar_t* path) {
|
||||||
result_code = filesystem_->RegisterDiscImageDevice(
|
result_code = filesystem_->RegisterDiscImageDevice(
|
||||||
"\\Device\\Cdrom0", path);
|
"\\Device\\Cdrom0", path);
|
||||||
if (result_code) {
|
if (result_code) {
|
||||||
XELOGE(XT("Unable to mount disc image %s"), path);
|
XELOGE("Unable to mount disc image");
|
||||||
return result_code;
|
return result_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
||||||
res->size = XEGETUINT32BE(pp + 0x10);
|
res->size = XEGETUINT32BE(pp + 0x10);
|
||||||
if ((opt_header->length - 4) / 16 > 1) {
|
if ((opt_header->length - 4) / 16 > 1) {
|
||||||
// Ignoring extra resources (not yet seen)
|
// Ignoring extra resources (not yet seen)
|
||||||
XELOGW(XT("ignoring extra XEX_HEADER_RESOURCE_INFO resources"));
|
XELOGW("ignoring extra XEX_HEADER_RESOURCE_INFO resources");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -219,8 +219,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
||||||
size_t count = XEGETUINT32BE(pp + 0x08);
|
size_t count = XEGETUINT32BE(pp + 0x08);
|
||||||
XEASSERT(count <= max_count);
|
XEASSERT(count <= max_count);
|
||||||
if (count > max_count) {
|
if (count > max_count) {
|
||||||
XELOGW(XT("ignoring %zu extra entries in ")
|
XELOGW("ignoring %zu extra entries in XEX_HEADER_IMPORT_LIBRARIES",
|
||||||
XT("XEX_HEADER_IMPORT_LIBRARIES"), (max_count - count));
|
(max_count - count));
|
||||||
count = max_count;
|
count = max_count;
|
||||||
}
|
}
|
||||||
header->import_library_count = count;
|
header->import_library_count = count;
|
||||||
|
@ -273,8 +273,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length,
|
||||||
size_t count = (opt_header->length - 4) / 16;
|
size_t count = (opt_header->length - 4) / 16;
|
||||||
XEASSERT(count <= max_count);
|
XEASSERT(count <= max_count);
|
||||||
if (count > max_count) {
|
if (count > max_count) {
|
||||||
XELOGW(XT("ignoring %zu extra entries in ")
|
XELOGW("ignoring %zu extra entries in XEX_HEADER_STATIC_LIBRARIES",
|
||||||
XT("XEX_HEADER_STATIC_LIBRARIES"), (max_count - count));
|
(max_count - count));
|
||||||
count = max_count;
|
count = max_count;
|
||||||
}
|
}
|
||||||
header->static_library_count = count;
|
header->static_library_count = count;
|
||||||
|
@ -763,7 +763,7 @@ int xe_xex2_load_pe(xe_xex2_ref xex) {
|
||||||
// Verify DOS signature (MZ).
|
// Verify DOS signature (MZ).
|
||||||
const IMAGE_DOS_HEADER* doshdr = (const IMAGE_DOS_HEADER*)p;
|
const IMAGE_DOS_HEADER* doshdr = (const IMAGE_DOS_HEADER*)p;
|
||||||
if (doshdr->e_magic != IMAGE_DOS_SIGNATURE) {
|
if (doshdr->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||||
XELOGE(XT("PE signature mismatch; likely bad decryption/decompression"));
|
XELOGE("PE signature mismatch; likely bad decryption/decompression");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
#include <xenia/common.h>
|
#include <xenia/common.h>
|
||||||
|
|
||||||
|
|
||||||
void xe_log_line(const xechar_t* file_path, const uint32_t line_number,
|
void xe_log_line(const char* file_path, const uint32_t line_number,
|
||||||
const xechar_t* function_name, const xechar_t level_char,
|
const char* function_name, const char level_char,
|
||||||
const xechar_t* fmt, ...) {
|
const char* fmt, ...) {
|
||||||
const int kLogMax = 2048;
|
const int kLogMax = 2048;
|
||||||
|
|
||||||
// Strip out just the filename from the path.
|
// Strip out just the filename from the path.
|
||||||
const xechar_t* filename = xestrrchr(file_path, XE_PATH_SEPARATOR);
|
const char* filename = xestrrchra(file_path, XE_PATH_SEPARATOR);
|
||||||
if (filename) {
|
if (filename) {
|
||||||
// Slash - skip over it.
|
// Slash - skip over it.
|
||||||
filename++;
|
filename++;
|
||||||
|
@ -30,29 +30,27 @@ void xe_log_line(const xechar_t* file_path, const uint32_t line_number,
|
||||||
// Scribble args into the print buffer.
|
// Scribble args into the print buffer.
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
xechar_t buffer[kLogMax];
|
char buffer[kLogMax];
|
||||||
int buffer_length = xevsnprintf(buffer, XECOUNT(buffer), fmt, args);
|
int buffer_length = xevsnprintfa(buffer, XECOUNT(buffer), fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
if (buffer_length < 0) {
|
if (buffer_length < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format string - add a trailing newline if required.
|
// Format string - add a trailing newline if required.
|
||||||
const xechar_t* outfmt;
|
const char* outfmt;
|
||||||
if ((buffer_length >= 1) && buffer[buffer_length - 1] == '\n') {
|
if ((buffer_length >= 1) && buffer[buffer_length - 1] == '\n') {
|
||||||
outfmt = XT("XE[%c] %s:%d: %s");
|
outfmt = "XE[%c] %s:%d: %s";
|
||||||
} else {
|
} else {
|
||||||
outfmt = XT("XE[%c] %s:%d: %s\n");
|
outfmt = "XE[%c] %s:%d: %s\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OutputDebugString)
|
#if defined(OutputDebugString)
|
||||||
xechar_t full_output[kLogMax];
|
char full_output[kLogMax];
|
||||||
if (xesnprintf(full_output, XECOUNT(buffer), outfmt, level_char,
|
if (xesnprintfa(full_output, XECOUNT(buffer), outfmt, level_char,
|
||||||
filename, line_number, buffer) >= 0) {
|
filename, line_number, buffer) >= 0) {
|
||||||
OutputDebugString(full_output);
|
OutputDebugStringA(full_output);
|
||||||
}
|
}
|
||||||
#elif defined(XE_WCHAR)
|
|
||||||
XEIGNORE(fwprintf(stdout, outfmt, level_char, filename, line_number, buffer));
|
|
||||||
#else
|
#else
|
||||||
XEIGNORE(fprintf(stdout, outfmt, level_char, filename, line_number, buffer));
|
XEIGNORE(fprintf(stdout, outfmt, level_char, filename, line_number, buffer));
|
||||||
#endif // OutputDebugString
|
#endif // OutputDebugString
|
||||||
|
|
|
@ -21,9 +21,9 @@
|
||||||
#else
|
#else
|
||||||
#define XE_LOG_LINE_ATTRIBUTE
|
#define XE_LOG_LINE_ATTRIBUTE
|
||||||
#endif // GNUC
|
#endif // GNUC
|
||||||
void xe_log_line(const xechar_t* file_path, const uint32_t line_number,
|
void xe_log_line(const char* file_path, const uint32_t line_number,
|
||||||
const xechar_t* function_name, const xechar_t level_char,
|
const char* function_name, const char level_char,
|
||||||
const xechar_t* fmt, ...) XE_LOG_LINE_ATTRIBUTE;
|
const char* fmt, ...) XE_LOG_LINE_ATTRIBUTE;
|
||||||
#undef XE_LOG_LINE_ATTRIBUTE
|
#undef XE_LOG_LINE_ATTRIBUTE
|
||||||
|
|
||||||
#if XE_OPTION(ENABLE_LOGGING)
|
#if XE_OPTION(ENABLE_LOGGING)
|
||||||
|
|
|
@ -21,7 +21,7 @@ typedef int (*user_main_t)(int argc, xechar_t** argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if XE_PLATFORM(WIN32) && XE_WCHAR
|
#if XE_LIKE(WIN32) && defined(UNICODE) && UNICODE
|
||||||
|
|
||||||
int xe_main_thunk(
|
int xe_main_thunk(
|
||||||
int argc, wchar_t* argv[],
|
int argc, wchar_t* argv[],
|
||||||
|
@ -29,22 +29,27 @@ int xe_main_thunk(
|
||||||
google::SetUsageMessage(std::string("usage: ") + usage);
|
google::SetUsageMessage(std::string("usage: ") + usage);
|
||||||
google::SetVersionString("1.0");
|
google::SetVersionString("1.0");
|
||||||
|
|
||||||
char** argva = new char*[argc];
|
int argca = argc;
|
||||||
for (int n = 0; n < argc; n++) {
|
char** argva = (char**)alloca(sizeof(char*) * argca);
|
||||||
|
for (int n = 0; n < argca; n++) {
|
||||||
size_t len = xestrlenw(argv[n]);
|
size_t len = xestrlenw(argv[n]);
|
||||||
argva[n] = (char*)malloc(len);
|
argva[n] = (char*)alloca(len + 1);
|
||||||
xestrnarrow(argva[n], len, argv[n]);
|
xestrnarrow(argva[n], len + 1, argv[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
google::ParseCommandLineFlags(&argc, &argva, true);
|
google::ParseCommandLineFlags(&argc, &argva, true);
|
||||||
|
|
||||||
int result = ((user_main_t)user_main)(argc, (xechar_t**)argv);
|
// Parse may have deleted flags - so widen again.
|
||||||
|
int argcw = argc;
|
||||||
|
wchar_t** argvw = (wchar_t**)alloca(sizeof(wchar_t*) * argca);
|
||||||
for (int n = 0; n < argc; n++) {
|
for (int n = 0; n < argc; n++) {
|
||||||
free(argva[n]);
|
size_t len = xestrlena(argva[n]);
|
||||||
|
argvw[n] = (wchar_t*)alloca(sizeof(wchar_t) * (len + 1));
|
||||||
|
xestrwiden(argvw[n], len + 1, argva[n]);
|
||||||
}
|
}
|
||||||
delete[] argva;
|
|
||||||
|
|
||||||
|
int result = ((user_main_t)user_main)(argcw, (xechar_t**)argvw);
|
||||||
|
google::ShutDownCommandLineFlags();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +61,9 @@ int xe_main_thunk(
|
||||||
google::SetUsageMessage(std::string("usage: ") + usage);
|
google::SetUsageMessage(std::string("usage: ") + usage);
|
||||||
google::SetVersionString("1.0");
|
google::SetVersionString("1.0");
|
||||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
return ((user_main_t)user_main)(argc, argv);
|
int result = ((user_main_t)user_main)(argc, argv);
|
||||||
|
google::ShutDownCommandLineFlags();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
|
@ -139,7 +139,7 @@ XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN
|
||||||
#define XE_ALIGNMENT 16
|
#define XE_ALIGNMENT 16
|
||||||
#endif // 32BIT
|
#endif // 32BIT
|
||||||
|
|
||||||
#if XE_LIKE(WIN32) && !defined(XE_CHAR)
|
#if XE_LIKE(WIN32) && defined(UNICODE) && UNICODE
|
||||||
int xe_main_thunk(
|
int xe_main_thunk(
|
||||||
int argc, wchar_t* argv[],
|
int argc, wchar_t* argv[],
|
||||||
void* user_main, const char* usage);
|
void* user_main, const char* usage);
|
||||||
|
|
|
@ -62,7 +62,7 @@ char* xestrcasestra(const char* str, const char* substr);
|
||||||
#define xesnprintfa(buffer, bufferCount, format, ...) _snprintf_s(buffer, bufferCount, bufferCount, format, ##__VA_ARGS__)
|
#define xesnprintfa(buffer, bufferCount, format, ...) _snprintf_s(buffer, bufferCount, bufferCount, format, ##__VA_ARGS__)
|
||||||
#define xevsnprintfa(buffer, bufferCount, format, args) vsnprintf(buffer, bufferCount, format, args)
|
#define xevsnprintfa(buffer, bufferCount, format, args) vsnprintf(buffer, bufferCount, format, args)
|
||||||
|
|
||||||
#if !defined(XE_CHAR) && XE_PLATFORM(WIN32)
|
#if XE_PLATFORM(WIN32) && defined(UNICODE) && UNICODE
|
||||||
|
|
||||||
typedef wchar_t xechar_t;
|
typedef wchar_t xechar_t;
|
||||||
#define XE_WCHAR 1
|
#define XE_WCHAR 1
|
||||||
|
|
|
@ -69,27 +69,19 @@ int Run::Launch(const xechar_t* path) {
|
||||||
// Normalize the path and make absolute.
|
// Normalize the path and make absolute.
|
||||||
// TODO(benvanik): move this someplace common.
|
// TODO(benvanik): move this someplace common.
|
||||||
xechar_t abs_path[XE_MAX_PATH];
|
xechar_t abs_path[XE_MAX_PATH];
|
||||||
#if XE_PLATFORM(WIN32)
|
xe_path_get_absolute(path, abs_path, XECOUNT(abs_path));
|
||||||
#if XE_WCHAR
|
|
||||||
_wfullpath(abs_path, path, XECOUNT(abs_path));
|
|
||||||
#else
|
|
||||||
_fullpath(abs_path, path, sizeof(abs_path));
|
|
||||||
#endif // XE_WCHAR
|
|
||||||
#else
|
|
||||||
realpath(path, abs_path);
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
// Grab file extension.
|
// Grab file extension.
|
||||||
const xechar_t* dot = xestrrchr(abs_path, '.');
|
const xechar_t* dot = xestrrchr(abs_path, '.');
|
||||||
if (!dot) {
|
if (!dot) {
|
||||||
XELOGE(XT("Invalid input path; no extension found"));
|
XELOGE("Invalid input path; no extension found");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the debugger.
|
// Run the debugger.
|
||||||
// This may pause waiting for connections.
|
// This may pause waiting for connections.
|
||||||
if (debugger_->Startup()) {
|
if (debugger_->Startup()) {
|
||||||
XELOGE(XT("Debugger failed to startup"));
|
XELOGE("Debugger failed to startup");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +121,6 @@ int xenia_run(int argc, xechar_t **argv) {
|
||||||
|
|
||||||
result_code = 0;
|
result_code = 0;
|
||||||
XECLEANUP:
|
XECLEANUP:
|
||||||
|
|
||||||
google::ShutDownCommandLineFlags();
|
|
||||||
return result_code;
|
return result_code;
|
||||||
}
|
}
|
||||||
XE_MAIN_THUNK(xenia_run, "xenia-run some.xex");
|
XE_MAIN_THUNK(xenia_run, "xenia-run some.xex");
|
||||||
|
|
|
@ -159,7 +159,7 @@ int discover_tests(string& test_path,
|
||||||
// TODO(benvanik): use PAL instead of this
|
// TODO(benvanik): use PAL instead of this
|
||||||
DIR* d = opendir(test_path.c_str());
|
DIR* d = opendir(test_path.c_str());
|
||||||
if (!d) {
|
if (!d) {
|
||||||
XELOGE(XT("Unable to find test path %s"), test_path.c_str());
|
XELOGE("Unable to find test path %s", test_path.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
struct dirent* dir;
|
struct dirent* dir;
|
||||||
|
@ -240,7 +240,6 @@ int xenia_test(int argc, xechar_t **argv) {
|
||||||
|
|
||||||
result_code = run_tests(test_name);
|
result_code = run_tests(test_name);
|
||||||
|
|
||||||
google::ShutDownCommandLineFlags();
|
|
||||||
return result_code;
|
return result_code;
|
||||||
}
|
}
|
||||||
XE_MAIN_THUNK(xenia_test, "xenia-test some.xex");
|
XE_MAIN_THUNK(xenia_test, "xenia-test some.xex");
|
||||||
|
|
Loading…
Reference in New Issue