#include "ft_nm.h" void ppp(Elf64_Sym sym, Elf64_Shdr sec); void print_section(Elf64_Shdr sec); void print_symbol(Elf64_Sym sym); char *get_sym_char(Elf64_Sym sym, Elf64_Shdr sec) { //ppp(sym, sec); // if ((sec.sh_flags & SHF_COMPRESSED) == SHF_COMPRESSED) { // return ("N"); // } if (sym.st_shndx == SHN_ABS) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("a"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("A"); } } if (ELF64_ST_BIND(sym.st_info) == STB_GNU_UNIQUE) { return ("u"); } if (ELF64_ST_TYPE(sym.st_info) == STT_GNU_IFUNC) { return ("i"); } if (sec.sh_flags & SHF_EXECINSTR) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("t"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("T"); } } if (sec.sh_type == SHT_NOBITS) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("b"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("B"); } } if (sec.sh_type == SHT_PROGBITS && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("d"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("D"); } } if (sec.sh_type == SHT_DYNAMIC && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("d"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("D"); } } if (sec.sh_type == SHT_INIT_ARRAY && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("d"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("D"); } } if (sec.sh_type == SHT_PREINIT_ARRAY && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("d"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("D"); } } if (sec.sh_type == SHT_FINI_ARRAY && (sec.sh_flags & (SHF_ALLOC | SHF_WRITE)) == (SHF_ALLOC | SHF_WRITE)) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("d"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("D"); } } if (/*sec.sh_type == SHT_PROGBITS &&*/ sec.sh_flags & SHF_ALLOC) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("r"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("R"); } } if (sec.sh_type == SHT_NOTE && sec.sh_flags == SHF_ALLOC) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("r"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("R"); } } if (sym.st_shndx == SHN_COMMON) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("c"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("C"); } } if (sym.st_shndx == SHN_UNDEF) { //return ("U"); if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("u"); } else if (ELF64_ST_BIND(sym.st_info) == STB_GLOBAL) { return ("U"); } } if (ELF64_ST_BIND(sym.st_info) == STB_WEAK) { if (ELF64_ST_TYPE(sym.st_info) == STT_OBJECT) { if (sec.sh_type == SHT_NULL) { return ("v"); } else { return ("V"); } } else { if (sec.sh_type == SHT_NULL) { return ("w"); } else { return ("W"); } } } if (ELF64_ST_BIND(sym.st_info) == STB_WEAK) { if (sec.sh_type == SHT_NULL) { return ("w"); } else { return ("W"); } } return ("n"); } int nm64(t_mapped_file mapped_file) { Elf64_Ehdr header; if (get_header64(mapped_file, &header) == FT_NM_FAILURE) { return FT_NM_FAILURE; } uint64_t addr = header.e_shoff + header.e_shentsize * header.e_shstrndx; Elf64_Shdr shstrtb; ft_memcpy(&shstrtb, mapped_file.ptr + addr, header.e_shentsize); for (int i = 0; i < header.e_shnum; i++) { uint64_t addr = header.e_shoff + header.e_shentsize * i; Elf64_Shdr sh; ft_memcpy(&sh, mapped_file.ptr + addr, header.e_shentsize); if (sh.sh_type == SHT_SYMTAB) { uint64_t addr2 = header.e_shoff + header.e_shentsize * sh.sh_link; Elf64_Shdr strtab; ft_memcpy(&strtab, mapped_file.ptr + addr2, header.e_shentsize); for (uint64_t j = sh.sh_entsize; j < sh.sh_size; j += sh.sh_entsize) { Elf64_Sym sym; Elf64_Shdr sec; ft_memcpy(&sym, mapped_file.ptr + sh.sh_offset + j, sh.sh_entsize); if (sym.st_shndx < header.e_shnum) { ft_memcpy(&sec, mapped_file.ptr + header.e_shoff + header.e_shentsize * sym.st_shndx, header.e_shentsize); } char *str; char *sec_str; Elf64_Shdr shdr; if (sym.st_shndx != SHN_ABS) { ft_memcpy(&shdr, mapped_file.ptr + header.e_shoff + header.e_shentsize * sym.st_shndx, header.e_shentsize); sec_str = ft_strdup(mapped_file.ptr + shstrtb.sh_offset + shdr.sh_name); } else { sec_str = ft_strdup(""); } if (sym.st_name) { str = ft_strdup(mapped_file.ptr + strtab.sh_offset + sym.st_name); } else { str = sec_str; } char *sym_char = ft_strdup(get_sym_char(sym, sec)); if (ft_strnstr(sec_str, ".debug", 6) && ft_strequ(sym_char, "n")) { free(sym_char); sym_char = ft_strdup("N"); } if (sym.st_value) { ft_printf("X s ss", sym.st_value, sym_char, str, "\n"); } else { if (ft_strcmp(sym_char, "U") && ft_strcmp(sym_char, "w") && ft_strcmp(sym_char, "v")) { ft_printf("X s ss", sym.st_value, sym_char, str, "\n"); } else { ft_printf("P s ss", sym_char, str, "\n"); } } fflush(stdout); } } char *str = ft_strdup(mapped_file.ptr + shstrtb.sh_offset + sh.sh_name); free(str); } return FT_NM_SUCCESS; } void print_symbol(Elf64_Sym sym) { printf("st_name: %d\n", sym.st_name); printf("st_info: %d\n", sym.st_info); printf("st_other: %d\n", sym.st_other); printf("st_shndx: %d\n", sym.st_shndx); // printf("st_value: %ld\n", sym.st_value); // printf("st_size: %ld\n", sym.st_size); fflush(stdout); } void print_section(Elf64_Shdr sec) { printf("sh_name : %d\n", sec.sh_name); printf("sh_type : %d\n", sec.sh_type); printf("sh_flags : %ld\n", sec.sh_flags); // printf("sh_addr : %ld\n", sec.sh_addr); // printf("sh_offset : %ld\n", sec.sh_offset); // printf("sh_size : %ld\n", sec.sh_size); printf("sh_link : %d\n", sec.sh_link); printf("sh_info : %d\n", sec.sh_info); // printf("sh_addralign : %ld\n", sec.sh_addralign); // printf("sh_entsize : %ld\n", sec.sh_entsize); fflush(stdout); } int nm32(t_mapped_file mapped_file) { (void)mapped_file; return FT_NM_SUCCESS; } void ppp(Elf64_Sym sym, Elf64_Shdr sec) { print_symbol(sym); print_section(sec); }