stuff
This commit is contained in:
parent
fcc8dc3536
commit
25362e802e
13 changed files with 342 additions and 223 deletions
|
|
@ -35,14 +35,15 @@ FT_NM_OBJ = $(OBJ_DIR)ft_nm.o
|
||||||
FT_OTOOL_OBJ= $(OBJ_DIR)ft_otool.o
|
FT_OTOOL_OBJ= $(OBJ_DIR)ft_otool.o
|
||||||
|
|
||||||
SRC_BASE = \
|
SRC_BASE = \
|
||||||
|
dump_symtab.c\
|
||||||
fetch_header.c\
|
fetch_header.c\
|
||||||
ft_nm.c\
|
ft_nm.c\
|
||||||
ft_otool.c\
|
ft_otool.c\
|
||||||
get_symbols.c\
|
|
||||||
hexdump.c\
|
hexdump.c\
|
||||||
|
mach_o_parse.c\
|
||||||
sym_dump.c\
|
sym_dump.c\
|
||||||
sym_format.c\
|
sym_format.c\
|
||||||
sym_get.c
|
symbol_init.c
|
||||||
|
|
||||||
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))
|
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))
|
||||||
OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))
|
OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/02/20 14:36:10 by jhalford #+# #+# */
|
/* Created: 2017/02/20 14:36:10 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/03/23 17:04:06 by jhalford ### ########.fr */
|
/* Updated: 2017/03/25 22:50:17 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -33,32 +33,36 @@ typedef enum e_symtype t_symtype;
|
||||||
typedef struct s_symbol t_symbol;
|
typedef struct s_symbol t_symbol;
|
||||||
typedef struct s_symbolmap t_symbolmap;
|
typedef struct s_symbolmap t_symbolmap;
|
||||||
typedef struct s_machodata t_machodata;
|
typedef struct s_machodata t_machodata;
|
||||||
|
typedef struct s_symbol t_symbol;
|
||||||
|
|
||||||
enum e_symtype
|
enum e_symtype
|
||||||
{
|
{
|
||||||
SYM_UNDEF,
|
SYM_UNDF,
|
||||||
SYM_ABS,
|
SYM_ABS,
|
||||||
SYM_TEXT,
|
SYM_TEXT,
|
||||||
SYM_DATA,
|
SYM_DATA,
|
||||||
SYM_BSS,
|
SYM_BSS,
|
||||||
SYM_COMMON,
|
SYM_COMMON,
|
||||||
SYM_DEBUG,
|
SYM_STAB,
|
||||||
SYM_OTHER,
|
SYM_OTHER,
|
||||||
SYM_INDIRECT,
|
SYM_INDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct s_machodata
|
struct s_machodata
|
||||||
{
|
{
|
||||||
struct symtab_command *symtab;
|
void *file;
|
||||||
struct dysymtab_command *dysymtab;
|
t_list *sects;
|
||||||
|
t_list *symbols;
|
||||||
|
struct symtab_command *symtab;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct s_symbol
|
struct s_symbol
|
||||||
{
|
{
|
||||||
t_symtype type;
|
t_symtype type;
|
||||||
long value;
|
int pos;
|
||||||
char *name;
|
struct nlist_64 nlist;
|
||||||
|
char *string;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct s_symbolmap
|
struct s_symbolmap
|
||||||
|
|
@ -68,16 +72,26 @@ struct s_symbolmap
|
||||||
};
|
};
|
||||||
|
|
||||||
extern t_symbolmap g_symbolmap[];
|
extern t_symbolmap g_symbolmap[];
|
||||||
|
extern t_machodata *g_data;
|
||||||
|
|
||||||
t_list *sym_get(char *file);
|
int mach_o_parse(t_machodata *data);
|
||||||
int fetch_header(t_machodata *data, void *file);
|
int fetch_header(t_machodata *data);
|
||||||
|
|
||||||
int sym_format(t_symbol *symbol);
|
int symbol_init(t_symbol *symbol,
|
||||||
int sym_format_text(t_symbolmap map, t_symbol *symbol);
|
char *stringtable, struct nlist_64 *array, int i);
|
||||||
|
int symbol_set(t_symbol *symbol);
|
||||||
|
|
||||||
void dump_symtab(struct symtab_command *symtab, void *file);
|
int sym_format(t_symbol *symbol);
|
||||||
void dump_dysymtab(struct dysymtab_command *dysymtab, void *file);
|
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 *hexdump(void *addr, unsigned int offset, unsigned int size);
|
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 *hexdump(void *addr, unsigned int offset, unsigned int size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
53
nm-otool/src/dump_symtab.c
Normal file
53
nm-otool/src/dump_symtab.c
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* dump_symtab.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/03/25 19:39:15 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/03/25 22:44:38 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "ft_nm_otool.h"
|
||||||
|
|
||||||
|
void dump_symtab(t_machodata *data, struct symtab_command *symtab)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *stringtable;
|
||||||
|
t_symbol symbol;
|
||||||
|
struct nlist_64 *array;
|
||||||
|
|
||||||
|
ft_printf("{blu}{inv}struct symtab_command{eoc}\n");
|
||||||
|
stringtable = data->file + symtab->stroff;
|
||||||
|
array = (struct nlist_64*)(data->file + symtab->symoff);
|
||||||
|
i = -1;
|
||||||
|
while (++i < (int)symtab->nsyms)
|
||||||
|
{
|
||||||
|
symbol_init(&symbol, stringtable, array, i);
|
||||||
|
dump_symbol(data, &symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_dysymtab(t_machodata *data, struct dysymtab_command *dysymtab)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
ft_printf("{blu}{inv}struct dysymtab_command{eoc}\n");
|
||||||
|
ft_printf("ilocalsym %i\n", dysymtab->ilocalsym);
|
||||||
|
ft_printf("nlocalsym %i\n", dysymtab->nlocalsym);
|
||||||
|
ft_printf("iextdefsym %i\n", dysymtab->iextdefsym);
|
||||||
|
ft_printf("nextdefsym %i\n", dysymtab->nextdefsym);
|
||||||
|
ft_printf("iundefsym %i\n", dysymtab->iundefsym);
|
||||||
|
ft_printf("nundefsym %i\n", dysymtab->nundefsym);
|
||||||
|
ft_printf("---------------\n");
|
||||||
|
ft_printf("ntoc %i\n", dysymtab->ntoc);
|
||||||
|
ft_printf("nmodtab %i\n", dysymtab->nmodtab);
|
||||||
|
ft_printf("nextrefsyms %i\n", dysymtab->nextrefsyms);
|
||||||
|
ft_printf("nmodtab %i\n", dysymtab->nmodtab);
|
||||||
|
ft_printf("nindirectsims %i\n", dysymtab->nindirectsyms);
|
||||||
|
ft_printf("nextrel %i\n", dysymtab->nextrel);
|
||||||
|
ft_printf("nlocrel %i\n", dysymtab->nlocrel);
|
||||||
|
ft_putendl("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -6,61 +6,100 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/03/23 15:56:37 by jhalford #+# #+# */
|
/* Created: 2017/03/23 15:56:37 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/03/23 16:25:49 by jhalford ### ########.fr */
|
/* Updated: 2017/03/25 22:51:09 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_nm_otool.h"
|
#include "ft_nm_otool.h"
|
||||||
|
|
||||||
static void fetch_machheader64(t_machodata *data, void *file)
|
static void fetch_symtab(t_machodata *data, struct symtab_command *symtab)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
t_symbol symbol;
|
||||||
|
char *stringtable;
|
||||||
|
struct nlist_64 *array;
|
||||||
|
|
||||||
|
data->symtab = symtab;
|
||||||
|
stringtable = data->file + symtab->stroff;
|
||||||
|
array = (struct nlist_64*)(data->file + symtab->symoff);
|
||||||
|
i = -1;
|
||||||
|
while (++i < (int)symtab->nsyms)
|
||||||
|
{
|
||||||
|
symbol_init(&symbol, stringtable, array, i);
|
||||||
|
ft_lsteadd(&data->symbols, ft_lstnew(&symbol, sizeof(symbol)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fetch_sects(t_machodata *data, struct segment_command_64 *seg)
|
||||||
|
{
|
||||||
|
uint32_t nsects;
|
||||||
|
uint32_t i;
|
||||||
|
struct section_64 *sect;
|
||||||
|
|
||||||
|
nsects = seg->nsects;
|
||||||
|
sect = (void*)(seg + 1);
|
||||||
|
for (i = 0; i < nsects; i++)
|
||||||
|
{
|
||||||
|
/* DG("sect at %p (%s)", sect, sect->sectname); */
|
||||||
|
/* DG("data->sects at %p", ft_lstlast(data->sects)); */
|
||||||
|
ft_lsteadd(&data->sects, ft_lstnew(§, sizeof(sect)));
|
||||||
|
/* DG("data->sects at %p -> %p", ft_lstlast(data->sects), *(struct section_64*)ft_lstlast(data->sects)->content); */
|
||||||
|
/* DG("------------------"); */
|
||||||
|
sect = sect + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fetch_machheader64(t_machodata *data)
|
||||||
{
|
{
|
||||||
uint32_t ncmds;
|
uint32_t ncmds;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct load_command *lc;
|
struct load_command *lc;
|
||||||
struct mach_header_64 *header = file;
|
struct mach_header_64 *header;
|
||||||
|
|
||||||
|
header = data->file;
|
||||||
ncmds = header->ncmds;
|
ncmds = header->ncmds;
|
||||||
lc = (void*)(header + 1);
|
lc = (void*)(header + 1);
|
||||||
/* ft_printf("{blu}{inv}mach_header_64 w/ [%d] load_commands{eoc}\n", ncmds); */
|
|
||||||
for (i = 0; i < ncmds; i++)
|
for (i = 0; i < ncmds; i++)
|
||||||
{
|
{
|
||||||
/* ft_printf("{yel}{inv}load_command #%d: %#x{eoc}\n", i, lc->cmd); */
|
|
||||||
if (lc->cmd == LC_SYMTAB)
|
if (lc->cmd == LC_SYMTAB)
|
||||||
data->symtab = (struct symtab_command*)lc;
|
fetch_symtab(data, (struct symtab_command*)lc);
|
||||||
else if (lc->cmd == LC_DYSYMTAB)
|
/* else if (lc->cmd == LC_DYSYMTAB) */
|
||||||
data->dysymtab = (struct dysymtab_command*)lc;
|
/* data->dysymtab = (struct dysymtab_command*)lc; */
|
||||||
|
else if (lc->cmd == LC_SEGMENT_64)
|
||||||
|
fetch_sects(data, (struct segment_command_64*)lc);
|
||||||
lc = (void*)lc + lc->cmdsize;
|
lc = (void*)lc + lc->cmdsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fetch_fatheader(t_machodata *data, void *file)
|
/* static void fetch_fatheader(t_machodata *data) */
|
||||||
{
|
/* { */
|
||||||
struct fat_header *header = file;
|
/* int i; */
|
||||||
struct fat_arch *arch;
|
/* int nfat_arch; */
|
||||||
int i;
|
/* struct fat_arch *arch; */
|
||||||
int nfat_arch;
|
/* struct fat_header *header; */
|
||||||
|
|
||||||
nfat_arch = header->nfat_arch;
|
/* header = data->file; */
|
||||||
arch = (void*)(header + 1);
|
/* nfat_arch = header->nfat_arch; */
|
||||||
ft_printf("{yel}{inv}FAT header w/ [%i] architures{eoc}\n", nfat_arch);
|
/* arch = (void*)(header + 1); */
|
||||||
for (i = 0; i < nfat_arch; i++)
|
/* 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);
|
/* ft_printf("CPU type=[%i]", arch->cputype); */
|
||||||
arch += 1;
|
/* fetch_machheader64(data->file + arch->offset, data); */
|
||||||
}
|
/* arch += 1; */
|
||||||
}
|
/* } */
|
||||||
|
/* } */
|
||||||
|
|
||||||
int fetch_header(t_machodata *data, void *file)
|
int fetch_header(t_machodata *data)
|
||||||
{
|
{
|
||||||
uint32_t magic = *(int *)file;
|
uint32_t magic = *(int *)data->file;
|
||||||
int is_fat = IS_FAT(magic);
|
/* int is_fat = IS_FAT(magic); */
|
||||||
int is_64 = IS_MAGIC_64(magic);
|
int is_64 = IS_MAGIC_64(magic);
|
||||||
|
|
||||||
if (is_64)
|
if (is_64)
|
||||||
fetch_machheader64(data, file);
|
fetch_machheader64(data);
|
||||||
else if (is_fat)
|
/* else if (is_fat) */
|
||||||
fetch_fatheader(data, file);
|
/* fetch_fatheader(data); */
|
||||||
else
|
else
|
||||||
ft_printf("{red}unsupported architecture:{eoc} magic = %#x\n", magic);
|
ft_printf("{red}unsupported architecture:{eoc} magic = %#x\n", magic);
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,26 @@
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2017/02/19 03:09:12 by jhalford #+# #+# */
|
/* Created: 2017/02/19 03:09:12 by jhalford #+# #+# */
|
||||||
/* Updated: 2017/03/23 17:04:13 by jhalford ### ########.fr */
|
/* Updated: 2017/03/25 22:49:54 by jhalford ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_nm_otool.h"
|
#include "ft_nm_otool.h"
|
||||||
|
|
||||||
|
t_machodata *g_data = NULL;
|
||||||
|
|
||||||
void nm(void *file)
|
void nm(void *file)
|
||||||
{
|
{
|
||||||
t_list *symbols;
|
t_machodata data;
|
||||||
|
|
||||||
symbols = sym_get(file);
|
data.sects = NULL;
|
||||||
ft_lstiter(symbols, sym_format);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
|
|
@ -27,7 +35,7 @@ int main(int ac, char **av)
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
if (ac != 2)
|
if (ac != 2)
|
||||||
{
|
{
|
||||||
ft_dprintf(2, "Please give me an arg\n");
|
ft_dprintf(2, "USAGE PLACEHOLDER\n");
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
if ((fd = open(av[1], O_RDONLY)) < 0)
|
if ((fd = open(av[1], O_RDONLY)) < 0)
|
||||||
|
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* dump_symtab.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* 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 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 *sym_get(char *file)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
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);
|
|
||||||
stringtable = file + data.symtab->stroff;
|
|
||||||
symbols = NULL;
|
|
||||||
|
|
||||||
dump_symtab(data.symtab, file);
|
|
||||||
dump_dysymtab(data.dysymtab, file);
|
|
||||||
/* return (NULL); */
|
|
||||||
i = -1;
|
|
||||||
array = (struct nlist_64*)(file + data.symtab->symoff);
|
|
||||||
while (++i < (int)data.symtab->nsyms)
|
|
||||||
{
|
|
||||||
sym.name = stringtable + array[i].n_un.n_strx;
|
|
||||||
sym.type = symtype(i, data.dysymtab);
|
|
||||||
sym.value = 0;
|
|
||||||
ft_lsteadd(&symbols, ft_lstnew(&sym, sizeof(sym)));
|
|
||||||
}
|
|
||||||
return (symbols);
|
|
||||||
i = -1;
|
|
||||||
ref = (struct dylib_reference *)(file + data.dysymtab->indirectsymoff);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
19
nm-otool/src/mach_o_parse.c
Normal file
19
nm-otool/src/mach_o_parse.c
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* mach_o_parse.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/03/25 20:56:50 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/03/25 22:09:56 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "ft_nm_otool.h"
|
||||||
|
|
||||||
|
int mach_o_parse(t_machodata *data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
@ -2,19 +2,19 @@
|
||||||
|
|
||||||
void dump_section_64(struct section_64 *sect)
|
void dump_section_64(struct section_64 *sect)
|
||||||
{
|
{
|
||||||
ft_printf("{blu}{inv}struct section_64{eoc}: segname=[%s], sectname=[%s]\n",
|
ft_printf("{blu}{inv}struct section_64{eoc} sectname=[%s]\n",
|
||||||
sect->segname, sect->sectname);
|
sect->sectname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_segment_64(struct segment_command_64 *seg, void *file)
|
void dump_segment_64(t_machodata *data, struct segment_command_64 *seg)
|
||||||
{
|
{
|
||||||
uint32_t nsects;
|
uint32_t nsects;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct section_64 *sect;
|
struct section_64 *sect;
|
||||||
|
|
||||||
(void)file;
|
(void)data;
|
||||||
nsects = seg->nsects;
|
nsects = seg->nsects;
|
||||||
ft_printf("{blu}{inv}struct segment_command_64{eoc}: segname=[%s], nsects=[%i]\n", seg->segname, nsects);
|
ft_printf("{blu}{inv}struct segment_command_64{eoc} segname=[%s], nsects=[%i]\n", seg->segname, nsects);
|
||||||
sect = (void*)(seg + 1);
|
sect = (void*)(seg + 1);
|
||||||
for (i = 0; i < nsects; i++)
|
for (i = 0; i < nsects; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -23,41 +23,50 @@ void dump_segment_64(struct segment_command_64 *seg, void *file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_symtab(struct symtab_command *symtab, void *file)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *stringtable;
|
|
||||||
char *string;
|
|
||||||
struct nlist_64 *array;
|
|
||||||
|
|
||||||
ft_printf("{blu}{inv}struct symtab_command{eoc}\n");
|
void dump_symbol(t_machodata *data, t_symbol *symbol)
|
||||||
stringtable = file + symtab->stroff;
|
{
|
||||||
array = (struct nlist_64*)(file + symtab->symoff);
|
uint8_t n_type; /* type flag, see below */
|
||||||
i = -1;
|
uint8_t n_sect; /* section number or NO_SECT */
|
||||||
while (++i < (int)symtab->nsyms)
|
uint16_t n_desc; /* see <mach-o/stab.h> */
|
||||||
|
uint64_t n_value; /* value of this symbol (or stab offset) */
|
||||||
|
char *sect_name;
|
||||||
|
|
||||||
|
n_type = symbol->nlist.n_type;
|
||||||
|
n_sect = symbol->nlist.n_sect;
|
||||||
|
n_desc = symbol->nlist.n_desc;
|
||||||
|
n_value = symbol->nlist.n_value;
|
||||||
|
DG("check");
|
||||||
|
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,
|
||||||
|
(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_machheader_64(t_machodata *data)
|
||||||
|
{
|
||||||
|
uint32_t ncmds;
|
||||||
|
uint32_t i;
|
||||||
|
struct load_command *lc;
|
||||||
|
struct mach_header_64 *header;
|
||||||
|
|
||||||
|
header = data->file;
|
||||||
|
ncmds = header->ncmds;
|
||||||
|
lc = (void*)(header + 1);
|
||||||
|
for (i = 0; i < ncmds; i++)
|
||||||
{
|
{
|
||||||
string = stringtable + array[i].n_un.n_strx;
|
if (lc->cmd == LC_SYMTAB)
|
||||||
ft_printf("%s\n", string);
|
dump_symtab(data, (struct symtab_command*)lc);
|
||||||
|
else if (lc->cmd == LC_DYSYMTAB)
|
||||||
|
dump_dysymtab(data, (struct dysymtab_command*)lc);
|
||||||
|
else if (lc->cmd == LC_SEGMENT_64)
|
||||||
|
dump_segment_64(data, (struct segment_command_64*)lc);
|
||||||
|
lc = (void*)lc + lc->cmdsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_dysymtab(struct dysymtab_command *dysymtab, void *file)
|
|
||||||
{
|
|
||||||
(void)file;
|
|
||||||
ft_printf("{blu}{inv}struct dysymtab_command{eoc}\n");
|
|
||||||
ft_printf("ilocalsym %i\n", dysymtab->ilocalsym);
|
|
||||||
ft_printf("nlocalsym %i\n", dysymtab->nlocalsym);
|
|
||||||
ft_printf("iextdefsym %i\n", dysymtab->iextdefsym);
|
|
||||||
ft_printf("nextdefsym %i\n", dysymtab->nextdefsym);
|
|
||||||
ft_printf("iundefsym %i\n", dysymtab->iundefsym);
|
|
||||||
ft_printf("nundefsym %i\n", dysymtab->nundefsym);
|
|
||||||
ft_printf("---------------\n");
|
|
||||||
ft_printf("ntoc %i\n", dysymtab->ntoc);
|
|
||||||
ft_printf("nmodtab %i\n", dysymtab->nmodtab);
|
|
||||||
ft_printf("nextrefsyms %i\n", dysymtab->nextrefsyms);
|
|
||||||
ft_printf("nmodtab %i\n", dysymtab->nmodtab);
|
|
||||||
ft_printf("nindirectsims %i\n", dysymtab->nindirectsyms);
|
|
||||||
ft_printf("nextrel %i\n", dysymtab->nextrel);
|
|
||||||
ft_printf("nlocrel %i\n", dysymtab->nlocrel);
|
|
||||||
ft_putendl("");
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,42 @@
|
||||||
|
|
||||||
t_symbolmap g_symbolmap[] =
|
t_symbolmap g_symbolmap[] =
|
||||||
{
|
{
|
||||||
{'U', NULL},
|
{'U', sym_format_undf},
|
||||||
{'A', NULL},
|
{'A', NULL},
|
||||||
{'T', sym_format_text},
|
{'T', sym_format_text},
|
||||||
{'D', NULL},
|
{'D', NULL},
|
||||||
{'B', NULL},
|
{'B', NULL},
|
||||||
{'C', NULL},
|
{'C', NULL},
|
||||||
{'-', NULL},
|
{'-', sym_format_stab},
|
||||||
{'S', NULL},
|
{'S', NULL},
|
||||||
{'I', NULL},
|
{'I', NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int sym_format_undf(t_symbolmap map, t_symbol *symbol)
|
||||||
|
{
|
||||||
|
ft_printf("%16s %c %s\n", " ", map.c, symbol->string);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int sym_format_text(t_symbolmap map, t_symbol *symbol)
|
int sym_format_text(t_symbolmap map, t_symbol *symbol)
|
||||||
{
|
{
|
||||||
ft_printf("%016x %c %s\n", symbol->value, map.c, symbol->name);
|
char c;
|
||||||
|
|
||||||
|
c = symbol->nlist.n_type & N_EXT ? 'T' : 't';
|
||||||
|
ft_printf("%016x %c %s\n", symbol->nlist.n_value, map.c, symbol->string);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sym_format_stab(t_symbolmap map, t_symbol *symbol)
|
||||||
|
{
|
||||||
|
struct nlist_64 stab;
|
||||||
|
|
||||||
|
stab = symbol->nlist;
|
||||||
|
ft_printf("%016x %c %02x %04b %#x %s\n",
|
||||||
|
stab.n_value, map.c,
|
||||||
|
stab.n_sect, stab.n_desc, stab.n_type,
|
||||||
|
symbol->string);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,6 +49,7 @@ int sym_format(t_symbol *symbol)
|
||||||
if (map.format)
|
if (map.format)
|
||||||
map.format(map, symbol);
|
map.format(map, symbol);
|
||||||
else
|
else
|
||||||
ft_printf("%16s %c %s\n", " ", map.c, symbol->name);
|
ft_printf("%016x %c %s\n",
|
||||||
|
symbol->nlist.n_value, map.c, symbol->string);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* dump_symtab.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* 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("");
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
56
nm-otool/src/symbol_init.c
Normal file
56
nm-otool/src/symbol_init.c
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* symbol_init.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2017/03/25 21:22:06 by jhalford #+# #+# */
|
||||||
|
/* Updated: 2017/03/25 22:53:07 by jhalford ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "ft_nm_otool.h"
|
||||||
|
|
||||||
|
t_machodata *g_data;
|
||||||
|
|
||||||
|
int symbol_init(t_symbol *symbol, char *stringtable, struct nlist_64 *array, int i)
|
||||||
|
{
|
||||||
|
symbol->type = 0;
|
||||||
|
symbol->pos = i;
|
||||||
|
symbol->nlist = array[i];
|
||||||
|
symbol->string = stringtable + array[i].n_un.n_strx;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int symbol_set(t_symbol *symbol)
|
||||||
|
{
|
||||||
|
struct nlist_64 nlist;
|
||||||
|
uint8_t n_type;
|
||||||
|
uint8_t type_mask;
|
||||||
|
char *sect_name;
|
||||||
|
|
||||||
|
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;
|
||||||
|
if (n_type & N_STAB)
|
||||||
|
symbol->type = SYM_STAB;
|
||||||
|
else if (type_mask == N_UNDF && n_type & N_EXT && nlist.n_value != 0)
|
||||||
|
symbol->type = SYM_COMMON;
|
||||||
|
else if (type_mask == N_UNDF)
|
||||||
|
symbol->type = SYM_UNDF;
|
||||||
|
else if (type_mask == N_SECT && ft_strcmp("__text", sect_name) == 0)
|
||||||
|
symbol->type = SYM_TEXT;
|
||||||
|
else if (type_mask == N_SECT && ft_strcmp("__data", sect_name) == 0)
|
||||||
|
symbol->type = SYM_DATA;
|
||||||
|
else if (type_mask == N_ABS)
|
||||||
|
symbol->type = SYM_ABS;
|
||||||
|
else if (type_mask == N_INDR)
|
||||||
|
symbol->type = SYM_INDR;
|
||||||
|
else
|
||||||
|
symbol->type = SYM_UNDF;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
1
nm-otool/tests/compile.sh
Normal file
1
nm-otool/tests/compile.sh
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
gcc -g3 stabs_define.c -w -o stabs_define
|
||||||
23
nm-otool/tests/stabs_define.c
Normal file
23
nm-otool/tests/stabs_define.c
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#define NONE 42
|
||||||
|
#define TWO(a, b) (a + (a) + 2 * b)
|
||||||
|
#define ONE(c) (c + 19)
|
||||||
|
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
func(NONE, TWO(10, 11));
|
||||||
|
func(NONE, ONE(23));
|
||||||
|
|
||||||
|
#undef ONE
|
||||||
|
#define ONE(c) (c + 23)
|
||||||
|
|
||||||
|
func(NONE, ONE(-23));
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int global;
|
||||||
|
|
||||||
|
func(int arg1, int arg2)
|
||||||
|
{
|
||||||
|
global = arg1 + arg2;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue