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

  1. head     1.5;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ediger:1.5;
  6. comment  @@;
  7.  
  8.  
  9. 1.5
  10. date     94.05.28.16.17.33;  author ediger;  state Exp;
  11. branches ;
  12. next     1.4;
  13.  
  14. 1.4
  15. date     94.05.26.21.47.00;  author ediger;  state Exp;
  16. branches ;
  17. next     1.3;
  18.  
  19. 1.3
  20. date     94.01.30.16.26.43;  author ediger;  state Exp;
  21. branches ;
  22. next     1.2;
  23.  
  24. 1.2
  25. date     93.10.27.23.43.08;  author ediger;  state Exp;
  26. branches ;
  27. next     1.1;
  28.  
  29. 1.1
  30. date     93.10.25.17.59.22;  author ediger;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34.  
  35. desc
  36. @implementation of a toplevel/test driver program
  37. @
  38.  
  39.  
  40. 1.5
  41. log
  42. @updated usage() to reflect actual options
  43. @
  44. text
  45. @#import <MachOFile.h>
  46. #import <MappedFile.h>
  47. /*
  48.  * $Log:    MachO.m,v $
  49. Revision 1.4  94/05/26  21:47:00  ediger
  50. "productionized" it
  51.  
  52. Revision 1.1  94/02/19  14:29:20  ediger
  53. Initial revision
  54.  */
  55.  
  56. static char MachORcsIdent[] = "$Id: MachO.m,v 1.4 94/05/26 21:47:00 ediger Exp Locker: ediger $";
  57.  
  58. // deal with user preference in which way "low memory" is on the printed
  59. // page.
  60. enum direction {UP, DOWN};
  61.  
  62. void print_segments(id mach_o_file, enum direction, BOOL printsects);
  63. void print_threads(id oFile);
  64.  
  65. void do_cmd_line(int, char **);
  66.  
  67. // Option flags: global to avoid complicating do_cmd_line()
  68. BOOL gyPrintThreads   = FALSE;
  69. BOOL gyPrintSections  = FALSE;
  70. BOOL gyPrintSegmentsVerbose  = FALSE;
  71. BOOL gyPrintLibraries = FALSE;
  72. enum direction geDir = UP;
  73.  
  74.  
  75. void usage(char *);
  76.  
  77. int
  78. main(int ac, char **av)
  79. {
  80.     MachOFile  *oFile;
  81.     MappedFile *oMap;
  82.     char       *bpFileName = NULL;
  83. #ifdef MALLOCDEBUGGING
  84.     char buf[256];
  85. #endif
  86.  
  87.     do_cmd_line(ac, av);
  88.  
  89. #ifdef MALLOCDEBUGGING
  90.     puts("Hit return to continue...");
  91.     gets(buf);
  92. #endif
  93.  
  94.     bpFileName = av[optind];
  95.  
  96.     if (bpFileName == NULL)
  97.     {
  98.         fprintf(stderr, "Specify file name on command line.\n");
  99.         usage(*av);
  100.         exit(9);
  101.     }
  102.  
  103.     oFile = [[MachOFile alloc] init];
  104.  
  105.     oMap = [[[MappedFile alloc] init] filename:bpFileName];
  106.     if ([oMap map] == FALSE)
  107.     {
  108.         fprintf(stderr, "Trouble mapping \"%s\": %s\n",
  109.             bpFileName, [oMap errorString]);
  110.         [oFile free];
  111.         exit(1);
  112.     }
  113.  
  114.     if (gyPrintLibraries == TRUE)
  115.         [oFile considerMappedFiles];
  116.  
  117.     if([oFile fillFromAddress:[oMap address]] == NULL)
  118.     {
  119.         fprintf(stderr, "\"%s\" is probably not a Mach-O file\n",
  120.             bpFileName);
  121.         exit(9);
  122.     }
  123.  
  124.     if (gyPrintThreads == TRUE)
  125.         print_threads(oFile);
  126.  
  127.     print_segments(oFile, geDir, gyPrintSections);
  128.  
  129.     [oFile free];
  130.     [oMap  free];
  131.  
  132. #ifdef MALLOCDEBUGGING
  133.     puts("Hit return to finish...");
  134.     gets(buf);
  135. #endif
  136.  
  137.     return 0;
  138. }
  139.  
  140. void
  141. print_threads(oFile)
  142.     id oFile;
  143. {
  144.     int iThreads, iCC;
  145.  
  146.     iThreads = [oFile threads];
  147.  
  148.     for (iCC = 0; iCC < iThreads; ++iCC)
  149.     {    id            oThread = [oFile thread:iCC];
  150.         unsigned long ulAddr = [oThread pc];
  151.  
  152.         printf("Thread's pc: 0x%lx\n", ulAddr);
  153.     }
  154. }
  155.  
  156. void
  157. print_segments(oFile, eDirection, ySections)
  158.     id   oFile;
  159.     enum direction eDirection;
  160.     BOOL ySections;
  161. {
  162.     int iSegments, iCC;
  163.     int iFrom, iTo, iIncr;
  164.  
  165.     iSegments = [oFile mappedSegments];
  166.  
  167.     if (eDirection == UP)
  168.     {
  169.         iFrom = 0;
  170.         iTo   = iSegments;
  171.         iIncr = 1;
  172.     } else {
  173.         iFrom = iSegments - 1;
  174.         iTo   = 0;
  175.         iIncr = -1;
  176.     }
  177.  
  178.     for (iCC = iFrom; eDirection == UP ? iCC < iTo : iCC >= iTo ; iCC += iIncr)
  179.     {    id  oSegment = [oFile mappedSegment:iCC];
  180.         int iSections;
  181.  
  182.         if (eDirection == DOWN)
  183.         {
  184.             printf("Segment 0x%lx => 0x%lx named \"%s\"\n",
  185.                 [oSegment getBaseAddress],
  186.                 [oSegment getUpperAddress],
  187.                 [oSegment commandName]);
  188.  
  189.             if (gyPrintSegmentsVerbose)
  190.             {
  191.                 struct segment_command *spSegCmd =
  192.                     (struct segment_command *)[oSegment loadCommandAddress];
  193.  
  194.                 printf("\tSegment at 0x%lx, size 0x%lx, offset in file 0x%lx, size 0x%lx\n",
  195.                     spSegCmd->vmaddr,
  196.                     spSegCmd->vmsize,
  197.                     spSegCmd->fileoff,
  198.                     spSegCmd->filesize);
  199.             }
  200.         }
  201.  
  202.         if (ySections == TRUE && (iSections = [oSegment numberOfSections]) > 0)
  203.         {    int iC;
  204.             int iInFrom, iInTo, iInIncr;
  205.  
  206.             if (eDirection == UP)
  207.             {
  208.                 iInFrom = iSections - 1;
  209.                 iInTo   = 0;
  210.                 iInIncr = -1;
  211.             } else {
  212.                 iInFrom = 0;
  213.                 iInTo   = iSections;
  214.                 iInIncr = 1;
  215.             }
  216.  
  217.             for (iC = iInFrom; eDirection == UP ? iC >= iInTo : iC < iInTo;
  218.                 iC += iInIncr)
  219.             {    struct section *sect = [oSegment getSection:iC];
  220.                 printf("\t%s in seg %s - 0x%lx, %lu bytes\n",
  221.                     sect->sectname, sect->segname,
  222.                     sect->addr, sect->size);
  223.             }
  224.         }
  225.  
  226.         if (eDirection == UP)
  227.         {
  228.             printf("Segment 0x%lx => 0x%lx named \"%s\"\n",
  229.                 [oSegment getBaseAddress],
  230.                 [oSegment getUpperAddress],
  231.                 [oSegment commandName]);
  232.  
  233.             if (gyPrintSegmentsVerbose)
  234.             {
  235.                 struct segment_command *spSegCmd =
  236.                     (struct segment_command *)[oSegment loadCommandAddress];
  237.  
  238.                 printf("\tSegment at 0x%lx, size 0x%lx, offset in file 0x%lx, size 0x%lx\n",
  239.                     spSegCmd->vmaddr,
  240.                     spSegCmd->vmsize,
  241.                     spSegCmd->fileoff,
  242.                     spSegCmd->filesize);
  243.             }
  244.         }
  245.     }
  246.  
  247.     return;
  248. }
  249.  
  250. void
  251. usage(char *abpProgName)
  252. {
  253.     fprintf(stderr, "Usage: %s <options> filename\n", abpProgName);
  254.     fprintf(stderr, "-t   print thread info\n");
  255.     fprintf(stderr, "-s   print info for sections of segments\n");
  256.     fprintf(stderr, "-v   print info for sections of segments verbosely\n");
  257.     fprintf(stderr, "-l   print info for segments of shared libraries used\n");
  258. }
  259.  
  260. extern char *optarg;
  261. extern int   optind;
  262.  
  263. void
  264. do_cmd_line(int ac, char **av)
  265. {
  266.     int iOption;
  267.  
  268.     while ((iOption = getopt(ac, av, "vdtsl")) != EOF)
  269.         switch (iOption)
  270.         {
  271.         case 't': gyPrintThreads         = TRUE;  break;
  272.         case 's': gyPrintSections        = TRUE; break;
  273.         case 'l': gyPrintLibraries       = TRUE; break;
  274.         case 'v': gyPrintSegmentsVerbose = TRUE; break;
  275.         case 'd': geDir                  = DOWN; break;
  276.         default:
  277.             usage(*av);
  278.             exit(9);
  279.             break;
  280.         }
  281. }
  282. @
  283.  
  284.  
  285. 1.4
  286. log
  287. @"productionized" it
  288. @
  289. text
  290. @d5 3
  291. d12 1
  292. a12 1
  293. static char MachORcsIdent[] = "$Id: MachO.m,v 1.1 94/02/19 14:29:20 ediger Exp Locker: ediger $";
  294. d212 1
  295. @
  296.  
  297.  
  298. 1.3
  299. log
  300. @add thread pc stuff
  301. @
  302. text
  303. @d2 1
  304. d5 2
  305. a6 4
  306. Revision 1.2  93/10/27  23:43:08  ediger
  307. Used instance methods of MachOFile to implement -printSegments outside
  308. of the object itself.
  309.  
  310. d9 1
  311. a9 1
  312. static char rcsident[] = "$Id: MachO.m,v 1.2 93/10/27 23:43:08 ediger Exp Locker: ediger $";
  313. d11 3
  314. a13 1
  315. void print_segments(id mach_o_file);
  316. d15 15
  317. d33 4
  318. a36 1
  319.     MachOFile *oFile;
  320. d38 1
  321. d40 3
  322. d45 1
  323. d47 9
  324. d58 8
  325. a65 1
  326.     [oFile considerMappedFiles];
  327. d67 2
  328. a68 1
  329.     [oFile fillFromFileNamed:av[1]];
  330. d70 6
  331. a75 1
  332.     print_threads(oFile);
  333. d77 2
  334. a78 1
  335.     print_segments(oFile);
  336. d80 2
  337. d83 1
  338. d85 1
  339. d88 1
  340. d110 4
  341. a113 2
  342. print_segments(oFile)
  343.     id oFile;
  344. d116 1
  345. d120 10
  346. a129 3
  347.     for (iCC = 0; iCC < iSegments; ++iCC)
  348.     {    id              oSegment = [oFile mappedSegment:iCC];
  349.         int             iSections;
  350. d131 3
  351. a133 2
  352.         if ((iSections = [oSegment numberOfSections]) > 0)
  353.         {    int             iC;
  354. d135 37
  355. a171 1
  356.             for (iC = 0; iC < iSections; ++iC)
  357. d179 19
  358. a197 4
  359.         printf("Segment 0x%lx => 0x%lx named \"%s\"\n",
  360.             [oSegment getBaseAddress],
  361.             [oSegment getUpperAddress],
  362.             [oSegment commandName]);
  363. d201 32
  364. @
  365.  
  366.  
  367. 1.2
  368. log
  369. @Used instance methods of MachOFile to implement -printSegments outside
  370. of the object itself.
  371. @
  372. text
  373. @d3 5
  374. a7 1
  375.  * $Log$
  376. d10 1
  377. a10 1
  378. static char rcsident[] = "$Id$";
  379. d18 1
  380. d20 2
  381. a21 1
  382.     oFile = [MachOFile new];
  383. d23 2
  384. d27 1
  385. a27 1
  386.     [oFile initFromFile: av[1]];
  387. d29 2
  388. d35 3
  389. d42 16
  390. d80 4
  391. a83 2
  392.         printf("Segment with base address 0x%lx named \"%s\"\n",
  393.             [oSegment getBaseAddress], [oSegment commandName]);
  394. @
  395.  
  396.  
  397. 1.1
  398. log
  399. @Initial revision
  400. @
  401. text
  402. @d2 3
  403. d6 5
  404. d17 2
  405. d21 1
  406. a21 1
  407.     [oFile printSegments];
  408. d24 32
  409. @
  410.