decompiled_code:
__int64 xengnttab_list_v2()
{
__int64 result; // rax
__int16 *v1; // rbx
unsigned int v2; // ebp

result = interface;
if ( *(_DWORD *)(interface + 40) )
{
v1 = grant_table_pages;
v2 = 0;
do
{
if ( *v1 )
micropv_printk(
"src/xengnttab.c",
345LL,
"ref=%i, frame=%lii, dom=%i, flags=%i",
v2,
*((_QWORD *)v1 + 1),
(unsigned __int16)v1[1],
(unsigned __int16)*v1);
++v2;
v1 += 8;
result = interface;
}
while ( *(_DWORD *)(interface + 40) > v2 );
}
return result;
}

canonical_decompiled_code:
__int64 func5()
{
__int64 result; // rax
__int16 *v1; // rbx
unsigned int v2; // ebp

result = interface;
if ( *(_DWORD *)(interface + 40) )
{
v1 = grant_table_pages;
v2 = 0;
do
{
if ( *v1 )
micropv_printk(
"src/xengnttab.c",
345LL,
"ref=%i, frame=%lii, dom=%i, flags=%i",
v2,
*((_QWORD *)v1 + 1),
(unsigned __int16)v1[1],
(unsigned __int16)*v1);
++v2;
v1 += 8;
result = interface;
}
while ( *(_DWORD *)(interface + 40) > v2 );
}
return result;
}

original_code:
static void xengnttab_list_v2()
{
    grant_entry_v2_t *gnttab_table = (grant_entry_v2_t *) grant_table_pages;
    for (int ref = 0; ref < interface->nr_grant_entries; ref++)
        if (gnttab_table[ref].full_page.hdr.flags)
            micropv_printk("src/xengnttab.c", 345,"ref=%i, frame=%lii, dom=%i, flags=%i", ref, gnttab_table[ref].full_page.frame, gnttab_table[ref].full_page.hdr.domid, gnttab_table[ref].full_page.hdr.flags);
}

canonical_original_code:
static void xengnttab_list_v2()
{
    union grant_entry_v2 *gnttab_table = (grant_entry_v2_t *) grant_table_pages;
    for (int ref = 0; ref < interface->nr_grant_entries; ref++)
        if (gnttab_table[ref].full_page.hdr.flags)
            micropv_printk("src/xengnttab.c", 345,"ref=%i, frame=%lii, dom=%i, flags=%i", ref, gnttab_table[ref].full_page.frame, gnttab_table[ref].full_page.hdr.domid, gnttab_table[ref].full_page.hdr.flags);
}

variable_types: union grant_entry_v2 { struct grant_entry_header { unsigned short flags; unsigned short domid; } hdr; struct { struct grant_entry_header hdr; unsigned int pad0; unsigned long frame; } full_page; struct { struct grant_entry_header hdr; unsigned short page_off; unsigned short length; unsigned long frame; } sub_page; struct { struct grant_entry_header hdr; unsigned short trans_domid; unsigned short pad0; unsigned int gref; } transitive; unsigned int __spacer[4]; } *

variable_types: ref int

user_defined_types: union grant_entry_v2 { struct grant_entry_header hdr; struct { struct grant_entry_header hdr; unsigned int pad0; unsigned long frame; } full_page; struct { struct grant_entry_header hdr; unsigned short page_off; unsigned short length; unsigned long frame; } sub_page; struct { struct grant_entry_header hdr; unsigned short trans_domid; unsigned short pad0; unsigned int gref; } transitive; unsigned int __spacer[4]; }


repo: FurryFuttock/micro-pv

decompiled_code:
__int64 xengnttab_list_v1()
{
__int64 result; // rax
__int64 v1; // rbx
unsigned __int16 v2; // ax

result = interface;
if ( *(_DWORD *)(interface + 40) )
{
v1 = 0LL;
do
{
v2 = grant_table_pages[4 * v1];
if ( v2 )
micropv_printk(
"src/xengnttab.c",
337LL,
"ref=%i, frame=%i, dom=%i, flags=%i",
(unsigned int)v1,
(unsigned int)dword_4004[2 * v1],
(unsigned __int16)word_4002[4 * v1],
v2);
++v1;
result = interface;
}
while ( *(_DWORD *)(interface + 40) > (unsigned int)v1 );
}
return result;
}

canonical_decompiled_code:
__int64 func6()
{
__int64 result; // rax
__int64 v1; // rbx
unsigned __int16 v2; // ax

result = interface;
if ( *(_DWORD *)(interface + 40) )
{
v1 = 0LL;
do
{
v2 = grant_table_pages[4 * v1];
if ( v2 )
micropv_printk(
"src/xengnttab.c",
337LL,
"ref=%i, frame=%i, dom=%i, flags=%i",
(unsigned int)v1,
(unsigned int)dword_4004[2 * v1],
(unsigned __int16)word_4002[4 * v1],
v2);
++v1;
result = interface;
}
while ( *(_DWORD *)(interface + 40) > (unsigned int)v1 );
}
return result;
}

original_code:
static void xengnttab_list_v1()
{
    grant_entry_v1_t *gnttab_table = (grant_entry_v1_t *) grant_table_pages;
    for (int ref = 0; ref < interface->nr_grant_entries; ref++)
        if (gnttab_table[ref].flags)
            micropv_printk("src/xengnttab.c", 337,"ref=%i, frame=%i, dom=%i, flags=%i", ref, gnttab_table[ref].frame, gnttab_table[ref].domid, gnttab_table[ref].flags);
}

canonical_original_code:
static void xengnttab_list_v1()
{
    struct grant_entry_v1 *gnttab_table = (grant_entry_v1_t *) grant_table_pages;
    for (int ref = 0; ref < interface->nr_grant_entries; ref++)
        if (gnttab_table[ref].flags)
            micropv_printk("src/xengnttab.c", 337,"ref=%i, frame=%i, dom=%i, flags=%i", ref, gnttab_table[ref].frame, gnttab_table[ref].domid, gnttab_table[ref].flags);
}

variable_types: struct grant_entry_v1 { unsigned short flags; unsigned short domid; unsigned int frame; } *

return_type: void


decompiled_code:
__int64 __fastcall put_free_entry(int a1)
{
micropv_interrupt_disable();
gnttab_list[a1] = gnttab_list[0];
gnttab_list[0] = a1;
return micropv_interrupt_enable();
}

canonical_decompiled_code:
__int64 __fastcall func7(int a1)
{
micropv_interrupt_disable();
gnttab_list[a1] = gnttab_list[0];
gnttab_list[0] = a1;
return micropv_interrupt_enable();
}

original_code:
static void put_free_entry(grant_ref_t ref)
{
    micropv_interrupt_disable();
    gnttab_list[ref] = gnttab_list[0];
    gnttab_list[0] = ref;
    micropv_interrupt_enable();
}

canonical_original_code:
static void put_free_entry(unsigned int ref)
{
    micropv_interrupt_disable();
    gnttab_list[ref] = gnttab_list[0];
    gnttab_list[0] = ref;
    micropv_interrupt_enable();
}

variable_types:
ref
unsigned int


decompiled_code:
__int64 get_free_entry()
{
unsigned int v0; // ebx

micropv_interrupt_disable();
v0 = gnttab_list[0];
if ( gnttab_list[0] <= 7u || *(_DWORD *)(interface + 40) <= gnttab_list[0] )
{
micropv_printk(
"src/xengnttab.c",
177LL,
"ASSERTION FAILED: %s at %s:%d.",
"!((ref < 8) || (ref >= interface->nr_grant_entries))",
"src/xengnttab.c",
177LL);
micropv_exit();
}
gnttab_list[0] = gnttab_list[v0];
micropv_interrupt_enable();
return v0;
}

canonical_decompiled_code:
__int64 func8()
{
unsigned int v0; // ebx

micropv_interrupt_disable();
v0 = gnttab_list[0];
if ( gnttab_list[0] <= 7u || *(_DWORD *)(interface + 40) <= gnttab_list[0] )
{
micropv_printk(
"src/xengnttab.c",
177LL,
"ASSERTION FAILED: %s at %s:%d.",
"!((ref < 8) || (ref >= interface->nr_grant_entries))",
"src/xengnttab.c",
177LL);
micropv_exit();
}
gnttab_list[0] = gnttab_list[v0];
micropv_interrupt_enable();
return v0;
}

original_code:
static grant_ref_t get_free_entry(void)
{
    unsigned int ref;
    micropv_interrupt_disable();
    ref = gnttab_list[0];
    do { if (!(!((ref < 8) || (ref >= interface->nr_grant_entries)))) { micropv_printk("src/xengnttab.c", 177,"ASSERTION FAILED: %s at %s:%d.", "!((ref < 8) || (ref >= interface->nr_grant_entries))" , "src/xengnttab.c", 177); micropv_exit(); } } while(0);
    gnttab_list[0] = gnttab_list[ref];
    micropv_interrupt_enable();
    return ref;
}

canonical_original_code:
static unsigned int get_free_entry()
{
    unsigned int ref;
    micropv_interrupt_disable();
    ref = gnttab_list[0];
    do { if (!(!((ref < 8) || (ref >= interface->nr_grant_entries)))) { micropv_printk("src/xengnttab.c", 177,"ASSERTION FAILED: %s at %s:%d.", "!((ref < 8) || (ref >= interface->nr_grant_entries))" , "src/xengnttab.c", 177); micropv_exit(); } } while(0);
    gnttab_list[0] = gnttab_list[ref];
    micropv_interrupt_enable();
    return ref;
}

return_type: unsigned int


decompiled_code:
__int64 __fastcall micropv_shared_memory_consume(unsigned int *a1, __int64 a2, const void *a3)
{
unsigned int v4; // er12
unsigned int v6[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v6[0] = 0;
if ( (unsigned int)xenstore_read_integer(0LL, a2, v6) )
return (unsigned int)-1;
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
229LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
229LL);
micropv_exit();
}
v4 = (*(__int64 (__fastcall **)(unsigned int *, _QWORD, _QWORD, const void *, _QWORD))(interface + 16))(
a1,
0LL,
v6[0],
a3,
0LL);
micropv_printk(
"src/xengnttab.c",
231LL,
"grant_handle %i for physical_address=%p mapped to dom=0 with grant_ref=%i",
*a1,
a3,
v6[0]);
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func9(unsigned int *a1, __int64 a2, const void *a3)
{
unsigned int v4; // er12
unsigned int v6[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v6[0] = 0;
if ( (unsigned int)xenstore_read_integer(0LL, a2, v6) )
return (unsigned int)-1;
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
229LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
229LL);
micropv_exit();
}
v4 = (*(__int64 (__fastcall **)(unsigned int *, _QWORD, _QWORD, const void *, _QWORD))(interface + 16))(
a1,
0LL,
v6[0],
a3,
0LL);
micropv_printk(
"src/xengnttab.c",
231LL,
"grant_handle %i for physical_address=%p mapped to dom=0 with grant_ref=%i",
*a1,
a3,
v6[0]);
return v4;
}

original_code:
int micropv_shared_memory_consume(micropv_grant_handle_t *handle, const char *name, void *buffer)
{
    grant_ref_t ref = 0;
    if (xenstore_read_integer(((xenbus_transaction_t)0), name, (signed *)&ref))
        return -1;
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 229,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 229); micropv_exit(); } } while(0);
    int rc = interface->xengnttab_map(handle, 0, ref, buffer, 0);
    micropv_printk("src/xengnttab.c", 231,"grant_handle %i for physical_address=%p mapped to dom=0 with grant_ref=%i", handle->handle, buffer, ref);
    return rc;
}

canonical_original_code:
int micropv_shared_memory_consume(struct micropv_grant_handle_t *handle, char *name, void *buffer)
{
    unsigned int ref = 0;
    if (xenstore_read_integer(((unsigned int)0), name, (int *)&ref))
        return -1;
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 229,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 229); micropv_exit(); } } while(0);
    int rc = interface->xengnttab_map(handle, 0, ref, buffer, 0);
    micropv_printk("src/xengnttab.c", 231,"grant_handle %i for physical_address=%p mapped to dom=0 with grant_ref=%i", handle->handle, buffer, ref);
    return rc;
}

variable_types: struct micropv_grant_handle_t { unsigned int handle; unsigned long dev_bus_addr; } *

variable_types:
name
char *

variable_types:
buffer
void *

variable_types: rc int

return_type: int


decompiled_code:
__int64 __fastcall micropv_shared_memory_unconsume(unsigned int *a1, const void *a2)
{
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
237LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
237LL);
micropv_exit();
}
micropv_printk("src/xengnttab.c", 238LL, "Unmap handle=%i for physical_address=%p", *a1, a2);
return (*(__int64 (__fastcall **)(unsigned int *, const void *))(interface + 24))(a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func10(unsigned int *a1, const void *a2)
{
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
237LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
237LL);
micropv_exit();
}
micropv_printk("src/xengnttab.c", 238LL, "Unmap handle=%i for physical_address=%p", *a1, a2);
return (*(__int64 (__fastcall **)(unsigned int *, const void *))(interface + 24))(a1, a2);
}

original_code:
void micropv_shared_memory_unconsume(micropv_grant_handle_t *handle, void *buffer)
{
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 237,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 237); micropv_exit(); } } while(0);
    micropv_printk("src/xengnttab.c", 238,"Unmap handle=%i for physical_address=%p", handle->handle, buffer);
    interface->xengnttab_unmap(handle, buffer);
}

