Difference between revisions of "SceError"

From Vita Development Wiki
Jump to navigation Jump to search
 
(22 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
== Module ==
 
== Module ==
  
=== Known NIDs ===
 
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Version !! Name !! World !! Privilege !! NID
+
! Version !! World !! Privilege
 
|-
 
|-
| 1.69 || SceError || Non-secure || Kernel || 0x802086B7
+
| 1.69-3.60 || Non-secure || Kernel
 
|}
 
|}
  
Line 19: Line 18:
 
| 1.69 || [[SceError#SceErrorForDriver|SceErrorForDriver]] || Non-secure || Kernel || 0xBA576248
 
| 1.69 || [[SceError#SceErrorForDriver|SceErrorForDriver]] || Non-secure || Kernel || 0xBA576248
 
|-
 
|-
| 1.69 || [[SceError#SceError|SceError]] || Non-secure || User || 0x5CD2CAD1
+
| 1.69-3.60 || [[SceError#SceError|SceError]] || Non-secure || User || 0x5CD2CAD1
 
|}
 
|}
  
== SceErrorForDriver ==
+
= Types =
 +
<source lang="C">
 +
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;
 +
</source>
 +
 
 +
= SceErrorForDriver =
  
== SceError ==
+
= SceError =
  
 
=== _sceErrorHistoryUpdateSequenceInfo ===
 
=== _sceErrorHistoryUpdateSequenceInfo ===
Line 31: Line 67:
 
! Version !! NID
 
! Version !! NID
 
|-
 
|-
| 1.69 || 0x6FBE4BDC
+
| 1.69-3.60 || 0x6FBE4BDC
|-
 
| 3.60 || 0x6FBE4BDC
 
 
|}
 
|}
  
<source lang="c">
+
<source lang="c">int _sceErrorHistoryUpdateSequenceInfo(const SceErrorSequenceInfo *info, int a2);</source>
//src_user is of size 0x20
 
int _sceErrorHistoryUpdateSequenceInfo(char* src_user, int unk1)
 
</source>
 
  
 
=== _sceErrorHistoryPostError ===
 
=== _sceErrorHistoryPostError ===
Line 46: Line 77:
 
! Version !! NID
 
! Version !! NID
 
|-
 
|-
| 1.69 || 0x70F9D872
+
| 1.69-3.60 || 0x70F9D872
|-
 
| 3.60 || 0x70F9D872
 
 
|}
 
|}
  
<source lang="c">
+
<source lang="c">int _sceErrorHistoryPostError(const SceErrorHistoryPostInfo *info);</source>
//src_user is of size 0x180
 
int _sceErrorHistoryPostError(char* src_user)
 
</source>
 
  
 
=== _sceErrorGetExternalString ===
 
=== _sceErrorGetExternalString ===
Line 61: Line 87:
 
! Version !! NID
 
! Version !! NID
 
|-
 
|-
| 1.69 || 0x85747003
+
| 1.69-3.60 || 0x85747003
|-
 
| 3.60 || 0x85747003
 
 
|}
 
|}
  
<source lang="C">
+
<source lang="C">int _sceErrorGetExternalString(SceErrorStrings *error_strings, int error_code);</source>
//dest is of size 0x10
 
int _sceErrorGetExternalString(char* dest_user, int unk)
 
</source>
 
  
 
=== _sceErrorHistorySetDefaultFormat ===
 
=== _sceErrorHistorySetDefaultFormat ===
Line 76: Line 97:
 
! Version !! NID
 
! Version !! NID
 
|-
 
|-
| 1.69 || 0xB94DAA2F
+
| 1.69-3.60 || 0xB94DAA2F
|-
 
| 3.60 || 0xB94DAA2F
 
 
|}
 
|}
  
<source lang="c">
+
<source lang="c">int _sceErrorHistorySetDefaultFormat(const SceErrorDefaultFormat *a1);</source>
//src_user is of size 0x08
 
int _sceErrorHistorySetDefaultFormat(char* src_user)
 
</source>
 
  
 
=== _sceErrorHistoryClearError ===
 
=== _sceErrorHistoryClearError ===
Line 91: Line 107:
 
