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

  1. head     1.12;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ediger:1.12;
  6. comment  @@;
  7.  
  8.  
  9. 1.12
  10. date     94.05.28.16.17.05;  author ediger;  state Exp;
  11. branches ;
  12. next     1.11;
  13.  
  14. 1.11
  15. date     94.01.30.16.25.39;  author ediger;  state Exp;
  16. branches ;
  17. next     1.10;
  18.  
  19. 1.10
  20. date     93.12.28.23.09.05;  author ediger;  state Exp;
  21. branches ;
  22. next     1.9;
  23.  
  24. 1.9
  25. date     93.12.28.23.07.40;  author ediger;  state Exp;
  26. branches ;
  27. next     1.8;
  28.  
  29. 1.8
  30. date     93.12.08.00.52.12;  author ediger;  state Exp;
  31. branches ;
  32. next     1.7;
  33.  
  34. 1.7
  35. date     93.12.02.00.45.36;  author ediger;  state Exp;
  36. branches ;
  37. next     1.6;
  38.  
  39. 1.6
  40. date     93.10.31.21.36.40;  author ediger;  state Exp;
  41. branches ;
  42. next     1.5;
  43.  
  44. 1.5
  45. date     93.10.31.16.47.01;  author ediger;  state Exp;
  46. branches ;
  47. next     1.4;
  48.  
  49. 1.4
  50. date     93.10.31.12.48.41;  author ediger;  state Exp;
  51. branches ;
  52. next     1.3;
  53.  
  54. 1.3
  55. date     93.10.28.00.07.08;  author ediger;  state Exp;
  56. branches ;
  57. next     1.2;
  58.  
  59. 1.2
  60. date     93.10.27.23.43.04;  author ediger;  state Exp;
  61. branches ;
  62. next     1.1;
  63.  
  64. 1.1
  65. date     93.10.25.17.59.06;  author ediger;  state Exp;
  66. branches ;
  67. next     ;
  68.  
  69.  
  70. desc
  71. @definition/implementation of LoadCommand object
  72. @
  73.  
  74.  
  75. 1.12
  76. log
  77. @added LoadCommand -getUpperAddress and - (struct load_command *)loadCommandAddress
  78. @
  79. text
  80. @#import <LoadCommand.h>
  81. /*
  82.  * $Log:    LoadCommand.m,v $
  83. Revision 1.11  94/01/30  16:25:39  ediger
  84. added working version of -(unsigned long)pc method
  85.  
  86. Revision 1.10  93/12/28  23:09:05  ediger
  87. removed printfs for memory leak checking.
  88.  
  89. Revision 1.9  93/12/28  23:07:40  ediger
  90. Fixed memory leak caused by sections instance var of SegmentCommand
  91. subclass not getting freed.  overrode -free method for that subclass.
  92. Left in the debug statements
  93.  
  94. Revision 1.8  93/12/08  00:52:12  ediger
  95. added some assert()s in accordance with new ideology
  96.  
  97. Revision 1.7  93/12/02  00:45:36  ediger
  98. fixed a renamed method (initFromFile: becomes initFromFileNamed:)
  99.  
  100. Revision 1.6  93/10/31  21:36:40  ediger
  101. changed initialization of new LoadCommand object from 'new'
  102. to 'alloc] init]'.
  103.  
  104. Revision 1.3  93/10/28  00:07:08  ediger
  105. correct a few typos, add better commentary
  106.  
  107. Revision 1.2  93/10/27  23:43:04  ediger
  108. changed to one subclass per type of load command
  109.  
  110.  */
  111.  
  112. @@implementation LoadCommand
  113.  
  114. static char rcsident[] = "@@(#) $Id: LoadCommand.m,v 1.11 94/01/30 16:25:39 ediger Exp Locker: ediger $";
  115.  
  116. //M+    LoadCommand +new
  117. //M-
  118. + new
  119. {
  120.     LoadCommand *oNew = [[LoadCommand alloc] init];
  121.     assert(oNew != NULL);
  122.     return oNew;
  123. }
  124.  
  125. //M+    LoadCommand +new:
  126. //        Accounts for cheesy polymorphism of Mach-O load commands.
  127. //        Each of them begins with a struct load_command, but
  128. //        a variable amount of stuff follows (and subsumes)
  129. //        each struct load_command.
  130. //M-
  131. + new: (caddr_t)loadCommandAddress;
  132. {
  133.     id oNew = Nil;
  134.     struct load_command *lc = (struct load_command *)loadCommandAddress;
  135.  
  136.     assert(NULL != loadCommandAddress);
  137.  
  138.     switch (lc->cmd)
  139.     {
  140.     case LC_SEGMENT:
  141.         oNew = [[SegmentCommand alloc] init];
  142.         break;
  143.     case LC_IDFVMLIB:
  144.         oNew = [[IdFVMLibCommand alloc] init];
  145.         break;
  146.     case LC_LOADFVMLIB:
  147.         oNew = [[LoadFVMLibCommand alloc] init];
  148.         break;
  149.     case LC_FVMFILE:
  150.         oNew = [[FVMFileCommand alloc] init];
  151.         break;
  152.     case LC_SYMTAB:
  153.         oNew = [[SymTabCommand alloc] init];
  154.         break;
  155.     case LC_SYMSEG:
  156.         oNew = [[SymSegCommand alloc] init];
  157.         break;
  158.     case LC_THREAD:
  159.         oNew = [[ThreadCommand alloc] init];
  160.         break;
  161.     case LC_UNIXTHREAD:
  162.         oNew = [[UnixThreadCommand alloc] init];
  163.         break;
  164.     case LC_IDENT:
  165.         oNew = [[IdentCommand alloc] init];
  166.         break;
  167.     default:
  168.         oNew = [[LoadCommand alloc] init];
  169.         break;
  170.     }
  171.  
  172.     assert(Nil != oNew);
  173.  
  174.     [oNew setLoadCommand:loadCommandAddress];
  175.  
  176.     if (lc->cmd == LC_SEGMENT)
  177.         [oNew fillSections];
  178.  
  179.     return oNew;
  180. }
  181.  
  182. //M+    LoadCommand -init
  183. // Assumes that "self" is already allocated.
  184. //M-
  185. - init
  186. {
  187.     [super init];
  188.     loadCommand = NULL;
  189.     mapped = FALSE;
  190.     otherFile = FALSE;
  191.     return self;
  192. }
  193.  
  194. //M+    LoadCommand -free
  195. //M-
  196. - free
  197. {
  198.     [super free];
  199.     return self;
  200. }
  201.  
  202. //M+    LoadCommand -setSegmentCommand
  203. //M-
  204. - setLoadCommand: (caddr_t)loadCommandAddress;
  205. {
  206.     assert(loadCommandAddress != NULL);
  207.     loadCommand = (struct load_command *)loadCommandAddress;
  208.     return self;
  209. }
  210.  
  211. //M+    LoadCommand -isMapped
  212. //        Does the object represent a memory-mapped piece
  213. //        of the file?  Probably not.
  214. //M-
  215. - (BOOL)isMapped
  216. {
  217.     return mapped;
  218. }
  219.  
  220. //M+    LoadCommand -isThread
  221. //        Does the object represent a thread of some sort.
  222. //        of the file?  Again, Probably not.
  223. //M-
  224. - (BOOL)isThread
  225. {
  226.     return FALSE;
  227. }
  228.  
  229. //M+    LoadCommand -representsMappedFile
  230. //        Does the object represent a load command
  231. //        that would end up causing some other file
  232. //        to be memory-mapped into the task's address
  233. //        space?
  234. //M-
  235. - (BOOL)representsMappedFile
  236. {
  237.     return otherFile;
  238. }
  239.  
  240.  
  241. //M+    LoadCommand -getBaseAddress
  242. //M-
  243. - (unsigned long)getBaseAddress
  244. {
  245.     return -1;
  246. }
  247.  
  248. //M+    LoadCommand -getUpperAddress
  249. //M-
  250. - (unsigned long)getUpperAddress
  251. {
  252.     return -1;
  253. }
  254.  
  255. //M+    LoadCommand -(unsigned long)commandSize
  256. //M-
  257. - (unsigned long)commandSize
  258. {
  259.     return loadCommand->cmdsize;
  260. }
  261.  
  262. //M+    LoadCommand -(char *)commandName
  263. //M-
  264. - (char *)commandName
  265. {
  266.     return "load command";
  267. }
  268.  
  269. //M+    LoadCommand - (int)numberOfSections
  270. //        Only struct segment_commands have sections,
  271. //        but it's handy to use this as a flag.
  272. //M-
  273. - (int)numberOfSections
  274. {
  275.     return 0;
  276. }
  277.  
  278. //M+    LoadCommand -struct load_command *)loadCommandAddress
  279. //M-
  280. - (struct load_command *)loadCommandAddress
  281. {
  282.     return loadCommand;
  283. }
  284.  
  285. @@end
  286.  
  287.  
  288. @@implementation SegmentCommand
  289.  
  290. //M+    SegmentCommand -init
  291. //M-
  292. - init
  293. {
  294.     [super init];
  295.     sections       = NULL;
  296.     segmentCommand = NULL;
  297.     mapped         = TRUE;  // struct segment_commands do map
  298.     return self;
  299. }
  300.  
  301. //M+    SegmentCommand -free
  302. //        Had to override so as to free sections instance var
  303. //M-
  304. - free
  305. {
  306.     if (NULL != sections)
  307.         free(sections);
  308.     [super free];
  309.     return self;
  310. }
  311.  
  312. //M+    SegmentCommand -fillSections
  313. //        Create a quick-to-access array of pointers to
  314. //        the struct sections in this load command.
  315. //M-
  316. - fillSections
  317. {
  318.     assert(segmentCommand != NULL);
  319.     sections
  320.          = (struct section **)malloc(
  321.             sizeof(struct section)*segmentCommand->nsects);
  322.  
  323.     if (sections != NULL)
  324.     {    int iCC;
  325.         struct section *spSection
  326.              = (struct section *)((unsigned long)segmentCommand
  327.                  + sizeof(struct segment_command));
  328.  
  329.         for (iCC = 0; iCC < segmentCommand->nsects; ++iCC)
  330.             sections[iCC] = spSection++;
  331.     }
  332.  
  333.     return self;
  334. }
  335.  
  336. //M+    SegmentCommand -getBaseAddress
  337. //M-
  338. - (unsigned long)getBaseAddress
  339. {
  340.     assert(segmentCommand != NULL);
  341.     return segmentCommand->vmaddr;
  342. }
  343.  
  344. //M+    SegmentCommand -getUpperAddress
  345. //M-
  346. - (unsigned long)getUpperAddress
  347. {
  348.     assert(segmentCommand != NULL);
  349.     return segmentCommand->vmaddr + segmentCommand->vmsize;
  350. }
  351.  
  352. //M+    SegmentCommand -setLoadCommand
  353. //M-
  354. - setLoadCommand: (caddr_t)loadCommandAddress;
  355. {
  356.     assert(loadCommandAddress != NULL);
  357.     [super setLoadCommand: loadCommandAddress];
  358.     segmentCommand = (struct segment_command *)loadCommandAddress;
  359.     return self;
  360. }
  361.  
  362.  
  363. //M+    SegmentCommand -(char *)commandName
  364. //M-
  365. - (char *)commandName
  366. {
  367.     assert(segmentCommand != NULL);
  368.     if (segmentCommand->segname == NULL || strlen(segmentCommand->segname) <= 0)
  369.         return "LC_SEGMENT";  // relocatable object files?
  370.     else
  371.         return segmentCommand->segname;
  372. }
  373.  
  374. //M+    SegmentCommand -numberOfSections
  375. //M-
  376. - (int)numberOfSections
  377. {
  378.     assert(segmentCommand != NULL);
  379.     return segmentCommand->nsects;
  380. }
  381.  
  382.  
  383. //M+    SegmentCommand -(struct section *)getSection:(int)sectionNumber
  384. //M-
  385. - (struct section *)getSection:(int)sectionNumber
  386. {
  387.     assert(segmentCommand != NULL);
  388.     if (sections != NULL && sectionNumber < segmentCommand->nsects)
  389.         return sections[sectionNumber];
  390.  
  391.     return NULL;
  392. }
  393.  
  394. @@end
  395.  
  396. @@implementation LoadFVMLibCommand
  397.  
  398. //M+    LoadFVMLibCommand -init
  399. //M-
  400. - init
  401. {
  402.     [super init];
  403.     fvmlibCommand = NULL;
  404.     mapped = FALSE;
  405.     otherFile = TRUE;
  406.     theOtherFile = Nil;
  407.     return self;
  408. }
  409.  
  410. //M+    LoadFVMLibCommand -getBaseAddress
  411. //M-
  412. - (unsigned long)getBaseAddress
  413. {
  414.     assert(fvmlibCommand != NULL);
  415.     return fvmlibCommand->fvmlib.header_addr;
  416. }
  417.  
  418. //M+    LoadFVMLibCommand -setLoadCommand
  419. //M-
  420. - setLoadCommand: (caddr_t)loadCommandAddress;
  421. {
  422.     assert(loadCommandAddress != NULL);
  423.     [super setLoadCommand: loadCommandAddress];
  424.     fvmlibCommand = (struct fvmlib_command *)loadCommandAddress;
  425.     return self;
  426. }
  427.  
  428. //M+    LoadFVMLibCommand -(char *)commandName
  429. //M-
  430. - (char *)commandName
  431. {
  432.     assert(fvmlibCommand != NULL);
  433.     return (char *)((unsigned long)fvmlibCommand
  434.             + fvmlibCommand->fvmlib.name.offset);
  435. }
  436.  
  437. //M+    LoadFVMLibCommand -loadOtherFile
  438. //M-
  439. - loadOtherFile
  440. {
  441.     if (fvmlibCommand != NULL)
  442.     {    theOtherFile = [[MachOFile alloc] init];
  443.         [theOtherFile fillFromFileNamed:[self commandName]];
  444.     }
  445.  
  446.     return self;
  447. }
  448.  
  449. //M+    LoadFVMLibCommand -otherFile
  450. //M-
  451. - otherFile
  452. {
  453.     return theOtherFile;
  454. }
  455.  
  456. //M+    LoadFVMLibCommand -free
  457. //        Had to override this to ditch any other mapped files. 
  458. //M-
  459. - free
  460. {
  461.     if (theOtherFile != Nil)
  462.         [theOtherFile free];
  463.  
  464.     [super free];
  465.  
  466.     return self;
  467. }
  468.  
  469. @@end
  470.  
  471. @@implementation IdFVMLibCommand
  472.  
  473. //M+    IdFVMLibCommand -init
  474. //M-
  475. - init
  476. {
  477.     [super init];
  478.     namebuf = NULL;
  479.     mapped = FALSE;
  480.     return self;
  481. }
  482.  
  483. //M+    IdFVMLibCommand -commandName
  484. //        This is cheesy, but it separates the ident sections from
  485. //        the mapped sections.
  486. //M-
  487. - (char *)commandName
  488. {
  489.     char *filename;
  490. #define IDENT_PHRASE "FVM Lib ident: "
  491.  
  492.     if (namebuf != NULL)
  493.         free(namebuf);
  494.  
  495.     filename = [super commandName];
  496.  
  497.     namebuf = malloc(strlen(filename) + strlen(IDENT_PHRASE) + 1);
  498.  
  499.     if (namebuf != NULL)
  500.         strcat(strcpy(namebuf, IDENT_PHRASE), filename);
  501.  
  502.     return namebuf;
  503. }
  504.  
  505. //M+    IdFVMLibCommand -free
  506. //        Possibly this object has allocated some memory for its
  507. //        own purposes.  Free it.
  508. //M-
  509. - free
  510. {
  511.     if (namebuf != NULL)
  512.         free(namebuf);
  513.  
  514.     [super free];
  515.  
  516.     return self;
  517. }
  518.  
  519. @@end
  520.  
  521. @@implementation FVMFileCommand
  522.  
  523. //M+    FVMFileCommand -init
  524. /*
  525.  * The fvmfile_command contains a reference to a file to be loaded at the
  526.  * specified virtual address.  (Presently, this command is reserved for NeXT
  527.  * internal use.  The kernel ignores this command when loading a program into
  528.  * memory).
  529.  */
  530. //M-
  531. - init
  532. {
  533.     [super init];
  534.     mapped = TRUE;
  535.     return self;
  536. }
  537.  
  538. //M+    FVMFileCommand -getBaseAddress
  539. //M-
  540. - (unsigned long)getBaseAddress
  541. {
  542.     assert(fvmFileCommand != NULL);
  543.     return fvmFileCommand->header_addr;  // address of FVM file's header
  544. }
  545.  
  546. //M+    FVMFileCommand -setLoadCommand
  547. //M-
  548. - setLoadCommand: (caddr_t)loadCommandAddress;
  549. {
  550.     assert(loadCommandAddress != NULL);
  551.     [super setLoadCommand: loadCommandAddress];
  552.     fvmFileCommand = (struct fvmfile_command *)loadCommandAddress;
  553.     return self;
  554. }
  555.  
  556. //M+    FVMFileCommand -(char *)commandName
  557. //M-
  558. - (char *)commandName
  559. {
  560.     assert(fvmFileCommand != NULL);
  561.     return (char *)((unsigned long)fvmFileCommand
  562.             + fvmFileCommand->name.offset);
  563. }
  564.  
  565. @@end
  566.  
  567. @@implementation SymTabCommand
  568.  
  569. //M+    SymTabCommand -init
  570. //M-
  571. - init
  572. {
  573.     [super init];
  574.     mapped = FALSE;
  575.     return self;
  576. }
  577.  
  578. //M+    SymTabCommand -setLoadCommand
  579. //M-
  580. - setLoadCommand: (caddr_t)loadCommandAddress;
  581. {
  582.     [super setLoadCommand: loadCommandAddress];
  583.     symTabCommand = (struct symtab_command *)loadCommandAddress;
  584.     return self;
  585. }
  586.  
  587. //M+    SymTabCommand -(char *)commandName
  588. //M-
  589. - (char *)commandName
  590. {
  591.     return "LC_SYMTAB";
  592. }
  593. @@end
  594.  
  595. @@implementation SymSegCommand
  596.  
  597. //M+    SymSegCommand -init
  598. //M-
  599. - init
  600. {
  601.     [super init];
  602.     mapped = FALSE;
  603.     return self;
  604. }
  605.  
  606. //M+    SymSegCommand -setLoadCommand
  607. //M-
  608. - setLoadCommand: (caddr_t)loadCommandAddress;
  609. {
  610.     assert(loadCommandAddress != NULL);
  611.     [super setLoadCommand: loadCommandAddress];
  612.     symSegCommand = (struct symseg_command *)loadCommandAddress;
  613.     return self;
  614. }
  615.  
  616. //M+    SymSegCommand -(char *)commandName
  617. //M-
  618. - (char *)commandName
  619. {
  620.     return "LC_SYMSEG";
  621. }
  622. @@end
  623.  
  624. @@implementation ThreadCommand
  625. //M+    ThreadCommand +new
  626.  
  627. //M+    ThreadCommand -init
  628. //M-
  629. - init
  630. {
  631.     [super init];
  632.     mapped = FALSE;
  633.     return self;
  634. }
  635.  
  636. //M+    ThreadCommand -setLoadCommand
  637. //M-
  638. - setLoadCommand: (caddr_t)loadCommandAddress;
  639. {
  640.     assert(loadCommandAddress != NULL);
  641.     [super setLoadCommand: loadCommandAddress];
  642.     threadCommand = (struct thread_command *)loadCommandAddress;
  643.     return self;
  644. }
  645.  
  646. //M+    ThreadCommand -(char *)commandName
  647. //M-
  648. - (char *)commandName
  649. {
  650.     return "LC_THREAD";
  651. }
  652.  
  653. //M+    ThreadCommand -(BOOL)isThread
  654. //M-
  655. - (BOOL)isThread
  656. {
  657.     return TRUE;
  658. }
  659.  
  660. - (unsigned long)pc
  661. {
  662.     struct thread_state_flavor *spThreadStateFlavor;
  663.     unsigned long               lNextAddress;
  664.     unsigned int irPC = -1;
  665.  
  666.     spThreadStateFlavor =
  667.      (struct thread_state_flavor *)((unsigned long)threadCommand
  668.         + sizeof(struct thread_command));
  669.  
  670.     lNextAddress = (unsigned long)spThreadStateFlavor
  671.         + sizeof(struct thread_state_flavor);
  672.  
  673.     switch(spThreadStateFlavor->flavor)
  674.     {
  675.     case M68K_THREAD_STATE_REGS:
  676.         irPC = ((struct m68k_thread_state_regs *)lNextAddress)->pc;
  677.         break;
  678.     case M68K_THREAD_STATE_68882:
  679.         irPC = ((struct m68k_thread_state_68882 *)lNextAddress)->iar;
  680.         break;
  681.     case M68K_THREAD_STATE_USER_REG:
  682.         irPC = ((struct m68k_thread_state_user_reg *)lNextAddress)->user_reg;
  683.         break;
  684.     case i386_THREAD_STATE:
  685.         irPC = ((i386_thread_state_t *)lNextAddress)->eip;
  686.         break;
  687.     }
  688.      
  689.     return irPC;
  690. }
  691.  
  692. @@end
  693.  
  694. @@implementation UnixThreadCommand
  695.  
  696. //M+    UnixThreadCommand -(char *)commandName
  697. //M-
  698. - (char *)commandName
  699. {
  700.     return "LC_UNIXTHREAD";
  701. }
  702.  
  703. @@end
  704.  
  705. @@implementation IdentCommand
  706.  
  707. //M+    IdentCommand -(char *)commandName
  708. //M-
  709. - (char *)commandName
  710. {
  711.     return "LC_IDENT";
  712. }
  713. @@end
  714. @
  715.  
  716.  
  717. 1.11
  718. log
  719. @added working version of -(unsigned long)pc method
  720. @
  721. text
  722. @d4 3
  723. d35 1
  724. a35 1
  725. static char rcsident[] = "@@(#) $Id: LoadCommand.m,v 1.10 93/12/28 23:09:05 ediger Exp Locker: ediger $";
  726. d169 7
  727. d198 9
  728. @
  729.  
  730.  
  731. 1.10
  732. log
  733. @removed printfs for memory leak checking.
  734. @
  735. text
  736. @d4 3
  737. d32 1
  738. a32 1
  739. static char rcsident[] = "@@(#) $Id: LoadCommand.m,v 1.9 93/12/28 23:07:40 ediger Exp Locker: ediger $";
  740. d138 9
  741. d554 40
  742. d604 1
  743. @
  744.  
  745.  
  746. 1.9
  747. log
  748. @Fixed memory leak caused by sections instance var of SegmentCommand
  749. subclass not getting freed.  overrode -free method for that subclass.
  750. Left in the debug statements
  751. @
  752. text
  753. @d4 5
  754. d29 1
  755. a29 1
  756. static char rcsident[] = "@@(#) $Id: LoadCommand.m,v 1.8 93/12/08 00:52:12 ediger Exp Locker: ediger $";
  757. a88 3
  758.     printf("LoadCommand +new:0x%x => 0x%x\n", loadCommandAddress,
  759.         oNew);
  760.  
  761. a101 1
  762.     printf("LoadCommand -init 0x%lx\n", self);
  763. a112 1
  764.     printf("LoadCommand -free 0x%lx\n", (unsigned long)self);
  765. a183 1
  766.     printf("SegmentCommand -init 0x%lx\n", self);
  767. a211 1
  768.     printf("SegmentCommand - fillSections, 0x%x\n", sections);
  769. a291 1
  770.     printf("LoadFVMLibCommand -init 0x%lx\n", self);
  771. a366 1
  772.     printf("IdFVMLibCommand -init 0x%lx\n", self);
  773. a422 1
  774.     printf("FVMFileCommand -init 0x%lx\n", self);
  775. a462 1
  776.     printf("SymTabCommand -init 0x%lx\n", self);
  777. a490 1
  778.     printf("SymSegCommand -init 0x%lx\n", self);
  779. a520 1
  780.     printf("ThreadCommand -init 0x%lx\n", self);
  781. @
  782.  
  783.  
  784. 1.8
  785. log
  786. @added some assert()s in accordance with new ideology
  787. @
  788. text
  789. @d4 3
  790. d24 1
  791. a24 1
  792. static char rcsident[] = "@@(#) $Id: LoadCommand.m,v 1.7 93/12/02 00:45:36 ediger Exp Locker: ediger $";
  793. d84 3
  794. d100 1
  795. d112 1
  796. d184 1
  797. d192 11
  798. d213 1
  799. d294 1
  800. d336 1
  801. a336 1
  802.         [theOtherFile initFromFileNamed:[self commandName]];
  803. d370 1
  804. d427 1
  805. d468 1
  806. d497 1
  807. d528 1
  808. @
  809.  
  810.  
  811. 1.7
  812. log
  813. @fixed a renamed method (initFromFile: becomes initFromFileNamed:)
  814. @
  815. text
  816. @d4 3
  817. d21 1
  818. a21 1
  819. static char rcsident[] = "@@(#) $Id: LoadCommand.m,v 1.6 93/10/31 21:36:40 ediger Exp Locker: ediger $";
  820. d28 1
  821. d43 2
  822. d79 2
  823. d113 1
  824. d189 1
  825. d211 1
  826. d219 1
  827. d227 1
  828. d238 1
  829. d249 1
  830. d258 1
  831. d285 1
  832. d293 1
  833. d303 1
  834. d413 1
  835. d421 1
  836. d431 1
  837. d481 1
  838. d511 1
  839. @
  840.  
  841.  
  842. 1.6
  843. log
  844. @changed initialization of new LoadCommand object from 'new'
  845. to 'alloc] init]'.
  846. @
  847. text
  848. @d4 4
  849. d18 1
  850. a18 1
  851. static char rcsident[] = "@@(#) $Id: LoadCommand.m,v 1.3 93/10/28 00:07:08 ediger Exp Locker: ediger $";
  852. d295 1
  853. a295 1
  854.         [theOtherFile initFromFile:[self commandName]];
  855. @
  856.  
  857.  
  858. 1.5
  859. log
  860. @ditched '+new' methods for all LoadCommand subclasses.  They were dead weight anyway.
  861. @
  862. text
  863. @d65 1
  864. a65 1
  865.         oNew = [LoadCommand new];
  866. @
  867.  
  868.  
  869. 1.4
  870. log
  871. @some assorted tiny typo corrections
  872. @
  873. text
  874. @d33 1
  875. a33 1
  876.     struct load_command *spLC = (struct load_command *)loadCommandAddress;
  877. d35 1
  878. a35 1
  879.     switch (spLC->cmd)
  880. d38 1
  881. a38 1
  882.         oNew = [SegmentCommand new];
  883. d41 1
  884. a41 1
  885.         oNew = [IdFVMLibCommand new];
  886. d44 1
  887. a44 1
  888.         oNew = [LoadFVMLibCommand new];
  889. d47 1
  890. a47 1
  891.         oNew = [FVMFileCommand new];
  892. d50 1
  893. a50 1
  894.         oNew = [SymTabCommand new];
  895. d53 1
  896. a53 1
  897.         oNew = [SymSegCommand new];
  898. d56 1
  899. a56 1
  900.         oNew = [ThreadCommand new];
  901. d59 1
  902. a59 1
  903.         oNew = [UnixThreadCommand new];
  904. d62 1
  905. a62 1
  906.         oNew = [IdentCommand new];
  907. d71 1
  908. a71 1
  909.     if (spLC->cmd == LC_SEGMENT)
  910. a158 8
  911. //M+    SegmentCommand +new
  912. //M-
  913. + new
  914. {
  915.     SegmentCommand *oNew = [[SegmentCommand alloc] init];
  916.     return oNew;
  917. }
  918.  
  919. a192 20
  920.  
  921. #ifdef DOO_DOO
  922. //M+    SegmentCommand -printSections
  923. //M-
  924. - printSections
  925. {
  926.     if (sections != NULL)
  927.     {    int iCC;
  928.         for (iCC = segmentCommand->nsects - 1; iCC >= 0; --iCC)
  929.         {
  930.             printf("\t%s in seg %s - 0x%lx, %lu bytes\n",
  931.                 sections[iCC]->sectname, sections[iCC]->segname,
  932.                 sections[iCC]->addr, sections[iCC]->size);
  933.         }
  934.     }
  935.  
  936.     return self;
  937. }
  938. #endif
  939.  
  940. a248 8
  941. //M+    LoadFVMLibCommand +new
  942. //M-
  943. + new
  944. {
  945.     LoadFVMLibCommand *oNew = [[LoadFVMLibCommand alloc] init];
  946.     return oNew;
  947. }
  948.  
  949. a320 8
  950. //M+    IdFVMLibCommand +new
  951. //M-
  952. + new
  953. {
  954.     IdFVMLibCommand *oNew = [[IdFVMLibCommand alloc] init];
  955.     return oNew;
  956. }
  957.  
  958. a370 8
  959. //M+    FVMFileCommand +new
  960. //M-
  961. + new
  962. {
  963.     FVMFileCommand *oNew = [[FVMFileCommand alloc] init];
  964.     return oNew;
  965. }
  966.  
  967. a412 7
  968. //M+    SymTabCommand +new
  969. //M-
  970. + new
  971. {
  972.     SymTabCommand *oNew = [[SymTabCommand alloc] init];
  973.     return oNew;
  974. }
  975. a440 7
  976. //M+    SymSegCommand +new
  977. //M-
  978. + new
  979. {
  980.     SymSegCommand *oNew = [[SymSegCommand alloc] init];
  981.     return oNew;
  982. }
  983. a469 6
  984. //M-
  985. + new
  986. {
  987.     ThreadCommand *oNew = [[ThreadCommand alloc] init];
  988.     return oNew;
  989. }
  990. a497 7
  991. //M+    ThreadCommand +new
  992. //M-
  993. + new
  994. {
  995.     UnixThreadCommand *oNew = [[UnixThreadCommand alloc] init];
  996.     return oNew;
  997. }
  998. a507 7
  999. //M+    IdentCommand +new
  1000. //M-
  1001. + new
  1002. {
  1003.     IdentCommand *oNew = [[IdentCommand alloc] init];
  1004.     return oNew;
  1005. }
  1006. a515 46
  1007.  
  1008. #ifdef BOOGER
  1009. @@implementation GenericCommand
  1010.  
  1011. //M+    GenericCommand +new
  1012. //M-
  1013. + new
  1014. {
  1015.     GenericCommand *oNew = [[GenericCommand alloc] init];
  1016.     return oNew;
  1017. }
  1018.  
  1019. //M+    GenericCommand -init
  1020. //M-
  1021. - init
  1022. {
  1023.     [super init];
  1024.     mapped = FALSE;
  1025.     return self;
  1026. }
  1027.  
  1028. //M+    GenericCommand -getBaseAddress
  1029. //M-
  1030. - (unsigned long)getBaseAddress
  1031. {
  1032.     return GenericCommand->vmaddr;
  1033. }
  1034.  
  1035. //M+    GenericCommand -setLoadCommand
  1036. //M-
  1037. - setLoadCommand: (caddr_t)loadCommandAddress;
  1038. {
  1039.     [super setLoadCommand: loadCommandAddress];
  1040.     GenericCommand = (struct generic_command *)loadCommandAddress;
  1041.     return self;
  1042. }
  1043.  
  1044. //M+    GenericCommand -(char *)commandName
  1045. //M-
  1046. - (char *)commandName
  1047. {
  1048.     return GenericCommand->segname;
  1049. }
  1050.  
  1051. @@end
  1052. #endif
  1053. @
  1054.  
  1055.  
  1056. 1.3
  1057. log
  1058. @correct a few typos, add better commentary
  1059. @
  1060. text
  1061. @d4 3
  1062. d14 1
  1063. a14 1
  1064. static char rcsident[] = "@@(#) $Id: LoadCommand.m,v 1.2 93/10/27 23:43:04 ediger Exp Locker: ediger $";
  1065. d147 4
  1066. d202 1
  1067. d219 1
  1068. d291 1
  1069. a291 1
  1070.     mapped = TRUE;
  1071. d333 1
  1072. a333 1
  1073. //M+    LoadFVMLibCommand -loadOtherFile
  1074. d424 6
  1075. @
  1076.  
  1077.  
  1078. 1.2
  1079. log
  1080. @changed to one subclass per type of load command
  1081. @
  1082. text
  1083. @d3 4
  1084. a6 1
  1085.  * $Log$
  1086. d11 1
  1087. a11 1
  1088. static char rcsident[] = "@@(#) $Id$";
  1089. d22 1
  1090. a22 1
  1091. //        Cheesy polymorphism of Mach-O load commands.
  1092. d25 1
  1093. a25 1
  1094. //        ecah struct load_command.
  1095. d103 2
  1096. d112 4
  1097. d141 1
  1098. a141 20
  1099. /*
  1100.     switch (loadCommand->lc.cmd) {
  1101.     case LC_THREAD:
  1102.         bpName = "LC_THREAD";
  1103.         break;
  1104.     case LC_UNIXTHREAD:
  1105.         bpName = "LC_UNIXTHREAD";
  1106.         break;
  1107.     case LC_IDENT:
  1108.         bpName = "LC_IDENT";
  1109.         break;
  1110.     case LC_PREPAGE:
  1111.         bpName = "LC_PREPAGE";
  1112.         break;
  1113.     default:
  1114.         bpName = "Bad cmd field";
  1115.         break;
  1116.     }
  1117. */
  1118.     return "mere load_command";
  1119. d167 1
  1120. a167 2
  1121.     nextSection    = 0;
  1122.     mapped         = TRUE;
  1123. d172 2
  1124. d240 4
  1125. a243 1
  1126.     return segmentCommand->segname;
  1127. d367 2
  1128. d389 1
  1129. a389 1
  1130. //        Possibly this object has allocated some memory for it's
  1131. d427 1
  1132. a427 1
  1133.     return fvmFileCommand->header_addr;
  1134. @
  1135.  
  1136.  
  1137. 1.1
  1138. log
  1139. @Initial revision
  1140. @
  1141. text
  1142. @d2 3
  1143. a4 1
  1144. #import <stdio.h>
  1145. d6 1
  1146. a6 5
  1147. //  This is a bit grosser than it could be.  The load commands in a
  1148. //    Mach-O file header aren't amenable to the "subclassing" as Objective-C
  1149. //    sees it.  The variable part of the struct is based on the "cmd" field
  1150. //    of a struct load_command.  The load_command part becomes the first
  1151. //    fields of the type of command specified in cmd.
  1152. d8 1
  1153. d10 1
  1154. a10 3
  1155. @@implementation LoadCommand
  1156.  
  1157. //M+    +new
  1158. d18 54
  1159. a71 1
  1160. //M+    -init
  1161. d78 2
  1162. a79 1
  1163.     sections    = NULL;
  1164. d83 1
  1165. a83 1
  1166. //M+    -free
  1167. d91 1
  1168. a91 1
  1169. //M+    -setSegmentCommand
  1170. d95 3
  1171. a97 1
  1172.     loadCommand = (union segment_hdr *)loadCommandAddress;
  1173. d99 6
  1174. a104 2
  1175.     if (loadCommand != NULL && loadCommand->lc.cmd == LC_SEGMENT)
  1176.         [self fillSections];
  1177. d106 5
  1178. a110 1
  1179.     return self;
  1180. d114 1
  1181. a114 1
  1182. //M+    -fillSections
  1183. d116 68
  1184. d188 1
  1185. a188 1
  1186.             sizeof(struct section)*loadCommand->segmentc.nsects);
  1187. d193 1
  1188. a193 1
  1189.              = (struct section *)((unsigned long)loadCommand
  1190. d196 1
  1191. a196 1
  1192.         for (iCC = 0; iCC < loadCommand->segmentc.nsects; ++iCC)
  1193. d204 1
  1194. a204 1
  1195. //M+    -printSections
  1196. d210 1
  1197. a210 1
  1198.         for (iCC = loadCommand->segmentc.nsects - 1; iCC >= 0; --iCC)
  1199. d221 1
  1200. a221 2
  1201.  
  1202. //M+    -getBaseAddress
  1203. d225 2
  1204. a226 1
  1205.     unsigned long lrBaseAddress = 0;
  1206. d228 6
  1207. a233 6
  1208.     if (loadCommand != NULL)
  1209.     {
  1210.         switch (loadCommand->lc.cmd) {
  1211.         case  LC_SEGMENT:
  1212.             lrBaseAddress = loadCommand->segmentc.vmaddr;
  1213.             break;
  1214. d235 8
  1215. a242 4
  1216.         case LC_LOADFVMLIB:
  1217.         case LC_IDFVMLIB:
  1218.             lrBaseAddress = loadCommand->fvmlibc.fvmlib.header_addr;
  1219.             break;
  1220. a243 3
  1221.         case LC_FVMFILE:
  1222.             lrBaseAddress = loadCommand->fvmfilec.header_addr;
  1223.             break;
  1224. d245 6
  1225. a250 10
  1226.         case LC_SYMTAB:
  1227.         case LC_SYMSEG:
  1228.         case LC_THREAD:
  1229.         case LC_UNIXTHREAD:
  1230.         case LC_IDENT:
  1231.         case LC_PREPAGE:
  1232.         default:
  1233.             lrBaseAddress = -1;
  1234.         }
  1235.     }
  1236. d252 5
  1237. a256 1
  1238.     return lrBaseAddress;
  1239. d259 2
  1240. a260 1
  1241. //M+ - (unsigned long)commandSize
  1242. d262 1
  1243. a262 1
  1244. - (unsigned long)commandSize
  1245. d264 4
  1246. a267 1
  1247.     return loadCommand->lc.cmdsize;
  1248. d270 5
  1249. a274 1
  1250. //M+ - (char *)commandName
  1251. d276 36
  1252. d314 3
  1253. a316 1
  1254.     char *bpName = NULL;
  1255. d318 7
  1256. a324 34
  1257.     switch (loadCommand->lc.cmd) {
  1258.     case  LC_SEGMENT:
  1259.         bpName = loadCommand->segmentc.segname;
  1260.         break;
  1261.     case LC_SYMTAB:
  1262.         bpName = "LC_SYMTAB";
  1263.         break;
  1264.     case LC_SYMSEG:
  1265.         bpName = "LC_SYMSEG";
  1266.         break;
  1267.     case LC_THREAD:
  1268.         bpName = "LC_THREAD";
  1269.         break;
  1270.     case LC_UNIXTHREAD:
  1271.         bpName = "LC_UNIXTHREAD";
  1272.         break;
  1273.     case LC_LOADFVMLIB:
  1274.     case LC_IDFVMLIB:
  1275.         bpName = (char *)((unsigned long)loadCommand
  1276.             + loadCommand->fvmlibc.fvmlib.name.offset);
  1277.         break;
  1278.     case LC_IDENT:
  1279.         bpName = "LC_IDENT";
  1280.         break;
  1281.     case LC_FVMFILE:
  1282.         bpName = (char *)((unsigned long)loadCommand
  1283.             + loadCommand->fvmfilec.name.offset);
  1284.         break;
  1285.     case LC_PREPAGE:
  1286.         bpName = "LC_PREPAGE";
  1287.         break;
  1288.     default:
  1289.         bpName = "Bad cmd field";
  1290.         break;
  1291. d326 2
  1292. a327 2
  1293.     
  1294.     return bpName;
  1295. d330 1
  1296. a330 3
  1297. //M+    -compareBaseAddress:
  1298. //        This didn't work well with the SortedList class.
  1299. //        I ended up hacking SortedList to handle unsigned longs.
  1300. d332 1
  1301. a332 2
  1302. /*
  1303. - (int)compareBaseAddress:anotherSegment
  1304. d334 2
  1305. a335 2
  1306.     int           irComparison;
  1307.     unsigned long lBaseAddress = [anotherSegment getBaseAddress];
  1308. d337 7
  1309. d345 1
  1310. a345 3
  1311.     if (lBaseAddress == -1)
  1312.         irComparison = 1;
  1313.     else {
  1314. d347 2
  1315. a348 9
  1316.         switch (loadCommand->lc.cmd) {
  1317.         case  LC_SEGMENT:
  1318.             if (loadCommand->segmentc.vmaddr > lBaseAddress)
  1319.                 irComparison = 1;
  1320.             else if (loadCommand->segmentc.vmaddr == lBaseAddress)
  1321.                 irComparison = 0;
  1322.             else if (loadCommand->segmentc.vmaddr < lBaseAddress)
  1323.                 irComparison = -1;
  1324.             break;
  1325. d350 1
  1326. a350 9
  1327.         case LC_LOADFVMLIB:
  1328.         case LC_IDFVMLIB:
  1329.             if (loadCommand->fvmlibc.fvmlib.header_addr > lBaseAddress)
  1330.                 irComparison = 1;
  1331.             else if (loadCommand->fvmlibc.fvmlib.header_addr == lBaseAddress)
  1332.                 irComparison = 0;
  1333.             else if (loadCommand->fvmlibc.fvmlib.header_addr < lBaseAddress)
  1334.                 irComparison = -1;
  1335.             break;
  1336. d352 1
  1337. a352 8
  1338.         case LC_FVMFILE:
  1339.             if (loadCommand->fvmfilec.header_addr > lBaseAddress)
  1340.                 irComparison = 1;
  1341.             else if (loadCommand->fvmfilec.header_addr == lBaseAddress)
  1342.                 irComparison = 0;
  1343.             else if (loadCommand->fvmfilec.header_addr < lBaseAddress)
  1344.                 irComparison = -1;
  1345.             break;
  1346. d354 7
  1347. a360 4
  1348.         default:
  1349.                 irComparison = 1;
  1350.         }
  1351.     }
  1352. d362 8
  1353. a369 1
  1354.     return irComparison;
  1355. d371 266
  1356. a636 1
  1357. */
  1358. @
  1359.