feat: multiple files managment
This commit is contained in:
		
							parent
							
								
									3ee3777174
								
							
						
					
					
						commit
						1a78d07f27
					
				
							
								
								
									
										4
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										4
									
								
								Makefile
								
								
								
								
							|  | @ -21,8 +21,8 @@ INC = $(addprefix $(INC_DIR), $(INC_FILES)) | ||||||
| OBJ = $(addprefix $(OBJ_DIR), $(OBJ_FILES)) | OBJ = $(addprefix $(OBJ_DIR), $(OBJ_FILES)) | ||||||
| 
 | 
 | ||||||
| CC = gcc | CC = gcc | ||||||
| 
 |   | ||||||
| CFLAGS = -Wall -Werror -Wextra | CFLAGS = -Wall -Werror -Wextra -g2 | ||||||
| 
 | 
 | ||||||
| LIB_NAME = libft | LIB_NAME = libft | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								inc/ft_nm.h
								
								
								
								
							
							
						
						
									
										22
									
								
								inc/ft_nm.h
								
								
								
								
							|  | @ -15,6 +15,28 @@ | ||||||
| # define FT_NM_SUCCESS 0 | # define FT_NM_SUCCESS 0 | ||||||
| # define FT_NM_FAILURE -1 | # define FT_NM_FAILURE -1 | ||||||
| 
 | 
 | ||||||
|  | typedef enum e_verbosity { | ||||||
|  | 	DEFAULT_VERBOSITY, | ||||||
|  | 	ALL, | ||||||
|  | 	GLOBAL, | ||||||
|  | 	UNDEFINED | ||||||
|  | } t_verbosity; | ||||||
|  | 
 | ||||||
|  | typedef enum e_ordering { | ||||||
|  | 	DEFAULT_ORDERING, | ||||||
|  | 	REVERSE, | ||||||
|  | 	NOSORT | ||||||
|  | } t_ordering; | ||||||
|  | 
 | ||||||
|  | typedef struct s_env { | ||||||
|  | 	char *bin_name; | ||||||
|  | 	t_verbosity verbosity; | ||||||
|  | 	t_ordering ordering; | ||||||
|  | 	t_list *list; | ||||||
|  | 	int list_len; | ||||||
|  | 	bool has_multiple_files; | ||||||
|  | } t_env; | ||||||
|  | 
 | ||||||
