File:  [Apple Darwin 0.x] / objc / Test / ostats / RegionManager.m
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:13:59 2018 UTC (8 years, 2 months ago) by root
Branches: MAIN, Apple
CVS tags: HEAD, Darwin03, Darwin01
Darwin 0.1 In-kernel Objective-C runtime

/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 * Reserved.  This file contains Original Code and/or Modifications of
 * Original Code as defined in and that are subject to the Apple Public
 * Source License Version 1.0 (the 'License').  You may not use this file
 * except in compliance with the License.  Please obtain a copy of the
 * License at http://www.apple.com/publicsource and read it before using
 * this file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 * License for the specific language governing rights and limitations
 * under the License."
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
#import "RegionManager.h"

#import <stdlib.h>
#import <string.h>
#import <sys/loader.h>

@implementation RegionManager

-initialize:  (vm_task_t)theTask
{
	regions = [Storage	newCount:	0 
					elementSize:	sizeof(Region) 
					description:	@encode(Region)];						
	task = theTask;
	return self;
}
+newTask: (vm_task_t)theTask
{
	return [[super new] initialize: theTask];
}

-free
{
	int count;
	Region *region;
	for (count = [regions count]; count; count--) {
		region = [regions elementAt: (count - 1)];
		vm_deallocate(task_self(), region->data, region->dataCount);
	}
	[regions free];
	return [super free];
}

-(Region *)regionFor: (void *)pointer
{
	Region newRegion;
	kern_return_t error = NO;
	Region *region = NULL;
	int count;
	BOOL found;
	for (count = [regions count], found = NO; count && !found; count--) {
		region = [regions elementAt: (count - 1)];
		if (	(region->address <= (pointer_t)pointer) 
			&& ((pointer_t)pointer < (region->maxAddress)))
			found = YES;
	}
	if (!found) {
		newRegion.address = (vm_address_t)pointer;
		error = vm_region(	task, 
						&newRegion.address,
						&newRegion.size,
						&newRegion.protection,
						&newRegion.maxProtection,
						&newRegion.inheritance,
						&newRegion.shared,
						&newRegion.objectName,
						&newRegion.offset);
		if (!error && (newRegion.protection & VM_PROT_READ)) {
			error = vm_read(	task,
							newRegion.address,
							newRegion.size,
							&newRegion.data,
							&newRegion.dataCount);
			if (!error) {
				newRegion.maxAddress = newRegion.address + newRegion.size;
				newRegion.maxData = newRegion.data + newRegion.size;
				newRegion.displacement = newRegion.data - newRegion.address;
				[regions addElement: &newRegion];
				region = &newRegion;
			} else
				region = NULL;
		} else
			region = NULL;
	}
	return region;
}

-invalidate
{
	int count;
	Region *region;
	for (count = [regions count]; count; count--) {
		region = [regions elementAt: (count - 1)];
		vm_deallocate(task_self(), region->data, region->dataCount);
	}
	[regions empty];
	return self;
}

-(Region *)oldRegionFor: (void *)pointer
{
	Region *region = NULL;
	int count;
	BOOL found;
	for (count = [regions count], found = NO; count && !found; count--) {
		region = [regions elementAt: (count - 1)];
		if ((region->data <= (pointer_t)pointer) 
			&& ((pointer_t)pointer < region->maxData))
			found = YES;
	}
	if (found)
		return region;
	else
		return NULL;
}

-(void *)originalPointerFor: (void *)pointer
{	
	Region *region = [self oldRegionFor: pointer];
	if (region)
		return (region->address + (pointer - region->data));
	else 
		return NULL;
}

-(void *)pointerFor: (void *)pointer
{
	Region *region;
	if (pointer && (region = [self  regionFor: pointer])) 
		return (void *)((pointer_t)pointer + region->displacement);
	else
		return NULL;
}

-(void *)pointerFor: (void *)pointer withSize: (int)size
{
	Region *region;
	pointer_t newPointer;
	if (pointer && (region = [self regionFor: pointer])) {
		newPointer = (pointer_t)pointer + region->displacement;
		if ((newPointer + size) < region->maxData)
			return (void *)newPointer;
		else
			return NULL;
	} else
		return NULL;
}

