|
|
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: #ifdef SHLIB ! 25: #import "shlib.h" ! 26: #undef moninitobjc ! 27: #endif ! 28: ! 29: #ifndef __ppc__ ! 30: #error "this is ppc machine dependent" ! 31: #endif ! 32: ! 33: #include <mach/mach.h> ! 34: ! 35: /* ! 36: * objc_exitPoints is a private_extern defined in the objective-C messager ! 37: * which is a zero terminated table of a list of text lables to write ! 38: * instructions which will cause the objective-C messager to then call ! 39: * moncount for each message it dispatches. The instruction at each of these ! 40: * text lables is a "bctr" instruction. The objective-C messager has ! 41: * allocated space after each of these instructions for moninitobjc to write ! 42: * the instructions to call moncount for each message it dispatches. ! 43: * ! 44: * The instructions written over the "bctr" and the allocated space after ! 45: * it are: ! 46: * exitPoint1: bctr ! 47: * ; replace with the following instructions ! 48: * stw r3, 24(r1) ; save register parameters ! 49: * stw r4, 28(r1) ; ! 50: * stw r5, 32(r1) ; ! 51: * stw r6, 36(r1) ; ! 52: * stw r7, 40(r1) ; ! 53: * stw r8, 44(r1) ; ! 54: * stw r9, 48(r1) ; ! 55: * stw r10,52(r1) ; ! 56: * mflr r0 ; move LR to r0 ! 57: * stw r0,8(r1) ; save LR (return addr) ! 58: * mfcr r12 ; move CTR to r12 ! 59: * stw r12,4(r1) ; save CTR (imp) ! 60: * stwu r1,-64(r1) ; grow the stack ! 61: * ! 62: * ori r3,r0,0 ; first arg is frompc (return addr) ! 63: * ori r4,r12,0 ; second arg is selfpc (imp) ! 64: * bl _moncount ! 65: * ! 66: * lwz r1,0(r1) ; restore the stack pointer ! 67: * lwz r12,4(r1) ; ! 68: * mtctr r12 ; restore CTR (imp) ! 69: * lwz r0,8(r1) ; ! 70: * mtlr r0 ; restore LR (return addr) ! 71: * lwz r3, 24(r1) ; ! 72: * lwz r4, 28(r1) ; ! 73: * lwz r5, 32(r1) ; ! 74: * lwz r6, 36(r1) ; ! 75: * lwz r7, 40(r1) ; ! 76: * lwz r8, 44(r1) ; ! 77: * lwz r9, 48(r1) ; ! 78: * lwz r10,52(r1) ; ! 79: * bctr ; goto *imp; ! 80: */ ! 81: extern unsigned long objc_exitPoints[]; ! 82: ! 83: /* ! 84: * objc_entryPoints is a private_extern defined in the objective-C messager ! 85: * which is a zero terminated table of a list of text lables that should not ! 86: * have a call inserted to moncount in their shared library branch table slot. ! 87: */ ! 88: extern unsigned long objc_entryPoints[]; ! 89: ! 90: /* ! 91: * moninitobjc() is a machine dependent routine that causes objective-C ! 92: * messager to call moncount() for each message it sends. ! 93: */ ! 94: unsigned long * ! 95: moninitobjc( ! 96: unsigned long moncount_addr) ! 97: { ! 98: unsigned long i, min, max; ! 99: unsigned long *p, disp; ! 100: kern_return_t r; ! 101: ! 102: if(objc_exitPoints[0] == 0) ! 103: return(objc_entryPoints); ! 104: ! 105: /* ! 106: * Determine the area to vm_protect() for writing the code. ! 107: */ ! 108: min = 0xffffffff; ! 109: max = 0; ! 110: for(i = 0; objc_exitPoints[i] != 0; i++){ ! 111: if(objc_exitPoints[i] < min) ! 112: min = objc_exitPoints[i]; ! 113: if(objc_exitPoints[i] > max) ! 114: max = objc_exitPoints[i]; ! 115: } ! 116: max += 116; ! 117: ! 118: if((r = vm_protect(task_self(), (vm_address_t)min, (vm_size_t)(max-min), ! 119: FALSE, VM_PROT_READ | VM_PROT_WRITE | ! 120: VM_PROT_EXECUTE)) != KERN_SUCCESS) ! 121: return(objc_entryPoints); ! 122: ! 123: /* ! 124: * Write in the code to call moncount. ! 125: */ ! 126: for(i = 0; objc_exitPoints[i] != 0; i++){ ! 127: p = (unsigned long *)(objc_exitPoints[i]); ! 128: /* stw r3,24(r1) */ ! 129: *p++ = 0x90610018; ! 130: /* stw r4,28(r1) */ ! 131: *p++ = 0x9081001c; ! 132: /* stw r5,32(r1) */ ! 133: *p++ = 0x90a10020; ! 134: /* stw r6,36(r1) */ ! 135: *p++ = 0x90c10024; ! 136: /* stw r7,40(r1) */ ! 137: *p++ = 0x90e10028; ! 138: /* stw r8,44(r1) */ ! 139: *p++ = 0x9101002c; ! 140: /* stw r9,48(r1) */ ! 141: *p++ = 0x91210030; ! 142: /* stw r10,52(r1) */ ! 143: *p++ = 0x91410034; ! 144: /* mflr r0 */ ! 145: *p++ = 0x7c0802a6; ! 146: /* stw r0,8(r1) */ ! 147: *p++ = 0x90010008; ! 148: /* mfcr r12 */ ! 149: *p++ = 0x7d800026; ! 150: /* stw r12,4(r1) */ ! 151: *p++ = 0x91810004; ! 152: /* stwu r1,-64(r1) */ ! 153: *p++ = 0x9421ffc0; ! 154: /* ori r3,r0,0 */ ! 155: *p++ = 0x60030000; ! 156: /* ori r4,r12,0 */ ! 157: *p++ = 0x61840000; ! 158: /* bl _moncount */ ! 159: disp = moncount_addr - (unsigned long)(p); ! 160: *p++ = 0x48000001 | (disp & 0x03fffffc); ! 161: /* lwz r1,0(r1) */ ! 162: *p++ = 0x80210000; ! 163: /* lwz r12,4(r1) */ ! 164: *p++ = 0x81810004; ! 165: /* mtctr r12 */ ! 166: *p++ = 0x7d8903a6; ! 167: /* lwz r0,8(r1) */ ! 168: *p++ = 0x80010008; ! 169: /* mtlr r0 */ ! 170: *p++ = 0x7c0803a6; ! 171: /* lwz r3,24(r1) */ ! 172: *p++ = 0x80610018; ! 173: /* lwz r4,28(r1) */ ! 174: *p++ = 0x8081001c; ! 175: /* lwz r5,32(r1) */ ! 176: *p++ = 0x80a10020; ! 177: /* lwz r6,36(r1) */ ! 178: *p++ = 0x80c10024; ! 179: /* lwz r7,40(r1) */ ! 180: *p++ = 0x80e10028; ! 181: /* lwz r8,44(r1) */ ! 182: *p++ = 0x8101002c; ! 183: /* lwz r9,48(r1) */ ! 184: *p++ = 0x81210030; ! 185: /* lwz r10,52(r1) */ ! 186: *p++ = 0x81410034; ! 187: /* bctr */ ! 188: *p++ = 0x4e800420; ! 189: } ! 190: /* ! 191: * The text cache for the this code now needs to be flushed since ! 192: * it was just written on so that future calls will get the new ! 193: * instructions. ! 194: */ ! 195: user_cache_flush(min, max-min); ! 196: ! 197: return(objc_entryPoints); ! 198: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.