// File: /workspace/github_c_makefile_star2_O0/buptlxb[P]xRay/src/binary.cpp
// Function: BinInfo::BinInfo(char const*)
BinInfo::BinInfo(const char *file_name):file_name(file_name), mapStart(NULL)
{
    fprintf(stderr, "Start processing %s\n", file_name);
    // 1.open file
    int fd = open(file_name, O_RDONLY);
    assert(fd!=-1);
    // 2.calculate elf size
    struct stat statbuf;
    assert(fstat(fd, &statbuf)==0);
    elf_size = statbuf.st_size;
    // 3.mmap elf
    mapStart = mmap(NULL, elf_size, PROT_READ, MAP_PRIVATE, fd, 0);
    if(mapStart==MAP_FAILED) {
        perror("Map ELF: ");
        abort();
    }
    // 4.isElf
    assert(isElf(mapStart));
    // 5.judgeIsSharedObject
    Elf64_Ehdr *elf_header = (Elf64_Ehdr*)mapStart;
    Elf64_Half elf_type = elf_header->e_type;
    if(elf_type==ET_EXEC)
        isSharedObjectFile = false;
    else if(elf_type==ET_DYN)
        isSharedObjectFile = true;
    else{
        cerr<<"xRay can only handle execute file and shared object file!"<<endl;
        abort();
    }

    Elf64_Half section_num = elf_header->e_shnum;
    Elf64_Shdr *section_table = (Elf64_Shdr*)((ADDR)mapStart+elf_header->e_shoff);
    char *shstrtab = (char *)((ADDR)mapStart + section_table[elf_header->e_shstrndx].sh_offset);
    char *strtab = NULL;
    for(int i=0; i<section_num; i++) {
        if (!strcmp(shstrtab + section_table[i].sh_name, ".strtab")) {
            strtab = (char *)((ADDR)mapStart + section_table[i].sh_offset);
            //printf("0x%lx\n", section_table[i].sh_offset);
        }
    }
    for(int i=0; i<section_num; i++) {
        if (section_table[i].sh_type != SHT_SYMTAB)
            continue;
        Elf64_Sym *sym_table = (Elf64_Sym *)((ADDR)mapStart+section_table[i].sh_offset);
        Elf64_Xword sym_num = section_table[i].sh_size / section_table[i].sh_entsize;

        for (int i = 0; i < sym_num; i++) {
            if (ELF64_ST_TYPE(sym_table[i].st_info) != STT_FUNC)
                continue;
            if (sym_table[i].st_shndx == SHN_UNDEF || sym_table[i].st_shndx > elf_header->e_shnum)
                continue;
            if (sym_table[i].st_size == 0)
                continue;
            Elf64_Shdr *reside_section = section_table + sym_table[i].st_shndx;
            assert(reside_section->sh_flags & SHF_EXECINSTR);

            ADDR funcVirStart = sym_table[i].st_value;
            ADDR funcMapStart = funcVirStart - reside_section->sh_addr + reside_section->sh_offset + (ADDR)mapStart;
            ADDR funcMapEnd = funcMapStart + sym_table[i].st_size;
            char *funcName = strtab + sym_table[i].st_name;
            //puts(strtab + sym_table[i].st_name);
            Function func(funcMapStart, funcMapEnd, funcVirStart, funcName);
            funcInfo.push_back(func);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3e0, %rsp            # imm = 0x3E0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x3a8(%rbp)
movq %rax, -0x3b0(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x3a0(%rbp)
leaq -0x11(%rbp), %rdi
movq %rdi, -0x398(%rbp)
callq 0x8330
movq -0x3a8(%rbp), %rdi
movq -0x3a0(%rbp), %rsi
movq -0x398(%rbp), %rdx
callq 0xd6e0
jmp 0xce7c
leaq -0x11(%rbp), %rdi
callq 0x8230
movq -0x3b0(%rbp), %rdi
movq $0x0, 0x28(%rdi)
addq $0x38, %rdi
movq %rdi, -0x3c8(%rbp)
callq 0xd790
movq 0x55125(%rip), %rax     # 0x61fd0
movq (%rax), %rdi
movq -0x10(%rbp), %rdx
leaq 0x44296(%rip), %rsi     # 0x5114f
xorl %eax, %eax
movl %eax, -0x3bc(%rbp)
movb %al, -0x3b5(%rbp)
callq 0x82a0
movl -0x3bc(%rbp), %esi
movb -0x3b5(%rbp), %al
movq -0x10(%rbp), %rdi
callq 0x8150
movl %eax, -0x3b4(%rbp)
jmp 0xcee9
movl -0x3b4(%rbp), %eax
movl %eax, -0x28(%rbp)
cmpl $-0x1, -0x28(%rbp)
je 0xcefa
jmp 0xcf44
leaq 0x44263(%rip), %rdi     # 0x51164
leaq 0x44263(%rip), %rsi     # 0x5116b
movl $0x13, %edx
leaq 0x44266(%rip), %rcx     # 0x5117a
callq 0x8120
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x11(%rbp), %rdi
callq 0x8230
jmp 0xd4a8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0xd490
movl -0x28(%rbp), %edi
leaq -0xb8(%rbp), %rsi
callq 0x8310
cmpl $0x0, %eax
jne 0xcf5a
jmp 0xcf79
leaq 0x44238(%rip), %rdi     # 0x51199
leaq 0x44203(%rip), %rsi     # 0x5116b
movl $0x16, %edx
leaq 0x44206(%rip), %rcx     # 0x5117a
callq 0x8120
movq -0x3b0(%rbp), %rax
movq -0x88(%rbp), %rcx
movq %rcx, 0x30(%rax)
movq 0x30(%rax), %rsi
movl -0x28(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x1, %edx
movl $0x2, %ecx
movq %r9, %rdi
callq 0x8340
movq %rax, %rcx
movq -0x3b0(%rbp), %rax
movq %rcx, 0x28(%rax)
movq $-0x1, %rcx
cmpq %rcx, 0x28(%rax)
jne 0xcfd8
leaq 0x441e4(%rip), %rdi     # 0x511b0
callq 0x8190
jmp 0xcfd3
callq 0x80f0
movq -0x3b0(%rbp), %rdi
movq 0x28(%rdi), %rsi
callq 0xd7b0
movb %al, -0x3c9(%rbp)
jmp 0xcff0
movb -0x3c9(%rbp), %al
testb $0x1, %al
jne 0xcffc
jmp 0xcffe
jmp 0xd01d
leaq 0x441b5(%rip), %rdi     # 0x511ba
leaq 0x4415f(%rip), %rsi     # 0x5116b
movl $0x1f, %edx
leaq 0x44162(%rip), %rcx     # 0x5117a
callq 0x8120
movq -0x3b0(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rax
movw 0x10(%rax), %ax
movw %ax, -0xc2(%rbp)
movzwl -0xc2(%rbp), %eax
cmpl $0x2, %eax
jne 0xd05a
movq -0x3b0(%rbp), %rax
movb $0x0, 0x50(%rax)
jmp 0xd0ab
movzwl -0xc2(%rbp), %eax
cmpl $0x3, %eax
jne 0xd073
movq -0x3b0(%rbp), %rax
movb $0x1, 0x50(%rax)
jmp 0xd0a9
movq 0x54f76(%rip), %rdi     # 0x61ff0
leaq 0x44149(%rip), %rsi     # 0x511ca
callq 0x81d0
movq %rax, -0x3d8(%rbp)
jmp 0xd08f
movq -0x3d8(%rbp), %rdi
movq 0x54f23(%rip), %rsi     # 0x61fc0
callq 0x8210
jmp 0xd0a4
callq 0x80f0
jmp 0xd0ab
movq -0x3b0(%rbp), %rax
movq -0xc0(%rbp), %rcx
movw 0x3c(%rcx), %cx
movw %cx, -0xc4(%rbp)
movq 0x28(%rax), %rcx
movq -0xc0(%rbp), %rdx
addq 0x28(%rdx), %rcx
movq %rcx, -0xd0(%rbp)
movq 0x28(%rax), %rax
movq -0xd0(%rbp), %rcx
movq -0xc0(%rbp), %rdx
movzwl 0x3e(%rdx), %edx
shlq $0x6, %rdx
addq %rdx, %rcx
addq 0x18(%rcx), %rax
movq %rax, -0xd8(%rbp)
movq $0x0, -0xe0(%rbp)
movl $0x0, -0xe4(%rbp)
movl -0xe4(%rbp), %eax
movzwl -0xc4(%rbp), %ecx
cmpl %ecx, %eax
jge 0xd19b
movq -0xd8(%rbp), %rdi
movq -0xd0(%rbp), %rax
movslq -0xe4(%rbp), %rcx
shlq $0x6, %rcx
addq %rcx, %rax
movl (%rax), %eax
addq %rax, %rdi
leaq 0x440b4(%rip), %rsi     # 0x51204
callq 0x8290
cmpl $0x0, %eax
jne 0xd185
movq -0x3b0(%rbp), %rax
movq 0x28(%rax), %rax
movq -0xd0(%rbp), %rcx
movslq -0xe4(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rcx
addq 0x18(%rcx), %rax
movq %rax, -0xe0(%rbp)
jmp 0xd187
movl -0xe4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe4(%rbp)
jmp 0xd117
movl $0x0, -0xe8(%rbp)
movl -0xe8(%rbp), %eax
movzwl -0xc4(%rbp), %ecx
cmpl %ecx, %eax
jge 0xd487
movq -0xd0(%rbp), %rax
movslq -0xe8(%rbp), %rcx
shlq $0x6, %rcx
addq %rcx, %rax
cmpl $0x2, 0x4(%rax)
je 0xd1da
jmp 0xd473
movq -0x3b0(%rbp), %rax
movq 0x28(%rax), %rax
movq -0xd0(%rbp), %rcx
movslq -0xe8(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rcx
addq 0x18(%rcx), %rax
movq %rax, -0xf0(%rbp)
movq -0xd0(%rbp), %rax
movslq -0xe8(%rbp), %rcx
shlq $0x6, %rcx
addq %rcx, %rax
movq 0x20(%rax), %rax
movq -0xd0(%rbp), %rcx
movslq -0xe8(%rbp), %rdx
shlq $0x6, %rdx
addq %rdx, %rcx
xorl %edx, %edx
divq 0x38(%rcx)
movq %rax, -0xf8(%rbp)
movl $0x0, -0xfc(%rbp)
movslq -0xfc(%rbp), %rax
cmpq -0xf8(%rbp), %rax
jae 0xd471
movq -0xf0(%rbp), %rax
movslq -0xfc(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movzbl 0x4(%rax), %eax
andl $0xf, %eax
cmpl $0x2, %eax
je 0xd284
jmp 0xd443
movq -0xf0(%rbp), %rax
movslq -0xfc(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movzwl 0x6(%rax), %eax
cmpl $0x0, %eax
je 0xd2ca
movq -0xf0(%rbp), %rax
movslq -0xfc(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movzwl 0x6(%rax), %eax
movq -0xc0(%rbp), %rcx
movzwl 0x3c(%rcx), %ecx
cmpl %ecx, %eax
jle 0xd2cf
jmp 0xd443
movq -0xf0(%rbp), %rax
movslq -0xfc(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
cmpq $0x0, 0x10(%rax)
jne 0xd2f0
jmp 0xd443
movq -0xd0(%rbp), %rax
movq -0xf0(%rbp), %rcx
movslq -0xfc(%rbp), %rdx
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movzwl 0x6(%rcx), %ecx
movslq %ecx, %rcx
shlq $0x6, %rcx
addq %rcx, %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rax
movq 0x8(%rax), %rax
andq $0x4, %rax
cmpq $0x0, %rax
je 0xd338
jmp 0xd357
leaq 0x43ecd(%rip), %rdi     # 0x5120c
leaq 0x43e25(%rip), %rsi     # 0x5116b
movl $0x44, %edx
leaq 0x43e28(%rip), %rcx     # 0x5117a
callq 0x8120
movq -0x3b0(%rbp), %rcx
movq -0xf0(%rbp), %rax
movslq -0xfc(%rbp), %rdx
leaq (%rdx,%rdx,2), %rdx
movq 0x8(%rax,%rdx,8), %rax
movq %rax, -0x110(%rbp)
movq -0x110(%rbp), %rax
movq -0x108(%rbp), %rdx
movq 0x10(%rdx), %rsi
movq 0x18(%rdx), %rdx
subq %rsi, %rax
addq %rdx, %rax
movq 0x28(%rcx), %rcx
addq %rcx, %rax
movq %rax, -0x118(%rbp)
movq -0x118(%rbp), %rax
movq -0xf0(%rbp), %rcx
movslq -0xfc(%rbp), %rdx
leaq (%rdx,%rdx,2), %rdx
movq 0x10(%rcx,%rdx,8), %rcx
addq %rcx, %rax
movq %rax, -0x120(%rbp)
movq -0xe0(%rbp), %rax
movq -0xf0(%rbp), %rcx
movslq -0xfc(%rbp), %rdx
leaq (%rdx,%rdx,2), %rdx
movl (%rcx,%rdx,8), %ecx
addq %rcx, %rax
movq %rax, -0x128(%rbp)
movq -0x118(%rbp), %rsi
movq -0x120(%rbp), %rdx
movq -0x110(%rbp), %rcx
movq -0x128(%rbp), %r8
leaq -0x390(%rbp), %rdi
callq 0xe7c0
jmp 0xd41e
movq -0x3b0(%rbp), %rdi
addq $0x38, %rdi
leaq -0x390(%rbp), %rsi
callq 0xd7e0
jmp 0xd437
leaq -0x390(%rbp), %rdi
callq 0xe910
movl -0xfc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xfc(%rbp)
jmp 0xd24a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x390(%rbp), %rdi
callq 0xe910
jmp 0xd490
jmp 0xd473
movl -0xe8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe8(%rbp)
jmp 0xd1a5
addq $0x3e0, %rsp            # imm = 0x3E0
popq %rbp
retq
movq -0x3c8(%rbp), %rdi
callq 0xd850
movq -0x3a8(%rbp), %rdi
callq 0x8110
movq -0x20(%rbp), %rdi
callq 0x8320
nopw %cs:(%rax,%rax)