repo: zrho/Hydrogen

decompiled_code:
__int64 kernel_find()
{
__int64 v0; // r12
unsigned __int16 *v1; // rbp
char *v2; // rbx
__int64 result; // rax

if ( !*(_WORD *)(info_root + 156LL) )
{
LABEL_5:
screen_write("PANIC: Could not find kernel binary.", 0LL, 3LL);
while ( 1 )
;
}
v0 = 0LL;
while ( 1 )
{
v1 = (unsigned __int16 *)(info_module + 16 * v0);
v2 = (char *)(info_strings + *v1);
if ( v2 == strstr(v2, "kernel64") )
break;
if ( *(unsigned __int16 *)(info_root + 156LL) <= (unsigned __int64)++v0 )
goto LABEL_5;
}
result = *(_QWORD *)(v1 + 1);
kernel_binary = result;
return result;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 v0; // r12
unsigned __int16 *v1; // rbp
char *v2; // rbx
__int64 result; // rax

if ( !*(_WORD *)(info_root + 156LL) )
{
LABEL_5:
screen_write("PANIC: Could not find kernel binary.", 0LL, 3LL);
while ( 1 )
;
}
v0 = 0LL;
while ( 1 )
{
v1 = (unsigned __int16 *)(info_module + 16 * v0);
v2 = (char *)(info_strings + *v1);
if ( v2 == strstr(v2, "kernel64") )
break;
if ( *(unsigned __int16 *)(info_root + 156LL) <= (unsigned __int64)++v0 )
goto LABEL_5;
}
result = *(_QWORD *)(v1 + 1);
kernel_binary = result;
return result;
}

original_code:
void kernel_find(void)
{
    size_t i;
    for (i = 0; i < info_root->module_count; ++i) {
        hy_info_module_t *mod = &info_module[i];
        char *name = &info_strings[mod->name];
        if (strstr(name, "kernel64") == name) {
            kernel_binary = (void *) mod->address;
            return;
        }
    }
    do { screen_write("PANIC: " "Could not find kernel binary.", 0, 3); while (1); } while (0);;
}

canonical_original_code:
void kernel_find()
{
    unsigned long long i;
    for (i = 0; i < info_root->module_count; ++i) {
        struct hy_info_module *mod = &info_module[i];
        char *name = &info_strings[mod->name];
        if (strstr(name, "kernel64") == name) {
            kernel_binary = (void *) mod->address;
            return;
        }
    }
    do { screen_write("PANIC: " "Could not find kernel binary.", 0, 3); while (1); } while (0);;
}

variable_types:
i
unsigned long long

variable_types: struct hy_info_module { unsigned short name; unsigned long long address; unsigned int length; unsigned short padding; } *

variable_types:
name
char *


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

result = kernel_binary;
if ( *(_DWORD *)kernel_binary != 1179403647
|| *(_BYTE *)(kernel_binary + 4) != 2
|| *(_WORD *)(kernel_binary + 16) != 2 )
{
screen_write("PANIC: Kernel is not an ELF64 executable.", 0LL, 3LL);
while ( 1 )
;
}
return result;
}

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

result = kernel_binary;
if ( *(_DWORD *)kernel_binary != 1179403647
|| *(_BYTE *)(kernel_binary + 4) != 2
|| *(_WORD *)(kernel_binary + 16) != 2 )
{
screen_write("PANIC: Kernel is not an ELF64 executable.", 0LL, 3LL);
while ( 1 )
;
}
return result;
}

original_code:
void kernel_check(void)
{
    elf64_ehdr_t *ehdr = (elf64_ehdr_t *) kernel_binary;
    if (ehdr->e_ident_mag != 0x464C457F ||
        ehdr->e_ident_class != 2 ||
        ehdr->e_type != 2) {
        do { screen_write("PANIC: " "Kernel is not an ELF64 executable.", 0, 3); while (1); } while (0);;
    }
}

canonical_original_code:
void kernel_check()
{
    struct elf64_ehdr *ehdr = (elf64_ehdr_t *) kernel_binary;
    if (ehdr->e_ident_mag != 0x464C457F ||
        ehdr->e_ident_class != 2 ||
        ehdr->e_type != 2) {
        do { screen_write("PANIC: " "Kernel is not an ELF64 executable.", 0, 3); while (1); } while (0);;
    }
}

variable_types: struct elf64_ehdr { unsigned int e_ident_mag; unsigned char e_ident_class; unsigned char e_ident_data; unsigned char e_ident_version; unsigned char e_ident_osabi; unsigned char e_ident_abiversion; unsigned char e_ident_pad[7]; unsigned short e_type; unsigned short e_machine; unsigned int e_version; unsigned long long e_entry; unsigned long long e_phoff; unsigned long long e_shoff; unsigned int e_flags; unsigned short e_ehsize; unsigned short e_phsize; unsigned short e_phnum; unsigned short e_shentsize; unsigned short e_shnum; unsigned short e_shstrndx; } *

return_type: void


decompiled_code:
_DWORD *kernel_analyze()
{
__int64 v0; // rax
_DWORD *result; // rax

v0 = elf64_sym_find("hydrogen_header", kernel_binary);
if ( !v0 )
{
screen_write("PANIC: The kernel binary does not provide a Hydrogen header.", 0LL, 3LL);
while ( 1 )
;
}
result = *(_DWORD **)(v0 + 8);
kernel_header = (__int64)result;
if ( *result != 1380211016 )
{
screen_write("PANIC: Invalid magic value in kernel header.", 0LL, 3LL);
while ( 1 )
;
}
return result;
}

canonical_decompiled_code:
_DWORD *func2()
{
__int64 v0; // rax
_DWORD *result; // rax

v0 = elf64_sym_find("hydrogen_header", kernel_binary);
if ( !v0 )
{
screen_write("PANIC: The kernel binary does not provide a Hydrogen header.", 0LL, 3LL);
while ( 1 )
;
}
result = *(_DWORD **)(v0 + 8);
kernel_header = (__int64)result;
if ( *result != 1380211016 )
{
screen_write("PANIC: Invalid magic value in kernel header.", 0LL, 3LL);
while ( 1 )
;
}
return result;
}

original_code:
void kernel_analyze(void)
{
    elf64_sym_t *sym = elf64_sym_find("hydrogen_header", kernel_binary);
    if (0 == sym) {
        do { screen_write("PANIC: " "The kernel binary does not provide a Hydrogen header.", 0, 3); while (1); } while (0);;
    }
    kernel_header = (hy_header_root_t *) sym->st_value;
    if (kernel_header->magic != 0x52445948) {
        do { screen_write("PANIC: " "Invalid magic value in kernel header.", 0, 3); while (1); } while (0);;
    }
}

canonical_original_code:
void kernel_analyze()
{
    struct elf64_sym *sym = elf64_sym_find("hydrogen_header", kernel_binary);
    if (0 == sym) {
        do { screen_write("PANIC: " "The kernel binary does not provide a Hydrogen header.", 0, 3); while (1); } while (0);;
    }
    kernel_header = (struct hy_header_root *) sym->st_value;
    if (kernel_header->magic != 0x52445948) {
        do { screen_write("PANIC: " "Invalid magic value in kernel header.", 0, 3); while (1); } while (0);;
    }
}

variable_types: struct elf64_sym { unsigned int st_name; unsigned char st_info; unsigned char st_other; unsigned short st_shndx; unsigned long long st_value; unsigned long long st_size; } *

user_defined_types: struct hy_header_root { unsigned int magic; unsigned int flags; unsigned long long stack_vaddr; unsigned long long info_vaddr; unsigned long long idt_vaddr; unsigned long long gdt_vaddr; unsigned long long ap_entry; unsigned long long syscall_entry; unsigned long long isr_entry_table; struct hy_header_irq irqs[16]; }

user_defined_types: struct hy_header_irq { unsigned char flags; unsigned char vector; }


decompiled_code:
_BYTE *kernel_map_stack()
{
_BYTE *result; // rax
__int64 v1; // rbx
__int64 v2; // rsi
_BYTE v3[24]; // [rsp+0h] [rbp-18h] BYREF

result = (_BYTE *)kernel_header;
v1 = *(_QWORD *)(kernel_header + 8);
if ( v1 )
{
if ( (v1 & 0xFFF) != 0 )
{
screen_write("PANIC: Virtual stack address in kernel header not page-aligned.", 0LL, 3LL);
while ( 1 )
;
}
v2 = v1 + ((unsigned int)lapic_id() << 12);
page_map(v3, v2, 258LL);
result = &v3[v2 - ((unsigned __int64)&v3[-1] & 0xFFFFFFFFFFFFF000LL)];
}
return result;
}

canonical_decompiled_code:
_BYTE *func3()
{
_BYTE *result; // rax
__int64 v1; // rbx
__int64 v2; // rsi
_BYTE v3[24]; // [rsp+0h] [rbp-18h] BYREF

result = (_BYTE *)kernel_header;
v1 = *(_QWORD *)(kernel_header + 8);
if ( v1 )
{
if ( (v1 & 0xFFF) != 0 )
{
screen_write("PANIC: Virtual stack address in kernel header not page-aligned.", 0LL, 3LL);
while ( 1 )
;
}
v2 = v1 + ((unsigned int)lapic_id() << 12);
page_map(v3, v2, 258LL);
result = &v3[v2 - ((unsigned __int64)&v3[-1] & 0xFFFFFFFFFFFFF000LL)];
}
return result;
}

original_code:
void kernel_map_stack(void)
{
    if (0 == kernel_header->stack_vaddr)
        return;
    if (0 != (kernel_header->stack_vaddr & 0xFFF)) {
        do { screen_write("PANIC: " "Virtual stack address in kernel header not page-aligned.", 0, 3); while (1); } while (0);;
    }
    uintptr_t stack_begin, stack_address, stack_offset;
    asm volatile ("mov %%rsp, %0" : "=a" (stack_address));
    stack_begin = (stack_address - 1) & ~0xFFF;
    stack_offset = stack_address - stack_begin;
    uintptr_t stack_target = kernel_header->stack_vaddr + 0x1000 * lapic_id();
    page_map(stack_address, stack_target, (1 << 1) | (1 << 8));
    asm volatile ("mov %0, %%rsp" :: "a" (stack_target + stack_offset));
}

canonical_original_code:
void kernel_map_stack()
{
    if (0 == kernel_header->stack_vaddr)
        return;
    if (0 != (kernel_header->stack_vaddr & 0xFFF)) {
        do { screen_write("PANIC: " "Virtual stack address in kernel header not page-aligned.", 0, 3); while (1); } while (0);;
    }
    unsigned long long stack_begin; unsigned long long stack_address; unsigned long long stack_offset;
    asm volatile ("mov %%rsp, %0" : "=a" (stack_address));
    stack_begin = (stack_address - 1) & ~0xFFF;
    stack_offset = stack_address - stack_begin;
    unsigned long long stack_target = kernel_header->stack_vaddr + 0x1000 * lapic_id();
    page_map(stack_address, stack_target, (1 << 1) | (1 << 8));
    asm volatile ("mov %0, %%rsp" :: "a" (stack_target + stack_offset));
}


decompiled_code:
void *kernel_map_info()
{
void *result; // rax
__int64 v1; // rbp
__int64 v2; // r12
unsigned __int64 v3; // r13
unsigned __int64 v4; // rbx

result = (void *)kernel_header;
v1 = *(_QWORD *)(kernel_header + 16);
if ( v1 )
{
result = &info_root;
v2 = info_root;
v3 = *(unsigned __int16 *)(info_root + 8LL);
if ( *(_WORD *)(info_root + 8LL) )
{
v4 = 0LL;
do
{
result = (void *)page_map(v2 + v4, v1 + v4, 258LL);
v4 += 4096LL;
}
while ( v3 > v4 );
}
}
return result;
}

canonical_decompiled_code:
void *func4()
{
void *result; // rax
__int64 v1; // rbp
__int64 v2; // r12
unsigned __int64 v3; // r13
unsigned __int64 v4; // rbx

result = (void *)kernel_header;
v1 = *(_QWORD *)(kernel_header + 16);
if ( v1 )
{
result = &info_root;
v2 = info_root;
v3 = *(unsigned __int16 *)(info_root + 8LL);
if ( *(_WORD *)(info_root + 8LL) )
{
v4 = 0LL;
do
{
result = (void *)page_map(v2 + v4, v1 + v4, 258LL);
v4 += 4096LL;
}
while ( v3 > v4 );
}
}
return result;
}

original_code:
void kernel_map_info(void)
{
    if (0 == kernel_header->info_vaddr)
        return;
    size_t length = info_root->length;
    size_t offset;
    uintptr_t physical = (uintptr_t) info_root;
    uintptr_t virtual = kernel_header->info_vaddr;
    for (offset = 0; offset < length; offset += 0x1000) {
        page_map(physical + offset, virtual + offset, (1 << 1) | (1 << 8));
    }
}

canonical_original_code:
void kernel_map_info()
{
    if (0 == kernel_header->info_vaddr)
        return;
    unsigned long long length = info_root->length;
    unsigned long long offset;
    unsigned long long physical = (uintptr_t) info_root;
    unsigned long long virtual = kernel_header->info_vaddr;
    for (offset = 0; offset < length; offset += 0x1000) {
        page_map(physical + offset, virtual + offset, (1 << 1) | (1 << 8));
    }
}

variable_types:
length
unsigned long long

variable_types:
offset
unsigned long long

variable_types:
physical
unsigned long long

variable_types:
virtual
unsigned long long


decompiled_code:
__int64 kernel_map_idt()
{
__int64 result; // rax
__int64 v1; // rsi

result = kernel_header;
v1 = *(_QWORD *)(kernel_header + 24);
if ( v1 )
{
page_map(&idt_data, v1, 258LL);
result = *(_QWORD *)(kernel_header + 24);
idt_address = result;
}
return result;
}

canonical_decompiled_code:
__int64 func5()
{
__int64 result; // rax
__int64 v1; // rsi

result = kernel_header;
v1 = *(_QWORD *)(kernel_header + 24);
if ( v1 )
{
page_map(&idt_data, v1, 258LL);
result = *(_QWORD *)(kernel_header + 24);
idt_address = result;
}
return result;
}

original_code:
void kernel_map_idt(void)
{
    if (0 == kernel_header->idt_vaddr)
        return;
    uintptr_t phys = (uintptr_t) &idt_data;
    page_map(
        phys,
        kernel_header->idt_vaddr,
        (1 << 1) | (1 << 8));
    idt_address = kernel_header->idt_vaddr;
}

canonical_original_code:
void kernel_map_idt()
{
    if (0 == kernel_header->idt_vaddr)
        return;
    unsigned long long phys = (uintptr_t) &idt_data;
    page_map(
        phys,
        kernel_header->idt_vaddr,
        (1 << 1) | (1 << 8));
    idt_address = kernel_header->idt_vaddr;
}

variable_types:
phys
unsigned long long


decompiled_code:
__int64 kernel_map_gdt()
{
__int64 result; // rax
__int64 v1; // rsi

result = kernel_header;
v1 = *(_QWORD *)(kernel_header + 32);
if ( v1 )
{
page_map(*(_QWORD *)((char *)&gdt_pointer + 2), v1, 258LL);
result = *(_QWORD *)(kernel_header + 32);
*(_QWORD *)((char *)&gdt_pointer + 2) = result;
}
return result;
}

