mirror of
https://github.com/Pharaoh2k/ps5debug-NG.git
synced 2026-10-21 19:33:05 -05:00
v1.2.8: bulk write CMD 0xBDAACC04 + branding capability level "1.0"
- New 0xBDAACC04 bulk-write command (proc.c proc_write_multi_handle), dispatched
raw (no name macro). Collapses N CMD_PROC_WRITE round-trips into one: header
{pid,count,flags} then count streamed {u64 addr,u32 len,bytes} entries; two
CMD_SUCCESS words. Interleaved streaming keeps server memory bounded to one
64KiB scratch. Not auth-gated (mirrors single write). Caps: count<=0xFFFF,
entry<=0x100000 -> CMD_ERROR + abort. Opt-in per-entry status byte array via
flags bit 0 (PROC_WRITE_MULTI_F_STATUS), using a returning proc_write_mem
variant (ptwalk ret + mdbg bytes-written); single write + breakpoint callers
untouched.
- CMD_BRANDING (meta.c) now returns brand + NUL + capability level "1.0" so
capability-aware clients gate features without probing. Split literal
"\0" "1.0" (not octal \01).
- version.h 1.2.7 -> 1.2.8. PROTOCOL.md documents both.
HW-validated (wire test). Sources not yet comment-stripped (pre-push step).
This commit is contained in:
1 parent
f8456241fc
commit
fedbd4f6d7
6 files changed
+159
-7
No files matched your search
@@ -25,8 +25,13 @@ int handle_version(int fd, struct cmd_packet *packet) {
|
||||
|
||||
int handle_branding(int fd, struct cmd_packet *packet) {
|
||||
(void)packet;
|
||||
char brand[] = PS5DEBUG_NG_BRAND_STR;
|
||||
uint32_t len = (uint32_t)(sizeof(brand) - 1);
|
||||
/* Human brand, a NUL, then the capability LEVEL. C-string clients stop at the
|
||||
NUL so the displayed brand is unchanged; capability-aware clients read the
|
||||
level past it. NOTE: the literals are split ("\0" "1.0") on purpose - "\01.0"
|
||||
would be parsed as the octal escape \01, not a NUL followed by "1.0". Bump the
|
||||
level (and add the feature on the client) as new capabilities are added. */
|
||||
static const char brand[] = PS5DEBUG_NG_BRAND_STR "\0" "1.0";
|
||||
uint32_t len = (uint32_t)(sizeof(brand) - 1);
|
||||
net_send_all(fd, &len, sizeof(uint32_t));
|
||||
net_send_all(fd, brand, (int)len);
|
||||
return 0;
|
||||
|
||||
@@ -595,6 +595,108 @@ int proc_write_handle(int fd, struct cmd_packet *packet) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Like proc_write_mem but reports 0 on success / 1 on failure. Used only by
|
||||
the bulk-write handler so it can fill an optional per-entry status array;
|
||||
proc_write_mem and its breakpoint callers stay void. The signal is real:
|
||||
proc_ptwalk_write returns 0/1, and the mdbg fallback exposes bytes-written
|
||||
through its arg5 out-param (sys_proc_rw_inner sets it to length on success). */
|
||||
static int proc_write_mem_status(uint32_t pid, uint64_t addr, uint64_t len, const void *buf) {
|
||||
static int s_fw_needs_dmap = -1;
|
||||
if (s_fw_needs_dmap < 0)
|
||||
s_fw_needs_dmap = ((kernel_get_fw_version() & 0xffff0000u) >= 0x08400000u) ? 1 : 0;
|
||||
|
||||
if (s_fw_needs_dmap && proc_ptwalk_write(pid, addr, len, buf) == 0)
|
||||
return 0;
|
||||
|
||||
uint64_t wrote = 0;
|
||||
sys_proc_rw_w1((uint64_t)pid, addr, len, (void *)buf, (uint64_t)(uintptr_t)&wrote);
|
||||
return (wrote == len) ? 0 : 1;
|
||||
}
|
||||
|
||||
int proc_write_multi_handle(int fd, struct cmd_packet *packet) {
|
||||
struct cmd_proc_write_multi_packet *mp =
|
||||
(struct cmd_proc_write_multi_packet *)packet->data;
|
||||
if (!mp) {
|
||||
net_send_int32(fd, CMD_DATA_NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t pid = mp->pid;
|
||||
uint32_t count = mp->count;
|
||||
int want_status = (mp->flags & PROC_WRITE_MULTI_F_STATUS) ? 1 : 0;
|
||||
|
||||
if (count > PROC_WRITE_MULTI_MAX_COUNT) {
|
||||
net_send_int32(fd, CMD_ERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t *buf = (uint8_t *)net_alloc_buffer(0x10000);
|
||||
if (!buf) {
|
||||
net_send_int32(fd, CMD_DATA_NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t *status = NULL;
|
||||
if (want_status && count > 0) {
|
||||
status = (uint8_t *)net_alloc_buffer(count);
|
||||
if (!status) {
|
||||
free(buf);
|
||||
net_send_int32(fd, CMD_DATA_NULL);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
net_send_int32(fd, CMD_SUCCESS);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
uint8_t hdr[12];
|
||||
if (net_recv_all(fd, hdr, 12, 1) < 0) {
|
||||
/* socket broken mid-stream; bail without further sends */
|
||||
if (status) free(status);
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
uint64_t addr;
|
||||
uint32_t len32;
|
||||
memcpy(&addr, hdr, 8);
|
||||
memcpy(&len32, hdr + 8, 4);
|
||||
|
||||
if (len32 > PROC_WRITE_MULTI_MAX_ENTRY) {
|
||||
/* protocol violation: we can't know how many data bytes follow,
|
||||
so the stream is no longer trustworthy - abort the command. */
|
||||
if (status) free(status);
|
||||
free(buf);
|
||||
net_send_int32(fd, CMD_ERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t length = len32;
|
||||
uint64_t a = addr;
|
||||
uint8_t failed = 0;
|
||||
while (length > 0) {
|
||||
uint64_t to_recv = (length > 0x10000ULL) ? 0x10000ULL : length;
|
||||
if (net_recv_all(fd, buf, (int)to_recv, 1) < 0) {
|
||||
if (status) free(status);
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
if (proc_write_mem_status(pid, a, to_recv, buf) != 0)
|
||||
failed = 1;
|
||||
a += to_recv;
|
||||
length -= to_recv;
|
||||
}
|
||||
if (status) status[i] = failed;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
net_send_all(fd, status, (int)count);
|
||||
free(status);
|
||||
}
|
||||
net_send_int32(fd, CMD_SUCCESS);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int proc_maps_handle(int fd, struct cmd_packet *packet) {
|
||||
|
||||
struct cmd_proc_maps_packet *mp = (struct cmd_proc_maps_packet *)packet->data;
|
||||
@@ -966,6 +1068,7 @@ int proc_handle(int fd, struct cmd_packet *packet, unsigned char client_idx) {
|
||||
case 0xBDAA0023u: return proc_read_stack_handle(fd, packet);
|
||||
case 0xBDAA0024u: return proc_assemble_handle(fd, packet);
|
||||
case 0xBDAA0003u: return proc_write_handle(fd, packet);
|
||||
case 0xBDAACC04u: return proc_write_multi_handle(fd, packet);
|
||||
case 0xBDAA0004u: return proc_maps_handle(fd, packet);
|
||||
case 0xBDAA0005u: return proc_install_handle(fd, packet);
|
||||
case 0xBDAA0006u: return proc_call_handle(fd, packet);
|
||||
|
||||
Reference in new issue
Block a user