diff --git a/nm-otool/Makefile b/nm-otool/Makefile index 76ed4024..560bd4a4 100644 --- a/nm-otool/Makefile +++ b/nm-otool/Makefile @@ -6,7 +6,7 @@ # By: jhalford +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2017/02/19 03:29:38 by jhalford #+# #+# # -# Updated: 2017/03/01 16:00:29 by jhalford ### ########.fr # +# Updated: 2017/03/23 17:04:19 by jhalford ### ########.fr # # # # **************************************************************************** # @@ -35,10 +35,12 @@ FT_NM_OBJ = $(OBJ_DIR)ft_nm.o FT_OTOOL_OBJ= $(OBJ_DIR)ft_otool.o SRC_BASE = \ -dump_symtab.c\ +fetch_header.c\ ft_nm.c\ ft_otool.c\ -hexdump.c +get_symbols.c\ +hexdump.c\ +symprint.c SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) @@ -51,6 +53,7 @@ OBJS := $(filter-out $(FT_OTOOL_OBJ), $(OBJS)) all: $(NAME) ft_nm: $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(FT_NM_OBJ) + @echo $(FT_NM_OBJ) @$(CC) $(FLAGS) $(D_FLAGS) \ -I $(INC_DIR) \ -I $(LIBFT_INC) \ @@ -72,7 +75,6 @@ ft_otool: $(LIBFT_LIB) $(OBJ_DIR) $(OBJS) $(FT_OTOOL_OBJ) @strip -x $@ @printf "\r\e[48;5;15;38;5;25m✅ MAKE $@\e[0m\e[K\n" - $(OBJ_DIR)%.o: $(SRC_DIR)%.c | $(OBJ_DIR) @$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB))))) @$(eval PERCENT=$(shell echo $$(($(INDEX)*100/$(NB))))) diff --git a/nm-otool/includes/ft_nm_otool.h b/nm-otool/includes/ft_nm_otool.h index 99a5ef20..885acdd7 100644 --- a/nm-otool/includes/ft_nm_otool.h +++ b/nm-otool/includes/ft_nm_otool.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/02/20 14:36:10 by jhalford #+# #+# */ -/* Updated: 2017/03/01 17:52:35 by jhalford ### ########.fr */ +/* Updated: 2017/03/23 17:04:06 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,10 +16,12 @@ # include "libft.h" # include # include + # include # include # include # include + # include # include # include @@ -27,7 +29,52 @@ # define IS_MAGIC_64(x) (x == MH_MAGIC_64 || x == MH_CIGAM_64) # define IS_FAT(x) (x == FAT_MAGIC || x == FAT_CIGAM) -void dump_symtab(struct symtab_command *sym, struct dysymtab_command *dysym, void *file); +typedef enum e_symtype t_symtype; +typedef struct s_symbol t_symbol; +typedef struct s_symbolmap t_symbolmap; +typedef struct s_machodata t_machodata; + +enum e_symtype +{ + SYM_UNDEF, + SYM_ABS, + SYM_TEXT, + SYM_DATA, + SYM_BSS, + SYM_COMMON, + SYM_DEBUG, + SYM_OTHER, + SYM_INDIRECT, +}; + + +struct s_machodata +{ + struct symtab_command *symtab; + struct dysymtab_command *dysymtab; +}; + +struct s_symbol +{ + t_symtype type; + long value; + char *name; +}; + +struct s_symbolmap +{ + char c; + int (*format)(); +}; + +extern t_symbolmap g_symbolmap[]; + +t_list *get_symbols(char *file); +int fetch_header(t_machodata *data, void *file); + +int symprint(t_symbol *symbol); +int symprint_text(t_symbol *symbol); + void *hexdump(void *addr, unsigned int offset, unsigned int size); #endif diff --git a/nm-otool/libft b/nm-otool/libft index 0ca8ca81..04b8d5cd 160000 --- a/nm-otool/libft +++ b/nm-otool/libft @@ -1 +1 @@ -Subproject commit 0ca8ca817f32fc0345ef93ef74a3abe2583bd89c +Subproject commit 04b8d5cd090e86b0f9d8160b01e49d43666deddf diff --git a/nm-otool/src/dump_symtab.c b/nm-otool/src/dump_symtab.c deleted file mode 100644 index 4e26ffa2..00000000 --- a/nm-otool/src/dump_symtab.c +++ /dev/null @@ -1,61 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* dump_symtab.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2017/02/20 13:20:22 by jhalford #+# #+# */ -/* Updated: 2017/03/01 17:55:11 by jhalford ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "ft_nm_otool.h" - -void dump_symtab(struct symtab_command *sym, struct dysymtab_command *dysym, void *file) -{ - int i; - int nsyms; - char *stringtable; - char *string; - struct nlist_64 *array; - struct dylib_reference *ref; - - nsyms = sym->nsyms; - array = file + sym->symoff; - stringtable = file + sym->stroff; - ft_printf("LC_SYMTAB [%d] symbols:\n", sym->nsyms); - i = 0; - while (++i < nsyms) - { - ft_printf("%s\n", stringtable + array[i].n_un.n_strx); - } - ft_putendl(""); - - ft_printf("ilocalsym %i\n", dysym->ilocalsym); - ft_printf("nlocalsym %i\n", dysym->nlocalsym); - - ft_printf("iextdefsym %i\n", dysym->iextdefsym); - ft_printf("nextdefsym %i\n", dysym->nextdefsym); - - ft_printf("iundefsym %i\n", dysym->iundefsym); - ft_printf("nundefsym %i\n", dysym->nundefsym); - - i = -1; - ft_printf("LC_DYSYMTAB ntoc=[%d]\n", dysym->ntoc); - ft_printf("LC_DYSYMTAB nmodtab=[%d]\n", dysym->nmodtab); - ft_printf("LC_DYSYMTAB nextrefsyms=[%d]\n", dysym->nextrefsyms); - ft_printf("LC_DYSYMTAB nmodtab=[%d]\n", dysym->nmodtab); - ft_printf("LC_DYSYMTAB nindirectsyms=[%d]\n", dysym->nindirectsyms); - ft_printf("LC_DYSYMTAB nextrel=[%d]\n", dysym->nextrel); - ft_printf("LC_DYSYMTAB nlocrel=[%d]\n", dysym->nlocrel); - ft_putendl(""); - ref = file + dysym->indirectsymoff; - while (++i < (int)dysym->nindirectsyms) - { - string = stringtable + array[ref->isym].n_un.n_strx; - ft_printf("%i: %s,%#x\n", ref->isym, string, ref->flags); - ref += 1; - } - (void)file; -} diff --git a/nm-otool/src/fetch_header.c b/nm-otool/src/fetch_header.c new file mode 100644 index 00000000..c2e2e1d5 --- /dev/null +++ b/nm-otool/src/fetch_header.c @@ -0,0 +1,68 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fetch_header.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/23 15:56:37 by jhalford #+# #+# */ +/* Updated: 2017/03/23 16:25:49 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_nm_otool.h" + +static void fetch_machheader64(t_machodata *data, void *file) +{ + uint32_t ncmds; + uint32_t i; + struct load_command *lc; + struct mach_header_64 *header = file; + + ncmds = header->ncmds; + lc = (void*)(header + 1); + /* ft_printf("{blu}{inv}mach_header_64 w/ [%d] load_commands{eoc}\n", ncmds); */ + for (i = 0; i < ncmds; i++) + { + /* ft_printf("{yel}{inv}load_command #%d: %#x{eoc}\n", i, lc->cmd); */ + if (lc->cmd == LC_SYMTAB) + data->symtab = (struct symtab_command*)lc; + else if (lc->cmd == LC_DYSYMTAB) + data->dysymtab = (struct dysymtab_command*)lc; + lc = (void*)lc + lc->cmdsize; + } +} + +static void fetch_fatheader(t_machodata *data, void *file) +{ + struct fat_header *header = file; + struct fat_arch *arch; + int i; + int nfat_arch; + + nfat_arch = header->nfat_arch; + arch = (void*)(header + 1); + ft_printf("{yel}{inv}FAT header w/ [%i] architures{eoc}\n", nfat_arch); + for (i = 0; i < nfat_arch; i++) + { + ft_printf("CPU type=[%i]", arch->cputype); + fetch_machheader64(data, file + arch->offset); + arch += 1; + } +} + +int fetch_header(t_machodata *data, void *file) +{ + uint32_t magic = *(int *)file; + int is_fat = IS_FAT(magic); + int is_64 = IS_MAGIC_64(magic); + + if (is_64) + fetch_machheader64(data, file); + if (is_fat) + fetch_fatheader(data, file); + else + ft_printf("{red}unsupported architecture:{eoc} magic = %#x\n", magic); + return (0); +} + diff --git a/nm-otool/src/ft_nm.c b/nm-otool/src/ft_nm.c index e68ba7a1..027c1970 100644 --- a/nm-otool/src/ft_nm.c +++ b/nm-otool/src/ft_nm.c @@ -6,15 +6,29 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/02/19 03:09:12 by jhalford #+# #+# */ -/* Updated: 2017/03/01 17:53:31 by jhalford ### ########.fr */ +/* Updated: 2017/03/23 17:04:13 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ #include "ft_nm_otool.h" +t_symbolmap g_symbolmap[] = +{ + {'U', NULL}, + {'A', NULL}, + {'T', symprint_text}, + {'D', NULL}, + {'B', NULL}, + {'C', NULL}, + {'-', NULL}, + {'S', NULL}, + {'I', NULL}, +}; + void dump_section_64(struct section_64 *sect) { - ft_printf("section64: segname=[%s], sectname=[%s]\n", sect->segname, sect->sectname); + ft_printf("section64: segname=[%s], sectname=[%s]\n", + sect->segname, sect->sectname); } void dump_segment_64(struct segment_command_64 *seg, void *file) @@ -34,66 +48,12 @@ void dump_segment_64(struct segment_command_64 *seg, void *file) } } -void print_output(int nsyms, int symoff, int stroff, void *ptr); - -void dump_mach_header_64(void *file) -{ - uint32_t ncmds; - uint32_t i; - struct load_command *lc; - struct symtab_command *symtab; - struct dysymtab_command *dysymtab; - struct mach_header_64 *header = file; - - ncmds = header->ncmds; - lc = (void*)(header + 1); - /* ft_printf("{blu}{inv}mach_header_64 w/ [%d] load_commands{eoc}\n", ncmds); */ - for (i = 0; i < ncmds; i++) - { - /* ft_printf("{yel}{inv}load_command #%d: %#x{eoc}\n", i, lc->cmd); */ - if (lc->cmd == LC_SYMTAB) - symtab = (struct symtab_command*)lc; - /* dump_symtab((struct symtab_command*)lc, file); */ - else if (lc->cmd == LC_DYSYMTAB) - dysymtab = (struct dysymtab_command*)lc; - /* dump_dysymtab((struct dysymtab_command*)lc, file); */ - /* else if (lc->cmd == LC_SEGMENT_64) */ - /* dump_segment_64((struct segment_command_64*)lc, file); */ - lc = (void*)lc + lc->cmdsize; - } - dump_symtab(symtab, dysymtab, file); -} - -void dump_fat_header(void *file) -{ - struct fat_header *header = file; - struct fat_arch *arch; - int i; - int nfat_arch; - - nfat_arch = header->nfat_arch; - arch = (void*)(header + 1); - ft_printf("{yel}{inv}FAT header w/ [%i] architures{eoc}\n", nfat_arch); - for (i = 0; i < nfat_arch; i++) - { - ft_printf("CPU type=[%i]", arch->cputype); - dump_mach_header_64(file + arch->offset); - arch += 1; - } -} - void nm(void *file) { - uint32_t magic = *(int *)file; - int is_fat = IS_FAT(magic); - int is_64 = IS_MAGIC_64(magic); + t_list *symbols; - if (is_fat) - dump_fat_header(file); - else if (is_64) - dump_mach_header_64(file); - else - ft_printf("{red}unsupported architecture:{eoc} magic = %#x\n", magic); + symbols = get_symbols(file); + ft_lstiter(symbols, symprint); } int main(int ac, char **av) @@ -101,7 +61,6 @@ int main(int ac, char **av) int fd; char *file; struct stat buf; - if (ac != 2) { ft_dprintf(2, "Please give me an arg\n"); diff --git a/nm-otool/src/get_symbols.c b/nm-otool/src/get_symbols.c new file mode 100644 index 00000000..e6f1d862 --- /dev/null +++ b/nm-otool/src/get_symbols.c @@ -0,0 +1,81 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* dump_symtab.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/20 13:20:22 by jhalford #+# #+# */ +/* Updated: 2017/03/23 16:49:03 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_nm_otool.h" + +static t_flag get_symtype(uint32_t i, struct dysymtab_command *dysym) +{ + if (dysym->ilocalsym <= i && i <= dysym->ilocalsym + dysym->nlocalsym) + return (SYM_DEBUG); + if (dysym->iextdefsym <= i && i <= dysym->iextdefsym + dysym->nextdefsym) + return (SYM_TEXT); + if (dysym->iundefsym <= i && i <= dysym->iundefsym + dysym->nundefsym) + return (SYM_UNDEF); + return (0); +} + +t_list *get_symbols(char *file) +{ + int i; + int nsyms; + char *stringtable; + char *string; + struct nlist_64 *array; + struct dylib_reference *ref; + t_symbol sym; + t_machodata data; + t_list *symbols; + + fetch_header(&data, file); + nsyms = data.symtab->nsyms; + array = (struct nlist_64*)(file + data.symtab->symoff); + stringtable = file + data.symtab->stroff; + ft_printf("LC_SYMTAB [%d] symbols:\n", data.symtab->nsyms); + i = -1; + symbols = NULL; + while (++i < nsyms) + { + sym.name = stringtable + array[i].n_un.n_strx; + sym.type = get_symtype(i, data.dysymtab); + sym.value = 0; + ft_lstadd(&symbols, ft_lstnew(&sym, sizeof(sym))); + } + return (symbols); + ft_putendl(""); + + ft_printf("ilocalsym %i\n", data.dysymtab->ilocalsym); + ft_printf("nlocalsym %i\n", data.dysymtab->nlocalsym); + + ft_printf("iextdefsym %i\n", data.dysymtab->iextdefsym); + ft_printf("nextdefsym %i\n", data.dysymtab->nextdefsym); + + ft_printf("iundefsym %i\n", data.dysymtab->iundefsym); + ft_printf("nundefsym %i\n", data.dysymtab->nundefsym); + + ft_printf("LC_DYSYMTAB ntoc=[%d]\n", data.dysymtab->ntoc); + ft_printf("LC_DYSYMTAB nmodtab=[%d]\n", data.dysymtab->nmodtab); + ft_printf("LC_DYSYMTAB nextrefsyms=[%d]\n", data.dysymtab->nextrefsyms); + ft_printf("LC_DYSYMTAB nmodtab=[%d]\n", data.dysymtab->nmodtab); + ft_printf("LC_DYSYMTAB nindirectsyms=[%d]\n", data.dysymtab->nindirectsyms); + ft_printf("LC_DYSYMTAB nextrel=[%d]\n", data.dysymtab->nextrel); + ft_printf("LC_DYSYMTAB nlocrel=[%d]\n", data.dysymtab->nlocrel); + ft_putendl(""); + ref = (struct dylib_reference *)(file + data.dysymtab->indirectsymoff); + i = -1; + while (++i < (int)data.dysymtab->nindirectsyms) + { + string = stringtable + array[ref->isym].n_un.n_strx; + ft_printf("%i: %s,%#x\n", ref->isym, string, ref->flags); + ref += 1; + } + (void)file; +} diff --git a/nm-otool/src/symprint.c b/nm-otool/src/symprint.c new file mode 100644 index 00000000..a76ad6c5 --- /dev/null +++ b/nm-otool/src/symprint.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* symprint.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/03/23 16:05:55 by jhalford #+# #+# */ +/* Updated: 2017/03/23 16:59:36 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "ft_nm_otool.h" + +int symprint_text(t_symbol *symbol) +{ + ft_printf("%16x %c %s\n", " ", symbol->value, symbol->name); + return (0); +} + +int symprint(t_symbol *symbol) +{ + t_symbolmap map; + + map = g_symbolmap[symbol->type]; + if (map.format) + map.format(symbol); + else + ft_printf("%16s %c %s\n", " ", map.c, symbol->name); + return (0); +}