// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %edx
movq -0x18(%rbp), %rcx
movl $0x1, %esi
callq 0x36b0
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x28(%rbp)
leaq 0x305a(%rip), %rdi      # 0x6a4a
movb $0x0, %al
callq 0x1070
movq -0x28(%rbp), %rdi
callq 0x3c40
movl %eax, %esi
leaq 0x31cf(%rip), %rdi      # 0x6bd8
movb $0x0, %al
callq 0x1070
movq -0x28(%rbp), %rdi
addq $0x4, %rdi
callq 0x3c40
movl %eax, %esi
leaq 0x3046(%rip), %rdi      # 0x6a6c
movb $0x0, %al
callq 0x1070
movq -0x28(%rbp), %rdi
addq $0x8, %rdi
callq 0x3c40
movl %eax, %esi
leaq 0x354c(%rip), %rdi      # 0x6f8f
movb $0x0, %al
callq 0x1070
leaq 0x302d(%rip), %rdi      # 0x6a7e
movb $0x0, %al
callq 0x1070
movl $0x0, -0x1c(%rbp)
cmpl $0x10, -0x1c(%rbp)
jge 0x3a8f
movq -0x28(%rbp), %rax
movl -0x1c(%rbp), %ecx
addl $0xc, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %esi
leaq 0x300f(%rip), %rdi      # 0x6a8c
movb $0x0, %al
callq 0x1070
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x3a5f
leaq 0x2b44(%rip), %rdi      # 0x65da
movb $0x0, %al
callq 0x1070
movq -0x28(%rbp), %rdi
addq $0x1c, %rdi
callq 0x3c40
movl %eax, -0x2c(%rbp)
movq -0x28(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x3c40
movl %eax, -0x44(%rbp)
movq -0x40(%rbp), %rdi
addq $0x4, %rdi
callq 0x3c40
movl %eax, -0x48(%rbp)
movq -0x40(%rbp), %rdi
addq $0x8, %rdi
callq 0x3c40
movl %eax, -0x4c(%rbp)
movl -0x44(%rbp), %esi
leaq 0x2f94(%rip), %rdi      # 0x6a92
movb $0x0, %al
callq 0x1070
movl -0x48(%rbp), %esi
leaq 0x2f9b(%rip), %rdi      # 0x6aaa
movb $0x0, %al
callq 0x1070
movl -0x4c(%rbp), %esi
leaq 0x2fa2(%rip), %rdi      # 0x6ac2
movb $0x0, %al
callq 0x1070
leaq 0x2aad(%rip), %rdi      # 0x65db
movb $0x0, %al
callq 0x1070
leaq 0x2f9e(%rip), %rdi      # 0x6ada
movb $0x0, %al
callq 0x1070
leaq 0x2fab(%rip), %rdi      # 0x6af5
movb $0x0, %al
callq 0x1070
leaq 0x2fc4(%rip), %rdi      # 0x6b1c
movb $0x0, %al
callq 0x1070
leaq 0x2fe0(%rip), %rdi      # 0x6b46
movb $0x0, %al
callq 0x1070
leaq 0x2fec(%rip), %rdi      # 0x6b60
movb $0x0, %al
callq 0x1070
movq -0x40(%rbp), %rax
addq $0xc, %rax
movq %rax, -0x40(%rbp)
movl -0x4c(%rbp), %ecx
shll $0x2, %ecx
shll %ecx
movq -0x40(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x44(%rbp), %eax
jae 0x3c2a
movq -0x40(%rbp), %rdi
callq 0x3c40
movl %eax, -0x50(%rbp)
movq -0x40(%rbp), %rdi
addq $0x4, %rdi
callq 0x3c40
movl %eax, -0x54(%rbp)
movq -0x38(%rbp), %rax
movl -0x50(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movl -0x1c(%rbp), %esi
movl -0x54(%rbp), %edx
movq -0x60(%rbp), %rcx
movl -0x50(%rbp), %r8d
leaq 0x2fa0(%rip), %rdi      # 0x6b8a
movb $0x0, %al
callq 0x1070
movq -0x60(%rbp), %rsi
leaq 0x2fad(%rip), %rdi      # 0x6ba9
callq 0x1090
cmpl $0x0, %eax
jne 0x3c10
movl -0x54(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x28(%rax)
movq -0x40(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x40(%rbp)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x3ba3
leaq 0x29aa(%rip), %rdi      # 0x65db
movb $0x0, %al
callq 0x1070
addq $0x60, %rsp
popq %rbp
retq
nop