// File: /workspace/github_c_makefile_star2_O0/mikeakohn[P]print_pe/build/../src/optional_header.c
// Function: optional_header_read
int optional_header_read(
  struct optional_header_t *optional_header,
  FILE *in,
  int header_size)
{
  int t;

  long marker = ftell(in);

  optional_header->Magic = read_uint16(in);
  optional_header->MajorLinkerVersion = getc(in);
  optional_header->MinorLinkerVersion = getc(in);
  optional_header->SizeOfCode = read_uint32(in);
  optional_header->SizeOfInitializedData = read_uint32(in);
  optional_header->SizeOfUninitializedData = read_uint32(in);
  optional_header->AddressOfEntryPoint = read_uint32(in);
  optional_header->BaseOfCode = read_uint32(in);

  int bitsize = 32;

  if (optional_header->Magic != 0x20b)
  {
    optional_header->BaseOfData = read_uint32(in);
  }
    else
  {
    bitsize = 64;
  }

  // FIXME: header_size for PE32 is 28, PE32+ is 24.  Is this really
  //        needed anyway?
  if (header_size <= 28) { return 0; }

  if (bitsize == 32)
  {
    optional_header->ImageBase = read_uint32(in);
  }
    else
  {
    optional_header->ImageBase = read_uint64(in);
  }

  optional_header->SectionAlignment = read_uint32(in);
  optional_header->FileAlignment = read_uint32(in);
  optional_header->MajorOperatingSystemVersion = read_uint16(in);
  optional_header->MinorOperatingSystemVersion = read_uint16(in);
  optional_header->MajorImageVersion = read_uint16(in);
  optional_header->MinorImageVersion = read_uint16(in);
  optional_header->MajorSubsystemVersion = read_uint16(in);
  optional_header->MinorSubsystemVersion = read_uint16(in);
  optional_header->Reserved1 = read_uint32(in);
  optional_header->SizeOfImage = read_uint32(in);
  optional_header->SizeOfHeaders = read_uint32(in);
  optional_header->CheckSum = read_uint32(in);
  optional_header->Subsystem = read_uint16(in);
  optional_header->DllCharacteristics = read_uint16(in);

  if (bitsize == 32)
  {
    optional_header->SizeOfStackReserve = read_uint32(in);
    optional_header->SizeOfStackCommit = read_uint32(in);
    optional_header->SizeOfHeapReserve = read_uint32(in);
    optional_header->SizeOfHeapCommit = read_uint32(in);
  }
    else
  {
    optional_header->SizeOfStackReserve = read_uint64(in);
    optional_header->SizeOfStackCommit = read_uint64(in);
    optional_header->SizeOfHeapReserve = read_uint64(in);
    optional_header->SizeOfHeapCommit = read_uint64(in);
  }

  optional_header->LoaderFlags = read_uint32(in);
  optional_header->NumberOfRvaAndSizes = read_uint32(in);

  int used_length = (int)(ftell(in) - marker);

  if (header_size > used_length)
  {
    optional_header->DataDirectoryCount = (header_size - used_length) / 8;

    for (t = 0; t < optional_header->DataDirectoryCount; t++)
    {
      optional_header->directory_entry[t].virtual_address = read_uint32(in);
      optional_header->directory_entry[t].size = read_uint32(in);
    }
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x18(%rbp), %rdi
callq 0x30e0
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, (%rax)
movq -0x18(%rbp), %rdi
callq 0x3150
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x2(%rax)
movq -0x18(%rbp), %rdi
callq 0x3150
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x3(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x14(%rax)
movl $0x20, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movzwl (%rax), %eax
cmpl $0x20b, %eax            # imm = 0x20B
je 0x691a
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x18(%rax)
jmp 0x6921
movl $0x40, -0x2c(%rbp)
cmpl $0x1c, -0x1c(%rbp)
jg 0x6933
movl $0x0, -0x4(%rbp)
jmp 0x6bc2
cmpl $0x20, -0x2c(%rbp)
jne 0x694f
movq -0x18(%rbp), %rdi
callq 0x6010
movslq %eax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x6963
movq -0x18(%rbp), %rdi
callq 0x5f40
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x28(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x2c(%rax)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x30(%rax)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x32(%rax)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x34(%rax)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x36(%rax)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x38(%rax)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x3a(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x3c(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x40(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x44(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x48(%rax)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x4c(%rax)
movq -0x18(%rbp), %rdi
callq 0x6070
movw %ax, %cx
movq -0x10(%rbp), %rax
movw %cx, 0x4e(%rax)
cmpl $0x20, -0x2c(%rbp)
jne 0x6ac7
movq -0x18(%rbp), %rdi
callq 0x6010
movslq %eax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x50(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movslq %eax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x58(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movslq %eax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x60(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movslq %eax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x68(%rax)
jmp 0x6b17
movq -0x18(%rbp), %rdi
callq 0x5f40
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x50(%rax)
movq -0x18(%rbp), %rdi
callq 0x5f40
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x58(%rax)
movq -0x18(%rbp), %rdi
callq 0x5f40
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x60(%rax)
movq -0x18(%rbp), %rdi
callq 0x5f40
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x70(%rax)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x74(%rax)
movq -0x18(%rbp), %rdi
callq 0x30e0
subq -0x28(%rbp), %rax
movl %eax, -0x30(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jle 0x6bbb
movl -0x1c(%rbp), %eax
subl -0x30(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x78(%rax)
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x78(%rcx), %eax
jge 0x6bb9
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %edx
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movl %edx, 0x7c(%rax,%rcx,8)
movq -0x18(%rbp), %rdi
callq 0x6010
movl %eax, %edx
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movl %edx, 0x80(%rax,%rcx,8)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x6b71
jmp 0x6bbb
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)