! Version !! NID
 
! Version !! NID
 
|-
 
|-
| 1.69 || 0xC88F479E
+
| 1.69-3.60 || 0xC88F479E
|-
 
| 3.60 || 0xC88F479E
 
 
|}
 
|}
  
 
<source lang="c">
 
<source lang="c">
//argument can be only 0, or SCE_ERROR_ERRNO_EINVAL error will be returned
+
// argument can be only 0, or SCE_ERROR_ERRNO_EINVAL error will be returned
int _sceErrorHistoryClearError(int zero)
+
int _sceErrorHistoryClearError(int ch);
 
</source>
 
</source>
  
Line 106: Line 120:
 
! Version !! NID
 
! Version !! NID
 
|-
 
|-
| 1.69 || 0xF16DF981
+
| 1.69-3.60 || 0xF16DF981
|-
 
| 3.60 || 0xF16DF981
 
 
|}
 
|}
  
<source lang="c">
+
<source lang="c">int _sceErrorHistoryGetError(SceUInt32 error_idx, SceErrorHistoryInfo *info);</source>
//dest_user is of size 0x1B0
+
 
int _sceErrorHistoryGetError (int unk0, char *dest_user)
+
= Error table translation =
</source>
+
 
 +
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 <code>os0:kd/error_table.bin</code>.
  
== 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 <code>os0:kd/error_table.bin</code>.
 
 
<source lang="c">
 
<source lang="c">
 
#include <stdlib.h>
 
#include <stdlib.h>
Line 126: Line 137:
 
#endif
 
#endif
  
