IOS LLE: IPC trace prints filesystem IOCTL paths (StarletOS phase 11 M1e)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Yaya48andClaude Opus 5.5 committed 2026-10-06 19:44:05 +02:00
1 parent 3ce435786c
commit 81ebec368b
3 files changed
+69 -6

No files matched your search

+47 -4
View File
@@ -3,6 +3,7 @@
#include "Core/HW/WII_IPC.h"
#include <algorithm>
#include <cstdlib>
#include <string>
@@ -148,10 +149,11 @@ void WiiIPC::Shutdown()
namespace
{
// StarletOS phase 11 (proposal L2): with DOLPHIN_IPC_TRACE=1 while the original IOS runs on the
// emulated Starlet, each IPC request Broadway posts (X1) and each reply Starlet posts (Y1) is
// logged with its metadata only: the command, the descriptor and the five argument words (an
// OPEN's path), then the reply's result. Buffer contents are never read.
// StarletOS phase 11 (proposal L2): with DOLPHIN_IPC_TRACE=1 while the emulated Starlet runs
// (the original IOS or a bootstrap ELF), each IPC request Broadway posts (X1) and each reply
// Starlet posts (Y1) is logged with its metadata only: the command, the descriptor and the five
// argument words (an OPEN's path), then the reply's result. Proposal M1e adds the paths of the
// filesystem IOCTLs. No other buffer content is read.
bool IPCTraceEnabled()
{
static const bool enabled = [] {
@@ -161,6 +163,45 @@ bool IPCTraceEnabled()
return enabled;
}
// A NUL-terminated absolute path of printable bytes in a 64-byte field, or "" otherwise.
std::string TracePath(Memory::MemoryManager& memory, u32 address)
{
if (memory.GetPointerForRange(address, 64) == nullptr)
return {};
const std::string path = memory.GetString(address, 64);
if (path.empty() || path.size() >= 64 || path[0] != '/' ||
!std::ranges::all_of(path, [](char c) { return c >= 0x20 && c < 0x7f; }))
return {};
return path;
}
// The paths a filesystem request names, by its input shape: a 64-byte path (DELETE, GET_ATTR),
// a 76-byte attribute record with the path at +6 (CREATE_DIR, CREATE_FILE, SET_ATTR), two
// 64-byte paths (RENAME), or an IOCTLV whose first input vector is a 64-byte path (READ_DIR,
// GET_USAGE). " F -" when the field holds no valid path.
std::string TraceFilesystemPaths(Memory::MemoryManager& memory, u32 command, const u32* arg)
{
const auto field = [&memory](u32 address) {
const std::string path = TracePath(memory, address);
return path.empty() ? std::string("-") : path;
};
if (command == 6)
{
if (arg[2] == 0x40)
return " F " + field(arg[1]);
if (arg[2] == 0x4c)
return " F " + field(arg[1] + 6);
if (arg[2] == 0x80)
return " F " + field(arg[1]) + " > " + field(arg[1] + 0x40);
}
else if (command == 7 && arg[1] != 0 && memory.GetPointerForRange(arg[3], 8) != nullptr &&
memory.Read_U32(arg[3] + 4) == 0x40)
{
return " F " + field(memory.Read_U32(arg[3]));
}
return {};
}
void TraceIPCRequest(Core::System& system, u32 address)
{
auto& memory = system.GetMemory();
@@ -177,6 +218,8 @@ void TraceIPCRequest(Core::System& system, u32 address)
std::string path;
if (command == 1 && memory.GetPointerForRange(arg[0], 64) != nullptr)
path = " P " + memory.GetString(arg[0], 64);
else
path = TraceFilesystemPaths(memory, command, arg);
NOTICE_LOG_FMT(WII_IPC, "IPCTRACE RQ {:08x} C {} FD {} A {:08x} {:08x} {:08x} {:08x} {:08x}{}",
address, command, static_cast<s32>(fd), arg[0], arg[1], arg[2], arg[3], arg[4],
path);