Annotation of objc/objc-moninit-ppc.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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