#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ esi;

/* Variables and functions */
unsigned char *calloc(int, int);
int /*<<< orphan*/ free(unsigned char *);
int /*<<< orphan*/ memset(unsigned char *, int /*<<< orphan*/, int);
int msf_unpack(unsigned char *, int, void *, int *);
int /*<<< orphan*/ msf_unpack_init();
int unmsf(void *in, int insz, void *out, int outsz) {
  int ret;
  unsigned char esi[0x1b0], *tmp;
  msf_unpack_init();
  memset(esi, 0, sizeof(esi));
  tmp = calloc(0x3e6c, 1);
  if (!tmp)
    return (-1);
  *(int *)(esi) = 3;
  *(int *)(esi + 0x04) = 0;
  *(int *)(esi + 0x08) = 2;
  *(int *)(esi + 0x0c) = 0x10000;
  *(int *)(esi + 0x54) = 0x1f36;
  *(void **)(esi + 0x10) = tmp;
  *(void **)(esi + 0x14) = out;
  *(int *)(esi + 0x28) = outsz;
  *(int *)(esi + 0x24) = 0;
  *(int *)(esi + 0x4c) = 1;
  *(int *)(esi + 0x48) = 0;
  *(int *)(esi + 0x58) = 0;
  *(int *)(esi + 0x2c) = 0;
  *(int *)(esi + 0x30) = 0;
  *(int *)(esi + 0x50) = 1;
  ret = msf_unpack(esi, outsz, in, &insz);
  free(tmp);
  if (ret)
    return (-1);
  return (*(int *)(esi + 0x24));
}


