#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 uint8_t;
typedef int /*<<< orphan*/ uint32_t;

/* Variables and functions */
int *malloc(int);
int /*<<< orphan*/ rand();
uint8_t *hk_ws_generate_close_frame(int *frame_length, int masked) {
  uint8_t *write_position, *frame;
  uint8_t opcode;
  int is_masked;
  union {
    uint32_t raw;
    uint8_t octets[4];
  } mask;
  opcode = 8;
  if (masked) {
    is_masked = 1;
    mask.raw = rand();
  } else {
    is_masked = 0;
  }
  *frame_length = 2;
  if (is_masked) {
    *frame_length += 4;
  }
  frame = malloc(*frame_length * sizeof(uint8_t));
  if (frame == NULL) {
    return NULL;
  }
  write_position = frame;
  *write_position = (opcode & 15) | 0b10000000;
  write_position += 1;
  *write_position = 0 | (is_masked << 7);
  if (is_masked) {
    *((uint32_t *)write_position) = mask.raw;
    write_position += 4;
  }
  return frame;
}


x86 assembly (clang, -O0):
<hk_ws_generate_close_frame>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
movl   $0x8,-0x2c(%rbp)
cmpl   $0x0,-0x14(%rbp)
je     1156 <hk_ws_generate_close_frame+0x36>
movl   $0x1,-0x30(%rbp)
mov    $0x0,%al
call   1040 <rand@plt>
mov    %eax,-0x40(%rbp)
jmp    115d <hk_ws_generate_close_frame+0x3d>
movl   $0x0,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movl   $0x2,(%rax)
cmpl   $0x0,-0x30(%rbp)
je     117c <hk_ws_generate_close_frame+0x5c>
mov    -0x10(%rbp),%rax
mov    (%rax),%ecx
add    $0x4,%ecx
mov    %ecx,(%rax)
mov    -0x10(%rbp),%rax
movslq (%rax),%rax
shl    $0x2,%rax
mov    %eax,%edi
call   1030 <malloc@plt>
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
jne    11aa <hk_ws_generate_close_frame+0x8a>
movq   $0x0,-0x8(%rbp)
jmp    1206 <hk_ws_generate_close_frame+0xe6>
mov    -0x28(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x2c(%rbp),%ecx
and    $0xf,%ecx
or     $0x80,%ecx
mov    -0x20(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x20(%rbp)
mov    -0x30(%rbp),%ecx
shl    $0x7,%ecx
or     $0x0,%ecx
mov    -0x20(%rbp),%rax
mov    %ecx,(%rax)
cmpl   $0x0,-0x30(%rbp)
je     11fe <hk_ws_generate_close_frame+0xde>
mov    -0x40(%rbp),%ecx
mov    -0x20(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
add    $0x10,%rax
mov    %rax,-0x20(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<hk_ws_generate_close_frame>:
push   %rbp
push   %rbx
push   %rax
mov    %rdi,%rbx
test   %esi,%esi
je     113a <hk_ws_generate_close_frame+0x1a>
xor    %eax,%eax
call   1040 <rand@plt>
mov    %eax,%ebp
mov    $0x6,%edi
jmp    1141 <hk_ws_generate_close_frame+0x21>
mov    $0x2,%edi
xor    %ebp,%ebp
mov    %edi,(%rbx)
shl    $0x2,%edi
call   1030 <malloc@plt>
test   %rax,%rax
je     1159 <hk_ws_generate_close_frame+0x39>
movl   $0x88,(%rax)
mov    %ebp,0x4(%rax)
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
%union.anon = type { [4 x i32] }
define i32* @hk_ws_generate_close_frame(i32* %0, i32 %1) {
%3 = alloca i32*
%4 = alloca i32*
%5 = alloca i32
%6 = alloca i32*
%7 = alloca i32*
%8 = alloca i32
%9 = alloca i32
%10 = alloca %union.anon
store i32* %0, i32** %4
store i32 %1, i32* %5
store i32 8, i32* %8
%11 = load i32, i32* %5
%12 = icmp ne i32 %11, 0
br i1 %12, label %13, label %16
13: ; preds = %2
store i32 1, i32* %9
%14 = call i32 (...) @rand()
%15 = bitcast %union.anon* %10 to i32*
store i32 %14, i32* %15
br label %17
16: ; preds = %2
store i32 0, i32* %9
br label %17
17: ; preds = %16, %13
%18 = load i32*, i32** %4
store i32 2, i32* %18
%19 = load i32, i32* %9
%20 = icmp ne i32 %19, 0
br i1 %20, label %21, label %25
21: ; preds = %17
%22 = load i32*, i32** %4
%23 = load i32, i32* %22
%24 = add nsw i32 %23, 4
store i32 %24, i32* %22
br label %25
25: ; preds = %21, %17
%26 = load i32*, i32** %4
%27 = load i32, i32* %26
%28 = sext i32 %27 to i64
%29 = mul i64 %28, 4
%30 = trunc i64 %29 to i32
%31 = call i32* @malloc(i32 %30)
store i32* %31, i32** %7
%32 = load i32*, i32** %7
%33 = icmp eq i32* %32, null
br i1 %33, label %34, label %35
34: ; preds = %25
store i32* null, i32** %3
br label %57
35: ; preds = %25
%36 = load i32*, i32** %7
store i32* %36, i32** %6
%37 = load i32, i32* %8
%38 = and i32 %37, 15
%39 = or i32 %38, 128
%40 = load i32*, i32** %6
store i32 %39, i32* %40
%41 = load i32*, i32** %6
%42 = getelementptr inbounds i32, i32* %41, i64 1
store i32* %42, i32** %6
%43 = load i32, i32* %9
%44 = shl i32 %43, 7
%45 = or i32 0, %44
%46 = load i32*, i32** %6
store i32 %45, i32* %46
%47 = load i32, i32* %9
%48 = icmp ne i32 %47, 0
br i1 %48, label %49, label %55
49: ; preds = %35
%50 = bitcast %union.anon* %10 to i32*
%51 = load i32, i32* %50
%52 = load i32*, i32** %6
store i32 %51, i32* %52
%53 = load i32*, i32** %6
%54 = getelementptr inbounds i32, i32* %53, i64 4
store i32* %54, i32** %6
br label %55
55: ; preds = %49, %35
%56 = load i32*, i32** %7
store i32* %56, i32** %3
br label %57
57: ; preds = %55, %34
%58 = load i32*, i32** %3
ret i32* %58
}

LLVM IR (-O2):
define noalias i32* @hk_ws_generate_close_frame(i32* nocapture writeonly %0, i32 %1) {
%3 = icmp eq i32 %1, 0
br i1 %3, label %6, label %4
4: ; preds = %2
%5 = tail call i32 (...) @rand()
br label %6
6: ; preds = %2, %4
%7 = phi i32 [ 0, %2 ], [ %5, %4 ]
%8 = phi i32 [ 2, %2 ], [ 6, %4 ]
store i32 %8, i32* %0
%9 = shl nuw nsw i32 %8, 2
%10 = tail call i32* @malloc(i32 %9)
%11 = icmp eq i32* %10, null
br i1 %11, label %14, label %12
12: ; preds = %6
store i32 136, i32* %10
%13 = getelementptr inbounds i32, i32* %10, i64 1
store i32 %7, i32* %13
br label %14
14: ; preds = %6, %12
ret i32* %10
}