#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 */
int /*<<< orphan*/ printf(char *, unsigned long, unsigned long, unsigned long);
unsigned long XFindNVOffset(unsigned short wId, unsigned char *lpCode,
                            unsigned long dwCodeSize, unsigned long *dwOffset,
                            unsigned long *dwLength, unsigned long bBigEndian) {
  unsigned short wCurID;
  unsigned char *pTemp;
  unsigned long bRet;
  *dwOffset = 4;
  *dwLength = 0;
  pTemp = lpCode + *dwOffset;
  while (*dwOffset < dwCodeSize) {
    wCurID = *(unsigned short *)pTemp;
    pTemp += 2;
    *dwLength = *(unsigned short *)pTemp;
    pTemp += 2;
    *dwOffset += 4;
    bRet = (*dwLength) % 4;
    if (bRet != 0) {
      *dwLength += 4 - bRet;
    }
    if (wCurID == 0xFFFF) {
      return 0;
    }
    if (wCurID == wId) {
      printf("dwOffset = 0x%08x  dwLength = 0x%08x  bRet = %d\n", *dwOffset,
             *dwLength, bRet);
      if ((*dwOffset + *dwLength - bRet) <= dwCodeSize)
        return 1;
      else
        return 0;
    } else {
      *dwOffset += *dwLength;
      pTemp += *dwLength;
    }
  }
  return 0;
}


