#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 */

/* Variables and functions */
scalar_t__ chdir(char *);
int /*<<< orphan*/ execvp(char *, char *const *);
int /*<<< orphan*/ getcwd(char *, int);
int /*<<< orphan*/ memset(char **, int /*<<< orphan*/, int);
int /*<<< orphan*/ printf(char *, char *);
int /*<<< orphan*/ strcmp(char *, char *);
int strlen(char *);
int /*<<< orphan*/ trim(char *);
void runprog(char *string) {
  trim(string);
  int i;
  int length = strlen(string);
  int arg = 1;
  char *argv[64];
  memset(argv, 0, 64 * sizeof(char *));
  argv[0] = string;
  int spaces = 0;
  for (i = 0; i < length; i++) {
    if (string[i] == ' ' && !spaces) {
      spaces++;
      string[i] = 0;
      argv[arg] = string + i + 1;
      arg++;
    } else
      spaces = 0;
  }
  argv[63] = 0;
  for (i = 0; i < 63; i++) {
    if (!argv[i])
      break;
    else
      trim(argv[i]);
  }
  if (!argv[0])
    return;
  if (!strcmp(argv[0], "cd")) {
    if (!argv[1])
      return;
    if (chdir(argv[1])) {
      printf("sh: %s: permission denied.\n", argv[1]);
      return;
    }
    char cwd_buff[128];
    getcwd(cwd_buff, 128);
  } else {
    execvp(argv[0], (char *const *)argv);
    printf("sh: binary not found: %s\n", argv[0]);
  }
  return;
}


