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:
1 parent
3ce435786c
commit
81ebec368b
3 files changed
+69
-6
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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.
|
||||
Reference in new issue
Block a user