decompiled_code:
__int64 __fastcall decode_hpet(__int64 a1)
{
const char *v1; // rax
unsigned __int8 *v2; // r13
__int64 v3; // r9
_QWORD *v4; // rbx
int v5; // ebp
__int64 result; // rax

v1 = "system IO";
if ( !*(_BYTE *)(a1 + 40) )
v1 = "system memory";
printf(
"hpet%u: rev=%u comp=%u pci_vendor_id=%x addr=0x%lx[%s]\n",
*(unsigned __int8 *)(a1 + 52),
*(unsigned __int8 *)(a1 + 36),
*(_BYTE *)(a1 + 37) & 0x1F,
*(unsigned __int16 *)(a1 + 38),
*(_QWORD *)(a1 + 44),
v1);
v2 = *(unsigned __int8 **)(a1 + 44);
create_page_entry_4k(kernel_pd, v2, v2, 259LL, 0LL);
v3 = *((_QWORD *)v2 + 1) | 3LL;
*((_QWORD *)v2 + 1) = v3;
printf(
"hpet%u: rev_id=%u num_tim_cap=%u clk=%u conf=%lx\n",
*(unsigned __int8 *)(a1 + 52),
*v2,
v2[1] & 0x1F,
*((unsigned int *)v2 + 1),
v3);
v4 = v2 + 32;
v5 = 0;
do
{
printf(
"hpet%u.%u: conf:%lx comp:%lx intr:%lx\n",
*(unsigned __int8 *)(a1 + 52),
(unsigned int)v5++,
*v4,
v4[1],
v4[2]);
v4 += 3;
result = v2[1] & 0x1F;
}
while ( (int)result >= v5 );
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
const char *v1; // rax
unsigned __int8 *v2; // r13
__int64 v3; // r9
_QWORD *v4; // rbx
int v5; // ebp
__int64 result; // rax

v1 = "system IO";
if ( !*(_BYTE *)(a1 + 40) )
v1 = "system memory";
printf(
"hpet%u: rev=%u comp=%u pci_vendor_id=%x addr=0x%lx[%s]\n",
*(unsigned __int8 *)(a1 + 52),
*(unsigned __int8 *)(a1 + 36),
*(_BYTE *)(a1 + 37) & 0x1F,
*(unsigned __int16 *)(a1 + 38),
*(_QWORD *)(a1 + 44),
v1);
v2 = *(unsigned __int8 **)(a1 + 44);
create_page_entry_4k(kernel_pd, v2, v2, 259LL, 0LL);
v3 = *((_QWORD *)v2 + 1) | 3LL;
*((_QWORD *)v2 + 1) = v3;
printf(
"hpet%u: rev_id=%u num_tim_cap=%u clk=%u conf=%lx\n",
*(unsigned __int8 *)(a1 + 52),
*v2,
v2[1] & 0x1F,
*((unsigned int *)v2 + 1),
v3);
v4 = v2 + 32;
v5 = 0;
do
{
printf(
"hpet%u.%u: conf:%lx comp:%lx intr:%lx\n",
*(unsigned __int8 *)(a1 + 52),
(unsigned int)v5++,
*v4,
v4[1],
v4[2]);
v4 += 3;
result = v2[1] & 0x1F;
}
while ( (int)result >= v5 );
return result;
}

original_code:
__attribute__((nonnull)) static void decode_hpet(struct ACPIHPET *const h)
{
 printf("hpet%u: rev=%u comp=%u pci_vendor_id=%x addr=0x%lx[%s]\n",
   h->hpet_number,
   h->hardware_rev_id,
   h->comparator_count,
   h->pci_vendor_id,
   h->address.address,
   h->address.address_space_id ? "system IO" : "system memory"
   );
 struct hpet *hpet = (void *)h->address.address;
 create_page_entry_4k(kernel_pd, (uint64_t)hpet, (uint64_t)hpet, 0x001|0x002|0x100, ((void*)0));
 hpet->conf |= 0x1|0x2;
 printf("hpet%u: rev_id=%u num_tim_cap=%u clk=%u conf=%lx\n",
   h->hpet_number,
   hpet->rev_id,
   hpet->num_tim_cap,
   hpet->counter_clk,
   hpet->conf);
 for(int i = 0; i < hpet->num_tim_cap + 1; i++)
 {
  printf("hpet%u.%u: conf:%lx comp:%lx intr:%lx\n",
    h->hpet_number,
    i,
    hpet->timers[i].conf,
    hpet->timers[i].comp,
    hpet->timers[i].intr);
 }
}

canonical_original_code:
static void decode_hpet(struct ACPIHPET *h)
{
 printf("hpet%u: rev=%u comp=%u pci_vendor_id=%x addr=0x%lx[%s]\n",
   h->hpet_number,
   h->hardware_rev_id,
   h->comparator_count,
   h->pci_vendor_id,
   h->address.address,
   h->address.address_space_id ? "system IO" : "system memory"
   );
 struct hpet *hpet = (void *)h->address.address;
 create_page_entry_4k(kernel_pd, (unsigned long)hpet, (unsigned long)hpet, 0x001|0x002|0x100, ((void *)0));
 hpet->conf |= 0x1|0x2;
 printf("hpet%u: rev_id=%u num_tim_cap=%u clk=%u conf=%lx\n",
   h->hpet_number,
   hpet->rev_id,
   hpet->num_tim_cap,
   hpet->counter_clk,
   hpet->conf);
 for(int i = 0; i < hpet->num_tim_cap + 1; i++)
 {
  printf("hpet%u.%u: conf:%lx comp:%lx intr:%lx\n",
    h->hpet_number,
    i,
    hpet->timers[i].conf,
    hpet->timers[i].comp,
    hpet->timers[i].intr);
 }
}

variable_types: struct ACPIHPET { struct ACPISDTHeader { char Signature[4]; unsigned int Length; unsigned char Revision; unsigned char Checksum; char OEMID[6]; char OEMTableID[8]; unsigned int OEMRevision; unsigned int CreatorID; unsigned int CreatorRevision; } h; unsigned char hardware_rev_id; unsigned int comparator_count; unsigned int counter_size; unsigned int reserved; unsigned int legacy_replacement; unsigned short pci_vendor_id; struct address_structure { unsigned char address_space_id; unsigned char register_bit_width; unsigned char register_bit_offset; unsigned char reserved; unsigned long address; } address; unsigned char hpet_number; unsigned short minimum_tick; unsigned char page_protection; } *

variable_types: struct hpet { union { unsigned long cap_id; struct { unsigned int rev_id; unsigned int num_tim_cap; unsigned int count_size_cap; unsigned int res0; unsigned int leg_rt_cap; unsigned int vendor_id; unsigned int counter_clk; }; }; union { unsigned long conf; struct { unsigned int enable_cnf; unsigned int leg_rt_cnf; unsigned long reserved; }; }; unsigned long intr; unsigned long main; struct { union { unsigned long conf; struct { unsigned int res0; unsigned int int_type_cnf; unsigned int int_enb_cnf; unsigned int type_cnf; unsigned int per_int_cnf; unsigned int size_cap; unsigned int val_set_cnf; unsigned int res1; unsigned int int_route_cnf; unsigned int fsb_en_cnf; unsigned int fsb_int_del_cap; unsigned int res2; unsigned int int_route_cap; }; }; unsigned long comp; unsigned long intr; } timers[]; } *

user_defined_types: struct ACPIHPET { struct ACPISDTHeader h; unsigned char hardware_rev_id; unsigned int comparator_count; unsigned int counter_size; unsigned int reserved; unsigned int legacy_replacement; unsigned short pci_vendor_id; struct address_structure address; unsigned char hpet_number; unsigned short minimum_tick; unsigned char page_protection; }


repo: juur/FailOS

decompiled_code:
int __fastcall decode_sdt(unsigned int *a1)
{
unsigned int v1; // ebp

v1 = *a1;
printf(
"acpi: %c%c%c%c: 0x%0x %x ver=%x (%c%c%c%c%c%c) (%c%c%c%c%c%c%c%c) %x %x %x\n",
(unsigned int)*(char *)a1,
(unsigned int)*((char *)a1 + 1),
(unsigned int)*((char *)a1 + 2),
(unsigned int)*((char *)a1 + 3),
(unsigned int)a1,
a1[1],
*((unsigned __int8 *)a1 + 8),
(unsigned int)*((char *)a1 + 10),
(unsigned int)*((char *)a1 + 11),
(unsigned int)*((char *)a1 + 12),
(unsigned int)*((char *)a1 + 13),
(unsigned int)*((char *)a1 + 14),
(unsigned int)*((char *)a1 + 15),
(unsigned int)*((char *)a1 + 16),
(unsigned int)*((char *)a1 + 17),
(unsigned int)*((char *)a1 + 18),
(unsigned int)*((char *)a1 + 19),
(unsigned int)*((char *)a1 + 20),
(unsigned int)*((char *)a1 + 21),
(unsigned int)*((char *)a1 + 22),
(unsigned int)*((char *)a1 + 23),
a1[6],
a1[7],
a1[8]);
switch ( v1 )
{
case 0x50434146u:
return decode_facp((__int64)a1);
case 0x54455048u:
return decode_hpet((__int64)a1);
case 0x43495041u:
return decode_madt(a1);
}
return printf(
"acpi_probe: unknown sig %x '%c%c%c%c'\n",
v1,
(unsigned int)*(char *)a1,
(unsigned int)*((char *)a1 + 1),
(unsigned int)*((char *)a1 + 2),
(unsigned int)*((char *)a1 + 3));
}

canonical_decompiled_code:
int __fastcall func3(unsigned int *a1)
{
unsigned int v1; // ebp

v1 = *a1;
printf(
"acpi: %c%c%c%c: 0x%0x %x ver=%x (%c%c%c%c%c%c) (%c%c%c%c%c%c%c%c) %x %x %x\n",
(unsigned int)*(char *)a1,
(unsigned int)*((char *)a1 + 1),
(unsigned int)*((char *)a1 + 2),
(unsigned int)*((char *)a1 + 3),
(unsigned int)a1,
a1[1],
*((unsigned __int8 *)a1 + 8),
(unsigned int)*((char *)a1 + 10),
(unsigned int)*((char *)a1 + 11),
(unsigned int)*((char *)a1 + 12),
(unsigned int)*((char *)a1 + 13),
(unsigned int)*((char *)a1 + 14),
(unsigned int)*((char *)a1 + 15),
(unsigned int)*((char *)a1 + 16),
(unsigned int)*((char *)a1 + 17),
(unsigned int)*((char *)a1 + 18),
(unsigned int)*((char *)a1 + 19),
(unsigned int)*((char *)a1 + 20),
(unsigned int)*((char *)a1 + 21),
(unsigned int)*((char *)a1 + 22),
(unsigned int)*((char *)a1 + 23),
a1[6],
a1[7],
a1[8]);
switch ( v1 )
{
case 0x50434146u:
return func1((__int64)a1);
case 0x54455048u:
return func2((__int64)a1);
case 0x43495041u:
return func0(a1);
}
return printf(
"acpi_probe: unknown sig %x '%c%c%c%c'\n",
v1,
(unsigned int)*(char *)a1,
(unsigned int)*((char *)a1 + 1),
(unsigned int)*((char *)a1 + 2),
(unsigned int)*((char *)a1 + 3));
}

original_code:
__attribute__((nonnull)) static void decode_sdt(const struct ACPISDTHeader *const h)
{
 uint32_t sig;
 sig = *(uint32_t*)h->Signature;
 printf("acpi: %c%c%c%c: 0x%0x %x ver=%x (%c%c%c%c%c%c) (%c%c%c%c%c%c%c%c) %x %x %x\n",
   h->Signature[0],
   h->Signature[1],
   h->Signature[2],
   h->Signature[3],
   (uint32_t)(uint64_t)h,
   h->Length,
   h->Revision,
   h->OEMID[0],
   h->OEMID[1],
   h->OEMID[2],
   h->OEMID[3],
   h->OEMID[4],
   h->OEMID[5],
   h->OEMTableID[0],
   h->OEMTableID[1],
   h->OEMTableID[2],
   h->OEMTableID[3],
   h->OEMTableID[4],
   h->OEMTableID[5],
   h->OEMTableID[6],
   h->OEMTableID[7],
   h->OEMRevision,
   h->CreatorID,
   h->CreatorRevision
   );
 switch(sig)
 {
  case 0x50434146:
   decode_facp((struct ACPIFADT *)h);
   break;
  case 0x43495041:
   decode_madt((struct ACPIMADT *)h);
   break;
  case 0x54455048:
   decode_hpet((struct ACPIHPET *)h);
   break;
  default:
   printf("acpi_probe: unknown sig %x '%c%c%c%c'\n",
     sig,
     h->Signature[0],
     h->Signature[1],
     h->Signature[2],
     h->Signature[3]
     );
 }
}

canonical_original_code:
static void decode_sdt(struct ACPISDTHeader *h)
{
 unsigned int sig;
 sig = *(unsigned int *)h->Signature;
 printf("acpi: %c%c%c%c: 0x%0x %x ver=%x (%c%c%c%c%c%c) (%c%c%c%c%c%c%c%c) %x %x %x\n",
   h->Signature[0],
   h->Signature[1],
   h->Signature[2],
   h->Signature[3],
   (unsigned int)(unsigned long)h,
   h->Length,
   h->Revision,
   h->OEMID[0],
   h->OEMID[1],
   h->OEMID[2],
   h->OEMID[3],
   h->OEMID[4],
   h->OEMID[5],
   h->OEMTableID[0],
   h->OEMTableID[1],
   h->OEMTableID[2],
   h->OEMTableID[3],
   h->OEMTableID[4],
   h->OEMTableID[5],
   h->OEMTableID[6],
   h->OEMTableID[7],
   h->OEMRevision,
   h->CreatorID,
   h->CreatorRevision
   );
 switch(sig)
 {
  case 0x50434146:
   decode_facp((struct ACPIFADT *)h);
   break;
  case 0x43495041:
   decode_madt((struct ACPIMADT *)h);
   break;
  case 0x54455048:
   decode_hpet((struct ACPIHPET *)h);
   break;
  default:
   printf("acpi_probe: unknown sig %x '%c%c%c%c'\n",
     sig,
     h->Signature[0],
     h->Signature[1],
     h->Signature[2],
     h->Signature[3]
     );
 }
}