canonical_original_code:
void micropv_shared_memory_unconsume(struct micropv_grant_handle_t *handle, void *buffer)
{
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 237,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 237); micropv_exit(); } } while(0);
    micropv_printk("src/xengnttab.c", 238,"Unmap handle=%i for physical_address=%p", handle->handle, buffer);
    interface->xengnttab_unmap(handle, buffer);
}

user_defined_types: struct micropv_grant_handle_t { unsigned int handle; unsigned long dev_bus_addr; }


decompiled_code:
__int64 __fastcall xengnttab_unshare(unsigned int a1)
{
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
265LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
265LL);
micropv_exit();
}
micropv_printk("src/xengnttab.c", 266LL, "unmapping grant_ref=%i", a1);
(*(void (__fastcall **)(_QWORD))(interface + 8))(a1);
return put_free_entry(a1);
}

canonical_decompiled_code:
__int64 __fastcall func11(unsigned int a1)
{
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
265LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
265LL);
micropv_exit();
}
micropv_printk("src/xengnttab.c", 266LL, "unmapping grant_ref=%i", a1);
(*(void (__fastcall **)(_QWORD))(interface + 8))(a1);
return func7(a1);
}

original_code:
void xengnttab_unshare(grant_ref_t ref)
{
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 265,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 265); micropv_exit(); } } while(0);
    micropv_printk("src/xengnttab.c", 266,"unmapping grant_ref=%i", ref);
    interface->xengnttab_unshare(ref);
    put_free_entry(ref);
}

canonical_original_code:
void xengnttab_unshare(unsigned int ref)
{
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 265,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 265); micropv_exit(); } } while(0);
    micropv_printk("src/xengnttab.c", 266,"unmapping grant_ref=%i", ref);
    interface->xengnttab_unshare(ref);
    put_free_entry(ref);
}


decompiled_code:
__int64 __fastcall xengnttab_share(unsigned int a1, unsigned __int64 a2, unsigned int a3)
{
__int64 v4; // r14
unsigned int v5; // ebx

v4 = *(_QWORD *)(phys_to_machine_mapping + 8 * (a2 >> 12));
v5 = get_free_entry();
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
302LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
302LL);
micropv_exit();
}
(*(void (__fastcall **)(_QWORD, _QWORD, __int64, _QWORD))interface)(a1, v5, v4, a3);
micropv_printk(
"src/xengnttab.c",
304LL,
"physical_address=%p mapped to machine_address=%lx with grant_ref=%i",
(const void *)a2,
v4 << 12,
v5);
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func12(unsigned int a1, unsigned __int64 a2, unsigned int a3)
{
__int64 v4; // r14
unsigned int v5; // ebx

v4 = *(_QWORD *)(phys_to_machine_mapping + 8 * (a2 >> 12));
v5 = func8();
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
302LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
302LL);
micropv_exit();
}
(*(void (__fastcall **)(_QWORD, _QWORD, __int64, _QWORD))interface)(a1, v5, v4, a3);
micropv_printk(
"src/xengnttab.c",
304LL,
"physical_address=%p mapped to machine_address=%lx with grant_ref=%i",
(const void *)a2,
v4 << 12,
v5);
return v5;
}

original_code:
grant_ref_t xengnttab_share(int remote_dom, const void *buffer, int readonly)
{
    uint64_t mfn = ((phys_to_machine_mapping[((((((unsigned long)(buffer)-((unsigned long)0))) >> 12)))]));
    grant_ref_t ref = get_free_entry();
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 302,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 302); micropv_exit(); } } while(0);
    interface->xengnttab_share(remote_dom, ref, mfn, readonly);
    micropv_printk("src/xengnttab.c", 304,"physical_address=%p mapped to machine_address=%lx with grant_ref=%i", buffer, mfn << 12, ref);
    return ref;
}

canonical_original_code:
unsigned int xengnttab_share(int remote_dom, void *buffer, int readonly)
{
    unsigned long mfn = ((phys_to_machine_mapping[((((((unsigned long)(buffer)-((unsigned long)0))) >> 12)))]));
    unsigned int ref = get_free_entry();
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 302,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 302); micropv_exit(); } } while(0);
    interface->xengnttab_share(remote_dom, ref, mfn, readonly);
    micropv_printk("src/xengnttab.c", 304,"physical_address=%p mapped to machine_address=%lx with grant_ref=%i", buffer, mfn << 12, ref);
    return ref;
}

variable_types: readonly int

variable_types:
mfn
unsigned long


decompiled_code:
__int64 __fastcall micropv_shared_memory_publish(unsigned int a1, __int64 a2, unsigned __int64 a3, unsigned int a4)
{
unsigned int v4; // eax

v4 = xengnttab_share(a1, a3, a4);
return xenstore_write_integer(0LL, a2, v4);
}

canonical_decompiled_code:
__int64 __fastcall func13(unsigned int a1, __int64 a2, unsigned __int64 a3, unsigned int a4)
{
unsigned int v4; // eax

v4 = func12(a1, a3, a4);
return xenstore_write_integer(0LL, a2, v4);
}

original_code:
void micropv_shared_memory_publish(int remote_dom, const char *name, const void *buffer, int readonly)
{
    grant_ref_t ref = xengnttab_share(remote_dom, buffer,readonly);
    xenstore_write_integer(((xenbus_transaction_t)0), name, ref);
}

canonical_original_code:
void micropv_shared_memory_publish(int remote_dom, char *name, void *buffer, int readonly)
{
    unsigned int ref = xengnttab_share(remote_dom, buffer,readonly);
    xenstore_write_integer(((unsigned int)0), name, ref);
}


decompiled_code:
__int64 __fastcall micropv_shared_memory_unpublish(__int64 a1)
{
__int64 result; // rax
unsigned int v2[3]; // [rsp+Ch] [rbp-Ch] BYREF

result = xenstore_read_integer(0LL, a1, v2);
if ( !(_DWORD)result )
{
xenstore_rm(0LL, a1);
result = xengnttab_unshare(v2[0]);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1)
{
__int64 result; // rax
unsigned int v2[3]; // [rsp+Ch] [rbp-Ch] BYREF

result = xenstore_read_integer(0LL, a1, v2);
if ( !(_DWORD)result )
{
xenstore_rm(0LL, a1);
result = func11(v2[0]);
}
return result;
}

original_code:
void micropv_shared_memory_unpublish(const char *name)
{
    int ref;
    if (xenstore_read_integer(((xenbus_transaction_t)0), name, &ref))
        return;
    xenstore_rm(((xenbus_transaction_t)0), name);
    xengnttab_unshare(ref);
}

canonical_original_code:
void micropv_shared_memory_unpublish(char *name)
{
    int ref;
    if (xenstore_read_integer(((unsigned int)0), name, &ref))
        return;
    xenstore_rm(((unsigned int)0), name);
    xengnttab_unshare(ref);
}


decompiled_code:
__int64 micropv_shared_memory_list()
{
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
350LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
350LL);
micropv_exit();
}
return (*(__int64 (**)(void))(interface + 32))();
}

canonical_decompiled_code:
__int64 func15()
{
if ( !interface )
{
micropv_printk(
"src/xengnttab.c",
350LL,
"ASSERTION FAILED: %s at %s:%d.",
"!(interface == ((void *)0))",
"src/xengnttab.c",
350LL);
micropv_exit();
}
return (*(__int64 (**)(void))(interface + 32))();
}

original_code:
void micropv_shared_memory_list()
{
    do { if (!(!(interface == ((void *)0)))) { micropv_printk("src/xengnttab.c", 350,"ASSERTION FAILED: %s at %s:%d.", "!(interface == ((void *)0))" , "src/xengnttab.c", 350); micropv_exit(); } } while(0);
    interface->xengnttab_list();
}


decompiled_code:
void __fastcall synch_set_bit(unsigned int a1, volatile signed __int32 *a2)
{
_interlockedbittestandset(a2, a1);
}

canonical_decompiled_code:
void __fastcall func0(unsigned int a1, volatile signed __int32 *a2)
{
_interlockedbittestandset(a2, a1);
}

original_code:
static inline void synch_set_bit(int nr, volatile void * addr)
{
    __asm__ __volatile__ (
        "lock btsl %1,%0"
        : "=m" ((*(volatile long *) addr)) : "Ir" (nr) : "memory" );
}

canonical_original_code:
static inline void synch_set_bit(int nr, void *addr)
{
    __asm__ __volatile__ (
        "lock btsl %1,%0"
        : "=m" ((*(long *) addr)) : "Ir" (nr) : "memory" );
}

variable_types: nr int

variable_types:
addr
void *


decompiled_code:
void __fastcall synch_clear_bit(unsigned int a1, volatile signed __int32 *a2)
{
_interlockedbittestandreset(a2, a1);
}

canonical_decompiled_code:
void __fastcall func1(unsigned int a1, volatile signed __int32 *a2)
{
_interlockedbittestandreset(a2, a1);
}

original_code:
static inline void synch_clear_bit(int nr, volatile void * addr)
{
    __asm__ __volatile__ (
        "lock btrl %1,%0"
        : "=m" ((*(volatile long *) addr)) : "Ir" (nr) : "memory" );
}

canonical_original_code:
static inline void synch_clear_bit(int nr, void *addr)
{
    __asm__ __volatile__ (
        "lock btrl %1,%0"
        : "=m" ((*(long *) addr)) : "Ir" (nr) : "memory" );
}


decompiled_code:
__int64 __fastcall synch_var_test_bit(unsigned int a1, const signed __int32 *a2)
{
return (unsigned int)-_bittest(a2, a1);
}

canonical_decompiled_code:
__int64 __fastcall func3(unsigned int a1, const signed __int32 *a2)
{
return (unsigned int)-_bittest(a2, a1);
}

original_code:
static inline int synch_var_test_bit(int nr, volatile void * addr)
{
    int oldbit;
    __asm__ __volatile__ (
        "btl %2,%1\n\tsbbl %0,%0"
        : "=r" (oldbit) : "m" ((*(volatile long *) addr)), "Ir" (nr) );
    return oldbit;
}

canonical_original_code:
static inline int synch_var_test_bit(int nr, void *addr)
{
    int oldbit;
    __asm__ __volatile__ (
        "btl %2,%1\n\tsbbl %0,%0"
        : "=r" (oldbit) : "m" ((*(long *) addr)), "Ir" (nr) );
    return oldbit;
}

variable_types: oldbit int


decompiled_code:
__int64 __fastcall synch_test_and_set_bit(unsigned int a1, volatile signed __int32 *a2)
{
return (unsigned int)-(unsigned __int8)_interlockedbittestandset(a2, a1);
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned int a1, volatile signed __int32 *a2)
{
return (unsigned int)-(unsigned __int8)_interlockedbittestandset(a2, a1);
}

original_code:
static inline int synch_test_and_set_bit(int nr, volatile void * addr)
{
    int oldbit;
    __asm__ __volatile__ (
        "lock btsl %2,%1\n\tsbbl %0,%0"
        : "=r" (oldbit), "=m" ((*(volatile long *) addr)) : "Ir" (nr) : "memory");
    return oldbit;
}

canonical_original_code:
static inline int synch_test_and_set_bit(int nr, void *addr)
{
    int oldbit;
    __asm__ __volatile__ (
        "lock btsl %2,%1\n\tsbbl %0,%0"
        : "=r" (oldbit), "=m" ((*(long *) addr)) : "Ir" (nr) : "memory");
    return oldbit;
}


decompiled_code:
__int64 __fastcall HYPERVISOR_event_channel_op(int a1)
{
return MEMORY[0x70B8](a1);
}

canonical_decompiled_code:
__int64 __fastcall func8(int a1)
{
return MEMORY[0x70B8](a1);
}

original_code:
static inline int
HYPERVISOR_event_channel_op(
       int cmd, void *op)
{
    return ({ long __res, __ign1, __ign2; __asm volatile ( "call hypercall_page + (""32"" * 32)" : "=a" (__res), "=D" (__ign1), "=S" (__ign2) : "1" ((long)(cmd)), "2" ((long)(op)) : "memory" ); (int)__res; });
}

canonical_original_code:
static inline int HYPERVISOR_event_channel_op(int cmd, void *op)
{
    return ({ long __res; long __ign1; long __ign2; __asm volatile ( "call hypercall_page + (""32"" * 32)" : "=a" (__res), "=D" (__ign1), "=S" (__ign2) : "1" ((long)(cmd)), "2" ((long)(op)) : "memory" ); (int)__res; });
}

variable_types: cmd int

variable_types:
op
void *


decompiled_code:
void __fastcall clear_evtchn(unsigned int a1)
{
synch_clear_bit(a1, (volatile signed __int32 *)(hypervisor_shared_info + 2048LL));
}

canonical_decompiled_code:
void __fastcall func10(unsigned int a1)
{
func1(a1, (volatile signed __int32 *)(hypervisor_shared_info + 2048LL));
}

original_code:
static void clear_evtchn(uint32_t port)
{
    shared_info_t *s = hypervisor_shared_info;
    synch_clear_bit(port, &s->evtchn_pending[0]);
}

canonical_original_code:
static void clear_evtchn(unsigned int port)
{
    struct shared_info *s = hypervisor_shared_info;
    synch_clear_bit(port, &s->evtchn_pending[0]);
}

variable_types:
port
unsigned int

