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);
+9 -2
View File
@@ -48,8 +48,8 @@
},
{
"path": "Source/Core/Core/HW/WII_IPC.cpp",
"sha256": "e216d272f7653b4650481a3335989a86550eee3d90aa7e6c7f06bb1ce87822e1",
"bytes": 21443
"sha256": "c3faf948533d494243caa229730dac8a8161144647aad22d219f1b4c9f727030",
"bytes": 23116
},
{
"path": "Source/Core/Core/IOS/Starlet/ARMCore.cpp",
@@ -144,6 +144,13 @@
"Source/Core/Core/IOS/Starlet/StarletMemory.cpp",
"Source/Core/Core/IOS/Starlet/StarletMemory.h"
]
},
{
"recordedAt": "2026-10-06",
"purpose": "StarletOS Phase 11 proposal M1e: the IPC trace also prints the paths named by filesystem IOCTLs (64-byte path, 76-byte record at +6, rename pair, first IOCTLV vector of 64 bytes); paths only",
"files": [
"Source/Core/Core/HW/WII_IPC.cpp"
]
}
]
}
+13
View File
@@ -159,3 +159,16 @@ with Revolution instead of the original IOS, to see where Broadway stops.
Next: the companion's M1b (smoke test with the variable, no window) and M1c
(the user launches the Mii Channel under Revolution in the X11 window).
## Filesystem paths in the IPC trace — 2026-10-06
Companion proposal M1e (approved): under Revolution in the window the System
Menu's save before a launch got -106 on its second CREATE_DIR, and no trace
had the path. `IPCTRACE RQ` lines now end with ` F <path>` for IOCTLs whose
input is a 64-byte path (DELETE, GET_ATTR), a 76-byte attribute record (path
at +6: CREATE_DIR, CREATE_FILE, SET_ATTR) or two paths (` F a > b`, RENAME),
and for IOCTLVs whose first input vector is 64 bytes (READ_DIR, GET_USAGE);
` F -` when that field holds no valid path. Read from memory when X1 is
rung, like the OPEN path; nothing else of the buffers. Checked headless under
Revolution: `/shared2/test2`, `/title/00000001/00000002/data/cache.dat`, the
GET_USAGE directories. 95 Starlet tests passed.