home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Apps / DevTools / MachOViewer / Source / MachO.m < prev    next >
Encoding:
Text File  |  1994-05-28  |  4.9 KB  |  241 lines

  1. #import <MachOFile.h>
  2. #import <MappedFile.h>
  3. /*
  4.  * $Log:    MachO.m,v $
  5. Revision 1.5  94/05/28  16:17:33  ediger
  6. updated usage() to reflect actual options
  7.  
  8. Revision 1.4  94/05/26  21:47:00  ediger
  9. "productionized" it
  10.  
  11. Revision 1.1  94/02/19  14:29:20  ediger
  12. Initial revision
  13.  */
  14.  
  15. static char MachORcsIdent[] = "$Id: MachO.m,v 1.5 94/05/28 16:17:33 ediger Exp Locker: ediger $";
  16.  
  17. // deal with user preference in which way "low memory" is on the printed
  18. // page.
  19. enum direction {UP, DOWN};
  20.  
  21. void print_segments(id mach_o_file, enum direction, BOOL printsects);
  22. void print_threads(id oFile);
  23.  
  24. void do_cmd_line(int, char **);
  25.  
  26. // Option flags: global to avoid complicating do_cmd_line()
  27. BOOL gyPrintThreads   = FALSE;
  28. BOOL gyPrintSections  = FALSE;
  29. BOOL gyPrintSegmentsVerbose  = FALSE;
  30. BOOL gyPrintLibraries = FALSE;
  31. enum direction geDir = UP;
  32.  
  33.  
  34. void usage(char *);
  35.  
  36. int
  37. main(int ac, char **av)
  38. {
  39.     MachOFile  *oFile;
  40.     MappedFile *oMap;
  41.     char       *bpFileName = NULL;
  42. #ifdef MALLOCDEBUGGING
  43.     char buf[256];
  44. #endif
  45.  
  46.     do_cmd_line(ac, av);
  47.  
  48. #ifdef MALLOCDEBUGGING
  49.     puts("Hit return to continue...");
  50.     gets(buf);
  51. #endif
  52.  
  53.     bpFileName = av[optind];
  54.  
  55.     if (bpFileName == NULL)
  56.     {
  57.         fprintf(stderr, "Specify file name on command line.\n");
  58.         usage(*av);
  59.         exit(9);
  60.     }
  61.  
  62.     oFile = [[MachOFile alloc] init];
  63.  
  64.     oMap = [[[MappedFile alloc] init] filename:bpFileName];
  65.     if ([oMap map] == FALSE)
  66.     {
  67.         fprintf(stderr, "Trouble mapping \"%s\": %s\n",
  68.             bpFileName, [oMap errorString]);
  69.         [oFile free];
  70.         exit(1);
  71.     }
  72.  
  73.     if (gyPrintLibraries == TRUE)
  74.         [oFile considerMappedFiles];
  75.  
  76.     if([oFile fillFromAddress:[oMap address]] == NULL)
  77.     {
  78.         fprintf(stderr, "\"%s\" is probably not a Mach-O file\n",
  79.             bpFileName);
  80.         exit(9);
  81.     }
  82.  
  83.     if (gyPrintThreads == TRUE)
  84.         print_threads(oFile);
  85.  
  86.     print_segments(oFile, geDir, gyPrintSections);
  87.  
  88.     [oFile free];
  89.     [oMap  free];
  90.  
  91. #ifdef MALLOCDEBUGGING
  92.     puts("Hit return to finish...");
  93.     gets(buf);
  94. #endif
  95.  
  96.     return 0;
  97. }
  98.  
  99. void
  100. print_threads(oFile)
  101.     id oFile;
  102. {
  103.     int iThreads, iCC;
  104.  
  105.     iThreads = [oFile threads];
  106.  
  107.     for (iCC = 0; iCC < iThreads; ++iCC)
  108.     {    id            oThread = [oFile thread:iCC];
  109.         unsigned long ulAddr = [oThread pc];
  110.  
  111.         printf("Thread's pc: 0x%lx\n", ulAddr);
  112.     }
  113. }
  114.  
  115. void
  116. print_segments(oFile, eDirection, ySections)
  117.     id   oFile;
  118.     enum direction eDirection;
  119.     BOOL ySections;
  120. {
  121.     int iSegments, iCC;
  122.     int iFrom, iTo, iIncr;
  123.  
  124.     iSegments = [oFile mappedSegments];
  125.  
  126.     if (eDirection == UP)
  127.     {
  128.         iFrom = 0;
  129.         iTo   = iSegments;
  130.         iIncr = 1;
  131.     } else {
  132.         iFrom = iSegments - 1;
  133.         iTo   = 0;
  134.         iIncr = -1;
  135.     }
  136.  
  137.     for (iCC = iFrom; eDirection == UP ? iCC < iTo : iCC >= iTo ; iCC += iIncr)
  138.     {    id  oSegment = [oFile mappedSegment:iCC];
  139.         int iSections;
  140.  
  141.         if (eDirection == DOWN)
  142.         {
  143.             printf("Segment 0x%lx => 0x%lx named \"%s\"\n",
  144.                 [oSegment getBaseAddress],
  145.                 [oSegment getUpperAddress],
  146.                 [oSegment commandName]);
  147.  
  148.             if (gyPrintSegmentsVerbose)
  149.             {
  150.                 struct segment_command *spSegCmd =
  151.                     (struct segment_command *)[oSegment loadCommandAddress];
  152.  
  153.                 printf("\tSegment at 0x%lx, size 0x%lx, offset in file 0x%lx, size 0x%lx\n",
  154.                     spSegCmd->vmaddr,
  155.                     spSegCmd->vmsize,
  156.                     spSegCmd->fileoff,
  157.                     spSegCmd->filesize);
  158.             }
  159.         }
  160.  
  161.         if (ySections == TRUE && (iSections = [oSegment numberOfSections]) > 0)
  162.         {    int iC;
  163.             int iInFrom, iInTo, iInIncr;
  164.  
  165.             if (eDirection == UP)
  166.             {
  167.                 iInFrom = iSections - 1;
  168.                 iInTo   = 0;
  169.                 iInIncr = -1;
  170.             } else {
  171.                 iInFrom = 0;
  172.                 iInTo   = iSections;
  173.                 iInIncr = 1;
  174.             }
  175.  
  176.             for (iC = iInFrom; eDirection == UP ? iC >= iInTo : iC < iInTo;
  177.                 iC += iInIncr)
  178.             {    struct section *sect = [oSegment getSection:iC];
  179.                 printf("\t%s in seg %s - 0x%lx, %lu bytes\n",
  180.                     sect->sectname, sect->segname,
  181.                     sect->addr, sect->size);
  182.             }
  183.         }
  184.  
  185.         if (eDirection == UP)
  186.         {
  187.             printf("Segment 0x%lx => 0x%lx named \"%s\"\n",
  188.                 [oSegment getBaseAddress],
  189.                 [oSegment getUpperAddress],
  190.                 [oSegment commandName]);
  191.  
  192.             if (gyPrintSegmentsVerbose)
  193.             {
  194.                 struct segment_command *spSegCmd =
  195.                     (struct segment_command *)[oSegment loadCommandAddress];
  196.  
  197.                 printf("\tSegment at 0x%lx, size 0x%lx, offset in file 0x%lx, size 0x%lx\n",
  198.                     spSegCmd->vmaddr,
  199.                     spSegCmd->vmsize,
  200.                     spSegCmd->fileoff,
  201.                     spSegCmd->filesize);
  202.             }
  203.         }
  204.     }
  205.  
  206.     return;
  207. }
  208.  
  209. void
  210. usage(char *abpProgName)
  211. {
  212.     fprintf(stderr, "Usage: %s <options> filename\n", abpProgName);
  213.     fprintf(stderr, "-t   print thread info\n");
  214.     fprintf(stderr, "-s   print info for sections of segments\n");
  215.     fprintf(stderr, "-v   print info for sections of segments verbosely\n");
  216.     fprintf(stderr, "-l   print info for segments of shared libraries used\n");
  217. }
  218.  
  219. extern char *optarg;
  220. extern int   optind;
  221.  
  222. void
  223. do_cmd_line(int ac, char **av)
  224. {
  225.     int iOption;
  226.  
  227.     while ((iOption = getopt(ac, av, "vdtsl")) != EOF)
  228.         switch (iOption)
  229.         {
  230.         case 't': gyPrintThreads         = TRUE;  break;
  231.         case 's': gyPrintSections        = TRUE; break;
  232.         case 'l': gyPrintLibraries       = TRUE; break;
  233.         case 'v': gyPrintSegmentsVerbose = TRUE; break;
  234.         case 'd': geDir                  = DOWN; break;
  235.         default:
  236.             usage(*av);
  237.             exit(9);
  238.             break;
  239.         }
  240. }
  241.