variable_types: struct ACPISDTHeader { char Signature[4]; unsigned int Length; unsigned char Revision; unsigned char Checksum; char OEMID[6]; char OEMTableID[8]; unsigned int OEMRevision; unsigned int CreatorID; unsigned int CreatorRevision; } *

variable_types:
sig
unsigned int

return_type: void

user_defined_types: struct ACPIFADT { struct ACPISDTHeader h; unsigned int firmware_ctrl; unsigned int dsdt; unsigned char res0; unsigned char preferred_pm_profile; unsigned short sci_int; unsigned int smi_cmd; unsigned char acpi_enable; unsigned char acpi_disable; unsigned char s4bios_req; unsigned char pstate_cnt; unsigned int pm1a_evt_blk; unsigned int pm1b_evt_blk; unsigned int pm1a_cnt_blk; unsigned int pm1b_cnt_blk; unsigned int pm2_cnt_blk; unsigned int pm_tmr_blk; unsigned int gpe0_blk; unsigned int gpe1_blk; unsigned char pm1_evt_len; unsigned char pm1_cnt_len; unsigned char pm2_cnt_len; unsigned char pm_tmr_len; unsigned char gpe0_blk_len; unsigned char gpe1_blk_len; unsigned char gpe1_base; unsigned char cst_cnt; unsigned short p_lvl2_lat; unsigned short p_lvl3_lat; unsigned short flush_size; unsigned short flush_stride; unsigned char duty_offset; unsigned char duty_width; unsigned char day_alrm; unsigned char mon_alrm; unsigned char century; union fadt_iapc_boot_arch iapc_boot_arch; unsigned char res1; union fadt_flags flags; struct fadt_gas reset_reg; unsigned char reset_value; unsigned short arm_boot_arch; unsigned char fadt_minor_version; unsigned long x_firmware_ctrl; unsigned long x_dsdt; struct fadt_gas x_pm1a_evt_blk; struct fadt_gas x_pm1b_evt_blk; struct fadt_gas x_pm1a_cnt_blk; struct fadt_gas x_pm1b_cnt_blk; struct fadt_gas x_pm2_cnt_blk; struct fadt_gas x_pm_tmr_blk; struct fadt_gas x_gpe0_blk; struct fadt_gas x_gpe1_blk; struct fadt_gas sleep_control_reg; struct fadt_gas sleep_status_reg; unsigned long hyp_vend_id; }

user_defined_types: struct ACPIMADT { struct ACPISDTHeader h; unsigned int lapic_addr; unsigned int flags; }

user_defined_types: union fadt_iapc_boot_arch { struct { unsigned int legacy_devices; unsigned int i8042; unsigned int no_vga; unsigned int no_msi; unsigned int pcie_aspm; unsigned int no_cmos_rtc; unsigned int res0; }; unsigned short a; }

user_defined_types: union fadt_flags { struct { unsigned int wbinvd; unsigned int wbinvd_flush; unsigned int proc_c1; unsigned int p_lvl2_up; unsigned int pwr_button; unsigned int slp_button; unsigned int fix_rtc; unsigned int rtc_s4; unsigned int tmr_val_ext; unsigned int dkc_cap; unsigned int reset_reg_sup; unsigned int sealed_case; unsigned int headless; unsigned int cpu_sw_slp; unsigned int pci_exp_wak; unsigned int use_platform_clock; unsigned int s4_rtc_sts_valid; unsigned int remote_power_on_capable; unsigned int force_apic_cluster_model; unsigned int force_apic_phys_dest_mode; unsigned int hw_reduced_acpi; unsigned int low_power_s0_idle_cap; unsigned int reserved; }; unsigned int a; }

user_defined_types: struct fadt_gas { unsigned char address_space; unsigned char bit_width; unsigned char bit_offset; unsigned char access_size; unsigned long address; }

user_defined_types: struct address_structure { unsigned char address_space_id; unsigned char register_bit_width; unsigned char register_bit_offset; unsigned char reserved; unsigned long address; }