canonical_decompiled_code:
__int64 func6()
{
__int64 result; // rax
__int64 v1; // rsi

result = kernel_header;
v1 = *(_QWORD *)(kernel_header + 32);
if ( v1 )
{
page_map(*(_QWORD *)((char *)&gdt_pointer + 2), v1, 258LL);
result = *(_QWORD *)(kernel_header + 32);
*(_QWORD *)((char *)&gdt_pointer + 2) = result;
}
return result;
}

original_code:
void kernel_map_gdt(void)
{
    if (0 == kernel_header->gdt_vaddr)
        return;
    uintptr_t phys = gdt_pointer.address;
    page_map(
        phys,
        kernel_header->gdt_vaddr,
        (1 << 1) | (1 << 8));
    gdt_pointer.address = kernel_header->gdt_vaddr;
}

canonical_original_code:
void kernel_map_gdt()
{
    if (0 == kernel_header->gdt_vaddr)
        return;
    unsigned long long phys = gdt_pointer.address;
    page_map(
        phys,
        kernel_header->gdt_vaddr,
        (1 << 1) | (1 << 8));
    gdt_pointer.address = kernel_header->gdt_vaddr;
}


decompiled_code:
__int64 kernel_enter_bsp()
{
return kernel_enter(*(_QWORD *)(kernel_binary + 24));
}

canonical_decompiled_code:
__int64 func7()
{
return kernel_enter(*(_QWORD *)(kernel_binary + 24));
}

original_code:
void kernel_enter_bsp(void)
{
    kernel_enter(((elf64_ehdr_t *) kernel_binary)->e_entry);
}

canonical_original_code:
void kernel_enter_bsp()
{
    kernel_enter(((struct elf64_ehdr *) kernel_binary)->e_entry);
}

user_defined_types: struct elf64_ehdr { unsigned int e_ident_mag; unsigned char e_ident_class; unsigned char e_ident_data; unsigned char e_ident_version; unsigned char e_ident_osabi; unsigned char e_ident_abiversion; unsigned char e_ident_pad[7]; unsigned short e_type; unsigned short e_machine; unsigned int e_version; unsigned long long e_entry; unsigned long long e_phoff; unsigned long long e_shoff; unsigned int e_flags; unsigned short e_ehsize; unsigned short e_phsize; unsigned short e_phnum; unsigned short e_shentsize; unsigned short e_shnum; unsigned short e_shstrndx; }


decompiled_code:
__int64 kernel_enter_ap()
{
__int64 v0; // rdi

v0 = *(_QWORD *)(kernel_header + 40);
if ( !v0 )
__halt();
return kernel_enter(v0);
}

canonical_decompiled_code:
__int64 func8()
{
__int64 v0; // rdi

v0 = *(_QWORD *)(kernel_header + 40);
if ( !v0 )
__halt();
return kernel_enter(v0);
}

original_code:
void kernel_enter_ap(void)
{
    if (0 == kernel_header->ap_entry) {
        while (1) { asm volatile ("hlt"); }
    } else {
        kernel_enter(kernel_header->ap_entry);
    }
}

canonical_original_code:
void kernel_enter_ap()
{
    if (0 == kernel_header->ap_entry) {
        while (1) { asm volatile ("hlt"); }
    } else {
        kernel_enter(kernel_header->ap_entry);
    }
}


decompiled_code:
__int64 main_bsp()
{
__int64 v0; // rbp
unsigned int v1; // eax

screen_write("Hydrogen v0.2b - http://github.com/farok/H2", 0LL, 0LL);
screen_write("Copyright (c) 2012 by Lukas Heidemann", 0LL, 1LL);
screen_write("-------------------------------------------------", 0LL, 2LL);
idt_load(idt_address, 4096LL);
idt_setup_loader();
info_init();
multiboot_parse();
heap_init();
acpi_parse();
ioapic_analyze();
kernel_find();
kernel_check();
elf64_load(kernel_binary);
kernel_analyze();
lapic_detect();
lapic_setup();
ioapic_setup_loader();
pic_setup();
lapic_timer_calibrate();
v0 = info_cpu;
v1 = lapic_id();
*(_WORD *)(info_cpu + 18LL * v1 + 8) = *(_WORD *)(v0 + 18LL * v1 + 8) | 2;
smp_setup();
idt_setup_kernel();
ioapic_setup_kernel();
syscall_init();
kernel_map_info();
kernel_map_stack();
kernel_map_idt();
kernel_map_gdt();
*(_QWORD *)(info_root + 50LL) = (heap_top + 4095LL) & 0xFFFFFFFFFFFFF000LL;
main_entry_barrier = 0;
return kernel_enter_bsp();
}

canonical_decompiled_code:
__int64 func0()
{
__int64 v0; // rbp
unsigned int v1; // eax

screen_write("Hydrogen v0.2b - http://github.com/farok/H2", 0LL, 0LL);
screen_write("Copyright (c) 2012 by Lukas Heidemann", 0LL, 1LL);
screen_write("-------------------------------------------------", 0LL, 2LL);
idt_load(idt_address, 4096LL);
idt_setup_loader();
info_init();
multiboot_parse();
heap_init();
acpi_parse();
ioapic_analyze();
kernel_find();
kernel_check();
elf64_load(kernel_binary);
kernel_analyze();
lapic_detect();
lapic_setup();
ioapic_setup_loader();
pic_setup();
lapic_timer_calibrate();
v0 = info_cpu;
v1 = lapic_id();
*(_WORD *)(info_cpu + 18LL * v1 + 8) = *(_WORD *)(v0 + 18LL * v1 + 8) | 2;
smp_setup();
idt_setup_kernel();
ioapic_setup_kernel();
syscall_init();
kernel_map_info();
kernel_map_stack();
kernel_map_idt();
kernel_map_gdt();
*(_QWORD *)(info_root + 50LL) = (heap_top + 4095LL) & 0xFFFFFFFFFFFFF000LL;
main_entry_barrier = 0;
return kernel_enter_bsp();
}

original_code:
void main_bsp(void)
{
    screen_write("Hydrogen v0.2b - http://github.com/farok/H2", 0, 0);
    screen_write("Copyright (c) 2012 by Lukas Heidemann", 0, 1);
    screen_write("-------------------------------------------------", 0, 2);
    idt_load(idt_address, 0x1000);
    idt_setup_loader();
    info_init();
    multiboot_parse();
    heap_init();
    acpi_parse();
    ioapic_analyze();
    kernel_find();
    kernel_check();
    elf64_load(kernel_binary);
    kernel_analyze();
    lapic_detect();
    lapic_setup();
    ioapic_setup_loader();
    pic_setup();
    lapic_timer_calibrate();
    info_cpu[lapic_id()].flags |= (1 << 1);
    smp_setup();
    idt_setup_kernel();
    ioapic_setup_kernel();
    syscall_init();
    kernel_map_info();
    kernel_map_stack();
    kernel_map_idt();
    kernel_map_gdt();
    info_root->free_paddr = (heap_top + 0xFFF) & ~0xFFF;
    main_entry_barrier = 0;
    kernel_enter_bsp();
}

canonical_original_code:
void main_bsp()
{
    screen_write("Hydrogen v0.2b - http://github.com/farok/H2", 0, 0);
    screen_write("Copyright (c) 2012 by Lukas Heidemann", 0, 1);
    screen_write("-------------------------------------------------", 0, 2);
    idt_load(idt_address, 0x1000);
    idt_setup_loader();
    info_init();
    multiboot_parse();
    heap_init();
    acpi_parse();
    ioapic_analyze();
    kernel_find();
    kernel_check();
    elf64_load(kernel_binary);
    kernel_analyze();
    lapic_detect();
    lapic_setup();
    ioapic_setup_loader();
    pic_setup();
    lapic_timer_calibrate();
    info_cpu[lapic_id()].flags |= (1 << 1);
    smp_setup();
    idt_setup_kernel();
    ioapic_setup_kernel();
    syscall_init();
    kernel_map_info();
    kernel_map_stack();
    kernel_map_idt();
    kernel_map_gdt();
    info_root->free_paddr = (heap_top + 0xFFF) & ~0xFFF;
    main_entry_barrier = 0;
    kernel_enter_bsp();
}


decompiled_code:
__int64 main_ap()
{
idt_load(&idt_data, 4096LL);
lapic_setup();
lapic_timer_calibrate();
kernel_map_stack();
syscall_init();
++smp_ready_count;
while ( main_entry_barrier == 1 )
;
return kernel_enter_ap(&idt_data, 4096LL, &main_entry_barrier);
}

canonical_decompiled_code:
__int64 func1()
{
idt_load(&idt_data, 4096LL);
lapic_setup();
lapic_timer_calibrate();
kernel_map_stack();
syscall_init();
++smp_ready_count;
while ( main_entry_barrier == 1 )
;
return kernel_enter_ap(&idt_data, 4096LL, &main_entry_barrier);
}

original_code:
void main_ap(void)
{
    idt_load((uintptr_t) &idt_data, 0x1000);
    lapic_setup();
    lapic_timer_calibrate();
    kernel_map_stack();
    syscall_init();
    ++smp_ready_count;
    while (main_entry_barrier == 1);
    kernel_enter_ap();
}

canonical_original_code:
void main_ap()
{
    idt_load((unsigned long long) &idt_data, 0x1000);
    lapic_setup();
    lapic_timer_calibrate();
    kernel_map_stack();
    syscall_init();
    ++smp_ready_count;
    while (main_entry_barrier == 1);
    kernel_enter_ap();
}


original_code:
void syscall_init(void)
{
    cpu_msr_write(0xC0000081, (((uint64_t) 0x8 << 32) | ((uint64_t) 0x18 << 48)));
    cpu_msr_write(0xC0000084, (1 << 9));
    cpu_msr_write(0xC0000083, 0);
    cpu_msr_write(0xC0000082, kernel_header->syscall_entry);
}

canonical_original_code:
void syscall_init()
{
    cpu_msr_write(0xC0000081, (((unsigned long long) 0x8 << 32) | ((unsigned long long) 0x18 << 48)));
    cpu_msr_write(0xC0000084, (1 << 9));
    cpu_msr_write(0xC0000083, 0);
    cpu_msr_write(0xC0000082, kernel_header->syscall_entry);
}


decompiled_code:
__int64 __fastcall ioapic_irq_by_gsi(int a1)
{
__int64 v1; // rdx

v1 = 0LL;
while ( *(_DWORD *)(info_root + 4 * v1 + 58) != a1 )
{
if ( ++v1 == 16 )
return 0xFFFFFFFFLL;
}
return (unsigned int)v1;
}

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

v1 = 0LL;
while ( *(_DWORD *)(info_root + 4 * v1 + 58) != a1 )
{
if ( ++v1 == 16 )
return 0xFFFFFFFFLL;
}
return (unsigned int)v1;
}

original_code:
static int8_t ioapic_irq_by_gsi(uint32_t gsi)
{
    size_t irq;
    for (irq = 0; irq < 16; ++irq) {
        if (info_root->irq_gsi[irq] == gsi) {
            return irq;
        }
    }
    return -1;
}

canonical_original_code:
static char ioapic_irq_by_gsi(unsigned int gsi)
{
    unsigned long long irq;
    for (irq = 0; irq < 16; ++irq) {
        if (info_root->irq_gsi[irq] == gsi) {
            return irq;
        }
    }
    return -1;
}

variable_types:
gsi
unsigned int

variable_types:
irq
unsigned long long

return_type: char


