Annotation of GNUtools/debug/Common/RelocManager.m, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.