x86 assembly (clang, -O0):
<XFindNVOffset>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %di,%ax
mov    %ax,-0xa(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
mov    -0x28(%rbp),%rax
movq   $0x4,(%rax)
mov    -0x30(%rbp),%rax
movq   $0x0,(%rax)
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
add    (%rcx),%rax
mov    %rax,-0x48(%rbp)
mov    -0x28(%rbp),%rax
mov    (%rax),%rax
cmp    -0x20(%rbp),%rax
jae    127c <XFindNVOffset+0x16c>
mov    -0x48(%rbp),%rax
mov    (%rax),%ax
mov    %ax,-0x3a(%rbp)
mov    -0x48(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
movzwl (%rax),%eax
mov    %eax,%ecx
mov    -0x30(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x48(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x48(%rbp)
mov    -0x28(%rbp),%rax
mov    (%rax),%rcx
add    $0x4,%rcx
mov    %rcx,(%rax)
mov    -0x30(%rbp),%rax
mov    (%rax),%rax
and    $0x3,%rax
mov    %rax,-0x50(%rbp)
cmpq   $0x0,-0x50(%rbp)
je     11d7 <XFindNVOffset+0xc7>
mov    $0x4,%ecx
sub    -0x50(%rbp),%rcx
mov    -0x30(%rbp),%rax
add    (%rax),%rcx
mov    %rcx,(%rax)
movzwl -0x3a(%rbp),%eax
cmp    $0xffff,%eax
jne    11f3 <XFindNVOffset+0xe3>
movq   $0x0,-0x8(%rbp)
jmp    1284 <XFindNVOffset+0x174>
movzwl -0x3a(%rbp),%eax
movzwl -0xa(%rbp),%ecx
cmp    %ecx,%eax
jne    1257 <XFindNVOffset+0x147>
mov    -0x28(%rbp),%rax
mov    (%rax),%rsi
mov    -0x30(%rbp),%rax
mov    (%rax),%rdx
mov    -0x50(%rbp),%rcx
lea    0xde4(%rip),%rdi
call   1030 <printf@plt>
mov    -0x28(%rbp),%rax
mov    (%rax),%rax
mov    -0x30(%rbp),%rcx
add    (%rcx),%rax
sub    -0x50(%rbp),%rax
cmp    -0x20(%rbp),%rax
ja     124a <XFindNVOffset+0x13a>
movq   $0x1,-0x8(%rbp)
jmp    1284 <XFindNVOffset+0x174>
movq   $0x0,-0x8(%rbp)
jmp    1284 <XFindNVOffset+0x174>
mov    -0x30(%rbp),%rax
mov    (%rax),%rcx
mov    -0x28(%rbp),%rax
add    (%rax),%rcx
mov    %rcx,(%rax)
mov    -0x30(%rbp),%rax
mov    (%rax),%rax
add    -0x48(%rbp),%rax
mov    %rax,-0x48(%rbp)
jmp    1158 <XFindNVOffset+0x48>
movq   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<XFindNVOffset>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
movq   $0x4,(%rcx)
movq   $0x0,(%r8)
mov    (%rcx),%rax
cmp    %rdx,%rax
jae    118b <XFindNVOffset+0x7b>
mov    %r8,%r12
mov    %rcx,%r15
mov    %rdx,%r14
add    %rax,%rsi
xor    %eax,%eax
nopl   (%rax)
movzwl (%rsi),%ebx
movzwl 0x2(%rsi),%ecx
mov    %rcx,(%r12)
addq   $0x4,(%r15)
mov    (%r12),%rdx
mov    %rdx,%r13
and    $0x3,%r13
je     1168 <XFindNVOffset+0x58>
add    $0x4,%rdx
and    $0xfffffffffffffffc,%rdx
mov    %rdx,(%r12)
cmp    $0xffff,%bx
je     11b3 <XFindNVOffset+0xa3>
mov    (%r15),%rcx
cmp    %di,%bx
je     118f <XFindNVOffset+0x7f>
add    $0x4,%rsi
add    %rdx,%rcx
mov    %rcx,(%r15)
add    (%r12),%rsi
cmp    %r14,%rcx
jb     1140 <XFindNVOffset+0x30>
jmp    11b3 <XFindNVOffset+0xa3>
xor    %eax,%eax
jmp    11b3 <XFindNVOffset+0xa3>
lea    0xe6a(%rip),%rdi
mov    %rcx,%rsi
mov    %r13,%rcx
call   1030 <printf@plt>
mov    (%r15),%rcx
sub    %r13,%rcx
add    (%r12),%rcx
xor    %eax,%eax
cmp    %r14,%rcx
setbe  %al
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@.str = [49 x i8] c"dwOffset = 0x%08x dwLength = 0x%08x bRet = %d\0A\00"
define i64 @XFindNVOffset(i16 zeroext %0, i8* %1, i64 %2, i64* %3, i64* %4, i64 %5) {
%7 = alloca i64
%8 = alloca i16
%9 = alloca i8*
%10 = alloca i64
%11 = alloca i64*
%12 = alloca i64*
%13 = alloca i64
%14 = alloca i16
%15 = alloca i8*
%16 = alloca i64
store i16 %0, i16* %8
store i8* %1, i8** %9
store i64 %2, i64* %10
store i64* %3, i64** %11
store i64* %4, i64** %12
store i64 %5, i64* %13
%17 = load i64*, i64** %11
store i64 4, i64* %17
%18 = load i64*, i64** %12
store i64 0, i64* %18
%19 = load i8*, i8** %9
%20 = load i64*, i64** %11
%21 = load i64, i64* %20
%22 = getelementptr inbounds i8, i8* %19, i64 %21
store i8* %22, i8** %15
br label %23
23: ; preds = %94, %6
%24 = load i64*, i64** %11
%25 = load i64, i64* %24
%26 = load i64, i64* %10
%27 = icmp ult i64 %25, %26
br i1 %27, label %28, label %95
28: ; preds = %23
%29 = load i8*, i8** %15
%30 = bitcast i8* %29 to i16*
%31 = load i16, i16* %30
store i16 %31, i16* %14
%32 = load i8*, i8** %15
%33 = getelementptr inbounds i8, i8* %32, i64 2
store i8* %33, i8** %15
%34 = load i8*, i8** %15
%35 = bitcast i8* %34 to i16*
%36 = load i16, i16* %35
%37 = zext i16 %36 to i64
%38 = load i64*, i64** %12
store i64 %37, i64* %38
%39 = load i8*, i8** %15
%40 = getelementptr inbounds i8, i8* %39, i64 2
store i8* %40, i8** %15
%41 = load i64*, i64** %11
%42 = load i64, i64* %41
%43 = add i64 %42, 4
store i64 %43, i64* %41
%44 = load i64*, i64** %12
%45 = load i64, i64* %44
%46 = urem i64 %45, 4
store i64 %46, i64* %16
%47 = load i64, i64* %16
%48 = icmp ne i64 %47, 0
br i1 %48, label %49, label %55
49: ; preds = %28
%50 = load i64, i64* %16
%51 = sub i64 4, %50
%52 = load i64*, i64** %12
%53 = load i64, i64* %52
%54 = add i64 %53, %51
store i64 %54, i64* %52
br label %55
55: ; preds = %49, %28
%56 = load i16, i16* %14
%57 = zext i16 %56 to i32
%58 = icmp eq i32 %57, 65535
br i1 %58, label %59, label %60
59: ; preds = %55
store i64 0, i64* %7
br label %96
60: ; preds = %55
%61 = load i16, i16* %14
%62 = zext i16 %61 to i32
%63 = load i16, i16* %8
%64 = zext i16 %63 to i32
%65 = icmp eq i32 %62, %64
br i1 %65, label %66, label %84
66: ; preds = %60
%67 = load i64*, i64** %11
%68 = load i64, i64* %67
%69 = load i64*, i64** %12
%70 = load i64, i64* %69
%71 = load i64, i64* %16
%72 = call i32 @printf(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str, i64 0, i64 0), i64 %68, i64 %70, i64 %71)
%73 = load i64*, i64** %11
%74 = load i64, i64* %73
%75 = load i64*, i64** %12
%76 = load i64, i64* %75
%77 = add i64 %74, %76
%78 = load i64, i64* %16
%79 = sub i64 %77, %78
%80 = load i64, i64* %10
%81 = icmp ule i64 %79, %80
br i1 %81, label %82, label %83
82: ; preds = %66
store i64 1, i64* %7
br label %96
83: ; preds = %66
store i64 0, i64* %7
br label %96
84: ; preds = %60
%85 = load i64*, i64** %12
%86 = load i64, i64* %85
%87 = load i64*, i64** %11
%88 = load i64, i64* %87
%89 = add i64 %88, %86
store i64 %89, i64* %87
%90 = load i64*, i64** %12
%91 = load i64, i64* %90
%92 = load i8*, i8** %15
%93 = getelementptr inbounds i8, i8* %92, i64 %91
store i8* %93, i8** %15
br label %94
94: ; preds = %84
br label %23
95: ; preds = %23
store i64 0, i64* %7
br label %96
96: ; preds = %95, %83, %82, %59
%97 = load i64, i64* %7
ret i64 %97
}

LLVM IR (-O2):
@.str = [49 x i8] c"dwOffset = 0x%08x dwLength = 0x%08x bRet = %d\0A\00"
define i64 @XFindNVOffset(i16 zeroext %0, i8* nocapture %1, i64 %2, i64* nocapture %3, i64* nocapture %4, i64 %5) {
store i64 4, i64* %3
store i64 0, i64* %4
%7 = load i64, i64* %3
%8 = icmp ult i64 %7, %2
br i1 %8, label %9, label %47
9: ; preds = %6
%10 = getelementptr inbounds i8, i8* %1, i64 %7
br label %11
11: ; preds = %9, %42
%12 = phi i8* [ %45, %42 ], [ %10, %9 ]
%13 = bitcast i8* %12 to i16*
%14 = load i16, i16* %13
%15 = getelementptr inbounds i8, i8* %12, i64 2
%16 = bitcast i8* %15 to i16*
%17 = load i16, i16* %16
%18 = zext i16 %17 to i64
store i64 %18, i64* %4
%19 = getelementptr inbounds i8, i8* %12, i64 4
%20 = load i64, i64* %3
%21 = add i64 %20, 4
store i64 %21, i64* %3
%22 = load i64, i64* %4
%23 = and i64 %22, 3
%24 = icmp eq i64 %23, 0
br i1 %24, label %28, label %25
25: ; preds = %11
%26 = add i64 %22, 4
%27 = and i64 %26, -4
store i64 %27, i64* %4
br label %28
28: ; preds = %25, %11
%29 = phi i64 [ %27, %25 ], [ %22, %11 ]
%30 = icmp eq i16 %14, -1
br i1 %30, label %47, label %31
31: ; preds = %28
%32 = icmp eq i16 %14, %0
%33 = load i64, i64* %3
br i1 %32, label %34, label %42
34: ; preds = %31
%35 = tail call i32 @printf(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str, i64 0, i64 0), i64 %33, i64 %29, i64 %23)
%36 = load i64, i64* %3
%37 = load i64, i64* %4
%38 = sub i64 %36, %23
%39 = add i64 %38, %37
%40 = icmp ule i64 %39, %2
%41 = zext i1 %40 to i64
br label %47
42: ; preds = %31
%43 = add i64 %33, %29
store i64 %43, i64* %3
%44 = load i64, i64* %4
%45 = getelementptr inbounds i8, i8* %19, i64 %44
%46 = icmp ult i64 %43, %2
br i1 %46, label %11, label %47
47: ; preds = %28, %42, %6, %34
%48 = phi i64 [ %41, %34 ], [ 0, %6 ], [ 0, %42 ], [ 0, %28 ]
ret i64 %48
}