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 "Core/HW/WII_IPC.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -148,10 +149,11 @@ void WiiIPC::Shutdown()
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// StarletOS phase 11 (proposal L2): with DOLPHIN_IPC_TRACE=1 while the original IOS runs on the
|
// StarletOS phase 11 (proposal L2): with DOLPHIN_IPC_TRACE=1 while the emulated Starlet runs
|
||||||
// emulated Starlet, each IPC request Broadway posts (X1) and each reply Starlet posts (Y1) is
|
// (the original IOS or a bootstrap ELF), each IPC request Broadway posts (X1) and each reply
|
||||||
// logged with its metadata only: the command, the descriptor and the five argument words (an
|
// Starlet posts (Y1) is logged with its metadata only: the command, the descriptor and the five
|
||||||
// OPEN's path), then the reply's result. Buffer contents are never read.
|
// 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()
|
bool IPCTraceEnabled()
|
||||||
{
|
{
|
||||||
static const bool enabled = [] {
|
static const bool enabled = [] {
|
||||||
@@ -161,6 +163,45 @@ bool IPCTraceEnabled()
|
|||||||
return enabled;
|
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)
|
void TraceIPCRequest(Core::System& system, u32 address)
|
||||||
{
|
{
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
@@ -177,6 +218,8 @@ void TraceIPCRequest(Core::System& system, u32 address)
|
|||||||
std::string path;
|
std::string path;
|
||||||
if (command == 1 && memory.GetPointerForRange(arg[0], 64) != nullptr)
|
if (command == 1 && memory.GetPointerForRange(arg[0], 64) != nullptr)
|
||||||
path = " P " + memory.GetString(arg[0], 64);
|
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}{}",
|
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],
|
address, command, static_cast<s32>(fd), arg[0], arg[1], arg[2], arg[3], arg[4],
|
||||||
path);
|
path);
|
||||||
|
|||||||
@@ -48,8 +48,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "Source/Core/Core/HW/WII_IPC.cpp",
|
"path": "Source/Core/Core/HW/WII_IPC.cpp",
|
||||||
"sha256": "e216d272f7653b4650481a3335989a86550eee3d90aa7e6c7f06bb1ce87822e1",
|
"sha256": "c3faf948533d494243caa229730dac8a8161144647aad22d219f1b4c9f727030",
|
||||||
"bytes": 21443
|
"bytes": 23116
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "Source/Core/Core/IOS/Starlet/ARMCore.cpp",
|
"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.cpp",
|
||||||
"Source/Core/Core/IOS/Starlet/StarletMemory.h"
|
"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
|
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).
|
(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