decompiled_code:
__int64 __fastcall ioapic_get_by_gsi(unsigned int a1)
{
__int64 v1; // rax
__int64 v2; // rcx
__int64 v3; // r9
unsigned int v4; // esi

if ( !*(_WORD *)(info_root + 152LL) )
return 0LL;
v1 = info_ioapic;
v2 = 0LL;
while ( 1 )
{
v3 = v1;
v4 = *(_DWORD *)(v1 + 2);
if ( v4 + *(unsigned __int16 *)(v1 + 6) > a1 && v4 <= a1 )
break;
++v2;
v1 += 16LL;
if ( v2 == *(unsigned __int16 *)(info_root + 152LL) )
return 0LL;
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1)
{
__int64 v1; // rax
__int64 v2; // rcx
__int64 v3; // r9
unsigned int v4; // esi

if ( !*(_WORD *)(info_root + 152LL) )
return 0LL;
v1 = info_ioapic;
v2 = 0LL;
while ( 1 )
{
v3 = v1;
v4 = *(_DWORD *)(v1 + 2);
if ( v4 + *(unsigned __int16 *)(v1 + 6) > a1 && v4 <= a1 )
break;
++v2;
v1 += 16LL;
if ( v2 == *(unsigned __int16 *)(info_root + 152LL) )
return 0LL;
}
return v3;
}

original_code:
hy_info_ioapic_t *ioapic_get_by_gsi(uint32_t gsi)
{
    size_t i;
    for (i = 0; i < info_root->ioapic_count; ++i) {
        hy_info_ioapic_t *ioapic = &info_ioapic[i];
        uint32_t start = ioapic->gsi_base;
        uint32_t end = start + ioapic->gsi_count;
        if (gsi >= start && gsi < end)
            return ioapic;
    }
    return 0;
}

canonical_original_code:
struct hy_info_ioapic *ioapic_get_by_gsi(unsigned int gsi)
{
    unsigned long long i;
    for (i = 0; i < info_root->ioapic_count; ++i) {
        struct hy_info_ioapic *ioapic = &info_ioapic[i];
        unsigned int start = ioapic->gsi_base;
        unsigned int end = start + ioapic->gsi_count;
        if (gsi >= start && gsi < end)
            return ioapic;
    }
    return 0;
}

variable_types: struct hy_info_ioapic { unsigned char apic_id; unsigned char version; unsigned int gsi_base; unsigned short gsi_count; unsigned long long mmio_paddr; } *

variable_types:
start
unsigned int

variable_types:
end
unsigned int


decompiled_code:
__int64 __fastcall ioapic_register_read(unsigned __int16 a1, __int64 a2)
{
**(_DWORD **)(a2 + 8) = a1;
return *(unsigned int *)(*(_QWORD *)(a2 + 8) + 16LL);
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned __int16 a1, __int64 a2)
{
**(_DWORD **)(a2 + 8) = a1;
return *(unsigned int *)(*(_QWORD *)(a2 + 8) + 16LL);
}

original_code:
uint32_t ioapic_register_read(uint16_t index, hy_info_ioapic_t *ioapic)
{
    *(uint32_t *) ((ioapic)->mmio_paddr + 0x0) = index;
    return *(uint32_t *)((ioapic)->mmio_paddr + 0x10);
}

canonical_original_code:
unsigned int ioapic_register_read(unsigned short index, struct hy_info_ioapic *ioapic)
{
    *(unsigned int *) ((ioapic)->mmio_paddr + 0x0) = index;
    return *(unsigned int *)((ioapic)->mmio_paddr + 0x10);
}

variable_types:
index
unsigned short

return_type: unsigned int

user_defined_types: struct hy_info_ioapic { unsigned char apic_id; unsigned char version; unsigned int gsi_base; unsigned short gsi_count; unsigned long long mmio_paddr; }


decompiled_code:
__int64 __fastcall ioapic_register_write(unsigned __int16 a1, int a2, __int64 a3)
{
__int64 v3; // rax
unsigned int v4; // edx

**(_DWORD **)(a3 + 8) = a1;
v3 = *(_QWORD *)(a3 + 8);
v4 = *(_DWORD *)(v3 + 16);
*(_DWORD *)(v3 + 16) = a2;
return v4;
}

original_code:
uint32_t ioapic_register_write(uint16_t index, uint32_t value, hy_info_ioapic_t *ioapic)
{
    *(uint32_t *) ((ioapic)->mmio_paddr + 0x0) = index;
    uint32_t old = *(uint32_t *)((ioapic)->mmio_paddr + 0x10);
    *(uint32_t *)((ioapic)->mmio_paddr + 0x10) = value;
    return old;
}

canonical_original_code:
unsigned int ioapic_register_write(unsigned short index, unsigned int value, struct hy_info_ioapic *ioapic)
{
    *(unsigned int *) ((ioapic)->mmio_paddr + 0x0) = index;
    unsigned int old = *(uint32_t *)((ioapic)->mmio_paddr + 0x10);
    *(unsigned int *)((ioapic)->mmio_paddr + 0x10) = value;
    return old;
}

variable_types:
value
unsigned int

variable_types:
old
unsigned int


decompiled_code:
unsigned __int64 __fastcall ioapic_redir_get(__int16 a1, __int64 a2)
{
unsigned int v2; // ebp

v2 = ioapic_register_read(2 * a1 + 16, a2);
return v2 | (unsigned __int64)(ioapic_register_read(2 * a1 + 17, a2) << 32);
}

canonical_decompiled_code:
unsigned __int64 __fastcall func4(__int16 a1, __int64 a2)
{
unsigned int v2; // ebp

v2 = func2(2 * a1 + 16, a2);
return v2 | (unsigned __int64)(func2(2 * a1 + 17, a2) << 32);
}

original_code:
uint64_t ioapic_redir_get(uint16_t index, hy_info_ioapic_t *ioapic)
{
    uint16_t register_index = 0x10 + index * 2;
    uint32_t low = ioapic_register_read(register_index, ioapic);
    uint32_t high = ioapic_register_read(register_index + 1, ioapic);
    return low | ((uint64_t) high << 32);
}

canonical_original_code:
unsigned long long ioapic_redir_get(unsigned short index, struct hy_info_ioapic *ioapic)
{
    unsigned short register_index = 0x10 + index * 2;
    unsigned int low = ioapic_register_read(register_index, ioapic);
    unsigned int high = ioapic_register_read(register_index + 1, ioapic);
    return low | ((unsigned long long) high << 32);
}

variable_types:
low
unsigned int

variable_types:
high
unsigned int

return_type: unsigned long long


decompiled_code:
__int64 __fastcall ioapic_redir_set(__int16 a1, __int64 a2, __int64 a3)
{
ioapic_register_write(2 * a1 + 16, a2, a3);
return ioapic_register_write(2 * a1 + 17, SHIDWORD(a2), a3);
}

original_code:
void ioapic_redir_set(uint16_t index, uint64_t redir, hy_info_ioapic_t *ioapic)
{
    uint16_t register_index = 0x10 + index * 2;
    ioapic_register_write(register_index, redir, ioapic);
    ioapic_register_write(register_index + 1, redir >> 32, ioapic);
}

canonical_original_code:
void ioapic_redir_set(unsigned short index, unsigned long long redir, struct hy_info_ioapic *ioapic)
{
    unsigned short register_index = 0x10 + index * 2;
    ioapic_register_write(register_index, redir, ioapic);
    ioapic_register_write(register_index + 1, redir >> 32, ioapic);
}

variable_types:
redir
unsigned long long


decompiled_code:
unsigned __int64 ioapic_analyze()
{
unsigned __int64 result; // rax
unsigned __int64 v1; // rbp
__int64 v2; // rbx
__int64 v3; // rax

result = info_root;
if ( *(_WORD *)(info_root + 152LL) )
{
v1 = 0LL;
do
{
v2 = info_ioapic + 16 * v1;
v3 = ioapic_register_read(1u, v2);
*(_BYTE *)(v2 + 1) = v3;
*(_WORD *)(v2 + 6) = BYTE2(v3) + 1;
++v1;
result = *(unsigned __int16 *)(info_root + 152LL);
}
while ( result > v1 );
}
return result;
}

canonical_decompiled_code:
unsigned __int64 func6()
{
unsigned __int64 result; // rax
unsigned __int64 v1; // rbp
__int64 v2; // rbx
__int64 v3; // rax

result = info_root;
if ( *(_WORD *)(info_root + 152LL) )
{
v1 = 0LL;
do
{
v2 = info_ioapic + 16 * v1;
v3 = func2(1u, v2);
*(_BYTE *)(v2 + 1) = v3;
*(_WORD *)(v2 + 6) = BYTE2(v3) + 1;
++v1;
result = *(unsigned __int16 *)(info_root + 152LL);
}
while ( result > v1 );
}
return result;
}

original_code:
void ioapic_analyze(void)
{
    size_t i;
    for (i = 0; i < info_root->ioapic_count; ++i) {
        hy_info_ioapic_t *ioapic = &info_ioapic[i];
        uint32_t version_reg = ioapic_register_read(0x01, ioapic);
        uint8_t version = version_reg & 0xFF;
        uint8_t max_entry = (version_reg >> 16) & 0xFF;
        ioapic->version = version;
        ioapic->gsi_count = max_entry + 1;
    }
}

canonical_original_code:
void ioapic_analyze()
{
    unsigned long long i;
    for (i = 0; i < info_root->ioapic_count; ++i) {
        struct hy_info_ioapic *ioapic = &info_ioapic[i];
        unsigned int version_reg = ioapic_register_read(0x01, ioapic);
        unsigned char version = version_reg & 0xFF;
        unsigned char max_entry = (version_reg >> 16) & 0xFF;
        ioapic->version = version;
        ioapic->gsi_count = max_entry + 1;
    }
}

variable_types:
i
unsigned long long

variable_types:
version
unsigned char


original_code:
uint64_t ioapic_redir_forge(uint32_t gsi, bool kernel)
{
    uint64_t redir = ( (0b000 << 8) | (1 << 16) | (0 << 11) );
    if (kernel) {
        redir = (0 == (kernel_header->flags & (1 << 0)))
                ? ( (0b001 << 8) | (1 << 11) | ((uint64_t) 0xFF << 56) ) : ( (0b000 << 8) | (0 << 11) );
    }
    int8_t irq = ioapic_irq_by_gsi(gsi);
    if (irq >= 0) {
        uint8_t flags = info_root->irq_flags[(size_t) irq];
        if (0 != ((1 << 0) & flags)) {
            redir |= (1 << 13);
        } else {
            redir |= (0 << 13);
        }
        redir |= (0 << 13);
        if (0 != ((1 << 1) & flags)) {
            redir |= (1 << 15);
        } else {
            redir |= (0 << 15);
        }
    } else {
        redir |= (1 << 15);
        redir |= (1 << 13);
    }
    if (kernel) {
        bool mask = 1;
        uint8_t vector = 0;
        if (irq >= 0) {
            hy_header_irq_t *config = &kernel_header->irqs[(size_t) irq];
            mask = (0 != (config->flags & (1 << 0)));
            vector = config->vector;
        }
        redir |= ((uint64_t) mask << 16);
        redir |= vector;
    } else {
        redir |= (1 << 16);
    }
    return redir;
}

canonical_original_code:
unsigned long long ioapic_redir_forge(unsigned int gsi, char kernel)
{
    unsigned long long redir = ( (0b000 << 8) | (1 << 16) | (0 << 11) );
    if (kernel) {
        redir = (0 == (kernel_header->flags & (1 << 0)))
                ? ( (0b001 << 8) | (1 << 11) | ((unsigned long long) 0xFF << 56) ) : ( (0b000 << 8) | (0 << 11) );
    }
    char irq = ioapic_irq_by_gsi(gsi);
    if (irq >= 0) {
        unsigned char flags = info_root->irq_flags[(size_t) irq];
        if (0 != ((1 << 0) & flags)) {
            redir |= (1 << 13);
        } else {
            redir |= (0 << 13);
        }
        redir |= (0 << 13);
        if (0 != ((1 << 1) & flags)) {
            redir |= (1 << 15);
        } else {
            redir |= (0 << 15);
        }
    } else {
        redir |= (1 << 15);
        redir |= (1 << 13);
    }
    if (kernel) {
        char mask = 1;
        unsigned char vector = 0;
        if (irq >= 0) {
            struct hy_header_irq *config = &kernel_header->irqs[(size_t) irq];
            mask = (0 != (config->flags & (1 << 0)));
            vector = config->vector;
        }
        redir |= ((unsigned long long) mask << 16);
        redir |= vector;
    } else {
        redir |= (1 << 16);
    }
    return redir;
}

variable_types: kernel char

variable_types: irq char

variable_types:
flags
unsigned char

variable_types: mask char

variable_types:
vector
unsigned char

variable_types: struct hy_header_irq { unsigned char flags; unsigned char vector; } *


decompiled_code:
unsigned __int64 __fastcall ioapic_setup(char a1)
{
unsigned __int64 result; // rax
unsigned __int64 v2; // r15
__int64 v3; // rbp
unsigned __int64 v4; // rbx
__int64 v5; // rax

result = info_root;
if ( *(_WORD *)(info_root + 152LL) )
{
v2 = 0LL;
do
{
v3 = info_ioapic + 16 * v2;
if ( *(_WORD *)(v3 + 6) )
{
v4 = 0LL;
do
{
v5 = ioapic_redir_forge(*(_DWORD *)(v3 + 2) + (int)v4, a1);
ioapic_redir_set(v4++, v5, v3);
}
while ( *(unsigned __int16 *)(v3 + 6) > v4 );
}
++v2;
result = *(unsigned __int16 *)(info_root + 152LL);
}
while ( result > v2 );
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func8(char a1)
{
unsigned __int64 result; // rax
unsigned __int64 v2; // r15
__int64 v3; // rbp
unsigned __int64 v4; // rbx
__int64 v5; // rax

result = info_root;
if ( *(_WORD *)(info_root + 152LL) )
{
v2 = 0LL;
do
{
v3 = info_ioapic + 16 * v2;
if ( *(_WORD *)(v3 + 6) )
{
v4 = 0LL;
do
{
v5 = func7(*(_DWORD *)(v3 + 2) + (int)v4, a1);
func5(v4++, v5, v3);
}
while ( *(unsigned __int16 *)(v3 + 6) > v4 );
}
++v2;
result = *(unsigned __int16 *)(info_root + 152LL);
}
while ( result > v2 );
}
return result;
}

original_code:
static void ioapic_setup(bool kernel)
{
    size_t i, j;
    for (i = 0; i < info_root->ioapic_count; ++i) {
        hy_info_ioapic_t *ioapic = &info_ioapic[i];
        for (j = 0; j < ioapic->gsi_count; ++j) {
            uint32_t gsi = ioapic->gsi_base + j;
            ioapic_redir_set(j, ioapic_redir_forge(gsi, kernel), ioapic);
        }
    }
}

canonical_original_code:
static void ioapic_setup(char kernel)
{
    unsigned long long i; unsigned long long j;
    for (i = 0; i < info_root->ioapic_count; ++i) {
        struct hy_info_ioapic *ioapic = &info_ioapic[i];
        for (j = 0; j < ioapic->gsi_count; ++j) {
            unsigned int gsi = ioapic->gsi_base + j;
            ioapic_redir_set(j, ioapic_redir_forge(gsi, kernel), ioapic);
        }
    }
}

variable_types:
j
unsigned long long

variable_types: struct hy_info_ioapic { unsigned char apic_id; unsigned char version; unsigned int gsi_base; unsigned short gsi_count; unsigned long long mmio_paddr; } *

variable_types:
gsi
unsigned int


decompiled_code:
unsigned __int64 ioapic_setup_kernel()
{
return ioapic_setup(1);
}

canonical_decompiled_code:
unsigned __int64 func9()
{
return func8(1);
}

original_code:
void ioapic_setup_kernel(void)
{
    ioapic_setup(1);
}

canonical_original_code:
void ioapic_setup_kernel()
{
    ioapic_setup(1);
}


decompiled_code:
unsigned __int64 ioapic_setup_loader()
{
return ioapic_setup(0);
}

canonical_decompiled_code:
unsigned __int64 func10()
{
return func8(0);
}

original_code:
void ioapic_setup_loader(void)
{
    ioapic_setup(0);
}

canonical_original_code:
void ioapic_setup_loader()
{
    ioapic_setup(0);
}


decompiled_code:
void *heap_modules_sort()
{
void *result; // rax
unsigned __int64 v1; // rbp
unsigned __int64 v2; // r12
unsigned __int64 i; // rbx
char dest[16]; // [rsp+10h] [rbp-48h] BYREF

result = (void *)info_root;
v1 = *(unsigned __int16 *)(info_root + 156LL);
if ( v1 > 1 )
{
v2 = 1LL;
for ( i = 0LL; ; ++i )
{
while ( i < v1 )
;
if ( i != -1LL )
{
memcpy(dest, (const void *)(info_module + 16 * i), sizeof(dest));
memcpy((void *)(16 * i + info_module), (const void *)(info_module - 16LL), 0x10uLL);
result = memcpy((void *)(info_module - 16LL), dest, 0x10uLL);
if ( v2 >= v1 - 1 )
break;
}
++v2;
}
}
return result;
}

canonical_decompiled_code:
void *func0()
{
void *result; // rax
unsigned __int64 v1; // rbp
unsigned __int64 v2; // r12
unsigned __int64 i; // rbx
char dest[16]; // [rsp+10h] [rbp-48h] BYREF

result = (void *)info_root;
v1 = *(unsigned __int16 *)(info_root + 156LL);
if ( v1 > 1 )
{
v2 = 1LL;
for ( i = 0LL; ; ++i )
{
while ( i < v1 )
;
if ( i != -1LL )
{
memcpy(dest, (const void *)(info_module + 16 * i), sizeof(dest));
memcpy((void *)(16 * i + info_module), (const void *)(info_module - 16LL), 0x10uLL);
result = memcpy((void *)(info_module - 16LL), dest, 0x10uLL);
if ( v2 >= v1 - 1 )
break;
}
++v2;
}
}
return result;
}

original_code:
static void heap_modules_sort(void)
{
    size_t count = info_root->module_count;
    size_t i, j;
    if (count > 1) {
        for (i = 0; i < count - 1; ++i) {
            uintptr_t min_addr = 0;
            size_t min_idx = -1;
            for (j = i; i < count; ++j) {
                hy_info_module_t *mod = &info_module[j];
                if (mod->address < min_addr) {
                    min_idx = j;
                    min_addr = mod->address;
                }
            }
            if (i != min_idx) {
                hy_info_module_t tmp;
                memcpy(&tmp, &info_module[i], sizeof(hy_info_module_t));
                memcpy(&info_module[i], &info_module[min_idx], sizeof(hy_info_module_t));
                memcpy(&info_module[min_idx], &tmp, sizeof(hy_info_module_t));
            }
        }
    }
}

canonical_original_code:
static void heap_modules_sort()
{
    unsigned long long count = info_root->module_count;
    unsigned long long i; unsigned long long j;
    if (count > 1) {
        for (i = 0; i < count - 1; ++i) {
            unsigned long long min_addr = 0;
            unsigned long long min_idx = -1;
            for (j = i; i < count; ++j) {
                struct hy_info_module *mod = &info_module[j];
                if (mod->address < min_addr) {
                    min_idx = j;
                    min_addr = mod->address;
                }
            }
            if (i != min_idx) {
                struct hy_info_module tmp;
                memcpy(&tmp, &info_module[i], sizeof(hy_info_module_t));
                memcpy(&info_module[i], &info_module[min_idx], sizeof(hy_info_module_t));
                memcpy(&info_module[min_idx], &tmp, sizeof(hy_info_module_t));
            }
        }
    }
}

variable_types:
count
unsigned long long

variable_types: struct hy_info_module { unsigned short name; unsigned long long address; unsigned int length; unsigned short padding; } *


decompiled_code:
__int64 __fastcall heap_alloc(__int64 a1)
{
__int64 result; // rax

result = heap_top;
heap_top += (a1 + 4095) & 0xFFFFFFFFFFFFF000LL;
return result;
}

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

result = heap_top;
heap_top += (a1 + 4095) & 0xFFFFFFFFFFFFF000LL;
return result;
}

original_code:
void *heap_alloc(size_t size)
{
 size = (size + 0xFFF) & ~0xFFF;
 uintptr_t chunk = heap_top;
 heap_top += size;
 return (void *) chunk;
}

canonical_original_code:
void *heap_alloc(unsigned long long size)
{
 size = (size + 0xFFF) & ~0xFFF;
 unsigned long long chunk = heap_top;
 heap_top += size;
 return (void *) chunk;
}

variable_types:
size
unsigned long long

variable_types:
chunk
unsigned long long

return_type: void *


decompiled_code:
unsigned __int64 heap_modules_move()
{
unsigned __int64 result; // rax
unsigned __int64 v1; // r12
__int64 v2; // rbx
void *v3; // rbp

result = info_root;
if ( *(_WORD *)(info_root + 156LL) )
{
v1 = 0LL;
do
{
v2 = info_module + 16 * v1;
v3 = (void *)heap_alloc(*(unsigned int *)(v2 + 10));
memcpy(v3, *(const void **)(v2 + 2), *(unsigned int *)(v2 + 10));
*(_QWORD *)(v2 + 2) = v3;
++v1;
result = *(unsigned __int16 *)(info_root + 156LL);
}
while ( result > v1 );
}
return result;
}

canonical_decompiled_code:
unsigned __int64 func2()
{
unsigned __int64 result; // rax
unsigned __int64 v1; // r12
__int64 v2; // rbx
void *v3; // rbp

result = info_root;
if ( *(_WORD *)(info_root + 156LL) )
{
v1 = 0LL;
do
{
v2 = info_module + 16 * v1;
v3 = (void *)func1(*(unsigned int *)(v2 + 10));
memcpy(v3, *(const void **)(v2 + 2), *(unsigned int *)(v2 + 10));
*(_QWORD *)(v2 + 2) = v3;
++v1;
result = *(unsigned __int16 *)(info_root + 156LL);
}
while ( result > v1 );
}
return result;
}

original_code:
static void heap_modules_move(void)
{
    size_t i;
    for (i = 0; i < info_root->module_count; ++i) {
        hy_info_module_t *mod = &info_module[i];
        void *buffer = heap_alloc(mod->length);
        memcpy((void *) buffer, (void *) mod->address, mod->length);
        mod->address = (uintptr_t) buffer;
    }
}

canonical_original_code:
static void heap_modules_move()
{
    unsigned long long i;
    for (i = 0; i < info_root->module_count; ++i) {
        struct hy_info_module *mod = &info_module[i];
        void *buffer = heap_alloc(mod->length);
        memcpy((void *) buffer, (void *) mod->address, mod->length);
        mod->address = (unsigned long long) buffer;
    }
}

variable_types:
buffer
void *

user_defined_types: struct hy_info_module { unsigned short name; unsigned long long address; unsigned int length; unsigned short padding; }


decompiled_code:
unsigned __int64 heap_init()
{
heap_top = (__int64)&heap_mark;
heap_modules_sort();
return heap_modules_move();
}

canonical_decompiled_code:
unsigned __int64 func3()
{
heap_top = (__int64)&heap_mark;
func0();
return func2();
}

original_code:
void heap_init(void)
{
 extern uint8_t heap_mark;
 heap_top = (uintptr_t) &heap_mark;
 heap_modules_sort();
 heap_modules_move();
}

canonical_original_code:
void heap_init()
{
 extern unsigned char heap_mark;
 heap_top = (unsigned long long) &heap_mark;
 heap_modules_sort();
 heap_modules_move();
}


decompiled_code:
__int64 __fastcall acpi_add_cpu(unsigned int a1, int a2, char a3)
{
__int64 v4; // rax
__int16 v5; // dx
unsigned int v6; // edi
__int64 result; // rax

v4 = info_cpu + 18LL * a1;
*(_DWORD *)(v4 + 4) = a2;
*(_DWORD *)v4 = a1;
v5 = *(_WORD *)(v4 + 8);
*(_DWORD *)(v4 + 14) = 0;
if ( (a3 & 1) != 0 )
{
*(_WORD *)(v4 + 8) = v5 | 1;
++*(_WORD *)(info_root + 148LL);
}
v6 = a1 + 1;
result = info_root;
if ( *(unsigned __int16 *)(info_root + 150LL) < (unsigned __int64)v6 )
*(_WORD *)(info_root + 150LL) = v6;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1, int a2, char a3)
{
__int64 v4; // rax
__int16 v5; // dx
unsigned int v6; // edi
__int64 result; // rax

v4 = info_cpu + 18LL * a1;
*(_DWORD *)(v4 + 4) = a2;
*(_DWORD *)v4 = a1;
v5 = *(_WORD *)(v4 + 8);
*(_DWORD *)(v4 + 14) = 0;
if ( (a3 & 1) != 0 )
{
*(_WORD *)(v4 + 8) = v5 | 1;
++*(_WORD *)(info_root + 148LL);
}
v6 = a1 + 1;
result = info_root;
if ( *(unsigned __int16 *)(info_root + 150LL) < (unsigned __int64)v6 )
*(_WORD *)(info_root + 150LL) = v6;
return result;
}

original_code:
static void acpi_add_cpu(uint32_t apic_id, uint32_t acpi_id, uint32_t flags)
{
    hy_info_cpu_t *cpu = &info_cpu[apic_id];
    cpu->acpi_id = acpi_id;
    cpu->apic_id = apic_id;
    cpu->flags |= 0;
    cpu->domain = 0;
    if (0 != (flags & (1 << 0))) {
        cpu->flags |= (1 << 0);
        ++info_root->cpu_count_active;
    }
    size_t new_count = apic_id + 1;
    if (info_root->cpu_count < new_count) {
        info_root->cpu_count = new_count;
    }
}

canonical_original_code:
static void acpi_add_cpu(unsigned int apic_id, unsigned int acpi_id, unsigned int flags)
{
    struct hy_info_cpu *cpu = &info_cpu[apic_id];
    cpu->acpi_id = acpi_id;
    cpu->apic_id = apic_id;
    cpu->flags |= 0;
    cpu->domain = 0;
    if (0 != (flags & (1 << 0))) {
        cpu->flags |= (1 << 0);
        ++info_root->cpu_count_active;
    }
    unsigned long long new_count = apic_id + 1;
    if (info_root->cpu_count < new_count) {
        info_root->cpu_count = new_count;
    }
}

variable_types:
flags
unsigned int

variable_types: struct hy_info_cpu { unsigned int apic_id; unsigned int acpi_id; unsigned short flags; unsigned int lapic_timer_freq; unsigned int domain; } *


decompiled_code:
__int64 __fastcall acpi_parse_madt_x2lapic(_DWORD *a1)
{
return acpi_add_cpu(a1[1], a1[3], a1[2]);
}

canonical_decompiled_code:
__int64 __fastcall func1(_DWORD *a1)
{
return func0(a1[1], a1[3], a1[2]);
}

original_code:
static void acpi_parse_madt_x2lapic(acpi_madt_x2lapic_t *entry)
{
    acpi_add_cpu(entry->x2apic_id, entry->acpi_id, entry->flags);
}

canonical_original_code:
static void acpi_parse_madt_x2lapic(struct apci_madt_x2lapic *entry)
{
    acpi_add_cpu(entry->x2apic_id, entry->acpi_id, entry->flags);
}

variable_types: struct apci_madt_x2lapic { struct acpi_madt_entry { unsigned char type; unsigned char length; } header; unsigned short reserved; unsigned int x2apic_id; unsigned int flags; unsigned int acpi_id; } *

user_defined_types: struct apci_madt_x2lapic { struct acpi_madt_entry header; unsigned short reserved; unsigned int x2apic_id; unsigned int flags; unsigned int acpi_id; }


decompiled_code:
__int64 __fastcall acpi_parse_madt_lapic(__int64 a1)
{
return acpi_add_cpu(*(unsigned __int8 *)(a1 + 3), *(unsigned __int8 *)(a1 + 2), *(_DWORD *)(a1 + 4));
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
return func0(*(unsigned __int8 *)(a1 + 3), *(unsigned __int8 *)(a1 + 2), *(_DWORD *)(a1 + 4));
}

original_code:
static void acpi_parse_madt_lapic(acpi_madt_lapic_t *entry)
{
    acpi_add_cpu(entry->apic_id, entry->acpi_id, entry->flags);
}

canonical_original_code:
static void acpi_parse_madt_lapic(struct acpi_madt_lapic *entry)
{
    acpi_add_cpu(entry->apic_id, entry->acpi_id, entry->flags);
}

variable_types: struct acpi_madt_lapic { struct acpi_madt_entry { unsigned char type; unsigned char length; } header; unsigned char acpi_id; unsigned char apic_id; unsigned int flags; } *

user_defined_types: struct acpi_madt_lapic { struct acpi_madt_entry header; unsigned char acpi_id; unsigned char apic_id; unsigned int flags; }


decompiled_code:
__int64 __fastcall acpi_parse_madt_ioapic(__int64 a1)
{
unsigned __int16 v1; // dx
__int64 v2; // rdx
__int64 result; // rax

v1 = *(_WORD *)(info_root + 152LL);
*(_WORD *)(info_root + 152LL) = v1 + 1;
v2 = info_ioapic + 16LL * v1;
*(_BYTE *)v2 = *(_BYTE *)(a1 + 2);
*(_QWORD *)(v2 + 8) = *(unsigned int *)(a1 + 4);
result = *(unsigned int *)(a1 + 8);
*(_DWORD *)(v2 + 2) = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
unsigned __int16 v1; // dx
__int64 v2; // rdx
__int64 result; // rax

v1 = *(_WORD *)(info_root + 152LL);
*(_WORD *)(info_root + 152LL) = v1 + 1;
v2 = info_ioapic + 16LL * v1;
*(_BYTE *)v2 = *(_BYTE *)(a1 + 2);
*(_QWORD *)(v2 + 8) = *(unsigned int *)(a1 + 4);
result = *(unsigned int *)(a1 + 8);
*(_DWORD *)(v2 + 2) = result;
return result;
}

original_code:
static void acpi_parse_madt_ioapic(acpi_madt_ioapic_t *entry)
{
    hy_info_ioapic_t *ioapic = &info_ioapic[info_root->ioapic_count++];
    ioapic->apic_id = entry->apic_id;
    ioapic->mmio_paddr = entry->mmio_addr;
    ioapic->gsi_base = entry->gsi_base;
}

canonical_original_code:
static void acpi_parse_madt_ioapic(struct acpi_madt_ioapic *entry)
{
    struct hy_info_ioapic *ioapic = &info_ioapic[info_root->ioapic_count++];
    ioapic->apic_id = entry->apic_id;
    ioapic->mmio_paddr = entry->mmio_addr;
    ioapic->gsi_base = entry->gsi_base;
}

variable_types: struct acpi_madt_ioapic { struct acpi_madt_entry { unsigned char type; unsigned char length; } header; unsigned char apic_id; unsigned char reserved; unsigned int mmio_addr; unsigned int gsi_base; } *

user_defined_types: struct acpi_madt_ioapic { struct acpi_madt_entry header; unsigned char apic_id; unsigned char reserved; unsigned int mmio_addr; unsigned int gsi_base; }


original_code:
static void acpi_parse_madt_iso(acpi_madt_iso_t *iso)
{
    if (iso->bus != 1 || iso->irq >= 16)
        return;
    uint8_t irq = iso->irq;
    uint16_t polarity = ((iso->flags >> 0) & 0b11);
    uint16_t trigger = ((iso->flags >> 2) & 0b11);
    info_root->irq_gsi[irq] = iso->gsi;
    if (polarity == (0b11)) {
        info_root->irq_flags[irq] |= (1 << 0);
    }
    if (trigger == (0b11)) {
        info_root->irq_flags[irq] |= (1 << 1);
    }
}

canonical_original_code:
static void acpi_parse_madt_iso(struct acpi_madt_iso *iso)
{
    if (iso->bus != 1 || iso->irq >= 16)
        return;
    unsigned char irq = iso->irq;
    unsigned short polarity = ((iso->flags >> 0) & 0b11);
    unsigned short trigger = ((iso->flags >> 2) & 0b11);
    info_root->irq_gsi[irq] = iso->gsi;
    if (polarity == (0b11)) {
        info_root->irq_flags[irq] |= (1 << 0);
    }
    if (trigger == (0b11)) {
        info_root->irq_flags[irq] |= (1 << 1);
    }
}

variable_types: struct acpi_madt_iso { struct acpi_madt_entry { unsigned char type; unsigned char length; } header; unsigned char bus; unsigned char irq; unsigned int gsi; unsigned short flags; } *

variable_types:
irq
unsigned char

variable_types:
polarity
unsigned short

variable_types:
trigger
unsigned short

user_defined_types: struct acpi_madt_iso { struct acpi_madt_entry header; unsigned char bus; unsigned char irq; unsigned int gsi; unsigned short flags; }


decompiled_code:
__int64 __fastcall acpi_parse_madt(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rbx
__int64 v3; // rbp
__int64 v4; // rdx
__int64 i; // rbp
unsigned __int8 v6; // al
__int64 result; // rax
unsigned __int64 v8; // rdx

v1 = info_root;
*(_QWORD *)(info_root + 10LL) = *(unsigned int *)(a1 + 36);
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
*(_DWORD *)(v1 + 4) |= 1u;
v2 = a1 + 44;
v3 = *(unsigned int *)(a1 + 4);
v4 = heap_top;
*(_WORD *)(info_root + 138LL) = heap_top - info_root;
info_cpu = v4;
for ( i = v3 - 44; i; v2 += *(unsigned __int8 *)(v2 + 1) )
{
i -= *(unsigned __int8 *)(v2 + 1);
v6 = *(_BYTE *)v2;
if ( *(_BYTE *)v2 == 2 )
{
acpi_parse_madt_iso(v2);
}
else if ( v6 > 2u )
{
if ( v6 == 9 )
acpi_parse_madt_x2lapic((_DWORD *)v2);
}
else if ( v6 )
{
acpi_parse_madt_ioapic(v2);
}
else
{
acpi_parse_madt_lapic(v2);
}
}
result = info_root;
v8 = (18LL * *(unsigned __int16 *)(info_root + 150LL) + 4095) & 0xFFFFFFFFFFFFF000LL;
heap_top += v8;
*(_WORD *)(info_root + 8LL) += v8;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rbx
__int64 v3; // rbp
__int64 v4; // rdx
__int64 i; // rbp
unsigned __int8 v6; // al
__int64 result; // rax
unsigned __int64 v8; // rdx

v1 = info_root;
*(_QWORD *)(info_root + 10LL) = *(unsigned int *)(a1 + 36);
if ( (*(_BYTE *)(a1 + 40) & 1) != 0 )
*(_DWORD *)(v1 + 4) |= 1u;
v2 = a1 + 44;
v3 = *(unsigned int *)(a1 + 4);
v4 = heap_top;
*(_WORD *)(info_root + 138LL) = heap_top - info_root;
info_cpu = v4;
for ( i = v3 - 44; i; v2 += *(unsigned __int8 *)(v2 + 1) )
{
i -= *(unsigned __int8 *)(v2 + 1);
v6 = *(_BYTE *)v2;
if ( *(_BYTE *)v2 == 2 )
{
func4(v2);
}
else if ( v6 > 2u )
{
if ( v6 == 9 )
func1((_DWORD *)v2);
}
else if ( v6 )
{
func3(v2);
}
else
{
func2(v2);
}
}
result = info_root;
v8 = (18LL * *(unsigned __int16 *)(info_root + 150LL) + 4095) & 0xFFFFFFFFFFFFF000LL;
heap_top += v8;
*(_WORD *)(info_root + 8LL) += v8;
return result;
}

original_code:
static void acpi_parse_madt(acpi_madt_t *madt)
{
    info_root->lapic_paddr = madt->lapic_paddr;
    if ((madt->flags & (1 << 0)) != 0) {
        info_root->flags |= (1 << 0);
    }
    acpi_madt_entry_t *entry = (acpi_madt_entry_t *) ((uintptr_t) madt + sizeof (acpi_madt_t));
    size_t size_left = madt->header.length - sizeof (acpi_madt_t);
    info_root->cpu_offset = heap_top - (uintptr_t) info_root;
    info_cpu = (hy_info_cpu_t *) heap_top;
    while (size_left > 0) {
        size_left -= entry->length;
        switch (entry->type) {
        case 0:
            acpi_parse_madt_lapic((acpi_madt_lapic_t *) entry);
            break;
        case 9:
            acpi_parse_madt_x2lapic((acpi_madt_x2lapic_t *) entry);
            break;
        case 1:
            acpi_parse_madt_ioapic((acpi_madt_ioapic_t *) entry);
            break;
        case 2:
            acpi_parse_madt_iso((acpi_madt_iso_t *) entry);
            break;
        }
        entry = (acpi_madt_entry_t *) ((uintptr_t) entry + entry->length);
    }
    size_t cpu_length = sizeof(hy_info_cpu_t) * info_root->cpu_count;
    cpu_length = (cpu_length + 0xFFF) & ~0xFFF;
    heap_top += cpu_length;
    info_root->length += cpu_length;
}

canonical_original_code:
static void acpi_parse_madt(struct acpi_madt *madt)
{
    info_root->lapic_paddr = madt->lapic_paddr;
    if ((madt->flags & (1 << 0)) != 0) {
        info_root->flags |= (1 << 0);
    }
    struct acpi_madt_entry *entry = (acpi_madt_entry_t *) ((uintptr_t) madt + sizeof (acpi_madt_t));
    unsigned long long size_left = madt->header.length - sizeof (acpi_madt_t);
    info_root->cpu_offset = heap_top - (unsigned long long) info_root;
    info_cpu = (struct hy_info_cpu *) heap_top;
    while (size_left > 0) {
        size_left -= entry->length;
        switch (entry->type) {
        case 0:
            acpi_parse_madt_lapic((struct acpi_madt_lapic *) entry);
            break;
        case 9:
            acpi_parse_madt_x2lapic((struct apci_madt_x2lapic *) entry);
            break;
        case 1:
            acpi_parse_madt_ioapic((struct acpi_madt_ioapic *) entry);
            break;
        case 2:
            acpi_parse_madt_iso((struct acpi_madt_iso *) entry);
            break;
        }
        entry = (struct acpi_madt_entry *) ((unsigned long long) entry + entry->length);
    }
    unsigned long long cpu_length = sizeof(hy_info_cpu_t) * info_root->cpu_count;
    cpu_length = (cpu_length + 0xFFF) & ~0xFFF;
    heap_top += cpu_length;
    info_root->length += cpu_length;
}

variable_types: struct acpi_madt { struct acpi_sdt_header { unsigned int signature; unsigned int length; unsigned char revision; unsigned char checksum; unsigned char oemid[6]; unsigned char oem_tbl_id[8]; unsigned int oem_rev; unsigned int creator_id; unsigned int creator_rev; } header; unsigned int lapic_paddr; unsigned int flags; } *

variable_types: struct acpi_madt_entry { unsigned char type; unsigned char length; } *

user_defined_types: struct acpi_madt { struct acpi_sdt_header header; unsigned int lapic_paddr; unsigned int flags; }

user_defined_types: struct hy_info_cpu { unsigned int apic_id; unsigned int acpi_id; unsigned short flags; unsigned int lapic_timer_freq; unsigned int domain; }


original_code:
static void acpi_parse_srat_lapic(acpi_srat_lapic_t *entry)
{
    if (0 == (entry->flags & (1 << 0)))
        return;
    uint32_t domain = entry->domain_low;
    domain |= entry->domain_high[0] << 8;
    domain |= entry->domain_high[1] << 16;
    domain |= entry->domain_high[2] << 24;
    info_cpu[entry->apic_id].domain = domain;
}

canonical_original_code:
static void acpi_parse_srat_lapic(struct acpi_srat_lapic *entry)
{
    if (0 == (entry->flags & (1 << 0)))
        return;
    unsigned int domain = entry->domain_low;
    domain |= entry->domain_high[0] << 8;
    domain |= entry->domain_high[1] << 16;
    domain |= entry->domain_high[2] << 24;
    info_cpu[entry->apic_id].domain = domain;
}

variable_types: struct acpi_srat_lapic { struct acpi_srat_entry { unsigned char type; unsigned char length; } header; unsigned char domain_low; unsigned char apic_id; unsigned int flags; unsigned char sapic_eid; unsigned char domain_high[3]; unsigned int clock_domain; } *

variable_types:
domain
unsigned int

user_defined_types: struct acpi_srat_lapic { struct acpi_srat_entry header; unsigned char domain_low; unsigned char apic_id; unsigned int flags; unsigned char sapic_eid; unsigned char domain_high[3]; unsigned int clock_domain; }


decompiled_code:
__int64 __fastcall acpi_parse_srat_x2lapic(__int64 a1)
{
__int64 result; // rax

if ( (*(_BYTE *)(a1 + 12) & 1) != 0 )
{
result = info_cpu;
*(_DWORD *)(info_cpu + 18LL * *(unsigned int *)(a1 + 8) + 14) = *(_DWORD *)(a1 + 4);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
__int64 result; // rax

if ( (*(_BYTE *)(a1 + 12) & 1) != 0 )
{
result = info_cpu;
*(_DWORD *)(info_cpu + 18LL * *(unsigned int *)(a1 + 8) + 14) = *(_DWORD *)(a1 + 4);
}
return result;
}

original_code:
static void acpi_parse_srat_x2lapic(acpi_srat_x2lapic_t *entry)
{
    if (0 == (entry->flags & (1 << 0)))
        return;
    info_cpu[entry->x2apic_id].domain = entry->domain;
}

canonical_original_code:
static void acpi_parse_srat_x2lapic(struct acpi_srat_x2lapic *entry)
{
    if (0 == (entry->flags & (1 << 0)))
        return;
    info_cpu[entry->x2apic_id].domain = entry->domain;
}

variable_types: struct acpi_srat_x2lapic { struct acpi_srat_entry { unsigned char type; unsigned char length; } header; unsigned short reserved0; unsigned int domain; unsigned int x2apic_id; unsigned int flags; unsigned int clock_domain; unsigned int reserved1; } *

user_defined_types: struct acpi_srat_x2lapic { struct acpi_srat_entry header; unsigned short reserved0; unsigned int domain; unsigned int x2apic_id; unsigned int flags; unsigned int clock_domain; unsigned int reserved1; }


decompiled_code:
void __fastcall acpi_parse_srat(__int64 a1)
{
unsigned __int8 *v1; // rbx
__int64 v2; // rbp
unsigned __int8 v3; // al

v1 = (unsigned __int8 *)(a1 + 48);
v2 = *(unsigned int *)(a1 + 4) - 48LL;
while ( v2 )
{
v3 = *v1;
if ( *v1 == 1 )
{
v2 -= 40LL;
v1 += 40;
}
else if ( v3 == 2 )
{
acpi_parse_srat_x2lapic((__int64)v1);
v2 -= 24LL;
v1 += 24;
}
else if ( !v3 )
{
acpi_parse_srat_lapic(v1);
v2 -= 16LL;
v1 += 16;
}
}
}

original_code:
static void acpi_parse_srat(acpi_srat_t *srat)
{
    acpi_srat_entry_t *entry = (acpi_srat_entry_t *) ((uintptr_t) srat + sizeof(acpi_srat_t));
    size_t length_remaining = srat->header.length - sizeof(acpi_srat_t);
    while (length_remaining > 0) {
        switch (entry->type) {
        case 0:
            acpi_parse_srat_lapic((acpi_srat_lapic_t *) entry);
            length_remaining -= sizeof(acpi_srat_lapic_t);
            entry = (acpi_srat_entry_t *)((char *)entry + sizeof(acpi_srat_lapic_t));
            break;
        case 1:
            length_remaining -= sizeof(acpi_srat_memory_t);
            entry = (acpi_srat_entry_t *)((char *)entry + sizeof(acpi_srat_memory_t));
            break;
        case 2:
            acpi_parse_srat_x2lapic((acpi_srat_x2lapic_t *) entry);
            length_remaining -= sizeof(acpi_srat_x2lapic_t);
            entry = (acpi_srat_entry_t *)((char *)entry + sizeof(acpi_srat_x2lapic_t));
            break;
        }
    }
}

canonical_original_code:
static void acpi_parse_srat(struct acpi_srat *srat)
{
    struct acpi_srat_entry *entry = (acpi_srat_entry_t *) ((uintptr_t) srat + sizeof(acpi_srat_t));
    unsigned long long length_remaining = srat->header.length - sizeof(acpi_srat_t);
    while (length_remaining > 0) {
        switch (entry->type) {
        case 0:
            acpi_parse_srat_lapic((struct acpi_srat_lapic *) entry);
            length_remaining -= sizeof(acpi_srat_lapic_t);
            entry = (struct acpi_srat_entry *)((char *)entry + sizeof(acpi_srat_lapic_t));
            break;
        case 1:
            length_remaining -= sizeof(acpi_srat_memory_t);
            entry = (struct acpi_srat_entry *)((char *)entry + sizeof(acpi_srat_memory_t));
            break;
        case 2:
            acpi_parse_srat_x2lapic((struct acpi_srat_x2lapic *) entry);
            length_remaining -= sizeof(acpi_srat_x2lapic_t);
            entry = (struct acpi_srat_entry *)((char *)entry + sizeof(acpi_srat_x2lapic_t));
            break;
        }
    }
}

variable_types: struct acpi_srat { struct acpi_sdt_header { unsigned int signature; unsigned int length; unsigned char revision; unsigned char checksum; unsigned char oemid[6]; unsigned char oem_tbl_id[8]; unsigned int oem_rev; unsigned int creator_id; unsigned int creator_rev; } header; unsigned int reserved0; unsigned long long reserved1; } *

variable_types: struct acpi_srat_entry { unsigned char type; unsigned char length; } *

user_defined_types: struct acpi_srat { struct acpi_sdt_header header; unsigned int reserved0; unsigned long long reserved1; }


decompiled_code:
bool __fastcall acpi_check(_BYTE *a1, __int64 a2)
{
_BYTE *v2; // rax
_BYTE *v3; // rsi
char v4; // dl

if ( a2 )
{
v2 = a1;
v3 = &a1[a2];
v4 = 0;
do
v4 += *v2++;
while ( v2 != v3 );
}
else
{
v4 = 0;
}
return v4 == 0;
}

canonical_decompiled_code:
bool __fastcall func9(_BYTE *a1, __int64 a2)
{
_BYTE *v2; // rax
_BYTE *v3; // rsi
char v4; // dl

if ( a2 )
{
v2 = a1;
v3 = &a1[a2];
v4 = 0;
do
v4 += *v2++;
while ( v2 != v3 );
}
else
{
v4 = 0;
}
return v4 == 0;
}

original_code:
bool acpi_check(void *table, size_t length)
{
    uint8_t *bytes = (uint8_t *) table;
    uint8_t sum = 0;
    size_t i;
    for (i = 0; i < length; ++i) {
        sum += bytes[i];
    }
    return (0 == sum);
}

canonical_original_code:
char acpi_check(void *table, unsigned long long length)
{
    unsigned char *bytes = (uint8_t *) table;
    unsigned char sum = 0;
    unsigned long long i;
    for (i = 0; i < length; ++i) {
        sum += bytes[i];
    }
    return (0 == sum);
}

variable_types:
table
void *

variable_types:
length
unsigned long long

variable_types:
bytes
unsigned char *

variable_types:
sum
unsigned char

variable_types:
i
unsigned long long


decompiled_code:
char __fastcall acpi_parse_table(void *s1)
{
char result; // al

result = acpi_check(s1, *((unsigned int *)s1 + 1));
if ( result )
{
if ( !(unsigned __int8)memcmp(s1, "MADT", 4uLL) && !(unsigned __int8)memcmp(s1, "APIC", 4uLL) )
{
result = memcmp(s1, "SRAT", 4uLL);
if ( result )
{
result = (char)s1;
acpi_srat = (__int64)s1;
}
}
else
{
result = (char)s1;
acpi_madt = (__int64)s1;
}
}
return result;
}

canonical_decompiled_code:
char __fastcall func10(void *s1)
{
char result; // al

result = func9(s1, *((unsigned int *)s1 + 1));
if ( result )
{
if ( !(unsigned __int8)memcmp(s1, "MADT", 4uLL) && !(unsigned __int8)memcmp(s1, "APIC", 4uLL) )
{
result = memcmp(s1, "SRAT", 4uLL);
if ( result )
{
result = (char)s1;
acpi_srat = (__int64)s1;
}
}
else
{
result = (char)s1;
acpi_madt = (__int64)s1;
}
}
return result;
}

original_code:
static void acpi_parse_table(acpi_sdt_header_t *table)
{
    if (!acpi_check(table, table->length))
        return;
    if (memcmp(&table->signature, "MADT", 4) ||
            memcmp(&table->signature, "APIC", 4)) {
        acpi_madt = (acpi_madt_t *) table;
    } else if (memcmp(&table->signature, "SRAT", 4)) {
        acpi_srat = (acpi_srat_t *) table;
    }
}

canonical_original_code:
static void acpi_parse_table(struct acpi_sdt_header *table)
{
    if (!acpi_check(table, table->length))
        return;
    if (memcmp(&table->signature, "MADT", 4) ||
            memcmp(&table->signature, "APIC", 4)) {
        acpi_madt = (struct acpi_madt *) table;
    } else if (memcmp(&table->signature, "SRAT", 4)) {
        acpi_srat = (struct acpi_srat *) table;
    }
}

variable_types: struct acpi_sdt_header { unsigned int signature; unsigned int length; unsigned char revision; unsigned char checksum; unsigned char oemid[6]; unsigned char oem_tbl_id[8]; unsigned int oem_rev; unsigned int creator_id; unsigned int creator_rev; } *


decompiled_code:
char __fastcall acpi_parse_xsdt(__int64 a1)
{
__int64 v1; // rbx
char result; // al
unsigned __int64 v3; // rbx
unsigned __int64 v4; // r12
unsigned __int64 v5; // rbx

v1 = *(unsigned int *)(a1 + 4);
result = acpi_check((_BYTE *)a1, v1);
if ( !result )
{
screen_write("PANIC: ACPI: XSDT is invalid.", 0LL, 3LL);
while ( 1 )
;
}
v3 = v1 - 36;
v4 = v3 >> 3;
if ( v3 > 7 )
{
v5 = 0LL;
do
result = acpi_parse_table(*(void **)(a1 + 8 * v5++ + 36));
while ( v4 > v5 );
}
return result;
}

canonical_decompiled_code:
char __fastcall func11(__int64 a1)
{
__int64 v1; // rbx
char result; // al
unsigned __int64 v3; // rbx
unsigned __int64 v4; // r12
unsigned __int64 v5; // rbx

v1 = *(unsigned int *)(a1 + 4);
result = func9((_BYTE *)a1, v1);
if ( !result )
{
screen_write("PANIC: ACPI: XSDT is invalid.", 0LL, 3LL);
while ( 1 )
;
}
v3 = v1 - 36;
v4 = v3 >> 3;
if ( v3 > 7 )
{
v5 = 0LL;
do
result = func10(*(void **)(a1 + 8 * v5++ + 36));
while ( v4 > v5 );
}
return result;
}

original_code:
static void acpi_parse_xsdt(acpi_sdt_header_t *xsdt)
{
    if (!acpi_check(xsdt, xsdt->length)) {
        do { screen_write("PANIC: " "ACPI: XSDT is invalid.", 0, 3); while (1); } while (0);;
    }
    size_t count = (xsdt->length - sizeof (acpi_sdt_header_t)) / 8;
    uint64_t *entry = (uint64_t *) ((uintptr_t) xsdt + sizeof (acpi_sdt_header_t));
    size_t i;
    for (i = 0; i < count; ++i) {
        acpi_parse_table((acpi_sdt_header_t *) entry[i]);
    }
}

canonical_original_code:
static void acpi_parse_xsdt(struct acpi_sdt_header *xsdt)
{
    if (!acpi_check(xsdt, xsdt->length)) {
        do { screen_write("PANIC: " "ACPI: XSDT is invalid.", 0, 3); while (1); } while (0);;
    }
    unsigned long long count = (xsdt->length - sizeof (acpi_sdt_header_t)) / 8;
    unsigned long long *entry = (uint64_t *) ((uintptr_t) xsdt + sizeof (acpi_sdt_header_t));
    unsigned long long i;
    for (i = 0; i < count; ++i) {
        acpi_parse_table((struct acpi_sdt_header *) entry[i]);
    }
}

variable_types:
count
unsigned long long

variable_types:
entry
unsigned long long *

user_defined_types: struct acpi_sdt_header { unsigned int signature; unsigned int length; unsigned char revision; unsigned char checksum; unsigned char oemid[6]; unsigned char oem_tbl_id[8]; unsigned int oem_rev; unsigned int creator_id; unsigned int creator_rev; }


decompiled_code:
char __fastcall acpi_parse_rsdt(__int64 a1)
{
__int64 v1; // rbx
char result; // al
unsigned __int64 v3; // rbx
unsigned __int64 v4; // r12
unsigned __int64 v5; // rbx

v1 = *(unsigned int *)(a1 + 4);
result = acpi_check((_BYTE *)a1, v1);
if ( !result )
{
screen_write("PANIC: ACPI: RSDT is invalid.", 0LL, 3LL);
while ( 1 )
;
}
v3 = v1 - 36;
v4 = v3 >> 2;
if ( v3 > 3 )
{
v5 = 0LL;
do
result = acpi_parse_table((void *)*(unsigned int *)(a1 + 4 * v5++ + 36));
while ( v4 > v5 );
}
return result;
}

canonical_decompiled_code:
char __fastcall func12(__int64 a1)
{
__int64 v1; // rbx
char result; // al
unsigned __int64 v3; // rbx
unsigned __int64 v4; // r12
unsigned __int64 v5; // rbx

v1 = *(unsigned int *)(a1 + 4);
result = func9((_BYTE *)a1, v1);
if ( !result )
{
screen_write("PANIC: ACPI: RSDT is invalid.", 0LL, 3LL);
while ( 1 )
;
}
v3 = v1 - 36;
v4 = v3 >> 2;
if ( v3 > 3 )
{
v5 = 0LL;
do
result = func10((void *)*(unsigned int *)(a1 + 4 * v5++ + 36));
while ( v4 > v5 );
}
return result;
}

original_code:
static void acpi_parse_rsdt(acpi_sdt_header_t *rsdt)
{
    if (!acpi_check(rsdt, rsdt->length)) {
        do { screen_write("PANIC: " "ACPI: RSDT is invalid.", 0, 3); while (1); } while (0);;
    }
    size_t count = (rsdt->length - sizeof (acpi_sdt_header_t)) / 4;
    uint32_t *entry = (uint32_t *) ((uintptr_t) rsdt + sizeof (acpi_sdt_header_t));
    size_t i;
    for (i = 0; i < count; ++i) {
        acpi_parse_table((acpi_sdt_header_t *) (uintptr_t) entry[i]);
    }
}

canonical_original_code:
static void acpi_parse_rsdt(struct acpi_sdt_header *rsdt)
{
    if (!acpi_check(rsdt, rsdt->length)) {
        do { screen_write("PANIC: " "ACPI: RSDT is invalid.", 0, 3); while (1); } while (0);;
    }
    unsigned long long count = (rsdt->length - sizeof (acpi_sdt_header_t)) / 4;
    unsigned int *entry = (uint32_t *) ((uintptr_t) rsdt + sizeof (acpi_sdt_header_t));
    unsigned long long i;
    for (i = 0; i < count; ++i) {
        acpi_parse_table((struct acpi_sdt_header *) (unsigned long long) entry[i]);
    }
}

variable_types:
entry
unsigned int *


decompiled_code:
char __fastcall acpi_parse_rsdp(__int64 a1)
{
char result; // al

if ( *(_BYTE *)(a1 + 15) )
result = acpi_parse_xsdt(*(_QWORD *)(a1 + 24));
else
result = acpi_parse_rsdt(*(unsigned int *)(a1 + 16));
return result;
}

canonical_decompiled_code:
char __fastcall func13(__int64 a1)
{
char result; // al

if ( *(_BYTE *)(a1 + 15) )
result = func11(*(_QWORD *)(a1 + 24));
else
result = func12(*(unsigned int *)(a1 + 16));
return result;
}

original_code:
static void acpi_parse_rsdp(acpi_rsdp_t *rsdp)
{
    if (rsdp->revision > 0) {
        acpi_parse_xsdt((acpi_sdt_header_t *) rsdp->xsdt_addr);
    } else {
        acpi_parse_rsdt((acpi_sdt_header_t *) (uintptr_t) rsdp->rsdt_addr);
    }
}

canonical_original_code:
static void acpi_parse_rsdp(struct acpi_rsdp *rsdp)
{
    if (rsdp->revision > 0) {
        acpi_parse_xsdt((struct acpi_sdt_header *) rsdp->xsdt_addr);
    } else {
        acpi_parse_rsdt((struct acpi_sdt_header *) (unsigned long long) rsdp->rsdt_addr);
    }
}

variable_types: struct acpi_rsdp { unsigned char signature[8]; unsigned char checksum; unsigned char oemid[6]; unsigned char revision; unsigned int rsdt_addr; unsigned int length; unsigned long long xsdt_addr; unsigned char xchecksum; unsigned char reserved[3]; } *


decompiled_code:
unsigned __int64 __fastcall acpi_find_rsdp(__int64 a1, __int64 a2)
{
unsigned __int64 v2; // r13
unsigned __int64 v3; // r12
unsigned __int64 v4; // rbx

v2 = (a1 + 15) & 0xFFFFFFFFFFFFFFF0LL;
if ( a1 + a2 == v2 )
return 0LL;
v3 = 0LL;
while ( 1 )
{
v4 = v2 + v3;
if ( (unsigned __int8)memcmp((const void *)(v2 + v3), "RSD PTR ", 8uLL) )
{
if ( acpi_check((_BYTE *)(v2 + v3), 20LL)
&& (!*(_BYTE *)(v4 + 15) || acpi_check((_BYTE *)(v2 + v3), *(unsigned int *)(v4 + 20))) )
{
break;
}
}
v3 += 16LL;
if ( a1 + a2 - v2 <= v3 )
return 0LL;
}
return v4;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func14(__int64 a1, __int64 a2)
{
unsigned __int64 v2; // r13
unsigned __int64 v3; // r12
unsigned __int64 v4; // rbx

v2 = (a1 + 15) & 0xFFFFFFFFFFFFFFF0LL;
if ( a1 + a2 == v2 )
return 0LL;
v3 = 0LL;
while ( 1 )
{
v4 = v2 + v3;
if ( (unsigned __int8)memcmp((const void *)(v2 + v3), "RSD PTR ", 8uLL) )
{
if ( func9((_BYTE *)(v2 + v3), 20LL)
&& (!*(_BYTE *)(v4 + 15) || func9((_BYTE *)(v2 + v3), *(unsigned int *)(v4 + 20))) )
{
break;
}
}
v3 += 16LL;
if ( a1 + a2 - v2 <= v3 )
return 0LL;
}
return v4;
}

original_code:
acpi_rsdp_t *acpi_find_rsdp(uintptr_t begin, size_t length)
{
    uintptr_t begin_aligned = (begin + 15) & ~15;
    length -= begin_aligned - begin;
    begin = begin_aligned;
    size_t offset;
    for (offset = 0; offset < length; offset += 16) {
        uintptr_t address = begin + offset;
        uint64_t *signature = (uint64_t *) address;
        if (!memcmp(signature, "RSD PTR ", 8))
            continue;
        acpi_rsdp_t *rsdp = (acpi_rsdp_t *) address;
        if (!acpi_check(rsdp, 20))
            continue;
        if (rsdp->revision >= 1) {
            if (!acpi_check(rsdp, rsdp->length))
                continue;
        }
        return rsdp;
    }
    return 0;
}

canonical_original_code:
struct acpi_rsdp *acpi_find_rsdp(unsigned long long begin, unsigned long long length)
{
    unsigned long long begin_aligned = (begin + 15) & ~15;
    length -= begin_aligned - begin;
    begin = begin_aligned;
    unsigned long long offset;
    for (offset = 0; offset < length; offset += 16) {
        unsigned long long address = begin + offset;
        unsigned long long *signature = (uint64_t *) address;
        if (!memcmp(signature, "RSD PTR ", 8))
            continue;
        struct acpi_rsdp *rsdp = (acpi_rsdp_t *) address;
        if (!acpi_check(rsdp, 20))
            continue;
        if (rsdp->revision >= 1) {
            if (!acpi_check(rsdp, rsdp->length))
                continue;
        }
        return rsdp;
    }
    return 0;
}

variable_types:
begin
unsigned long long

variable_types:
offset
unsigned long long

variable_types:
address
unsigned long long

variable_types:
signature
unsigned long long *

return_type: struct acpi_rsdp { unsigned char signature[8]; unsigned char checksum; unsigned char oemid[6]; unsigned char revision; unsigned int rsdt_addr; unsigned int length; unsigned long long xsdt_addr; unsigned char xchecksum; unsigned char reserved[3]; } *


decompiled_code:
__int64 acpi_parse()
{
__int64 v0; // rax
__int64 result; // rax

v0 = acpi_find_rsdp(917504LL, 0x20000LL);
if ( !v0 )
{
screen_write("PANIC: ACPI: Could not find RSDP.", 0LL, 3LL);
while ( 1 )
;
}
*(_QWORD *)(info_root + 18LL) = v0;
acpi_parse_rsdp(v0);
if ( !acpi_madt )
{
screen_write("PANIC: No MADT ACPI table found.", 0LL, 3LL);
while ( 1 )
;
}
acpi_parse_madt(acpi_madt);
if ( acpi_srat )
acpi_parse_srat(acpi_srat);
result = info_root;
if ( !*(_WORD *)(info_root + 150LL) )
{
screen_write("PANIC: No CPU information in ACPI tables.", 0LL, 3LL);
while ( 1 )
;
}
if ( !*(_WORD *)(info_root + 152LL) )
{
screen_write("PANIC: No I/O APIC found in ACPI tables.", 0LL, 3LL);
while ( 1 )
;
}
return result;
}

canonical_decompiled_code:
__int64 func15()
{
__int64 v0; // rax
__int64 result; // rax

v0 = func14(917504LL, 0x20000LL);
if ( !v0 )
{
screen_write("PANIC: ACPI: Could not find RSDP.", 0LL, 3LL);
while ( 1 )
;
}
*(_QWORD *)(info_root + 18LL) = v0;
func13(v0);
if ( !acpi_madt )
{
screen_write("PANIC: No MADT ACPI table found.", 0LL, 3LL);
while ( 1 )
;
}
func5(acpi_madt);
if ( acpi_srat )
func8(acpi_srat);
result = info_root;
if ( !*(_WORD *)(info_root + 150LL) )
{
screen_write("PANIC: No CPU information in ACPI tables.", 0LL, 3LL);
while ( 1 )
;
}
if ( !*(_WORD *)(info_root + 152LL) )
{
screen_write("PANIC: No I/O APIC found in ACPI tables.", 0LL, 3LL);
while ( 1 )
;
}
return result;
}

original_code:
void acpi_parse(void)
{
    acpi_rsdp_t *rsdp = acpi_find_rsdp(0xE0000, 0x100000 - 0xE0000);
    if (0 == rsdp) {
        do { screen_write("PANIC: " "ACPI: Could not find RSDP.", 0, 3); while (1); } while (0);;
    }
    info_root->rsdp_paddr = (uintptr_t) rsdp;
    acpi_parse_rsdp(rsdp);
    if (0 == acpi_madt) {
        do { screen_write("PANIC: " "No MADT ACPI table found.", 0, 3); while (1); } while (0);;
    }
    acpi_parse_madt(acpi_madt);
    if (0 != acpi_srat) {
        acpi_parse_srat(acpi_srat);
    }
    if (0 == info_root->cpu_count) {
        do { screen_write("PANIC: " "No CPU information in ACPI tables.", 0, 3); while (1); } while (0);;
    }
    if (0 == info_root->ioapic_count) {
        do { screen_write("PANIC: " "No I/O APIC found in ACPI tables.", 0, 3); while (1); } while (0);;
    }
}

canonical_original_code:
void acpi_parse()
{
    struct acpi_rsdp *rsdp = acpi_find_rsdp(0xE0000, 0x100000 - 0xE0000);
    if (0 == rsdp) {
        do { screen_write("PANIC: " "ACPI: Could not find RSDP.", 0, 3); while (1); } while (0);;
    }
    info_root->rsdp_paddr = (unsigned long long) rsdp;
    acpi_parse_rsdp(rsdp);
    if (0 == acpi_madt) {
        do { screen_write("PANIC: " "No MADT ACPI table found.", 0, 3); while (1); } while (0);;
    }
    acpi_parse_madt(acpi_madt);
    if (0 != acpi_srat) {
        acpi_parse_srat(acpi_srat);
    }
    if (0 == info_root->cpu_count) {
        do { screen_write("PANIC: " "No CPU information in ACPI tables.", 0, 3); while (1); } while (0);;
    }
    if (0 == info_root->ioapic_count) {
        do { screen_write("PANIC: " "No I/O APIC found in ACPI tables.", 0, 3); while (1); } while (0);;
    }
}

user_defined_types: struct acpi_rsdp { unsigned char signature[8]; unsigned char checksum; unsigned char oemid[6]; unsigned char revision; unsigned int rsdt_addr; unsigned int length; unsigned long long xsdt_addr; unsigned char xchecksum; unsigned char reserved[3]; }


decompiled_code:
void *smp_prepare_boot16()
{
return memcpy((void *)0x1000, &boot16_begin, &boot16_end - &boot16_begin);
}

canonical_decompiled_code:
void *func0()
{
return memcpy((void *)0x1000, &boot16_begin, &boot16_end - &boot16_begin);
}

original_code:
static void smp_prepare_boot16(void)
{
    extern uint8_t boot16_begin;
    extern uint8_t boot16_end;
    size_t length = ((uintptr_t) &boot16_end - (uintptr_t) &boot16_begin);
    memcpy((void *) 0x1000, &boot16_begin, length);
}

canonical_original_code:
static void smp_prepare_boot16()
{
    extern unsigned char boot16_begin;
    extern unsigned char boot16_end;
    unsigned long long length = ((uintptr_t) &boot16_end - (uintptr_t) &boot16_begin);
    memcpy((void *) 0x1000, &boot16_begin, length);
}


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

smp_prepare_boot16();
result = info_root;
if ( *(_WORD *)(info_root + 150LL) )
{
v1 = 0LL;
v2 = 0LL;
do
{
v3 = *(_WORD *)(info_cpu + v1 + 8);
if ( (v3 & 1) != 0 && (v3 & 2) == 0 )
smp_boot((unsigned int *)(info_cpu + v1));
++v2;
v1 += 18LL;
result = *(unsigned __int16 *)(info_root + 150LL);
}
while ( result > v2 );
}
return result;
}

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

func0();
result = info_root;
if ( *(_WORD *)(info_root + 150LL) )
{
v1 = 0LL;
v2 = 0LL;
do
{
v3 = *(_WORD *)(info_cpu + v1 + 8);
if ( (v3 & 1) != 0 && (v3 & 2) == 0 )
smp_boot((unsigned int *)(info_cpu + v1));
++v2;
v1 += 18LL;
result = *(unsigned __int16 *)(info_root + 150LL);
}
while ( result > v2 );
}
return result;
}

original_code:
void smp_setup(void)
{
    smp_prepare_boot16();
    size_t i;
    for (i = 0; i < info_root->cpu_count; ++i) {
        hy_info_cpu_t *cpu = &info_cpu[i];
        if (0 == (cpu->flags & (1 << 0)))
            continue;
        if (0 != (cpu->flags & (1 << 1)))
            continue;
        smp_boot(cpu);
    }
}

canonical_original_code:
void smp_setup()
{
    smp_prepare_boot16();
    unsigned long long i;
    for (i = 0; i < info_root->cpu_count; ++i) {
        struct hy_info_cpu *cpu = &info_cpu[i];
        if (0 == (cpu->flags & (1 << 0)))
            continue;
        if (0 != (cpu->flags & (1 << 1)))
            continue;
        smp_boot(cpu);
    }
}

variable_types: struct hy_info_cpu { unsigned int apic_id; unsigned int acpi_id; unsigned short flags; unsigned int lapic_timer_freq; unsigned int domain; } *


decompiled_code:
unsigned __int64 __fastcall multiboot_align_mmap(unsigned __int64 *a1)
{
unsigned __int64 v1; // rdx
unsigned __int64 result; // rax

if ( a1[2] )
{
v1 = (*a1 + 4095) & 0xFFFFFFFFFFFFF000LL;
result = (v1 + a1[1] - *a1) & 0xFFFFFFFFFFFFF000LL;
}
else
{
v1 = *a1 & 0xFFFFFFFFFFFFF000LL;
result = (v1 + a1[1] + 4095 - *a1) & 0xFFFFFFFFFFFFF000LL;
}
a1[1] = result;
*a1 = v1;
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func0(unsigned __int64 *a1)
{
unsigned __int64 v1; // rdx
unsigned __int64 result; // rax

if ( a1[2] )
{
v1 = (*a1 + 4095) & 0xFFFFFFFFFFFFF000LL;
result = (v1 + a1[1] - *a1) & 0xFFFFFFFFFFFFF000LL;
}
else
{
v1 = *a1 & 0xFFFFFFFFFFFFF000LL;
result = (v1 + a1[1] + 4095 - *a1) & 0xFFFFFFFFFFFFF000LL;
}
a1[1] = result;
*a1 = v1;
return result;
}

original_code:
static void multiboot_align_mmap(hy_info_mmap_t *entry)
{
    uintptr_t aligned_addr;
    if (entry->available) {
        aligned_addr = (entry->address + 0xFFF) & ~0xFFF;
        entry->length -= (entry->address - aligned_addr);
        entry->length &= ~0xFFF;
    } else {
        aligned_addr = entry->address & ~0xFFF;
        entry->length += (aligned_addr - entry->address);
        entry->length = (entry->length + 0xFFF) & ~0xFFF;
    }
    entry->address = aligned_addr;
}

canonical_original_code:
static void multiboot_align_mmap(struct hy_info_mmap *entry)
{
    unsigned long long aligned_addr;
    if (entry->available) {
        aligned_addr = (entry->address + 0xFFF) & ~0xFFF;
        entry->length -= (entry->address - aligned_addr);
        entry->length &= ~0xFFF;
    } else {
        aligned_addr = entry->address & ~0xFFF;
        entry->length += (aligned_addr - entry->address);
        entry->length = (entry->length + 0xFFF) & ~0xFFF;
    }
    entry->address = aligned_addr;
}

variable_types: struct hy_info_mmap { unsigned long long address; unsigned long long length; unsigned long long available; unsigned long long padding; } *


decompiled_code:
__int64 __fastcall multiboot_parse_mmap(unsigned int *a1, __int64 a2)
{
__int64 v3; // rbp
unsigned __int16 v4; // di
unsigned __int64 *v5; // rdi
__int64 v6; // rdx
__int64 result; // rax

if ( a2 )
{
v3 = a2;
do
{
v4 = *(_WORD *)(info_root + 154LL);
*(_WORD *)(info_root + 154LL) = v4 + 1;
v5 = (unsigned __int64 *)(info_mmap + 32LL * v4);
*v5 = *(_QWORD *)(a1 + 1);
v5[1] = *(_QWORD *)(a1 + 3);
v5[2] = a1[5] == 1;
multiboot_align_mmap(v5);
v6 = *a1;
result = -4 - v6;
a1 = (unsigned int *)((char *)a1 + v6 + 4);
v3 += -4 - v6;
}
while ( v3 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int *a1, __int64 a2)
{
__int64 v3; // rbp
unsigned __int16 v4; // di
unsigned __int64 *v5; // rdi
__int64 v6; // rdx
__int64 result; // rax

if ( a2 )
{
v3 = a2;
do
{
v4 = *(_WORD *)(info_root + 154LL);
*(_WORD *)(info_root + 154LL) = v4 + 1;
v5 = (unsigned __int64 *)(info_mmap + 32LL * v4);
*v5 = *(_QWORD *)(a1 + 1);
v5[1] = *(_QWORD *)(a1 + 3);
v5[2] = a1[5] == 1;
func0(v5);
v6 = *a1;
result = -4 - v6;
a1 = (unsigned int *)((char *)a1 + v6 + 4);
v3 += -4 - v6;
}
while ( v3 );
}
return result;
}

original_code:
static void multiboot_parse_mmap(multiboot_mmap_t *mmap, size_t length)
{
    while (0 != length) {
        hy_info_mmap_t *hyentry = &info_mmap[info_root->mmap_count++];
        hyentry->address = mmap->address;
        hyentry->length = mmap->length;
        hyentry->available = mmap->type == 1;
        multiboot_align_mmap(hyentry);
        length -= mmap->size + sizeof(uint32_t);
        mmap = (multiboot_mmap_t *) ((uintptr_t) mmap + mmap->size + sizeof(uint32_t));
    }
}

canonical_original_code:
static void multiboot_parse_mmap(struct multiboot_mmap *mmap, unsigned long long length)
{
    while (0 != length) {
        struct hy_info_mmap *hyentry = &info_mmap[info_root->mmap_count++];
        hyentry->address = mmap->address;
        hyentry->length = mmap->length;
        hyentry->available = mmap->type == 1;
        multiboot_align_mmap(hyentry);
        length -= mmap->size + sizeof(unsigned int);
        mmap = (struct multiboot_mmap *) ((unsigned long long) mmap + mmap->size + sizeof(unsigned int));
    }
}

variable_types: struct multiboot_mmap { unsigned int size; unsigned long long address; unsigned long long length; unsigned int type; } *

user_defined_types: struct hy_info_mmap { unsigned long long address; unsigned long long length; unsigned long long available; unsigned long long padding; }


decompiled_code:
void __fastcall multiboot_parse_mods(unsigned int *a1, __int64 a2)
{
__int64 i; // r13
unsigned __int16 v4; // bx
__int64 v5; // rbx
const char *v6; // r14
void *v7; // rbp
size_t n; // [rsp+0h] [rbp-48h]

if ( a2 )
{
for ( i = 0LL; i != a2; ++i )
{
v4 = *(_WORD *)(info_root + 156LL);
*(_WORD *)(info_root + 156LL) = v4 + 1;
v5 = info_module + 16LL * v4;
*(_QWORD *)(v5 + 2) = *a1;
*(_DWORD *)(v5 + 10) = a1[1] - *a1;
v6 = (const char *)a1[2];
n = strlen(v6);
v7 = (void *)info_string_alloc(n);
memcpy(v7, v6, n);
*(_WORD *)v5 = (_WORD)v7 - info_strings;
a1 += 4;
}
}
}

canonical_decompiled_code:
void __fastcall func2(unsigned int *a1, __int64 a2)
{
__int64 i; // r13
unsigned __int16 v4; // bx
__int64 v5; // rbx
const char *v6; // r14
void *v7; // rbp
size_t n; // [rsp+0h] [rbp-48h]

if ( a2 )
{
for ( i = 0LL; i != a2; ++i )
{
v4 = *(_WORD *)(info_root + 156LL);
*(_WORD *)(info_root + 156LL) = v4 + 1;
v5 = info_module + 16LL * v4;
*(_QWORD *)(v5 + 2) = *a1;
*(_DWORD *)(v5 + 10) = a1[1] - *a1;
v6 = (const char *)a1[2];
n = strlen(v6);
v7 = (void *)info_string_alloc(n);
memcpy(v7, v6, n);
*(_WORD *)v5 = (_WORD)v7 - info_strings;
a1 += 4;
}
}
}

original_code:
static void multiboot_parse_mods(multiboot_mod_t *mods, size_t count)
{
    size_t i;
    for (i = 0; i < count; ++i) {
        multiboot_mod_t *mod = &mods[i];
        hy_info_module_t *hymod = &info_module[info_root->module_count++];
        hymod->address = mod->start;
        hymod->length = mod->end - mod->start;
        char *name = (char *) (uintptr_t) mod->cmdline;
        size_t name_len = strlen(name);
        char *name_tbl = info_string_alloc(name_len);
        memcpy(name_tbl, name, name_len);
        hymod->name = ((uintptr_t) name_tbl - (uintptr_t) info_strings);
    }
}

canonical_original_code:
static void multiboot_parse_mods(struct multiboot_mod *mods, unsigned long long count)
{
    unsigned long long i;
    for (i = 0; i < count; ++i) {
        struct multiboot_mod *mod = &mods[i];
        struct hy_info_module *hymod = &info_module[info_root->module_count++];
        hymod->address = mod->start;
        hymod->length = mod->end - mod->start;
        char *name = (char *) (uintptr_t) mod->cmdline;
        unsigned long long name_len = strlen(name);
        char *name_tbl = info_string_alloc(name_len);
        memcpy(name_tbl, name, name_len);
        hymod->name = ((unsigned long long) name_tbl - (unsigned long long) info_strings);
    }
}

variable_types: struct multiboot_mod { unsigned int start; unsigned int end; unsigned int cmdline; unsigned int pad; } *

variable_types: struct hy_info_module { unsigned short name; unsigned long long address; unsigned int length; unsigned short padding; } *

variable_types:
name
char *


decompiled_code:
void multiboot_parse()
{
unsigned int *v0; // rbp

v0 = (unsigned int *)*(unsigned int *)(multiboot_info + 24LL);
multiboot_parse_mmap(
(unsigned int *)*(unsigned int *)(multiboot_info + 48LL),
*(unsigned int *)(multiboot_info + 44LL));
multiboot_parse_mods(v0, *(unsigned int *)(multiboot_info + 20LL));
}

canonical_decompiled_code:
void func3()
{
unsigned int *v0; // rbp

v0 = (unsigned int *)*(unsigned int *)(multiboot_info + 24LL);
func1(
(unsigned int *)*(unsigned int *)(multiboot_info + 48LL),
*(unsigned int *)(multiboot_info + 44LL));
func2(v0, *(unsigned int *)(multiboot_info + 20LL));
}

original_code:
void multiboot_parse()
{
    multiboot_mmap_t *mmap = (multiboot_mmap_t *) (uintptr_t) multiboot_info->mmap_addr;
    multiboot_mod_t *mods = (multiboot_mod_t *) (uintptr_t) multiboot_info->mods_addr;
    multiboot_parse_mmap(mmap, multiboot_info->mmap_length);
    multiboot_parse_mods(mods, multiboot_info->mods_count);
}

canonical_original_code:
void multiboot_parse()
{
    struct multiboot_mmap *mmap = (multiboot_mmap_t *) (uintptr_t) multiboot_info->mmap_addr;
    struct multiboot_mod *mods = (multiboot_mod_t *) (uintptr_t) multiboot_info->mods_addr;
    multiboot_parse_mmap(mmap, multiboot_info->mmap_length);
    multiboot_parse_mods(mods, multiboot_info->mods_count);
}

user_defined_types: struct multiboot_mmap { unsigned int size; unsigned long long address; unsigned long long length; unsigned int type; }

user_defined_types: struct multiboot_mod { unsigned int start; unsigned int end; unsigned int cmdline; unsigned int pad; }


decompiled_code:
__int64 lapic_detect()
{
__int64 result; // rax
_BYTE v1[24]; // [rsp+0h] [rbp-18h] BYREF

cpu_cpuid(1LL, v1);
result = *(unsigned int *)(kernel_header + 4LL);
if ( (result & 2) != 0 )
{
if ( (v1[10] & 0x20) != 0 )
{
result = info_root;
*(_DWORD *)(info_root + 4LL) |= 2u;
}
else if ( (result & 4) != 0 )
{
screen_write("PANIC: x2APIC required but not supported.", 0LL, 3LL);
while ( 1 )
;
}
}
return result;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 result; // rax
_BYTE v1[24]; // [rsp+0h] [rbp-18h] BYREF

cpu_cpuid(1LL, v1);
result = *(unsigned int *)(kernel_header + 4LL);
if ( (result & 2) != 0 )
{
if ( (v1[10] & 0x20) != 0 )
{
result = info_root;
*(_DWORD *)(info_root + 4LL) |= 2u;
}
else if ( (result & 4) != 0 )
{
screen_write("PANIC: x2APIC required but not supported.", 0LL, 3LL);
while ( 1 )
;
}
}
return result;
}

original_code:
void lapic_detect(void)
{
    cpu_cpuid_result_t cpuid;
    cpu_cpuid(0x1, &cpuid);
    bool x2apic_supported = (0 != ((1 << 21) & cpuid.c));
    if (0 != (kernel_header->flags & (1 << 1))) {
        if (x2apic_supported) {
            info_root->flags |= (1 << 1);
        } else if (0 != (kernel_header->flags & (1 << 2))) {
            do { screen_write("PANIC: " "x2APIC required but not supported.", 0, 3); while (1); } while (0);;
        }
    }
}

canonical_original_code:
void lapic_detect()
{
    struct cpu_cpuid_result cpuid;
    cpu_cpuid(0x1, &cpuid);
    char x2apic_supported = (0 != ((1 << 21) & cpuid.c));
    if (0 != (kernel_header->flags & (1 << 1))) {
        if (x2apic_supported) {
            info_root->flags |= (1 << 1);
        } else if (0 != (kernel_header->flags & (1 << 2))) {
            do { screen_write("PANIC: " "x2APIC required but not supported.", 0, 3); while (1); } while (0);;
        }
    }
}

variable_types: struct cpu_cpuid_result { unsigned int a; unsigned int b; unsigned int c; unsigned int d; }


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

if ( (*(_BYTE *)(info_root + 4LL) & 2) != 0 )
result = cpu_msr_read((unsigned int)(unsigned __int16)a1 + 2048);
else
result = *(unsigned int *)(*(_QWORD *)(info_root + 10LL) + ((16 * a1) & 0xFFFF0));
return result;
}

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

if ( (*(_BYTE *)(info_root + 4LL) & 2) != 0 )
result = cpu_msr_read((unsigned int)(unsigned __int16)a1 + 2048);
else
result = *(unsigned int *)(*(_QWORD *)(info_root + 10LL) + ((16 * a1) & 0xFFFF0));
return result;
}

original_code:
uint32_t lapic_register_read(uint16_t index)
{
    if (!(0 != ((1 << 1) & info_root->flags))) {
        return *((uint32_t *) (info_root->lapic_paddr + index * 0x10));
    } else {
        return cpu_msr_read(0x800 + index);
    }
}

canonical_original_code:
unsigned int lapic_register_read(unsigned short index)
{
    if (!(0 != ((1 << 1) & info_root->flags))) {
        return *((unsigned int *) (info_root->lapic_paddr + index * 0x10));
    } else {
        return cpu_msr_read(0x800 + index);
    }
}

variable_types:
index
unsigned short


decompiled_code:
__int64 __fastcall lapic_register_write(int a1, unsigned int a2)
{
__int64 result; // rax

if ( (*(_BYTE *)(info_root + 4LL) & 2) != 0 )
return cpu_msr_write((unsigned int)(unsigned __int16)a1 + 2048, a2);
result = *(_QWORD *)(info_root + 10LL);
*(_DWORD *)(result + ((16 * a1) & 0xFFFF0)) = a2;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, unsigned int a2)
{
__int64 result; // rax

if ( (*(_BYTE *)(info_root + 4LL) & 2) != 0 )
return cpu_msr_write((unsigned int)(unsigned __int16)a1 + 2048, a2);
result = *(_QWORD *)(info_root + 10LL);
*(_DWORD *)(result + ((16 * a1) & 0xFFFF0)) = a2;
return result;
}

original_code:
void lapic_register_write(uint16_t index, uint32_t value)
{
    if (!(0 != ((1 << 1) & info_root->flags))) {
        *((uint32_t *) (info_root->lapic_paddr + index * 0x10)) = value;
    } else {
        cpu_msr_write(0x800 + index, value);
    }
}

canonical_original_code:
void lapic_register_write(unsigned short index, unsigned int value)
{
    if (!(0 != ((1 << 1) & info_root->flags))) {
        *((unsigned int *) (info_root->lapic_paddr + index * 0x10)) = value;
    } else {
        cpu_msr_write(0x800 + index, value);
    }
}

variable_types:
value
unsigned int


decompiled_code:
__int64 lapic_id()
{
unsigned int v0; // edx

v0 = lapic_register_read(2);
if ( (*(_BYTE *)(info_root + 4LL) & 2) == 0 )
v0 >>= 24;
return v0;
}

canonical_decompiled_code:
__int64 func3()
{
unsigned int v0; // edx

v0 = func1(2);
if ( (*(_BYTE *)(info_root + 4LL) & 2) == 0 )
v0 >>= 24;
return v0;
}

original_code:
uint32_t lapic_id(void)
{
    uint32_t id = lapic_register_read(0x02);
    return ((0 != ((1 << 1) & info_root->flags))) ? id : (id >> 24);
}

canonical_original_code:
unsigned int lapic_id()
{
    unsigned int id = lapic_register_read(0x02);
    return ((0 != ((1 << 1) & info_root->flags))) ? id : (id >> 24);
}

variable_types:
id
unsigned int


decompiled_code:
__int64 lapic_eoi()
{
return lapic_register_write(11, 0);
}

canonical_decompiled_code:
__int64 func4()
{
return func2(11, 0);
}

original_code:
void lapic_eoi(void)
{
    lapic_register_write(0x0B, 0);
}

canonical_original_code:
void lapic_eoi()
{
    lapic_register_write(0x0B, 0);
}


decompiled_code:
__int64 __fastcall lapic_ipi(unsigned int a1, __int64 a2)
{
if ( (*(_BYTE *)(info_root + 4LL) & 2) != 0 )
return cpu_msr_write(2096LL, a1 | (unsigned __int64)(a2 << 32));
lapic_register_write(49, (_DWORD)a2 << 24);
return lapic_register_write(48, a1);
}

canonical_decompiled_code:
__int64 __fastcall func5(unsigned int a1, __int64 a2)
{
if ( (*(_BYTE *)(info_root + 4LL) & 2) != 0 )
return cpu_msr_write(2096LL, a1 | (unsigned __int64)(a2 << 32));
func2(49, (_DWORD)a2 << 24);
return func2(48, a1);
}

original_code:
void lapic_ipi(uint32_t icr_low, uint32_t destination)
{
    if (!(0 != ((1 << 1) & info_root->flags))) {
        lapic_register_write(0x31, (destination & 0xFF) << 24);
        lapic_register_write(0x30, icr_low);
    } else {
        uint64_t icr = icr_low | ((uint64_t) destination << 32);
        cpu_msr_write(0x800 + 0x30, icr);
    }
}

canonical_original_code:
void lapic_ipi(unsigned int icr_low, unsigned int destination)
{
    if (!(0 != ((1 << 1) & info_root->flags))) {
        lapic_register_write(0x31, (destination & 0xFF) << 24);
        lapic_register_write(0x30, icr_low);
    } else {
        unsigned long long icr = icr_low | ((uint64_t) destination << 32);
        cpu_msr_write(0x800 + 0x30, icr);
    }
}

variable_types:
destination
unsigned int

variable_types:
icr
unsigned long long


decompiled_code:
__int64 __fastcall lapic_timer_update(unsigned int a1, unsigned __int8 a2, char a3, char a4)
{
lapic_register_write(62, 0xBu);
lapic_register_write(50, (a4 << 17) | a2 | (a3 << 16));
return lapic_register_write(56, a1);
}

canonical_decompiled_code:
__int64 __fastcall func6(unsigned int a1, unsigned __int8 a2, char a3, char a4)
{
func2(62, 0xBu);
func2(50, (a4 << 17) | a2 | (a3 << 16));
return func2(56, a1);
}

original_code:
void lapic_timer_update(uint32_t init_count, uint8_t vector, bool mask, bool periodic)
{
    uint32_t lvt = vector | (mask << 16) | (periodic << 17);
    lapic_register_write(0x3E, 0xB);
    lapic_register_write(0x32, lvt);
    lapic_register_write(0x38, init_count);
}

canonical_original_code:
void lapic_timer_update(unsigned int init_count, unsigned char vector, char mask, char periodic)
{
    unsigned int lvt = vector | (mask << 16) | (periodic << 17);
    lapic_register_write(0x3E, 0xB);
    lapic_register_write(0x32, lvt);
    lapic_register_write(0x38, init_count);
}

variable_types:
vector
unsigned char

variable_types: mask char

variable_types: periodic char

variable_types:
lvt
unsigned int


decompiled_code:
__int64 lapic_setup()
{
__int64 v0; // rax
__int64 v1; // rbx
__int64 v2; // rbp
char v4; // al

v0 = cpu_msr_read(27LL);
v1 = v0;
v2 = v0 & 0x400;
if ( (v0 & 0x800) == 0 )
{
BYTE1(v1) = BYTE1(v0) | 8;
cpu_msr_write(27LL, v1);
}
if ( (*(_BYTE *)(info_root + 4LL) & 2) != 0 && !v2 )
cpu_msr_write(27LL, v1 | 0x400);
lapic_timer_update(0xFFFFFFFF, 0, 1, 0);
lapic_register_write(8, 0);
lapic_register_write(52, 0x10000u);
lapic_register_write(53, 0x8700u);
lapic_register_write(54, 0x400u);
lapic_register_write(55, 0x10000u);
if ( (*(_BYTE *)(info_root + 4LL) & 2) == 0 )
{
v4 = lapic_id();
lapic_register_write(13, 1 << (v4 & 7));
}
return lapic_register_write(15, 0x120u);
}

original_code:
void lapic_setup(void)
{
    uint64_t base_msr = cpu_msr_read(0x01B);
    bool en = (0 != (base_msr & (1 << 11)));
    bool extd = (0 != (base_msr & (1 << 10)));
    if (!en) {
        base_msr |= (1 << 11);
        cpu_msr_write(0x01B, base_msr);
    }
    if ((0 != ((1 << 1) & info_root->flags)) && !extd) {
        base_msr |= (1 << 10);
        cpu_msr_write(0x01B, base_msr);
    }
    lapic_timer_update(0xFFFFFFFF, 0, 1, 0);
    lapic_register_write(0x08, 0x0);
    lapic_register_write(0x34, (1 << 16));
    lapic_register_write(0x35, (0b111 << 8) | (1 << 15));
    lapic_register_write(0x36, (0b100 << 8));
    lapic_register_write(0x37, (1 << 16));
    if (!(0 != ((1 << 1) & info_root->flags))) {
        lapic_register_write(0x0D, (1 << (lapic_id() % 8)));
    }
    lapic_register_write(0x0F, 0x20 | (1 << 8));
}

canonical_original_code:
void lapic_setup()
{
    unsigned long long base_msr = cpu_msr_read(0x01B);
    char en = (0 != (base_msr & (1 << 11)));
    char extd = (0 != (base_msr & (1 << 10)));
    if (!en) {
        base_msr |= (1 << 11);
        cpu_msr_write(0x01B, base_msr);
    }
    if ((0 != ((1 << 1) & info_root->flags)) && !extd) {
        base_msr |= (1 << 10);
        cpu_msr_write(0x01B, base_msr);
    }
    lapic_timer_update(0xFFFFFFFF, 0, 1, 0);
    lapic_register_write(0x08, 0x0);
    lapic_register_write(0x34, (1 << 16));
    lapic_register_write(0x35, (0b111 << 8) | (1 << 15));
    lapic_register_write(0x36, (0b100 << 8));
    lapic_register_write(0x37, (1 << 16));
    if (!(0 != ((1 << 1) & info_root->flags))) {
        lapic_register_write(0x0D, (1 << (lapic_id() % 8)));
    }
    lapic_register_write(0x0F, 0x20 | (1 << 8));
}

variable_types: en char

variable_types: extd char


decompiled_code:
__int64 lapic_timer_calibrate()
{
int v0; // ebx
__int64 v1; // rbp

idt_intgate((char *)&idt_data + 768, &lapic_timer_calibrate_handler, 8LL, 0LL);
pit_freq_set(100LL);
pit_route();
v0 = lapic_timer_calibrate_worker();
v1 = info_cpu;
*(_DWORD *)(v1 + 18LL * (unsigned int)lapic_id() + 10) = v0;
pit_mask();
return idt_setup_loader();
}

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

idt_intgate((char *)&idt_data + 768, &lapic_timer_calibrate_handler, 8LL, 0LL);
pit_freq_set(100LL);
pit_route();
v0 = lapic_timer_calibrate_worker();
v1 = info_cpu;
*(_DWORD *)(v1 + 18LL * (unsigned int)func3() + 10) = v0;
pit_mask();
return idt_setup_loader();
}

original_code:
void lapic_timer_calibrate(void)
{
    extern uint32_t lapic_timer_calibrate_worker(void);
    extern void lapic_timer_calibrate_handler(void);
    uint8_t vector = 0x30;
    idt_intgate(&idt_data[vector], (uintptr_t) &lapic_timer_calibrate_handler, 0x08, 0x0);
    pit_freq_set(100);
    pit_route();
    uint32_t ticks_per_second = lapic_timer_calibrate_worker();
    info_cpu[lapic_id()].lapic_timer_freq = ticks_per_second;
    pit_mask();
    idt_setup_loader();
}

canonical_original_code:
void lapic_timer_calibrate()
{
    extern unsigned int lapic_timer_calibrate_worker();
    extern void lapic_timer_calibrate_handler();
    unsigned char vector = 0x30;
    idt_intgate(&idt_data[vector], (unsigned long long) &lapic_timer_calibrate_handler, 0x08, 0x0);
    pit_freq_set(100);
    pit_route();
    unsigned int ticks_per_second = lapic_timer_calibrate_worker();
    info_cpu[lapic_id()].lapic_timer_freq = ticks_per_second;
    pit_mask();
    idt_setup_loader();
}