// File: /workspace/github_c_makefile_star2_O0/shuffle2[P]nx2elf/nx2elf.cpp
// Function: NsoFile::DumpElfInfo()
void DumpElfInfo() {
    puts("dynamic:");
    struct {
      Elf64_Rela* rela;
      u64 num_rela;
      Elf64_Rela* jmprel;
      u64 num_jmprel;
    } rela_info;
    for (auto dyn = dynamic; dyn->d_tag; dyn++) {
      printf("%16" PRIx64 " %16" PRIx64 "\n", dyn->d_tag, dyn->d_un);

#define DT_ASSIGN_PTR(dt, var, x)                                   \
  case dt:                                                          \
    rela_info.var = reinterpret_cast<decltype(rela_info.var)>((x)); \
    break;
#define DT_ASSIGN_U64(dt, var, x)                              \
  case dt:                                                     \
    rela_info.var = static_cast<decltype(rela_info.var)>((x)); \
    break;

      switch (dyn->d_tag) {
        DT_ASSIGN_PTR(DT_RELA, rela, &image[dyn->d_un]);
        DT_ASSIGN_U64(DT_RELASZ, num_rela, dyn->d_un / sizeof(*rela_info.rela));
        DT_ASSIGN_PTR(DT_JMPREL, jmprel, &image[dyn->d_un]);
        DT_ASSIGN_U64(DT_PLTRELSZ, num_jmprel,
                      dyn->d_un / sizeof(*rela_info.jmprel));
      }
#undef DT_ASSIGN_U64
#undef DT_ASSIGN_PTR
    }
    puts("rela:");
    for (size_t i = 0; i < rela_info.num_rela; i++) {
      auto& rela = rela_info.rela[i];
      printf("%16" PRIx64 " %8x %8x %16" PRIx64 "\n", rela.r_offset,
             ELF64_R_SYM(rela.r_info), ELF64_R_TYPE(rela.r_info),
             rela.r_addend);
    }
    puts("jmprel:");
    for (size_t i = 0; i < rela_info.num_jmprel; i++) {
      auto& rela = rela_info.jmprel[i];
      printf("%16" PRIx64 " %8x %8x %16" PRIx64 "x\n", rela.r_offset,
             ELF64_R_SYM(rela.r_info), ELF64_R_TYPE(rela.r_info),
             rela.r_addend);
    }

    auto rodata = &image[header.segments[kRodata].mem_offset];
    auto dynstr = reinterpret_cast<const char*>(&rodata[header.dynstr.offset]);
    puts("symbols:");
    iter_dynsym([&](const Elf64_Sym& sym, u32) {
      auto name = &dynstr[sym.st_name];
      printf("%x %x %x %4x %16" PRIx64 " %16" PRIx64 " %s\n",
             ELF64_ST_BIND(sym.st_info), ELF64_ST_TYPE(sym.st_info),
             ELF64_ST_VISIBILITY(sym.st_other), sym.st_shndx, sym.st_value,
             sym.st_size, name);
    });
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa0(%rbp)
leaq 0x62960(%rip), %rdi     # 0x683a1
callq 0x2330
movq -0xa0(%rbp), %rax
movq 0x120(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq $0x0, (%rax)
je 0x5b35
movq -0x30(%rbp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
leaq 0x62932(%rip), %rdi     # 0x683aa
xorl %eax, %eax
callq 0x2030
movq -0x30(%rbp), %rax
movq (%rax), %rax
addq $-0x2, %rax
movq %rax, -0xa8(%rbp)
subq $0x15, %rax
ja 0x5b22
movq -0xa8(%rbp), %rax
leaq 0x625a7(%rip), %rcx     # 0x68050
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0xa0(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x8f70
movq %rax, -0x28(%rbp)
jmp 0x5b22
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movl $0x18, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, -0x20(%rbp)
jmp 0x5b22
movq -0xa0(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x8f70
movq %rax, -0x18(%rbp)
jmp 0x5b22
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movl $0x18, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, -0x10(%rbp)
jmp 0x5b24
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x30(%rbp)
jmp 0x5a58
leaq 0x6287b(%rip), %rdi     # 0x683b7
callq 0x2330
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x20(%rbp), %rax
jae 0x5ba6
movq -0x28(%rbp), %rax
imulq $0x18, -0x38(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rsi
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
movl %eax, %edx
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movl %eax, %ecx
movq -0x40(%rbp), %rax
movq 0x10(%rax), %r8
leaq 0x6282c(%rip), %rdi     # 0x683bd
movb $0x0, %al
callq 0x2030
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x5b49
leaq 0x62825(%rip), %rdi     # 0x683d2
callq 0x2330
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x5c17
movq -0x18(%rbp), %rax
imulq $0x18, -0x48(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq (%rax), %rsi
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0x20, %rax
movl %eax, %edx
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movl %eax, %ecx
movq -0x50(%rbp), %rax
movq 0x10(%rax), %r8
leaq 0x627d8(%rip), %rdi     # 0x683da
movb $0x0, %al
callq 0x2030
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x5bba
movq -0xa0(%rbp), %rax
movq %rax, %rdi
addq $0x108, %rdi            # imm = 0x108
movl 0x28(%rax), %eax
movl %eax, %esi
callq 0x8f70
movq -0xa0(%rbp), %rcx
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movl 0x94(%rcx), %ecx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
leaq 0x6279b(%rip), %rdi     # 0x683f0
callq 0x2330
leaq -0x60(%rbp), %rax
movq %rax, -0x88(%rbp)
leaq -0x80(%rbp), %rdi
movq %rdi, -0xb0(%rbp)
leaq -0x88(%rbp), %rsi
callq 0xd440
movq -0xa0(%rbp), %rdi
movq -0xb0(%rbp), %rsi
callq 0x92d0
jmp 0x5c91
leaq -0x80(%rbp), %rdi
callq 0x9400
addq $0xb0, %rsp
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x90(%rbp)
movl %eax, -0x94(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x9400
movq -0x90(%rbp), %rdi
callq 0x2370
nopw (%rax,%rax)