Annotation of GNUtools/debug/Common/RelocManager.m, revision 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.