diff --git a/nm-otool/Makefile b/nm-otool/Makefile index 0ca0816b..ec52288f 100644 --- a/nm-otool/Makefile +++ b/nm-otool/Makefile @@ -43,7 +43,8 @@ hexdump.c\ mach_o_parse.c\ sym_dump.c\ sym_format.c\ -symbol_init.c +symbol_init.c\ +symbol_sort.c SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) diff --git a/nm-otool/includes/ft_nm_otool.h b/nm-otool/includes/ft_nm_otool.h index 0e7ef329..5cf6d515 100644 --- a/nm-otool/includes/ft_nm_otool.h +++ b/nm-otool/includes/ft_nm_otool.h @@ -29,6 +29,11 @@ # define IS_MAGIC_64(x) (x == MH_MAGIC_64 || x == MH_CIGAM_64) # define IS_FAT(x) (x == FAT_MAGIC || x == FAT_CIGAM) +# define NM_NSORT (1 << 0) +# define NM_ASORT (1 << 1) +# define NM_RSORT (1 << 1) + +typedef t_data_template t_nmdata; typedef enum e_symtype t_symtype; typedef struct s_symbol t_symbol; typedef struct s_symbolmap t_symbolmap; @@ -62,6 +67,7 @@ struct s_symbol t_symtype type; int pos; struct nlist_64 nlist; + char *sect_name; char *string; }; @@ -74,23 +80,24 @@ struct s_symbolmap extern t_symbolmap g_symbolmap[]; extern t_machodata *g_data; -int mach_o_parse(t_machodata *data); -int fetch_header(t_machodata *data); +int mach_o_parse(t_machodata *data); +int fetch_header(t_machodata *data); -int symbol_init(t_symbol *symbol, +int symbol_init(t_symbol *symbol, char *stringtable, struct nlist_64 *array, int i); -int symbol_set(t_symbol *symbol); +int symbol_set(t_symbol *symbol, t_machodata *data); +int symbol_sort(t_list **syms, t_flag flag); -int sym_format(t_symbol *symbol); -int sym_format_undf(t_symbolmap map, t_symbol *symbol); -int sym_format_text(t_symbolmap map, t_symbol *symbol); -int sym_format_stab(t_symbolmap map, t_symbol *symbol); +int sym_format(t_symbol *symbol); +int sym_format_undf(t_symbolmap map, t_symbol *symbol); +int sym_format_text(t_symbolmap map, t_symbol *symbol); +int sym_format_stab(t_symbolmap map, t_symbol *symbol); -void dump_symbol(t_machodata *data, t_symbol *symbol); -void dump_machheader_64(t_machodata *data); -void dump_segment_64(t_machodata *data, struct segment_command_64 *seg); -void dump_symtab(t_machodata *data, struct symtab_command *symtab); -void dump_dysymtab(t_machodata *data, struct dysymtab_command *dysymtab); +void dump_symbol(t_machodata *data, t_symbol *symbol); +void mach_64_parse(t_machodata *data); +void dump_segment_64(t_machodata *data, struct segment_command_64 *seg); +void dump_symtab(t_machodata *data, struct symtab_command *symtab); +void dump_dysymtab(t_machodata *data, struct dysymtab_command *dysymtab); void *hexdump(void *addr, unsigned int offset, unsigned int size); diff --git a/nm-otool/src/fetch_header.c b/nm-otool/src/fetch_header.c index da5b8eba..5d03ea79 100644 --- a/nm-otool/src/fetch_header.c +++ b/nm-otool/src/fetch_header.c @@ -12,7 +12,7 @@ #include "ft_nm_otool.h" -static void fetch_symtab(t_machodata *data, struct symtab_command *symtab) +static void symtab_parse(t_machodata *data, struct symtab_command *symtab) { int i; t_symbol symbol; @@ -26,6 +26,7 @@ static void fetch_symtab(t_machodata *data, struct symtab_command *symtab) while (++i < (int)symtab->nsyms) { symbol_init(&symbol, stringtable, array, i); + symbol_set(&symbol, data); ft_lsteadd(&data->symbols, ft_lstnew(&symbol, sizeof(symbol))); } } @@ -49,7 +50,7 @@ static void fetch_sects(t_machodata *data, struct segment_command_64 *seg) } } -static void fetch_machheader64(t_machodata *data) +void mach_64_parse(t_machodata *data) { uint32_t ncmds; uint32_t i; @@ -62,7 +63,7 @@ static void fetch_machheader64(t_machodata *data) for (i = 0; i < ncmds; i++) { if (lc->cmd == LC_SYMTAB) - fetch_symtab(data, (struct symtab_command*)lc); + symtab_parse(data, (struct symtab_command*)lc); /* else if (lc->cmd == LC_DYSYMTAB) */ /* data->dysymtab = (struct dysymtab_command*)lc; */ else if (lc->cmd == LC_SEGMENT_64) @@ -90,18 +91,3 @@ static void fetch_machheader64(t_machodata *data) /* } */ /* } */ -int fetch_header(t_machodata *data) -{ - uint32_t magic = *(int *)data->file; - /* int is_fat = IS_FAT(magic); */ - int is_64 = IS_MAGIC_64(magic); - - if (is_64) - fetch_machheader64(data); - /* else if (is_fat) */ - /* fetch_fatheader(data); */ - 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 4125248d..ed35cffc 100644 --- a/nm-otool/src/ft_nm.c +++ b/nm-otool/src/ft_nm.c @@ -14,39 +14,79 @@ t_machodata *g_data = NULL; -void nm(void *file) +t_cliopts g_nm_opts[] = { - t_machodata data; + {'n', NULL, NM_NSORT, NM_ASORT, NULL, 0}, + {'p', NULL, 0, NM_NSORT | NM_ASORT, NULL, 0}, + {'r', NULL, NM_RSORT, 0, NULL, 0}, - data.sects = NULL; - data.symbols = NULL; - data.file = file; - fetch_header(&data); - dump_symtab(&data, data.symtab); - g_data = &data; - ft_lstiter(data.symbols, symbol_set); - ft_lstiter(data.symbols, sym_format); + {'g', NULL, 0, 0, NULL, 0}, + {'u', NULL, 0, 0, NULL, 0}, + {'a', NULL, 0, 0, NULL, 0}, + {'U', NULL, 0, 0, NULL, 0}, + {'o', NULL, 0, 0, NULL, 0}, + {'A', NULL, 0, 0, NULL, 0}, + {'m', NULL, 0, 0, NULL, 0}, + {'x', NULL, 0, 0, NULL, 0}, + {'j', NULL, 0, 0, NULL, 0}, +}; + +void mach_64_dump(struct mach_header_64 *file, t_nmdata *data) +{ + t_machodata mach; + + mach.sects = NULL; + mach.symbols = NULL; + mach.file = file; + mach_64_parse(&mach); + dump_symtab(&mach, mach.symtab); + symbol_sort(&mach.symbols, data->flag); + ft_lstiter(mach.symbols, sym_format); +} + +int nm(void *file, t_nmdata *data) +{ + uint32_t magic = *(int *)file; + int is_fat = IS_FAT(magic); + int is_64 = IS_MAGIC_64(magic); + + if (is_64) + { + ft_printf("{red}unsupported architecture:{eoc} magic = %#x (FAT)\n", magic); + mach_64_dump(file, data); + } + else if (is_fat) + ft_printf("{red}unsupported architecture:{eoc} magic = %#x (FAT)\n", magic); + else + ft_printf("{red}unsupported architecture:{eoc} magic = %#x\n", magic); + return (0); } int main(int ac, char **av) { - int fd; - char *file; - struct stat buf; - if (ac != 2) + char *file; + t_nmdata data; + int fd; + int i; + struct stat buf; + + data.flag = NM_ASORT; + if (cliopts_get(av, g_nm_opts, &data)) + return (ft_dprintf(2, "USAGE PLACEHOLDER\n") * 0 + 1); + i = 1; + while (i < ac && av[i]) { - ft_dprintf(2, "USAGE PLACEHOLDER\n"); - return (1); + if ((fd = open(av[i], O_RDONLY)) < 0) + return (1); + if ((fstat(fd, &buf)) < 0) + return (1); + if ((file = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) + == MAP_FAILED) + return (1); + nm(file, &data); + if (munmap(file, buf.st_size)) + return (1); + i++; } - if ((fd = open(av[1], O_RDONLY)) < 0) - return (1); - if ((fstat(fd, &buf)) < 0) - return (1); - if ((file = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) - == MAP_FAILED) - return (1); - nm(file); - if (munmap(file, buf.st_size)) - return (1); return (0); } diff --git a/nm-otool/src/sym_dump.c b/nm-otool/src/sym_dump.c index 3a2fd2e8..5c973e13 100644 --- a/nm-otool/src/sym_dump.c +++ b/nm-otool/src/sym_dump.c @@ -40,13 +40,13 @@ void dump_symbol(t_machodata *data, t_symbol *symbol) sect_name = n_sect ? (*(struct section_64**)ft_lst_at(data->sects, n_sect - 1)->content)->sectname : NULL; DG("check2"); - ft_printf("%i: %s\n\ - \t%03b|%b|%x|%b\ - \t%i(%s) \t%#06x \t%x\n", - symbol->pos, symbol->string, + ft_printf("%i:\t%03b|%b|%x|%b\ + \t%i(%s) \t%#06x \t%x %-20s\n", + symbol->pos, (n_type & N_STAB) >> 5, (n_type & N_PEXT) >> 4, n_type & N_TYPE, n_type & N_EXT, - n_sect, sect_name, n_desc, n_value); + n_sect, sect_name, n_desc, n_value, + symbol->string); } void dump_machheader_64(t_machodata *data) diff --git a/nm-otool/src/symbol_init.c b/nm-otool/src/symbol_init.c index b2861cdd..9a61f6e0 100644 --- a/nm-otool/src/symbol_init.c +++ b/nm-otool/src/symbol_init.c @@ -23,7 +23,7 @@ int symbol_init(t_symbol *symbol, char *stringtable, struct nlist_64 *array, int return (0); } -int symbol_set(t_symbol *symbol) +int symbol_set(t_symbol *symbol, t_machodata *data) { struct nlist_64 nlist; uint8_t n_type; @@ -33,9 +33,8 @@ int symbol_set(t_symbol *symbol) nlist = symbol->nlist; n_type = symbol->nlist.n_type; type_mask = n_type & N_TYPE; - sect_name = symbol->nlist.n_sect ? - (*(struct section_64**)ft_lst_at(g_data->sects, - symbol->nlist.n_sect - 1)->content)->sectname : NULL; + symbol->sect_name = symbol->nlist.n_sect ? + (*(struct section_64**)ft_lst_at(data->sects, symbol->nlist.n_sect - 1)->content)->sectname : NULL; if (n_type & N_STAB) symbol->type = SYM_STAB; else if (type_mask == N_UNDF && n_type & N_EXT && nlist.n_value != 0) diff --git a/nm-otool/src/symbol_sort.c b/nm-otool/src/symbol_sort.c new file mode 100644 index 00000000..e669ec87 --- /dev/null +++ b/nm-otool/src/symbol_sort.c @@ -0,0 +1,24 @@ +#include "ft_nm_otool.h" + +static int sym_asort(t_symbol *sym1, t_symbol *sym2) +{ + return (ft_strcmp(sym1->string, sym2->string)); +} + +static int sym_nsort(t_symbol *sym1, t_symbol *sym2) +{ + if (sym1->nlist.n_value == sym2->nlist.n_value) + return (ft_strcmp(sym1->string, sym2->string)); + return (sym1->nlist.n_value - sym2->nlist.n_value); +} + +int symbol_sort(t_list **syms, t_flag flag) +{ + if (flag & NM_ASORT) + ft_lstsort(syms, sym_asort); + else if (flag & NM_NSORT) + ft_lstsort(syms, sym_nsort); + if (flag & NM_RSORT) + ft_lst_reverse(syms); + return (0); +}