#include "ft_re.h" void display_64_section_header(t_elf64 *nm, int i) { printf( " [Nr] Name Type Addr Off Size " " " "ES Flg Lk Inf Al\n"); printf(" [%2d] ", i); printf("%-18s", nm->string_table + nm->shdr[i].sh_name); printf("%-16s", get_section_type(nm->shdr[i].sh_type)); printf("%016lx ", nm->shdr[i].sh_addr); printf("%06lx ", nm->shdr[i].sh_offset); printf("%06lx ", nm->shdr[i].sh_size); printf("%02lx ", nm->shdr[i].sh_entsize); printf("%3s ", get_section_flags(nm->shdr[i].sh_flags)); printf("%02x ", nm->shdr[i].sh_link); printf("%02x ", nm->shdr[i].sh_info); printf("%02lx\n", nm->shdr[i].sh_addralign); } void display_64_header(t_elf64 *nm) { printf("ELF Header:\n"); printf(" Magic: "); for (int i = 0; i < EI_NIDENT; i++) printf("%02x ", nm->ehdr->e_ident[i]); printf("\n Class: ELF64\n"); printf( " Data: 2's complement, little endian\n"); printf(" Version: 1 (current)\n"); printf(" OS/ABI: UNIX - System V\n"); printf(" ABI Version: 0\n"); printf(" Version: 0x%016x\n", nm->ehdr->e_version); printf(" Entry point address: 0x%016lx\n", nm->ehdr->e_entry); printf(" Start of program headers: %ld (bytes into file)\n", nm->ehdr->e_phoff); printf(" Start of section headers: %ld (bytes into file)\n", nm->ehdr->e_shoff); printf(" Flags: 0x%016x\n", nm->ehdr->e_flags); printf(" Size of this header: %d (bytes)\n", nm->ehdr->e_ehsize); printf(" Size of program headers: %d (bytes)\n", nm->ehdr->e_phentsize); printf(" Number of program headers: %d\n", nm->ehdr->e_phnum); printf(" Size of section headers: %d (bytes)\n", nm->ehdr->e_shentsize); printf(" Number of section headers: %d\n", nm->ehdr->e_shnum); printf(" Section header string table index: %d\n", nm->ehdr->e_shstrndx); } int print_64_symtab(t_elf64 *nm) { int sym_num = nm->symtab_end - nm->symtab; printf("Symbol table '%s' contains %d entries:\n", nm->file, sym_num); printf("Contents of the (%s) section: \n", nm->string_table + nm->shdr[nm->ehdr->e_shstrndx].sh_name); printf( "| Num: |Value |Size |Type |Bind |Vis " " |Ndx0x |Ndx " " |shndxty |shndxfl|nmChar |Name\n"); for (int i = 0; i < sym_num; i++) { int id = nm->opts.p == 0 ? nm->ordered_sym_ids[i] : i; printf("| %4d: ", id); printf("|%16lx ", nm->symtab[id].st_value); printf("|%16lx ", nm->symtab[id].st_size); printf("|%-6s ", get_sym_type(ELF64_ST_TYPE(nm->symtab[id].st_info))); printf("|%-6s ", get_sym_bind(ELF64_ST_BIND(nm->symtab[id].st_info))); printf("|%-7s ", get_sym_vis(ELF64_ST_VISIBILITY(nm->symtab[id].st_other))); printf("|%5d", nm->symtab[id].st_shndx); printf("|%7s ", get_sym_shndx(nm->symtab[id].st_shndx)); if (nm->symtab[id].st_shndx < nm->ehdr->e_shnum) { printf("|%8s", get_sh_type(nm->shdr[nm->symtab[id].st_shndx].sh_type)); printf("|%8s", get_sh_flag(nm->shdr[nm->symtab[id].st_shndx].sh_flags)); } else { printf("|%8c", ' '); printf("|%8c", ' '); } printf("|%6c ", nm->sym_types[id]); printf("|%s\n", nm->sym_names[id]); } return 1; } int parse_64_symtab(t_elf64 *nm) { Elf64_Shdr *shdr = &nm->shdr[nm->ehdr->e_shstrndx]; nm->string_table = (char *)(nm->ptr + shdr->sh_offset); for (int i = 0; i < nm->ehdr->e_shnum; i++) { display_64_section_header(nm, i); if (nm->shdr[i].sh_type == SHT_SYMTAB || (nm->opts.D && nm->shdr[i].sh_type == SHT_DYNSYM)) { nm->symtab = (Elf64_Sym *)(nm->ptr + nm->shdr[i].sh_offset); nm->symtab_end = nm->symtab + (nm->shdr[i].sh_size / sizeof(Elf64_Sym)); int symbol_num = nm->shdr[i].sh_size / nm->shdr[i].sh_entsize; nm->linked_symnames = (char *)(nm->ptr + nm->shdr[nm->shdr[i].sh_link].sh_offset); nm->sym_names = malloc(sizeof(char *) * symbol_num); nm->ordered_sym_ids = malloc(sizeof(int) * symbol_num); nm->sym_types = malloc(sizeof(char) * symbol_num); for (int j = 0; j < symbol_num; j++) { nm->ordered_sym_ids[j] = j; if (ELF64_ST_TYPE(nm->symtab[j].st_info) == STT_SECTION ) nm->sym_names[j] = nm->string_table + nm->shdr[nm->symtab[j].st_shndx].sh_name; else nm->sym_names[j] = nm->linked_symnames + nm->symtab[j].st_name; } print_64_symtab(nm); free(nm->sym_names); free(nm->sym_types); free(nm->ordered_sym_ids); } nm->symtab = NULL; nm->symtab_end = NULL; nm->sym_names = NULL; nm->ordered_sym_ids = NULL; } return (0); } int ft_re64(char *filename, int filesize, char *file, t_opts opts) { t_elf64 nm; nm.file = filename; nm.size = filesize; nm.ptr = file; nm.opts = opts; nm.ehdr = (Elf64_Ehdr *)nm.ptr; nm.shdr = (Elf64_Shdr *)(nm.ptr + nm.ehdr->e_shoff); nm.name = malloc(nm.ehdr->e_shnum * sizeof(char *)); // check if file is complete if (nm.ehdr->e_shoff + nm.ehdr->e_shnum * nm.ehdr->e_shentsize > nm.size) { fprintf(stderr, "bfd plugin: %s: file too short\n", nm.file); return -1; } for (int i = 0; i < nm.ehdr->e_shnum; i++) nm.name[i] = &nm.string_table[nm.shdr[i].sh_name]; display_64_header(&nm); parse_64_symtab(&nm); return 0; }