x86 assembly (clang, -O0):
<runprog>:
push   %rbp
mov    %rsp,%rbp
sub    $0x2b0,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
call   1060 <trim@plt>
mov    -0x8(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,-0x10(%rbp)
movl   $0x1,-0x14(%rbp)
lea    -0x220(%rbp),%rdi
xor    %esi,%esi
mov    $0x200,%edx
call   1070 <memset@plt>
mov    -0x8(%rbp),%rax
mov    %rax,-0x220(%rbp)
movl   $0x0,-0x224(%rbp)
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    1269 <runprog+0xe9>
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x20,%eax
jne    124c <runprog+0xcc>
cmpl   $0x0,-0x224(%rbp)
jne    124c <runprog+0xcc>
mov    -0x224(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x224(%rbp)
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x8(%rbp),%rcx
movslq -0xc(%rbp),%rax
add    %rax,%rcx
add    $0x1,%rcx
movslq -0x14(%rbp),%rax
mov    %rcx,-0x220(%rbp,%rax,8)
ff
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1256 <runprog+0xd6>
movl   $0x0,-0x224(%rbp)
jmp    125b <runprog+0xdb>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    11da <runprog+0x5a>
movq   $0x0,-0x28(%rbp)
movl   $0x0,-0xc(%rbp)
cmpl   $0x3f,-0xc(%rbp)
jge    12be <runprog+0x13e>
movslq -0xc(%rbp),%rax
cmpq   $0x0,-0x220(%rbp,%rax,8)
jne    129a <runprog+0x11a>
jmp    12be <runprog+0x13e>
movslq -0xc(%rbp),%rax
mov    -0x220(%rbp,%rax,8),%rdi
ff
call   1060 <trim@plt>
jmp    12b0 <runprog+0x130>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1278 <runprog+0xf8>
cmpq   $0x0,-0x220(%rbp)
jne    12d1 <runprog+0x151>
jmp    136f <runprog+0x1ef>
mov    -0x220(%rbp),%rdi
lea    0xd21(%rip),%rsi
call   1090 <strcmp@plt>
cmp    $0x0,%eax
jne    1344 <runprog+0x1c4>
cmpq   $0x0,-0x218(%rbp)
jne    1300 <runprog+0x180>
jmp    136f <runprog+0x1ef>
mov    -0x218(%rbp),%rdi
call   1040 <chdir@plt>
cmp    $0x0,%rax
je     132e <runprog+0x1ae>
mov    -0x218(%rbp),%rsi
lea    0xcdf(%rip),%rdi
call   1050 <printf@plt>
jmp    136f <runprog+0x1ef>
lea    -0x2b0(%rbp),%rdi
mov    $0x80,%esi
call   1080 <getcwd@plt>
jmp    136a <runprog+0x1ea>
mov    -0x220(%rbp),%rdi
lea    -0x220(%rbp),%rsi
call   10a0 <execvp@plt>
mov    -0x220(%rbp),%rsi
lea    0xcba(%rip),%rdi
call   1050 <printf@plt>
jmp    136f <runprog+0x1ef>
add    $0x2b0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<runprog>:
push   %rbp
push   %r14
push   %rbx
sub    $0x280,%rsp
mov    %rdi,%r14
call   1060 <trim@plt>
mov    %r14,%rdi
call   1030 <strlen@plt>
mov    %eax,%ebx
mov    %rsp,%rdi
xor    %ebp,%ebp
xor    %esi,%esi
mov    $0x200,%edx
call   1070 <memset@plt>
mov    %r14,(%rsp)
test   %ebx,%ebx
jle    11eb <runprog+0x6b>
mov    %ebx,%r8d
cmp    $0x1,%ebx
jne    125f <runprog+0xdf>
mov    $0x1,%eax
xor    %edx,%edx
test   $0x1,%r8b
je     11eb <runprog+0x6b>
test   %ebp,%ebp
jne    11eb <runprog+0x6b>
cmpb   $0x20,(%r14,%rdx,1)
jne    11eb <runprog+0x6b>
add    %rdx,%r14
movb   $0x0,(%r14)
add    $0x1,%r14
cltq
mov    %r14,(%rsp,%rax,8)
movq   $0x0,0x1f8(%rsp)
xor    %ebx,%ebx
nopl   0x0(%rax)
mov    (%rsp,%rbx,8),%rdi
test   %rdi,%rdi
je     1218 <runprog+0x98>
call   1060 <trim@plt>
add    $0x1,%rbx
cmp    $0x3f,%rbx
jne    1200 <runprog+0x80>
mov    (%rsp),%rbx
test   %rbx,%rbx
je     1253 <runprog+0xd3>
lea    0xdd8(%rip),%rsi
mov    %rbx,%rdi
call   1090 <strcmp@plt>
test   %eax,%eax
je     12d8 <runprog+0x158>
mov    %rsp,%rsi
mov    %rbx,%rdi
call   10a0 <execvp@plt>
mov    (%rsp),%rsi
lea    0xdd1(%rip),%rdi
call   1050 <printf@plt>
add    $0x280,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret
mov    %r8d,%esi
and    $0xfffffffe,%esi
lea    0x1(%r14),%rdi
mov    $0x1,%eax
xor    %edx,%edx
xor    %ebp,%ebp
jmp    1291 <runprog+0x111>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
add    $0x2,%rdx
add    $0x2,%rdi
cmp    %rdx,%rsi
je     11c9 <runprog+0x49>
movzbl -0x1(%rdi),%ecx
test   %ebp,%ebp
jne    12ab <runprog+0x12b>
cmp    $0x20,%cl
jne    12ab <runprog+0x12b>
movb   $0x0,-0x1(%rdi)
cltq
mov    %rdi,(%rsp,%rax,8)
add    $0x1,%eax
test   %ebp,%ebp
sete   %bl
cmp    $0x20,%cl
sete   %cl
xor    %ebp,%ebp
test   %cl,%bl
jne    1280 <runprog+0x100>
cmpb   $0x20,(%rdi)
jne    1280 <runprog+0x100>
movb   $0x0,(%rdi)
lea    0x1(%rdi),%rcx
cltq
mov    %rcx,(%rsp,%rax,8)
add    $0x1,%eax
mov    $0x1,%ebp
jmp    1280 <runprog+0x100>
mov    0x8(%rsp),%rdi
test   %rdi,%rdi
je     1253 <runprog+0xd3>
call   1040 <chdir@plt>
test   %rax,%rax
je     1301 <runprog+0x181>
mov    0x8(%rsp),%rsi
lea    0xd07(%rip),%rdi
jmp    124e <runprog+0xce>
lea    0x200(%rsp),%rdi
mov    $0x80,%esi
call   1080 <getcwd@plt>
jmp    1253 <runprog+0xd3>

LLVM IR (-O0):
@.str = [3 x i8] c"cd\00"
@.str.1 = [28 x i8] c"sh: %s: permission denied.\0A\00"
@.str.2 = [26 x i8] c"sh: binary not found: %s\0A\00"
define void @runprog(i8* %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
%6 = alloca [64 x i8*]
%7 = alloca i32
%8 = alloca [128 x i8]
store i8* %0, i8** %2
%9 = load i8*, i8** %2
%10 = call i32 @trim(i8* %9)
%11 = load i8*, i8** %2
%12 = call i32 @strlen(i8* %11)
store i32 %12, i32* %4
store i32 1, i32* %5
%13 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 0
%14 = call i32 @memset(i8** %13, i32 0, i32 512)
%15 = load i8*, i8** %2
%16 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 0
store i8* %15, i8** %16
store i32 0, i32* %7
store i32 0, i32* %3
br label %17
17: ; preds = %51, %1
%18 = load i32, i32* %3
%19 = load i32, i32* %4
%20 = icmp slt i32 %18, %19
br i1 %20, label %21, label %54
21: ; preds = %17
%22 = load i8*, i8** %2
%23 = load i32, i32* %3
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds i8, i8* %22, i64 %24
%26 = load i8, i8* %25
%27 = sext i8 %26 to i32
%28 = icmp eq i32 %27, 32
br i1 %28, label %29, label %49
29: ; preds = %21
%30 = load i32, i32* %7
%31 = icmp ne i32 %30, 0
br i1 %31, label %49, label %32
32: ; preds = %29
%33 = load i32, i32* %7
%34 = add nsw i32 %33, 1
store i32 %34, i32* %7
%35 = load i8*, i8** %2
%36 = load i32, i32* %3
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds i8, i8* %35, i64 %37
store i8 0, i8* %38
%39 = load i8*, i8** %2
%40 = load i32, i32* %3
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %39, i64 %41
%43 = getelementptr inbounds i8, i8* %42, i64 1
%44 = load i32, i32* %5
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 %45
store i8* %43, i8** %46
%47 = load i32, i32* %5
%48 = add nsw i32 %47, 1
store i32 %48, i32* %5
br label %50
49: ; preds = %29, %21
store i32 0, i32* %7
br label %50
50: ; preds = %49, %32
br label %51
51: ; preds = %50
%52 = load i32, i32* %3
%53 = add nsw i32 %52, 1
store i32 %53, i32* %3
br label %17
54: ; preds = %17
%55 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 63
store i8* null, i8** %55
store i32 0, i32* %3
br label %56
56: ; preds = %73, %54
%57 = load i32, i32* %3
%58 = icmp slt i32 %57, 63
br i1 %58, label %59, label %76
59: ; preds = %56
%60 = load i32, i32* %3
%61 = sext i32 %60 to i64
%62 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 %61
%63 = load i8*, i8** %62
%64 = icmp ne i8* %63, null
br i1 %64, label %66, label %65
65: ; preds = %59
br label %76
66: ; preds = %59
%67 = load i32, i32* %3
%68 = sext i32 %67 to i64
%69 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 %68
%70 = load i8*, i8** %69
%71 = call i32 @trim(i8* %70)
br label %72
72: ; preds = %66
br label %73
73: ; preds = %72
%74 = load i32, i32* %3
%75 = add nsw i32 %74, 1
store i32 %75, i32* %3
br label %56
76: ; preds = %65, %56
%77 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 0
%78 = load i8*, i8** %77
%79 = icmp ne i8* %78, null
br i1 %79, label %81, label %80
80: ; preds = %76
br label %112
81: ; preds = %76
%82 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 0
%83 = load i8*, i8** %82
%84 = call i32 @strcmp(i8* %83, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0))
%85 = icmp ne i32 %84, 0
br i1 %85, label %103, label %86
86: ; preds = %81
%87 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 1
%88 = load i8*, i8** %87
%89 = icmp ne i8* %88, null
br i1 %89, label %91, label %90
90: ; preds = %86
br label %112
91: ; preds = %86
%92 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 1
%93 = load i8*, i8** %92
%94 = call i64 @chdir(i8* %93)
%95 = icmp ne i64 %94, 0
br i1 %95, label %96, label %100
96: ; preds = %91
%97 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 1
%98 = load i8*, i8** %97
%99 = call i32 @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.1, i64 0, i64 0), i8* %98)
br label %112
100: ; preds = %91
%101 = getelementptr inbounds [128 x i8], [128 x i8]* %8, i64 0, i64 0
%102 = call i32 @getcwd(i8* %101, i32 128)
br label %111
103: ; preds = %81
%104 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 0
%105 = load i8*, i8** %104
%106 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 0
%107 = call i32 @execvp(i8* %105, i8** %106)
%108 = getelementptr inbounds [64 x i8*], [64 x i8*]* %6, i64 0, i64 0
%109 = load i8*, i8** %108
%110 = call i32 @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.2, i64 0, i64 0), i8* %109)
br label %111
111: ; preds = %103, %100
br label %112
112: ; preds = %111, %96, %90, %80
ret void
}

