/*************************************************************************** main.c - core dump debugger - Mac OS X code ------------------- begin : Sun Nov 27 21:46:02 EDT 2003 copyright : (C) 2003 by Atanas Dimitrov email : atanas_dimitrov@bobcat.gcsu.edu ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define EMPTY 0 #define MAX_NOTES 10 #define CPU_TYPE_MIPS ((cpu_type_t) 8) /* to avoid implicit declaration warnings generated by -Wall */ extern char *ctime(const time_t *timep); int main(int argc, char *argv[]) { int fdin; char *acctime, *modtime, *chtime; char *longarray; struct stat statbuf; struct mach_header *mach_hdr; /* check for necessary number of command line arguments */ if(argc < 2) { printf("Usage: %s \n", argv[0]); exit(1); } /* check for successful binary file opening */ if ((fdin = open(argv[1], O_RDONLY)) == -1) { perror("open"); exit(2); } /* get the attributes of the file but first check for errors */ if ((fstat(fdin, &statbuf)) < 0) { perror("fstat"); exit(3); } /* display some attributes */ printf("\n.: FILE STATUS INFORMATION :.\n"); printf("hard links: %d\n", statbuf.st_nlink); printf("uid: %d\n", statbuf.st_uid); printf("gid: %d\n", statbuf.st_gid); printf("size: %d\n", statbuf.st_size); printf("block size: %d\n", statbuf.st_blksize); printf("block count: %d\n", statbuf.st_blocks); acctime = (char *) ctime(&statbuf.st_atime); printf("last access: %s", acctime); modtime = (char *) ctime(&statbuf.st_mtime); printf("last mod: %s", modtime); chtime = (char *) ctime(&statbuf.st_ctime); printf("last change: %s", chtime); /* initialize the array to hold the file */ if ((longarray = mmap(0, statbuf.st_size, PROT_READ, \ MAP_FILE | MAP_SHARED, fdin, 0)) == -1) { printf("\nmmap"); exit(4); } /* copy over the mach-o header */ mach_hdr = (struct mach_header *) ((unsigned char *) &longarray[0x0]); if (mach_hdr->magic == 0xfeedface) { printf("\n%#lx type accepted\n", mach_hdr->magic); } else { perror("\nunrecognized file format...quitting!"); exit(4); } /* display mach-o header file information */ printf("\n.: MACH-O HEADER INFORMATION :.\n"); printf("MACH-O magic number: %#lx\n", mach_hdr->magic); /* START: DETERMINE CPU SPECIFFICS */ /* determine CPU type and CPU subtype */ printf("CPU type: "); if (mach_hdr->cputype == CPU_TYPE_ANY) { printf("ANY\n"); printf("CPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_MULTIPLE) printf("MULTIPLE"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_LITTLE_ENDIAN) printf("LITTLE_ENDIAN"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_BIG_ENDIAN) printf("BIG_ENDIAN"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_VAX) { printf("VAX"); printf("CPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX_ALL) printf("VAX_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX780) printf("VAX780"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX785) printf("VAX785"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX750) printf("VAX750"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX730) printf("VAX730"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_UVAXI) printf("UVAXI"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_UVAXII) printf("UVAXII"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX8200) printf("VAX8200"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX8500) printf("VAX8500"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX8600) printf("VAX8600"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX8650) printf("VAX8650"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_VAX8800) printf("VA8800"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_UVAXIII) printf("UVAXIII"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_MC680x0) { printf("MC680x0"); printf("CPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC680x0_ALL) printf("MC680x0_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC68030) printf("MC68030"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC68040) printf("MC68040"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC68030_ONLY) printf("MC68030_ONLY"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_I386) { printf("I386"); printf("CPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_I386_ALL) printf("I386_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_386) printf("386"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_486) printf("486"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_486SX) printf("486SX"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_586) printf("586"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_PENT) printf("PENT"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_PENTPRO) printf("PENTPRO"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_PENTII_M3) printf("PENTII_M3"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_PENTII_M5) printf("PENTII_M5"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_INTEL_FAMILY_MAX) printf("INTEL_FAMILY_MAX"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_INTEL_MODEL_ALL) printf("INTEL_MODEL_ALL"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_MIPS) { printf("MIPS"); printf("\nCPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_MIPS_ALL) printf("MIPS_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MIPS_R2300) printf("MIPS_R2300"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MIPS_R2600) printf("MIPS_R2600"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MIPS_R2800) printf("MIPS_R2800"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MIPS_R2000a) printf("MIPS_R2000a"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MIPS_R2000) printf("MIPS_R2000"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MIPS_R3000a) printf("MIPS_R3000a"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MIPS_R3000) printf("MIPS_R3000"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_MC98000) { printf("MC98000"); printf("\nCPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC98000_ALL) printf("MC98000_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC98601) printf("MC98601"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_HPPA) { printf("HPPA"); printf("\nCPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_HPPA_ALL) printf("HPPA_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_HPPA_7100) printf("HPPA_7100"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_HPPA_7100LC) printf("HPPA_7100LC"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_MC88000) { printf("MC88000"); printf("\nCPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC88000_ALL) printf("MC88000_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC88100) printf("MC88100"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_MC88110) printf("MC88110"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_SPARC) { printf("SPARC"); printf("\nCPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_SPARC_ALL) printf("SPARC_ALL"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_I860) { printf("I860"); printf("\nCPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_I860_ALL) printf("I860_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_I860_860) printf("I860_860"); else printf("unrecognized CPU subtype"); } else if (mach_hdr->cputype == CPU_TYPE_POWERPC) { printf("POWERPC"); printf("\nCPU subtype: "); if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_ALL) printf("POWERPC_ALL"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_601) printf("POWERPC_601"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_602) printf("POWERPC_602"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_603) printf("POWERPC_603"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_603e) printf("POWERPC_603e"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_603ev) printf("POWERPC_603ev"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_604) printf("POWERPC_604"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_604e) printf("POWERPC_604e"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_620) printf("POWERPC_620"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_750) printf("POWERPC_750"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_7400) printf("POWERPC_7400"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_7450) printf("POWERPC_7450"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_POWERPC_970) printf("POWERPC_970"); else printf("unrecognized CPU subtype"); } /* don't know what it is */ else printf("unrecognized CPU type"); printf("\n"); /* determine the general cpu subtype after arch speciffic */ printf("general CPU subtype:"); if (mach_hdr->cpusubtype == CPU_SUBTYPE_MULTIPLE) printf(" MULTIPLE"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_LITTLE_ENDIAN) printf(" LITTLE_ENDIAN"); else if (mach_hdr->cpusubtype == CPU_SUBTYPE_BIG_ENDIAN) printf(" BIG_ENDIAN"); else printf("unrecognized general CPU subtype"); printf("\n"); /* END: DETERMINE CPU SPECIFFICS */ /* file type determination section */ printf("File Type: "); if (mach_hdr->filetype == MH_OBJECT) printf("OBJECT"); else if (mach_hdr->filetype == MH_EXECUTE) printf("EXECUTE"); else if (mach_hdr->filetype == MH_FVMLIB) printf("FVMLIB"); else if (mach_hdr->filetype == MH_CORE) printf("CORE"); else if (mach_hdr->filetype == MH_PRELOAD) printf("PRELOAD"); else if (mach_hdr->filetype == MH_DYLIB) printf("DYLIB"); else if (mach_hdr->filetype == MH_DYLINKER) printf("DYLINKER"); else if (mach_hdr->filetype == MH_BUNDLE) printf("BUNDLE"); else if (mach_hdr->filetype == MH_DYLIB_STUB) printf("DYLIB_STUB"); else { printf("unknown file format! quitting...\n"); exit(1); } /* display the number of load commands */ printf("\nNumber of load commands: %ld", mach_hdr->ncmds); /* display the size of all the load commands */ printf("\nSize of all the commands: %ld", mach_hdr->sizeofcmds); /* determine the flags */ printf("\nFlags: "); printf("(%#lx) ", mach_hdr->flags); if ((mach_hdr->flags & MH_NOUNDEFS) == MH_NOUNDEFS) printf("NOUNDEFS "); if ((mach_hdr->flags & MH_INCRLINK) == MH_INCRLINK) printf("INCRLINK "); if ((mach_hdr->flags & MH_DYLDLINK) == MH_DYLDLINK) printf("DYLDLINK "); if ((mach_hdr->flags & MH_BINDATLOAD) == MH_BINDATLOAD) printf("BINDATLOAD "); if ((mach_hdr->flags & MH_PREBOUND) == MH_PREBOUND) printf("PREBOUND "); if ((mach_hdr->flags & MH_SPLIT_SEGS) == MH_SPLIT_SEGS) printf("SPLIT_SEGS "); if ((mach_hdr->flags & MH_LAZY_INIT) == MH_LAZY_INIT) printf("LAZY_INIT "); if ((mach_hdr->flags & MH_TWOLEVEL) == MH_TWOLEVEL) printf("TWOLEVEL "); if ((mach_hdr->flags & MH_FORCE_FLAT) == MH_FORCE_FLAT) printf("FORCE_FLAT "); if ((mach_hdr->flags & MH_NOMULTIDEFS) == MH_NOMULTIDEFS) printf("NOMULTIDEFS "); if ((mach_hdr->flags & MH_NOFIXPREBINDING) == MH_NOFIXPREBINDING) printf("NOFIXPREBINDING "); printf("\n"); printf("Size of mach_header: %#lx\n", sizeof(struct mach_header)); /* Set offset to facillitate the moving about the bin file */ int offset=offset+sizeof(struct mach_header); /* Use this variable to go along all the load commands locate d immediately after the header */ struct load_command *ldcmd; /* Determine the load_command mach-o/loader.h*/ int i; /* Go through each one and display properties */ for(i=1; i<=mach_hdr->ncmds; i++) { ldcmd = (struct load_command *) ((unsigned char *) &longarray[offset]); printf("\nLoad command: (%#lx) ", ldcmd->cmd); /* repetitive and not quite meaningful yet */ if (ldcmd->cmd == LC_SEGMENT) { printf("LC_SEGMENT"); struct segment_command *segment_cmd=(struct segment_command *) ((unsigned char *) \ &longarray[offset]); printf("\nSegment Name: %s\n", segment_cmd->segname); printf("Size of section structs: %#lx\n", segment_cmd->cmdsize); printf("Memory address of the segment: %#lx\n", segment_cmd->vmaddr); printf("Memory size of the segment: %#lx\n", segment_cmd->vmsize); printf("File offset of the segment: %#lx\n", segment_cmd->fileoff); printf("Ammount to map from the file: %#lx\n", segment_cmd->filesize); printf("Maximum VM protection: %#lx\n", segment_cmd->maxprot); printf("Initial VM protection: %#lx\n", segment_cmd->initprot); printf("Number of sections in the segment: %#lx\n", segment_cmd->nsects); printf("Flags: (%#lx)", segment_cmd->flags); if ((segment_cmd->flags & SG_HIGHVM) == SG_HIGHVM) printf("SG_HIGHVM"); if ((segment_cmd->flags & SG_HIGHVM) == SG_FVMLIB) printf("SG_FVMLIB"); if ((segment_cmd->flags & SG_NORELOC) == SG_NORELOC) printf("SG_NORELOC"); } else if (ldcmd->cmd == LC_SYMTAB) printf("LC_SYMTAB"); else if (ldcmd->cmd == LC_SYMSEG) printf("LC_SYMSEG"); /* the thread state ... hope this is meaningful*/ else if (ldcmd->cmd == LC_THREAD) { printf("LC_THREAD"); //struct thread_command *thread_cmd=(struct thread_command *) ((unsigned char *) \ &longarray[offset]); //printf("Command: %#lx\n", thread_cmd->cmd); //printf("Size of section structs: %#lx\n", thread_cmd->cmdsize); /* trying this the fake way :-) */ struct ppc_thread_state *thread_state=(struct ppc_thread_state *) ((unsigned char *) \ &longarray[offset+4*sizeof(unsigned long)]); /* print the register values when the processs terminated abnormally */ printf("\nsrr0: %#10x\t", thread_state->srr0); printf("srr1: %#10x\t", thread_state->srr1); printf("\nr0: %#12x\t ", thread_state->r0); printf("r1: %#12x\t ", thread_state->r1); printf("r2: %#12x\t ", thread_state->r2); printf("\nr3: %#12x\t ", thread_state->r3); printf("r4: %#12x\t ", thread_state->r4); printf("r5: %#12x\t ", thread_state->r5); printf("\nr6: %#12x\t ", thread_state->r6); printf("r7: %#12x\t ", thread_state->r7); printf("r8: %#12x\t ", thread_state->r8); printf("\nr9: %#12x\t ", thread_state->r9); printf("r10: %#11x\t ", thread_state->r10); printf("r11: %#11x\t ", thread_state->r11); printf("\nr12: %#11x\t ", thread_state->r12); printf("r13: %#11x\t ", thread_state->r13); printf("r14: %#11x\t ", thread_state->r14); printf("\nr15: %#11x\t ", thread_state->r15); printf("r16: %#11x\t ", thread_state->r16); printf("r17: %#11x\t ", thread_state->r17); printf("\nr18: %#11x\t ", thread_state->r18); printf("r19: %#11x\t ", thread_state->r19); printf("r20: %#11x\t ", thread_state->r20); printf("\nr21: %#11x\t ", thread_state->r21); printf("r22: %#11x\t ", thread_state->r22); printf("r23: %#11x\t ", thread_state->r23); printf("\nr24: %#11x\t ", thread_state->r24); printf("r25: %#11x\t ", thread_state->r25); printf("r26: %#11x\t ", thread_state->r26); printf("\nr27: %#11x\t ", thread_state->r27); printf("r28: %#11x\t ", thread_state->r28); printf("r29: %#11x\t ", thread_state->r29); printf("\nr30: %#11x\t ", thread_state->r30); printf("r31: %#11x\t ", thread_state->r31); printf("\ncr: %#12x\t ", thread_state->cr); printf("xer: %#11x\t ", thread_state->xer); printf("lr: %#12x\t ", thread_state->lr); printf("\nctr: %#11x\t ", thread_state->ctr); printf("mq: %#12x\t ", thread_state->mq); printf("vrsave: %#10x\n", thread_state->vrsave); } else if (ldcmd->cmd == LC_UNIXTHREAD) printf("LC_UNIXTHREAD"); else if (ldcmd->cmd == LC_LOADFVMLIB) printf("LC_LOADFVMLIB"); else if (ldcmd->cmd == LC_IDFVMLIB) printf("LC_IDFVMLIB"); else if (ldcmd->cmd == LC_IDENT) printf("LC_IDENT"); else if (ldcmd->cmd == LC_FVMFILE) printf("LC_FVMFILE"); else if (ldcmd->cmd == LC_PREPAGE) printf("LC_PREPAGE"); else if (ldcmd->cmd == LC_DYSYMTAB) printf("LC_DYSYMTAB"); else if (ldcmd->cmd == LC_LOAD_DYLIB) printf("LC_LOAD_DYLIB"); else if (ldcmd->cmd == LC_ID_DYLIB) printf("LC_ID_DYLIB"); else if (ldcmd->cmd == LC_LOAD_DYLINKER) printf("LC_LOAD_DYLINKER"); else if (ldcmd->cmd == LC_ID_DYLINKER) printf("LC_ID_DYLINKER"); else if (ldcmd->cmd == LC_PREBOUND_DYLIB) printf("LC_PREBOUND_DYLIB"); else if (ldcmd->cmd == LC_ROUTINES) printf("LC_ROUTINES"); else if (ldcmd->cmd == LC_SUB_FRAMEWORK) printf("LC_SUB_FRAMEWORK"); else if (ldcmd->cmd == LC_SUB_UMBRELLA) printf("LC_SUB_UMBRELLA"); else if (ldcmd->cmd == LC_SUB_CLIENT) printf("LC_SUB_CLIENT"); else if (ldcmd->cmd == LC_SUB_LIBRARY) printf("LC_SUB_LIBRARY"); else if (ldcmd->cmd == LC_TWOLEVEL_HINTS) printf("LC_TWOLEVEL_HINTS"); else if (ldcmd->cmd == LC_PREBIND_CKSUM) printf("LC_PREBIND_CKSUM"); /* every other case */ else printf("Unknown"); printf("\n"); printf("Size: %#lx\n", ldcmd->cmdsize); printf("Located at offset: %#lx\n", offset); offset=offset+ldcmd->cmdsize; } /* unmap the region of memory -- this segfaults */ // munmap(&longarray, statbuf.st_size); // fpe at the following line ???!!! printf("\n"); exit(0); }