| #include <u.h> | 
 | #include <libc.h> | 
 | #include <mach.h> | 
 | #include "stabs.h" | 
 | #include "macho.h" | 
 |  | 
 | void | 
 | usage(void) | 
 | { | 
 | 	fprint(2, "usage: machodump file list\n"); | 
 | 	fprint(2, "	machodump file stabs\n"); | 
 | 	exits("usage"); | 
 | } | 
 |  | 
 | uchar* | 
 | load(int fd, ulong off, int size) | 
 | { | 
 | 	uchar *a; | 
 |  | 
 | 	a = malloc(size); | 
 | print("malloc %d -> %p\n", size, a); | 
 | 	if(a == nil) | 
 | 		sysfatal("malloc: %r"); | 
 | 	if(seek(fd, off, 0) < 0) | 
 | 		sysfatal("seek %lud: %r", off); | 
 | 	if(readn(fd, a, size) != size) | 
 | 		sysfatal("readn: %r"); | 
 | 	return a; | 
 | } | 
 |  | 
 | void | 
 | main(int argc, char **argv) | 
 | { | 
 | 	int i; | 
 | 	Macho *m; | 
 |  | 
 | 	ARGBEGIN{ | 
 | 	default: | 
 | 		usage(); | 
 | 	}ARGEND | 
 |  | 
 | 	if(argc < 2) | 
 | 		usage(); | 
 |  | 
 | 	if((m = machoopen(argv[0])) == nil) | 
 | 		sysfatal("machoopen %s: %r", argv[0]); | 
 |  | 
 | 	if(strcmp(argv[1], "stabs") == 0){ | 
 | 		Stab stabs; | 
 | 		StabSym sym; | 
 |  | 
 | 		for(i=0; i<m->ncmd; i++){ | 
 | 			if(m->cmd[i].type == MachoCmdSymtab){ | 
 | 				stabs.stabbase = load(m->fd, m->cmd[i].sym.symoff, m->cmd[i].sym.nsyms*16); | 
 | 				stabs.stabsize = m->cmd[i].sym.nsyms*16; | 
 | 				stabs.strbase = load(m->fd, m->cmd[i].sym.stroff, m->cmd[i].sym.strsize); | 
 | 				stabs.strsize = m->cmd[i].sym.strsize; | 
 | 				stabs.e4 = m->e4; | 
 | 				stabs.e2 = (m->e4 == beload4 ? beload2 : leload2); | 
 | 				print("cmd%d: %p %ud %p %ud\n", i, stabs.stabbase, stabs.stabsize, stabs.strbase, stabs.strsize); | 
 | 				for(i=0; stabsym(&stabs, i, &sym) >= 0; i++) | 
 | 					print("%s type 0x%x other %d desc %d value 0x%lux\n", | 
 | 						sym.name, sym.type, sym.other, (int)sym.desc, (ulong)sym.value); | 
 | 				print("err at %d: %r\n", i); | 
 | 			} | 
 | 		} | 
 | 	} | 
 | 	else if(strcmp(argv[1], "list") == 0){ | 
 | 		print("macho cpu %ud sub %ud filetype %lud flags %lud\n", | 
 | 			m->cputype, m->subcputype, m->filetype, m->flags); | 
 | 		for(i=0; i<m->ncmd; i++){ | 
 | 			switch(m->cmd[i].type){ | 
 | 			case MachoCmdSymtab: | 
 | 				print("cmd%d: symtab %lud+%lud %lud+%lud\n", i, | 
 | 					m->cmd[i].sym.symoff, m->cmd[i].sym.nsyms, | 
 | 					m->cmd[i].sym.stroff, m->cmd[i].sym.strsize); | 
 | 				break; | 
 | 			case MachoCmdSegment: | 
 | 				print("cmd%d: segment %s vm 0x%lux+0x%lux file 0x%lux+0x%lux prot 0x%lux/0x%lux ns %d flags 0x%lux\n", i, | 
 | 					m->cmd[i].seg.name, m->cmd[i].seg.vmaddr, m->cmd[i].seg.vmsize, | 
 | 					m->cmd[i].seg.fileoff, m->cmd[i].seg.filesz, m->cmd[i].seg.maxprot, | 
 | 					m->cmd[i].seg.initprot, m->cmd[i].seg.nsect, m->cmd[i].seg.flags); | 
 | 				break; | 
 | 			default: | 
 | 				print("cmd%d: type %d offset %lud\n", i, m->cmd[i].type, m->cmd[i].off); | 
 | 				break; | 
 | 			} | 
 | 		} | 
 | 	} | 
 | 	else | 
 | 		usage(); | 
 | 	exits(0); | 
 | } |