diff --git a/.gitignore b/.gitignore index 9e35c3d..7c10034 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ # ft_nm +out.all ft_nm +a +b # libft inc/libft.h diff --git a/src/nm.c b/src/nm.c index fd85aef..f2d6dbf 100644 --- a/src/nm.c +++ b/src/nm.c @@ -4,10 +4,14 @@ 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) { +char *get_sym_char(Elf64_Sym sym, Elf64_Shdr sec, int *tool) { // if ((sec.sh_flags & SHF_COMPRESSED) == SHF_COMPRESSED) { // return ("N"); // } + *tool = 0; + if (ELF64_ST_TYPE(sym.st_info) == STT_SECTION) { + *tool = 1; + } if (sym.st_shndx == SHN_ABS) { if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL) { return ("a"); @@ -166,6 +170,7 @@ void put_entry(void *data) { int nm64(t_mapped_file mapped_file, char *path, t_verbosity verbosity, t_ordering ordering) { t_root *tree = NULL; t_entry *entry = (t_entry *)malloc(sizeof(t_entry)); + int tool; if (!entry) return FT_NM_FAILURE; Elf64_Ehdr header; @@ -213,17 +218,26 @@ int nm64(t_mapped_file mapped_file, char *path, t_verbosity verbosity, t_orderin // ici la str (le symbole) est bon, on la charge dans le truc, ensuite on genere la vrai string a afficher, avant de sort entry->symbol = ft_strdup(str); free(str); - char *sym_char = ft_strdup(get_sym_char(sym, sec)); - if (ft_strnstr(sec_str, ".debug", 6) && ft_strequ(sym_char, "n")) { + char *sym_char = ft_strdup(get_sym_char(sym, sec, &tool)); + //if (entry->symbol[0] == '.' || ft_strnstr(entry->symbol, "lpstub", 6)) { + + if (ft_strnstr(entry->symbol, ".debug", 6) && ft_strequ(sym_char, "n")) { free(sym_char); sym_char = ft_strdup("N"); } + if (sym_char[0] == 'N') { + ft_putstr(entry->symbol); + ft_putchar(*sym_char); + ft_putchar('\n'); + print_symbol(sym); + } + // ici le sym char a ete calculer, a partir de la on determine la verbosity // ici on fait if entry->verbosity >= verbosity, si c'est pas bon on skip toute la suite entry->verbosity = DEFAULT_VERBOSITY; - if (sym_char[0] == 'a') + if ((sym_char[0] == 'a' && sym.st_info == 4) || sym_char[0] == 'N' || tool == 1)// || entry->symbol[0] == '.') entry->verbosity = ALL; - if (sym_char[0] == 'u' || sym_char[0] == 'v' || sym_char[0] == 'w' || (sym_char[0] >= 'A' && sym_char[0] <= 'Z')) + if (sym_char[0] == 'u' || sym_char[0] == 'v' || sym_char[0] == 'w' || (sym_char[0] >= 'A' && sym_char[0] <= 'Z' && sym_char[0] != 'N')) entry->verbosity = GLOBAL; if (sym_char[0] == 'w' || sym_char[0] == 'U') entry->verbosity = UNDEFINED; @@ -240,7 +254,7 @@ int nm64(t_mapped_file mapped_file, char *path, t_verbosity verbosity, t_orderin entry->string[17] = sym_char[0]; entry->string[18] = ' '; ft_memcpy(entry->string + 19, entry->symbol, ft_strlen(entry->symbol)); - if (sym.st_value) { + if (sym.st_value && !ft_strstr(entry->symbol, "@@")) { for (char i = 15; i >= 0; i--) { entry->string[15 - i] = ft_get_hex_digit((sym.st_value >> i * 4) & 0xF); } @@ -285,9 +299,45 @@ int nm64(t_mapped_file mapped_file, char *path, t_verbosity verbosity, t_orderin return FT_NM_SUCCESS; } +void print_st_info(unsigned char st_info) { + unsigned char type = ELF64_ST_TYPE(st_info); + unsigned char bind = ELF64_ST_BIND(st_info); + if (type == STT_NOTYPE) { + ft_putstr("symbol has no type (STT_NOTYPE)\n"); + } else if (type == STT_OBJECT) { + ft_putstr("symbol has object type (STT_OBJECT)\n"); + } else if (type == STT_FUNC) { + ft_putstr("symbol has func type (STT_FUNC)\n"); + } else if (type == STT_SECTION) { + ft_putstr("symbol has section type (STT_SECTION)\n"); + } else if (type == STT_FILE) { + ft_putstr("symbol has file type (STT_FILE)\n"); + } else if (type >= STT_LOPROC && type <= STT_HIPROC) { + ft_putnbr(type); + ft_putstr(" reserved for processor-specific semantics (STT_LOPROC <= type <= STT_HIPROC)\n"); + } else { + ft_putstr("symbol TYPE unknown (warning: no matching STT_****)\n"); + } + + if (bind == STB_LOCAL) { + ft_putstr("symbol has local bind (STB_LOCAL)\n"); + } else if (bind == STB_GLOBAL) { + ft_putstr("symbol has global bind (STB_GLOBAL)\n"); + } else if (bind == STB_WEAK) { + ft_putstr("symbol has weak bind (STB_WEAK)\n"); + } else if (bind >= STB_LOPROC && bind <= STB_HIPROC) { + ft_putnbr(bind); + ft_putstr(" reserved for processor-specific semantics (STB_LOPROC <= bind <= STB_HIPROC)\n"); + } else { + ft_putstr("symbol BIND unknown (warning: no matching STB_****)\n"); + } +} + void print_symbol(Elf64_Sym sym) { printf("st_name: %d\n", sym.st_name); printf("st_info: %d\n", sym.st_info); + print_st_info(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); diff --git a/unit_test.sh b/unit_test.sh new file mode 100755 index 0000000..ba0e97f --- /dev/null +++ b/unit_test.sh @@ -0,0 +1,10 @@ +#!/bin/bash +for file in $1*/**/* +do + if [[ "$file" != *.a ]] ;then + echo $file + ./ft_nm $2 $file 2>&1 | cat > a + nm $2 $file 2>&1 | cat > b + diff a b + fi +done