You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
6.1 KiB
148 lines
6.1 KiB
#include "ft_re.h"
|
|
|
|
void display_64_section_header(t_elf64 *nm, int i) {
|
|
ft_printf(
|
|
" [Nr] Name Type Addr Off Size "
|
|
" "
|
|
"ES Flg Lk Inf Al\n");
|
|
ft_printf(" [%2d] ", i);
|
|
ft_printf("%-18s", nm->string_table + nm->shdr[i].sh_name);
|
|
ft_printf("%-16s", get_section_type(nm->shdr[i].sh_type));
|
|
ft_printf("%016lx ", nm->shdr[i].sh_addr);
|
|
ft_printf("%06lx ", nm->shdr[i].sh_offset);
|
|
ft_printf("%06lx ", nm->shdr[i].sh_size);
|
|
ft_printf("%02lx ", nm->shdr[i].sh_entsize);
|
|
ft_printf("%3s ", get_section_flags(nm->shdr[i].sh_flags));
|
|
ft_printf("%02x ", nm->shdr[i].sh_link);
|
|
ft_printf("%02x ", nm->shdr[i].sh_info);
|
|
ft_printf("%02lx\n", nm->shdr[i].sh_addralign);
|
|
}
|
|
|
|
void display_64_header(t_elf64 *nm) {
|
|
ft_printf("ELF Header:\n");
|
|
ft_printf(" Magic: ");
|
|
for (int i = 0; i < EI_NIDENT; i++)ft_printf("%02x ", nm->ehdr->e_ident[i]);
|
|
ft_printf("\n Class: ELF64\n");
|
|
ft_printf(
|
|
" Data: 2's complement, little endian\n");
|
|
ft_printf(" Version: 1 (current)\n");
|
|
ft_printf(" OS/ABI: UNIX - System V\n");
|
|
ft_printf(" ABI Version: 0\n");
|
|
ft_printf(" Version: 0x%016x\n",
|
|
nm->ehdr->e_version);
|
|
ft_printf(" Entry point address: 0x%016lx\n",
|
|
nm->ehdr->e_entry);
|
|
ft_printf(" Start of program headers: %ld (bytes into file)\n",
|
|
nm->ehdr->e_phoff);
|
|
ft_printf(" Start of section headers: %ld (bytes into file)\n",
|
|
nm->ehdr->e_shoff);
|
|
ft_printf(" Flags: 0x%016x\n", nm->ehdr->e_flags);
|
|
ft_printf(" Size of this header: %d (bytes)\n",
|
|
nm->ehdr->e_ehsize);
|
|
ft_printf(" Size of program headers: %d (bytes)\n",
|
|
nm->ehdr->e_phentsize);
|
|
ft_printf(" Number of program headers: %d\n", nm->ehdr->e_phnum);
|
|
ft_printf(" Size of section headers: %d (bytes)\n",
|
|
nm->ehdr->e_shentsize);
|
|
ft_printf(" Number of section headers: %d\n", nm->ehdr->e_shnum);
|
|
ft_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;
|
|
|
|
ft_printf("Symbol table '%s' contains %d entries:\n", nm->file, sym_num);
|
|
ft_printf("Contents of the (%s) section: \n",
|
|
nm->string_table + nm->shdr[nm->ehdr->e_shstrndx].sh_name);
|
|
ft_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;
|
|
ft_printf("| %4d: ", id);
|
|
ft_printf("|%16lx ", nm->symtab[id].st_value);
|
|
ft_printf("|%16lx ", nm->symtab[id].st_size);
|
|
ft_printf("|%-6s ", get_sym_type(ELF64_ST_TYPE(nm->symtab[id].st_info)));
|
|
ft_printf("|%-6s ", get_sym_bind(ELF64_ST_BIND(nm->symtab[id].st_info)));
|
|
ft_printf("|%-7s ",
|
|
get_sym_vis(ELF64_ST_VISIBILITY(nm->symtab[id].st_other)));
|
|
ft_printf("|%5d", nm->symtab[id].st_shndx);
|
|
ft_printf("|%7s ", get_sym_shndx(nm->symtab[id].st_shndx));
|
|
if (nm->symtab[id].st_shndx < nm->ehdr->e_shnum) {
|
|
ft_printf("|%8s",
|
|
get_sh_type(nm->shdr[nm->symtab[id].st_shndx].sh_type));
|
|
ft_printf("|%8s",
|
|
get_sh_flag(nm->shdr[nm->symtab[id].st_shndx].sh_flags));
|
|
} else {
|
|
ft_printf("|%8c", ' ');
|
|
ft_printf("|%8c", ' ');
|
|
}
|
|
ft_printf("|%6c ", nm->sym_types[id]);
|
|
ft_printf("|%s\n", nm->sym_names[id]);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
nt 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) {
|
|
ft_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;
|
|
}
|
|
|