// File: /workspace/github_c_makefile_star2_O2/mikeakohn[P]print_pe/build/../src/pdb.c
// Function: print_pdb_stream_info
void print_pdb_stream_info(
  struct pdb_dir_t *pdb_dir,
  struct pdb_header_t *pdb_header,
  FILE *in)
{
  //int total_length = pdb_dir->stream_sizes[1];
  int i;

  read_data(pdb_dir, 1, pdb_header->block_size, in);

  uint8_t *data = pdb_dir->heap;

  printf(" -- PDB Info Stream (index 1) --\n");

  printf("     version: %d\n", get_uint32(data + 0));
  printf("   signature: %d\n", get_uint32(data + 4));
  printf("         age: %d\n", get_uint32(data + 8));
  printf("        guid:");

  for (i = 0; i < 16; i++)
  {
    printf(" %02x", data[i + 12]);
  }
  printf("\n\n");

  // This is the length of the names section.
  int length = get_uint32(data + 28);

  uint8_t *names = data + 32;
  uint8_t *hash = names + length;

  uint32_t hash_size = get_uint32(hash + 0);
  uint32_t hash_capacity = get_uint32(hash + 4);
  uint32_t vector_words = get_uint32(hash + 8);

  printf("         hash_size: %d\n", hash_size);
  printf("     hash_capacity: %d\n", hash_capacity);
  printf("  bit_vector_count: %d\n", vector_words);
  printf("\n");

  printf("   index=0  /OldDirectory\n");
  printf("   index=1  /PDB (Stream Information)\n");
  printf("   index=2  /TPI (CodeView Type Records)\n");
  printf("   index=3  /DBI (Debug)\n");
  printf("   index=4  /IPI (CodeView Type Records)\n");

  // FIXME: According to some docs, the full hash is supposed to be in
  // the file. So the for loop below should be hash_capacity in length
  // and buckets are ignored by bits in the vector_mask. In the test file
  // though, doing that ends up with 11 words for a capacity of 6 (should
  // be 12 words in the file. Or maybe it's 10 words because the deleted
  // buckets is it's own word (as it's implemented here). This seems to work
  // though.

  hash += 12;

  //const uint32_t *vector_bits = (uint32_t *)hash;
  hash += vector_words * 4 * 2;

  for (i = 0; i < hash_size; i++)
  {
    //if ((vector_bits[ptr] & bit_mask) != 0)
    {
      uint32_t key = get_uint32(hash + 0);
      uint32_t value = get_uint32(hash + 4);
      const char *name = (char *)names + key;

      printf("%d: index=%-2d %s (offset=%d)\n", i, value, name, key);

      if (strcmp("/names", name) == 0)
      {
        pdb_dir->names_index = value;
      }
    }

    hash += 8;
  };

  printf("\n");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rcx
movq %rdi, %rbx
movl 0x58(%rsi), %edx
pushq $0x1
popq %rsi
callq 0x298d
movq %rbx, 0x8(%rsp)
movq 0x18(%rbx), %rbx
leaq 0x2cc8(%rip), %rdi      # 0x58de
callq 0x1060
movl (%rbx), %esi
leaq 0x1dd0(%rip), %rdi      # 0x49f4
xorl %eax, %eax
callq 0x1090
movl 0x4(%rbx), %esi
leaq 0x1d03(%rip), %rdi      # 0x4938
xorl %eax, %eax
callq 0x1090
movl 0x8(%rbx), %esi
leaq 0x2152(%rip), %rdi      # 0x4d98
xorl %eax, %eax
callq 0x1090
leaq 0x1cf6(%rip), %rdi      # 0x494a
xorl %eax, %eax
callq 0x1090
leaq 0x1cf6(%rip), %r14      # 0x4958
xorl %r15d, %r15d
cmpq $0x10, %r15
je 0x2c80
movzbl 0xc(%rbx,%r15), %esi
movq %r14, %rdi
xorl %eax, %eax
callq 0x1090
incq %r15
jmp 0x2c65
leaq 0x2b95(%rip), %rdi      # 0x581c
callq 0x1060
movslq 0x1c(%rbx), %rax
leaq 0x20(%rbx), %rcx
movq %rcx, 0x10(%rsp)
leaq (%rbx,%rax), %r12
addq $0x20, %r12
movl 0x20(%rbx,%rax), %r14d
movl 0x24(%rbx,%rax), %ebp
movl 0x28(%rbx,%rax), %ebx
leaq 0x1ca9(%rip), %rdi      # 0x495e
movl %r14d, %esi
xorl %eax, %eax
callq 0x1090
leaq 0x1cb0(%rip), %rdi      # 0x4976
movl %ebp, %esi
xorl %eax, %eax
callq 0x1090
leaq 0x1cb8(%rip), %rdi      # 0x498e
movl %ebx, %esi
xorl %eax, %eax
callq 0x1090
pushq $0xa
popq %rdi
callq 0x1040
leaq 0x2c11(%rip), %rdi      # 0x58ff
callq 0x1060
leaq 0x2c1f(%rip), %rdi      # 0x5919
callq 0x1060
leaq 0x2c39(%rip), %rdi      # 0x593f
callq 0x1060
leaq 0x2c56(%rip), %rdi      # 0x5968
callq 0x1060
leaq 0x2c63(%rip), %rdi      # 0x5981
callq 0x1060
shll $0x3, %ebx
leaq (%rbx,%r12), %r15
addq $0xc, %r15
leaq 0x1c90(%rip), %r12      # 0x49c5
xorl %r13d, %r13d
cmpl %r13d, %r14d
je 0x2d80
movl (%r15,%r13,8), %r8d
movl 0x4(%r15,%r13,8), %ebp
movq %r8, %rbx
addq 0x10(%rsp), %rbx
leaq 0x1c51(%rip), %rdi      # 0x49a6
movl %r13d, %esi
movl %ebp, %edx
movq %rbx, %rcx
xorl %eax, %eax
callq 0x1090
movq %r12, %rdi
movq %rbx, %rsi
callq 0x10b0
testl %eax, %eax
jne 0x2d7b
movq 0x8(%rsp), %rax
movl %ebp, 0x28(%rax)
incq %r13
jmp 0x2d38
pushq $0xa
popq %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1040