|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.0 (the 'License'). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License." ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: #import <objc/Storage.h> ! 26: #import <objc/List.h> ! 27: #import <objc/HashTable.h> ! 28: #import <objc/objc-runtime.h> ! 29: ! 30: ! 31: #import "RegionManager.h" ! 32: #import "ObjcImage.h" ! 33: #import <sys/loader.h> ! 34: ! 35: struct section *getsectbynamefromheader(struct mach_header *, char *, char *); ! 36: ! 37: @implementation ObjcImage ! 38: ! 39: ! 40: + newFromHeader:(struct mach_header *)mh ! 41: { ! 42: self = [super new]; ! 43: machhdr = mh; ! 44: pagehash = [HashTable newKeyDesc:"i"]; ! 45: instanceCachePageHash = [HashTable newKeyDesc:"i"]; ! 46: classCachePageHash = [HashTable newKeyDesc:"i"]; ! 47: return self; ! 48: } ! 49: ! 50: - regionManager:region ! 51: { ! 52: regionManager = region; ! 53: return self; ! 54: } ! 55: ! 56: - getModules ! 57: { ! 58: Module mod; ! 59: Symtab symtab; ! 60: ! 61: modPtr = [regionManager ! 62: getSectData: SEG_OBJC ! 63: section: SECT_OBJC_MODULES ! 64: size: &modSize ! 65: forHeader: machhdr]; ! 66: ! 67: //printf("%x\n",modPtr+modSize); ! 68: ! 69: for ( mod = modPtr; ! 70: mod < (STR)modPtr + modSize; ! 71: mod = (Module)((STR)mod + mod->size)) { ! 72: char *name = mod->name; ! 73: int idx; ! 74: ! 75: /* relocate module */ ! 76: mod->name = WARP(mod->name); ! 77: //printf("module = %x, %s (%x, %x)\n",mod,mod->name, UNWARP(mod->name), name); ! 78: ! 79: if (symtab = mod->symtab = WARP(mod->symtab)) { ! 80: ! 81: /* collect some statistics */ ! 82: n_selrefs += symtab->sel_ref_cnt; ! 83: n_classes += symtab->cls_def_cnt; ! 84: n_categories += symtab->cat_def_cnt; ! 85: ! 86: /* relocate classes */ ! 87: for (idx = 0; idx < symtab->cls_def_cnt; idx++) { ! 88: ! 89: Class myClass, myMetaClass; ! 90: struct objc_method_list *methods; ! 91: void *page; ! 92: ! 93: page = (unsigned int)symtab->defs[idx] - ! 94: ((unsigned int)symtab->defs[idx] % 0x2000); ! 95: [pagehash insertKey:page value:symtab->defs[idx]]; ! 96: ! 97: if (myClass = symtab->defs[idx] = WARP(symtab->defs[idx])) { ! 98: myClass->name = WARP(myClass->name); ! 99: myMetaClass = myClass->isa = WARP(myClass->isa); ! 100: if (CLS_GETINFO(myMetaClass, CLS_INITIALIZED)) ! 101: n_classesInUse++; ! 102: ! 103: /* relocate instance methods */ myClass->methods = methods = WARP(myClass->methods); ! 104: if (methods) ! 105: n_instanceMethods += methods->method_count; ! 106: ! 107: while (methods && methods->method_next) { ! 108: /* we have some categories */ methods->method_next = methods = WARP(methods->method_next); if (methods) ! 109: n_instanceMethods += methods->method_count; ! 110: } ! 111: ! 112: /* relocate instance method cache */ ! 113: if (myClass->cache) { ! 114: page = (unsigned int)myClass->cache - ! 115: ((unsigned int)myClass->cache % 0x2000); ! 116: [instanceCachePageHash ! 117: insertKey:page value:myClass->cache]; ! 118: ! 119: myClass->cache = WARP(myClass->cache); ! 120: n_instanceCacheSlots += (myClass->cache->mask+1); ! 121: n_instanceCacheOccupied += myClass->cache->occupied; ! 122: n_instanceCache++; } ! 123: ! 124: /* relocate class methods */ myMetaClass->methods = methods = WARP(myMetaClass->methods); ! 125: if (methods) ! 126: n_classMethods += methods->method_count; ! 127: ! 128: while (methods && methods->method_next) { ! 129: /* we have some categories */ methods->method_next = methods = WARP(methods->method_next); if (methods) ! 130: n_classMethods += methods->method_count; ! 131: } ! 132: ! 133: /* relocate class method cache */ ! 134: if (myMetaClass->cache) { ! 135: page = (unsigned int)myMetaClass->cache - ! 136: ((unsigned int)myMetaClass->cache % 0x2000); ! 137: [classCachePageHash ! 138: insertKey:page value:myMetaClass->cache]; ! 139: ! 140: myMetaClass->cache = WARP(myMetaClass->cache); ! 141: n_classCacheSlots += (myMetaClass->cache->mask+1); ! 142: n_classCacheOccupied += myMetaClass->cache->occupied; ! 143: n_classCache++; } ! 144: ! 145: //printf("class = %s\n",myClass->name); ! 146: } ! 147: } ! 148: ! 149: /* relocate categories */ ! 150: for (idx = 0; idx < symtab->cat_def_cnt; idx++) { ! 151: ! 152: Category myCategory; ! 153: ! 154: if (myCategory = symtab->defs[idx + symtab->cls_def_cnt] = ! 155: WARP(symtab->defs[idx + symtab->cls_def_cnt])) { ! 156: myCategory->category_name = WARP(myCategory->category_name); ! 157: //printf("category = %s\n",myCategory->category_name); ! 158: } ! 159: } ! 160: } ! 161: } ! 162: printf("\n************************************************" ! 163: "*************************\n"); ! 164: if (machhdr->filetype == MH_EXECUTE) ! 165: printf("\nApplication image statistics\n\n"); ! 166: else if (machhdr->filetype == MH_FVMLIB) { ! 167: printf("\nShared library image statistics for %s\n\n", WARP((char *)machhdr->flags)); ! 168: } ! 169: ! 170: printf("%d classes (%d categories) - class descriptors spread across %d pages.\n", ! 171: n_classes, n_categories, [pagehash count]); ! 172: printf("%d classes currently in use\n", n_classesInUse); ! 173: printf("%d instance methods, %d class methods\n",n_instanceMethods, n_classMethods); ! 174: printf("%d selector references\n",n_selrefs); ! 175: ! 176: printf("\nMethod Cache Info (caches are dynamically allocated):\n\n"); ! 177: if (n_instanceCache) { ! 178: printf("%d instance caches - caches spread across %d pages.\n", ! 179: n_instanceCache, [instanceCachePageHash count]); ! 180: printf("%d currently in use / %d method slots (%3.2f%% full).\n", ! 181: n_instanceCacheOccupied, n_instanceCacheSlots, ! 182: (float)n_instanceCacheOccupied/n_instanceCacheSlots * 100); ! 183: printf("%d bytes to cache instance methods ", ! 184: ((n_instanceCache * sizeof(struct objc_cache)) + ! 185: (n_instanceCacheSlots * sizeof(Method)))); ! 186: printf("(%d bytes per class)\n", ! 187: ((n_instanceCache * sizeof(struct objc_cache)) + ! 188: (n_instanceCacheSlots * sizeof(Method)))/n_instanceCache); ! 189: } ! 190: if (n_classCache) { ! 191: printf("%d class caches - caches spread across %d pages.\n", ! 192: n_classCache, [classCachePageHash count]); ! 193: printf("%d currently in use / %d method slots (%3.2f%% full).\n", ! 194: n_classCacheOccupied, n_classCacheSlots, ! 195: (float)n_classCacheOccupied/n_classCacheSlots * 100); ! 196: printf("%d bytes to cache class methods ", ! 197: ((n_classCache * sizeof(struct objc_cache)) + ! 198: (n_classCacheSlots * sizeof(Method)))); ! 199: printf("(%d bytes per meta class)\n", ! 200: ((n_classCache * sizeof(struct objc_cache)) + ! 201: (n_classCacheSlots * sizeof(Method)))/n_classCache); ! 202: } ! 203: return self; ! 204: } ! 205: ! 206: ! 207: @end ! 208: ! 209: ! 210: ! 211: ! 212: ! 213: ! 214: ! 215: ! 216: ! 217: ! 218: ! 219:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.