home *** CD-ROM | disk | FTP | other *** search
- #import <LoadCommand.h>
- /*
- * $Log: LoadCommand.m,v $
- Revision 1.12 94/05/28 16:17:05 ediger
- added LoadCommand -getUpperAddress and - (struct load_command *)loadCommandAddress
-
- Revision 1.11 94/01/30 16:25:39 ediger
- added working version of -(unsigned long)pc method
-
- Revision 1.10 93/12/28 23:09:05 ediger
- removed printfs for memory leak checking.
-
- Revision 1.9 93/12/28 23:07:40 ediger
- Fixed memory leak caused by sections instance var of SegmentCommand
- subclass not getting freed. overrode -free method for that subclass.
- Left in the debug statements
-
- Revision 1.8 93/12/08 00:52:12 ediger
- added some assert()s in accordance with new ideology
-
- Revision 1.7 93/12/02 00:45:36 ediger
- fixed a renamed method (initFromFile: becomes initFromFileNamed:)
-
- Revision 1.6 93/10/31 21:36:40 ediger
- changed initialization of new LoadCommand object from 'new'
- to 'alloc] init]'.
-
- Revision 1.3 93/10/28 00:07:08 ediger
- correct a few typos, add better commentary
-
- Revision 1.2 93/10/27 23:43:04 ediger
- changed to one subclass per type of load command
-
- */
-
- @implementation LoadCommand
-
- static char rcsident[] = "@(#) $Id: LoadCommand.m,v 1.12 94/05/28 16:17:05 ediger Exp Locker: ediger $";
-
- //M+ LoadCommand +new
- //M-
- + new
- {
- LoadCommand *oNew = [[LoadCommand alloc] init];
- assert(oNew != NULL);
- return oNew;
- }
-
- //M+ LoadCommand +new:
- // Accounts for cheesy polymorphism of Mach-O load commands.
- // Each of them begins with a struct load_command, but
- // a variable amount of stuff follows (and subsumes)
- // each struct load_command.
- //M-
- + new: (caddr_t)loadCommandAddress;
- {
- id oNew = Nil;
- struct load_command *lc = (struct load_command *)loadCommandAddress;
-
- assert(NULL != loadCommandAddress);
-
- switch (lc->cmd)
- {
- case LC_SEGMENT:
- oNew = [[SegmentCommand alloc] init];
- break;
- case LC_IDFVMLIB:
- oNew = [[IdFVMLibCommand alloc] init];
- break;
- case LC_LOADFVMLIB:
- oNew = [[LoadFVMLibCommand alloc] init];
- break;
- case LC_FVMFILE:
- oNew = [[FVMFileCommand alloc] init];
- break;
- case LC_SYMTAB:
- oNew = [[SymTabCommand alloc] init];
- break;
- case LC_SYMSEG:
- oNew = [[SymSegCommand alloc] init];
- break;
- case LC_THREAD:
- oNew = [[ThreadCommand alloc] init];
- break;
- case LC_UNIXTHREAD:
- oNew = [[UnixThreadCommand alloc] init];
- break;
- case LC_IDENT:
- oNew = [[IdentCommand alloc] init];
- break;
- default:
- oNew = [[LoadCommand alloc] init];
- break;
- }
-
- assert(Nil != oNew);
-
- [oNew setLoadCommand:loadCommandAddress];
-
- if (lc->cmd == LC_SEGMENT)
- [oNew fillSections];
-
- return oNew;
- }
-
- //M+ LoadCommand -init
- // Assumes that "self" is already allocated.
- //M-
- - init
- {
- [super init];
- loadCommand = NULL;
- mapped = FALSE;
- otherFile = FALSE;
- return self;
- }
-
- //M+ LoadCommand -free
- //M-
- - free
- {
- [super free];
- return self;
- }
-
- //M+ LoadCommand -setSegmentCommand
- //M-
- - setLoadCommand: (caddr_t)loadCommandAddress;
- {
- assert(loadCommandAddress != NULL);
- loadCommand = (struct load_command *)loadCommandAddress;
- return self;
- }
-
- //M+ LoadCommand -isMapped
- // Does the object represent a memory-mapped piece
- // of the file? Probably not.
- //M-
- - (BOOL)isMapped
- {
- return mapped;
- }
-
- //M+ LoadCommand -isThread
- // Does the object represent a thread of some sort.
- // of the file? Again, Probably not.
- //M-
- - (BOOL)isThread
- {
- return FALSE;
- }
-
- //M+ LoadCommand -representsMappedFile
- // Does the object represent a load command
- // that would end up causing some other file
- // to be memory-mapped into the task's address
- // space?
- //M-
- - (BOOL)representsMappedFile
- {
- return otherFile;
- }
-
-
- //M+ LoadCommand -getBaseAddress
- //M-
- - (unsigned long)getBaseAddress
- {
- return -1;
- }
-
- //M+ LoadCommand -getUpperAddress
- //M-
- - (unsigned long)getUpperAddress
- {
- return -1;
- }
-
- //M+ LoadCommand -(unsigned long)commandSize
- //M-
- - (unsigned long)commandSize
- {
- return loadCommand->cmdsize;
- }
-
- //M+ LoadCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- return "load command";
- }
-
- //M+ LoadCommand - (int)numberOfSections
- // Only struct segment_commands have sections,
- // but it's handy to use this as a flag.
- //M-
- - (int)numberOfSections
- {
- return 0;
- }
-
- //M+ LoadCommand -struct load_command *)loadCommandAddress
- //M-
- - (struct load_command *)loadCommandAddress
- {
- return loadCommand;
- }
-
- @end
-
-
- @implementation SegmentCommand
-
- //M+ SegmentCommand -init
- //M-
- - init
- {
- [super init];
- sections = NULL;
- segmentCommand = NULL;
- mapped = TRUE; // struct segment_commands do map
- return self;
- }
-
- //M+ SegmentCommand -free
- // Had to override so as to free sections instance var
- //M-
- - free
- {
- if (NULL != sections)
- free(sections);
- [super free];
- return self;
- }
-
- //M+ SegmentCommand -fillSections
- // Create a quick-to-access array of pointers to
- // the struct sections in this load command.
- //M-
- - fillSections
- {
- assert(segmentCommand != NULL);
- sections
- = (struct section **)malloc(
- sizeof(struct section)*segmentCommand->nsects);
-
- if (sections != NULL)
- { int iCC;
- struct section *spSection
- = (struct section *)((unsigned long)segmentCommand
- + sizeof(struct segment_command));
-
- for (iCC = 0; iCC < segmentCommand->nsects; ++iCC)
- sections[iCC] = spSection++;
- }
-
- return self;
- }
-
- //M+ SegmentCommand -getBaseAddress
- //M-
- - (unsigned long)getBaseAddress
- {
- assert(segmentCommand != NULL);
- return segmentCommand->vmaddr;
- }
-
- //M+ SegmentCommand -getUpperAddress
- //M-
- - (unsigned long)getUpperAddress
- {
- assert(segmentCommand != NULL);
- return segmentCommand->vmaddr + segmentCommand->vmsize;
- }
-
- //M+ SegmentCommand -setLoadCommand
- //M-
- - setLoadCommand: (caddr_t)loadCommandAddress;
- {
- assert(loadCommandAddress != NULL);
- [super setLoadCommand: loadCommandAddress];
- segmentCommand = (struct segment_command *)loadCommandAddress;
- return self;
- }
-
-
- //M+ SegmentCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- assert(segmentCommand != NULL);
- if (segmentCommand->segname == NULL || strlen(segmentCommand->segname) <= 0)
- return "LC_SEGMENT"; // relocatable object files?
- else
- return segmentCommand->segname;
- }
-
- //M+ SegmentCommand -numberOfSections
- //M-
- - (int)numberOfSections
- {
- assert(segmentCommand != NULL);
- return segmentCommand->nsects;
- }
-
-
- //M+ SegmentCommand -(struct section *)getSection:(int)sectionNumber
- //M-
- - (struct section *)getSection:(int)sectionNumber
- {
- assert(segmentCommand != NULL);
- if (sections != NULL && sectionNumber < segmentCommand->nsects)
- return sections[sectionNumber];
-
- return NULL;
- }
-
- @end
-
- @implementation LoadFVMLibCommand
-
- //M+ LoadFVMLibCommand -init
- //M-
- - init
- {
- [super init];
- fvmlibCommand = NULL;
- mapped = FALSE;
- otherFile = TRUE;
- theOtherFile = Nil;
- return self;
- }
-
- //M+ LoadFVMLibCommand -getBaseAddress
- //M-
- - (unsigned long)getBaseAddress
- {
- assert(fvmlibCommand != NULL);
- return fvmlibCommand->fvmlib.header_addr;
- }
-
- //M+ LoadFVMLibCommand -setLoadCommand
- //M-
- - setLoadCommand: (caddr_t)loadCommandAddress;
- {
- assert(loadCommandAddress != NULL);
- [super setLoadCommand: loadCommandAddress];
- fvmlibCommand = (struct fvmlib_command *)loadCommandAddress;
- return self;
- }
-
- //M+ LoadFVMLibCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- assert(fvmlibCommand != NULL);
- return (char *)((unsigned long)fvmlibCommand
- + fvmlibCommand->fvmlib.name.offset);
- }
-
- //M+ LoadFVMLibCommand -loadOtherFile
- //M-
- - loadOtherFile
- {
- if (fvmlibCommand != NULL)
- { theOtherFile = [[MachOFile alloc] init];
- [theOtherFile fillFromFileNamed:[self commandName]];
- }
-
- return self;
- }
-
- //M+ LoadFVMLibCommand -otherFile
- //M-
- - otherFile
- {
- return theOtherFile;
- }
-
- //M+ LoadFVMLibCommand -free
- // Had to override this to ditch any other mapped files.
- //M-
- - free
- {
- if (theOtherFile != Nil)
- [theOtherFile free];
-
- [super free];
-
- return self;
- }
-
- @end
-
- @implementation IdFVMLibCommand
-
- //M+ IdFVMLibCommand -init
- //M-
- - init
- {
- [super init];
- namebuf = NULL;
- mapped = FALSE;
- return self;
- }
-
- //M+ IdFVMLibCommand -commandName
- // This is cheesy, but it separates the ident sections from
- // the mapped sections.
- //M-
- - (char *)commandName
- {
- char *filename;
- #define IDENT_PHRASE "FVM Lib ident: "
-
- if (namebuf != NULL)
- free(namebuf);
-
- filename = [super commandName];
-
- namebuf = malloc(strlen(filename) + strlen(IDENT_PHRASE) + 1);
-
- if (namebuf != NULL)
- strcat(strcpy(namebuf, IDENT_PHRASE), filename);
-
- return namebuf;
- }
-
- //M+ IdFVMLibCommand -free
- // Possibly this object has allocated some memory for its
- // own purposes. Free it.
- //M-
- - free
- {
- if (namebuf != NULL)
- free(namebuf);
-
- [super free];
-
- return self;
- }
-
- @end
-
- @implementation FVMFileCommand
-
- //M+ FVMFileCommand -init
- /*
- * The fvmfile_command contains a reference to a file to be loaded at the
- * specified virtual address. (Presently, this command is reserved for NeXT
- * internal use. The kernel ignores this command when loading a program into
- * memory).
- */
- //M-
- - init
- {
- [super init];
- mapped = TRUE;
- return self;
- }
-
- //M+ FVMFileCommand -getBaseAddress
- //M-
- - (unsigned long)getBaseAddress
- {
- assert(fvmFileCommand != NULL);
- return fvmFileCommand->header_addr; // address of FVM file's header
- }
-
- //M+ FVMFileCommand -setLoadCommand
- //M-
- - setLoadCommand: (caddr_t)loadCommandAddress;
- {
- assert(loadCommandAddress != NULL);
- [super setLoadCommand: loadCommandAddress];
- fvmFileCommand = (struct fvmfile_command *)loadCommandAddress;
- return self;
- }
-
- //M+ FVMFileCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- assert(fvmFileCommand != NULL);
- return (char *)((unsigned long)fvmFileCommand
- + fvmFileCommand->name.offset);
- }
-
- @end
-
- @implementation SymTabCommand
-
- //M+ SymTabCommand -init
- //M-
- - init
- {
- [super init];
- mapped = FALSE;
- return self;
- }
-
- //M+ SymTabCommand -setLoadCommand
- //M-
- - setLoadCommand: (caddr_t)loadCommandAddress;
- {
- [super setLoadCommand: loadCommandAddress];
- symTabCommand = (struct symtab_command *)loadCommandAddress;
- return self;
- }
-
- //M+ SymTabCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- return "LC_SYMTAB";
- }
- @end
-
- @implementation SymSegCommand
-
- //M+ SymSegCommand -init
- //M-
- - init
- {
- [super init];
- mapped = FALSE;
- return self;
- }
-
- //M+ SymSegCommand -setLoadCommand
- //M-
- - setLoadCommand: (caddr_t)loadCommandAddress;
- {
- assert(loadCommandAddress != NULL);
- [super setLoadCommand: loadCommandAddress];
- symSegCommand = (struct symseg_command *)loadCommandAddress;
- return self;
- }
-
- //M+ SymSegCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- return "LC_SYMSEG";
- }
- @end
-
- @implementation ThreadCommand
- //M+ ThreadCommand +new
-
- //M+ ThreadCommand -init
- //M-
- - init
- {
- [super init];
- mapped = FALSE;
- return self;
- }
-
- //M+ ThreadCommand -setLoadCommand
- //M-
- - setLoadCommand: (caddr_t)loadCommandAddress;
- {
- assert(loadCommandAddress != NULL);
- [super setLoadCommand: loadCommandAddress];
- threadCommand = (struct thread_command *)loadCommandAddress;
- return self;
- }
-
- //M+ ThreadCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- return "LC_THREAD";
- }
-
- //M+ ThreadCommand -(BOOL)isThread
- //M-
- - (BOOL)isThread
- {
- return TRUE;
- }
-
- - (unsigned long)pc
- {
- struct thread_state_flavor *spThreadStateFlavor;
- unsigned long lNextAddress;
- unsigned int irPC = -1;
-
- spThreadStateFlavor =
- (struct thread_state_flavor *)((unsigned long)threadCommand
- + sizeof(struct thread_command));
-
- lNextAddress = (unsigned long)spThreadStateFlavor
- + sizeof(struct thread_state_flavor);
-
- switch(spThreadStateFlavor->flavor)
- {
- case M68K_THREAD_STATE_REGS:
- irPC = ((struct m68k_thread_state_regs *)lNextAddress)->pc;
- break;
- case M68K_THREAD_STATE_68882:
- irPC = ((struct m68k_thread_state_68882 *)lNextAddress)->iar;
- break;
- case M68K_THREAD_STATE_USER_REG:
- irPC = ((struct m68k_thread_state_user_reg *)lNextAddress)->user_reg;
- break;
- case i386_THREAD_STATE:
- irPC = ((i386_thread_state_t *)lNextAddress)->eip;
- break;
- }
-
- return irPC;
- }
-
- @end
-
- @implementation UnixThreadCommand
-
- //M+ UnixThreadCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- return "LC_UNIXTHREAD";
- }
-
- @end
-
- @implementation IdentCommand
-
- //M+ IdentCommand -(char *)commandName
- //M-
- - (char *)commandName
- {
- return "LC_IDENT";
- }
- @end
-