x86 assembly (clang, -O0):
<unmsf>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1f0,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %ecx,-0x24(%rbp)
mov    $0x0,%al
call   1070 <msf_unpack_init@plt>
lea    -0x1e0(%rbp),%rdi
xor    %esi,%esi
mov    $0x1b0,%edx
call   1040 <memset@plt>
mov    $0x3e6c,%edi
mov    $0x1,%esi
call   1060 <calloc@plt>
mov    %rax,-0x1e8(%rbp)
cmpq   $0x0,-0x1e8(%rbp)
jne    11b3 <unmsf+0x63>
movl   $0xffffffff,-0x4(%rbp)
jmp    1292 <unmsf+0x142>
movl   $0x3,-0x1e0(%rbp)
movl   $0x0,-0x1dc(%rbp)
movl   $0x2,-0x1d8(%rbp)
movl   $0x10000,-0x1d4(%rbp)
movl   $0x1f36,-0x18c(%rbp)
mov    -0x1e8(%rbp),%rax
mov    %rax,-0x1d0(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x1cc(%rbp)
mov    -0x24(%rbp),%eax
mov    %eax,-0x1b8(%rbp)
movl   $0x0,-0x1bc(%rbp)
movl   $0x1,-0x194(%rbp)
movl   $0x0,-0x198(%rbp)
movl   $0x0,-0x188(%rbp)
movl   $0x0,-0x1b4(%rbp)
movl   $0x0,-0x1b0(%rbp)
movl   $0x1,-0x190(%rbp)
lea    -0x1e0(%rbp),%rdi
mov    -0x24(%rbp),%esi
mov    -0x10(%rbp),%rdx
lea    -0x14(%rbp),%rcx
call   1050 <msf_unpack@plt>
mov    %eax,-0x28(%rbp)
mov    -0x1e8(%rbp),%rdi
call   1030 <free@plt>
cmpl   $0x0,-0x28(%rbp)
je     1289 <unmsf+0x139>
movl   $0xffffffff,-0x4(%rbp)
jmp    1292 <unmsf+0x142>
mov    -0x1bc(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x1f0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<unmsf>:
push   %rbp
push   %r15
push   %r14
push   %rbx
sub    $0x1c8,%rsp
mov    %ecx,%ebp
mov    %rdx,%r15
mov    %rdi,%r14
mov    %esi,0xc(%rsp)
xor    %eax,%eax
call   1070 <msf_unpack_init@plt>
lea    0x10(%rsp),%rdi
xor    %esi,%esi
mov    $0x1b0,%edx
call   1040 <memset@plt>
mov    $0x3e6c,%edi
mov    $0x1,%esi
call   1060 <calloc@plt>
test   %rax,%rax
je     11ff <unmsf+0xaf>
mov    %rax,%rbx
movaps 0xe61(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
mov    %rax,0x20(%rsp)
mov    %r15,0x24(%rsp)
mov    %ebp,0x38(%rsp)
movl   $0x0,0x34(%rsp)
movl   $0x0,0x68(%rsp)
movq   $0x0,0x3c(%rsp)
movaps 0xe3e(%rip),%xmm0
movups %xmm0,0x58(%rsp)
lea    0x10(%rsp),%rdi
lea    0xc(%rsp),%rcx
mov    %ebp,%esi
mov    %r14,%rdx
call   1050 <msf_unpack@plt>
mov    %eax,%ebp
mov    %rbx,%rdi
call   1030 <free@plt>
neg    %ebp
sbb    %eax,%eax
or     0x34(%rsp),%eax
jmp    1204 <unmsf+0xb4>
mov    $0xffffffff,%eax
add    $0x1c8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @unmsf(i8* %0, i32 %1, i8* %2, i32 %3) {
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i8*
%9 = alloca i32
%10 = alloca i32
%11 = alloca [432 x i8]
%12 = alloca i8*
store i8* %0, i8** %6
store i32 %1, i32* %7
store i8* %2, i8** %8
store i32 %3, i32* %9
%13 = call i32 (...) @msf_unpack_init()
%14 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%15 = call i32 @memset(i8* %14, i32 0, i32 432)
%16 = call i8* @calloc(i32 15980, i32 1)
store i8* %16, i8** %12
%17 = load i8*, i8** %12
%18 = icmp ne i8* %17, null
br i1 %18, label %20, label %19
19: ; preds = %4
store i32 -1, i32* %5
br label %82
20: ; preds = %4
%21 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%22 = bitcast i8* %21 to i32*
store i32 3, i32* %22
%23 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%24 = getelementptr inbounds i8, i8* %23, i64 4
%25 = bitcast i8* %24 to i32*
store i32 0, i32* %25
%26 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%27 = getelementptr inbounds i8, i8* %26, i64 8
%28 = bitcast i8* %27 to i32*
store i32 2, i32* %28
%29 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%30 = getelementptr inbounds i8, i8* %29, i64 12
%31 = bitcast i8* %30 to i32*
store i32 65536, i32* %31
%32 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%33 = getelementptr inbounds i8, i8* %32, i64 84
%34 = bitcast i8* %33 to i32*
store i32 7990, i32* %34
%35 = load i8*, i8** %12
%36 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%37 = getelementptr inbounds i8, i8* %36, i64 16
%38 = bitcast i8* %37 to i8**
store i8* %35, i8** %38
%39 = load i8*, i8** %8
%40 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%41 = getelementptr inbounds i8, i8* %40, i64 20
%42 = bitcast i8* %41 to i8**
store i8* %39, i8** %42
%43 = load i32, i32* %9
%44 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%45 = getelementptr inbounds i8, i8* %44, i64 40
%46 = bitcast i8* %45 to i32*
store i32 %43, i32* %46
%47 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%48 = getelementptr inbounds i8, i8* %47, i64 36
%49 = bitcast i8* %48 to i32*
store i32 0, i32* %49
%50 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%51 = getelementptr inbounds i8, i8* %50, i64 76
%52 = bitcast i8* %51 to i32*
store i32 1, i32* %52
%53 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%54 = getelementptr inbounds i8, i8* %53, i64 72
%55 = bitcast i8* %54 to i32*
store i32 0, i32* %55
%56 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%57 = getelementptr inbounds i8, i8* %56, i64 88
%58 = bitcast i8* %57 to i32*
store i32 0, i32* %58
%59 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%60 = getelementptr inbounds i8, i8* %59, i64 44
%61 = bitcast i8* %60 to i32*
store i32 0, i32* %61
%62 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%63 = getelementptr inbounds i8, i8* %62, i64 48
%64 = bitcast i8* %63 to i32*
store i32 0, i32* %64
%65 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%66 = getelementptr inbounds i8, i8* %65, i64 80
%67 = bitcast i8* %66 to i32*
store i32 1, i32* %67
%68 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%69 = load i32, i32* %9
%70 = load i8*, i8** %6
%71 = call i32 @msf_unpack(i8* %68, i32 %69, i8* %70, i32* %7)
store i32 %71, i32* %10
%72 = load i8*, i8** %12
%73 = call i32 @free(i8* %72)
%74 = load i32, i32* %10
%75 = icmp ne i32 %74, 0
br i1 %75, label %76, label %77
76: ; preds = %20
store i32 -1, i32* %5
br label %82
77: ; preds = %20
%78 = getelementptr inbounds [432 x i8], [432 x i8]* %11, i64 0, i64 0
%79 = getelementptr inbounds i8, i8* %78, i64 36
%80 = bitcast i8* %79 to i32*
%81 = load i32, i32* %80
store i32 %81, i32* %5
br label %82
82: ; preds = %77, %76, %19
%83 = load i32, i32* %5
ret i32 %83
}

LLVM IR (-O2):
define i32 @unmsf(i8* %0, i32 %1, i8* %2, i32 %3) {
%5 = alloca i32
%6 = alloca [432 x i8]
store i32 %1, i32* %5
%7 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 0
%8 = tail call i32 (...) @msf_unpack_init()
%9 = call i32 @memset(i8* %7, i32 0, i32 432)
%10 = call dereferenceable_or_null(15980) i8* @calloc(i32 15980, i32 1)
%11 = icmp eq i8* %10, null
br i1 %11, label %35, label %12
12: ; preds = %4
%13 = bitcast [432 x i8]* %6 to <4 x i32>*
store <4 x i32> <i32 3, i32 0, i32 2, i32 65536>, <4 x i32>* %13
%14 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 16
%15 = bitcast i8* %14 to i8**
store i8* %10, i8** %15
%16 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 20
%17 = bitcast i8* %16 to i8**
store i8* %2, i8** %17
%18 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 40
%19 = bitcast i8* %18 to i32*
store i32 %3, i32* %19
%20 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 36
%21 = bitcast i8* %20 to i32*
store i32 0, i32* %21
%22 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 72
%23 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 88
%24 = bitcast i8* %23 to i32*
store i32 0, i32* %24
%25 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 44
%26 = bitcast i8* %25 to i32*
store i32 0, i32* %26
%27 = getelementptr inbounds [432 x i8], [432 x i8]* %6, i64 0, i64 48
%28 = bitcast i8* %27 to i32*
store i32 0, i32* %28
%29 = bitcast i8* %22 to <4 x i32>*
store <4 x i32> <i32 0, i32 1, i32 1, i32 7990>, <4 x i32>* %29
%30 = call i32 @msf_unpack(i8* %7, i32 %3, i8* %0, i32* %5)
%31 = call i32 @free(i8* %10)
%32 = icmp eq i32 %30, 0
%33 = load i32, i32* %21
%34 = select i1 %32, i32 %33, i32 -1
br label %35
35: ; preds = %12, %4
%36 = phi i32 [ -1, %4 ], [ %34, %12 ]
ret i32 %36
}