Annotation of GNUtools/debug/Common/LazyRegionManager.m, revision 1.1

1.1     ! root        1: #import "LazyRegionManager.h"
        !             2: 
        !             3: #import <string.h>
        !             4: 
        !             5: #define        VM_PROT_VOLATILE        ((vm_prot_t) 0x08)      // not cacheable
        !             6: #define                VM_PROT_SPARSE          ((vm_prot_t) 0x10)      // sparse addr space
        !             7: 
        !             8: @implementation LazyRegionManager
        !             9: 
        !            10: -(BOOL)readInReloc: (Reloc *)reloc
        !            11: {
        !            12:     kern_return_t ret;
        !            13:     
        !            14:     if (!reloc->rFlags.readIn) {
        !            15:        ret = vm_allocate(task_self(), &reloc->data, reloc->size, YES);
        !            16:        if (ret == KERN_SUCCESS) {
        !            17:            reloc->maxData = reloc->data + reloc->size;
        !            18:            reloc->displacement = reloc->data - reloc->address;
        !            19:            reloc->rFlags.readIn = YES;
        !            20:        }
        !            21:     }
        !            22:     return reloc->rFlags.readIn ? YES : NO;
        !            23: }
        !            24: 
        !            25: -(int)pageFor: (const void *)pointer inRegion: (Region *)region
        !            26: {
        !            27:     return (((unsigned int)pointer - region->reloc.address) / pageSize);
        !            28: }
        !            29: 
        !            30: -(BOOL)readInDataFor: (const void *)pointer into: (void *)data withSize: (int)size
        !            31: {
        !            32:     unsigned int error = 0, nData;
        !            33:     pointer_t readPage;
        !            34:     
        !            35:     error = vm_read(task, (vm_address_t)pointer, size, &readPage, &nData);
        !            36:     if (!error) {
        !            37:        bcopy((void *)readPage, data, size);
        !            38:        vm_deallocate(task_self(), readPage, nData);
        !            39:     } else
        !            40:        [self isTask];
        !            41:     return error ? NO : YES;
        !            42: }
        !            43: 
        !            44: -(BOOL)readInPage: (unsigned char *)page
        !            45:               for: (void *)pointer
        !            46:              into: (void *)data
        !            47: {
        !            48:     unsigned int error = 0, nData;
        !            49:     pointer_t readPage;
        !            50:     
        !            51:     if (!(*page & PAGEREADIN)) {
        !            52: //     printf("Reading in page at %p.\n", pointer);
        !            53:        error = vm_read(task, (vm_address_t)pointer, pageSize, &readPage, 
        !            54:                        &nData);
        !            55:        if (!error) {
        !            56:            bcopy((void *)readPage, data, pageSize);
        !            57:            vm_deallocate(task_self(), readPage, nData);
        !            58:            if (!(*page & VM_PROT_VOLATILE))
        !            59:                *page |= PAGEREADIN;
        !            60:        } else
        !            61:            [self isTask];
        !            62:     }
        !            63:     return error ? NO : YES;
        !            64: }
        !            65: 
        !            66: -(BOOL)readInPagesFor: (const void *)pointer withSize: (int)size inRegion: (Region *)region
        !            67: {
        !            68:     int nPage, offset;
        !            69:     unsigned char *page, *endPage;
        !            70:     void *data, *address;
        !            71:     int ok = YES;
        !            72:     
        !            73: //    printf("Getting data at: %p for %d bytes.\n", pointer, size);
        !            74:     
        !            75:     nPage = [self pageFor: pointer inRegion: region];
        !            76:     offset = nPage * pageSize;
        !            77:     page = region->pages + nPage;
        !            78:     if (*page & VM_PROT_SPARSE)
        !            79:        ok = [self readInDataFor: pointer
        !            80:                            into: (void *)pointer + region->reloc.displacement 
        !            81:                        withSize: size];
        !            82:     else {
        !            83:        endPage = region->pages
        !            84:                    + [self pageFor: pointer + size inRegion: region];
        !            85:        data = (void *)(region->reloc.data + offset);
        !            86:        address = (void *)(region->reloc.address + offset);
        !            87:        while (ok && page <= endPage) {
        !            88:            ok = [self readInPage: page for: address into: data];
        !            89:            address += pageSize;
        !            90:            data += pageSize;
        !            91:            page++;
        !            92:        }
        !            93:     }
        !            94:     return ok;
        !            95: }
        !            96: 
        !            97: -(void *)pointerFor: (const void *)pointer withSize: (int)size
        !            98: {
        !            99:     Region *region;
        !           100:     pointer_t newPointer;
        !           101:     if (pointer && (region = (Region *)[self relocFor: pointer])) {
        !           102:        newPointer = (pointer_t)pointer + region->reloc.displacement;
        !           103:        if (((newPointer + size) <= region->reloc.maxData)
        !           104:            && [self readInPagesFor: pointer withSize: size inRegion: region])
        !           105:            return (void *)newPointer;
        !           106:        else
        !           107:            return NULL;
        !           108:     } else
        !           109:        return NULL;
        !           110: }
        !           111: 
        !           112: -(int)getDataAt: (const void *)start for: (int)numBytes into: (void *)data
        !           113: {
        !           114:     Reloc *reloc = [self relocFor: start];
        !           115:     int numBytesInRegion;
        !           116:     
        !           117: //    printf("Getting data at: %p for %d bytes.\n", start, numBytes);
        !           118:     
        !           119:     if (reloc) {
        !           120:         numBytesInRegion = reloc->maxAddress - (int)start;
        !           121:         if (numBytes > numBytesInRegion)
        !           122:            numBytes = numBytesInRegion;
        !           123:        if ([self readInPagesFor: start
        !           124:                        withSize: numBytes
        !           125:                        inRegion: (Region *)reloc]) {
        !           126:            memcpy(data,
        !           127:                    (void *)(reloc->data
        !           128:                             + ((pointer_t)start - reloc->address)),
        !           129:                    numBytes);
        !           130:            return numBytes;
        !           131:        } else
        !           132:            return 0;
        !           133:     } else
        !           134:        return 0;
        !           135: }
        !           136: 
        !           137: -(int)putDataAt: (void *)start for: (int)numBytes from: (const void *)data
        !           138: {
        !           139:     int numBytesInRegion;
        !           140:     Reloc *reloc = [self relocFor: start];
        !           141:  
        !           142: //    printf("Putting data at: %p for %d bytes.\n", start, numBytes);
        !           143: 
        !           144:     if (reloc) {
        !           145:         numBytesInRegion = reloc->maxAddress - (int)start;
        !           146:         if (numBytes > numBytesInRegion)
        !           147:            numBytes = numBytesInRegion;
        !           148:        if ([self readInPagesFor: start
        !           149:                        withSize: numBytes
        !           150:                        inRegion: (Region *)reloc]) {
        !           151:            memcpy((void *)(reloc->data + ((pointer_t)start - reloc->address)),
        !           152:                   data,
        !           153:                   numBytes);
        !           154:            return [self writeDataAt: start for: numBytes
        !           155:                               reloc: (Region *)reloc];
        !           156:        } else
        !           157:            return 0;
        !           158:     } else
        !           159:        return 0;
        !           160: }
        !           161: 
        !           162: -(char *)pointerForString: (const char *)pointer isNullTerminated: (BOOL *)isNT
        !           163: {
        !           164:     char *retPointer;
        !           165:     Region *region;
        !           166:     char *string;
        !           167:     int nPage, offset;
        !           168:     unsigned char *page;
        !           169:     void *data, *address;
        !           170:     BOOL ok;
        !           171:     
        !           172:     if (pointer && (region = (Region *)[self relocFor: pointer])) {
        !           173:        retPointer = (char *)((pointer_t)pointer + region->reloc.displacement);
        !           174:        nPage = [self pageFor: pointer inRegion: region];
        !           175:        page = region->pages + nPage;
        !           176:        offset = nPage * pageSize;
        !           177:        data = (void *)(region->reloc.data + offset);
        !           178:        address = (void *)(region->reloc.address + offset);
        !           179:        string = retPointer;
        !           180:        do {
        !           181:            ok = [self readInPage: page for: address into: data];
        !           182:            if (ok) {
        !           183:                page++;
        !           184:                address += pageSize;
        !           185:                data += pageSize;
        !           186:                while (*string && (string < (char *)data))
        !           187:                    string++;
        !           188:            }
        !           189:        } while (ok && *string && (data < (void *)region->reloc.maxData));
        !           190:        *isNT = *string ? NO : YES;
        !           191:        return retPointer;
        !           192:     } else{
        !           193:        *isNT = NO;
        !           194:        return NULL;
        !           195:     }
        !           196: }
        !           197: 
        !           198: -(int)writeDataAt: (const void *)start for: (int)numBytes reloc: (Region *)region
        !           199: {
        !           200:     char *page = pages + [self pageFor: start inRegion: region];
        !           201:     kern_return_t ret;
        !           202:     
        !           203:     if (*page & VM_PROT_SPARSE) {
        !           204:        ret = vm_write(task,
        !           205:                       (vm_address_t)start,
        !           206:                       (pointer_t)(start + region->reloc.displacement),
        !           207:                       numBytes);
        !           208:        if (ret == KERN_SUCCESS)
        !           209:            return numBytes;
        !           210:        else {
        !           211:            [self isTask];
        !           212:            return 0;
        !           213:        }
        !           214:     } else
        !           215:        return [super writeDataAt: start for: numBytes reloc: region];
        !           216: }
        !           217: 
        !           218: @end

unix.superglobalmegacorp.com

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