variable_types: struct shared_info { struct vcpu_info { unsigned char evtchn_upcall_pending; unsigned char evtchn_upcall_mask; unsigned long evtchn_pending_sel; struct arch_vcpu_info { unsigned long cr2; unsigned long pad; } arch; struct vcpu_time_info { unsigned int version; unsigned int pad0; unsigned long tsc_timestamp; unsigned long system_time; unsigned int tsc_to_system_mul; char tsc_shift; char pad1[3]; } time; } vcpu_info[32]; unsigned long evtchn_pending[-1]; unsigned long evtchn_mask[-1]; unsigned int wc_version; unsigned int wc_sec; unsigned int wc_nsec; unsigned int wc_sec_hi; struct arch_shared_info { unsigned long max_pfn; unsigned long pfn_to_mfn_frame_list_list; unsigned long nmi_reason; unsigned long p2m_cr3; unsigned long p2m_vaddr; unsigned long p2m_generation; } arch; } *

user_defined_types: struct shared_info { struct vcpu_info vcpu_info[32]; unsigned long evtchn_pending[-1]; unsigned long evtchn_mask[-1]; unsigned int wc_version; unsigned int wc_sec; unsigned int wc_nsec; unsigned int wc_sec_hi; struct arch_shared_info arch; }

user_defined_types: struct vcpu_info { unsigned char evtchn_upcall_pending; unsigned char evtchn_upcall_mask; unsigned long evtchn_pending_sel; struct arch_vcpu_info arch; struct vcpu_time_info time; }


decompiled_code:
void __fastcall mask_evtchn(unsigned int a1)
{
synch_set_bit(a1, (volatile signed __int32 *)(hypervisor_shared_info + 2560LL));
}

canonical_decompiled_code:
void __fastcall func11(unsigned int a1)
{
func0(a1, (volatile signed __int32 *)(hypervisor_shared_info + 2560LL));
}

original_code:
static void mask_evtchn(uint32_t port)
{
    shared_info_t *s = hypervisor_shared_info;
    synch_set_bit(port, &s->evtchn_mask[0]);
}

canonical_original_code:
static void mask_evtchn(unsigned int port)
{
    struct shared_info *s = hypervisor_shared_info;
    synch_set_bit(port, &s->evtchn_mask[0]);
}

user_defined_types: struct arch_shared_info { unsigned long max_pfn; unsigned long pfn_to_mfn_frame_list_list; unsigned long nmi_reason; unsigned long p2m_cr3; unsigned long p2m_vaddr; unsigned long p2m_generation; }

user_defined_types: struct arch_vcpu_info { unsigned long cr2; unsigned long pad; }

user_defined_types: struct vcpu_time_info { unsigned int version; unsigned int pad0; unsigned long tsc_timestamp; unsigned long system_time; unsigned int tsc_to_system_mul; char tsc_shift; char pad1[3]; }


decompiled_code:
__int64 __fastcall default_handler(unsigned int a1)
{
return micropv_printk("src/xenevents.c", 97LL, "[Port %d] - event received", a1);
}

canonical_decompiled_code:
__int64 __fastcall func12(unsigned int a1)
{
return micropv_printk("src/xenevents.c", 97LL, "[Port %d] - event received", a1);
}

original_code:
static void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
{
    micropv_printk("src/xenevents.c", 97,"[Port %d] - event received", port);
}

canonical_original_code:
static void default_handler(unsigned int port, struct pt_regs *regs, void *ignore)
{
    micropv_printk("src/xenevents.c", 97,"[Port %d] - event received", port);
}

variable_types: struct pt_regs { unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long bp; unsigned long bx; unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; unsigned long ax; unsigned long cx; unsigned long dx; unsigned long si; unsigned long di; unsigned long orig_ax; unsigned long ip; unsigned long cs; unsigned long flags; unsigned long sp; unsigned long ss; } *

variable_types:
ignore
void *