decompiled_code:
__int64 acpi_probe()
{
__int64 v0; // rsi
unsigned __int64 v1; // rbx
int v2; // ebp
int v3; // ebx
__int64 result; // rax
unsigned __int64 v5; // rbx
char s[31]; // [rsp+9h] [rbp-1Fh] BYREF

RSDP = 0LL;
RSDT = 0LL;
XSDT = 0LL;
printf("acpi_probe: ");
v0 = 57344LL;
while ( *(_QWORD *)v0 != 0x2052545020445352LL )
{
v0 += 16LL;
if ( v0 == 0x100000 )
goto LABEL_6;
}
RSDP = v0;
printf("found at 0x%0x\n", v0);
LABEL_6:
if ( RSDP )
{
memset(s, 0, 7uLL);
memcpy(s, (const void *)(RSDP + 9), 6uLL);
printf("acpi: OEM='%s' rev=%u RSDT=0x%x", s, *(unsigned __int8 *)(RSDP + 15), *(unsigned int *)(RSDP + 16));
if ( *(_BYTE *)(RSDP + 15) > 1u )
printf("len=%x XSDT=0x%lx", *(unsigned int *)(RSDP + 20), *(_QWORD *)(RSDP + 24));
printf("\n");
RSDT = *(unsigned int *)(RSDP + 16);
v1 = ((unsigned __int64)*(unsigned int *)(RSDT + 4) - 36) >> 2;
v2 = v1;
printf(
"acpi: %c%c%c%c: len=%x oemrev=%x cID=%x crev=%x rsdt[%u]=0x%p\n",
(unsigned int)*(char *)(unsigned int)RSDT,
(unsigned int)*(char *)(RSDT + 1),
(unsigned int)*(char *)(RSDT + 2),
(unsigned int)*(char *)(RSDT + 3),
*(unsigned int *)(RSDT + 4),
*(unsigned int *)(RSDT + 24),
*(unsigned int *)(RSDT + 28),
*(unsigned int *)(RSDT + 32),
v1,
(const void *)RSDT);
if ( (int)v1 > 0 )
{
v3 = 0;
do
decode_sdt((unsigned int *)*(unsigned int *)(RSDT + 4 * (v3++ + 8LL) + 4));
while ( v2 != v3 );
}
result = 0LL;
if ( *(_BYTE *)(RSDP + 15) > 1u && *(_QWORD *)(RSDP + 24) )
{
XSDT = *(_QWORD *)(RSDP + 24);
v5 = ((unsigned __int64)*(unsigned int *)(XSDT + 4) - 36) >> 3;
if ( XSDT == RSDT )
printf("acpi: XSDT exists and points to RSDT ");
else
printf("acpi: XSDT differs from RSDT ");
printf("XSDT[%u]=0x%p\n", (unsigned int)v5, (const void *)XSDT);
result = 0LL;
}
}
else
{
printf("not found\n");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 func4()
{
__int64 v0; // rsi
unsigned __int64 v1; // rbx
int v2; // ebp
int v3; // ebx
__int64 result; // rax
unsigned __int64 v5; // rbx
char s[31]; // [rsp+9h] [rbp-1Fh] BYREF

RSDP = 0LL;
RSDT = 0LL;
XSDT = 0LL;
printf("acpi_probe: ");
v0 = 57344LL;
while ( *(_QWORD *)v0 != 0x2052545020445352LL )
{
v0 += 16LL;
if ( v0 == 0x100000 )
goto LABEL_6;
}
RSDP = v0;
printf("found at 0x%0x\n", v0);
LABEL_6:
if ( RSDP )
{
memset(s, 0, 7uLL);
memcpy(s, (const void *)(RSDP + 9), 6uLL);
printf("acpi: OEM='%s' rev=%u RSDT=0x%x", s, *(unsigned __int8 *)(RSDP + 15), *(unsigned int *)(RSDP + 16));
if ( *(_BYTE *)(RSDP + 15) > 1u )
printf("len=%x XSDT=0x%lx", *(unsigned int *)(RSDP + 20), *(_QWORD *)(RSDP + 24));
printf("\n");
RSDT = *(unsigned int *)(RSDP + 16);
v1 = ((unsigned __int64)*(unsigned int *)(RSDT + 4) - 36) >> 2;
v2 = v1;
printf(
"acpi: %c%c%c%c: len=%x oemrev=%x cID=%x crev=%x rsdt[%u]=0x%p\n",
(unsigned int)*(char *)(unsigned int)RSDT,
(unsigned int)*(char *)(RSDT + 1),
(unsigned int)*(char *)(RSDT + 2),
(unsigned int)*(char *)(RSDT + 3),
*(unsigned int *)(RSDT + 4),
*(unsigned int *)(RSDT + 24),
*(unsigned int *)(RSDT + 28),
*(unsigned int *)(RSDT + 32),
v1,
(const void *)RSDT);
if ( (int)v1 > 0 )
{
v3 = 0;
do
func3((unsigned int *)*(unsigned int *)(RSDT + 4 * (v3++ + 8LL) + 4));
while ( v2 != v3 );
}
result = 0LL;
if ( *(_BYTE *)(RSDP + 15) > 1u && *(_QWORD *)(RSDP + 24) )
{
XSDT = *(_QWORD *)(RSDP + 24);
v5 = ((unsigned __int64)*(unsigned int *)(XSDT + 4) - 36) >> 3;
if ( XSDT == RSDT )
printf("acpi: XSDT exists and points to RSDT ");
else
printf("acpi: XSDT differs from RSDT ");
printf("XSDT[%u]=0x%p\n", (unsigned int)v5, (const void *)XSDT);
result = 0LL;
}
}
else
{
printf("not found\n");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int acpi_probe(void)
{
 char *tmp;
 uint64_t offset;
 RSDP = ((void*)0);
 RSDT = ((void*)0);
 XSDT = ((void*)0);
 printf("acpi_probe: ");
 for(offset = 0xe000; offset < 0xFFFFF; offset+=16)
 {
  tmp = (char *)(0 + offset);
  if(*(uint64_t *)tmp == acpi_id) {
   RSDP = (struct RSDPDescriptor20 *)tmp;
   printf("found at 0x%0x\n", (uint32_t)(uint64_t)tmp);
   break;
  }
 }
 if(RSDP == ((void*)0)) {
  printf("not found\n");
  return -1;
 }
 char acpi_OEMID[7];
 memset(acpi_OEMID, 0, 7);
 memcpy(acpi_OEMID, (char *)RSDP->OEMID, 6);
 printf("acpi: OEM='%s' rev=%u RSDT=0x%x",
   acpi_OEMID,
   RSDP->Revision,
   RSDP->RsdtAddress);
 if((uint32_t)RSDP->Revision >= 2) {
  printf("len=%x XSDT=0x%lx",
    RSDP->Length,
    RSDP->XsdtAddress);
 }
 printf("\n");
 int RSDT_ent;
 int XSDT_ent;
 RSDT = (struct ACPIRSDT *)(uint64_t)RSDP->RsdtAddress;
 RSDT_ent = (RSDT->h.Length - sizeof(RSDT->h)) / sizeof(uint32_t);
 printf("acpi: %c%c%c%c: len=%x oemrev=%x cID=%x crev=%x rsdt[%u]=0x%p\n",
   RSDT->h.Signature[0], RSDT->h.Signature[1],
   RSDT->h.Signature[2], RSDT->h.Signature[3],
   RSDT->h.Length, RSDT->h.OEMRevision, RSDT->h.CreatorID,
   RSDT->h.CreatorRevision,
   RSDT_ent,
   (void *)RSDT);
 for(int i = 0; i < RSDT_ent; i++) {
  decode_sdt((struct ACPISDTHeader *)(uint64_t)RSDT->otherSDT[i]);
 }
 if(RSDP->Revision >= 2 && RSDP->XsdtAddress) {
  XSDT = (struct ACPIXSDT *)(uint64_t)RSDP->XsdtAddress;
  XSDT_ent = (XSDT->h.Length - sizeof(XSDT->h)) / sizeof(uint64_t);
  if((void *)XSDT == (void *)RSDT)
   printf("acpi: XSDT exists and points to RSDT ");
  else
   printf("acpi: XSDT differs from RSDT ");
  printf("XSDT[%u]=0x%p\n",
    XSDT_ent,
    (void *)XSDT);
 }
 return 0;
}

canonical_original_code:
int acpi_probe()
{
 char *tmp;
 unsigned long offset;
 RSDP = ((void *)0);
 RSDT = ((void *)0);
 XSDT = ((void *)0);
 printf("acpi_probe: ");
 for(offset = 0xe000; offset < 0xFFFFF; offset+=16)
 {
  tmp = (char *)(0 + offset);
  if(*(unsigned long *)tmp == acpi_id) {
   RSDP = (struct RSDPDescriptor20 *)tmp;
   printf("found at 0x%0x\n", (unsigned int)(unsigned long)tmp);
   break;
  }
 }
 if(RSDP == ((void *)0)) {
  printf("not found\n");
  return -1;
 }
 char acpi_OEMID[7];
 memset(acpi_OEMID, 0, 7);
 memcpy(acpi_OEMID, (char *)RSDP->OEMID, 6);
 printf("acpi: OEM='%s' rev=%u RSDT=0x%x",
   acpi_OEMID,
   RSDP->Revision,
   RSDP->RsdtAddress);
 if((unsigned int)RSDP->Revision >= 2) {
  printf("len=%x XSDT=0x%lx",
    RSDP->Length,
    RSDP->XsdtAddress);
 }
 printf("\n");
 int RSDT_ent;
 int XSDT_ent;
 RSDT = (struct ACPIRSDT *)(unsigned long)RSDP->RsdtAddress;
 RSDT_ent = (RSDT->h.Length - sizeof(RSDT->h)) / sizeof(unsigned int);
 printf("acpi: %c%c%c%c: len=%x oemrev=%x cID=%x crev=%x rsdt[%u]=0x%p\n",
   RSDT->h.Signature[0], RSDT->h.Signature[1],
   RSDT->h.Signature[2], RSDT->h.Signature[3],
   RSDT->h.Length, RSDT->h.OEMRevision, RSDT->h.CreatorID,
   RSDT->h.CreatorRevision,
   RSDT_ent,
   (void *)RSDT);
 for(int i = 0; i < RSDT_ent; i++) {
  decode_sdt((struct ACPISDTHeader *)(unsigned long)RSDT->otherSDT[i]);
 }
 if(RSDP->Revision >= 2 && RSDP->XsdtAddress) {
  XSDT = (struct ACPIXSDT *)(unsigned long)RSDP->XsdtAddress;
  XSDT_ent = (XSDT->h.Length - sizeof(XSDT->h)) / sizeof(unsigned long);
  if((void *)XSDT == (void *)RSDT)
   printf("acpi: XSDT exists and points to RSDT ");
  else
   printf("acpi: XSDT differs from RSDT ");
  printf("XSDT[%u]=0x%p\n",
    XSDT_ent,
    (void *)XSDT);
 }
 return 0;
}

variable_types:
tmp
char *

variable_types:
offset
unsigned long

variable_types: i int

return_type: int

user_defined_types: struct RSDPDescriptor20 { char Signature[8]; unsigned char Checksum; char OEMID[6]; unsigned char Revision; unsigned int RsdtAddress; unsigned int Length; unsigned long XsdtAddress; unsigned char ExtendedChecksum; unsigned char reserved[3]; }

user_defined_types: struct ACPIRSDT { struct ACPISDTHeader h; unsigned int otherSDT[]; }

user_defined_types: struct ACPISDTHeader { char Signature[4]; unsigned int Length; unsigned char Revision; unsigned char Checksum; char OEMID[6]; char OEMTableID[8]; unsigned int OEMRevision; unsigned int CreatorID; unsigned int CreatorRevision; }

user_defined_types: struct ACPIXSDT { struct ACPISDTHeader h; unsigned long otherSDT[]; }


decompiled_code:
void __noreturn show_usage()
{
fwrite("Usage: mkfs.ffs [-f] file|device\n", 1uLL, 0x21uLL, stderr);
exit(1);
}

canonical_decompiled_code:
void __noreturn func7()
{
fwrite("Usage: mkfs.ffs [-f] file|device\n", 1uLL, 0x21uLL, stderr);
exit(1);
}

original_code:
static __attribute__((noreturn)) void show_usage()
{
 fprintf(stderr, "Usage: mkfs.ffs [-f] file|device\n");
 exit(1);
}

canonical_original_code:
static void show_usage()
{
 fprintf(stderr, "Usage: mkfs.ffs [-f] file|device\n");
 exit(1);
}


original_code:
static void ffs_format(int fd, off_t bytes, int blksize)
{
 const ffs_superblock sb = {
  .magic = "FAILFS",
  .block_type = FFS_BT_SUPER,
  .block_size = blksize,
  .num_blocks = bytes / blksize,
  .root_block = 3,
  .free_block = 4
 };
 if( lseek(fd, blksize * 2, 0) == (off_t)-1 )
  err(1, "lseek");
 if( write(fd, &sb, sizeof(sb)) != sizeof(sb) )
  err(1, "write(superblock)");
    const ffs_file_block root = {
        .magic = "FAILFS",
        .block_type = FFS_BT_FILE,
        .size = 0,
        .type = FFS_FT_DIR,
        .flags = 0,
        .owner = 0,
        .group = 0,
        .perms = 0755,
        .major = 0,
        .minor = 0,
        .atime = time(0),
        .mtime = time(0),
        .ctime = time(0),
        .name = "/",
        .child = 0,
        .next = 0,
        .parent = 0,
    };
    if( lseek(fd, blksize * sb.root_block, 0) == (off_t)-1 ) {
        err(1, "lseek"); }
    if( write(fd, &root, sizeof(root)) != sizeof(root) ) {
  err(1, "write(root)"); }
 const int fb_len = (blksize - sizeof(ffs_free_block));
 const int num_fb = sb.num_blocks / (fb_len * 64);
 printf("mkfs.failfs: %u free blocks required for %u total blocks of %u bytes\n",
   num_fb,
   sb.num_blocks,
   blksize
   );
 ffs_free_block **fb;
 if( (fb = calloc(num_fb, sizeof(ffs_free_block *))) == ((void *)0) )
  err(1, "calloc");
 for( int i = 0; i < num_fb; i++ )
 {
  if ( (fb[i] = calloc(1, sizeof(ffs_free_block) + fb_len)) == ((void *)0) )
   err(1, "malloc");
  *fb[i] = (ffs_free_block){
   .magic = "FAILFS",
   .block_type = FFS_BT_FREE,
   .len = fb_len,
   .next = (i + 1 == num_fb) ? 0 : sb.free_block + i + 1,
   .prev = (i == 0) ? 0 : sb.free_block + i - 1,
   .flags = 0
  };
 }
 fb[0]->data[0] |= 0x1|0x2|0x4|0x8;
 for( int i = 0; i < num_fb; i++ )
  fb[0]->data[0] |= (1 << (i + 4));
 for( int i = 0; i < num_fb; i++ )
 {
  printf("mkfs.failfs: writing sector %d\n", (sb.free_block + i));
  if( lseek(fd, (sb.free_block + i) * blksize, 0) == -1 )
   err(1, "lseek");
  if( write(fd, fb[i], sizeof(ffs_free_block) + fb_len) != (int)(sizeof(ffs_free_block) + fb_len) )
   err(1, "write(freeblock:%d)", i);
 }
 for( int i = 0; i < num_fb; i++ )
  if(fb[i])
   free(fb[i]);
 free(fb);
}

canonical_original_code:
static void ffs_format(int fd, long bytes, int blksize)
{
 struct _ffs_superblock sb = {
  .magic = "FAILFS",
  .block_type = FFS_BT_SUPER,
  .block_size = blksize,
  .num_blocks = bytes / blksize,
  .root_block = 3,
  .free_block = 4
 };
 if( lseek(fd, blksize * 2, 0) == (off_t)-1 )
  err(1, "lseek");
 if( write(fd, &sb, sizeof(sb)) != sizeof(sb) )
  err(1, "write(superblock)");
    struct _ffs_file_block root = {
        .magic = "FAILFS",
        .block_type = FFS_BT_FILE,
        .size = 0,
        .type = FFS_FT_DIR,
        .flags = 0,
        .owner = 0,
        .group = 0,
        .perms = 0755,
        .major = 0,
        .minor = 0,
        .atime = time(0),
        .mtime = time(0),
        .ctime = time(0),
        .name = "/",
        .child = 0,
        .next = 0,
        .parent = 0,
    };
    if( lseek(fd, blksize * sb.root_block, 0) == (off_t)-1 ) {
        err(1, "lseek"); }
    if( write(fd, &root, sizeof(root)) != sizeof(root) ) {
  err(1, "write(root)"); }
 int fb_len = (blksize - sizeof(ffs_free_block));
 int num_fb = sb.num_blocks / (fb_len * 64);
 printf("mkfs.failfs: %u free blocks required for %u total blocks of %u bytes\n",
   num_fb,
   sb.num_blocks,
   blksize
   );
 struct _ffs_free_block **fb;
 if( (fb = calloc(num_fb, sizeof(struct _ffs_free_block *))) == ((void *)0) )
  err(1, "calloc");
 for( int i = 0; i < num_fb; i++ )
 {
  if ( (fb[i] = calloc(1, sizeof(ffs_free_block) + fb_len)) == ((void *)0) )
   err(1, "malloc");
  *fb[i] = (struct _ffs_free_block){
   .magic = "FAILFS",
   .block_type = FFS_BT_FREE,
   .len = fb_len,
   .next = (i + 1 == num_fb) ? 0 : sb.free_block + i + 1,
   .prev = (i == 0) ? 0 : sb.free_block + i - 1,
   .flags = 0
  };
 }
 fb[0]->data[0] |= 0x1|0x2|0x4|0x8;
 for( int i = 0; i < num_fb; i++ )
  fb[0]->data[0] |= (1 << (i + 4));
 for( int i = 0; i < num_fb; i++ )
 {
  printf("mkfs.failfs: writing sector %d\n", (sb.free_block + i));
  if( lseek(fd, (sb.free_block + i) * blksize, 0) == -1 )
   err(1, "lseek");
  if( write(fd, fb[i], sizeof(ffs_free_block) + fb_len) != (int)(sizeof(ffs_free_block) + fb_len) )
   err(1, "write(freeblock:%d)", i);
 }
 for( int i = 0; i < num_fb; i++ )
  if(fb[i])
   free(fb[i]);
 free(fb);
}

variable_types: fd int

variable_types: bytes long

variable_types: blksize int

variable_types: struct _ffs_superblock { unsigned char magic[6]; unsigned short block_type; unsigned short block_size; unsigned int num_blocks; unsigned short root_block; unsigned short free_block; }

variable_types: struct _ffs_file_block { unsigned char magic[6]; unsigned short block_type; unsigned short type; char name[128]; unsigned int child; unsigned int parent; unsigned int next; unsigned int target; unsigned long size; unsigned long flags; unsigned int owner; unsigned int group; unsigned long perms; unsigned short major; unsigned short minor; unsigned long nlink; unsigned long atime; unsigned int data; unsigned long res[4]; }

variable_types: struct _ffs_free_block { unsigned char magic[6]; unsigned short block_type; unsigned short len; unsigned short pad0; unsigned int next; unsigned int prev; unsigned long flags; unsigned long res[4]; unsigned long data[]; } **


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // ebx
int v4; // eax
int v5; // ebx
struct stat v7; // [rsp+0h] [rbp-A8h] BYREF

while ( 1 )
{
v3 = getopt(argc, (char *const *)argv, "fb:");
if ( v3 == -1 )
break;
if ( v3 == 98 )
{
opt_blksize = atoi(optarg);
}
else
{
if ( v3 != 102 )
{
if ( ((*__ctype_b_loc())[v3] & 0x4000) == 0 )
v3 = 63;
warnx("Unknown option '%c'\n", v3);
show_usage();
}
opt_force = 1;
}
}
if ( !opt_blksize )
opt_blksize = 512;
if ( argc - optind != 1 )
{
warnx("Missing file or device\n");
show_usage();
}
if ( !opt_force )
errx(1, "please pass -f to erase file or device");
v4 = open(argv[optind], 2);
v5 = v4;
if ( v4 == -1 )
err(1, "open: %s\n", argv[optind]);
if ( (unsigned int)fstat(v4, &v7) == -1 )
err(1, "stat: %s\n", argv[optind]);
if ( (v7.st_mode & 0xF000) != 0x8000 )
err(1, "%s is not a regular file", argv[optind]);
ffs_format(v5, v7.st_size, opt_blksize);
close(v5);
puts("mkfs.failfs: done");
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // ebx
int v4; // eax
int v5; // ebx
struct stat v7; // [rsp+0h] [rbp-A8h] BYREF

while ( 1 )
{
v3 = getopt(argc, (char *const *)argv, "fb:");
if ( v3 == -1 )
break;
if ( v3 == 98 )
{
opt_blksize = atoi(optarg);
}
else
{
if ( v3 != 102 )
{
if ( ((*__ctype_b_loc())[v3] & 0x4000) == 0 )
v3 = 63;
warnx("Unknown option '%c'\n", v3);
func7();
}
opt_force = 1;
}
}
if ( !opt_blksize )
opt_blksize = 512;
if ( argc - optind != 1 )
{
warnx("Missing file or device\n");
func7();
}
if ( !opt_force )
errx(1, "please pass -f to erase file or device");
v4 = open(argv[optind], 2);
v5 = v4;
if ( v4 == -1 )
err(1, "open: %s\n", argv[optind]);
if ( (unsigned int)func11(v4, &v7) == -1 )
err(1, "stat: %s\n", argv[optind]);
if ( (v7.st_mode & 0xF000) != 0x8000 )
err(1, "%s is not a regular file", argv[optind]);
func8(v5, v7.st_size, opt_blksize);
close(v5);
puts("mkfs.failfs: done");
return 0;
}

original_code:
int main(int argc, char *argv[])
{
 int opt;
 while( (opt = getopt(argc, argv, "fb:")) != -1 )
 {
  switch( opt ) {
   case 'f':
    opt_force = 1;
    break;
   case 'b':
    opt_blksize = atoi(optarg);
    break;
   default:
    warnx("Unknown option '%c'\n", ((*__ctype_b_loc ())[(int) ((opt))] & (unsigned short int) _ISprint) ? opt : '?');
    show_usage();
  }
 }
 if( opt_blksize == 0 )
  opt_blksize = 512;
 if( (argc - optind) != 1 ) {
  warnx("Missing file or device\n");
  show_usage();
 }
 if( !opt_force )
  errx(1, "please pass -f to erase file or device");
 int fd;
 if( (fd = open(argv[optind], 02)) == -1 )
  err(1, "open: %s\n", argv[optind]);
 struct stat sb;
 if( fstat(fd, &sb) == -1 )
  err(1, "stat: %s\n", argv[optind]);
 if( (sb.st_mode & 0170000) != 0100000 )
  err(1, "%s is not a regular file", argv[optind]);
 ffs_format(fd, sb.st_size, opt_blksize);
 close(fd);
 printf("mkfs.failfs: done\n");
}

canonical_original_code:
int main(int argc, char *argv[])
{
 int opt;
 while( (opt = getopt(argc, argv, "fb:")) != -1 )
 {
  switch( opt ) {
   case 'f':
    opt_force = 1;
    break;
   case 'b':
    opt_blksize = atoi(optarg);
    break;
   default:
    warnx("Unknown option '%c'\n", ((*__ctype_b_loc ())[(int) ((opt))] & (unsigned short) _ISprint) ? opt : '?');
    show_usage();
  }
 }
 if( opt_blksize == 0 )
  opt_blksize = 512;
 if( (argc - optind) != 1 ) {
  warnx("Missing file or device\n");
  show_usage();
 }
 if( !opt_force )
  errx(1, "please pass -f to erase file or device");
 int fd;
 if( (fd = open(argv[optind], 02)) == -1 )
  err(1, "open: %s\n", argv[optind]);
 struct stat sb;
 if( fstat(fd, &sb) == -1 )
  err(1, "stat: %s\n", argv[optind]);
 if( (sb.st_mode & 0170000) != 0100000 )
  err(1, "%s is not a regular file", argv[optind]);
 ffs_format(fd, sb.st_size, opt_blksize);
 close(fd);
 printf("mkfs.failfs: done\n");
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: opt int

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }

user_defined_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


insw

decompiled_code:
__int64 __fastcall insw(unsigned int a1, unsigned __int16 *a2, unsigned int a3)
{
__int64 result; // rax

result = a1;
__inwordstring(a1, a2, a3);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int a1, unsigned __int16 *a2, unsigned int a3)
{
__int64 result; // rax

result = a1;
__inwordstring(a1, a2, a3);
return result;
}

original_code:
__attribute__((unused)) static inline void insw (unsigned short _port, void *addr, uint64_t _cnt)
{
 __asm__ volatile (
   "cld ; rep ; insw"
   : "=D" (addr), "=c" (_cnt)
   : "d" (_port), "0" (addr), "1" (_cnt)
   : "memory"
   );
}

canonical_original_code:
static inline void insw(unsigned short _port, void *addr, unsigned long _cnt)
{
 __asm__ volatile (
   "cld ; rep ; insw"
   : "=D" (addr), "=c" (_cnt)
   : "d" (_port), "0" (addr), "1" (_cnt)
   : "memory"
   );
}

variable_types:
addr
void *


outw

decompiled_code:
void __fastcall outw(unsigned __int16 a1, unsigned __int16 *a2, unsigned int a3)
{
__outwordstring(a1, a2, a3);
}

canonical_decompiled_code:
void __fastcall func1(unsigned __int16 a1, unsigned __int16 *a2, unsigned int a3)
{
__outwordstring(a1, a2, a3);
}

original_code:
__attribute__((unused)) static inline void outw (unsigned short _port, const void *addr, uint64_t _cnt)
{
 __asm__ volatile (
   "cld ; rep ; outsw"
   : "=S" (addr), "=c" (_cnt)
   : "d" (_port), "0" (addr), "1" (_cnt)
   : "memory"
   );
}

canonical_original_code:
static inline void outw(unsigned short _port, void *addr, unsigned long _cnt)
{
 __asm__ volatile (
   "cld ; rep ; outsw"
   : "=S" (addr), "=c" (_cnt)
   : "d" (_port), "0" (addr), "1" (_cnt)
   : "memory"
   );
}


decompiled_code:
__int64 __fastcall ide_wait(__int16 a1, unsigned __int8 a2, char *a3)
{
__int64 v4; // rbx
char v6; // [rsp+Fh] [rbp-29h]

v4 = 10000LL;
while ( 1 )
{
v6 = inportb((unsigned __int16)(a1 + 7));
*a3 = v6;
if ( v6 >= 0 )
{
if ( (v6 & 1) != 0 )
return 0LL;
if ( (a2 & (unsigned __int8)v6) != 0 )
break;
}
_mm_pause();
if ( !--v4 )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int16 a1, unsigned __int8 a2, char *a3)
{
__int64 v4; // rbx
char v6; // [rsp+Fh] [rbp-29h]

v4 = 10000LL;
while ( 1 )
{
v6 = inportb((unsigned __int16)(a1 + 7));
*a3 = v6;
if ( v6 >= 0 )
{
if ( (v6 & 1) != 0 )
return 0LL;
if ( (a2 & (unsigned __int8)v6) != 0 )
break;
}
_mm_pause();
if ( !--v4 )
return 0LL;
}
return 1LL;
}

original_code:
__attribute__((nonnull)) static bool ide_wait(uint16_t cmd, uint8_t mask, uint8_t *code)
{
 uint64_t cnt;
 volatile uint8_t t8;
 cnt = 10000;
 while(cnt--)
 {
  *code = t8 = inportb(cmd + 0x07);
  __asm__ volatile("nop":::"memory");
  if(t8 & 0x80) __asm__ volatile("pause");
  else if(t8 & 0x01) return 0;
  else if(t8 & mask) return 1;
  else __asm__ volatile("pause");
 }
 return 0;
}

canonical_original_code:
static _Bool ide_wait(unsigned short cmd, unsigned char mask, unsigned char *code)
{
 unsigned long cnt;
 unsigned char t8;
 cnt = 10000;
 while(cnt--)
 {
  *code = t8 = inportb(cmd + 0x07);
  __asm__ volatile("nop":::"memory");
  if(t8 & 0x80) __asm__ volatile("pause");
  else if(t8 & 0x01) return 0;
  else if(t8 & mask) return 1;
  else __asm__ volatile("pause");
 }
 return 0;
}

variable_types:
cmd
unsigned short

variable_types:
mask
unsigned char

variable_types:
code
unsigned char *

variable_types:
cnt
unsigned long


decompiled_code:
__int64 __fastcall init_ide(__int64 a1)
{
unsigned int v2; // ebp
unsigned __int16 v3; // r12
unsigned __int16 v4; // ax

v2 = *(_DWORD *)(a1 + 124);
printf("init_ide: called on pci_dev:0x%p IO:%x\n", (const void *)a1, v2);
v3 = pci_read_conf16(*(unsigned __int8 *)(a1 + 8), *(unsigned __int8 *)(a1 + 9), *(unsigned __int8 *)(a1 + 10), 4LL);
pci_write_conf16(
*(unsigned __int8 *)(a1 + 8),
*(unsigned __int8 *)(a1 + 9),
*(unsigned __int8 *)(a1 + 10),
4LL,
v3 | 1u);
if ( (v3 & 4) == 0 )
{
pci_write_conf16(
*(unsigned __int8 *)(a1 + 8),
*(unsigned __int8 *)(a1 + 9),
*(unsigned __int8 *)(a1 + 10),
4LL,
v3 | 4u);
printf("init_ide: enabling PCI master bit\n");
}
v4 = pci_read_conf16(*(unsigned __int8 *)(a1 + 8), *(unsigned __int8 *)(a1 + 9), *(unsigned __int8 *)(a1 + 10), 72LL);
pci_write_conf16(
*(unsigned __int8 *)(a1 + 8),
*(unsigned __int8 *)(a1 + 9),
*(unsigned __int8 *)(a1 + 10),
72LL,
v4 | 0xFu);
outportw((unsigned __int16)(v2 + 64), 17LL);
init_ide_port(0x1F0u, 0);
return init_ide_port(0x170u, 1u);
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
unsigned int v2; // ebp
unsigned __int16 v3; // r12
unsigned __int16 v4; // ax

v2 = *(_DWORD *)(a1 + 124);
printf("init_ide: called on pci_dev:0x%p IO:%x\n", (const void *)a1, v2);
v3 = pci_read_conf16(*(unsigned __int8 *)(a1 + 8), *(unsigned __int8 *)(a1 + 9), *(unsigned __int8 *)(a1 + 10), 4LL);
pci_write_conf16(
*(unsigned __int8 *)(a1 + 8),
*(unsigned __int8 *)(a1 + 9),
*(unsigned __int8 *)(a1 + 10),
4LL,
v3 | 1u);
if ( (v3 & 4) == 0 )
{
pci_write_conf16(
*(unsigned __int8 *)(a1 + 8),
*(unsigned __int8 *)(a1 + 9),
*(unsigned __int8 *)(a1 + 10),
4LL,
v3 | 4u);
printf("init_ide: enabling PCI master bit\n");
}
v4 = pci_read_conf16(*(unsigned __int8 *)(a1 + 8), *(unsigned __int8 *)(a1 + 9), *(unsigned __int8 *)(a1 + 10), 72LL);
pci_write_conf16(
*(unsigned __int8 *)(a1 + 8),
*(unsigned __int8 *)(a1 + 9),
*(unsigned __int8 *)(a1 + 10),
72LL,
v4 | 0xFu);
outportw((unsigned __int16)(v2 + 64), 17LL);
func8(0x1F0u, 0);
return func8(0x170u, 1u);
}

original_code:
__attribute__((nonnull)) void init_ide(struct pci_dev *const d)
{
 uint32_t io = d->bars[4].addr;
 uint16_t tmp,t16;
 printf("init_ide: called on pci_dev:0x%p IO:%x\n", (void *)d, io);
 tmp = pci_read_conf16(d->bus, d->dev, d->func, 0x4);
 pci_write_conf16(d->bus, d->dev, d->func, 0x4,
   tmp|0x1);
 if(!(tmp & 0x04)) {
  pci_write_conf16(d->bus, d->dev, d->func, 0x4,
    tmp|0x04);
  printf("init_ide: enabling PCI master bit\n");
 }
 t16 = pci_read_conf16(d->bus, d->dev, d->func, 0x48);
 pci_write_conf16(d->bus, d->dev, d->func, 0x48,
   t16|(1 << 3)|(1 << 2)|(1 << 1)|(1 << 0));
 outportw(io + 0x40, (1 << 0)|(1 << 4));
 init_ide_port(0x01f0, 0);
 init_ide_port(0x0170, 1);
}

canonical_original_code:
void init_ide(struct pci_dev *d)
{
 unsigned int io = d->bars[4].addr;
 unsigned short tmp; unsigned short t16;
 printf("init_ide: called on pci_dev:0x%p IO:%x\n", (void *)d, io);
 tmp = pci_read_conf16(d->bus, d->dev, d->func, 0x4);
 pci_write_conf16(d->bus, d->dev, d->func, 0x4,
   tmp|0x1);
 if(!(tmp & 0x04)) {
  pci_write_conf16(d->bus, d->dev, d->func, 0x4,
    tmp|0x04);
  printf("init_ide: enabling PCI master bit\n");
 }
 t16 = pci_read_conf16(d->bus, d->dev, d->func, 0x48);
 pci_write_conf16(d->bus, d->dev, d->func, 0x48,
   t16|(1 << 3)|(1 << 2)|(1 << 1)|(1 << 0));
 outportw(io + 0x40, (1 << 0)|(1 << 4));
 init_ide_port(0x01f0, 0);
 init_ide_port(0x0170, 1);
}

variable_types: struct pci_dev { struct pci_dev *next; unsigned char bus; struct pcicfg { unsigned short vendor_id; unsigned short device_id; unsigned short cmd_reg; unsigned short status_reg; unsigned int rev; unsigned char progif; unsigned char subclass; unsigned char class_code; unsigned char pad0; unsigned char pad1; unsigned char header_type; unsigned char pad2; unsigned int bar[6]; unsigned int pad3; unsigned short sub_vendor_id; unsigned short sub_id; unsigned int pad4; unsigned int pad5; unsigned int res0; unsigned int res1; unsigned char int_line; unsigned char int_pin; unsigned char pad6; unsigned char pad7; } cfg; struct pcibar { unsigned int addr; unsigned int len; union { struct { unsigned char pad; } io; struct { unsigned char bits; unsigned char prefs; } mem; } un; _Bool mem; } bars[6]; } *

variable_types:
io
unsigned int

variable_types:
tmp
unsigned short

user_defined_types: struct pci_dev { struct pci_dev *next; unsigned char bus; struct pcicfg cfg; struct pcibar bars[6]; }


checksum

decompiled_code:
__int64 __fastcall checksum(unsigned __int8 *a1, unsigned int a2)
{
unsigned __int8 *v2; // rcx
unsigned int v3; // eax

if ( a2 <= 1 )
{
v2 = a1;
v3 = 0;
}
else
{
v2 = &a1[2 * ((a2 - 2) >> 1) + 2];
v3 = 0;
do
{
a1 += 2;
v3 += *((unsigned __int16 *)a1 - 1);
}
while ( a1 != v2 );
a2 &= 1u;
}
if ( a2 )
v3 += *v2;
return ~((unsigned __int16)v3 + HIWORD(v3) + ((unsigned int)((unsigned __int16)v3 + HIWORD(v3)) >> 16));
}

canonical_decompiled_code:
__int64 __fastcall func9(unsigned __int8 *a1, unsigned int a2)
{
unsigned __int8 *v2; // rcx
unsigned int v3; // eax

if ( a2 <= 1 )
{
v2 = a1;
v3 = 0;
}
else
{
v2 = &a1[2 * ((a2 - 2) >> 1) + 2];
v3 = 0;
do
{
a1 += 2;
v3 += *((unsigned __int16 *)a1 - 1);
}
while ( a1 != v2 );
a2 &= 1u;
}
if ( a2 )
v3 += *v2;
return ~((unsigned __int16)v3 + HIWORD(v3) + ((unsigned int)((unsigned __int16)v3 + HIWORD(v3)) >> 16));
}

original_code:
uint16_t checksum(uint16_t *data, uint32_t len)
{
 uint32_t sum;
 for(sum=0; len>1; len-=2)
  sum += *data++;
 if(len) sum += *(uint8_t*)data;
 sum = (sum >> 16) + (sum & 0xffff);
 sum += (sum >> 16);
 sum = ~sum;
 return (uint16_t)sum;
}

canonical_original_code:
unsigned short checksum(unsigned short *data, unsigned int len)
{
 unsigned int sum;
 for(sum=0; len>1; len-=2)
  sum += *data++;
 if(len) sum += *(unsigned char *)data;
 sum = (sum >> 16) + (sum & 0xffff);
 sum += (sum >> 16);
 sum = ~sum;
 return (unsigned short)sum;
}

variable_types:
data
unsigned short *

variable_types:
len
unsigned int

variable_types:
sum
unsigned int

return_type: unsigned short


repo: juxstapose/stykfighta

decompiled_code:
void log_init()
{
debug_level = 0;
}

canonical_decompiled_code:
void func0()
{
debug_level = 0;
}

original_code:
void log_init() {
    _debug_level = 0;
}

canonical_original_code:
void log_init() {
    _debug_level = 0;
}


decompiled_code:
void __fastcall log_set_debug_level(int a1)
{
debug_level = a1;
}

canonical_decompiled_code:
void __fastcall func1(int a1)
{
debug_level = a1;
}

original_code:
void log_set_debug_level(int debug_level) {
    _debug_level = debug_level;
}


decompiled_code:
int __fastcall log_file_open(const char *a1)
{
FILE *v1; // rax

v1 = fopen(a1, "w");
lfp = v1;
if ( !v1 )
LODWORD(v1) = fclose(0LL);
return (int)v1;
}

canonical_decompiled_code:
int __fastcall func2(const char *a1)
{
FILE *v1; // rax

v1 = fopen(a1, "w");
lfp = v1;
if ( !v1 )
LODWORD(v1) = fclose(0LL);
return (int)v1;
}

original_code:
void log_file_open(const char* filename) {
    _lfp = fopen(filename, "w");
    if(_lfp == ((void *)0)) {
        fclose(_lfp);
    }
}

canonical_original_code:
void log_file_open(char *filename) {
    _lfp = fopen(filename, "w");
    if(_lfp == ((void *)0)) {
        fclose(_lfp);
    }
}

variable_types:
filename
char *


decompiled_code:
int log_file_close()
{
return fclose(lfp);
}

canonical_decompiled_code:
int func3()
{
return fclose(lfp);
}

original_code:
void log_file_close() {
    fclose(_lfp);
}

canonical_original_code:
void log_file_close() {
    fclose(_lfp);
}


decompiled_code:
__int64 log_msg(int a1, const char *a2, ...)
{
unsigned int v2; // ebx
FILE *v4; // rbp
size_t v5; // rax
gcc_va_list arg; // [rsp+8h] [rbp-40E0h] BYREF
char s[8]; // [rsp+20h] [rbp-40C8h] BYREF

v2 = 0;
if ( debug_level <= a1 )
{
va_start(arg, a2);
if ( a1 )
{
if ( a1 == 1 )
{
strcpy(s, "INFO: ");
v2 = vsnprintf(&s[6], 0x3FFAuLL, a2, arg) + 6;
}
else
{
v2 = 0;
if ( a1 == 2 )
{
strcpy(s, "ERROR: ");
v2 = vsnprintf(&s[7], 0x3FF9uLL, a2, arg) + 7;
}
}
}
else
{
strcpy(s, "DEBUG: ");
v2 = vsnprintf(&s[7], 0x3FF9uLL, a2, arg) + 7;
}
printf("%s", s);
v4 = lfp;
if ( lfp )
{
v5 = strlen(s);
fwrite(s, 1uLL, v5, v4);
}
}
return v2;
}

canonical_decompiled_code:
__int64 func4(int a1, const char *a2, ...)
{
unsigned int v2; // ebx
FILE *v4; // rbp
size_t v5; // rax
gcc_va_list arg; // [rsp+8h] [rbp-40E0h] BYREF
char s[8]; // [rsp+20h] [rbp-40C8h] BYREF

v2 = 0;
if ( debug_level <= a1 )
{
va_start(arg, a2);
if ( a1 )
{
if ( a1 == 1 )
{
strcpy(s, "INFO: ");
v2 = vsnprintf(&s[6], 0x3FFAuLL, a2, arg) + 6;
}
else
{
v2 = 0;
if ( a1 == 2 )
{
strcpy(s, "ERROR: ");
v2 = vsnprintf(&s[7], 0x3FF9uLL, a2, arg) + 7;
}
}
}
else
{
strcpy(s, "DEBUG: ");
v2 = vsnprintf(&s[7], 0x3FF9uLL, a2, arg) + 7;
}
printf("%s", s);
v4 = lfp;
if ( lfp )
{
v5 = strlen(s);
fwrite(s, 1uLL, v5, v4);
}
}
return v2;
}

original_code:
int log_msg(int debug_level, const char* format, ...) {
    if(debug_level < _debug_level) {
        return 0;
    }
    char dest[1024 * 16];
    int count = 0;
    va_list arglist;
    __builtin_va_start(arglist,format);
    if(debug_level == 0) {
        strcpy(dest, "DEBUG: ");
        count = vsnprintf(&dest[7], 1024*16-7, format, arglist);
        count+=7;
    }
    if(debug_level == 1) {
        strcpy(dest, "INFO: ");
        count = vsnprintf(&dest[6], 1024*16-6, format, arglist);
        count+=6;
    }
    if(debug_level == 2) {
        strcpy(dest, "ERROR: ");
        count = vsnprintf(&dest[7], 1024*16-7, format, arglist);
        count+=7;
    }
    printf("%s", dest);
    if(_lfp != ((void *)0)) {
        fwrite(dest, 1, strlen(dest), _lfp);
    }
    __builtin_va_end(arglist);
    return count;
}

canonical_original_code:
int log_msg(int debug_level, char *format, ...) {
    if(debug_level < _debug_level) {
        return 0;
    }
    char dest[-1];
    int count = 0;
    __builtin_va_list arglist;
    __builtin_va_start(arglist,format);
    if(debug_level == 0) {
        strcpy(dest, "DEBUG: ");
        count = vsnprintf(&dest[7], 1024*16-7, format, arglist);
        count+=7;
    }
    if(debug_level == 1) {
        strcpy(dest, "INFO: ");
        count = vsnprintf(&dest[6], 1024*16-6, format, arglist);
        count+=6;
    }
    if(debug_level == 2) {
        strcpy(dest, "ERROR: ");
        count = vsnprintf(&dest[7], 1024*16-7, format, arglist);
        count+=7;
    }
    printf("%s", dest);
    if(_lfp != ((void *)0)) {
        fwrite(dest, 1, strlen(dest), _lfp);
    }
    __builtin_va_end(arglist);
    return count;
}

variable_types:
format
char *

variable_types:
dest
char [-1]

variable_types: count int


repo: jvirkki/dupd

decompiled_code:
int __fastcall operation_cache_delete(const char *a1)
{
int result; // eax
char v2[4104]; // [rsp+0h] [rbp-1008h] BYREF

result = unlink(a1);
if ( result )
{
snprintf(v2, 0x1000uLL, "unlink %s", a1);
perror(v2);
exit(1);
}
return result;
}

canonical_decompiled_code:
int __fastcall func0(const char *a1)
{
int result; // eax
char v2[4104]; // [rsp+0h] [rbp-1008h] BYREF

result = unlink(a1);
if ( result )
{
snprintf(v2, 0x1000uLL, "unlink %s", a1);
perror(v2);
exit(1);
}
return result;
}

original_code:
void operation_cache_delete(char * path)
{
  int rv = unlink(path);
  if (rv != 0) {
    char line[4096];
    snprintf(line, 4096, "unlink %s", path);
    perror(line);
    exit(1);
  }
}

canonical_original_code:
void operation_cache_delete(char *path)
{
  int rv = unlink(path);
  if (rv != 0) {
    char line[4096];
    snprintf(line, 4096, "unlink %s", path);
    perror(line);
    exit(1);
  }
}

variable_types:
path
char *

variable_types: rv int

variable_types:
line
char [4096]


decompiled_code:
__int64 operation_cache_ls()
{
open_cache_database();
cache_db_list_entries();
return close_cache_database();
}

canonical_decompiled_code:
__int64 func1()
{
open_cache_database();
cache_db_list_entries();
return close_cache_database();
}

original_code:
void operation_cache_ls(char * path)
{
  open_cache_database(path);
  cache_db_list_entries();
  close_cache_database();
}

canonical_original_code:
void operation_cache_ls(char *path)
{
  open_cache_database(path);
  cache_db_list_entries();
  close_cache_database();
}


decompiled_code:
void __fastcall handle_signal(int a1)
{
if ( a1 == 10 )
{
log_level = 9 * (log_level <= 9) + 1;
}
else if ( a1 == 12 )
{
dump_state = 1;
}
}

canonical_decompiled_code:
void __fastcall func0(int a1)
{
if ( a1 == 10 )
{
log_level = 9 * (log_level <= 9) + 1;
}
else if ( a1 == 12 )
{
dump_state = 1;
}
}

original_code:
void handle_signal(int sig)
{
  if (sig == 10) {
    if (log_level < 10) {
      log_level = 10;
    } else {
      log_level = 1;
    }
  } else if (sig == 12) {
    dump_state = 1;
  }
}

variable_types: sig int


decompiled_code:
void free_start_paths()
{
void **v0; // rbx

start_path_count = 0;
v0 = (void **)&start_path;
do
{
if ( *v0 )
{
free(*v0);
*v0 = 0LL;
}
++v0;
}
while ( v0 != (void **)(unsigned int)((_DWORD)&start_path + 80) );
}

canonical_decompiled_code:
void func1()
{
void **v0; // rbx

start_path_count = 0;
v0 = (void **)&start_path;
do
{
if ( *v0 )
{
free(*v0);
*v0 = 0LL;
}
++v0;
}
while ( v0 != (void **)(unsigned int)((_DWORD)&start_path + 80) );
}

original_code:
static void free_start_paths()
{
  start_path_count = 0;
  for (int n = 0; n < 10; n++) {
    if (start_path[n]) {
      free(start_path[n]);
      start_path[n] = ((void *)0);
    }
  }
}

variable_types: n int


decompiled_code:
int show_banner()
{
puts("dupd 2.0-dev Copyright 2012-2020 Jyri J. Virkki");
puts("This program comes with ABSOLUTELY NO WARRANTY.");
puts("This is free software, and you are welcome to redistribute it");
puts("under certain conditions. Run 'dupd license' for details.");
return putchar(10);
}

canonical_decompiled_code:
int func2()
{
puts("dupd 2.0-dev Copyright 2012-2020 Jyri J. Virkki");
puts("This program comes with ABSOLUTELY NO WARRANTY.");
puts("This is free software, and you are welcome to redistribute it");
puts("under certain conditions. Run 'dupd license' for details.");
return putchar(10);
}

original_code:
static void show_banner()
{
  printf("dupd " "2.0-dev" " Copyright 2012-2020 Jyri J. Virkki\n");
  printf("This program comes with ABSOLUTELY NO WARRANTY.\n");
  printf("This is free software, and you are welcome to redistribute it\n");
  printf("under certain conditions. Run 'dupd license' for details.\n");
  printf("\n");
}


decompiled_code:
int show_usage()
{
int result; // eax
__int64 v1; // rbx

result = show_banner();
if ( man_dupd_len )
{
v1 = 0LL;
do
result = putchar(man_dupd[v1++]);
while ( man_dupd_len > (unsigned int)v1 );
}
return result;
}

canonical_decompiled_code:
int func3()
{
int result; // eax
__int64 v1; // rbx

result = func2();
if ( man_dupd_len )
{
v1 = 0LL;
do
result = putchar(man_dupd[v1++]);
while ( man_dupd_len > (unsigned int)v1 );
}
return result;
}

original_code:
static void show_usage()
{
  show_banner();
  for (unsigned int c = 0; c < man_dupd_len; c++) {
    putchar((char)man_dupd[c]);
  }
}

variable_types:
c
unsigned int


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

if ( cache_delete )
result = operation_cache_delete(cache_db_path);
if ( cache_ls )
result = operation_cache_ls(cache_db_path);
return result;
}

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

if ( cache_delete )
result = operation_cache_delete(cache_db_path);
if ( cache_ls )
result = operation_cache_ls(cache_db_path);
return result;
}

original_code:
static void operation_cache()
{
  if (cache_delete) { operation_cache_delete(cache_db_path); }
  if (cache_ls) { operation_cache_ls(cache_db_path); }
}


decompiled_code:
__int64 show_help()
{
show_banner();
printf("%% dupd operation options\n");
putchar(10);
return opt_show_help();
}

canonical_decompiled_code:
__int64 func5()
{
func2();
printf("%% dupd operation options\n");
putchar(10);
return opt_show_help();
}

original_code:
static void show_help()
{
  show_banner();
  printf("%% dupd operation options\n");
  printf("\n");
  opt_show_help();
}


decompiled_code:
__int64 __fastcall process_args(__int64 a1, __int64 a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx
unsigned int v4; // eax
int v5; // eax
int v6; // eax
const char *v7; // rbp
const char *v8; // rbp
const char *v9; // rbp
unsigned __int64 v10; // r12
const char *v11; // rdx
__int64 v12; // r12
unsigned int v13; // eax
const char *v14; // rbp
const char *v16; // rax
char *v17; // rbp
char *v18; // rax
char *v19; // rax
unsigned __int64 v20; // rax
unsigned __int64 v21; // rbp
double v22; // xmm0_8
double v23; // xmm0_8
double v24; // xmm0_8
double v25; // xmm0_8
const char *v26; // rax
const char *v27; // rax
unsigned __int64 v28; // r12
const char *v29; // rax
_QWORD v30[19]; // [rsp+0h] [rbp-148h] BYREF
char *src; // [rsp+98h] [rbp-B0h]
_BYTE *v32; // [rsp+A0h] [rbp-A8h]
__int64 v33; // [rsp+A8h] [rbp-A0h]
__int64 v34; // [rsp+B0h] [rbp-98h]
__int64 v35; // [rsp+B8h] [rbp-90h]
__int64 v36; // [rsp+C0h] [rbp-88h]
__int64 v37; // [rsp+C8h] [rbp-80h]
__int64 v38; // [rsp+D0h] [rbp-78h]
__int64 v39; // [rsp+D8h] [rbp-70h]
__int64 v40; // [rsp+E0h] [rbp-68h]
__int64 v41; // [rsp+E8h] [rbp-60h]
char *v42; // [rsp+F0h] [rbp-58h]
char *v43; // [rsp+F8h] [rbp-50h]
__int64 v44; // [rsp+100h] [rbp-48h]
__int64 v45; // [rsp+108h] [rbp-40h]
__int64 v46; // [rsp+110h] [rbp-38h]
__int64 v47; // [rsp+118h] [rbp-30h]
__int64 v48; // [rsp+120h] [rbp-28h]
__int64 v49; // [rsp+128h] [rbp-20h]

using_fiemap = 1;
v2 = optgen_parse(a1, a2, &operation, v30);
if ( v44 )
{
show_help();
return 1;
}
v3 = v2;
if ( v2 == 1 )
{
show_banner();
putchar(10);
puts("Run 'dupd help' for a summary of available options.");
puts("Run 'dupd usage' for more documentation.");
return v3;
}
if ( v2 )
{
puts("error parsing command line arguments");
return 2;
}
if ( v49 )
{
v4 = getpid();
printf("%d\n", v4);
getchar();
}
if ( v45 )
x_small_buffers = 1;
if ( v46 )
only_testing = 1;
if ( v41 )
log_level = -99;
log_level = opt_int(v40, (unsigned int)log_level);
v5 = log_level + opt_count(v39);
if ( v5 > 13 )
v5 = 13;
log_level = v5;
if ( !start_path_state )
{
start_path = (char *)malloc(0x1000uLL);
if ( !getcwd(start_path, 0x1000uLL) )
goto LABEL_75;
start_path_count = 1;
if ( log_level > 3 )
{
pthread_mutex_lock(&logger_lock);
v16 = (const char *)get_thread_name();
printf("%s", v16);
printf("Defaulting --path to [%s]\n", start_path);
fflush(stdout);
pthread_mutex_unlock(&logger_lock);
}
}
if ( src )
{
file_path = src;
if ( *src != 47 )
{
file_path = (char *)malloc(0x1000uLL);
free_file_path = 1;
if ( getcwd(file_path, 0x1000uLL) )
{
v17 = file_path;
*(_WORD *)&v17[strlen(file_path)] = 47;
strcat(file_path, src);
goto LABEL_17;
}
LABEL_75:
puts("error: unable to get current directory");
return 2;
}
}
LABEL_17:
db_path = v42;
if ( !v42 )
{
db_path = (char *)malloc(0x1000uLL);
free_db_path = 1;
v18 = getenv("HOME");
snprintf(db_path, 0x1000uLL, "%s/.dupd_sqlite", v18);
}
cache_db_path = v43;
if ( !v43 )
{
cache_db_path = (char *)malloc(0x1000uLL);
free_cache_db_path = 1;
v19 = getenv("HOME");
snprintf(cache_db_path, 0x1000uLL, "%s/.dupd_cache", v19);
}
if ( v35 )
rmsh_link = 1;
if ( v36 )
rmsh_link = 2;
if ( v30[3] )
scan_hidden = 1;
if ( v30[8] )
threaded_sizetree = 0;
if ( v30[7] )
hardlink_is_unique = 1;
if ( v30[5] )
one_file_system = 1;
if ( v47 )
use_hash_cache = 0;
if ( v33 )
cache_delete = 1;
if ( v34 )
cache_ls = 1;
cache_min_size = (int)opt_int(v48, (unsigned int)cache_min_size);
hash_one_block_size = opt_int(v30[10], (unsigned int)hash_one_block_size);
hash_block_size = opt_int(v30[11], (unsigned int)hash_block_size);
filecmp_block_size = opt_int(v30[12], (unsigned int)filecmp_block_size);
hash_one_max_blocks = opt_int(v30[9], (unsigned int)hash_one_max_blocks);
debug_size = (int)opt_int(v30[16], (unsigned int)debug_size);
cut_path = v30[17];
exclude_path = (__int64)v32;
if ( v32 && *v32 != 47 )
{
puts("error: --exclude-path must be absolute");
return 2;
}
stats_file = v30[1];
trace_file = (char *)v30[6];
info_extents_path = v37;
v6 = opt_int(v30[2], (unsigned int)minimum_file_size);
if ( !v6 )
v6 = 1;
minimum_file_size = v6;
path_sep_string = malloc(2uLL);
*(_WORD *)path_sep_string = (unsigned __int8)path_separator;
v7 = (const char *)opt_string(v38, "xxhash");
if ( !strcmp("md5", v7) )
{
hash_function = 1;
}
else if ( !strcmp("sha1", v7) )
{
hash_function = 2;
}
else if ( !strcmp("sha512", v7) )
{
hash_function = 3;
}
else
{
if ( strcmp("xxhash", v7) )
{
printf("error: unknown hash %s\n", v7);
return 2;
}
hash_function = 4;
}
hash_bufsize = hash_get_bufsize((unsigned int)hash_function);
v8 = (const char *)opt_string(v30[18], "text");
if ( !strcmp("text", v8) )
{
report_format = 1;
}
else if ( !strcmp("csv", v8) )
{
report_format = 2;
}
else
{
if ( strcmp("json", v8) )
{
printf("error: unknown report format %s\n", v8);
return 2;
}
report_format = 3;
}
v9 = (const char *)opt_string(v30[4], "0");
v10 = 0LL;
if ( strcmp("0", v9) )
{
v11 = &v9[(int)strlen(v9) - 1];
if ( *v11 == 77 )
{
*v11 = 0;
v12 = 0x100000LL;
}
else
{
v12 = 1LL;
if ( *v11 == 71 )
{
*v11 = 0;
v12 = 0x40000000LL;
}
}
v10 = atol(v9) * v12;
if ( v10 < 0x800000 )
v10 = 0x800000LL;
}
if ( v30[13] )
opt_compare_two = 1;
if ( !hash_one_block_size )
hash_one_block_size = DEF_HDD_hash_one_block_size;
v13 = hash_one_max_blocks * hash_one_block_size;
round1_max_bytes = hash_one_max_blocks * hash_one_block_size;
if ( !cache_min_size )
{
if ( v13 > 0x7FFFF )
cache_min_size = v13;
else
cache_min_size = 0x80000LL;
}
v14 = (const char *)opt_string(v30[14], "def");
if ( !strcmp("inode", v14) )
{
sort_bypass = 15;
}
else if ( !strcmp("block", v14) )
{
sort_bypass = 13;
}
else if ( !strcmp("none", v14) )
{
sort_bypass = 11;
}
else if ( !sort_bypass )
{
goto LABEL_99;
}
if ( log_level > 3 )
{
pthread_mutex_lock(&logger_lock);
v26 = (const char *)get_thread_name();
printf("%s", v26);
printf("Sort bypass set to %s\n", v14);
fflush(stdout);
pthread_mutex_unlock(&logger_lock);
}
if ( hardlink_is_unique )
{
puts("Don't do that..");
return 2;
}
if ( sort_bypass && sort_bypass != 13 )
using_fiemap = 0;
LABEL_99:
if ( v30[15] )
using_fiemap = 0;
if ( log_level > 3 )
{
pthread_mutex_lock(&logger_lock);
v27 = (const char *)get_thread_name();
printf("%s", v27);
printf("Will be using_fiemap (if available): %d\n", (unsigned int)using_fiemap);
fflush(stdout);
pthread_mutex_unlock(&logger_lock);
}
v20 = total_ram();
v21 = v20;
if ( !v10 )
goto LABEL_109;
if ( v10 > v20 )
{
if ( (v20 & 0x8000000000000000LL) != 0LL )
v22 = (double)(int)(v20 & 1 | (v20 >> 1)) + (double)(int)(v20 & 1 | (v20 >> 1));
else
v22 = (double)(int)v20;
v23 = v22 * 0.9;
if ( v23 >= 9.223372036854776e18 )
{
buffer_limit = (unsigned int)(int)(v23 - 9.223372036854776e18);
buffer_limit ^= 0x8000000000000000LL;
}
else
{
buffer_limit = (unsigned int)(int)v23;
}
LABEL_109:
if ( !buffer_limit )
{
v24 = (v20 & 0x8000000000000000LL) != 0LL ? (double)(int)(v20 & 1 | (v20 >> 1))
+ (double)(int)(v20 & 1 | (v20 >> 1)) : (double)(int)v20;
v25 = v24 * 0.5;
if ( v25 >= 9.223372036854776e18 )
{
buffer_limit = (unsigned int)(int)(v25 - 9.223372036854776e18);
buffer_limit ^= 0x8000000000000000LL;
}
else
{
buffer_limit = (unsigned int)(int)v25;
}
if ( x_small_buffers )
buffer_limit = 0x100000LL;
}
goto LABEL_120;
}
buffer_limit = v10;
LABEL_120:
if ( log_level > 3 )
{
v28 = buffer_limit;
pthread_mutex_lock(&logger_lock);
v29 = (const char *)get_thread_name();
printf("%s", v29);
printf("Reported RAM: %dMB buffer limit: %dMB\n", v21 >> 20, v28 >> 20);
fflush(stdout);
pthread_mutex_unlock(&logger_lock);
}
if ( debug_size && log_level <= 2 )
log_level = 3;
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx
unsigned int v4; // eax
int v5; // eax
int v6; // eax
const char *v7; // rbp
const char *v8; // rbp
const char *v9; // rbp
unsigned __int64 v10; // r12
const char *v11; // rdx
__int64 v12; // r12
unsigned int v13; // eax
const char *v14; // rbp
const char *v16; // rax
char *v17; // rbp
char *v18; // rax
char *v19; // rax
unsigned __int64 v20; // rax
unsigned __int64 v21; // rbp
double v22; // xmm0_8
double v23; // xmm0_8
double v24; // xmm0_8
double v25; // xmm0_8
const char *v26; // rax
const char *v27; // rax
unsigned __int64 v28; // r12
const char *v29; // rax
_QWORD v30[19]; // [rsp+0h] [rbp-148h] BYREF
char *src; // [rsp+98h] [rbp-B0h]
_BYTE *v32; // [rsp+A0h] [rbp-A8h]
__int64 v33; // [rsp+A8h] [rbp-A0h]
__int64 v34; // [rsp+B0h] [rbp-98h]
__int64 v35; // [rsp+B8h] [rbp-90h]
__int64 v36; // [rsp+C0h] [rbp-88h]
__int64 v37; // [rsp+C8h] [rbp-80h]
__int64 v38; // [rsp+D0h] [rbp-78h]
__int64 v39; // [rsp+D8h] [rbp-70h]
__int64 v40; // [rsp+E0h] [rbp-68h]
__int64 v41; // [rsp+E8h] [rbp-60h]
char *v42; // [rsp+F0h] [rbp-58h]
char *v43; // [rsp+F8h] [rbp-50h]
__int64 v44; // [rsp+100h] [rbp-48h]
__int64 v45; // [rsp+108h] [rbp-40h]
__int64 v46; // [rsp+110h] [rbp-38h]
__int64 v47; // [rsp+118h] [rbp-30h]
__int64 v48; // [rsp+120h] [rbp-28h]
__int64 v49; // [rsp+128h] [rbp-20h]

using_fiemap = 1;
v2 = optgen_parse(a1, a2, &operation, v30);
if ( v44 )
{
func5();
return 1;
}
v3 = v2;
if ( v2 == 1 )
{
func2();
putchar(10);
puts("Run 'dupd help' for a summary of available options.");
puts("Run 'dupd usage' for more documentation.");
return v3;
}
if ( v2 )
{
puts("error parsing command line arguments");
return 2;
}
if ( v49 )
{
v4 = getpid();
printf("%d\n", v4);
getchar();
}
if ( v45 )
x_small_buffers = 1;
if ( v46 )
only_testing = 1;
if ( v41 )
log_level = -99;
log_level = opt_int(v40, (unsigned int)log_level);
v5 = log_level + opt_count(v39);
if ( v5 > 13 )
v5 = 13;
log_level = v5;
if ( !start_path_state )
{
start_path = (char *)malloc(0x1000uLL);
if ( !getcwd(start_path, 0x1000uLL) )
goto LABEL_75;
start_path_count = 1;
if ( log_level > 3 )
{
pthread_mutex_lock(&logger_lock);
v16 = (const char *)get_thread_name();
printf("%s", v16);
printf("Defaulting --path to [%s]\n", start_path);
fflush(stdout);
pthread_mutex_unlock(&logger_lock);
}
}
if ( src )
{
file_path = src;
if ( *src != 47 )
{
file_path = (char *)malloc(0x1000uLL);
free_file_path = 1;
if ( getcwd(file_path, 0x1000uLL) )
{
v17 = file_path;
*(_WORD *)&v17[strlen(file_path)] = 47;
strcat(file_path, src);
goto LABEL_17;
}
LABEL_75:
puts("error: unable to get current directory");
return 2;
}
}
LABEL_17:
db_path = v42;
if ( !v42 )
{
db_path = (char *)malloc(0x1000uLL);
free_db_path = 1;
v18 = getenv("HOME");
snprintf(db_path, 0x1000uLL, "%s/.dupd_sqlite", v18);
}
cache_db_path = v43;
if ( !v43 )
{
cache_db_path = (char *)malloc(0x1000uLL);
free_cache_db_path = 1;
v19 = getenv("HOME");
snprintf(cache_db_path, 0x1000uLL, "%s/.dupd_cache", v19);
}
if ( v35 )
rmsh_link = 1;
if ( v36 )
rmsh_link = 2;
if ( v30[3] )
scan_hidden = 1;
if ( v30[8] )
threaded_sizetree = 0;
if ( v30[7] )
hardlink_is_unique = 1;
if ( v30[5] )
one_file_system = 1;
if ( v47 )
use_hash_cache = 0;
if ( v33 )
cache_delete = 1;
if ( v34 )
cache_ls = 1;
cache_min_size = (int)opt_int(v48, (unsigned int)cache_min_size);
hash_one_block_size = opt_int(v30[10], (unsigned int)hash_one_block_size);
hash_block_size = opt_int(v30[11], (unsigned int)hash_block_size);
filecmp_block_size = opt_int(v30[12], (unsigned int)filecmp_block_size);
hash_one_max_blocks = opt_int(v30[9], (unsigned int)hash_one_max_blocks);
debug_size = (int)opt_int(v30[16], (unsigned int)debug_size);
cut_path = v30[17];
exclude_path = (__int64)v32;
if ( v32 && *v32 != 47 )
{
puts("error: --exclude-path must be absolute");
return 2;
}
stats_file = v30[1];
trace_file = (char *)v30[6];
info_extents_path = v37;
v6 = opt_int(v30[2], (unsigned int)minimum_file_size);
if ( !v6 )
v6 = 1;
minimum_file_size = v6;
path_sep_string = malloc(2uLL);
*(_WORD *)path_sep_string = (unsigned __int8)path_separator;
v7 = (const char *)opt_string(v38, "xxhash");
if ( !strcmp("md5", v7) )
{
hash_function = 1;
}
else if ( !strcmp("sha1", v7) )
{
hash_function = 2;
}
else if ( !strcmp("sha512", v7) )
{
hash_function = 3;
}
else
{
if ( strcmp("xxhash", v7) )
{
printf("error: unknown hash %s\n", v7);
return 2;
}
hash_function = 4;
}
hash_bufsize = hash_get_bufsize((unsigned int)hash_function);
v8 = (const char *)opt_string(v30[18], "text");
if ( !strcmp("text", v8) )
{
report_format = 1;
}
else if ( !strcmp("csv", v8) )
{
report_format = 2;
}
else
{
if ( strcmp("json", v8) )
{
printf("error: unknown report format %s\n", v8);
return 2;
}
report_format = 3;
}
v9 = (const char *)opt_string(v30[4], "0");
v10 = 0LL;
if ( strcmp("0", v9) )
{
v11 = &v9[(int)strlen(v9) - 1];
if ( *v11 == 77 )
{
*v11 = 0;
v12 = 0x100000LL;
}
else
{
v12 = 1LL;
if ( *v11 == 71 )
{
*v11 = 0;
v12 = 0x40000000LL;
}
}
v10 = atol(v9) * v12;
if ( v10 < 0x800000 )
v10 = 0x800000LL;
}
if ( v30[13] )
opt_compare_two = 1;
if ( !hash_one_block_size )
hash_one_block_size = DEF_HDD_hash_one_block_size;
v13 = hash_one_max_blocks * hash_one_block_size;
round1_max_bytes = hash_one_max_blocks * hash_one_block_size;
if ( !cache_min_size )
{
if ( v13 > 0x7FFFF )
cache_min_size = v13;
else
cache_min_size = 0x80000LL;
}
v14 = (const char *)opt_string(v30[14], "def");
if ( !strcmp("inode", v14) )
{
sort_bypass = 15;
}
else if ( !strcmp("block", v14) )
{
sort_bypass = 13;
}
else if ( !strcmp("none", v14) )
{
sort_bypass = 11;
}
else if ( !sort_bypass )
{
goto LABEL_99;
}
if ( log_level > 3 )
{
pthread_mutex_lock(&logger_lock);
v26 = (const char *)get_thread_name();
printf("%s", v26);
printf("Sort bypass set to %s\n", v14);
fflush(stdout);
pthread_mutex_unlock(&logger_lock);
}
if ( hardlink_is_unique )
{
puts("Don't do that..");
return 2;
}
if ( sort_bypass && sort_bypass != 13 )
using_fiemap = 0;
LABEL_99:
if ( v30[15] )
using_fiemap = 0;
if ( log_level > 3 )
{
pthread_mutex_lock(&logger_lock);
v27 = (const char *)get_thread_name();
printf("%s", v27);
printf("Will be using_fiemap (if available): %d\n", (unsigned int)using_fiemap);
fflush(stdout);
pthread_mutex_unlock(&logger_lock);
}
v20 = total_ram();
v21 = v20;
if ( !v10 )
goto LABEL_109;
if ( v10 > v20 )
{
if ( (v20 & 0x8000000000000000LL) != 0LL )
v22 = (double)(int)(v20 & 1 | (v20 >> 1)) + (double)(int)(v20 & 1 | (v20 >> 1));
else
v22 = (double)(int)v20;
v23 = v22 * 0.9;
if ( v23 >= 9.223372036854776e18 )
{
buffer_limit = (unsigned int)(int)(v23 - 9.223372036854776e18);
buffer_limit ^= 0x8000000000000000LL;
}
else
{
buffer_limit = (unsigned int)(int)v23;
}
LABEL_109:
if ( !buffer_limit )
{
v24 = (v20 & 0x8000000000000000LL) != 0LL ? (double)(int)(v20 & 1 | (v20 >> 1))
+ (double)(int)(v20 & 1 | (v20 >> 1)) : (double)(int)v20;
v25 = v24 * 0.5;
if ( v25 >= 9.223372036854776e18 )
{
buffer_limit = (unsigned int)(int)(v25 - 9.223372036854776e18);
buffer_limit ^= 0x8000000000000000LL;
}
else
{
buffer_limit = (unsigned int)(int)v25;
}
if ( x_small_buffers )
buffer_limit = 0x100000LL;
}
goto LABEL_120;
}
buffer_limit = v10;
LABEL_120:
if ( log_level > 3 )
{
v28 = buffer_limit;
pthread_mutex_lock(&logger_lock);
v29 = (const char *)get_thread_name();
printf("%s", v29);
printf("Reported RAM: %dMB buffer limit: %dMB\n", v21 >> 20, v28 >> 20);
fflush(stdout);
pthread_mutex_unlock(&logger_lock);
}
if ( debug_size && log_level <= 2 )
log_level = 3;
return v3;
}

original_code:
static int process_args(int argc, char * argv[])
{
  char * options[38];
  uint64_t user_ram_limit = 0;
  using_fiemap = 1;
  int rv = optgen_parse(argc, argv, &operation, options);
  if (options[32]) {
    show_help();
    return 1;
  }
  if (rv == 1) {
    show_banner();
    printf("\n");
    printf("Run 'dupd help' for a summary of available options.\n");
    printf("Run 'dupd usage' for more documentation.\n");
    return 1;
  }
  if (rv != 0) {
    printf("error parsing command line arguments\n");
    return 2;
  }
  if (options[37]) {
    printf("%d\n", getpid());
    getchar();
  }
  if (options[33]) { x_small_buffers = 1; }
  if (options[34]) { only_testing = 1; }
  if (options[29]) { log_level = -99; }
  log_level = opt_int(options[28], log_level);
  log_level += opt_count(options[27]);
  if (log_level > 13) { log_level = 13; }
  if (start_path_state == 0) {
    start_path[0] = (char *)malloc(4096);
    if (!getcwd(start_path[0], 4096)) {
      printf("error: unable to get current directory\n");
      return 2;
    }
    start_path_count = 1;
    if (4 <= log_level) { pthread_mutex_lock(&logger_lock); printf("%s", get_thread_name()); printf("Defaulting --path to [%s]\n", start_path[0]); fflush(stdout); pthread_mutex_unlock(&logger_lock); };
  }
  if (options[19] != ((void *)0)) {
    file_path = options[19];
    if (file_path[0] != '/') {
      file_path = (char *)malloc(4096);
      free_file_path = 1;
      if (!getcwd(file_path, 4096)) {
        printf("error: unable to get current directory\n");
        return 2;
      }
      strcat(file_path, "/");
      strcat(file_path, options[19]);
    }
  }
  db_path = options[30];
  if (db_path == ((void *)0)) {
    db_path = (char *)malloc(4096);
    free_db_path = 1;
    snprintf(db_path, 4096, "%s/.dupd_sqlite", getenv("HOME"));
  }
  cache_db_path = options[31];
  if (cache_db_path == ((void *)0)) {
    cache_db_path = (char *)malloc(4096);
    free_cache_db_path = 1;
    snprintf(cache_db_path, 4096, "%s/.dupd_cache", getenv("HOME"));
  }
  if (options[23]) { rmsh_link = 1; }
  if (options[24]) { rmsh_link = 2; }
  if (options[3]) { scan_hidden = 1; }
  if (options[8]) { threaded_sizetree = 0; }
  if (options[7]) { hardlink_is_unique = 1; }
  if (options[5]) { one_file_system = 1; }
  if (options[35]) { use_hash_cache = 0; }
  if (options[21]) { cache_delete = 1; }
  if (options[22]) { cache_ls = 1; }
  cache_min_size =
    (uint64_t)opt_int(options[36], cache_min_size);
  hash_one_block_size = opt_int(options[10],
                                hash_one_block_size);
  hash_block_size = opt_int(options[11], hash_block_size);
  filecmp_block_size = opt_int(options[12], filecmp_block_size);
  hash_one_max_blocks = opt_int(options[9], hash_one_max_blocks);
  debug_size = opt_int(options[16], debug_size);
  cut_path = options[17];
  exclude_path = options[20];
  if (exclude_path != ((void *)0) && exclude_path[0] != '/') {
    printf("error: --exclude-path must be absolute\n");
    return 2;
  }
  stats_file = options[1];
  trace_file = options[6];
  info_extents_path = options[25];
  minimum_file_size = opt_int(options[2], minimum_file_size);
  if (minimum_file_size < 1) { minimum_file_size = 1; }
  path_sep_string = (char *)malloc(2);
  path_sep_string[0] = (char)path_separator;
  path_sep_string[1] = 0;
  char * hash_name = opt_string(options[26], "xxhash");
  if (!strcmp("md5", hash_name)) {
    hash_function = 1;
  } else if (!strcmp("sha1", hash_name)) {
    hash_function = 2;
  } else if (!strcmp("sha512", hash_name)) {
    hash_function = 3;
  } else if (!strcmp("xxhash", hash_name)) {
    hash_function = 4;
  } else {
    printf("error: unknown hash %s\n", hash_name);
    return 2;
  }
  hash_bufsize = hash_get_bufsize(hash_function);
  char * report_format_name = opt_string(options[18], "text");
  if (!strcmp("text", report_format_name)) {
    report_format = 1;
  } else if (!strcmp("csv", report_format_name)) {
    report_format = 2;
  } else if (!strcmp("json", report_format_name)) {
    report_format = 3;
  } else {
    printf("error: unknown report format %s\n", report_format_name);
    return 2;
  }
  char * buflimstr = opt_string(options[4], "0");
  if (strcmp("0", buflimstr)) {
    int len = strlen(buflimstr);
    if (buflimstr[len-1] == 'M') {
      user_ram_limit = (1024 * 1024);
      buflimstr[len-1] = 0;
    } else if (buflimstr[len-1] == 'G') {
      user_ram_limit = (1024 * 1024 * 1024);
      buflimstr[len-1] = 0;
    } else {
      user_ram_limit = 1;
    }
    long c = atol(buflimstr);
    user_ram_limit *= c;
    if (user_ram_limit < (1024 * 1024 * 8)) {
      user_ram_limit = (1024 * 1024 * 8);
    }
  }
  if (options[13]) {
    opt_compare_two = 1;
  }
  if (hash_one_block_size == 0) {
    hash_one_block_size = DEF_HDD_hash_one_block_size;
  }
  round1_max_bytes = hash_one_block_size * hash_one_max_blocks;
  if (cache_min_size == 0) {
    if (round1_max_bytes < (1024 * 512)) {
      cache_min_size = (1024 * 512);
    } else {
      cache_min_size = round1_max_bytes;
    }
  }
  char * sortby = opt_string(options[14], "def");
  if (!strcmp("inode", sortby)) {
    sort_bypass = 15;
  } else if (!strcmp("block", sortby)) {
    sort_bypass = 13;
  } else if (!strcmp("none", sortby)) {
    sort_bypass = 11;
  }
  if (sort_bypass != 0) {
    if (4 <= log_level) { pthread_mutex_lock(&logger_lock); printf("%s", get_thread_name()); printf("Sort bypass set to %s\n", sortby); fflush(stdout); pthread_mutex_unlock(&logger_lock); };
    if (hardlink_is_unique) {
      printf("Don't do that..\n");
      return 2;
    }
  }
  if (sort_bypass != 0 && sort_bypass != 13) {
    using_fiemap = 0;
  }
  if (options[15]) { using_fiemap = 0; }
  if (4 <= log_level) { pthread_mutex_lock(&logger_lock); printf("%s", get_thread_name()); printf("Will be using_fiemap (if available): %d\n", using_fiemap); fflush(stdout); pthread_mutex_unlock(&logger_lock); };
  uint64_t ram = total_ram();
  if (user_ram_limit > 0) {
    if (user_ram_limit > ram) {
      buffer_limit = 0.9 * ram;
    } else {
      buffer_limit = user_ram_limit;
    }
  }
  if (buffer_limit == 0) {
    buffer_limit = 0.5 * ram;
    if (x_small_buffers) {
      buffer_limit = (1024 * 1024);
    }
  }
  int ramm = ram / (1024 * 1024);
  int blim = buffer_limit / (1024 * 1024);
  if (4 <= log_level) { pthread_mutex_lock(&logger_lock); printf("%s", get_thread_name()); printf("Reported RAM: %dMB  buffer limit: %dMB\n", ramm, blim); fflush(stdout); pthread_mutex_unlock(&logger_lock); };
  if (debug_size) {
    if (log_level < 3) { log_level = 3; }
  }
  return 0;
}

canonical_original_code:
static int process_args(int argc, char *argv[])
{
  char *options[38];
  unsigned long user_ram_limit = 0;
  using_fiemap = 1;
  int rv = optgen_parse(argc, argv, &operation, options);
  if (options[32]) {
    show_help();
    return 1;
  }
  if (rv == 1) {
    show_banner();
    printf("\n");
    printf("Run 'dupd help' for a summary of available options.\n");
    printf("Run 'dupd usage' for more documentation.\n");
    return 1;
  }
  if (rv != 0) {
    printf("error parsing command line arguments\n");
    return 2;
  }
  if (options[37]) {
    printf("%d\n", getpid());
    getchar();
  }
  if (options[33]) { x_small_buffers = 1; }
  if (options[34]) { only_testing = 1; }
  if (options[29]) { log_level = -99; }
  log_level = opt_int(options[28], log_level);
  log_level += opt_count(options[27]);
  if (log_level > 13) { log_level = 13; }
  if (start_path_state == 0) {
    start_path[0] = (char *)malloc(4096);
    if (!getcwd(start_path[0], 4096)) {
      printf("error: unable to get current directory\n");
      return 2;
    }
    start_path_count = 1;
    if (4 <= log_level) { pthread_mutex_lock(&logger_lock); printf("%s", get_thread_name()); printf("Defaulting --path to [%s]\n", start_path[0]); fflush(stdout); pthread_mutex_unlock(&logger_lock); };
  }
  if (options[19] != ((void *)0)) {
    file_path = options[19];
    if (file_path[0] != '/') {
      file_path = (char *)malloc(4096);
      free_file_path = 1;
      if (!getcwd(file_path, 4096)) {
        printf("error: unable to get current directory\n");
        return 2;
      }
      strcat(file_path, "/");
      strcat(file_path, options[19]);
    }
  }
  db_path = options[30];
  if (db_path == ((void *)0)) {
    db_path = (char *)malloc(4096);
    free_db_path = 1;
    snprintf(db_path, 4096, "%s/.dupd_sqlite", getenv("HOME"));
  }
  cache_db_path = options[31];
  if (cache_db_path == ((void *)0)) {
    cache_db_path = (char *)malloc(4096);
    free_cache_db_path = 1;
    snprintf(cache_db_path, 4096, "%s/.dupd_cache", getenv("HOME"));
  }
  if (options[23]) { rmsh_link = 1; }
  if (options[24]) { rmsh_link = 2; }
  if (options[3]) { scan_hidden = 1; }
  if (options[8]) { threaded_sizetree = 0; }
  if (options[7]) { hardlink_is_unique = 1; }
  if (options[5]) { one_file_system = 1; }
  if (options[35]) { use_hash_cache = 0; }
  if (options[21]) { cache_delete = 1; }
  if (options[22]) { cache_ls = 1; }
  cache_min_size =
    (unsigned long)opt_int(options[36], cache_min_size);
  hash_one_block_size = opt_int(options[10],
                                hash_one_block_size);
  hash_block_size = opt_int(options[11], hash_block_size);
  filecmp_block_size = opt_int(options[12], filecmp_block_size);
  hash_one_max_blocks = opt_int(options[9], hash_one_max_blocks);
  debug_size = opt_int(options[16], debug_size);
  cut_path = options[17];
  exclude_path = options[20];
  if (exclude_path != ((void *)0) && exclude_path[0] != '/') {
    printf("error: --exclude-path must be absolute\n");
    return 2;
  }
  stats_file = options[1];
  trace_file = options[6];
  info_extents_path = options[25];
  minimum_file_size = opt_int(options[2], minimum_file_size);
  if (minimum_file_size < 1) { minimum_file_size = 1; }
  path_sep_string = (char *)malloc(2);
  path_sep_string[0] = (char)path_separator;
  path_sep_string[1] = 0;
  char *hash_name = opt_string(options[26], "xxhash");
  if (!strcmp("md5", hash_name)) {
    hash_function = 1;
  } else if (!strcmp("sha1", hash_name)) {
    hash_function = 2;
  } else if (!strcmp("sha512", hash_name)) {
    hash_function = 3;
  } else if (!strcmp("xxhash", hash_name)) {
    hash_function = 4;
  } else {
    printf("error: unknown hash %s\n", hash_name);
    return 2;
  }
  hash_bufsize = hash_get_bufsize(hash_function);
  char *report_format_name = opt_string(options[18], "text");
  if (!strcmp("text", report_format_name)) {
    report_format = 1;
  } else if (!strcmp("csv", report_format_name)) {
    report_format = 2;
  } else if (!strcmp("json", report_format_name)) {
    report_format = 3;
  } else {
    printf("error: unknown report format %s\n", report_format_name);
    return 2;
  }
  char *buflimstr = opt_string(options[4], "0");
  if (strcmp("0", buflimstr)) {
    int len = strlen(buflimstr);
    if (buflimstr[len-1] == 'M') {
      user_ram_limit = (1024 * 1024);
      buflimstr[len-1] = 0;
    } else if (buflimstr[len-1] == 'G') {
      user_ram_limit = (1024 * 1024 * 1024);
      buflimstr[len-1] = 0;
    } else {
      user_ram_limit = 1;
    }
    long c = atol(buflimstr);
    user_ram_limit *= c;
    if (user_ram_limit < (1024 * 1024 * 8)) {
      user_ram_limit = (1024 * 1024 * 8);
    }
  }
  if (options[13]) {
    opt_compare_two = 1;
  }
  if (hash_one_block_size == 0) {
    hash_one_block_size = DEF_HDD_hash_one_block_size;
  }
  round1_max_bytes = hash_one_block_size * hash_one_max_blocks;
  if (cache_min_size == 0) {
    if (round1_max_bytes < (1024 * 512)) {
      cache_min_size = (1024 * 512);
    } else {
      cache_min_size = round1_max_bytes;
    }
  }
  char *sortby = opt_string(options[14], "def");
  if (!strcmp("inode", sortby)) {
    sort_bypass = 15;
  } else if (!strcmp("block", sortby)) {
    sort_bypass = 13;
  } else if (!strcmp("none", sortby)) {
    sort_bypass = 11;
  }
  if (sort_bypass != 0) {
    if (4 <= log_level) { pthread_mutex_lock(&logger_lock); printf("%s", get_thread_name()); printf("Sort bypass set to %s\n", sortby); fflush(stdout); pthread_mutex_unlock(&logger_lock); };
    if (hardlink_is_unique) {
      printf("Don't do that..\n");
      return 2;
    }
  }
  if (sort_bypass != 0 && sort_bypass != 13) {
    using_fiemap = 0;
  }
  if (options[15]) { using_fiemap = 0; }
  if (4 <= log_level) { pthread_mutex_lock(&logger_lock); printf("%s", get_thread_name()); printf("Will be using_fiemap (if available): %d\n", using_fiemap); fflush(stdout); pthread_mutex_unlock(&logger_lock); };
  unsigned long ram = total_ram();
  if (user_ram_limit > 0) {
    if (user_ram_limit > ram) {
      buffer_limit = 0.9 * ram;
    } else {
      buffer_limit = user_ram_limit;
    }
  }
  if (buffer_limit == 0) {
    buffer_limit = 0.5 * ram;
    if (x_small_buffers) {
      buffer_limit = (1024 * 1024);
    }
  }
  int ramm = ram / (1024 * 1024);
  int blim = buffer_limit / (1024 * 1024);
  if (4 <= log_level) { pthread_mutex_lock(&logger_lock); printf("%s", get_thread_name()); printf("Reported RAM: %dMB  buffer limit: %dMB\n", ramm, blim); fflush(stdout); pthread_mutex_unlock(&logger_lock); };
  if (debug_size) {
    if (log_level < 3) { log_level = 3; }
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
options
char *[38]

variable_types:
buflimstr
char *

variable_types: len int

variable_types: c long

variable_types:
sortby
char *

variable_types:
ram
unsigned long

variable_types: ramm int

variable_types: blim int


decompiled_code:
__int64 __fastcall opt_add_path(const char *a1)
{
int v1; // ebx
char *v2; // rax
int v3; // er14
const char *v4; // r12
__int64 v5; // rbx
const char *v6; // rbp
int v7; // er14
__int64 v8; // rbx
__int64 v10; // rbx
_WORD v11[92]; // [rsp+0h] [rbp-B8h] BYREF

if ( !start_path_state )
start_path_state = 1;
v1 = start_path_count;
v2 = realpath(a1, 0LL);
(&start_path)[v1] = v2;
if ( (unsigned int)get_file_info(v2, v11) || (v11[12] & 0xF000) != 0x4000 )
{
printf("error: not a directory: %s\n", (&start_path)[start_path_count]);
v8 = start_path_count;
free((&start_path)[start_path_count]);
(&start_path)[v8] = 0LL;
start_path_state = 2;
}
else
{
v3 = start_path_count;
if ( start_path_count <= 0 )
{
LABEL_10:
v7 = v3 + 1;
start_path_count = v7;
if ( v7 == 10 )
{
puts("error: exceeded max number of --path elements");
exit(1);
}
(&start_path)[v7] = 0LL;
}
else
{
v4 = (&start_path)[start_path_count];
v5 = 0LL;
while ( 1 )
{
v6 = (&start_path)[v5];
if ( strstr(v6, v4) || strstr(v4, v6) )
break;
if ( ++v5 == v3 )
goto LABEL_10;
}
printf("error: overlap between %s and %s\n", v6, v4);
v10 = start_path_count;
free((&start_path)[start_path_count]);
(&start_path)[v10] = 0LL;
start_path_state = 2;
}
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(const char *a1)
{
int v1; // ebx
char *v2; // rax
int v3; // er14
const char *v4; // r12
__int64 v5; // rbx
const char *v6; // rbp
int v7; // er14
__int64 v8; // rbx
__int64 v10; // rbx
_WORD v11[92]; // [rsp+0h] [rbp-B8h] BYREF

if ( !start_path_state )
start_path_state = 1;
v1 = start_path_count;
v2 = realpath(a1, 0LL);
(&start_path)[v1] = v2;
if ( (unsigned int)get_file_info(v2, v11) || (v11[12] & 0xF000) != 0x4000 )
{
printf("error: not a directory: %s\n", (&start_path)[start_path_count]);
v8 = start_path_count;
free((&start_path)[start_path_count]);
(&start_path)[v8] = 0LL;
start_path_state = 2;
}
else
{
v3 = start_path_count;
if ( start_path_count <= 0 )
{
LABEL_10:
v7 = v3 + 1;
start_path_count = v7;
if ( v7 == 10 )
{
puts("error: exceeded max number of --path elements");
exit(1);
}
(&start_path)[v7] = 0LL;
}
else
{
v4 = (&start_path)[start_path_count];
v5 = 0LL;
while ( 1 )
{
v6 = (&start_path)[v5];
if ( strstr(v6, v4) || strstr(v4, v6) )
break;
if ( ++v5 == v3 )
goto LABEL_10;
}
printf("error: overlap between %s and %s\n", v6, v4);
v10 = start_path_count;
free((&start_path)[start_path_count]);
(&start_path)[v10] = 0LL;
start_path_state = 2;
}
}
return 0LL;
}

original_code:
int opt_add_path(char * arg, int command)
{
  (void)command;
  if (start_path_state == 0) {
    start_path_state = 1;
  }
  start_path[start_path_count] = realpath(arg, ((void *)0));
  struct stat info;
  if (get_file_info(start_path[start_path_count], &info) ||
      !((((info.st_mode)) & 0170000) == (0040000))) {
    printf("error: not a directory: %s\n", start_path[start_path_count]);
    free(start_path[start_path_count]);
    start_path[start_path_count] = ((void *)0);
    start_path_state = 2;
    return 0;
  }
  for (int n = 0; n < start_path_count; n++) {
    if (strstr(start_path[n], start_path[start_path_count]) ||
        strstr(start_path[start_path_count], start_path[n])) {
      printf("error: overlap between %s and %s\n",
             start_path[n], start_path[start_path_count]);
      free(start_path[start_path_count]);
      start_path[start_path_count] = ((void *)0);
      start_path_state = 2;
      return 0;
    }
  }
  start_path_count++;
  if (start_path_count == 10) {
    printf("error: exceeded max number of --path elements\n");
    exit(1);
  }
  start_path[start_path_count] = ((void *)0);
  return 0;
}

canonical_original_code:
int opt_add_path(char *arg, int command)
{
  (void)command;
  if (start_path_state == 0) {
    start_path_state = 1;
  }
  start_path[start_path_count] = realpath(arg, ((void *)0));
  struct stat info;
  if (get_file_info(start_path[start_path_count], &info) ||
      !((((info.st_mode)) & 0170000) == (0040000))) {
    printf("error: not a directory: %s\n", start_path[start_path_count]);
    free(start_path[start_path_count]);
    start_path[start_path_count] = ((void *)0);
    start_path_state = 2;
    return 0;
  }
  for (int n = 0; n < start_path_count; n++) {
    if (strstr(start_path[n], start_path[start_path_count]) ||
        strstr(start_path[start_path_count], start_path[n])) {
      printf("error: overlap between %s and %s\n",
             start_path[n], start_path[start_path_count]);
      free(start_path[start_path_count]);
      start_path[start_path_count] = ((void *)0);
      start_path_state = 2;
      return 0;
    }
  }
  start_path_count++;
  if (start_path_count == 10) {
    printf("error: exceeded max number of --path elements\n");
    exit(1);
  }
  start_path[start_path_count] = ((void *)0);
  return 0;
}

variable_types:
arg
char *

variable_types: command int

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }