238 lines
6.5 KiB
C
238 lines
6.5 KiB
C
#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);
|
|
}
|
|
|