decompiled_code:
__int64 __fastcall bind_event_handler(unsigned int a1, __int64 a2, __int64 a3)
{
__int64 v4; // rcx
__int64 result; // rax

if ( a1 > 0x3FF )
{
micropv_printk("src/xenevents.c", 105LL, "ERROR: Invalid port %i", a1);
result = 0xFFFFFFFFLL;
}
else
{
if ( (__int64 (__fastcall *)(unsigned int))ev_actions[3 * a1] != default_handler )
micropv_printk("src/xenevents.c", 110LL, "WARN: Handler for port %d already registered, replacing", a1);
v4 = 3LL * a1;
qword_708[v4] = a3;
_mm_sfence();
ev_actions[v4] = a2;
result = a1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(unsigned int a1, __int64 a2, __int64 a3)
{
__int64 v4; // rcx
__int64 result; // rax

if ( a1 > 0x3FF )
{
micropv_printk("src/xenevents.c", 105LL, "ERROR: Invalid port %i", a1);
result = 0xFFFFFFFFLL;
}
else
{
if ( (__int64 (__fastcall *)(unsigned int))ev_actions[3 * a1] != default_handler )
micropv_printk("src/xenevents.c", 110LL, "WARN: Handler for port %d already registered, replacing", a1);
v4 = 3LL * a1;
qword_708[v4] = a3;
_mm_sfence();
ev_actions[v4] = a2;
result = a1;
}
return result;
}

original_code:
evtchn_port_t bind_event_handler(evtchn_port_t port, evtchn_handler_t handler, void *data)
{
    if ((port < 0) || (port >= (1024)))
    {
        micropv_printk("src/xenevents.c", 105,"ERROR: Invalid port %i", port);
        return -1;
    }
    if (ev_actions[port].handler != default_handler)
        micropv_printk("src/xenevents.c", 110,"WARN: Handler for port %d already registered, replacing", port);
    ev_actions[port].data = data;
    __asm__ __volatile__ ("sfence" ::: "memory");
    ev_actions[port].handler = handler;
    return port;
}

canonical_original_code:
unsigned int bind_event_handler(unsigned int port, void (*handler)(unsigned int port, struct pt_regs *register_file, void *context), void *data)
{
    if ((port < 0) || (port >= (1024)))
    {
        micropv_printk("src/xenevents.c", 105,"ERROR: Invalid port %i", port);
        return -1;
    }
    if (ev_actions[port].handler != default_handler)
        micropv_printk("src/xenevents.c", 110,"WARN: Handler for port %d already registered, replacing", port);
    ev_actions[port].data = data;
    __asm__ __volatile__ ("sfence" ::: "memory");
    ev_actions[port].handler = handler;
    return port;
}

variable_types: void (*)(unsigned int port, struct pt_regs { unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long bp; unsigned long bx; unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; unsigned long ax; unsigned long cx; unsigned long dx; unsigned long si; unsigned long di; unsigned long orig_ax; unsigned long ip; unsigned long cs; unsigned long flags; unsigned long sp; unsigned long ss; } *register_file, void *context)

variable_types:
data
void *


decompiled_code:
__int64 __fastcall bind_virq(unsigned int a1, __int64 a2, __int64 a3)
{
unsigned int v4; // eax
__int64 result; // rax
unsigned int v6; // [rsp+Ch] [rbp-1Ch]

v4 = HYPERVISOR_event_channel_op(1);
if ( v4 )
{
micropv_printk("src/xenevents.c", 144LL, "Failed to bind virtual IRQ %d with rc=%d", a1, v4);
result = 0xFFFFFFFFLL;
}
else
{
bind_event_handler(v6, a2, a3);
result = v6;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func16(unsigned int a1, __int64 a2, __int64 a3)
{
unsigned int v4; // eax
__int64 result; // rax
unsigned int v6; // [rsp+Ch] [rbp-1Ch]

v4 = func8(1);
if ( v4 )
{
micropv_printk("src/xenevents.c", 144LL, "Failed to bind virtual IRQ %d with rc=%d", a1, v4);
result = 0xFFFFFFFFLL;
}
else
{
func14(v6, a2, a3);
result = v6;
}
return result;
}

original_code:
evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
{
    evtchn_bind_virq_t op;
    int rc;
    op.virq = virq;
    op.vcpu = 0;
    if ((rc = HYPERVISOR_event_channel_op(1, &op)) != 0)
    {
        micropv_printk("src/xenevents.c", 144,"Failed to bind virtual IRQ %d with rc=%d", virq, rc);
        return -1;
    }
    bind_event_handler(op.port, handler, data);
    return op.port;
}

canonical_original_code:
unsigned int bind_virq(unsigned int virq, void (*handler)(unsigned int port, struct pt_regs *register_file, void *context), void *data)
{
    struct evtchn_bind_virq op;
    int rc;
    op.virq = virq;
    op.vcpu = 0;
    if ((rc = HYPERVISOR_event_channel_op(1, &op)) != 0)
    {
        micropv_printk("src/xenevents.c", 144,"Failed to bind virtual IRQ %d with rc=%d", virq, rc);
        return -1;
    }
    bind_event_handler(op.port, handler, data);
    return op.port;
}

variable_types:
virq
unsigned int

variable_types: struct evtchn_bind_virq { unsigned int virq; unsigned int vcpu; unsigned int port; }

user_defined_types: struct pt_regs { unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long bp; unsigned long bx; unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; unsigned long ax; unsigned long cx; unsigned long dx; unsigned long si; unsigned long di; unsigned long orig_ax; unsigned long ip; unsigned long cs; unsigned long flags; unsigned long sp; unsigned long ss; }


decompiled_code:
__int64 force_evtchn_callback()
{
_BYTE *v0; // rbx
char v1; // bp
__int64 result; // rax

v0 = (_BYTE *)hypervisor_shared_info;
v1 = *(_BYTE *)(hypervisor_shared_info + 1LL);
if ( *hypervisor_shared_info )
{
do
{
v0[1] = 1;
result = do_hypervisor_callback(0LL);
v0[1] = v1;
}
while ( *v0 );
}
return result;
}

canonical_decompiled_code:
__int64 func18()
{
_BYTE *v0; // rbx
char v1; // bp
__int64 result; // rax

v0 = (_BYTE *)hypervisor_shared_info;
v1 = *(_BYTE *)(hypervisor_shared_info + 1LL);
if ( *hypervisor_shared_info )
{
do
{
v0[1] = 1;
result = func17(0LL);
v0[1] = v1;
}
while ( *v0 );
}
return result;
}

original_code:
static void force_evtchn_callback(void)
{
    int save;
    vcpu_info_t *vcpu;
    vcpu = &hypervisor_shared_info->vcpu_info[0];
    save = vcpu->evtchn_upcall_mask;
    while (vcpu->evtchn_upcall_pending)
    {
        vcpu->evtchn_upcall_mask = 1;
        __asm__ __volatile__("": : :"memory");
        do_hypervisor_callback(((void *)0));
        __asm__ __volatile__("": : :"memory");
        vcpu->evtchn_upcall_mask = save;
        __asm__ __volatile__("": : :"memory");
    };
}

canonical_original_code:
static void force_evtchn_callback()
{
    int save;
    struct vcpu_info *vcpu;
    vcpu = &hypervisor_shared_info->vcpu_info[0];
    save = vcpu->evtchn_upcall_mask;
    while (vcpu->evtchn_upcall_pending)
    {
        vcpu->evtchn_upcall_mask = 1;
        __asm__ __volatile__("": : :"memory");
        do_hypervisor_callback(((void *)0));
        __asm__ __volatile__("": : :"memory");
        vcpu->evtchn_upcall_mask = save;
        __asm__ __volatile__("": : :"memory");
    };
}

variable_types: save int

variable_types: struct vcpu_info { unsigned char evtchn_upcall_pending; unsigned char evtchn_upcall_mask; unsigned long evtchn_pending_sel; struct arch_vcpu_info { unsigned long cr2; unsigned long pad; } arch; struct vcpu_time_info { unsigned int version; unsigned int pad0; unsigned long tsc_timestamp; unsigned long system_time; unsigned int tsc_to_system_mul; char tsc_shift; char pad1[3]; } time; } *


decompiled_code:
__int64 __fastcall unmask_evtchn(unsigned int a1)
{
__int64 v1; // rbp
__int64 result; // rax

v1 = hypervisor_shared_info;
micropv_printk("src/xenevents.c", 168LL, "unmask port %d", a1);
synch_clear_bit(a1, (volatile signed __int32 *)(v1 + 2560));
result = synch_var_test_bit(a1, (const signed __int32 *)(v1 + 2048));
if ( (_DWORD)result )
{
result = synch_test_and_set_bit(a1 >> 6, (volatile signed __int32 *)(v1 + 8));
if ( !(_DWORD)result )
{
*(_BYTE *)v1 = 1;
if ( !*(_BYTE *)(v1 + 1) )
result = force_evtchn_callback();
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func19(unsigned int a1)
{
__int64 v1; // rbp
__int64 result; // rax

v1 = hypervisor_shared_info;
micropv_printk("src/xenevents.c", 168LL, "unmask port %d", a1);
func1(a1, (volatile signed __int32 *)(v1 + 2560));
result = func3(a1, (const signed __int32 *)(v1 + 2048));
if ( (_DWORD)result )
{
result = func4(a1 >> 6, (volatile signed __int32 *)(v1 + 8));
if ( !(_DWORD)result )
{
*(_BYTE *)v1 = 1;
if ( !*(_BYTE *)(v1 + 1) )
result = func18();
}
}
return result;
}

original_code:
static void unmask_evtchn(uint32_t port)
{
    shared_info_t *s = hypervisor_shared_info;
    vcpu_info_t *vcpu_info = &s->vcpu_info[0];
    micropv_printk("src/xenevents.c", 168,"unmask port %d", port);
    synch_clear_bit(port, &s->evtchn_mask[0]);
    if ((__builtin_constant_p(port) ? synch_const_test_bit((port),(&s->evtchn_pending[0])) : synch_var_test_bit((port),(&s->evtchn_pending[0]))) &&
        !synch_test_and_set_bit(port / (sizeof(unsigned long) * 8), &vcpu_info->evtchn_pending_sel))
    {
        vcpu_info->evtchn_upcall_pending = 1;
        if (!vcpu_info->evtchn_upcall_mask)
            force_evtchn_callback();
    }
}

canonical_original_code:
static void unmask_evtchn(unsigned int port)
{
    struct shared_info *s = hypervisor_shared_info;
    struct vcpu_info *vcpu_info = &s->vcpu_info[0];
    micropv_printk("src/xenevents.c", 168,"unmask port %d", port);
    synch_clear_bit(port, &s->evtchn_mask[0]);
    if ((__builtin_constant_p(port) ? synch_const_test_bit((port),(&s->evtchn_pending[0])) : synch_var_test_bit((port),(&s->evtchn_pending[0]))) &&
        !synch_test_and_set_bit(port / (sizeof(unsigned long) * 8), &vcpu_info->evtchn_pending_sel))
    {
        vcpu_info->evtchn_upcall_pending = 1;
        if (!vcpu_info->evtchn_upcall_mask)
            force_evtchn_callback();
    }
}


decompiled_code:
__int64 xenevents_init()
{
__int64 *v0; // rbp
unsigned int i; // ebx

v0 = ev_actions;
for ( i = 0; i != 1024; ++i )
{
*v0 = (__int64)default_handler;
mask_evtchn(i);
v0 += 3;
}
return HYPERVISOR_set_callbacks(&hypervisor_callback, &failsafe_callback, 0LL);
}

canonical_decompiled_code:
__int64 func20()
{
__int64 *v0; // rbp
unsigned int i; // ebx

v0 = ev_actions;
for ( i = 0; i != 1024; ++i )
{
*v0 = (__int64)default_handler;
func11(i);
v0 += 3;
}
return func7(&hypervisor_callback, &failsafe_callback, 0LL);
}

original_code:
void xenevents_init(void)
{
    for (unsigned int i = 0; i < (1024); i++)
    {
        ev_actions[i].handler = default_handler;
        mask_evtchn(i);
    }
    HYPERVISOR_set_callbacks((unsigned long)hypervisor_callback, (unsigned long)failsafe_callback, 0);
}

canonical_original_code:
void xenevents_init()
{
    for (unsigned int i = 0; i < (1024); i++)
    {
        ev_actions[i].handler = default_handler;
        mask_evtchn(i);
    }
    HYPERVISOR_set_callbacks((unsigned long)hypervisor_callback, (unsigned long)failsafe_callback, 0);
}

variable_types:
i
unsigned int


decompiled_code:
__int64 __fastcall xenevents_bind_virq(unsigned int a1, __int64 a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx

v2 = bind_virq(a1, a2, 0LL);
v3 = v2;
if ( v2 == -1 )
micropv_printk("src/xenevents.c", 263LL, "Error initialising VIRQ %i", a1);
else
unmask_evtchn(v2);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func21(unsigned int a1, __int64 a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx

v2 = func16(a1, a2, 0LL);
v3 = v2;
if ( v2 == -1 )
micropv_printk("src/xenevents.c", 263LL, "Error initialising VIRQ %i", a1);
else
func19(v2);
return v3;
}

original_code:
evtchn_port_t xenevents_bind_virq(int virq, evtchn_handler_t handler)
{
    evtchn_port_t port = bind_virq(virq, handler, ((void *)0));
    if (port == -1)
    {
        micropv_printk("src/xenevents.c", 263,"Error initialising VIRQ %i", virq);
        return -1;
    }
    unmask_evtchn(port);
    return port;
}

canonical_original_code:
unsigned int xenevents_bind_virq(int virq, void (*handler)(unsigned int port, struct pt_regs *register_file, void *context))
{
    unsigned int port = bind_virq(virq, handler, ((void *)0));
    if (port == -1)
    {
        micropv_printk("src/xenevents.c", 263,"Error initialising VIRQ %i", virq);
        return -1;
    }
    unmask_evtchn(port);
    return port;
}

variable_types: virq int


decompiled_code:
__int64 __fastcall xenevents_bind_handler(unsigned int a1, __int64 a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx

v2 = bind_event_handler(a1, a2, 0LL);
v3 = v2;
if ( v2 == -1 )
micropv_printk("src/xenevents.c", 275LL, "Error initialising channel %i", a1);
else
unmask_evtchn(v2);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func22(unsigned int a1, __int64 a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx

v2 = func14(a1, a2, 0LL);
v3 = v2;
if ( v2 == -1 )
micropv_printk("src/xenevents.c", 275LL, "Error initialising channel %i", a1);
else
func19(v2);
return v3;
}

original_code:
evtchn_port_t xenevents_bind_handler(int channel, evtchn_handler_t handler)
{
    evtchn_port_t port = bind_event_handler(channel, handler, ((void *)0));
    if (-1 == port)
    {
        micropv_printk("src/xenevents.c", 275,"Error initialising channel %i", channel);
        return -1;
    }
    unmask_evtchn(port);
    return port;
}

canonical_original_code:
unsigned int xenevents_bind_handler(int channel, void (*handler)(unsigned int port, struct pt_regs *register_file, void *context))
{
    unsigned int port = bind_event_handler(channel, handler, ((void *)0));
    if (-1 == port)
    {
        micropv_printk("src/xenevents.c", 275,"Error initialising channel %i", channel);
        return -1;
    }
    unmask_evtchn(port);
    return port;
}

variable_types: channel int


decompiled_code:
__int64 __fastcall xenevents_bind_interdomain_channel(__int64 a1, __int64 a2, _DWORD *a3)
{
unsigned int v4; // eax
unsigned int v5; // ebx
int v7; // [rsp+Ch] [rbp-1Ch]

v4 = HYPERVISOR_event_channel_op(0);
v5 = v4;
if ( v4 )
micropv_printk("src/xenevents.c", 297LL, "ERROR: xenevents_alloc_channel failed with rc=%d", v4);
else
*a3 = v7;
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func24(__int64 a1, __int64 a2, _DWORD *a3)
{
unsigned int v4; // eax
unsigned int v5; // ebx
int v7; // [rsp+Ch] [rbp-1Ch]

v4 = func8(0);
v5 = v4;
if ( v4 )
micropv_printk("src/xenevents.c", 297LL, "ERROR: xenevents_alloc_channel failed with rc=%d", v4);
else
*a3 = v7;
return v5;
}

original_code:
evtchn_port_t xenevents_bind_interdomain_channel(int remote_dom, int remote_port, int *local_port)
{
    int rc;
    evtchn_bind_interdomain_t op;
    op.remote_dom = remote_dom;
    op.remote_port = remote_port;
    rc = HYPERVISOR_event_channel_op(0, &op);
    if (rc)
        micropv_printk("src/xenevents.c", 297,"ERROR: xenevents_alloc_channel failed with rc=%d", rc);
    else
        *local_port = op.local_port;
    return rc;
}

canonical_original_code:
unsigned int xenevents_bind_interdomain_channel(int remote_dom, int remote_port, int *local_port)
{
    int rc;
    struct evtchn_bind_interdomain op;
    op.remote_dom = remote_dom;
    op.remote_port = remote_port;
    rc = HYPERVISOR_event_channel_op(0, &op);
    if (rc)
        micropv_printk("src/xenevents.c", 297,"ERROR: xenevents_alloc_channel failed with rc=%d", rc);
    else
        *local_port = op.local_port;
    return rc;
}

variable_types: rc int

variable_types: struct evtchn_bind_interdomain { unsigned short remote_dom; unsigned int remote_port; unsigned int local_port; }


decompiled_code:
__int64 __fastcall micropv_fire_event(unsigned int a1)
{
__int64 result; // rax

if ( a1 > 0x3FF )
{
micropv_printk("src/xenevents.c", 339LL, "ERROR: Invalid port %i", a1);
result = 0xFFFFFFFFLL;
}
else
{
result = HYPERVISOR_event_channel_op(4);
if ( (_DWORD)result )
{
micropv_printk("src/xenevents.c", 351LL, "Failed to send event %i", (unsigned int)result);
result = 0xFFFFFFFFLL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func25(unsigned int a1)
{
__int64 result; // rax

if ( a1 > 0x3FF )
{
micropv_printk("src/xenevents.c", 339LL, "ERROR: Invalid port %i", a1);
result = 0xFFFFFFFFLL;
}
else
{
result = func8(4);
if ( (_DWORD)result )
{
micropv_printk("src/xenevents.c", 351LL, "Failed to send event %i", (unsigned int)result);
result = 0xFFFFFFFFLL;
}
}
return result;
}

original_code:
int micropv_fire_event(uint32_t event_port)
{
    if ((event_port < 0) || (event_port >= (1024)))
    {
        micropv_printk("src/xenevents.c", 339,"ERROR: Invalid port %i", event_port);
        return -1;
    }
    evtchn_send_t op =
    {
        .port = event_port
    };
    int rc;
    if ((rc = HYPERVISOR_event_channel_op(4, &op)) != 0)
    {
        micropv_printk("src/xenevents.c", 351,"Failed to send event %i", rc);
        return -1;
    }
    return 0;
}

canonical_original_code:
int micropv_fire_event(unsigned int event_port)
{
    if ((event_port < 0) || (event_port >= (1024)))
    {
        micropv_printk("src/xenevents.c", 339,"ERROR: Invalid port %i", event_port);
        return -1;
    }
    struct evtchn_send op = {
        .port = event_port
    };
    int rc;
    if ((rc = HYPERVISOR_event_channel_op(4, &op)) != 0)
    {
        micropv_printk("src/xenevents.c", 351,"Failed to send event %i", rc);
        return -1;
    }
    return 0;
}

variable_types: struct evtchn_send { unsigned int port; }


decompiled_code:
__int64 micropv_interrupt_disable()
{
__int64 result; // rax

result = hypervisor_shared_info;
*(_BYTE *)(hypervisor_shared_info + 1LL) = 1;
return result;
}

canonical_decompiled_code:
__int64 func26()
{
__int64 result; // rax

result = hypervisor_shared_info;
*(_BYTE *)(hypervisor_shared_info + 1LL) = 1;
return result;
}

original_code:
void micropv_interrupt_disable(void)
{
    __asm__ __volatile__("": : :"memory");
    hypervisor_shared_info->vcpu_info[0].evtchn_upcall_mask = 1;
    __asm__ __volatile__("": : :"memory");
}

canonical_original_code:
void micropv_interrupt_disable()
{
    __asm__ __volatile__("": : :"memory");
    hypervisor_shared_info->vcpu_info[0].evtchn_upcall_mask = 1;
    __asm__ __volatile__("": : :"memory");
}


decompiled_code:
__int64 micropv_interrupt_enable()
{
__int64 result; // rax

*(_BYTE *)(hypervisor_shared_info + 1LL) = 0;
result = hypervisor_shared_info;
if ( *hypervisor_shared_info )
result = HYPERVISOR_xen_version(0);
return result;
}

canonical_decompiled_code:
__int64 func27()
{
__int64 result; // rax

*(_BYTE *)(hypervisor_shared_info + 1LL) = 0;
result = hypervisor_shared_info;
if ( *hypervisor_shared_info )
result = func9(0);
return result;
}

original_code:
void micropv_interrupt_enable(void)
{
    __asm__ __volatile__("": : :"memory");
    hypervisor_shared_info->vcpu_info[0].evtchn_upcall_mask = 0;
    __asm__ __volatile__("": : :"memory");
    if (hypervisor_shared_info->vcpu_info[0].evtchn_upcall_pending)
        HYPERVISOR_xen_version(0, ((void *)0));
}

canonical_original_code:
void micropv_interrupt_enable()
{
    __asm__ __volatile__("": : :"memory");
    hypervisor_shared_info->vcpu_info[0].evtchn_upcall_mask = 0;
    __asm__ __volatile__("": : :"memory");
    if (hypervisor_shared_info->vcpu_info[0].evtchn_upcall_pending)
        HYPERVISOR_xen_version(0, ((void *)0));
}


decompiled_code:
__int64 __fastcall xenevents_alloc_channel(__int64 a1, _DWORD *a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx
int v5; // [rsp+Ch] [rbp-1Ch]

v2 = HYPERVISOR_event_channel_op(6);
v3 = v2;
if ( v2 )
micropv_printk("src/xenevents.c", 387LL, "ERROR: xenevents_alloc_channel failed with rc=%d", v2);
else
*a2 = v5;
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func28(__int64 a1, _DWORD *a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx
int v5; // [rsp+Ch] [rbp-1Ch]

v2 = func8(6);
v3 = v2;
if ( v2 )
micropv_printk("src/xenevents.c", 387LL, "ERROR: xenevents_alloc_channel failed with rc=%d", v2);
else
*a2 = v5;
return v3;
}

original_code:
int xenevents_alloc_channel(int remote_dom, int *port)
{
    int rc;
    evtchn_alloc_unbound_t op;
    op.dom = 0x7FF0U;
    op.remote_dom = remote_dom;
    rc = HYPERVISOR_event_channel_op(6, &op);
    if (rc)
        micropv_printk("src/xenevents.c", 387,"ERROR: xenevents_alloc_channel failed with rc=%d", rc);
    else
        *port = op.port;
    return rc;
}

canonical_original_code:
int xenevents_alloc_channel(int remote_dom, int *port)
{
    int rc;
    struct evtchn_alloc_unbound op;
    op.dom = 0x7FF0U;
    op.remote_dom = remote_dom;
    rc = HYPERVISOR_event_channel_op(6, &op);
    if (rc)
        micropv_printk("src/xenevents.c", 387,"ERROR: xenevents_alloc_channel failed with rc=%d", rc);
    else
        *port = op.port;
    return rc;
}

variable_types:
port
int *

variable_types: struct evtchn_alloc_unbound { unsigned short dom; unsigned int port; }


decompiled_code:
__int64 __fastcall xenevents_create_event(unsigned int *a1, __int64 a2)
{
unsigned int v2; // ebx
unsigned int v4; // [rsp+8h] [rbp-20h] BYREF
unsigned int v5[7]; // [rsp+Ch] [rbp-1Ch] BYREF

if ( (unsigned int)xenevents_alloc_channel(32752LL, v5) )
{
micropv_printk("src/xenevents.c", 308LL, "Failed to create event channel");
v2 = -1;
}
else
{
v2 = 0;
if ( (unsigned int)xenevents_bind_interdomain_channel(32752LL, v5[0], &v4) )
{
micropv_printk("src/xenevents.c", 315LL, "Failed to bind to interdomain channel");
v2 = -1;
}
else if ( (unsigned int)xenevents_bind_handler(v4, a2) == -1 )
{
micropv_printk("src/xenevents.c", 323LL, "Failed to bind event");
v2 = -1;
}
else
{
*a1 = v5[0];
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func29(unsigned int *a1, __int64 a2)
{
unsigned int v2; // ebx
unsigned int v4; // [rsp+8h] [rbp-20h] BYREF
unsigned int v5[7]; // [rsp+Ch] [rbp-1Ch] BYREF

if ( (unsigned int)func28(32752LL, v5) )
{
micropv_printk("src/xenevents.c", 308LL, "Failed to create event channel");
v2 = -1;
}
else
{
v2 = 0;
if ( (unsigned int)func24(32752LL, v5[0], &v4) )
{
micropv_printk("src/xenevents.c", 315LL, "Failed to bind to interdomain channel");
v2 = -1;
}
else if ( (unsigned int)func22(v4, a2) == -1 )
{
micropv_printk("src/xenevents.c", 323LL, "Failed to bind event");
v2 = -1;
}
else
{
*a1 = v5[0];
}
}
return v2;
}

original_code:
int xenevents_create_event(evtchn_port_t *event_port, evtchn_handler_t event_handler)
{
    int remote_port;
    if (xenevents_alloc_channel(0x7FF0U, &remote_port))
    {
        micropv_printk("src/xenevents.c", 308,"Failed to create event channel");
        return -1;
    }
    int local_port;
    if (xenevents_bind_interdomain_channel(0x7FF0U, remote_port, &local_port))
    {
        micropv_printk("src/xenevents.c", 315,"Failed to bind to interdomain channel");
        return -1;
    }
    int local_channel;
    local_channel = xenevents_bind_handler(local_port, event_handler);
    if (-1 == local_channel)
    {
        micropv_printk("src/xenevents.c", 323,"Failed to bind event");
        return -1;
    }
    *event_port = remote_port;
    return 0;
}

canonical_original_code:
int xenevents_create_event(unsigned int *event_port, void (*event_handler)(unsigned int port, struct pt_regs *register_file, void *context))
{
    int remote_port;
    if (xenevents_alloc_channel(0x7FF0U, &remote_port))
    {
        micropv_printk("src/xenevents.c", 308,"Failed to create event channel");
        return -1;
    }
    int local_port;
    if (xenevents_bind_interdomain_channel(0x7FF0U, remote_port, &local_port))
    {
        micropv_printk("src/xenevents.c", 315,"Failed to bind to interdomain channel");
        return -1;
    }
    int local_channel;
    local_channel = xenevents_bind_handler(local_port, event_handler);
    if (-1 == local_channel)
    {
        micropv_printk("src/xenevents.c", 323,"Failed to bind event");
        return -1;
    }
    *event_port = remote_port;
    return 0;
}


decompiled_code:
__int64 xenmmu_init()
{
__int64 result; // rax

max_pfn = hypervisor_start_info[4];
result = hypervisor_start_info[13];
phys_to_machine_mapping = result;
return result;
}

canonical_decompiled_code:
__int64 func1()
{
__int64 result; // rax

max_pfn = hypervisor_start_info[4];
result = hypervisor_start_info[13];
phys_to_machine_mapping = result;
return result;
}

original_code:
void xenmmu_init(void)
{
    max_pfn = hypervisor_start_info.nr_pages;
    phys_to_machine_mapping = (uint64_t *)hypervisor_start_info.mfn_list;
}

canonical_original_code:
void xenmmu_init()
{
    max_pfn = hypervisor_start_info.nr_pages;
    phys_to_machine_mapping = (unsigned long *)hypervisor_start_info.mfn_list;
}


decompiled_code:
__int64 __fastcall micropv_remap_page(__int64 a1, __int64 a2, __int64 a3, int a4)
{
unsigned __int64 v5; // rdx
int v6; // er15
int v7; // er12
__int64 v8; // rbx
__int64 v9; // r13
__int64 v10; // rsi
__int64 v11; // rbx
unsigned int v12; // ebp
__int64 result; // rax
__int64 v14; // [rsp+10h] [rbp-48h]
unsigned int v15; // [rsp+18h] [rbp-40h]

v5 = (unsigned __int64)(a3 + 4095) >> 12;
v15 = v5;
if ( (int)v5 <= 0 )
{
LABEL_5:
micropv_printk(
"src/xenmmu.c",
95LL,
"Physical address 0x%lx mapped to machine address 0x%lx for a length of %i pages",
a1,
a2,
v15);
result = a1;
}
else
{
v6 = v5;
v7 = 0;
v14 = a4 == 0 ? 39 : 37;
while ( 1 )
{
v8 = v7 << 12;
v9 = v8 + a2;
v10 = (v8 + a2) | v14;
v11 = a1 + v8;
v12 = HYPERVISOR_update_va_mapping(v11, v10, 2LL);
if ( v12 )
break;
if ( v6 == ++v7 )
goto LABEL_5;
}
micropv_printk("src/xenmmu.c", 90LL, "FAIL mapping physical address 0x%lx to machine address 0x%lx", v11, v9);
micropv_printk("src/xenmmu.c", 91LL, "HYPERVISOR_update_va_mapping returns %i", v12);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2, __int64 a3, int a4)
{
unsigned __int64 v5; // rdx
int v6; // er15
int v7; // er12
__int64 v8; // rbx
__int64 v9; // r13
__int64 v10; // rsi
__int64 v11; // rbx
unsigned int v12; // ebp
__int64 result; // rax
__int64 v14; // [rsp+10h] [rbp-48h]
unsigned int v15; // [rsp+18h] [rbp-40h]

v5 = (unsigned __int64)(a3 + 4095) >> 12;
v15 = v5;
if ( (int)v5 <= 0 )
{
LABEL_5:
micropv_printk(
"src/xenmmu.c",
95LL,
"Physical address 0x%lx mapped to machine address 0x%lx for a length of %i pages",
a1,
a2,
v15);
result = a1;
}
else
{
v6 = v5;
v7 = 0;
v14 = a4 == 0 ? 39 : 37;
while ( 1 )
{
v8 = v7 << 12;
v9 = v8 + a2;
v10 = (v8 + a2) | v14;
v11 = a1 + v8;
v12 = func0(v11, v10, 2LL);
if ( v12 )
break;
if ( v6 == ++v7 )
goto LABEL_5;
}
micropv_printk("src/xenmmu.c", 90LL, "FAIL mapping physical address 0x%lx to machine address 0x%lx", v11, v9);
micropv_printk("src/xenmmu.c", 91LL, "HYPERVISOR_update_va_mapping returns %i", v12);
result = 0LL;
}
return result;
}

original_code:
void *micropv_remap_page(uint64_t physical_address, uint64_t machine_address, size_t size, int readonly)
{
    int pte_type = readonly ? (0x001ULL|0x020ULL|0x004ULL) : (0x001ULL|0x002ULL|0x020ULL|0x004ULL);
    int pages = (size + (1UL << 12) - 1) >> 12;
    int page;
    for (page = 0; page < pages; page++)
    {
        int rc = HYPERVISOR_update_va_mapping(physical_address + (page << 12), ((pte_t) { ((machine_address + (page << 12)) | pte_type) } ), (2UL<<0));
        if (rc)
        {
            micropv_printk("src/xenmmu.c", 90,"FAIL mapping physical address 0x%lx to machine address 0x%lx", physical_address + (page << 12), machine_address + (page << 12));
            micropv_printk("src/xenmmu.c", 91,"HYPERVISOR_update_va_mapping returns %i", rc);
            return ((void *)0);
        }
    }
    micropv_printk("src/xenmmu.c", 95,"Physical address 0x%lx mapped to machine address 0x%lx for a length of %i pages", physical_address, machine_address, pages);
    return (void*)physical_address;
}

canonical_original_code:
void *micropv_remap_page(unsigned long physical_address, unsigned long machine_address, unsigned long size, int readonly)
{
    int pte_type = readonly ? (0x001ULL|0x020ULL|0x004ULL) : (0x001ULL|0x002ULL|0x020ULL|0x004ULL);
    int pages = (size + (1UL << 12) - 1) >> 12;
    int page;
    for (page = 0; page < pages; page++)
    {
        int rc = HYPERVISOR_update_va_mapping(physical_address + (page << 12), ((pte_t) { ((machine_address + (page << 12)) | pte_type) } ), (2UL<<0));
        if (rc)
        {
            micropv_printk("src/xenmmu.c", 90,"FAIL mapping physical address 0x%lx to machine address 0x%lx", physical_address + (page << 12), machine_address + (page << 12));
            micropv_printk("src/xenmmu.c", 91,"HYPERVISOR_update_va_mapping returns %i", rc);
            return ((void *)0);
        }
    }
    micropv_printk("src/xenmmu.c", 95,"Physical address 0x%lx mapped to machine address 0x%lx for a length of %i pages", physical_address, machine_address, pages);
    return (void *)physical_address;
}

variable_types:
size
unsigned long

variable_types: readonly int

variable_types: pages int

variable_types: page int

return_type: void *


original_code:
void *xenmmu_map_frames(uint64_t mfn[], size_t mfn_size, int readonly)
{
    uint64_t physical_address = max_pfn << 12;
    void *physical_ptr = (void *)physical_address;
    for (int fn = 0; fn < mfn_size; fn++, max_pfn++, physical_address += (1UL << 12))
    {
        micropv_remap_page(physical_address, mfn[fn] << 12, (1UL << 12), readonly);
    }
    return physical_ptr;
}

canonical_original_code:
void *xenmmu_map_frames(unsigned long mfn[], unsigned long mfn_size, int readonly)
{
    unsigned long physical_address = max_pfn << 12;
    void *physical_ptr = (void *)physical_address;
    for (int fn = 0; fn < mfn_size; fn++, max_pfn++, physical_address += (1UL << 12))
    {
        micropv_remap_page(physical_address, mfn[fn] << 12, (1UL << 12), readonly);
    }
    return physical_ptr;
}

variable_types:
mfn
unsigned long []

variable_types: fn int


decompiled_code:
__int64 __fastcall micropv_virtual_to_machine_address(unsigned __int64 a1)
{
return a1 & 0xFFF | (*(_QWORD *)(phys_to_machine_mapping + 8 * (a1 >> 12)) << 12);
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned __int64 a1)
{
return a1 & 0xFFF | (*(_QWORD *)(phys_to_machine_mapping + 8 * (a1 >> 12)) << 12);
}

original_code:
uint64_t micropv_virtual_to_machine_address(uint64_t virtual_address)
{
    uint64_t offset = virtual_address & ((1 << 12) - 1);
    uint64_t physical_address = ((unsigned long)(virtual_address)-((unsigned long)0));
    uint64_t physical_frame_number = ((physical_address) >> 12);
    uint64_t machine_frame_number = (phys_to_machine_mapping[(physical_frame_number)]);
    return (machine_frame_number << 12) | offset;
}

canonical_original_code:
unsigned long micropv_virtual_to_machine_address(unsigned long virtual_address)
{
    unsigned long offset = virtual_address & ((1 << 12) - 1);
    unsigned long physical_address = ((unsigned long)(virtual_address)-((unsigned long)0));
    unsigned long physical_frame_number = ((physical_address) >> 12);
    unsigned long machine_frame_number = (phys_to_machine_mapping[(physical_frame_number)]);
    return (machine_frame_number << 12) | offset;
}

variable_types:
offset
unsigned long

return_type: unsigned long


decompiled_code:
__int64 __fastcall micropv_machine_to_virtual_address(unsigned __int64 a1)
{
return a1 & 0xFFF | (*(_QWORD *)(8 * (a1 >> 12) - 0x800000000000LL) << 12);
}

original_code:
uint64_t micropv_machine_to_virtual_address(uint64_t machine_address)
{
    uint64_t offset = machine_address & ((1 << 12) - 1);
    uint64_t machine_frame_number = machine_address >> 12;
    uint64_t physical_frame_number = (((unsigned long *)0xFFFF800000000000UL)[(machine_frame_number)]);
    uint64_t physical_address = physical_frame_number << 12;
    uint64_t virtual_address = (uint64_t)((void *)((unsigned long)(physical_address)+((unsigned long)0)));
    return virtual_address | offset;
}

canonical_original_code:
unsigned long micropv_machine_to_virtual_address(unsigned long machine_address)
{
    unsigned long offset = machine_address & ((1 << 12) - 1);
    unsigned long machine_frame_number = machine_address >> 12;
    unsigned long physical_frame_number = (((unsigned long *)0xFFFF800000000000UL)[(machine_frame_number)]);
    unsigned long physical_address = physical_frame_number << 12;
    unsigned long virtual_address = (uint64_t)((void *)((unsigned long)(physical_address)+((unsigned long)0)));
    return virtual_address | offset;
}


decompiled_code:
__int64 xenconsole_interface()
{
return *(_QWORD *)(8LL * hypervisor_start_info[9] - 0x800000000000LL) << 12;
}

canonical_decompiled_code:
__int64 func2()
{
return *(_QWORD *)(8LL * hypervisor_start_info[9] - 0x800000000000LL) << 12;
}

original_code:
static inline struct xencons_interface *xenconsole_interface(void)
{
    return (((void *)((unsigned long)((((unsigned long *)0xFFFF800000000000UL)[(hypervisor_start_info.console.domU.mfn)]) << 12)+((unsigned long)0))));
}

canonical_original_code:
static inline struct xencons_interface *xenconsole_interface()
{
    return (((void *)((unsigned long)((((unsigned long *)0xFFFF800000000000UL)[(hypervisor_start_info.console.domU.mfn)]) << 12)+((unsigned long)0))));
}

return_type: struct xencons_interface { char in[1024]; char out[2048]; unsigned int in_cons; unsigned int out_cons; } *


decompiled_code:
__int64 xenconsole_event()
{
return hypervisor_start_info[20];
}

canonical_decompiled_code:
__int64 func3()
{
return hypervisor_start_info[20];
}

original_code:
static inline evtchn_port_t xenconsole_event(void)
{
    return hypervisor_start_info.console.domU.evtchn;
}

canonical_original_code:
static inline unsigned int xenconsole_event()
{
    return hypervisor_start_info.console.domU.evtchn;
}


original_code:
static int xenconsole_ring_send_no_notify(struct xencons_interface *ring, const char *data, unsigned len)
{
    int sent = 0;
    XENCONS_RING_IDX cons, prod;
    cons = ring->out_cons;
    prod = ring->out_prod;
    __asm__ __volatile__ ("mfence":::"memory");
    while ((sent < len) && ((prod - cons) < sizeof(ring->out)))
            ring->out[((prod++) & (sizeof(ring->out)-1))] = data[sent++];
    __asm__ __volatile__ ("sfence" ::: "memory");
    ring->out_prod = prod;
    return sent;
}

canonical_original_code:
static int xenconsole_ring_send_no_notify(struct xencons_interface *ring, char *data, unsigned int len)
{
    int sent = 0;
    unsigned int cons; unsigned int prod;
    cons = ring->out_cons;
    prod = ring->out_prod;
    __asm__ __volatile__ ("mfence":::"memory");
    while ((sent < len) && ((prod - cons) < sizeof(ring->out)))
            ring->out[((prod++) & (sizeof(ring->out)-1))] = data[sent++];
    __asm__ __volatile__ ("sfence" ::: "memory");
    ring->out_prod = prod;
    return sent;
}

variable_types: struct xencons_interface { char in[1024]; char out[2048]; unsigned int in_cons; unsigned int out_cons; } *

variable_types:
data
char *

variable_types:
len
unsigned int

variable_types: sent int

variable_types:
cons
unsigned int

variable_types:
prod
unsigned int


decompiled_code:
__int64 __fastcall xenconsole_ring_send(__int64 a1, unsigned int a2, __int64 a3, unsigned int a4)
{
unsigned int v6; // ebx

v6 = 0;
do
{
v6 += xenconsole_ring_send_no_notify(a1, a3, a4);
xenevents_notify_remote_via_evtchn(a2);
}
while ( v6 < a4 );
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, unsigned int a2, __int64 a3, unsigned int a4)
{
unsigned int v6; // ebx

v6 = 0;
do
{
v6 += func4(a1, a3, a4);
func1(a2);
}
while ( v6 < a4 );
return v6;
}

original_code:
static int xenconsole_ring_send(struct xencons_interface *ring, evtchn_port_t port, const char *data, unsigned len)
{
    int sent = 0;
    do
    {
        sent += xenconsole_ring_send_no_notify(ring, data, len);
        xenevents_notify_remote_via_evtchn(port);
    }
    while (sent < len);
    return sent;
}

canonical_original_code:
static int xenconsole_ring_send(struct xencons_interface *ring, unsigned int port, char *data, unsigned int len)
{
    int sent = 0;
    do
    {
        sent += xenconsole_ring_send_no_notify(ring, data, len);
        xenevents_notify_remote_via_evtchn(port);
    }
    while (sent < len);
    return sent;
}

variable_types:
port
unsigned int

user_defined_types: struct xencons_interface { char in[1024]; char out[2048]; unsigned int in_cons; unsigned int out_cons; }


decompiled_code:
void xenconsole_event_handler()
{
;
}

canonical_decompiled_code:
void func6()
{
;
}

original_code:
static void xenconsole_event_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
{
}

canonical_original_code:
static void xenconsole_event_handler(unsigned int port, struct pt_regs *regs, void *data)
{
}

variable_types: struct pt_regs { unsigned long r15; unsigned long r14; unsigned long r13; unsigned long r12; unsigned long bp; unsigned long bx; unsigned long r11; unsigned long r10; unsigned long r9; unsigned long r8; unsigned long ax; unsigned long cx; unsigned long dx; unsigned long si; unsigned long di; unsigned long orig_ax; unsigned long ip; unsigned long cs; unsigned long flags; unsigned long sp; unsigned long ss; } *

variable_types:
data
void *


decompiled_code:
__int64 __fastcall micropv_console_write(__int64 a1, unsigned int a2)
{
unsigned int v2; // ebx
__int64 v3; // rax

v2 = xenconsole_event();
v3 = xenconsole_interface();
return xenconsole_ring_send(v3, v2, a1, a2);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, unsigned int a2)
{
unsigned int v2; // ebx
__int64 v3; // rax

v2 = func3();
v3 = func2();
return func5(v3, v2, a1, a2);
}

original_code:
int micropv_console_write(const void *ptr, size_t len)
{
    return xenconsole_ring_send(xenconsole_interface(), xenconsole_event(), ptr, len);
}

canonical_original_code:
int micropv_console_write(void *ptr, unsigned long len)
{
    return xenconsole_ring_send(xenconsole_interface(), xenconsole_event(), ptr, len);
}

variable_types:
ptr
void *

variable_types:
len
unsigned long


decompiled_code:
__int64 micropv_console_write_available()
{
__int64 v0; // rax

v0 = xenconsole_interface();
return (*(_DWORD *)(v0 + 3084) - 1 - *(_DWORD *)(v0 + 3080)) & 0x7FF;
}

original_code:
int micropv_console_write_available()
{
    struct xencons_interface *ring = xenconsole_interface();
    return (ring->out_prod - ring->out_cons - 1) & (sizeof(ring->out) - 1);
}


decompiled_code:
__int64 xenconsole_printf(__int64 a1, ...)
{
int v1; // eax
unsigned int v2; // ebx
signed __int64 v4; // rsi
void *v5; // rsp
__int64 v6; // [rsp+0h] [rbp-F0h] BYREF
gcc_va_list va; // [rsp+8h] [rbp-E8h] BYREF

va_start(va, a1);
v1 = pvsnprintf(0LL, 0LL, a1, va);
v2 = v1;
if ( v1 > 0 )
{
v4 = v1 + 1;
v5 = alloca(v4);
va_end(va);
va_start(va, a1);
v2 = pvsnprintf(&v6, v4, a1, va);
micropv_console_write((__int64)&v6, v2);
}
return v2;
}

canonical_decompiled_code:
__int64 func9(__int64 a1, ...)
{
int v1; // eax
unsigned int v2; // ebx
signed __int64 v4; // rsi
void *v5; // rsp
__int64 v6; // [rsp+0h] [rbp-F0h] BYREF
gcc_va_list va; // [rsp+8h] [rbp-E8h] BYREF

va_start(va, a1);
v1 = pvsnprintf(0LL, 0LL, a1, va);
v2 = v1;
if ( v1 > 0 )
{
v4 = v1 + 1;
v5 = alloca(v4);
va_end(va);
va_start(va, a1);
v2 = pvsnprintf(&v6, v4, a1, va);
func7((__int64)&v6, v2);
}
return v2;
}

original_code:
int xenconsole_printf(const char *format, ...)
{
    va_list args;
    int length;
    __builtin_va_start(args,format);
    length = pvsnprintf(((void *)0), 0, format, args);
    __builtin_va_end(args);
    if (length > 0)
    {
        char message[length + 1];
        __builtin_va_start(args,format);
        length = pvsnprintf(message, length + 1, format, args);
        __builtin_va_end(args);
        micropv_console_write(message, length);
    }
    return length;
}

canonical_original_code:
int xenconsole_printf(char *format, ...)
{
    __builtin_va_list args;
    int length;
    __builtin_va_start(args,format);
    length = pvsnprintf(((void *)0), 0, format, args);
    __builtin_va_end(args);
    if (length > 0)
    {
        char message[-1];
        __builtin_va_start(args,format);
        length = pvsnprintf(message, length + 1, format, args);
        __builtin_va_end(args);
        micropv_console_write(message, length);
    }
    return length;
}

variable_types:
format
char *

variable_types: length int

variable_types:
message
char [-1]


original_code:
int micropv_console_read(void *ptr, size_t len)
{
    int received = 0;
    XENCONS_RING_IDX cons, prod;
    struct xencons_interface *ring = xenconsole_interface();
    cons = ring->in_cons;
    prod = ring->in_prod;
    __asm__ __volatile__ ("mfence":::"memory");
    while ((received < len) && ((cons - prod) & (sizeof(ring->in) - 1)))
        ((char *)ptr)[received++] = ring->in[((cons++) & (sizeof(ring->in)-1))];
    __asm__ __volatile__ ("sfence" ::: "memory");
    ring->in_cons = cons;
    return received;
}

canonical_original_code:
int micropv_console_read(void *ptr, unsigned long len)
{
    int received = 0;
    unsigned int cons; unsigned int prod;
    struct xencons_interface *ring = xenconsole_interface();
    cons = ring->in_cons;
    prod = ring->in_prod;
    __asm__ __volatile__ ("mfence":::"memory");
    while ((received < len) && ((cons - prod) & (sizeof(ring->in) - 1)))
        ((char *)ptr)[received++] = ring->in[((cons++) & (sizeof(ring->in)-1))];
    __asm__ __volatile__ ("sfence" ::: "memory");
    ring->in_cons = cons;
    return received;
}

variable_types: received int


decompiled_code:
__int64 micropv_console_read_available()
{
__int64 v0; // rax

v0 = xenconsole_interface();
return (*(_WORD *)(v0 + 3072) - *(_WORD *)(v0 + 3076)) & 0x3FF;
}

original_code:
int micropv_console_read_available()
{
    struct xencons_interface *ring = xenconsole_interface();
    return (ring->in_cons - ring->in_prod) & (sizeof(ring->in) - 1);
}


decompiled_code:
__int64 xenconsole_init()
{
__int64 v0; // rdi
__int64 result; // rax
unsigned int v2; // eax

v0 = (unsigned int)xenconsole_event();
result = 0LL;
if ( (_DWORD)v0 )
{
if ( (unsigned int)xenevents_bind_handler(v0, xenconsole_event_handler) == -1 )
{
micropv_printk("src/xenconsole.c", 204LL, "XEN console channel bind failed");
result = 0xFFFFFFFFLL;
}
else
{
v2 = xenconsole_event();
xenevents_notify_remote_via_evtchn(v2);
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 func12()
{
__int64 v0; // rdi
__int64 result; // rax
unsigned int v2; // eax

v0 = (unsigned int)func3();
result = 0LL;
if ( (_DWORD)v0 )
{
if ( (unsigned int)xenevents_bind_handler(v0, xenconsole_event_handler) == -1 )
{
micropv_printk("src/xenconsole.c", 204LL, "XEN console channel bind failed");
result = 0xFFFFFFFFLL;
}
else
{
v2 = func3();
func1(v2);
result = 0LL;
}
}
return result;
}

original_code:
int xenconsole_init(void)
{
    if (!xenconsole_event())
        return 0;
    port = xenevents_bind_handler(xenconsole_event(), xenconsole_event_handler);
    if (port == -1)
    {
        micropv_printk("src/xenconsole.c", 204,"XEN console channel bind failed");
        return -1;
    }
    xenevents_notify_remote_via_evtchn(xenconsole_event());
    return 0;
}

canonical_original_code:
int xenconsole_init()
{
    if (!xenconsole_event())
        return 0;
    port = xenevents_bind_handler(xenconsole_event(), xenconsole_event_handler);
    if (port == -1)
    {
        micropv_printk("src/xenconsole.c", 204,"XEN console channel bind failed");
        return -1;
    }
    xenevents_notify_remote_via_evtchn(xenconsole_event());
    return 0;
}


decompiled_code:
__int64 scheduler_timer_dummy()
{
return 10000000LL;
}

original_code:
static uint64_t scheduler_timer_dummy(struct pt_regs *regs, uint64_t deadline)
{
    return (((10L) * 1000UL) * 1000UL);
}

canonical_original_code:
static unsigned long scheduler_timer_dummy(struct pt_regs *regs, unsigned long deadline)
{
    return (((10L) * 1000UL) * 1000UL);
}

variable_types:
deadline
unsigned long


decompiled_code:
void scheduler_yield_dummy()
{
;
}

canonical_decompiled_code:
void func4()
{
;
}

original_code:
static void scheduler_yield_dummy(struct pt_regs *regs)
{
}


decompiled_code:
__int64 __fastcall yield_handler(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // r12
__int64 result; // rax

if ( in_yield )
{
in_yield = 0;
v2 = *(_QWORD *)(a2 + 152);
v3 = *(_QWORD *)(a2 + 160);
result = micropv_scheduler_yield_callback(a2);
if ( *(_QWORD *)(a2 + 152) != v2 || *(_QWORD *)(a2 + 160) != v3 )
{
HYPERVISOR_stack_switch(*(_QWORD *)(a2 + 160));
result = HYPERVISOR_fpu_taskswitch(1);
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // r12
__int64 result; // rax

if ( in_yield )
{
in_yield = 0;
v2 = *(_QWORD *)(a2 + 152);
v3 = *(_QWORD *)(a2 + 160);
result = micropv_scheduler_yield_callback(a2);
if ( *(_QWORD *)(a2 + 152) != v2 || *(_QWORD *)(a2 + 160) != v3 )
{
func0(*(_QWORD *)(a2 + 160));
result = func1(1);
}
}
return result;
}

original_code:
static void yield_handler(uint32_t port, struct pt_regs *regs, void *context)
{
    if (in_yield)
    {
        in_yield = 0;
        unsigned long sp = regs->sp;
        unsigned long ss = regs->ss;
        micropv_scheduler_yield_callback(regs);
        if ((sp != regs->sp) || (ss != regs->ss))
        {
            HYPERVISOR_stack_switch(regs->ss, regs->sp);
            HYPERVISOR_fpu_taskswitch(1);
        }
    }
}

canonical_original_code:
static void yield_handler(unsigned int port, struct pt_regs *regs, void *context)
{
    if (in_yield)
    {
        in_yield = 0;
        unsigned long sp = regs->sp;
        unsigned long ss = regs->ss;
        micropv_scheduler_yield_callback(regs);
        if ((sp != regs->sp) || (ss != regs->ss))
        {
            HYPERVISOR_stack_switch(regs->ss, regs->sp);
            HYPERVISOR_fpu_taskswitch(1);
        }
    }
}

variable_types:
context
void *

variable_types:
sp
unsigned long

variable_types:
ss
unsigned long


decompiled_code:
__int64 __fastcall timer_handler(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // r12
__int64 v4; // r13
__int64 (__fastcall *v5)(); // rax
__int64 result; // rax

v2 = timer_deadline;
do
timer_deadline += timer_period;
while ( micropv_time_monotonic_clock() > (unsigned __int64)timer_deadline );
xentime_set_next_event();
xentime_update();
v3 = *(_QWORD *)(a2 + 152);
v4 = *(_QWORD *)(a2 + 160);
v5 = micropv_scheduler_timer_callback;
if ( !micropv_scheduler_timer_callback )
v5 = scheduler_timer_dummy;
result = ((__int64 (__fastcall *)(__int64, __int64))v5)(a2, v2);
timer_period = result;
if ( *(_QWORD *)(a2 + 152) != v3 || *(_QWORD *)(a2 + 160) != v4 )
{
HYPERVISOR_stack_switch(*(_QWORD *)(a2 + 160));
result = HYPERVISOR_fpu_taskswitch(1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // r12
__int64 v4; // r13
__int64 (__fastcall *v5)(); // rax
__int64 result; // rax

v2 = timer_deadline;
do
timer_deadline += timer_period;
while ( micropv_time_monotonic_clock() > (unsigned __int64)timer_deadline );
xentime_set_next_event();
xentime_update();
v3 = *(_QWORD *)(a2 + 152);
v4 = *(_QWORD *)(a2 + 160);
v5 = micropv_scheduler_timer_callback;
if ( !micropv_scheduler_timer_callback )
v5 = scheduler_timer_dummy;
result = ((__int64 (__fastcall *)(__int64, __int64))v5)(a2, v2);
timer_period = result;
if ( *(_QWORD *)(a2 + 152) != v3 || *(_QWORD *)(a2 + 160) != v4 )
{
func0(*(_QWORD *)(a2 + 160));
result = func1(1);
}
return result;
}

original_code:
static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign)
{
    uint64_t deadline = timer_deadline;
    do timer_deadline += timer_period;
    while (timer_deadline < micropv_time_monotonic_clock());
    xentime_set_next_event(timer_deadline);
    xentime_update();
    unsigned long sp = regs->sp;
    unsigned long ss = regs->ss;
    timer_period = (micropv_scheduler_timer_callback ? micropv_scheduler_timer_callback : scheduler_timer_dummy)(regs, deadline);
    if ((sp != regs->sp) || (ss != regs->ss))
    {
        HYPERVISOR_stack_switch(regs->ss, regs->sp);
        HYPERVISOR_fpu_taskswitch(1);
    }
}

canonical_original_code:
static void timer_handler(unsigned int ev, struct pt_regs *regs, void *ign)
{
    unsigned long deadline = timer_deadline;
    do timer_deadline += timer_period;
    while (timer_deadline < micropv_time_monotonic_clock());
    xentime_set_next_event(timer_deadline);
    xentime_update();
    unsigned long sp = regs->sp;
    unsigned long ss = regs->ss;
    timer_period = (micropv_scheduler_timer_callback ? micropv_scheduler_timer_callback : scheduler_timer_dummy)(regs, deadline);
    if ((sp != regs->sp) || (ss != regs->ss))
    {
        HYPERVISOR_stack_switch(regs->ss, regs->sp);
        HYPERVISOR_fpu_taskswitch(1);
    }
}

variable_types:
ev
unsigned int

variable_types:
ign
void *


decompiled_code:
void micropv_scheduler_yield()
{
if ( yield_port != -1 )
{
in_yield = 1;
if ( (unsigned int)micropv_fire_event() )
micropv_printk("src/xenschedule.c", 174LL, "Error firing context_switch_event");
}
}

canonical_decompiled_code:
void func8()
{
if ( yield_port != -1 )
{
in_yield = 1;
if ( (unsigned int)micropv_fire_event() )
micropv_printk("src/xenschedule.c", 174LL, "Error firing context_switch_event");
}
}

original_code:
void micropv_scheduler_yield(void)
{
    if (-1 != yield_port)
    {
        in_yield = 1;
        if (micropv_fire_event(yield_port))
            micropv_printk("src/xenschedule.c", 174,"Error firing context_switch_event");
    }
}

canonical_original_code:
void micropv_scheduler_yield()
{
    if (-1 != yield_port)
    {
        in_yield = 1;
        if (micropv_fire_event(yield_port))
            micropv_printk("src/xenschedule.c", 174,"Error firing context_switch_event");
    }
}


decompiled_code:
__int64 micropv_scheduler_block()
{
return HYPERVISOR_sched_op(1);
}

canonical_decompiled_code:
__int64 func9()
{
return func2(1);
}

original_code:
void micropv_scheduler_block(void)
{
    HYPERVISOR_sched_op(1, 0);
}

canonical_original_code:
void micropv_scheduler_block()
{
    HYPERVISOR_sched_op(1, 0);
}


decompiled_code:
__int64 xenscheduler_init()
{
xentime_stop_periodic();
xenevents_bind_virq(0LL, timer_handler);
xenevents_create_event(&yield_port, yield_handler);
timer_deadline = timer_period + micropv_time_monotonic_clock();
return xentime_set_next_event(timer_deadline);
}

canonical_decompiled_code:
__int64 func10()
{
xentime_stop_periodic();
xenevents_bind_virq(0LL, timer_handler);
xenevents_create_event(&yield_port, yield_handler);
timer_deadline = timer_period + micropv_time_monotonic_clock();
return xentime_set_next_event(timer_deadline);
}

original_code:
void xenscheduler_init(void)
{
    xentime_stop_periodic();
    timer_port = xenevents_bind_virq(0, &timer_handler);
    xenevents_create_event(&yield_port, yield_handler);
    timer_deadline = micropv_time_monotonic_clock() + timer_period;
    xentime_set_next_event(timer_deadline);
}

canonical_original_code:
void xenscheduler_init()
{
    xentime_stop_periodic();
    timer_port = xenevents_bind_virq(0, &timer_handler);
    xenevents_create_event(&yield_port, yield_handler);
    timer_deadline = micropv_time_monotonic_clock() + timer_period;
    xentime_set_next_event(timer_deadline);
}


decompiled_code:
void __noreturn micropv_exit()
{
micropv_printk("src/xenschedule.c", 201LL, "micropv_exit called!");
while ( 1 )
HYPERVISOR_sched_op(2);
}

canonical_decompiled_code:
void __noreturn func11()
{
micropv_printk("src/xenschedule.c", 201LL, "micropv_exit called!");
while ( 1 )
func2(2);
}

original_code:
void micropv_exit(void)
{
    micropv_printk("src/xenschedule.c", 201,"micropv_exit called!");
    for (;;)
    {
        struct sched_shutdown sched_shutdown = { .reason = 1 };
        HYPERVISOR_sched_op(2, &sched_shutdown);
    }
}

canonical_original_code:
void micropv_exit()
{
    micropv_printk("src/xenschedule.c", 201,"micropv_exit called!");
    for (;;)
    {
        struct sched_shutdown sched_shutdown = { .reason = 1 };
        HYPERVISOR_sched_op(2, &sched_shutdown);
    }
}

variable_types: struct sched_shutdown { unsigned int reason; }


strlen

decompiled_code:
__int64 __fastcall strlen(_BYTE *a1)
{
__int64 result; // rax

if ( !*a1 )
return 0LL;
result = 0LL;
do
++result;
while ( a1[result] );
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(_BYTE *a1)
{
__int64 result; // rax

if ( !*a1 )
return 0LL;
result = 0LL;
do
++result;
while ( a1[result] );
return result;
}

original_code:
size_t strlen(const char *s)
{
    size_t c;
    for (c = 0; *s++; c++) ;
    return c;
}

canonical_original_code:
unsigned long strlen(char *s)
{
    unsigned long c;
    for (c = 0; *s++; c++) ;
    return c;
}

variable_types:
s
char *

variable_types:
c
unsigned long


decompiled_code:
int __fastcall start_kernel(__int64 a1)
{
const char **v1; // rdx

micropv_printk("src/kernel.c", 65LL, "micro_pv started");
hypervisor_start(a1);
micropv_printk("src/kernel.c", 71LL, "calling main");
return main((int)"src/kernel.c", (const char **)((char *)&loc_43 + 4), v1);
}

canonical_decompiled_code:
int __fastcall func0(__int64 a1)
{
const char **v1; // rdx

micropv_printk("src/kernel.c", 65LL, "micro_pv started");
hypervisor_start(a1);
micropv_printk("src/kernel.c", 71LL, "calling main");
return main((int)"src/kernel.c", (const char **)((char *)&loc_43 + 4), v1);
}

original_code:
void start_kernel(start_info_t *si)
{
    micropv_printk("src/kernel.c", 65,"micro_pv started");
    hypervisor_start(si);
    micropv_printk("src/kernel.c", 71,"calling main");
    main();
}

canonical_original_code:
void start_kernel(struct start_info *si)
{
    micropv_printk("src/kernel.c", 65,"micro_pv started");
    hypervisor_start(si);
    micropv_printk("src/kernel.c", 71,"calling main");
    main();
}

variable_types: struct start_info { char magic[32]; unsigned long nr_pages; unsigned long shared_info; unsigned int flags; unsigned long store_mfn; unsigned int store_evtchn; union { struct { unsigned long mfn; unsigned int evtchn; } domU; struct { unsigned int info_off; unsigned int info_size; } dom0; } console; unsigned long pt_base; unsigned long nr_pt_frames; unsigned long mfn_list; unsigned long mod_start; unsigned long mod_len; char cmd_line[1024]; unsigned long first_p2m_pfn; unsigned long nr_p2m_frames; } *


decompiled_code:
__int64 hypervisor_setup_xen_features()
{
__int64 result; // rax
__int64 i; // rcx

result = HYPERVISOR_xen_version(6);
if ( (int)result >= 0 )
{
for ( i = 0LL; i != 32; ++i )
{
result = (unsigned int)(1 << i);
xen_features[i] = 0;
}
}
return result;
}

canonical_decompiled_code:
__int64 func2()
{
__int64 result; // rax
__int64 i; // rcx

result = func0(6);
if ( (int)result >= 0 )
{
for ( i = 0LL; i != 32; ++i )
{
result = (unsigned int)(1 << i);
xen_features[i] = 0;
}
}
return result;
}

original_code:
static void hypervisor_setup_xen_features(void)
{
    xen_feature_info_t fi;
    int i, j;
    for (i = 0; i < 1; i++)
    {
        fi.submap = 0;
        fi.submap_idx = i;
        if (HYPERVISOR_xen_version(6, &fi) < 0)
            break;
        for (j = 0; j < 32; j++) xen_features[i * 32 + j] = !!(fi.submap & 1 << j);
    }
}

canonical_original_code:
static void hypervisor_setup_xen_features()
{
    struct xen_feature_info fi;
    int i; int j;
    for (i = 0; i < 1; i++)
    {
        fi.submap = 0;
        fi.submap_idx = i;
        if (HYPERVISOR_xen_version(6, &fi) < 0)
            break;
        for (j = 0; j < 32; j++) xen_features[i * 32 + j] = !!(fi.submap & 1 << j);
    }
}

variable_types: struct xen_feature_info { unsigned int submap_idx; unsigned int submap; }

variable_types: i int

variable_types: j int


original_code:
static void console_printkv(const char *file, long line, const char *format, va_list args)
{
    va_list args0;;
    int message_length;
    __builtin_va_copy(args0,args);
    message_length = pvsnprintf(((void *)0), 0, format, args);
    if (message_length > 0)
    {
        char header[strlen(file)+ 30];
        struct timeval tv;
        micropv_time_gettimeofday(&tv, ((void *)0));
        uint64_t millisecond = tv.tv_usec / 1000;
        uint64_t second = tv.tv_sec % 60; tv.tv_sec /= 60;
        uint64_t minute = tv.tv_sec % 60; tv.tv_sec /= 60;
        uint64_t hour = tv.tv_sec % 24;
        int header_length = psnprintf(header, sizeof(header), "%02lu:%02lu:%02lu.%03lu %s@%.5li: ", hour, minute, second, millisecond, file, line);
        char message[message_length + 1];
        message_length = pvsnprintf(message, message_length + 1, format, args0);
        HYPERVISOR_console_io(0, header_length, header);
        HYPERVISOR_console_io(0, message_length, message);
        if ((header_length + message_length) < 80) {
            static char lf = '\n';
            HYPERVISOR_console_io(0, 1, &lf);
        }
    }
    __builtin_va_end(args0);
}

canonical_original_code:
static void console_printkv(char *file, long line, char *format, __builtin_va_list args)
{
    __builtin_va_list args0;;
    int message_length;
    __builtin_va_copy(args0,args);
    message_length = pvsnprintf(((void *)0), 0, format, args);
    if (message_length > 0)
    {
        char header[-1];
        struct timeval tv;
        micropv_time_gettimeofday(&tv, ((void *)0));
        unsigned long millisecond = tv.tv_usec / 1000;
        unsigned long second = tv.tv_sec % 60; tv.tv_sec /= 60;
        unsigned long minute = tv.tv_sec % 60; tv.tv_sec /= 60;
        unsigned long hour = tv.tv_sec % 24;
        int header_length = psnprintf(header, sizeof(header), "%02lu:%02lu:%02lu.%03lu %s@%.5li: ", hour, minute, second, millisecond, file, line);
        char message[-1];
        message_length = pvsnprintf(message, message_length + 1, format, args0);
        HYPERVISOR_console_io(0, header_length, header);
        HYPERVISOR_console_io(0, message_length, message);
        if ((header_length + message_length) < 80) {
            static char lf = '\n';
            HYPERVISOR_console_io(0, 1, &lf);
        }
    }
    __builtin_va_end(args0);
}

variable_types:
file
char *

variable_types: line long

variable_types:
format
char *

variable_types:
header
char [-1]

variable_types: struct timeval { long tv_sec; long tv_usec; }

variable_types:
millisecond
unsigned long

variable_types:
second
unsigned long

variable_types:
minute
unsigned long

variable_types:
hour
unsigned long

variable_types: lf char


decompiled_code:
__int64 micropv_printk(__int64 a1, __int64 a2, __int64 a3, ...)
{
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

va_start(va, a3);
return micropv_printkv(a1, a2, a3, va);
}

canonical_decompiled_code:
__int64 func4(__int64 a1, __int64 a2, __int64 a3, ...)
{
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

va_start(va, a3);
return micropv_printkv(a1, a2, a3, va);
}

original_code:
void micropv_printk(const char *file, long line, const char *format, ...)
{
    va_list args;
    __builtin_va_start(args,format);
    micropv_printkv(file, line, format, args);
    __builtin_va_end(args);
}

canonical_original_code:
void micropv_printk(char *file, long line, char *format, ...)
{
    __builtin_va_list args;
    __builtin_va_start(args,format);
    micropv_printkv(file, line, format, args);
    __builtin_va_end(args);
}


original_code:
void micropv_printk_binary(const char *file, long line, const char *buffer, size_t buffer_len)
{
    const int entries_per_line = 0x10;
    const int entries_per_line_mask = entries_per_line - 1;
    const int line_length = 3 + (entries_per_line * 2) + (entries_per_line / 4) + 5 + entries_per_line + 2;
    char debug_buffer[line_length];
    static const char hex[] = "0123456789abcdef";
    int i = 0;
    while (i < buffer_len)
    {
        int output_index = 0;
        debug_buffer[output_index++] = hex[(i >> 4) & 0xf];
        debug_buffer[output_index++] = hex[i & 0xf];
        debug_buffer[output_index++] = ' ';
        do
        {
            debug_buffer[output_index++] = hex[(buffer[i] >> 4) & 0xf];
            debug_buffer[output_index++] = hex[buffer[i] & 0xf];
            if ((i & 3) == 3)
                debug_buffer[output_index++] = ' ';
            i++;
        } while ((i & entries_per_line_mask) && (i < buffer_len));
        while (i & entries_per_line_mask)
        {
            debug_buffer[output_index++] = ' ';
            debug_buffer[output_index++] = ' ';
            if ((i & 3) == 3)
                debug_buffer[output_index++] = ' ';
            i++;
        }
        debug_buffer[output_index++] = '.';
        debug_buffer[output_index++] = '.';
        debug_buffer[output_index++] = '.';
        debug_buffer[output_index++] = ' ';
        debug_buffer[output_index++] = '[';
        i -= entries_per_line;
        do
        {
            debug_buffer[output_index++] = (buffer[i] >= ' ') ? buffer[i] : '.';
            i++;
        } while ((i & entries_per_line_mask) && (i < buffer_len));
        debug_buffer[output_index++] = ']';
        debug_buffer[output_index++] = 0;
        micropv_printk(file, line, "%.*s", output_index, debug_buffer);
    }
}

canonical_original_code:
void micropv_printk_binary(char *file, long line, char *buffer, unsigned long buffer_len)
{
    int entries_per_line = 0x10;
    int entries_per_line_mask = entries_per_line - 1;
    int line_length = 3 + (entries_per_line * 2) + (entries_per_line / 4) + 5 + entries_per_line + 2;
    char debug_buffer[-1];
    static char hex[] = "0123456789abcdef";
    int i = 0;
    while (i < buffer_len)
    {
        int output_index = 0;
        debug_buffer[output_index++] = hex[(i >> 4) & 0xf];
        debug_buffer[output_index++] = hex[i & 0xf];
        debug_buffer[output_index++] = ' ';
        do
        {
            debug_buffer[output_index++] = hex[(buffer[i] >> 4) & 0xf];
            debug_buffer[output_index++] = hex[buffer[i] & 0xf];
            if ((i & 3) == 3)
                debug_buffer[output_index++] = ' ';
            i++;
        } while ((i & entries_per_line_mask) && (i < buffer_len));
        while (i & entries_per_line_mask)
        {
            debug_buffer[output_index++] = ' ';
            debug_buffer[output_index++] = ' ';
            if ((i & 3) == 3)
                debug_buffer[output_index++] = ' ';
            i++;
        }
        debug_buffer[output_index++] = '.';
        debug_buffer[output_index++] = '.';
        debug_buffer[output_index++] = '.';
        debug_buffer[output_index++] = ' ';
        debug_buffer[output_index++] = '[';
        i -= entries_per_line;
        do
        {
            debug_buffer[output_index++] = (buffer[i] >= ' ') ? buffer[i] : '.';
            i++;
        } while ((i & entries_per_line_mask) && (i < buffer_len));
        debug_buffer[output_index++] = ']';
        debug_buffer[output_index++] = 0;
        micropv_printk(file, line, "%.*s", output_index, debug_buffer);
    }
}

variable_types:
buffer
char *

variable_types:
hex
char []


decompiled_code:
__int64 __fastcall hypervisor_start(_QWORD *a1)
{
micropv_printk((__int64)"src/hypervisor.c", 216LL, (__int64)"Allocated memory pages : %lu", a1[4]);
micropv_printk((__int64)"src/hypervisor.c", 217LL, (__int64)"Allocated memory MB : %lu", a1[4] >> 8);
micropv_printk((__int64)"src/hypervisor.c", 218LL, (__int64)"Machine address of shared memory : 0x%lx", a1[5]);
__asm { fninit }
_mm_setcsr(0x1F80u);
qmemcpy(hypervisor_start_info, a1, sizeof(hypervisor_start_info));
hypervisor_setup_xen_features();
xentraps_init();
xenmmu_init();
hypervisor_shared_info = micropv_remap_page(&shared_info, hypervisor_start_info[5], 4096LL, 0LL);
if ( !hypervisor_shared_info )
{
micropv_printk(
(__int64)"src/hypervisor.c",
242LL,
(__int64)"ASSERTION FAILED: %s at %s:%d.",
"!(hypervisor_shared_info == ((void *)0))",
"src/hypervisor.c",
242LL);
micropv_exit();
}
xenevents_init();
xenconsole_init();
xentime_init();
xenstore_init();
xengnttab_init();
return xenscheduler_init();
}

canonical_decompiled_code:
__int64 __fastcall func6(_QWORD *a1)
{
func4((__int64)"src/hypervisor.c", 216LL, (__int64)"Allocated memory pages : %lu", a1[4]);
func4((__int64)"src/hypervisor.c", 217LL, (__int64)"Allocated memory MB : %lu", a1[4] >> 8);
func4((__int64)"src/hypervisor.c", 218LL, (__int64)"Machine address of shared memory : 0x%lx", a1[5]);
__asm { fninit }
_mm_setcsr(0x1F80u);
qmemcpy(hypervisor_start_info, a1, sizeof(hypervisor_start_info));
func2();
xentraps_init();
xenmmu_init();
hypervisor_shared_info = micropv_remap_page(&shared_info, hypervisor_start_info[5], 4096LL, 0LL);
if ( !hypervisor_shared_info )
{
func4(
(__int64)"src/hypervisor.c",
242LL,
(__int64)"ASSERTION FAILED: %s at %s:%d.",
"!(hypervisor_shared_info == ((void *)0))",
"src/hypervisor.c",
242LL);
micropv_exit();
}
xenevents_init();
xenconsole_init();
xentime_init();
xenstore_init();
xengnttab_init();
return xenscheduler_init();
}

original_code:
void hypervisor_start(start_info_t *si)
{
    micropv_printk("src/hypervisor.c", 216,"Allocated memory pages           : %lu", si->nr_pages);
    micropv_printk("src/hypervisor.c", 217,"Allocated memory MB              : %lu", si->nr_pages >> (20 - 12));
    micropv_printk("src/hypervisor.c", 218,"Machine address of shared memory : 0x%lx", si->shared_info);
    __asm__ volatile(" fninit");
    unsigned long status = 0x1f80;
    __asm__ volatile("ldmxcsr %0" : : "m" (status));
    memcpy(&hypervisor_start_info, si, sizeof(hypervisor_start_info));
    hypervisor_setup_xen_features();
    xentraps_init();
    xenmmu_init();
    hypervisor_shared_info = micropv_remap_page((unsigned long)&shared_info, hypervisor_start_info.shared_info, sizeof(shared_info), 0);
    do { if (!(!(hypervisor_shared_info == ((void *)0)))) { micropv_printk("src/hypervisor.c", 242,"ASSERTION FAILED: %s at %s:%d.", "!(hypervisor_shared_info == ((void *)0))" , "src/hypervisor.c", 242); micropv_exit(); } } while(0);
    xenevents_init();
    xenconsole_init();
    xentime_init();
    xenstore_init();
    xengnttab_init();
    xenscheduler_init();
}

canonical_original_code:
void hypervisor_start(struct start_info *si)
{
    micropv_printk("src/hypervisor.c", 216,"Allocated memory pages           : %lu", si->nr_pages);
    micropv_printk("src/hypervisor.c", 217,"Allocated memory MB              : %lu", si->nr_pages >> (20 - 12));
    micropv_printk("src/hypervisor.c", 218,"Machine address of shared memory : 0x%lx", si->shared_info);
    __asm__ volatile(" fninit");
    unsigned long status = 0x1f80;
    __asm__ volatile("ldmxcsr %0" : : "m" (status));
    memcpy(&hypervisor_start_info, si, sizeof(hypervisor_start_info));
    hypervisor_setup_xen_features();
    xentraps_init();
    xenmmu_init();
    hypervisor_shared_info = micropv_remap_page((unsigned long)&shared_info, hypervisor_start_info.shared_info, sizeof(shared_info), 0);
    do { if (!(!(hypervisor_shared_info == ((void *)0)))) { micropv_printk("src/hypervisor.c", 242,"ASSERTION FAILED: %s at %s:%d.", "!(hypervisor_shared_info == ((void *)0))" , "src/hypervisor.c", 242); micropv_exit(); } } while(0);
    xenevents_init();
    xenconsole_init();
    xentime_init();
    xenstore_init();
    xengnttab_init();
    xenscheduler_init();
}

variable_types:
status
unsigned long

user_defined_types: struct start_info { char magic[32]; unsigned long nr_pages; unsigned long shared_info; unsigned int flags; unsigned long store_mfn; unsigned int store_evtchn; union { struct { unsigned long mfn; unsigned int evtchn; } domU; struct { unsigned int info_off; unsigned int info_size; } dom0; } console; unsigned long pt_base; unsigned long nr_pt_frames; unsigned long mfn_list; unsigned long mod_start; unsigned long mod_len; char cmd_line[1024]; unsigned long first_p2m_pfn; unsigned long nr_p2m_frames; }