|
|
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.