|
|
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.