SceError

From Vita Development Wiki
Jump to navigation Jump to search

Module

Known NIDs

Version Name World Privilege NID
1.69 SceError Non-secure Kernel 0x802086B7

Libraries

Known NIDs

Version Name World Visibility NID
1.69 SceErrorForDriver Non-secure Kernel 0xBA576248
1.69 SceError Non-secure User 0x5CD2CAD1

SceErrorForDriver

SceError

_sceErrorHistoryUpdateSequenceInfo

Version NID
1.69 0x6FBE4BDC
3.60 0x6FBE4BDC

_sceErrorHistoryPostError

Version NID
1.69 0x70F9D872
3.60 0x70F9D872

_sceErrorGetExternalString

Version NID
1.69 0x85747003
3.60 0x85747003

//dest is of size 0x10

int _sceErrorGetExternalString(char* dest, int unk)

_sceErrorHistorySetDefaultFormat

Version NID
1.69 0xB94DAA2F
3.60 0xB94DAA2F

_sceErrorHistoryClearError

Version NID
1.69 0xC88F479E
3.60 0xC88F479E

//argument can be only 0, or SCE_ERROR_ERRNO_EINVAL error will be returned

int _sceErrorHistoryClearError(int zero)

_sceErrorHistoryGetError

Version NID
1.69 0xF16DF981
3.60 0xF16DF981

Error translation

In various places Vita 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;
}