| typedef struct s_mapped_file { | typedef struct s_mapped_file { | ||||||
| 	void *ptr; | 	void *ptr; | ||||||
| 	off_t size; | 	off_t size; | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								libft
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								libft
								
								
								
								
							|  | @ -1 +1 @@ | ||||||
| Subproject commit 1ab0cdf1acf97db0cb8d90940c96a6f1ccb3a7af | Subproject commit a9a3c473d5898d1eacfe2c036266fe0f810b0b53 | ||||||
|  | @ -48,6 +48,9 @@ void ft_printf(const char *format, ...) { | ||||||
| 			case 'P': | 			case 'P': | ||||||
| 				ft_putstr("                "); | 				ft_putstr("                "); | ||||||
| 				break; | 				break; | ||||||
|  | 			default: | ||||||
|  | 				ft_putchar(format[i]); | ||||||
|  | 				break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	va_end(ap); | 	va_end(ap); | ||||||
|  |  | ||||||
							
								
								
									
										131
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										131
									
								
								src/main.c
								
								
								
								
							|  | @ -1,62 +1,147 @@ | ||||||
| #include "ft_nm.h" | #include "ft_nm.h" | ||||||
| 
 | 
 | ||||||
| int main(int ac, char **av) { | void help(char *bin_name) { | ||||||
| 	char *path = ft_strdup("a.out"); | 	ft_printf("sss", "Usage: ", bin_name, " [option(s)] [file(s)]\n"); | ||||||
|  | 	ft_putstr( | ||||||
|  | 			" List symbols in [file(s)] (a.out by default).\n" | ||||||
|  | 			" The options are:\n" | ||||||
|  | 			"  -a Display debugger-only symbols\n" | ||||||
|  | 			"  -g Display only external symbols\n" | ||||||
|  | 			"  -p Do not sort the symbols\n" | ||||||
|  | 			"  -r Reverse the sense of the sort\n" | ||||||
|  | 			"  -u Display only undefined symbols\n" | ||||||
|  | 			"  -h Display this information\n"); | ||||||
|  | 	ft_printf("ss", bin_name, ": supported targets: elf64-x86-64 elf32-x86-64\n"); | ||||||
|  | 	ft_putstr("Report bugs to gaetanbrochard@protonmail.com\n"); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	if (ac > 1) { | int parse_options(char *options, t_env *env, bool *use_options) { | ||||||
| 		free(path); | 	int len = ft_strlen(options); | ||||||
| 		path = ft_strdup(av[1]); | 	if (len == 2 && options[1] == '-') { | ||||||
|  | 		*use_options = false; | ||||||
|  | 		return 0; | ||||||
| 	} | 	} | ||||||
|  | 	for (int i = 1; i < len; i++) { | ||||||
|  | 		switch (options[i]) { | ||||||
|  | 			case 'h': | ||||||
|  | 				help(env->bin_name); | ||||||
|  | 				return -2; | ||||||
|  | 				break; | ||||||
|  | 			case 'a': | ||||||
|  | 				if (env->verbosity < ALL) | ||||||
|  | 					env->verbosity = ALL; | ||||||
|  | 				break; | ||||||
|  | 			case 'g': | ||||||
|  | 				if (env->verbosity < GLOBAL) | ||||||
|  | 					env->verbosity = GLOBAL; | ||||||
|  | 				break; | ||||||
|  | 			case 'u': | ||||||
|  | 				if (env->verbosity < UNDEFINED) | ||||||
|  | 					env->verbosity = UNDEFINED; | ||||||
|  | 				break; | ||||||
|  | 			case 'r': | ||||||
|  | 				if (env->ordering < REVERSE) | ||||||
|  | 					env->ordering = REVERSE; | ||||||
|  | 				break; | ||||||
|  | 			case 'p': | ||||||
|  | 				if (env->ordering < NOSORT) | ||||||
|  | 					env->ordering = NOSORT; | ||||||
|  | 				break; | ||||||
|  | 			default: | ||||||
|  | 				return -1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | int parse_arguments(int ac, char **av, t_env *env) { | ||||||
|  | 	bool use_options = true; | ||||||
|  | 	if (ac > 0) { | ||||||
|  | 		env->bin_name = ft_strdup(av[0]); | ||||||
|  | 	} | ||||||
|  | 	for (int i = 1; i < ac; i++) { | ||||||
|  | 		if (ft_strlen(av[i]) > 0 && av[i][0] == '-' && use_options) { | ||||||
|  | 			int ret = parse_options(av[i], env, &use_options); | ||||||
|  | 			if (ret != 0) | ||||||
|  | 				return ret; | ||||||
|  | 		} else { | ||||||
|  | 			if (env->list_len == 0) { | ||||||
|  | 				env->list = ft_lstnew(av[i], ft_strlen(av[i]) + 1); | ||||||
|  | 			} else { | ||||||
|  | 				ft_lstadd_back(&env->list, ft_lstnew(av[i], ft_strlen(av[i]) + 1)); | ||||||
|  | 			} | ||||||
|  | 			env->list_len++; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int nm(char *path) { | ||||||
| 	int fd = open(path, O_RDONLY); | 	int fd = open(path, O_RDONLY); | ||||||
| 	if (fd == -1) { | 	if (fd == -1) { | ||||||
| 		ft_nm_error(path); | 		ft_nm_error(path); | ||||||
| 		free(path); |  | ||||||
| 		exit (EXIT_FAILURE); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	struct stat stat; | 	struct stat stat; | ||||||
| 	if (fstat(fd, &stat) == -1) { | 	if (fstat(fd, &stat) == -1) { | ||||||
| 		ft_nm_error(path); | 		ft_nm_error(path); | ||||||
| 		free(path); |  | ||||||
| 		exit (EXIT_FAILURE); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	t_mapped_file mapped_file; | 	t_mapped_file mapped_file; | ||||||
| 
 | 
 | ||||||
| //	ft_printf("sds", "file size: ", stat.st_size, "\n");
 |  | ||||||
| 	mapped_file.ptr = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | 	mapped_file.ptr = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | ||||||
| 	mapped_file.size = stat.st_size; | 	mapped_file.size = stat.st_size; | ||||||
| 	if (mapped_file.ptr != MAP_FAILED) { | 	if (mapped_file.ptr != MAP_FAILED) { | ||||||
| 		void *ident_ptr = fetch(mapped_file, 0, EI_NIDENT); | 		void *ident_ptr = fetch(mapped_file, 0, EI_NIDENT); | ||||||
| 		unsigned char ident[EI_NIDENT]; | 		unsigned char ident[EI_NIDENT]; | ||||||
| 		if (!ident_ptr) { | 		if (!ident_ptr) { | ||||||
| 			ft_printf("sss", "ft_nm: ", path, ": file format not recognized\n"); | 			ft_printf("sss", "nm: ", path, ": file format not recognized\n"); | ||||||
| 			free(path); | 			return 0; | ||||||
| 			exit(EXIT_FAILURE); | 
 | ||||||
| 		} | 		} | ||||||
| 		ft_memcpy(ident, ident_ptr, EI_NIDENT); | 		ft_memcpy(ident, ident_ptr, EI_NIDENT); | ||||||
| 		if (check_ident(ident) == FT_NM_FAILURE) { | 		if (check_ident(ident) == FT_NM_FAILURE) { | ||||||
| 			ft_printf("sss", "ft_nm: ", path, ": file format not recognized\n"); | 			ft_printf("sss", "nm: ", path, ": file format not recognized\n"); | ||||||
| 			free(path); | 			return 0; | ||||||
| 			exit(EXIT_FAILURE); |  | ||||||
| 		} | 		} | ||||||
| 		if (ident[EI_CLASS] == ELFCLASS32) { | 		if (ident[EI_CLASS] == ELFCLASS32) { | ||||||
| 			if (nm32(mapped_file) == FT_NM_FAILURE) { | 			if (nm32(mapped_file) == FT_NM_FAILURE) { | ||||||
| 				ft_printf("sss", "ft_nm: ", path, ": file format not recognized\n"); | 				ft_printf("sss", "nm: ", path, ": file format not recognized\n"); | ||||||
| 				free(path); | 				return 0; | ||||||
| 				exit(EXIT_FAILURE); |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else if (ident[EI_CLASS] == ELFCLASS64) { | 		else if (ident[EI_CLASS] == ELFCLASS64) { | ||||||
| 			if (nm64(mapped_file) == FT_NM_FAILURE) { | 			if (nm64(mapped_file) == FT_NM_FAILURE) { | ||||||
| 				ft_printf("sss", "ft_nm: ", path, ": file format not recognized\n"); | 				ft_printf("sss", "nm: ", path, ": file format not recognized\n"); | ||||||
| 				free(path); | 				return 0; | ||||||
| 				exit(EXIT_FAILURE); |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	free(path); |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int main(int ac, char **av) { | ||||||
|  | 	t_env env; | ||||||
|  | 	env.verbosity = DEFAULT_VERBOSITY; | ||||||
|  | 	env.ordering = DEFAULT_ORDERING; | ||||||
|  | 	env.list_len = 0; | ||||||
|  | 	env.list = NULL; | ||||||
|  | 	int error = parse_arguments(ac, av, &env); | ||||||
|  | 	if (env.list_len == 0) { | ||||||
|  | 		env.list = ft_lstnew(ft_strdup("a.out"), 6); | ||||||
|  | 		env.list_len = 1; | ||||||
|  | 	} | ||||||
|  | 	if (error) { | ||||||
|  | 		return error; | ||||||
|  | 	} | ||||||
|  | 	if (env.list_len == 1) { | ||||||
|  | 		nm(env.list->content); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 	while (env.list) { | ||||||
|  | 		ft_printf("\ns:\n", env.list->content); | ||||||
|  | 		nm(env.list->content); | ||||||
|  | 		env.list = env.list->next; | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										50
									
								
								src/nm.c
								
								
								
								
							
							
						
						
									
										50
									
								
								src/nm.c
								
								
								
								
							|  | @ -5,7 +5,7 @@ void print_section(Elf64_Shdr sec); | ||||||
| void print_symbol(Elf64_Sym sym); | 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) { | ||||||
| 	//	ppp(sym, sec);
 | 		//ppp(sym, sec);
 | ||||||
| 	//	if ((sec.sh_flags & SHF_COMPRESSED) == SHF_COMPRESSED) {
 | 	//	if ((sec.sh_flags & SHF_COMPRESSED) == SHF_COMPRESSED) {
 | ||||||
| 	//		return ("N");
 | 	//		return ("N");
 | ||||||
| 	//	}
 | 	//	}
 | ||||||
|  | @ -137,8 +137,6 @@ char *get_sym_char(Elf64_Sym sym, Elf64_Shdr sec) { | ||||||
| 			return ("W"); | 			return ("W"); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// if section name starts with .debug....
 |  | ||||||
| 	// return ("N");
 |  | ||||||
| 	return ("n"); | 	return ("n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -147,41 +145,9 @@ int nm64(t_mapped_file mapped_file) { | ||||||
| 	if (get_header64(mapped_file, &header) == FT_NM_FAILURE) { | 	if (get_header64(mapped_file, &header) == FT_NM_FAILURE) { | ||||||
| 		return FT_NM_FAILURE; | 		return FT_NM_FAILURE; | ||||||
| 	} | 	} | ||||||
| 	/*	printf("Header:\n");
 |  | ||||||
| 		printf("Version: %d\n", header.e_version); |  | ||||||
| 		printf("Entry point: %ld\n", header.e_entry); |  | ||||||
| 		printf("Program header offset: "); |  | ||||||
| 		fflush(stdout); |  | ||||||
| 		ft_printf("X", header.e_phoff); |  | ||||||
| 		ft_putchar('\n'); |  | ||||||
| 		printf("Section header offset: "); |  | ||||||
| 		fflush(stdout); |  | ||||||
| 		ft_printf("X", header.e_shoff); |  | ||||||
| 		ft_putchar('\n'); |  | ||||||
| 		printf("Header size: %d\n", header.e_ehsize); |  | ||||||
| 		printf("Program header entry size: %d\n", header.e_phentsize); |  | ||||||
| 		printf("Program header num: %d\n", header.e_phnum); |  | ||||||
| 		printf("Section header entry size: %d\n", header.e_shentsize); |  | ||||||
| 		printf("Section header num: %d\n", header.e_shnum); |  | ||||||
| 		printf("Section header string table index: %d\n", header.e_shstrndx); |  | ||||||
| 		*/ |  | ||||||
| 	/*
 |  | ||||||
| 	   for (int i = 0; i < header.e_phnum; i++) { |  | ||||||
| 	   uint64_t addr = header.e_phoff + header.e_phentsize * i; |  | ||||||
| 	   Elf64_Phdr phstr; |  | ||||||
| 	   ft_memcpy(&phstr, mapped_file.ptr + addr, header.e_phentsize); |  | ||||||
| 	   ft_printf("X", phstr.p_offset); |  | ||||||
| 	   ft_putchar('\n'); |  | ||||||
| 	   char *str = ft_strdup(mapped_file.ptr + phstr.p_offset + 1); |  | ||||||
| 	   ft_putstr(str); |  | ||||||
| 	   ft_putchar('\n'); |  | ||||||
| 	   } |  | ||||||
| 	   */ |  | ||||||
| 	uint64_t addr = header.e_shoff + header.e_shentsize * header.e_shstrndx; | 	uint64_t addr = header.e_shoff + header.e_shentsize * header.e_shstrndx; | ||||||
| 	//ft_printf("sX", "addr: ", addr);
 |  | ||||||
| 	Elf64_Shdr shstrtb; | 	Elf64_Shdr shstrtb; | ||||||
| 	ft_memcpy(&shstrtb, mapped_file.ptr + addr, header.e_shentsize); | 	ft_memcpy(&shstrtb, mapped_file.ptr + addr, header.e_shentsize); | ||||||
| 	//ft_printf("sX", "offset: ", shstrtb.sh_offset);
 |  | ||||||
| 	for (int i = 0; i < header.e_shnum; i++) { | 	for (int i = 0; i < header.e_shnum; i++) { | ||||||
| 		uint64_t addr = header.e_shoff + header.e_shentsize * i; | 		uint64_t addr = header.e_shoff + header.e_shentsize * i; | ||||||
| 		Elf64_Shdr sh; | 		Elf64_Shdr sh; | ||||||
|  | @ -190,12 +156,10 @@ int nm64(t_mapped_file mapped_file) { | ||||||
| 			uint64_t addr2 = header.e_shoff + header.e_shentsize * sh.sh_link; | 			uint64_t addr2 = header.e_shoff + header.e_shentsize * sh.sh_link; | ||||||
| 			Elf64_Shdr strtab; | 			Elf64_Shdr strtab; | ||||||
| 			ft_memcpy(&strtab, mapped_file.ptr + addr2, header.e_shentsize); | 			ft_memcpy(&strtab, mapped_file.ptr + addr2, header.e_shentsize); | ||||||
| 			//			ft_printf("sdsds", "SYMTAB Size: ", sh.sh_size, " Entity size: ", sh.sh_entsize, "\n");
 |  | ||||||
| 			for (uint64_t j = sh.sh_entsize; j < sh.sh_size; j += sh.sh_entsize) { | 			for (uint64_t j = sh.sh_entsize; j < sh.sh_size; j += sh.sh_entsize) { | ||||||
| 				Elf64_Sym sym; | 				Elf64_Sym sym; | ||||||
| 				Elf64_Shdr sec; | 				Elf64_Shdr sec; | ||||||
| 				ft_memcpy(&sym, mapped_file.ptr + sh.sh_offset + j, sh.sh_entsize); | 				ft_memcpy(&sym, mapped_file.ptr + sh.sh_offset + j, sh.sh_entsize); | ||||||
| 				//				printf("st_shndx: %d\n", sym.st_shndx);
 |  | ||||||
| 				if (sym.st_shndx < header.e_shnum) { | 				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); | 					ft_memcpy(&sec, mapped_file.ptr + header.e_shoff + header.e_shentsize * sym.st_shndx, header.e_shentsize); | ||||||
| 				} | 				} | ||||||
|  | @ -214,10 +178,6 @@ int nm64(t_mapped_file mapped_file) { | ||||||
| 				else { | 				else { | ||||||
| 					str = sec_str; | 					str = sec_str; | ||||||
| 				} | 				} | ||||||
| 				//if (str[ft_strlen(str) - 1] == 'c') {
 |  | ||||||
| 				/*
 |  | ||||||
| 				*/ |  | ||||||
| 				//}
 |  | ||||||
| 				char *sym_char = ft_strdup(get_sym_char(sym, sec)); | 				char *sym_char = ft_strdup(get_sym_char(sym, sec)); | ||||||
| 				if (ft_strnstr(sec_str, ".debug", 6) && ft_strequ(sym_char, "n")) { | 				if (ft_strnstr(sec_str, ".debug", 6) && ft_strequ(sym_char, "n")) { | ||||||
| 					free(sym_char); | 					free(sym_char); | ||||||
|  | @ -229,22 +189,14 @@ int nm64(t_mapped_file mapped_file) { | ||||||
| 					if (ft_strcmp(sym_char, "U") && ft_strcmp(sym_char, "w") && ft_strcmp(sym_char, "v")) { | 					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"); | 						ft_printf("X s ss", sym.st_value, sym_char, str, "\n"); | ||||||
| 					} else { | 					} else { | ||||||
| 						//ft_printf("P s ss", sym_char, mapped_file.ptr + strtab.sh_offset + sym.st_name, "\n");
 |  | ||||||
| 						ft_printf("P s ss", sym_char, str, "\n"); | 						ft_printf("P s ss", sym_char, str, "\n"); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				fflush(stdout); | 				fflush(stdout); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		/*ft_printf("X", sh.sh_offset);
 |  | ||||||
| 		  ft_putchar('\n'); |  | ||||||
| 		  ft_printf("X", sh.sh_name); |  | ||||||
| 		  ft_putchar('\n');*/ |  | ||||||
| 		char *str = ft_strdup(mapped_file.ptr + shstrtb.sh_offset + sh.sh_name); | 		char *str = ft_strdup(mapped_file.ptr + shstrtb.sh_offset + sh.sh_name); | ||||||
| 		//ft_putstr(str);
 |  | ||||||
| 		//		ft_printf("x x x ss", sh.sh_name, sh.sh_offset, addr, str, "\n");
 |  | ||||||
| 		free(str); | 		free(str); | ||||||
| 		//ft_putchar('\n');
 |  | ||||||
| 	} | 	} | ||||||
| 	return FT_NM_SUCCESS; | 	return FT_NM_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue