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

1.1       root        1: #import "SegmentManager.h"
                      2: #import <stdlib.h>
                      3: #import <string.h>
                      4: #import <mach-o/loader.h>
                      5: #import <sys/types.h>
                      6: #import <sys/stat.h>
                      7: #import <mach-o/ldsyms.h>
                      8: #import <libc.h>
                      9: #import <objc/maptable.h>
                     10: #import <mach-o/fat.h>
                     11: 
                     12: #define REALLY_SWAP_LONG(a) ( ((a) << 24) | \
                     13:                      (((a) << 8) & 0x00ff0000) | \
                     14:                      (((a) >> 8) & 0x0000ff00) | \
                     15:        ((unsigned long)(a) >> 24) )
                     16: 
                     17: #define SWAP_LONG(a) (shouldSwap ? REALLY_SWAP_LONG(a) : (a))
                     18: 
                     19: @implementation SegmentManager
                     20: 
                     21: static NXMapTable *managers = NULL;
                     22: 
                     23: +initialize
                     24: {
                     25:     static BOOL beenHere = NO;
                     26:     
                     27:     if (!beenHere) {
                     28:        beenHere = YES;
                     29:        managers = NXCreateMapTable(NXStrValueMapPrototype, 0);
                     30:     }
                     31:     return self;
                     32: }
                     33: 
                     34: -init
                     35: {
                     36:     relocSize = sizeof(Segment);
                     37:     rmFlags.shouldSortRelocs = YES;
                     38:     [self readInAllRelocs];
                     39:     lastReloc = NULL;
                     40:     if (numRelocs) {
                     41:        if (images[0].name)
                     42:            NXMapInsert(managers, images[0].name, self);
                     43:        return self;
                     44:     } else {
                     45:        [self free];
                     46:        return nil;
                     47:     }
                     48: }
                     49: 
                     50: -(void)setCpuType: (cpu_type_t)type
                     51: {
                     52:     static cpu_type_t defaultCpuType = 0;
                     53:     if (type)
                     54:        cpuType = type;
                     55:     else {
                     56:        if (!defaultCpuType) {
                     57:            struct host_basic_info host_basic_info;
                     58:            unsigned int count = HOST_BASIC_INFO_COUNT;
                     59:            
                     60:            if (host_info(host_self(), HOST_BASIC_INFO,
                     61:                          (host_info_t)(&host_basic_info),
                     62:                          &count) == KERN_SUCCESS)
                     63:                defaultCpuType = host_basic_info.cpu_type;
                     64:        }
                     65:        cpuType = defaultCpuType;
                     66:     }
                     67: }
                     68: 
                     69: -initFile: (STR)theName skipShlibs: (BOOL)shouldSkipShlibs withDesc: (int)desc cpuType: (cpu_type_t)type
                     70: {
                     71:     SegmentManager *oldManager;
                     72:     if (oldManager = NXMapGet(managers, theName)) {
                     73:        close(desc);
                     74:        [self free];
                     75:        return oldManager;
                     76:     } else  {
                     77:        name = malloc(strlen(theName) + 1);
                     78:        strcpy(name, theName);
                     79:        skipShlibs = shouldSkipShlibs;
                     80:        imageFd = desc;
                     81:        [self setCpuType: type];
                     82:        [self getImages];
                     83:        return [self init];
                     84:     }
                     85: }
                     86: 
                     87: static const char loadedName[] = "loaded file";
                     88: 
                     89: -(struct mach_header *)headerFromStart: (void *)start
                     90: {
                     91:     struct mach_header *header = start;
                     92:     if (header->magic == MH_MAGIC && header->cputype == cpuType)
                     93:        return header;
                     94:     else {
                     95:        struct fat_header *fatHeader = start;
                     96:        if ((fatHeader->magic == FAT_MAGIC)
                     97:            || (fatHeader->magic == REALLY_SWAP_LONG(FAT_MAGIC))) {
                     98:            BOOL shouldSwap = !(fatHeader->magic == FAT_MAGIC);
                     99:            unsigned int nArches;
                    100:            struct fat_arch *fatArch, *foundArch;
                    101:            
                    102:            for (nArches = SWAP_LONG(fatHeader->nfat_arch),
                    103:                 fatArch = (struct fat_arch *)(fatHeader + 1),
                    104:                 foundArch = NULL;
                    105:                 nArches && !foundArch;
                    106:                 fatArch++, nArches--) {
                    107:                if (cpuType == SWAP_LONG(fatArch->cputype))
                    108:                    foundArch = fatArch;
                    109:            }
                    110:            if (foundArch)
                    111:                return start + SWAP_LONG(foundArch->offset);
                    112:            else
                    113:                return NULL;
                    114:        } else
                    115:            return NULL;
                    116:     }
                    117: }
                    118: 
                    119: -initHeader: (struct mach_header *)header withSize: (int)size
                    120: {
                    121:     numImages = 1;
                    122:     [self setCpuType: 0];
                    123:     images = malloc(sizeof(*images));
                    124:     images->header = [self headerFromStart: header];
                    125:     images->size = size;
                    126:     images->name = NULL;
                    127:     images->mtime = 0;
                    128:     name = malloc(sizeof(loadedName));
                    129:     strcpy(name, loadedName);
                    130:     return [self init];
                    131: }
                    132: 
                    133: -initFile: (STR)theName
                    134: {
                    135:     return [self initFile: theName skipShlibs: NO withDesc: -1 cpuType: 0];
                    136: }
                    137: 
                    138: +newExecutable: (STR)theName skipShlibs: (BOOL)shouldSkipShlibs withDesc: (int)desc cpuType: (cpu_type_t)type
                    139: {
                    140:     SegmentManager *sm = [[super alloc] initFile: (STR)theName
                    141:                                     skipShlibs: shouldSkipShlibs
                    142:                                      withDesc: desc
                    143:                                   cpuType: type];
                    144:     if (sm && [sm isExecutable])
                    145:         return sm;
                    146:     else {
                    147:        [sm free];
                    148:        return nil;
                    149:     }
                    150: }
                    151: 
                    152: +newExecutable: (STR)theName
                    153: {
                    154:     return [self newExecutable: theName skipShlibs: NO withDesc: -1 cpuType: 0];
                    155: }
                    156: 
                    157: +newCore: (STR)theName
                    158: {
                    159:     SegmentManager *sm = [[super alloc] initFile: (STR)theName];
                    160:     if (sm && [sm isCore])
                    161:         return sm;
                    162:     else {
                    163:        [sm free];
                    164:        return nil;
                    165:     }
                    166: }
                    167: 
                    168: +newFile: (STR)theName
                    169: {
                    170:     return [[super alloc] initFile: (STR)theName];
                    171: }
                    172: 
                    173: +newShlib: (STR)theName cpuType: (cpu_type_t)type
                    174: {
                    175:     SegmentManager *sm = [[super alloc] initFile: (STR)theName
                    176:                                     skipShlibs: YES
                    177:                                      withDesc: -1
                    178:                                       cpuType: type];
                    179:     if (sm && [sm isShlib])
                    180:         return sm;
                    181:     else {
                    182:        [sm free];
                    183:        return nil;
                    184:     }
                    185: }
                    186: 
                    187: +newShlib: (STR)theName
                    188: {
                    189:     return [self newShlib: theName cpuType: 0];
                    190: }
                    191: 
                    192: +newHeader: (struct mach_header *)header withSize: (int)size
                    193: {
                    194:     return [[super alloc] initHeader: header withSize: size];
                    195: }
                    196: 
                    197: -(STR)executableName
                    198: {
                    199:     return name;
                    200: }
                    201: 
                    202: -(long)mtime
                    203: {
                    204:     return images[0].mtime;
                    205: }
                    206: 
                    207: -free
                    208: {
                    209:     NXMapRemove(managers, name);
                    210:     free(name); name = NULL;
                    211:     return [super free];
                    212: }
                    213: 
                    214: -invalidate
                    215: {
                    216:     int count;
                    217:     Image *image;
                    218:     
                    219:     if (images) {
                    220:        for (count = numImages, image = images; count; count--, image++) {
                    221:            if (image->deallocate)
                    222:                vm_deallocate(task_self(),
                    223:                                (vm_address_t)image->header,
                    224:                                image->size);
                    225:        }
                    226:        free(images); images = NULL;
                    227:        numImages = 0;
                    228:     }
                    229:     return [super invalidate];
                    230: }
                    231: 
                    232: -(void)getImages
                    233: {
                    234:     struct stat imageStat;
                    235:     struct load_command *loadCmd;
                    236:     struct fvmlib_command *fvmCmd;
                    237:     struct mach_header *header;
                    238:     int i;
                    239:     Image *image;
                    240:     numImages = 0;
                    241:     if (imageFd < 0)
                    242:        imageFd = open(name, O_RDONLY, 0);
                    243:     if (imageFd >= 0) {
                    244:        fstat(imageFd, &imageStat);
                    245:        if (map_fd(imageFd,
                    246:                   0,
                    247:                   (vm_address_t *)&header,
                    248:                   YES,
                    249:                   imageStat.st_size) == 0) {
                    250: //         printf("Map_fp successfull.\n");
                    251:            header = [self headerFromStart: header];
                    252:            if (header) {
                    253: //             printf("Got header.\n");
                    254:                numImages = 1;
                    255:                if (skipShlibs) {
                    256:                    images = malloc(sizeof(Image));
                    257:                    images->name = name;
                    258:                    images->header = header;
                    259:                    images->size = imageStat.st_size;
                    260:                    images->deallocate = YES;
                    261:                    images->mtime = imageStat.st_mtime;
                    262:                } else {
                    263:                    for (i = 0, loadCmd = (struct load_command *)(header + 1);
                    264:                         i < header->ncmds;
                    265:                         i++, ((void *)loadCmd) += loadCmd->cmdsize) {
                    266:                        if (loadCmd->cmd == LC_LOADFVMLIB) 
                    267:                            numImages++;
                    268:                    }
                    269:                    image
                    270:                    = images
                    271:                    = calloc(numImages, sizeof(Image));
                    272:                    image->name = name;
                    273:                    image->header = header;
                    274:                    image->size = imageStat.st_size;
                    275:                    image->deallocate = YES;
                    276:                    image->mtime = imageStat.st_mtime;
                    277:                    image++;
                    278:                    for (i = 0, loadCmd = (struct load_command *)(header + 1);
                    279:                         i < header->ncmds;
                    280:                         i++, ((void *)loadCmd) += loadCmd->cmdsize) {
                    281:                        int shlibFd;
                    282:                        if (loadCmd->cmd == LC_LOADFVMLIB) {
                    283:                            fvmCmd = (struct fvmlib_command *)loadCmd;
                    284:                            image->name
                    285:                            = (void *)fvmCmd + fvmCmd->fvmlib.name.offset;
                    286:                            shlibFd = open(image->name, O_RDONLY, 0);
                    287:                            if (shlibFd >= 0) {
                    288:                                fstat(shlibFd, &imageStat);
                    289:                                image->size = imageStat.st_size;
                    290:                                image->mtime = imageStat.st_mtime;
                    291:                                if (map_fd(shlibFd,
                    292:                                           0,
                    293:                                           (vm_address_t *)&image->header,
                    294:                                           YES,
                    295:                                           image->size)
                    296:                                          == 0) {
                    297:                                    image->header
                    298:                                    = [self headerFromStart: image->header];
                    299:                                    image->deallocate = YES;
                    300:                                    image++;
                    301:                                } else
                    302:                                    numImages--;
                    303:                                close(shlibFd);
                    304:                            } else
                    305:                                numImages--;
                    306:                        }
                    307:                    }
                    308:                }
                    309:            } else {
                    310:                return;
                    311:            }
                    312:        } else {
                    313:            extern int errno;
                    314: //         printf("Map_fd failed, errno = %d.\n", errno);
                    315:        }
                    316:        close(imageFd);
                    317:        imageFd = -1;
                    318:     }
                    319: }
                    320:                                                    
                    321: -(int)numSegments
                    322: {
                    323:     int count, numSegs = 0, i;
                    324:     Image *image;
                    325:     struct load_command *loadCmd;
                    326:     struct mach_header *header;
                    327:     for (count = numImages,
                    328:         image = images;
                    329:         count;
                    330:         count--, image++) {
                    331:        header = image->header;
                    332:        for (i = 0, loadCmd = (struct load_command *)(header + 1);
                    333:             i < header->ncmds;
                    334:             i++, ((void *)loadCmd) += loadCmd->cmdsize) {
                    335:            if (loadCmd->cmd == LC_SEGMENT) 
                    336:                numSegs++;
                    337:        }
                    338:     }
                    339:     return numSegs;
                    340: }
                    341: 
                    342: -(BOOL)validate
                    343: {
                    344:     int nImages, i;
                    345:     Image *image;
                    346:     struct mach_header *header;
                    347:     struct load_command *loadCmd;
                    348:     struct segment_command *segCmd;
                    349:     BOOL allOK = YES;
                    350:     for (nImages = numImages,
                    351:         image = images;
                    352:         allOK && nImages;
                    353:         nImages--, image++) {
                    354:        header = image->header;
                    355:        for (i = 0, loadCmd = (struct load_command *)(header + 1);
                    356:             allOK && i < header->ncmds;
                    357:             i++, ((void *)loadCmd) += loadCmd->cmdsize) {
                    358:            if (loadCmd->cmd == LC_SEGMENT) {
                    359:                segCmd = (struct segment_command *)loadCmd;
                    360:                if ((segCmd->fileoff + segCmd->vmsize) > image->size)
                    361:                    allOK = NO;
                    362:            }
                    363:            if (!loadCmd->cmdsize)
                    364:                allOK = NO;
                    365:        }
                    366:     }
                    367:     return allOK;
                    368: }
                    369: 
                    370: -(void)readInSegments
                    371: {
                    372:     int nImages, i;
                    373:     Image *image;
                    374:     struct mach_header *header;
                    375:     struct load_command *loadCmd;
                    376:     struct segment_command *segCmd;
                    377:     Segment *segment = relocs;
                    378:     for (nImages = numImages,
                    379:         image = images;
                    380:         nImages;
                    381:         nImages--, image++) {
                    382:        header = image->header;
                    383:        for (i = 0, loadCmd = (struct load_command *)(header + 1);
                    384:             i < header->ncmds;
                    385:             i++, ((void *)loadCmd) += loadCmd->cmdsize) {
                    386:            if (loadCmd->cmd == LC_SEGMENT) {
                    387:                segCmd = (struct segment_command *)loadCmd;
                    388:                segment->address = segCmd->vmaddr;
                    389:                segment->size = segCmd->vmsize;
                    390:                segment->data = (vm_address_t)header + segCmd->fileoff;
                    391:                segment->maxAddress = segment->address + segment->size;
                    392:                segment->displacement = segment->data - segment->address;
                    393:                segment->maxData = segment->data + segment->size;
                    394:                segment->segName = segCmd->segname;
                    395:                segment->rFlags.readIn = YES;
                    396:                ((void *)segment) += relocSize;
                    397:            }
                    398:        }
                    399:     }
                    400: }
                    401: 
                    402: -(void)_readInAllRelocs
                    403: {
                    404:     numRelocs = [self numSegments];
                    405:     relocs = calloc(numRelocs, relocSize);
                    406:     [self readInSegments];
                    407:     rmFlags.invalid = NO;
                    408: }
                    409: 
                    410: -(struct mach_header *)getMachHeader
                    411: {
                    412:     if (numImages)
                    413:        return images[0].header;
                    414:     else
                    415:        return NULL;
                    416: }
                    417: 
                    418: -(int)getNumMachHeaders
                    419: {
                    420:     return numImages;
                    421: }
                    422: 
                    423: -(struct mach_header **)getMachHeaders
                    424: {
                    425:     struct mach_header **headers;
                    426:     int headerIndex;
                    427:     headers = malloc((numImages + 1) * sizeof(*headers));
                    428:     for (headerIndex = 0; headerIndex < numImages; headerIndex++)
                    429:        headers[headerIndex] = images[headerIndex].header;
                    430:     headers[numImages] = NULL;
                    431:     return headers;
                    432: }
                    433: 
                    434: -(struct mach_header **)getMachHeadersWithNames: (char ***)names
                    435: {
                    436:     struct mach_header **headers;
                    437:     char **theNames;
                    438:     int headerIndex;
                    439:     headers = malloc((numImages + 1) * sizeof(*headers));
                    440:     *names = theNames = malloc((numImages + 1) * sizeof(*theNames));
                    441:     for (headerIndex = 0; headerIndex < numImages; headerIndex++) {
                    442:        headers[headerIndex] = images[headerIndex].header;
                    443:        theNames[headerIndex] = images[headerIndex].name;
                    444:     }
                    445:     headers[numImages] = NULL;
                    446:     theNames[numImages] = NULL;
                    447:     return headers;
                    448: }
                    449: 
                    450: -(struct load_command *)findLoadCommand: (unsigned long)command
                    451:                               forHeader: (struct mach_header *)header
                    452: {
                    453:     int i;
                    454:     struct load_command *loadCmd, *foundCmd = NULL;
                    455:     for (i = 0, loadCmd = (struct load_command *)(header + 1);
                    456:         i < header->ncmds && !foundCmd;
                    457:         i++, ((void *)loadCmd) += loadCmd->cmdsize) {
                    458:        if (loadCmd->cmd == command)
                    459:            foundCmd = loadCmd;
                    460:     }
                    461:     return foundCmd;
                    462: }
                    463: 
                    464: -(int)numCommands: (unsigned long)command
                    465:         forHeader: (struct mach_header *)header
                    466: {
                    467:     int i, nCommands = 0;
                    468:     struct load_command *loadCmd;
                    469:     for (i = 0, loadCmd = (struct load_command *)(header + 1);
                    470:         i < header->ncmds;
                    471:         i++, ((void *)loadCmd) += loadCmd->cmdsize) {
                    472:        if (loadCmd->cmd == command)
                    473:            nCommands++;
                    474:     }
                    475:     return nCommands;
                    476: }
                    477: 
                    478: -(struct symtab_command *)symCmd
                    479: {
                    480:     return (struct symtab_command *)
                    481:              [self findLoadCommand: LC_SYMTAB
                    482:                         forHeader: images[0].header];
                    483: }
                    484: 
                    485: -(char *)stringTable
                    486: {
                    487:     struct symtab_command *symCmd = [self symCmd];
                    488:     return (char *)(images[0].header) + symCmd->stroff;
                    489: }
                    490: 
                    491: -(BOOL)isCore
                    492: {
                    493:     return images && images[0].header->filetype == MH_CORE;
                    494: }
                    495: 
                    496: -(BOOL)isShlib
                    497: {
                    498:     return images && images[0].header->filetype == MH_FVMLIB;
                    499: }
                    500: 
                    501: -(BOOL)isExecutable
                    502: {
                    503:     BOOL ret = images && ((images[0].header->filetype == MH_EXECUTE)
                    504:                      || (images[0].header->filetype == MH_OBJECT)
                    505:                       || (images[0].header->filetype == MH_PRELOAD));
                    506: //    if (ret)
                    507: //     printf("Is executable.\n");
                    508: //    else
                    509: //     printf("Isn't executable.\n");
                    510:     return ret;
                    511: }
                    512: 
                    513: @end

unix.superglobalmegacorp.com

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