home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Programming / GDBbundle-1.0-MIS / src / debug / Common / RelocManager.m < prev    next >
Encoding:
Text File  |  1997-02-25  |  9.9 KB  |  434 lines

  1. #import "RelocManager.h"
  2. #import <stdlib.h>
  3. #import <string.h>
  4. #import <mach-o/loader.h>
  5. #import <libc.h>
  6.  
  7. int slideWarpM = 0;
  8.  
  9. @implementation RelocManager
  10.  
  11. -init
  12. {
  13.     rmFlags.invalid = YES;
  14.     rmFlags.shouldSortRelocs = YES;
  15.     return self;
  16. }
  17.  
  18. -free
  19. {
  20.     [self invalidate];
  21.     return [super free];
  22. }
  23.  
  24. int compareRelocsSort(const void *v1, const void *v2)
  25. {
  26.     const Reloc *r1 = v1, *r2 = v2;
  27.     pointer_t a1 = r1->address, a2 = r2->address;
  28.     return a1 < a2 ? -1 : (a1 == a2 ? 0 : 1);
  29. }
  30.  
  31. int compareRelocsSearch(const void *v1, const void *v2)
  32. {
  33.     const Reloc *r1 = v1, *r2 = v2;
  34.     pointer_t address = r1->address;
  35.     return address < r2->address ? -1 : (address >= r2->maxAddress ? 1 : 0);
  36. }
  37.  
  38. -(Reloc *)relocFor: (const void *)pointer
  39. {
  40.     Reloc *reloc;
  41.     int count;
  42.     BOOL found, tooFar;
  43.     if (rmFlags.invalid)
  44.     [self readInAllRelocs];
  45.     if (lastReloc
  46.     && (lastReloc->address <= (pointer_t)pointer) 
  47.     && ((pointer_t)pointer < (lastReloc->maxAddress)))
  48.     return lastReloc;
  49.     else {
  50. #if 1 
  51.     Reloc keyReloc;
  52.     keyReloc.address = (pointer_t)pointer;
  53.     if (reloc = bsearch(&keyReloc, relocs, numRelocs, relocSize, compareRelocsSearch))
  54.         found = YES;
  55.     else
  56.         found = NO;
  57. #else
  58.     reloc = relocs;
  59.     for (count = numRelocs, found = NO, tooFar = NO;
  60.          count && !found && !tooFar; count--) {
  61.         if ((pointer_t)pointer < (reloc->maxAddress)) {
  62.         if (reloc->address <= (pointer_t)pointer)
  63.             found = YES;
  64.         else
  65.             tooFar = YES;
  66.         } else
  67.         ((void *)reloc) += relocSize;
  68.     }
  69. #endif
  70.     if (found && (reloc->rFlags.readIn || [self readInReloc: reloc])) {
  71.         lastReloc = reloc;
  72.         return reloc;
  73.     } else
  74.         return NULL;
  75.     }
  76. }
  77.  
  78. -(BOOL)readInReloc: (Reloc *)reloc
  79. {
  80.     [self subclassResponsibility: _cmd];
  81.     return NO;
  82. }
  83.  
  84. -(void)_readInAllRelocs
  85. {
  86.     [self subclassResponsibility: _cmd];
  87. }
  88.  
  89. -(void)readInAllRelocs
  90. {
  91.     [self _readInAllRelocs];
  92.     if (rmFlags.shouldSortRelocs)
  93.     qsort(relocs, numRelocs, relocSize, compareRelocsSort);
  94. }
  95.  
  96. -invalidate
  97. {
  98.     if (rmFlags.invalid)
  99.     return self;
  100.     else {
  101.     if (relocs) {
  102.         free(relocs); relocs = NULL;
  103.     }
  104.     numRelocs = 0;
  105.     lastReloc = NULL;
  106.     rmFlags.invalid = YES;
  107.     return self;
  108.     }
  109. }
  110.  
  111. -(Reloc *)oldRelocFor: (const void *)pointer
  112. {
  113.    int count;
  114.    BOOL found;
  115.    Reloc *reloc;
  116.     if (lastReloc
  117.     && (lastReloc->data <= (pointer_t)pointer) 
  118.     && ((pointer_t)pointer < lastReloc->maxData))
  119.     return lastReloc;
  120.     else {
  121.     reloc = relocs;
  122.     for (count = numRelocs, found = NO; count && !found; count--) {
  123.         if (reloc->rFlags.readIn && (reloc->data <= (pointer_t)pointer) 
  124.         && ((pointer_t)pointer < reloc->maxData))
  125.         found = YES;
  126.         else
  127.         ((void *)reloc) += relocSize;
  128.     }
  129.     if (found) {
  130.         lastReloc = reloc;
  131.         return reloc;
  132.     } else
  133.         return NULL;
  134.     }
  135. }
  136.  
  137. -(void *)originalPointerFor: (const void *)pointer
  138. {    
  139.     Reloc *reloc = [self oldRelocFor: pointer];
  140.     if (reloc)
  141.     return (void *)(reloc->address + (pointer - reloc->data));
  142.     else 
  143.     return NULL;
  144. }
  145.  
  146. -(void *)pointerFor: (const void *)pointer
  147. {
  148.     Reloc *reloc;
  149.     if (pointer && (reloc = [self  relocFor: pointer])) 
  150.     return (void *)((pointer_t)pointer + reloc->displacement);
  151.     else
  152.     return NULL;
  153. }
  154.  
  155. -(char *)pointerForString: (const char *)pointer isNullTerminated: (BOOL *)isNT
  156. {
  157.     char *retPointer;
  158.     Reloc *reloc;
  159.     char *string;
  160.     if (pointer && (reloc = [self relocFor: pointer])) {
  161.         retPointer = (char *)((pointer_t)pointer + reloc->displacement);
  162.     for (string = retPointer;
  163.          *string && ((pointer_t)string < reloc->maxData);
  164.          string++);
  165.     *isNT = *string ? NO : YES;
  166.     return retPointer;
  167.     } else{
  168.     *isNT = NO;
  169.     return NULL;
  170.     }
  171. }
  172.  
  173. -(char *)pointerForString: (const char *)string
  174. {
  175.     BOOL isNT;
  176.     char *retPointer;
  177.     if ((retPointer = [self pointerForString: string isNullTerminated: &isNT])
  178.     && isNT)
  179.     return retPointer;
  180.     else
  181.     return NULL;
  182. }
  183.  
  184. -(void *)pointerFor: (const void *)pointer withSize: (int)size
  185. {
  186.     Reloc *reloc;
  187.     pointer_t newPointer;
  188.     if (pointer && (reloc = [self relocFor: pointer])) {
  189.     newPointer = (pointer_t)pointer + reloc->displacement;
  190.     if ((newPointer + size) <= reloc->maxData)
  191.         return (void *)newPointer;
  192.     else
  193.         return NULL;
  194.     } else
  195.     return NULL;
  196. }
  197.  
  198. -pointerForID: (const id)pointer
  199. {
  200.     Class theClass;
  201.     struct _ObjectID {
  202.     @defs(Object)
  203.     } *newID;
  204.     
  205.     if (pointer
  206.         && (newID = [self pointerFor: pointer withSize: sizeof(id)])
  207.     && (theClass = [self pointerFor: newID->isa
  208.                            withSize: sizeof(Class)])
  209.     && (newID
  210.         = [self pointerFor: pointer withSize: theClass->instance_size]))
  211.     return (id)newID;
  212.     else
  213.     return nil;
  214. }
  215.             
  216. -(int)getDataAt: (const void *)start for: (int)numBytes into: (void *)data
  217. {
  218.     Reloc *reloc = [self relocFor: start];
  219.     int numBytesInReloc;
  220.     
  221.     if (reloc) {
  222.         numBytesInReloc = reloc->maxAddress - (int)start;
  223.         if (numBytes > numBytesInReloc)
  224.         numBytes = numBytesInReloc;
  225.     memcpy(data,
  226.            (void *)(reloc->data + ((pointer_t)start - reloc->address)),
  227.            numBytes);
  228.     return numBytes;
  229.     } else
  230.     return 0;
  231. }
  232.  
  233. -(struct mach_header *)getMachHeader
  234. {
  235.     [self subclassResponsibility: _cmd];
  236.     return NULL;
  237. }
  238.  
  239. -(unsigned)getSlide
  240. {
  241.     [self subclassResponsibility: _cmd];
  242.     return 0;
  243. }
  244.  
  245. -(int)getNumMachHeaders
  246. {
  247.     [self subclassResponsibility: _cmd];
  248.     return 0;
  249. }
  250.  
  251. -(struct mach_header **)getMachHeaders
  252. {
  253.     [self subclassResponsibility: _cmd];
  254.     return NULL;
  255. }
  256.  
  257. -(unsigned*)getSlides
  258. {
  259.     [self subclassResponsibility: _cmd];
  260.     return NULL;
  261. }
  262.  
  263. -(struct mach_header **)getMachHeadersWithNames: (char ***)names
  264. {
  265.     [self subclassResponsibility: _cmd];
  266.     return NULL;
  267. }
  268.  
  269. -(unsigned*)getSlidesWithNames: (char ***)names
  270. {
  271.     [self subclassResponsibility: _cmd];
  272.     return NULL;
  273. }
  274.  
  275. -(void *)getSectData: (STR)segName 
  276.          section: (STR)sectName 
  277.         size: (int *)pSize 
  278.        forHeader: (struct mach_header *)header
  279.            withSlide: (unsigned)slide
  280. {
  281.     void *data = getsectdatafromheader(header, segName, sectName, pSize);
  282.     return [self pointerFor: (void*) ((char*) data + slide) withSize: *pSize];
  283. }
  284.  
  285. -(void *)getSectData: (STR)segName 
  286.          section: (STR)sectName 
  287.         size: (int *)pSize 
  288. {
  289.     return [self getSectData: segName 
  290.              section: sectName 
  291.             size: pSize 
  292.            forHeader: [self getMachHeader]
  293.                withSlide: [self getSlide]];
  294. }
  295.  
  296. -(const struct section *)getSeg: (STR)segName sect: (STR)sectName
  297. {
  298.     return getsectbynamefromheader([self getMachHeader], segName, sectName);
  299. }
  300.  
  301. -(const struct section *)firstSection
  302. {
  303.     struct mach_header *header = [self getMachHeader];
  304.     int i;
  305.     struct load_command *loadCmd;
  306.     
  307.     for (i = 0, loadCmd = (struct load_command *)(header + 1);
  308.      i < header->ncmds;
  309.      i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  310.     if (loadCmd->cmd == LC_SEGMENT) {
  311.         struct segment_command *segCmd = (struct segment_command *)loadCmd;
  312.         if (segCmd->nsects)
  313.         return (struct section *)(segCmd + 1);
  314.     }
  315.     }
  316.     return NULL;
  317. }
  318.         
  319. -(unsigned)getMaximumAddressForHeader: (struct mach_header *)header withSlide:(unsigned)slide
  320. {
  321.     int i;
  322.     struct load_command *loadCmd;
  323.     unsigned maxAddr = 0;
  324.     
  325.     for (i = 0, loadCmd = (struct load_command *)(header + 1);
  326.      i < header->ncmds;
  327.      i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  328.     if (loadCmd->cmd == LC_SEGMENT) {
  329.         struct segment_command *segCmd = (struct segment_command *)loadCmd;
  330.         if ((segCmd->vmaddr + segCmd->vmsize + slide) > maxAddr)
  331.         maxAddr = segCmd->vmaddr + segCmd->vmsize;
  332.     }
  333.     }
  334.     return maxAddr;
  335. }
  336.  
  337. -(struct segment_command *)getSegment: (const char *)segName
  338. {
  339.     int i;
  340.     struct load_command *loadCmd;
  341.     struct segment_command *foundSeg = NULL;
  342.     struct mach_header *header = [self getMachHeader];
  343.     
  344.     for (i = 0, loadCmd = (struct load_command *)(header + 1);
  345.      i < header->ncmds && !foundSeg;
  346.      i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  347.     if (loadCmd->cmd == LC_SEGMENT) {
  348.         struct segment_command *segCmd = (struct segment_command *)loadCmd;
  349.         if (strcmp(segName, segCmd->segname) == 0)
  350.         foundSeg = segCmd;
  351.     }
  352.     }
  353.     return foundSeg;
  354. }
  355.  
  356. -(unsigned)getMaximumAddressForSegment: (const char *)segName
  357. {
  358.     int i;
  359.     struct load_command *loadCmd;
  360.     unsigned maxAddr = 0;
  361.     struct mach_header *header = [self getMachHeader];
  362.     unsigned int slide = [self getSlide];
  363.     
  364.     for (i = 0, loadCmd = (struct load_command *)(header + 1);
  365.      i < header->ncmds;
  366.      i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  367.     if (loadCmd->cmd == LC_SEGMENT) {
  368.         struct segment_command *segCmd = (struct segment_command *)loadCmd;
  369.         struct section *section;
  370.         int nSects;
  371.         
  372.         for (nSects = segCmd->nsects,
  373.              section = (struct section *)(segCmd + 1);
  374.              nSects;
  375.          nSects--, section++) {
  376.         if (strcmp(section->segname, segName) == 0) {
  377.             if ((section->addr + section->size + slide) > maxAddr)
  378.             maxAddr = (section->addr + section->size + slide);
  379.         }
  380.         }
  381.     }
  382.     }
  383.     return maxAddr;
  384. }
  385.  
  386. -(unsigned)getMaximumAddress
  387. {
  388.     return [self getMaximumAddressForHeader: [self getMachHeader]
  389.          withSlide: [self getSlide]];
  390. }
  391.  
  392. -(unsigned)getMinimumAddressForSegment: (const char*)segName
  393. {
  394.   int i;
  395.   struct load_command *loadCmd;
  396.   unsigned minAddr = 0xffffffffU;
  397.   struct mach_header *header = [self getMachHeader];
  398.   unsigned int slide = [self getSlide];
  399.     
  400.   for (i = 0, loadCmd = (struct load_command *)(header + 1);
  401.        i < header->ncmds;
  402.        i++, ((void *)loadCmd) += loadCmd->cmdsize) {
  403.     if (loadCmd->cmd == LC_SEGMENT) {
  404.       struct segment_command *segCmd = (struct segment_command *)loadCmd;
  405.       struct section *section;
  406.       int nSects;
  407.         
  408.       for (nSects = segCmd->nsects,
  409.        section = (struct section *)(segCmd + 1);
  410.        nSects;
  411.        nSects--, section++) {
  412.     if (strcmp(section->segname, segName) == 0) {
  413.       if ((section->addr + slide) < minAddr)
  414.         minAddr = (section->addr + slide);
  415.     }
  416.       }
  417.     }
  418.   }
  419.   
  420.   return minAddr;
  421. }
  422.  
  423. -(unsigned)getMaximumTextAddress
  424. {
  425.     return [self getMaximumAddressForSegment: "__TEXT"];
  426. }
  427.  
  428. -(unsigned)getMaximumDataAddress
  429. {
  430.     return [self getMaximumAddressForSegment: "__DATA"];
  431. }
  432.  
  433. @end
  434.