// File: /workspace/github_c_makefile_star2_O2/mikeakohn[P]print_pe/build/../src/optional_header.c
// Function: optional_header_print
int optional_header_print(struct optional_header_t *optional_header)
{
  int t;

  printf("---------------------------------------------\n");
  printf("Image Optional Header\n");
  printf("---------------------------------------------\n");

  const char *magic;

  switch (optional_header->Magic)
  {
    case 0x10b: magic = "PE32 32 Bit Exe"; break;
    case 0x20b: magic = "PE32+ 64 Bit Exe"; break;
    case 0x107: magic = "ROM"; break;
    default: magic = "Unknown"; break;
  }

  printf("             Magic: 0x%04x (%s)\n", optional_header->Magic, magic);

  printf("MajorLinkerVersion: %d\n", optional_header->MajorLinkerVersion);
  printf("MinorLinkerVersion: %d\n", optional_header->MinorLinkerVersion);
  printf("        SizeOfCode: %d\n", optional_header->SizeOfCode);
  printf("SizeOfInitilzdData: %d\n", optional_header->SizeOfInitializedData);
  printf("SizeOfUnintlzdData: %d\n", optional_header->SizeOfUninitializedData);
  printf("  AddrOfEntryPoint: %d\n", optional_header->AddressOfEntryPoint);
  printf("        BaseOfCode: %d\n", optional_header->BaseOfCode);
  printf("        BaseOfData: %d\n", optional_header->BaseOfData);
  printf("         ImageBase: 0x%" PRIx64 "\n", optional_header->ImageBase);
  printf("  SectionAlignment: %d\n", optional_header->SectionAlignment);
  printf("     FileAlignment: %d\n", optional_header->FileAlignment);
  printf("    MajorOSVersion: %d\n", optional_header->MajorOperatingSystemVersion);
  printf("    MinorOSVersion: %d\n", optional_header->MinorOperatingSystemVersion);
  printf(" MajorImageVersion: %d\n", optional_header->MajorImageVersion);
  printf(" MinorImageVersion: %d\n", optional_header->MinorImageVersion);
  printf(" MajorSubsystemVer: %d\n", optional_header->MajorSubsystemVersion);
  printf(" MinorSubsystemVer: %d\n", optional_header->MinorSubsystemVersion);
  printf("         Reserved1: %d\n", optional_header->Reserved1);
  printf("       SizeOfImage: %d\n", optional_header->SizeOfImage);
  printf("     SizeOfHeaders: %d\n", optional_header->SizeOfHeaders);
  printf("          CheckSum: %d\n", optional_header->CheckSum);

  const char *subsystem;

  switch (optional_header->Subsystem)
  {
    case 1: subsystem = "Native"; break;
    case 2: subsystem = "GUI"; break;
    case 3: subsystem = "Console"; break;
    case 5: subsystem = "OS2 GUI"; break;
    case 7: subsystem = "Posix Console"; break;
    case 9: subsystem = "Windows CE GUI"; break;
    case 10: subsystem = "EFI App"; break;
    case 11: subsystem = "EFI Boot Service Driver"; break;
    case 12: subsystem = "EFI Runtime Driver"; break;
    case 13: subsystem = "EFI ROM"; break;
    case 14: subsystem = "Xbox"; break;
    case 15: subsystem = "Windows Boot Application"; break;
    default: subsystem = "Unknown"; break;
  }

  printf("         Subsystem: %d (%s)\n", optional_header->Subsystem, subsystem);
  printf("DllCharacteristics: 0x%04x", optional_header->DllCharacteristics);

  if ((optional_header->DllCharacteristics & 1) != 0)
  {
    printf(" (Reserved_1)");
  }

  if ((optional_header->DllCharacteristics & 2) != 0)
  {
    printf(" (Reserved_2)");
  }

  if ((optional_header->DllCharacteristics & 4) != 0)
  {
    printf(" (Reserved_4)");
  }

  if ((optional_header->DllCharacteristics & 8) != 0)
  {
    printf(" (Reserved_8)");
  }

  if ((optional_header->DllCharacteristics & 0x40) != 0)
  {
    printf(" (Dyanamic Base)");
  }

  if ((optional_header->DllCharacteristics & 0x80) != 0)
  {
    printf(" (Force Integrity)");
  }

  if ((optional_header->DllCharacteristics & 0x100) != 0)
  {
    printf(" (NX Compatiblity)");
  }

  if ((optional_header->DllCharacteristics & 0x200) != 0)
  {
    printf(" (No Isolation)");
  }

  if ((optional_header->DllCharacteristics & 0x400) != 0)
  {
    printf(" (No Structure Exception Handling)");
  }

  if ((optional_header->DllCharacteristics & 0x800) != 0)
  {
    printf(" (No Bind)");
  }

  if ((optional_header->DllCharacteristics & 0x2000) != 0)
  {
    printf(" (WDM Driver)");
  }

  if ((optional_header->DllCharacteristics & 0x8000) != 0)
  {
    printf(" (Terminal Server Aware)");
  }

  printf("\n");

  printf("SizeOfStackReserve: %" PRId64 "\n", optional_header->SizeOfStackReserve);
  printf(" SizeOfStackCommit: %" PRId64 "\n", optional_header->SizeOfStackCommit);
  printf(" SizeOfHeapReserve: %" PRId64 "\n", optional_header->SizeOfHeapReserve);
  printf("  SizeOfHeapCommit: %" PRId64 "\n", optional_header->SizeOfHeapCommit);
  printf("       LoaderFlags: %d\n", optional_header->LoaderFlags);
  printf("  NumOfRvaAndSizes: %d\n", optional_header->NumberOfRvaAndSizes);
  printf("\n");

  if (optional_header->DataDirectoryCount != 0)
  {
    printf("   Directory Description             VirtualAddr  Size\n");

    for (t = 0; t < optional_header->DataDirectoryCount; t++)
    {
      const char *desc;

      if (t < sizeof(dir_entries) / sizeof(char *))
      {
        desc = dir_entries[t];
      }
        else
      {
        desc = "";
      }

      printf("%2d %-33s 0x%08x   0x%08x (%d)\n", t, desc,
        optional_header->directory_entry[t].virtual_address,
        optional_header->directory_entry[t].size,
        optional_header->directory_entry[t].size);
    }

    if (t != 0) { printf("\n"); }
  }

  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
leaq 0x2932(%rip), %r14      # 0x8241
movq %r14, %rdi
callq 0x3060
leaq 0x43a9(%rip), %rdi      # 0x9cc7
callq 0x3060
movq %r14, %rdi
callq 0x3060
movzwl (%rbx), %esi
cmpl $0x107, %esi            # imm = 0x107
je 0x5958
cmpl $0x10b, %esi            # imm = 0x10B
je 0x594f
cmpl $0x20b, %esi            # imm = 0x20B
jne 0x5961
leaq 0x3f08(%rip), %rdx      # 0x9855
jmp 0x5968
leaq 0x3eef(%rip), %rdx      # 0x9845
jmp 0x5968
leaq 0x4186(%rip), %rdx      # 0x9ae5
jmp 0x5968
leaq 0x3338(%rip), %rdx      # 0x8ca0
leaq 0x3ef7(%rip), %rdi      # 0x9866
xorl %eax, %eax
callq 0x3090
movzbl 0x2(%rbx), %esi
leaq 0x3f06(%rip), %rdi      # 0x9887
xorl %eax, %eax
callq 0x3090
movzbl 0x3(%rbx), %esi
leaq 0x3f0c(%rip), %rdi      # 0x989f
xorl %eax, %eax
callq 0x3090
movl 0x4(%rbx), %esi
leaq 0x3f13(%rip), %rdi      # 0x98b7
xorl %eax, %eax
callq 0x3090
movl 0x8(%rbx), %esi
leaq 0x3f1a(%rip), %rdi      # 0x98cf
xorl %eax, %eax
callq 0x3090
movl 0xc(%rbx), %esi
leaq 0x3f21(%rip), %rdi      # 0x98e7
xorl %eax, %eax
callq 0x3090
movl 0x10(%rbx), %esi
leaq 0x3f28(%rip), %rdi      # 0x98ff
xorl %eax, %eax
callq 0x3090
movl 0x14(%rbx), %esi
leaq 0x3f2f(%rip), %rdi      # 0x9917
xorl %eax, %eax
callq 0x3090
movl 0x18(%rbx), %esi
leaq 0x3f36(%rip), %rdi      # 0x992f
xorl %eax, %eax
callq 0x3090
movq 0x20(%rbx), %rsi
leaq 0x3f3c(%rip), %rdi      # 0x9947
xorl %eax, %eax
callq 0x3090
movl 0x28(%rbx), %esi
leaq 0x3f46(%rip), %rdi      # 0x9962
xorl %eax, %eax
callq 0x3090
movl 0x2c(%rbx), %esi
leaq 0x3f4d(%rip), %rdi      # 0x997a
xorl %eax, %eax
callq 0x3090
movzwl 0x30(%rbx), %esi
leaq 0x3f53(%rip), %rdi      # 0x9992
xorl %eax, %eax
callq 0x3090
movzwl 0x32(%rbx), %esi
leaq 0x3f59(%rip), %rdi      # 0x99aa
xorl %eax, %eax
callq 0x3090
movzwl 0x34(%rbx), %esi
leaq 0x3f5f(%rip), %rdi      # 0x99c2
xorl %eax, %eax
callq 0x3090
movzwl 0x36(%rbx), %esi
leaq 0x3f65(%rip), %rdi      # 0x99da
xorl %eax, %eax
callq 0x3090
movzwl 0x38(%rbx), %esi
leaq 0x3f6b(%rip), %rdi      # 0x99f2
xorl %eax, %eax
callq 0x3090
movzwl 0x3a(%rbx), %esi
leaq 0x3f71(%rip), %rdi      # 0x9a0a
xorl %eax, %eax
callq 0x3090
movl 0x3c(%rbx), %esi
leaq 0x3f78(%rip), %rdi      # 0x9a22
xorl %eax, %eax
callq 0x3090
movl 0x40(%rbx), %esi
leaq 0x3f7f(%rip), %rdi      # 0x9a3a
xorl %eax, %eax
callq 0x3090
movl 0x44(%rbx), %esi
leaq 0x3f86(%rip), %rdi      # 0x9a52
xorl %eax, %eax
callq 0x3090
movl 0x48(%rbx), %esi
leaq 0x3f8d(%rip), %rdi      # 0x9a6a
xorl %eax, %eax
callq 0x3090
movzwl 0x4c(%rbx), %esi
leal -0x1(%rsi), %eax
cmpw $0xe, %ax
ja 0x5b04
movzwl %ax, %eax
leaq 0x4219(%rip), %rcx      # 0x9d14
movslq (%rcx,%rax,4), %rdx
addq %rcx, %rdx
jmp 0x5b0b
leaq 0x3195(%rip), %rdx      # 0x8ca0
leaq 0x3ff5(%rip), %rdi      # 0x9b07
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %esi
leaq 0x4000(%rip), %rdi      # 0x9b24
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
testb $0x1, %al
je 0x5b45
leaq 0x4005(%rip), %rdi      # 0x9b3f
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
testb $0x2, %al
je 0x5b5b
leaq 0x3ffd(%rip), %rdi      # 0x9b4d
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
testb $0x4, %al
je 0x5b71
leaq 0x3ff5(%rip), %rdi      # 0x9b5b
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
testb $0x8, %al
je 0x5b87
leaq 0x3fed(%rip), %rdi      # 0x9b69
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
testb $0x40, %al
je 0x5b9d
leaq 0x3fe5(%rip), %rdi      # 0x9b77
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
testb %al, %al
jns 0x5bb3
leaq 0x3fe0(%rip), %rdi      # 0x9b88
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
btl $0x8, %eax
jae 0x5bcb
leaq 0x3fdb(%rip), %rdi      # 0x9b9b
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
btl $0x9, %eax
jae 0x5be3
leaq 0x3fd6(%rip), %rdi      # 0x9bae
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
btl $0xa, %eax
jae 0x5bfb
leaq 0x3fce(%rip), %rdi      # 0x9bbe
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
btl $0xb, %eax
jae 0x5c13
leaq 0x3fd9(%rip), %rdi      # 0x9be1
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
btl $0xd, %eax
jae 0x5c2b
leaq 0x3fcc(%rip), %rdi      # 0x9bec
xorl %eax, %eax
callq 0x3090
movzwl 0x4e(%rbx), %eax
testw %ax, %ax
jns 0x5c3e
leaq 0x3fc3(%rip), %rdi      # 0x9bfa
xorl %eax, %eax
callq 0x3090
pushq $0xa
popq %rbp
movl %ebp, %edi
callq 0x3030
movq 0x50(%rbx), %rsi
leaq 0x3fc0(%rip), %rdi      # 0x9c13
xorl %eax, %eax
callq 0x3090
movq 0x58(%rbx), %rsi
leaq 0x3fc7(%rip), %rdi      # 0x9c2c
xorl %eax, %eax
callq 0x3090
movq 0x60(%rbx), %rsi
leaq 0x3fce(%rip), %rdi      # 0x9c45
xorl %eax, %eax
callq 0x3090
movq 0x68(%rbx), %rsi
leaq 0x3fd5(%rip), %rdi      # 0x9c5e
xorl %eax, %eax
callq 0x3090
movl 0x70(%rbx), %esi
leaq 0x3fdd(%rip), %rdi      # 0x9c77
xorl %eax, %eax
callq 0x3090
movl 0x74(%rbx), %esi
leaq 0x3fe4(%rip), %rdi      # 0x9c8f
xorl %eax, %eax
callq 0x3090
movl %ebp, %edi
callq 0x3030
cmpl $0x0, 0x78(%rbx)
je 0x5d2c
leaq 0x4017(%rip), %rdi      # 0x9cdd
callq 0x3060
leaq 0x83fe(%rip), %r12      # 0xe0d0
leaq 0x2442(%rip), %r13      # 0x811b
leaq 0x3fc7(%rip), %r14      # 0x9ca7
xorl %r15d, %r15d
movslq 0x78(%rbx), %rax
cmpq %rax, %r15
jge 0x5d1f
movq %r13, %rdx
cmpq $0xe, %r15
ja 0x5cf9
movq (%r12), %rdx
movl 0x7c(%rbx,%r15,8), %ecx
movl 0x80(%rbx,%r15,8), %r8d
movq %r14, %rdi
movl %r15d, %esi
movl %r8d, %r9d
xorl %eax, %eax
callq 0x3090
incq %r15
addq $0x8, %r12
jmp 0x5ce3
testq %r15, %r15
je 0x5d2c
pushq $0xa
popq %rdi
callq 0x3030
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)