|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: #include <mach/mach_types.h> ! 23: #include <mach/exception_types.h> ! 24: #include <mach/error.h> ! 25: #include <kern/counters.h> ! 26: #include <kern/syscall_sw.h> ! 27: #include <kern/task.h> ! 28: #include <kern/thread.h> ! 29: #include <ppc/thread.h> ! 30: #include <kern/thread_act.h> ! 31: #include <ppc/thread_act.h> ! 32: #include <ppc/asm.h> ! 33: #include <ppc/proc_reg.h> ! 34: #include <ppc/trap.h> ! 35: #include <ppc/exception.h> ! 36: #include <kern/assert.h> ! 37: ! 38: #include <sys/kdebug.h> ! 39: ! 40: #define ERESTART -1 /* restart syscall */ ! 41: #define EJUSTRETURN -2 /* don't modify regs, just return */ ! 42: ! 43: struct unix_syscallargs { ! 44: int flavor; ! 45: int r3; ! 46: int arg1, arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9; ! 47: }; ! 48: struct sysent { /* system call table */ ! 49: unsigned short sy_narg; /* number of args */ ! 50: unsigned short sy_parallel; /* can execute in parallel */ ! 51: unsigned long (*sy_call)(void *, void *, int *); /* implementing function */ ! 52: }; ! 53: ! 54: extern struct sysent sysent[]; ! 55: ! 56: void *get_bsdtask_info( ! 57: task_t); ! 58: ! 59: int set_bsduthreadargs ( ! 60: thread_act_t, struct pcb *, ! 61: struct unix_syscallargs *); ! 62: ! 63: void * get_bsduthreadarg( ! 64: thread_act_t); ! 65: ! 66: void ! 67: unix_syscall( ! 68: struct pcb * pcb, ! 69: int, int, int, int, int, int, int ); ! 70: ! 71: /* ! 72: * Function: unix_syscall ! 73: * ! 74: * Inputs: pcb - pointer to Process Control Block ! 75: * arg1 - arguments to mach system calls ! 76: * arg2 ! 77: * arg3 ! 78: * arg4 ! 79: * arg5 ! 80: * arg6 ! 81: * arg7 ! 82: * ! 83: * Outputs: none ! 84: */ ! 85: void ! 86: unix_syscall( ! 87: struct pcb * pcb, ! 88: int arg1, ! 89: int arg2, ! 90: int arg3, ! 91: int arg4, ! 92: int arg5, ! 93: int arg6, ! 94: int arg7 ! 95: ) ! 96: { ! 97: struct ppc_saved_state *regs; ! 98: thread_act_t thread; ! 99: struct sysent *callp; ! 100: int nargs, error; ! 101: unsigned short code; ! 102: void * p, *vt; ! 103: int * vtint; ! 104: int *rval; ! 105: ! 106: struct unix_syscallargs sarg; ! 107: extern int nsysent; ! 108: ! 109: (void) thread_set_funneled(TRUE); ! 110: ! 111: regs = &pcb->ss; ! 112: thread = current_act(); ! 113: p = get_bsdtask_info(current_task()); ! 114: rval = (int *)get_bsduthreadrval(thread); ! 115: ! 116: /* ! 117: ** Get index into sysent table ! 118: */ ! 119: code = regs->r0; ! 120: ! 121: ! 122: /* ! 123: ** Set up call pointer ! 124: */ ! 125: callp = (code >= nsysent) ? &sysent[63] : &sysent[code]; ! 126: ! 127: sarg. flavor = (callp == sysent)? 1: 0; ! 128: if (sarg.flavor) { ! 129: code = regs->r3; ! 130: callp = (code >= nsysent) ? &sysent[63] : &sysent[code]; ! 131: ! 132: } ! 133: else ! 134: sarg. r3 = regs->r3; ! 135: sarg. arg1 = arg1; ! 136: sarg. arg2 = arg2; ! 137: sarg. arg3 = arg3; ! 138: sarg. arg4 = arg4; ! 139: sarg. arg5 = arg5; ! 140: sarg. arg6 = arg6; ! 141: sarg. arg7 = arg7; ! 142: ! 143: set_bsduthreadargs(thread,pcb,&sarg); ! 144: ! 145: ! 146: if (callp->sy_narg > 8) ! 147: panic("unix_syscall: max arg count exceeded"); ! 148: ! 149: rval[0] = 0; ! 150: ! 151: /* r4 is volatile, if we set it to regs->r4 here the child ! 152: * will have parents r4 after execve */ ! 153: rval[1] = 0; ! 154: ! 155: error = 0; /* Start with a good value */ ! 156: ! 157: /* ! 158: ** the PPC runtime calls cerror after every unix system call, so ! 159: ** assume no error and adjust the "pc" to skip this call. ! 160: ** It will be set back to the cerror call if an error is detected. ! 161: */ ! 162: regs->srr0 += 4; ! 163: vt = get_bsduthreadarg(thread); ! 164: ! 165: if (code != 180) { ! 166: vtint = (int *) vt; ! 167: KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START, ! 168: vtint[0],vtint[1], vtint[2], vtint[3], 0); ! 169: } ! 170: ! 171: counter_always(c_syscalls_unix++); ! 172: current_task()->syscalls_unix++; ! 173: error = (*(callp->sy_call))(p, (void *)vt, rval); ! 174: ! 175: if (code != 180) { ! 176: KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END, ! 177: error, rval[0], rval[1], 0, 0); ! 178: } ! 179: ! 180: if (error == ERESTART) { ! 181: regs->srr0 -= 8; ! 182: } ! 183: else if (error != EJUSTRETURN) { ! 184: if (error) ! 185: { ! 186: regs->r3 = error; ! 187: /* set the "pc" to execute cerror routine */ ! 188: regs->srr0 -= 4; ! 189: } else { /* (not error) */ ! 190: regs->r3 = rval[0]; ! 191: regs->r4 = rval[1]; ! 192: } ! 193: } ! 194: /* else (error == EJUSTRETURN) { nothing } */ ! 195: ! 196: (void) thread_set_funneled(FALSE); ! 197: ! 198: thread_exception_return(); ! 199: /* NOTREACHED */ ! 200: } ! 201: ! 202: unix_syscall_return(error) ! 203: { ! 204: struct ppc_saved_state *regs; ! 205: thread_act_t thread; ! 206: struct sysent *callp; ! 207: int nargs; ! 208: unsigned short code; ! 209: int *rval; ! 210: void * p, *vt; ! 211: int * vtint; ! 212: struct pcb *pcb; ! 213: ! 214: struct unix_syscallargs sarg; ! 215: extern int nsysent; ! 216: ! 217: thread = current_act(); ! 218: p = get_bsdtask_info(current_task()); ! 219: rval = (int *)get_bsduthreadrval(thread); ! 220: pcb = thread->mact.pcb; ! 221: regs = &pcb->ss; ! 222: ! 223: /* ! 224: ** Get index into sysent table ! 225: */ ! 226: code = regs->r0; ! 227: ! 228: if (code != 180) { ! 229: KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END, ! 230: error, rval[0], rval[1], 0, 0); ! 231: } ! 232: ! 233: if (error == ERESTART) { ! 234: regs->srr0 -= 8; ! 235: } ! 236: else if (error != EJUSTRETURN) { ! 237: if (error) ! 238: { ! 239: regs->r3 = error; ! 240: /* set the "pc" to execute cerror routine */ ! 241: regs->srr0 -= 4; ! 242: } else { /* (not error) */ ! 243: regs->r3 = rval[0]; ! 244: regs->r4 = rval[1]; ! 245: } ! 246: } ! 247: /* else (error == EJUSTRETURN) { nothing } */ ! 248: ! 249: (void) thread_set_funneled(FALSE); ! 250: ! 251: thread_exception_return(); ! 252: /* NOTREACHED */ ! 253: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.