home *** CD-ROM | disk | FTP | other *** search
- #import <MachOFile.h>
- #import <MappedFile.h>
- /*
- * $Log: MachO.m,v $
- Revision 1.5 94/05/28 16:17:33 ediger
- updated usage() to reflect actual options
-
- Revision 1.4 94/05/26 21:47:00 ediger
- "productionized" it
-
- Revision 1.1 94/02/19 14:29:20 ediger
- Initial revision
- */
-
- static char MachORcsIdent[] = "$Id: MachO.m,v 1.5 94/05/28 16:17:33 ediger Exp Locker: ediger $";
-
- // deal with user preference in which way "low memory" is on the printed
- // page.
- enum direction {UP, DOWN};
-
- void print_segments(id mach_o_file, enum direction, BOOL printsects);
- void print_threads(id oFile);
-
- void do_cmd_line(int, char **);
-
- // Option flags: global to avoid complicating do_cmd_line()
- BOOL gyPrintThreads = FALSE;
- BOOL gyPrintSections = FALSE;
- BOOL gyPrintSegmentsVerbose = FALSE;
- BOOL gyPrintLibraries = FALSE;
- enum direction geDir = UP;
-
-
- void usage(char *);
-
- int
- main(int ac, char **av)
- {
- MachOFile *oFile;
- MappedFile *oMap;
- char *bpFileName = NULL;
- #ifdef MALLOCDEBUGGING
- char buf[256];
- #endif
-
- do_cmd_line(ac, av);
-
- #ifdef MALLOCDEBUGGING
- puts("Hit return to continue...");
- gets(buf);
- #endif
-
- bpFileName = av[optind];
-
- if (bpFileName == NULL)
- {
- fprintf(stderr, "Specify file name on command line.\n");
- usage(*av);
- exit(9);
- }
-
- oFile = [[MachOFile alloc] init];
-
- oMap = [[[MappedFile alloc] init] filename:bpFileName];
- if ([oMap map] == FALSE)
- {
- fprintf(stderr, "Trouble mapping \"%s\": %s\n",
- bpFileName, [oMap errorString]);
- [oFile free];
- exit(1);
- }
-
- if (gyPrintLibraries == TRUE)
- [oFile considerMappedFiles];
-
- if([oFile fillFromAddress:[oMap address]] == NULL)
- {
- fprintf(stderr, "\"%s\" is probably not a Mach-O file\n",
- bpFileName);
- exit(9);
- }
-
- if (gyPrintThreads == TRUE)
- print_threads(oFile);
-
- print_segments(oFile, geDir, gyPrintSections);
-
- [oFile free];
- [oMap free];
-
- #ifdef MALLOCDEBUGGING
- puts("Hit return to finish...");
- gets(buf);
- #endif
-
- return 0;
- }
-
- void
- print_threads(oFile)
- id oFile;
- {
- int iThreads, iCC;
-
- iThreads = [oFile threads];
-
- for (iCC = 0; iCC < iThreads; ++iCC)
- { id oThread = [oFile thread:iCC];
- unsigned long ulAddr = [oThread pc];
-
- printf("Thread's pc: 0x%lx\n", ulAddr);
- }
- }
-
- void
- print_segments(oFile, eDirection, ySections)
- id oFile;
- enum direction eDirection;
- BOOL ySections;
- {
- int iSegments, iCC;
- int iFrom, iTo, iIncr;
-
- iSegments = [oFile mappedSegments];
-
- if (eDirection == UP)
- {
- iFrom = 0;
- iTo = iSegments;
- iIncr = 1;
- } else {
- iFrom = iSegments - 1;
- iTo = 0;
- iIncr = -1;
- }
-
- for (iCC = iFrom; eDirection == UP ? iCC < iTo : iCC >= iTo ; iCC += iIncr)
- { id oSegment = [oFile mappedSegment:iCC];
- int iSections;
-
- if (eDirection == DOWN)
- {
- printf("Segment 0x%lx => 0x%lx named \"%s\"\n",
- [oSegment getBaseAddress],
- [oSegment getUpperAddress],
- [oSegment commandName]);
-
- if (gyPrintSegmentsVerbose)
- {
- struct segment_command *spSegCmd =
- (struct segment_command *)[oSegment loadCommandAddress];
-
- printf("\tSegment at 0x%lx, size 0x%lx, offset in file 0x%lx, size 0x%lx\n",
- spSegCmd->vmaddr,
- spSegCmd->vmsize,
- spSegCmd->fileoff,
- spSegCmd->filesize);
- }
- }
-
- if (ySections == TRUE && (iSections = [oSegment numberOfSections]) > 0)
- { int iC;
- int iInFrom, iInTo, iInIncr;
-
- if (eDirection == UP)
- {
- iInFrom = iSections - 1;
- iInTo = 0;
- iInIncr = -1;
- } else {
- iInFrom = 0;
- iInTo = iSections;
- iInIncr = 1;
- }
-
- for (iC = iInFrom; eDirection == UP ? iC >= iInTo : iC < iInTo;
- iC += iInIncr)
- { struct section *sect = [oSegment getSection:iC];
- printf("\t%s in seg %s - 0x%lx, %lu bytes\n",
- sect->sectname, sect->segname,
- sect->addr, sect->size);
- }
- }
-
- if (eDirection == UP)
- {
- printf("Segment 0x%lx => 0x%lx named \"%s\"\n",
- [oSegment getBaseAddress],
- [oSegment getUpperAddress],
- [oSegment commandName]);
-
- if (gyPrintSegmentsVerbose)
- {
- struct segment_command *spSegCmd =
- (struct segment_command *)[oSegment loadCommandAddress];
-
- printf("\tSegment at 0x%lx, size 0x%lx, offset in file 0x%lx, size 0x%lx\n",
- spSegCmd->vmaddr,
- spSegCmd->vmsize,
- spSegCmd->fileoff,
- spSegCmd->filesize);
- }
- }
- }
-
- return;
- }
-
- void
- usage(char *abpProgName)
- {
- fprintf(stderr, "Usage: %s <options> filename\n", abpProgName);
- fprintf(stderr, "-t print thread info\n");
- fprintf(stderr, "-s print info for sections of segments\n");
- fprintf(stderr, "-v print info for sections of segments verbosely\n");
- fprintf(stderr, "-l print info for segments of shared libraries used\n");
- }
-
- extern char *optarg;
- extern int optind;
-
- void
- do_cmd_line(int ac, char **av)
- {
- int iOption;
-
- while ((iOption = getopt(ac, av, "vdtsl")) != EOF)
- switch (iOption)
- {
- case 't': gyPrintThreads = TRUE; break;
- case 's': gyPrintSections = TRUE; break;
- case 'l': gyPrintLibraries = TRUE; break;
- case 'v': gyPrintSegmentsVerbose = TRUE; break;
- case 'd': geDir = DOWN; break;
- default:
- usage(*av);
- exit(9);
- break;
- }
- }
-