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