SceError
Jump to navigation
Jump to search
Module
Version | World | Privilege |
---|---|---|
1.69-3.60 | Non-secure | Kernel |
Libraries
Known NIDs
Version | Name | World | Visibility | NID |
---|---|---|---|---|
1.69 | SceErrorForDriver | Non-secure | Kernel | 0xBA576248 |
1.69-3.60 | SceError | Non-secure | User | 0x5CD2CAD1 |
Types
typedef struct SceErrorDefaultFormat { int data1; int data2; } SceErrorDefaultFormat; typedef struct SceErrorStrings { char s[0x10]; } SceErrorStrings; typedef struct SceErrorHistoryPostInfo { // size is 0x180 char error_message[0x100]; char data_0x100[0x40]; // unknown int error_code_hex; int data_0x174; SceUInt version; // from SceKernelFwInfo int data_0x17C; char titleid[0xC]; int data_0x15C; // from SceKernelFwInfo->unk_24 char data_0x160[0x20]; } SceErrorHistoryPostInfo; typedef struct SceErrorHistoryInfo { int data_0x00; int data_0x04; SceInt64 time; SceErrorStrings error_code; char data_0x20[0x10]; SceErrorHistoryPostInfo post; } SceErrorHistoryInfo; typedef struct SceErrorSequenceInfo { // size is 0x20 int data[8]; } SceErrorSequenceInfo;
SceErrorForDriver
SceError
_sceErrorHistoryUpdateSequenceInfo
Version | NID |
---|---|
1.69-3.60 | 0x6FBE4BDC |
int _sceErrorHistoryUpdateSequenceInfo(const SceErrorSequenceInfo *info, int a2);
_sceErrorHistoryPostError
Version | NID |
---|---|
1.69-3.60 | 0x70F9D872 |
int _sceErrorHistoryPostError(const SceErrorHistoryPostInfo *info);
_sceErrorGetExternalString
Version | NID |
---|---|
1.69-3.60 | 0x85747003 |
int _sceErrorGetExternalString(SceErrorStrings *error_strings, int error_code);
_sceErrorHistorySetDefaultFormat
Version | NID |
---|---|
1.69-3.60 | 0xB94DAA2F |
int _sceErrorHistorySetDefaultFormat(const SceErrorDefaultFormat *a1);
_sceErrorHistoryClearError
Version | NID |
---|---|
1.69-3.60 | 0xC88F479E |
// argument can be only 0, or SCE_ERROR_ERRNO_EINVAL error will be returned int _sceErrorHistoryClearError(int ch);
_sceErrorHistoryGetError
Version | NID |
---|---|
1.69-3.60 | 0xF16DF981 |
int _sceErrorHistoryGetError(SceUInt32 error_idx, SceErrorHistoryInfo *info);
Error table translation
In various places PSVita may display errors translated into their string representation. The code below also does this, provided you feed it with a copy of os0:kd/error_table.bin
.
#include <stdlib.h> #include <stdio.h> #ifdef _MSC_VER #define snprintf _snprintf #endif int read_error_table(const char *path, void *buf) { unsigned int v6; // r1@6 unsigned int v7; // r1@10 FILE *f = fopen(path, "rb"); if ( f ) { if ( fread(buf, 1, 8, f) == 8 ) { v6 = *((short *)buf + 2); if ( v6 <= 0x20 ) { if ( fread(*((int *)buf + 2), 1, 8 * v6, f) == 8 * v6 && fread((char *)buf + 12, 1, 4, f) == 4 ) { v7 = *((short *)buf + 7); if ( v7 <= 0x36B0 ) { if ( fread(*((int *)buf + 4), 1, 4 * v7, f) == 4 * v7 ) { fclose(f); return 0; } } else fprintf(stderr, "[SceError] error_table_num = %d\n", v7); } } else fprintf(stderr, "[SceError] facility_group_num = %d\n", v6); } fclose(f); } *(int *)buf = 0; *((int *)buf + 1) = 0; *((int *)buf + 2) = 0; *((int *)buf + 3) = 0; *((int *)buf + 4) = 0; *((int *)buf + 5) = 0; return 0; } #define _WORD short #define _DWORD int #define _BYTE char int error_code_to_string(int error_table, char *output, unsigned int error_code) { signed int v4; // r7@2 int v5; // r4@2 int v6; // r2@4 int v7; // r5@4 int v8; // t1@6 int v9; // t1@9 int v10; // t1@10 int v11; // r5@11 int v12; // r12@11 int v13; // r6@11 int v14; // r5@12 int v15; // t1@12 int v16; // r5@13 int v17; // t1@13 signed int v18; // lr@17 unsigned int v19; // r3@17 int v20; // r4@17 int v21; // r6@18 int v22; // r5@18 signed int v23; // r6@19 signed int v24; // r5@23 signed int v25; // r5@25 signed int v26; // r7@28 int v27; // r5@28 signed int v28; // r7@30 signed int v29; // r7@32 signed int v30; // r5@35 int v31; // r6@37 int v32; // r3@38 int v33; // r4@39 int v34; // r5@40 signed int v35; // r2@41 signed int v36; // r6@41 int v37; // r7@42 if (!output) return 0; v4 = *(_WORD *)(error_table + 14); v5 = *(_DWORD *)(error_table + 16); if (!*(_WORD *)(error_table + 14)) goto LABEL_46; if (*(_DWORD *)v5 == error_code) { v6 = 0; goto LABEL_17; } v6 = 0; v7 = ((_BYTE)v4 - 1) & 3; if (!(((_BYTE)v4 - 1) & 3)) goto LABEL_11; v6 = 1; if (v4 <= 1) { LABEL_46: snprintf(output, 16, "E-%08x", error_code); return 0; } v8 = *(_DWORD *)(v5 + 4); v5 += 4; if (v8 != error_code) { if (v7 == 1 || (v7 == 2 || (v9 = *(_DWORD *)(v5 + 4), v5 += 4, v6 = 2, v9 != error_code)) && (v10 = *(_DWORD *)(v5 + 4), v5 += 4, ++v6, v10 != error_code)) { LABEL_11: while (1) { ++v6; v11 = v5; v12 = v5 + 12; v13 = v6; v5 += 16; if (v6 >= v4) goto LABEL_46; v15 = *(_DWORD *)(v11 + 4); v14 = v11 + 4; if (v15 != error_code) { v17 = *(_DWORD *)(v14 + 4); v16 = v14 + 4; ++v6; if (v17 != error_code) { v6 = v13 + 2; if (*(_DWORD *)(v16 + 4) != error_code) { v6 = v13 + 3; if (*(_DWORD *)(v12 + 4) != error_code) continue; } } } break; } } } if (*(_WORD *)(error_table + 6) < v6) { snprintf(output, 16, "*-%08x", error_code); return 0; } LABEL_17: v18 = *(_WORD *)(error_table + 4); v19 = (error_code >> 16) & 0xFFF; v20 = *(_DWORD *)(error_table + 8); if (*(_WORD *)(error_table + 4)) { v21 = 0; v22 = ((_BYTE)v18 - 1) & 3; if (!(((_BYTE)v18 - 1) & 3)) { LABEL_35: while (1) { v30 = *(_WORD *)v20; if ((signed int)v19 >= v30 && (signed int)v19 < *(_WORD *)(v20 + 2) + v30) goto LABEL_48; v31 = v21 + 1; if (v31 >= v18) goto LABEL_38; v20 += 8; v26 = *(_WORD *)v20; v27 = v20; if ((signed int)v19 >= v26 && (signed int)v19 < v26 + *(_WORD *)(v20 + 2)) goto LABEL_48; v28 = *(_WORD *)(v20 + 8); v20 += 8; if ((signed int)v19 >= v28 && (signed int)v19 < v28 + *(_WORD *)(v27 + 10)) goto LABEL_48; v29 = *(_WORD *)(v27 + 16); v20 = v27 + 16; if ((signed int)v19 >= v29 && (signed int)v19 < v29 + *(_WORD *)(v27 + 18)) goto LABEL_48; v21 = v31 + 3; v20 = v27 + 24; } } v23 = *(_WORD *)v20; if ((signed int)v19 >= v23 && (signed int)v19 < *(_WORD *)(v20 + 2) + v23) { LABEL_48: v32 = v20 + 4; goto LABEL_39; } v21 = 1; if (v18 > 1) { v20 += 8; if (v22 == 1) goto LABEL_35; if (v22 != 2) { v24 = *(_WORD *)v20; if ((signed int)v19 >= v24 && (signed int)v19 < *(_WORD *)(v20 + 2) + v24) { v32 = v20 + 4; goto LABEL_39; } v21 = 2; v20 += 8; } v25 = *(_WORD *)v20; if ((signed int)v19 < v25 || (signed int)v19 >= *(_WORD *)(v20 + 2) + v25) { ++v21; v20 += 8; goto LABEL_35; } goto LABEL_48; } } LABEL_38: v32 = error_table; LABEL_39: v33 = v6 + *(_WORD *)(error_table + 12); if (v33) { v35 = v6 + *(_WORD *)(error_table + 12); v36 = 0; do { v37 = v35 % 10; v35 /= 10; v36 += v37; } while (v35); v34 = v36 % 10; } else v34 = 0; snprintf(output, 16, "%s-%d-%1d", v32, v33, v34); return 0; } int main(int argc, char *argv[]) { if (argc != 3) { fprintf(stderr, "Usage: ./error error_table.bin 0xC0DE"); return 1; } int *error_table = calloc(1, 1024 * 1024); error_table[2] = calloc(1, 1024 * 1024); error_table[4] = calloc(1, 1024 * 1024); read_error_table(argv[1], error_table); char *str = calloc(1, 500); error_code_to_string(error_table, str, strtoul(argv[2], NULL, 0)); printf("%s\n", str); free(str); free(error_table[2]); free(error_table[4]); free(error_table); return 0; }