-(id)pointerForID: (id)pointer
{
	Region *region;
	pointer_t newID;
	Class theClass;
	if (pointer && (region = [self regionFor: pointer])) {
		newID = (pointer_t)pointer + region->displacement;
		if (	((newID + sizeof(id)) < region->maxData) 
		&&	(theClass = [self pointerFor: ((id)newID)->isa withSize: sizeof(Class)])
		&&	((newID + theClass->instance_size) < region->maxData))
			return (id)newID;
		else
			return NULL;
	} else
		return NULL;
}
			

-(BOOL)getDataAt: (void *)start for: (int)numBytes into: (void *)data
{
	Region *region = [self regionFor: start];
	if (region) {
		if (((pointer_t)start + numBytes) < (region->address + region->size)) {
			memcpy(data, (void *)(region->data + ((pointer_t)start - region->address)), numBytes);
			return YES;
		} else
			return NO;
	} else
		return NO;
}

-(struct mach_header *)getMachHeader
{
	BOOL found;
	Region *region;
	Region newRegion;
	struct mach_header *myHeader = NULL, *hisHeader;
	for (	found = NO, hisHeader = 0x0000; 
		!found; 
		hisHeader = (struct mach_header *)(region->address + region->size)) {
		region = [self regionFor: hisHeader];
		if (region) { 
			myHeader = (struct mach_header *)(region->data + ((pointer_t)hisHeader - region->address));
			if (myHeader->magic == MH_MAGIC)
				found = YES;
		} else {
			newRegion.address = (vm_address_t) hisHeader;
			vm_region(	task, 
						&newRegion.address,
						&newRegion.size,
						&newRegion.protection,
						&newRegion.maxProtection,
						&newRegion.inheritance,
						&newRegion.shared,
						&newRegion.objectName,
						&newRegion.offset);
			region = &newRegion;
		}
	}
	return myHeader;
}

-(struct mach_header **)getMachHeaders
{
	struct mach_header *myHeader, **headers;
	struct fvmlib_command *loadCmd;
	int numHeaders, i, headerIndex;
	myHeader = [self getMachHeader];
	for (	i = 0, numHeaders = 0, loadCmd = (struct fvmlib_command *)(myHeader + 1); 
		i < myHeader->ncmds;
		i++, loadCmd = (struct fvmlib_command *)((char *)loadCmd + loadCmd->cmdsize)) {
		if (loadCmd->cmd == LC_LOADFVMLIB)
			numHeaders++;
	}
	headers = malloc((numHeaders + 2) * sizeof(*headers));
	headers[0] = myHeader;
	for (	headerIndex = 1, loadCmd = (struct fvmlib_command *)(myHeader + 1); 
		headerIndex <= numHeaders;
		loadCmd = (struct fvmlib_command *)((char *)loadCmd + loadCmd->cmdsize)) {
		if (loadCmd->cmd == LC_LOADFVMLIB) {
			headers[headerIndex] = [self pointerFor: (void *)(loadCmd->fvmlib.header_addr)];
			/* snaroff */
			headers[headerIndex]->flags =  
				(char *)[self originalPointerFor:loadCmd] + 
					loadCmd->fvmlib.name.offset;
			headerIndex++;
		}
	}
	headers[headerIndex] = NULL;
	return headers;
}

-(void *)	getSectData: 	(STR)segName 
		section: 		(STR)sectName 
		size: 		(int *)pSize 
		forHeader:	(struct mach_header *)header
{
	void *data = getsectdatafromheader(header, segName, sectName, pSize);
	return [self pointerFor: data];
}

-(void *)	getSectData: 	(STR)segName 
		section: 		(STR)sectName 
		size: 		(int *)pSize 
{
	return [self getSectData: segName section: sectName size: pSize forHeader: [self getMachHeader]];
}

@end


















unix.superglobalmegacorp.com

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