|
|
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 __hppa__ ! 30: #error "this is hppa 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 "bv,n 0(%r19)" 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 "bv,n 0(%r19)" and the allocated space ! 45: * after it are: ! 46: * exitPoint1: bv,n 0(%r19) ! 47: * | replace with the following instructions ! 48: * copy %r30,%r20 ! 49: * ldo 128(%r30),%r30 ; Allocate space on stack ! 50: * stwm %r2,4(0,%r20) ; Save return pointer ! 51: * stwm %r19,4(0,%r20) ; Save imp ! 52: * stwm %r23,4(0,%r20) ; Save old args ! 53: * stwm %r24,4(0,%r20) ; ! 54: * stwm %r25,4(0,%r20) ; ! 55: * stwm %r26,4(0,%r20) ; ! 56: * fstds,ma %fr4,8(0,%r20) ; Save floating point args ! 57: * fstds,ma %fr5,8(0,%r20) ; (could actually save singles ! 58: * fstds,ma %fr6,8(0,%r20) ; for fr4 & fr6, but so what?) ! 59: * fstds,ma %fr7,8(0,%r20) ; ! 60: * copy %r2,%r26 ; moncount frompc param. ! 61: * copy %r19,%r25 ; moncount selfpc param. ! 62: * ldil L`_moncount,%r1 ; ! 63: * ble R`_moncount(%sr4,%r1) ; ! 64: * copy %r31,%r2 ; <delay slot> mrp->rp ! 65: * ldo -128(%r30),%r30 ; deallocate ! 66: * copy %r30,%r20 ; ! 67: * ldwm 4(0,%r20),%r2 ; restore everything ! 68: * ldwm 4(0,%r20),%r19 ; ! 69: * ldwm 4(0,%r20),%r23 ; ! 70: * ldwm 4(0,%r20),%r24 ; ! 71: * ldwm 4(0,%r20),%r25 ; ! 72: * ldwm 4(0,%r20),%r26 ; ! 73: * fldds,ma 8(0,%r20),%fr4 ; ! 74: * fldds,ma 8(0,%r20),%fr5 ; ! 75: * fldds,ma 8(0,%r20),%fr6 ; ! 76: * fldds,ma 8(0,%r20),%fr7 ; ! 77: * bv,n 0(%r19) ; goto *imp ! 78: * ! 79: */ ! 80: extern unsigned long objc_exitPoints[]; ! 81: ! 82: /* ! 83: * objc_entryPoints is a private_extern defined in the objective-C messager ! 84: * which is a zero terminated table of a list of text lables that should not ! 85: * have a call inserted to moncount in their shared library branch table slot. ! 86: */ ! 87: extern unsigned long objc_entryPoints[]; ! 88: ! 89: /* _moncode contains the assembled version of the code listed above. ! 90: * moninit_objc will bcopy it to the right places and adjust the ! 91: * (relative) branch instruction appropriately. ! 92: */ ! 93: ! 94: static unsigned long _moncode[] = { ! 95: 0x081e0254, ! 96: 0x37de0100, ! 97: 0x6e820008, ! 98: 0x6e930008, ! 99: 0x6e970008, ! 100: 0x6e980008, ! 101: 0x6e990008, ! 102: 0x6e9a0008, ! 103: 0x2e901224, ! 104: 0x2e901225, ! 105: 0x2e901226, ! 106: 0x2e901227, ! 107: 0x0802025a, ! 108: 0x08130259, ! 109: 0x20200000, /* ldil L`_moncount,%r1 */ ! 110: 0xe4202000, /* ble R`_moncount(%sr4,%r1) */ ! 111: 0x081f0242, ! 112: 0x37de3f01, ! 113: 0x081e0254, ! 114: 0x4e820008, ! 115: 0x4e930008, ! 116: 0x4e970008, ! 117: 0x4e980008, ! 118: 0x4e990008, ! 119: 0x4e9a0008, ! 120: 0x2e901024, ! 121: 0x2e901025, ! 122: 0x2e901026, ! 123: 0x2e901027, ! 124: 0xea60c002 ! 125: }; ! 126: #define LDIL_INSTRUCTION_INDEX 14 ! 127: #define BLE_INSTRUCTION_INDEX 15 ! 128: ! 129: static unsigned long dis_assemble_21(as21) ! 130: unsigned int as21; ! 131: { ! 132: unsigned long temp; ! 133: ! 134: ! 135: temp = ( as21 & 0x100000 ) >> 20; ! 136: temp |= ( as21 & 0x0ffe00 ) >> 8; ! 137: temp |= ( as21 & 0x000180 ) << 7; ! 138: temp |= ( as21 & 0x00007c ) << 14; ! 139: temp |= ( as21 & 0x000003 ) << 12; ! 140: return temp ; ! 141: } ! 142: ! 143: static void dis_assemble_17(as17,x,y,z) ! 144: unsigned int as17; ! 145: unsigned int *x,*y,*z; ! 146: { ! 147: ! 148: *z = ( as17 & 0x10000 ) >> 16; ! 149: *x = ( as17 & 0x0f800 ) >> 11; ! 150: *y = ( ( as17 & 0x00400 ) >> 10 ) | ( ( as17 & 0x3ff ) << 1 ); ! 151: } ! 152: ! 153: /* ! 154: * moninitobjc() is a machine dependent routine that causes objective-C ! 155: * messager to call moncount() for each message it sends. ! 156: */ ! 157: ! 158: unsigned long * ! 159: moninitobjc( ! 160: unsigned long moncount_addr) ! 161: { ! 162: unsigned long i, min, max; ! 163: unsigned long *p; ! 164: kern_return_t r; ! 165: unsigned w,w1,w2; ! 166: ! 167: if(objc_exitPoints[0] == 0) ! 168: return(objc_entryPoints); ! 169: ! 170: /* ! 171: * Determine the area to vm_protect() for writing the code. ! 172: */ ! 173: min = 0xffffffff; ! 174: max = 0; ! 175: for(i = 0; objc_exitPoints[i] != 0; i++){ ! 176: if(objc_exitPoints[i] < min) ! 177: min = objc_exitPoints[i]; ! 178: if(objc_exitPoints[i] > max) ! 179: max = objc_exitPoints[i]; ! 180: } ! 181: max += 80; ! 182: ! 183: if((r = vm_protect(task_self(), (vm_address_t)min, (vm_size_t)(max-min), ! 184: FALSE, VM_PROT_READ | VM_PROT_WRITE | ! 185: VM_PROT_EXECUTE)) != KERN_SUCCESS) ! 186: return(objc_entryPoints); ! 187: ! 188: /* ! 189: * Write in the code to call moncount. ! 190: */ ! 191: for(i = 0; objc_exitPoints[i] != 0; i++){ ! 192: ! 193: p = (unsigned long *)(objc_exitPoints[i]); ! 194: memcpy(p,_moncode,sizeof(_moncode)); ! 195: ! 196: /* Calculate the displacements for the branch to _moncount. */ ! 197: p[LDIL_INSTRUCTION_INDEX] |= dis_assemble_21(moncount_addr>>11); ! 198: dis_assemble_17((moncount_addr & 0x7ff)>>2,&w1,&w2,&w); ! 199: p[BLE_INSTRUCTION_INDEX] |= (w1<<16) | (w2<<2) | w; ! 200: } ! 201: /* ! 202: * The text cache for the this code now needs to be flushed since ! 203: * it was just written on so that future calls will get the new ! 204: * instructions. ! 205: */ ! 206: #warning objc-moninit-hppa not doing text cache flush!! ! 207: // user_cache_flush(min, max-min); ! 208: ! 209: return(objc_entryPoints); ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.