|
|
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 <libc.h>
26: #import <stdio.h>
27: #import <streams/streams.h>
28: #import <mach-o/loader.h>
29:
30: #define SIZEHASHTABLE 821
31:
32: typedef struct optHashedSelector OHASH, *POHASH;
33:
34: struct optHashedSelector {
35: POHASH next;
36: const char * key_uid;
37: };
38:
39: #define MAP_HASH(x) \
40: (x ? (void *) ((int) hashtable + (int) (x) - hashtable_addr) : NULL)
41: #define MAP_STRING(x) \
42: (x ? (void *) ((int) strings + (int) (x) - strings_addr): NULL)
43: #define UNMAP_HASH(x) \
44: (x ? (void *) (hashtable_addr + (int) (x) - (int) hashtable) : NULL)
45:
46: int main (int argc, char *argv[])
47: {
48: NXStream *stream;
49: char *buffer;
50: int length, allocLength;
51: const struct mach_header *header;
52: const struct section *section;
53: POHASH *hashtable;
54: const char *strings;
55: int hashtable_addr, strings_addr, strings_size, hashtable_size;
56: unsigned int i;
57: unsigned int maxLength = 0;
58: unsigned int total = 0;
59: unsigned int emptyBuckets = 0;
60:
61: if (argc != 2)
62: {
63: fprintf (stderr, "usage: %s filename\n", argv[0]);
64: return EXIT_FAILURE;
65: }
66:
67: stream = NXMapFile (argv[1], NX_READONLY);
68:
69: NXGetMemoryBuffer (stream, &buffer, &length, &allocLength);
70:
71: header = (const struct mach_header *) buffer;
72:
73: section = getsectbynamefromheader (header, "__OBJC", "__runtime_setup");
74:
75: if (!section || section->size == 0)
76: {
77: fprintf (stderr, "cannot find __runtime_setup section\n");
78: exit (EXIT_FAILURE);
79: }
80:
81: hashtable_addr = (int) section->addr;
82: hashtable_size = (int) section->size;
83: hashtable = (POHASH *) (buffer + section->offset);
84:
85: printf ("%d hashtable entries from 0x%x to 0x%x\n",
86: SIZEHASHTABLE,
87: hashtable_addr,
88: hashtable_addr + SIZEHASHTABLE * sizeof (POHASH));
89: printf ("%d buckets from 0x%x to 0x%x\n",
90: (hashtable_size - SIZEHASHTABLE * sizeof (POHASH)) / sizeof (OHASH),
91: hashtable_addr + SIZEHASHTABLE * sizeof (POHASH),
92: hashtable_addr + hashtable_size);
93:
94: section = getsectbynamefromheader (header, "__OBJC", "__meth_var_names");
95:
96: if (!section || section->size == 0)
97: section = getsectbynamefromheader (header, "__OBJC", "__selector_strs");
98:
99: if (!section || section->size == 0)
100: {
101: fprintf (stderr,
102: "cannot find __meth_var_names or __selector_strs section\n");
103: exit (EXIT_FAILURE);
104: }
105:
106: strings_addr = (int) section->addr;
107: strings_size = (int) section->size;
108: strings = (const char *) (buffer + section->offset);
109:
110: printf ("%d bytes of strings from 0x%x to 0x%x\n",
111: strings_size,
112: strings_addr,
113: strings_addr + strings_size);
114:
115: for (i = 0; i < SIZEHASHTABLE; i++)
116: {
117: POHASH target = MAP_HASH (hashtable[i]);
118: int length = 0;
119:
120: // printf ("hash[%d]:", i);
121:
122: while (target)
123: {
124: POHASH next;
125: const char *string = MAP_STRING (target->key_uid);
126:
127: length++;
128:
129: if (string < strings || strings >= strings + strings_size)
130: {
131: printf ("Bad string pointer 0x%x in entry %d at address 0x%x\n",
132: string, i, UNMAP_HASH (&target->key_uid));
133: target = 0;
134: continue;
135: }
136: if (string != strings && string[-1] != '\0')
137: {
138: const char *start = strrchr (string - 1, '\0') + 1;
139:
140: printf ("bad string %s in entry %d (substring of %s)\n",
141: string, i, start);
142: }
143: // printf ( " %s", string);
144: next = MAP_HASH (target->next);
145: if (next && (next < (POHASH) &hashtable[SIZEHASHTABLE]
146: || next >= (POHASH) ((int) hashtable + hashtable_size)))
147: {
148: printf ("Bad next pointer 0x%x in entry %d at address 0x%x\n",
149: next, i, UNMAP_HASH (&target->next));
150: next = 0;
151: }
152: target = next;
153: }
154:
155: // printf ("\n");
156:
157: total += length;
158:
159: if (length == 0)
160: emptyBuckets++;
161:
162: if (length > maxLength)
163: maxLength = length;
164: }
165:
166: printf ("%d buckets\n", SIZEHASHTABLE);
167: printf ("%d entries\n", total);
168: printf ("%f average entries/bucket\n", (float) total / SIZEHASHTABLE);
169: printf ("%d maximum entries/bucket\n", maxLength);
170: printf ("%d empty buckets\n", emptyBuckets);
171:
172: return EXIT_SUCCESS;
173: }
174:
175: #if 0
176: ��
177: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.