|
|
1.1 root 1: #import "RelocManager.h"
2: #import <stdlib.h>
3: #import <string.h>
4: #import <mach-o/loader.h>
5: #import <libc.h>
6:
7: @implementation RelocManager
8:
9: -init
10: {
11: rmFlags.invalid = YES;
12: rmFlags.shouldSortRelocs = YES;
13: return self;
14: }
15:
16: -free
17: {
18: [self invalidate];
19: return [super free];
20: }
21:
22: int compareRelocsSort(const void *v1, const void *v2)
23: {
24: const Reloc *r1 = v1, *r2 = v2;
25: pointer_t a1 = r1->address, a2 = r2->address;
26: return a1 < a2 ? -1 : (a1 == a2 ? 0 : 1);
27: }
28:
29: int compareRelocsSearch(const void *v1, const void *v2)
30: {
31: const Reloc *r1 = v1, *r2 = v2;
32: pointer_t address = r1->address;
33: return address < r2->address ? -1 : (address >= r2->maxAddress ? 1 : 0);
34: }
35:
36: -(Reloc *)relocFor: (const void *)pointer
37: {
38: Reloc *reloc;
39: int count;
40: BOOL found, tooFar;
41: if (rmFlags.invalid)
42: [self readInAllRelocs];
43: if (lastReloc
44: && (lastReloc->address <= (pointer_t)pointer)
45: && ((pointer_t)pointer < (lastReloc->maxAddress)))
46: return lastReloc;
47: else {
48: #if 1
49: Reloc keyReloc;
50: keyReloc.address = (pointer_t)pointer;
51: if (reloc = bsearch(&keyReloc, relocs, numRelocs, relocSize, compareRelocsSearch))
52: found = YES;
53: else
54: found = NO;
55: #else
56: reloc = relocs;
57: for (count = numRelocs, found = NO, tooFar = NO;
58: count && !found && !tooFar; count--) {
59: if ((pointer_t)pointer < (reloc->maxAddress)) {
60: if (reloc->address <= (pointer_t)pointer)
61: found = YES;
62: else
63: tooFar = YES;
64: } else
65: ((void *)reloc) += relocSize;
66: }
67: #endif
68: if (found && (reloc->rFlags.readIn || [self readInReloc: reloc])) {
69: lastReloc = reloc;
70: return reloc;
71: } else
72: return NULL;
73: }
74: }
75:
76: -(BOOL)readInReloc: (Reloc *)reloc
77: {
78: [self subclassResponsibility: _cmd];
79: return NO;
80: }
81:
82: -(void)_readInAllRelocs
83: {
84: [self subclassResponsibility: _cmd];
85: }
86:
87: -(void)readInAllRelocs
88: {
89: [self _readInAllRelocs];
90: if (rmFlags.shouldSortRelocs)
91: qsort(relocs, numRelocs, relocSize, compareRelocsSort);
92: }
93:
94: -invalidate
95: {
96: if (rmFlags.invalid)
97: return self;
98: else {
99: if (relocs) {
100: free(relocs); relocs = NULL;
101: }
102: numRelocs = 0;
103: lastReloc = NULL;
104: rmFlags.invalid = YES;
105: return self;
106: }
107: }
108:
109: -(Reloc *)oldRelocFor: (const void *)pointer
110: {
111: int count;
112: BOOL found;
113: Reloc *reloc;
114: if (lastReloc
115: && (lastReloc->data <= (pointer_t)pointer)
116: && ((pointer_t)pointer < lastReloc->maxData))
117: return lastReloc;
118: else {
119: reloc = relocs;
120: for (count = numRelocs, found = NO; count && !found; count--) {
121: if (reloc->rFlags.readIn && (reloc->data <= (pointer_t)pointer)
122: && ((pointer_t)pointer < reloc->maxData))
123: found = YES;
124: else
125: ((void *)reloc) += relocSize;
126: }
127: if (found) {
128: lastReloc = reloc;
129: return reloc;
130: } else
131: return NULL;
132: }
133: }
134:
135: -(void *)originalPointerFor: (const void *)pointer
136: {
137: Reloc *reloc = [self oldRelocFor: pointer];
138: if (reloc)
139: return (void *)(reloc->address + (pointer - reloc->data));
140: else
141: return NULL;
142: }
143:
144: -(void *)pointerFor: (const void *)pointer
145: {
146: Reloc *reloc;
147: if (pointer && (reloc = [self relocFor: pointer]))
148: return (void *)((pointer_t)pointer + reloc->displacement);
149: else
150: return NULL;
151: }
152:
153: -(char *)pointerForString: (const char *)pointer isNullTerminated: (BOOL *)isNT
154: {
155: char *retPointer;
156: Reloc *reloc;
157: char *string;
158: if (pointer && (reloc = [self relocFor: pointer])) {
159: retPointer = (char *)((pointer_t)pointer + reloc->displacement);
160: for (string = retPointer;
161: *string && ((pointer_t)string < reloc->maxData);
162: string++);
163: *isNT = *string ? NO : YES;
164: return retPointer;
165: } else{
166: *isNT = NO;
167: return NULL;
168: }
169: }
170:
171: -(char *)pointerForString: (const char *)string
172: {
173: BOOL isNT;
174: char *retPointer;
175: if ((retPointer = [self pointerForString: string isNullTerminated: &isNT])
176: && isNT)
177: return retPointer;
178: else
179: return NULL;
180: }
181:
182: -(void *)pointerFor: (const void *)pointer withSize: (int)size
183: {
184: Reloc *reloc;
185: pointer_t newPointer;
186: if (pointer && (reloc = [self relocFor: pointer])) {
187: newPointer = (pointer_t)pointer + reloc->displacement;
188: if ((newPointer + size) <= reloc->maxData)
189: return (void *)newPointer;
190: else
191: return NULL;
192: } else
193: return NULL;
194: }
195:
196: -(id)pointerForID: (const id)pointer
197: {
198: Class theClass;
199: struct _ObjectID {
200: @defs(Object)
201: } *newID;
202:
203: if (pointer
204: && (newID = [self pointerFor: pointer withSize: sizeof(id)])
205: && (theClass = [self pointerFor: newID->isa
206: withSize: sizeof(Class)])
207: && (newID
208: = [self pointerFor: pointer withSize: theClass->instance_size]))
209: return (id)newID;
210: else
211: return nil;
212: }
213:
214: -(int)getDataAt: (const void *)start for: (int)numBytes into: (void *)data
215: {
216: Reloc *reloc = [self relocFor: start];
217: int numBytesInReloc;
218:
219: if (reloc) {
220: numBytesInReloc = reloc->maxAddress - (int)start;
221: if (numBytes > numBytesInReloc)
222: numBytes = numBytesInReloc;
223: memcpy(data,
224: (void *)(reloc->data + ((pointer_t)start - reloc->address)),
225: numBytes);
226: return numBytes;
227: } else
228: return 0;
229: }
230:
231: -(struct mach_header *)getMachHeader
232: {
233: [self subclassResponsibility: _cmd];
234: return NULL;
235: }
236:
237: -(int)getNumMachHeaders
238: {
239: [self subclassResponsibility: _cmd];
240: return 0;
241: }
242:
243: -(struct mach_header **)getMachHeaders
244: {
245: [self subclassResponsibility: _cmd];
246: return NULL;
247: }
248:
249: -(struct mach_header **)getMachHeadersWithNames: (char ***)names
250: {
251: [self subclassResponsibility: _cmd];
252: return NULL;
253: }
254:
255: -(void *)getSectData: (STR)segName
256: section: (STR)sectName
257: size: (int *)pSize
258: forHeader: (struct mach_header *)header
259: {
260: void *data = getsectdatafromheader(header, segName, sectName, pSize);
261: return [self pointerFor: data withSize: *pSize];
262: }
263:
264: -(void *)getSectData: (STR)segName
265: section: (STR)sectName
266: size: (int *)pSize
267: {
268: return [self getSectData: segName
269: section: sectName
270: size: pSize
271: forHeader: [self getMachHeader]];
272: }
273:
274: -(const struct section *)getSeg: (STR)segName sect: (STR)sectName
275: {
276: return getsectbynamefromheader([self getMachHeader], segName, sectName);
277: }
278:
279: -(const struct section *)firstSection
280: {
281: struct mach_header *header = [self getMachHeader];
282: int i;
283: struct load_command *loadCmd;
284:
285: for (i = 0, loadCmd = (struct load_command *)(header + 1);
286: i < header->ncmds;
287: i++, ((void *)loadCmd) += loadCmd->cmdsize) {
288: if (loadCmd->cmd == LC_SEGMENT) {
289: struct segment_command *segCmd = (struct segment_command *)loadCmd;
290: if (segCmd->nsects)
291: return (struct section *)(segCmd + 1);
292: }
293: }
294: return NULL;
295: }
296:
297: -(unsigned)getMaximumAddressForHeader: (struct mach_header *)header
298: {
299: int i;
300: struct load_command *loadCmd;
301: unsigned maxAddr = 0;
302:
303: for (i = 0, loadCmd = (struct load_command *)(header + 1);
304: i < header->ncmds;
305: i++, ((void *)loadCmd) += loadCmd->cmdsize) {
306: if (loadCmd->cmd == LC_SEGMENT) {
307: struct segment_command *segCmd = (struct segment_command *)loadCmd;
308: if ((segCmd->vmaddr + segCmd->vmsize) > maxAddr)
309: maxAddr = segCmd->vmaddr + segCmd->vmsize;
310: }
311: }
312: return maxAddr;
313: }
314:
315: -(struct segment_command *)getSegment: (const char *)segName
316: {
317: int i;
318: struct load_command *loadCmd;
319: struct segment_command *foundSeg = NULL;
320: struct mach_header *header = [self getMachHeader];
321:
322: for (i = 0, loadCmd = (struct load_command *)(header + 1);
323: i < header->ncmds && !foundSeg;
324: i++, ((void *)loadCmd) += loadCmd->cmdsize) {
325: if (loadCmd->cmd == LC_SEGMENT) {
326: struct segment_command *segCmd = (struct segment_command *)loadCmd;
327: if (strcmp(segName, segCmd->segname) == 0)
328: foundSeg = segCmd;
329: }
330: }
331: return foundSeg;
332: }
333:
334: -(unsigned)getMaximumAddressForSegment: (const char *)segName
335: {
336: int i;
337: struct load_command *loadCmd;
338: unsigned maxAddr = 0;
339: struct mach_header *header = [self getMachHeader];
340:
341: for (i = 0, loadCmd = (struct load_command *)(header + 1);
342: i < header->ncmds;
343: i++, ((void *)loadCmd) += loadCmd->cmdsize) {
344: if (loadCmd->cmd == LC_SEGMENT) {
345: struct segment_command *segCmd = (struct segment_command *)loadCmd;
346: struct section *section;
347: int nSects;
348:
349: for (nSects = segCmd->nsects,
350: section = (struct section *)(segCmd + 1);
351: nSects;
352: nSects--, section++) {
353: if (strcmp(section->segname, segName) == 0) {
354: if ((section->addr + section->size) > maxAddr)
355: maxAddr = (section->addr + section->size);
356: }
357: }
358: }
359: }
360: return maxAddr;
361: }
362:
363: -(unsigned)getMaximumAddress
364: {
365: return [self getMaximumAddressForHeader: [self getMachHeader]];
366: }
367:
368: -(unsigned)getMaximumTextAddress
369: {
370: return [self getMaximumAddressForSegment: "__TEXT"];
371: }
372:
373: -(unsigned)getMaximumDataAddress
374: {
375: return [self getMaximumAddressForSegment: "__DATA"];
376: }
377:
378: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.