Files
ps5debug-NG/debugger/source/meta.c
T
Pharaoh2k 5fbdd894ee Add TURBOSCAN scan command family + aliasing read engine (v1.3.0)
Additive, capability-gated turbo memory-scan path (CC10-CC16); the legacy and
async scan paths stay byte-for-byte unchanged.

- SIMD typed comparator (scan_compare_simd.c) + CC10 caps + CC11 first scan.
- CC12 local-cluster rescan; server-resident survivor sets (CC13 GET / CC14
  END); unknown-value bitmap + NVMe snapshot with since-last narrowing and a
  materialize-when-sparse handoff to a compact record list.
- Aliasing read engine (scan_alias.c): maps target physical pages into our pmap
  via guarded not-present leaf-PTE writes, scanning in place at DRAM bandwidth.
  Unified per-2MB-span derivation (proc_ptwalk_span_resolve) makes it page-size
  agnostic; verify-before-trust + restore + verify-before-munmap reclaim keep it
  safe-to-fail. Opt-in (TSE_ALIASING + TS_USE_ALIASING, default off); mdbg is the
  floor. Verifies 1-in-16 maps (derivation is byte-proven, guards prevent faults
  regardless) - ~30% faster than verify-every-map.
- Opt-in server-side parallel compare for the aliased exact-match streaming scan
  (TSE_PARALLEL_COMPARE + TS_PARALLEL_COMPARE, default off) - for single-
  connection clients; multi-connection clients fan out across connections instead.
- Region-parallel multi-pattern AOB scan (CMD_PROC_SCAN_AOB_MULTI, aob_scan.h):
  splits the range into per-worker sub-ranges, each scanned once for all patterns
  via a shared first-byte dispatch table. Wire and results unchanged.
- Region-classify query (0xBDAACC16): per-region cache attribute (uncached PCD
  bit) + measured read throughput, so a client can opt out of slow/uncached
  regions. Read-only; the server drops nothing.

HW-validated on FW 9.00.
2026-06-20 00:48:15 +07:00

158 lines
5.0 KiB
C

// SPDX-License-Identifier: GPL-3.0-only
#include "protocol.h"
#include "sdk_shim.h"
#include "net.h"
#include "proc.h"
#include "debug_state.h"
#include "version.h"
extern int kern_handle(int fd, struct cmd_packet *packet);
extern int console_handle(int fd, struct cmd_packet *packet);
__attribute__((weak)) int debug_handle(int fd, struct cmd_packet *packet);
__attribute__((weak)) int dispatch_debug_events(void) { return 0; }
__attribute__((weak)) void debug_full_teardown(void *dbgctx) { (void)dbgctx; }
int handle_version(int fd, struct cmd_packet *packet) {
(void)packet;
char ver[] = "1.3";
uint32_t len = (uint32_t)(sizeof(ver) - 1);
net_send_all(fd, &len, sizeof(uint32_t));
net_send_all(fd, ver, (int)len);
return 0;
}
int handle_branding(int fd, struct cmd_packet *packet) {
(void)packet;
/* 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;
}
int handle_platform_id(int fd, struct cmd_packet *packet) {
(void)packet;
uint16_t v = 5;
net_send_all(fd, &v, 2);
return 0;
}
int handle_fw_version(int fd, struct cmd_packet *packet) {
(void)packet;
uint32_t fw = kernel_get_fw_version();
uint16_t fw_high = (uint16_t)(fw >> 16);
uint16_t fw_dec = (uint16_t)(((fw_high >> 12) & 0xF) * 1000
+ ((fw_high >> 8) & 0xF) * 100
+ ((fw_high >> 4) & 0xF) * 10
+ (fw_high & 0xF));
net_send_all(fd, &fw_dec, 2);
return 0;
}
int cmd_handler(int fd, struct cmd_packet *packet, unsigned char client_idx) {
uint32_t cmd = packet->cmd;
if (!VALID_CMD(cmd)) return 1;
switch (cmd) {
case CMD_VERSION: return handle_version(fd, packet);
case CMD_FW_VERSION: return handle_fw_version(fd, packet);
case CMD_BRANDING: return handle_branding(fd, packet);
case CMD_PLATFORM_ID: return handle_platform_id(fd, packet);
case CMD_PROC_NOP: net_send_int32(fd, CMD_SUCCESS); return 0;
}
if (VALID_PROC_CMD(cmd)) return proc_handle(fd, packet, client_idx);
if (VALID_DEBUG_CMD(cmd) && debug_handle) return debug_handle(fd, packet);
if (VALID_KERN_CMD(cmd)) return kern_handle(fd, packet);
if (VALID_CONSOLE_CMD(cmd)) return console_handle(fd, packet);
return 0;
}
#define SERVER_PORT 744
#define SERVER_MAXCLIENTS 12
#define SERVER_CLIENT_STRIDE 0x378
struct server_client {
uint32_t active;
int fd;
uint32_t debugging;
uint8_t client_addr[16];
uint8_t pad_1c[4];
uint8_t dbgctx[0x358];
};
struct server_client g_clients[SERVER_MAXCLIENTS];
void *curdbgcli = NULL;
void *curdbgctx = NULL;
uint32_t g_debug_attached = 0;
void *g_server_mutex = NULL;
void *g_proc_rw_mutex = NULL;
void *kr_fast_mutex = NULL;
uint32_t g_stopgo_mode = 0;
uint32_t g_stopgo_target_pid = 0;
uint32_t g_stopgo_last_signal = 0xFFFFFFFFu;
uint32_t g_stopgo_resume_pid = 0;
uint32_t g_stopgo_resume_signal = 0xFFFFFFFFu;
void server_state_init(void) {
if (g_proc_rw_mutex == NULL) {
scePthreadMutexInit(&g_proc_rw_mutex, NULL, "ps5d_procrw");
}
if (g_server_mutex == NULL) {
scePthreadMutexInit(&g_server_mutex, NULL, "ps5d_server");
}
if (kr_fast_mutex == NULL) {
scePthreadMutexInit(&kr_fast_mutex, NULL, "ps5d_krfast");
}
memset(g_clients, 0, sizeof(g_clients));
g_debug_attached = 0;
g_stopgo_resume_signal = 0xFFFFFFFFu;
g_stopgo_resume_pid = 0;
g_stopgo_last_signal = 0xFFFFFFFFu;
g_stopgo_target_pid = 0;
g_stopgo_mode = 0;
curdbgcli = NULL;
curdbgctx = NULL;
}
void *alloc_client(void) {
for (int idx = 0; idx < SERVER_MAXCLIENTS; idx++) {
if (g_clients[idx].active == 0) {
g_clients[idx].active = (uint32_t)(idx + 1);
return &g_clients[idx];
}
}
return NULL;
}
void free_client(void *svc_) {
struct server_client *svc = (struct server_client *)svc_;
// free any server-resident turbo-scan session + persistent aliasing arena for this
// connection (leak/UAF guard)
long slot = svc - g_clients;
if (slot >= 0 && slot < SERVER_MAXCLIENTS) {
turboscan_session_free_idx((unsigned char)slot);
turboscan_alias_free_idx((unsigned char)slot);
}
svc->active = 0;
close(svc->fd);
if (svc->debugging != 0) {
debug_full_teardown(svc->dbgctx);
}
memset(svc, 0, SERVER_CLIENT_STRIDE);
}