LLVM IR (-O2):
@.str = [3 x i8] c"cd\00"
@.str.1 = [28 x i8] c"sh: %s: permission denied.\0A\00"
@.str.2 = [26 x i8] c"sh: binary not found: %s\0A\00"
define void @runprog(i8* %0) {
%2 = alloca [64 x i8*]
%3 = alloca [128 x i8]
%4 = tail call i32 @trim(i8* %0)
%5 = tail call i32 @strlen(i8* %0)
%6 = bitcast [64 x i8*]* %2 to i8*
%7 = getelementptr inbounds [64 x i8*], [64 x i8*]* %2, i64 0, i64 0
%8 = call i32 @memset(i8** %7, i32 0, i32 512)
store i8* %0, i8** %7
%9 = icmp sgt i32 %5, 0
br i1 %9, label %10, label %65
10: ; preds = %1
%11 = zext i32 %5 to i64
%12 = and i64 %11, 1
%13 = icmp eq i32 %5, 1
br i1 %13, label %50, label %14
14: ; preds = %10
%15 = and i64 %11, 4294967294
br label %16
16: ; preds = %44, %14
%17 = phi i64 [ 0, %14 ], [ %47, %44 ]
%18 = phi i32 [ 0, %14 ], [ %46, %44 ]
%19 = phi i32 [ 1, %14 ], [ %45, %44 ]
%20 = phi i64 [ 0, %14 ], [ %48, %44 ]
%21 = getelementptr inbounds i8, i8* %0, i64 %17
%22 = load i8, i8* %21
%23 = icmp ne i8 %22, 32
%24 = icmp ne i32 %18, 0
%25 = or i1 %24, %23
br i1 %25, label %31, label %26
26: ; preds = %16
store i8 0, i8* %21
%27 = getelementptr inbounds i8, i8* %21, i64 1
%28 = sext i32 %19 to i64
%29 = getelementptr inbounds [64 x i8*], [64 x i8*]* %2, i64 0, i64 %28
store i8* %27, i8** %29
%30 = add nsw i32 %19, 1
br label %31
31: ; preds = %16, %26
%32 = phi i32 [ %30, %26 ], [ %19, %16 ]
%33 = or i1 %24, %23
%34 = or i64 %17, 1
%35 = getelementptr inbounds i8, i8* %0, i64 %34
%36 = load i8, i8* %35
%37 = icmp eq i8 %36, 32
%38 = and i1 %33, %37
br i1 %38, label %39, label %44
39: ; preds = %31
store i8 0, i8* %35
%40 = getelementptr inbounds i8, i8* %35, i64 1
%41 = sext i32 %32 to i64
%42 = getelementptr inbounds [64 x i8*], [64 x i8*]* %2, i64 0, i64 %41
store i8* %40, i8** %42
%43 = add nsw i32 %32, 1
br label %44
44: ; preds = %39, %31
%45 = phi i32 [ %43, %39 ], [ %32, %31 ]
%46 = phi i32 [ 1, %39 ], [ 0, %31 ]
%47 = add nuw nsw i64 %17, 2
%48 = add i64 %20, 2
%49 = icmp eq i64 %48, %15
br i1 %49, label %50, label %16
50: ; preds = %44, %10
%51 = phi i64 [ 0, %10 ], [ %47, %44 ]
%52 = phi i32 [ 0, %10 ], [ %46, %44 ]
%53 = phi i32 [ 1, %10 ], [ %45, %44 ]
%54 = icmp eq i64 %12, 0
br i1 %54, label %65, label %55
55: ; preds = %50
%56 = getelementptr inbounds i8, i8* %0, i64 %51
%57 = load i8, i8* %56
%58 = icmp ne i8 %57, 32
%59 = icmp ne i32 %52, 0
%60 = or i1 %59, %58
br i1 %60, label %65, label %61
61: ; preds = %55
store i8 0, i8* %56
%62 = getelementptr inbounds i8, i8* %56, i64 1
%63 = sext i32 %53 to i64
%64 = getelementptr inbounds [64 x i8*], [64 x i8*]* %2, i64 0, i64 %63
store i8* %62, i8** %64
br label %65
65: ; preds = %50, %61, %55, %1
%66 = getelementptr inbounds [64 x i8*], [64 x i8*]* %2, i64 0, i64 63
store i8* null, i8** %66
br label %67
67: ; preds = %65, %72
%68 = phi i64 [ 0, %65 ], [ %74, %72 ]
%69 = getelementptr inbounds [64 x i8*], [64 x i8*]* %2, i64 0, i64 %68
%70 = load i8*, i8** %69
%71 = icmp eq i8* %70, null
br i1 %71, label %76, label %72
72: ; preds = %67
%73 = call i32 @trim(i8* %70)
%74 = add nuw nsw i64 %68, 1
%75 = icmp eq i64 %74, 63
br i1 %75, label %76, label %67
76: ; preds = %67, %72
%77 = load i8*, i8** %7
%78 = icmp eq i8* %77, null
br i1 %78, label %99, label %79
79: ; preds = %76
%80 = call i32 @strcmp(i8* %77, i8* dereferenceable(3) getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0))
%81 = icmp eq i32 %80, 0
br i1 %81, label %82, label %95
82: ; preds = %79
%83 = getelementptr inbounds [64 x i8*], [64 x i8*]* %2, i64 0, i64 1
%84 = load i8*, i8** %83
%85 = icmp eq i8* %84, null
br i1 %85, label %99, label %86
86: ; preds = %82
%87 = call i64 @chdir(i8* %84)
%88 = icmp eq i64 %87, 0
br i1 %88, label %92, label %89
89: ; preds = %86
%90 = load i8*, i8** %83
%91 = call i32 @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.1, i64 0, i64 0), i8* %90)
br label %99
92: ; preds = %86
%93 = getelementptr inbounds [128 x i8], [128 x i8]* %3, i64 0, i64 0
%94 = call i32 @getcwd(i8* %93, i32 128)
br label %99
95: ; preds = %79
%96 = call i32 @execvp(i8* %77, i8** %7)
%97 = load i8*, i8** %7
%98 = call i32 @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.2, i64 0, i64 0), i8* %97)
br label %99
99: ; preds = %92, %95, %82, %76, %89
ret void
}