int read_error_table(const char *path, void *buf)
+
int read_error_table(const char *path, void *buf) {
{
 
 
   unsigned int v6; // r1@6
 
   unsigned int v6; // r1@6
 
   unsigned int v7; // r1@10
 
   unsigned int v7; // r1@10
  
 
   FILE *f = fopen(path, "rb");
 
   FILE *f = fopen(path, "rb");
   if ( f )
+
   if ( f ) {
  {
+
     if ( fread(buf, 1, 8, f) == 8 ) {
     if ( fread(buf, 1, 8, f) == 8 )
 
    {
 
 
       v6 = *((short *)buf + 2);
 
       v6 = *((short *)buf + 2);
 
       if ( v6 <= 0x20 )
 
       if ( v6 <= 0x20 )
 
       {
 
       {
 
         if ( fread(*((int *)buf + 2), 1, 8 * v6, f) == 8 * v6
 
         if ( fread(*((int *)buf + 2), 1, 8 * v6, f) == 8 * v6
           && fread((char *)buf + 12, 1, 4, f) == 4 )
+
           && fread((char *)buf + 12, 1, 4, f) == 4 ) {
        {
 
 
           v7 = *((short *)buf + 7);
 
           v7 = *((short *)buf + 7);
           if ( v7 <= 0x36B0 )
+
           if ( v7 <= 0x36B0 ) {
          {
+
             if ( fread(*((int *)buf + 4), 1, 4 * v7, f) == 4 * v7 ) {
             if ( fread(*((int *)buf + 4), 1, 4 * v7, f) == 4 * v7 )
 
            {
 
 
               fclose(f);
 
               fclose(f);
 
               return 0;
 
               return 0;
Line 152: Line 157:
 
           }
 
           }
 
           else
 
           else
          {
 
 
             fprintf(stderr, "[SceError] error_table_num = %d\n", v7);
 
             fprintf(stderr, "[SceError] error_table_num = %d\n", v7);
          }
 
 
         }
 
         }
 
       }
 
       }
 
       else
 
       else
      {
 
 
         fprintf(stderr, "[SceError] facility_group_num = %d\n", v6);
 
         fprintf(stderr, "[SceError] facility_group_num = %d\n", v6);
      }
 
 
     }
 
     }
 
     fclose(f);
 
     fclose(f);
Line 177: Line 178:
 
#define _BYTE char
 
#define _BYTE char
  
int error_code_to_string(int error_table, char *output, unsigned int error_code)
+
int error_code_to_string(int error_table, char *output, unsigned int error_code) {
{
 
 
     signed int v4; // r7@2
 
     signed int v4; // r7@2
 
     int v5; // r4@2
 
     int v5; // r4@2
Line 220: Line 220:
 
     if (!*(_WORD *)(error_table + 14))
 
     if (!*(_WORD *)(error_table + 14))
 
         goto LABEL_46;
 
         goto LABEL_46;
     if (*(_DWORD *)v5 == error_code)
+
     if (*(_DWORD *)v5 == error_code) {
    {
 
 
         v6 = 0;
 
         v6 = 0;
 
         goto LABEL_17;
 
         goto LABEL_17;
Line 230: Line 229:
 
         goto LABEL_11;
 
         goto LABEL_11;
 
     v6 = 1;
 
     v6 = 1;
     if (v4 <= 1)
+
     if (v4 <= 1) {
    {
 
 
     LABEL_46:
 
     LABEL_46:
 
         snprintf(output, 16, "E-%08x", error_code);
 
         snprintf(output, 16, "E-%08x", error_code);
Line 238: Line 236:
 
     v8 = *(_DWORD *)(v5 + 4);
 
     v8 = *(_DWORD *)(v5 + 4);
 
     v5 += 4;
 
     v5 += 4;
     if (v8 != error_code)
+
     if (v8 != error_code) {
    {
 
 
         if (v7 == 1
 
         if (v7 == 1
 
             || (v7 == 2 || (v9 = *(_DWORD *)(v5 + 4), v5 += 4, v6 = 2, v9 != error_code))
 
             || (v7 == 2 || (v9 = *(_DWORD *)(v5 + 4), v5 += 4, v6 = 2, v9 != error_code))
             && (v10 = *(_DWORD *)(v5 + 4), v5 += 4, ++v6, v10 != error_code))
+
             && (v10 = *(_DWORD *)(v5 + 4), v5 += 4, ++v6, v10 != error_code)) {
        {
 
 
         LABEL_11:
 
         LABEL_11:
             while (1)
+
             while (1) {
            {
 
 
                 ++v6;
 
                 ++v6;
 
                 v11 = v5;
 
                 v11 = v5;
Line 256: Line 251:
 
                 v15 = *(_DWORD *)(v11 + 4);
 
                 v15 = *(_DWORD *)(v11 + 4);
 
                 v14 = v11 + 4;
 
                 v14 = v11 + 4;
                 if (v15 != error_code)
+
                 if (v15 != error_code) {
                {
 
 
                     v17 = *(_DWORD *)(v14 + 4);
 
                     v17 = *(_DWORD *)(v14 + 4);
 
                     v16 = v14 + 4;
 
                     v16 = v14 + 4;
 
                     ++v6;
 
                     ++v6;
                     if (v17 != error_code)
+
                     if (v17 != error_code) {
                    {
 
 
                         v6 = v13 + 2;
 
                         v6 = v13 + 2;
                         if (*(_DWORD *)(v16 + 4) != error_code)
+
                         if (*(_DWORD *)(v16 + 4) != error_code) {
                        {
 
 
                             v6 = v13 + 3;
 
                             v6 = v13 + 3;
 
                             if (*(_DWORD *)(v12 + 4) != error_code)
 
                             if (*(_DWORD *)(v12 + 4) != error_code)
Line 276: Line 268:
 
         }
 
         }
 
     }
 
     }
     if (*(_WORD *)(error_table + 6) < v6)
+
     if (*(_WORD *)(error_table + 6) < v6) {
    {
 
 
         snprintf(output, 16, "*-%08x", error_code);
 
         snprintf(output, 16, "*-%08x", error_code);
 
         return 0;
 
         return 0;
Line 285: Line 276:
 
     v19 = (error_code >> 16) & 0xFFF;
 
     v19 = (error_code >> 16) & 0xFFF;
 
     v20 = *(_DWORD *)(error_table + 8);
 
     v20 = *(_DWORD *)(error_table + 8);
     if (*(_WORD *)(error_table + 4))
+
     if (*(_WORD *)(error_table + 4)) {
    {
 
 
         v21 = 0;
 
         v21 = 0;
 
         v22 = ((_BYTE)v18 - 1) & 3;
 
         v22 = ((_BYTE)v18 - 1) & 3;
         if (!(((_BYTE)v18 - 1) & 3))
+
         if (!(((_BYTE)v18 - 1) & 3)) {
        {
 
 
         LABEL_35:
 
         LABEL_35:
             while (1)
+
             while (1) {
            {
 
 
                 v30 = *(_WORD *)v20;
 
                 v30 = *(_WORD *)v20;
 
                 if ((signed int)v19 >= v30 && (signed int)v19 < *(_WORD *)(v20 + 2) + v30)
 
                 if ((signed int)v19 >= v30 && (signed int)v19 < *(_WORD *)(v20 + 2) + v30)
Line 318: Line 306:
 
         }
 
         }
 
         v23 = *(_WORD *)v20;
 
         v23 = *(_WORD *)v20;
         if ((signed int)v19 >= v23 && (signed int)v19 < *(_WORD *)(v20 + 2) + v23)
+
         if ((signed int)v19 >= v23 && (signed int)v19 < *(_WORD *)(v20 + 2) + v23) {
        {
 
 
         LABEL_48:
 
         LABEL_48:
 
             v32 = v20 + 4;
 
             v32 = v20 + 4;
Line 325: Line 312:
 
         }
 
         }
 
         v21 = 1;
 
         v21 = 1;
         if (v18 > 1)
+
         if (v18 > 1) {
        {
 
 
             v20 += 8;
 
             v20 += 8;
 
             if (v22 == 1)
 
             if (v22 == 1)
 
                 goto LABEL_35;
 
                 goto LABEL_35;
             if (v22 != 2)
+
             if (v22 != 2) {
            {
 
 
                 v24 = *(_WORD *)v20;
 
                 v24 = *(_WORD *)v20;
                 if ((signed int)v19 >= v24 && (signed int)v19 < *(_WORD *)(v20 + 2) + v24)
+
                 if ((signed int)v19 >= v24 && (signed int)v19 < *(_WORD *)(v20 + 2) + v24) {
                {
 
 
                     v32 = v20 + 4;
 
                     v32 = v20 + 4;
 
                     goto LABEL_39;
 
                     goto LABEL_39;
Line 342: Line 326:
 
             }
 
             }
 
             v25 = *(_WORD *)v20;
 
             v25 = *(_WORD *)v20;
             if ((signed int)v19 < v25 || (signed int)v19 >= *(_WORD *)(v20 + 2) + v25)
+
             if ((signed int)v19 < v25 || (signed int)v19 >= *(_WORD *)(v20 + 2) + v25) {
            {
 
 
                 ++v21;
 
                 ++v21;
 
                 v20 += 8;
 
                 v20 += 8;
Line 355: Line 338:
 
LABEL_39:
 
LABEL_39:
 
     v33 = v6 + *(_WORD *)(error_table + 12);
 
     v33 = v6 + *(_WORD *)(error_table + 12);
     if (v33)
+
     if (v33) {
    {
 
 
         v35 = v6 + *(_WORD *)(error_table + 12);
 
         v35 = v6 + *(_WORD *)(error_table + 12);
 
         v36 = 0;
 
         v36 = 0;
         do
+
         do {
        {
 
 
             v37 = v35 % 10;
 
             v37 = v35 % 10;
 
             v35 /= 10;
 
             v35 /= 10;
Line 368: Line 349:
 
     }
 
     }
 
     else
 
     else
    {
 
 
         v34 = 0;
 
         v34 = 0;
    }
 
 
     snprintf(output, 16, "%s-%d-%1d", v32, v33, v34);
 
     snprintf(output, 16, "%s-%d-%1d", v32, v33, v34);
 
     return 0;
 
     return 0;
Line 398: Line 377:
 
</source>
 
</source>
  
 +
[[Category:ARM]]
 +
[[Category:Kernel]]
 
[[Category:Modules]]
 
[[Category:Modules]]
[[Category:Kernel]]
+
[[Category:Library]]

Latest revision as of 21:01, 1 May 2023

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;
}