1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1997-2000 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #include <sys/isa_defs.h> 28 #include <stdlib.h> 29 #include <unistd.h> 30 #include <errno.h> 31 #include "libproc.h" 32 33 /* 34 * getitimer() system call -- executed by victim process. 35 */ 36 int 37 pr_getitimer(struct ps_prochandle *Pr, int which, struct itimerval *itv) 38 { 39 sysret_t rval; /* return value from getitimer() */ 40 argdes_t argd[2]; /* arg descriptors for getitimer() */ 41 argdes_t *adp; 42 int error; 43 #ifdef _LP64 44 int victim32 = (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32); 45 struct itimerval32 itimerval32; 46 #endif 47 48 if (Pr == NULL) /* no victim process */ 49 return (getitimer(which, itv)); 50 51 adp = &argd[0]; /* which argument */ 52 adp->arg_value = which; 53 adp->arg_type = AT_BYVAL; 54 adp->arg_inout = AI_INPUT; 55 adp->arg_object = NULL; 56 adp->arg_size = 0; 57 58 adp++; /* itv argument */ 59 adp->arg_value = 0; 60 adp->arg_type = AT_BYREF; 61 adp->arg_inout = AI_OUTPUT; 62 #ifdef _LP64 63 if (victim32) { 64 adp->arg_object = &itimerval32; 65 adp->arg_size = sizeof (itimerval32); 66 } else { 67 adp->arg_object = itv; 68 adp->arg_size = sizeof (*itv); 69 } 70 #else /* _LP64 */ 71 adp->arg_object = itv; 72 adp->arg_size = sizeof (*itv); 73 #endif /* _LP64 */ 74 75 error = Psyscall(Pr, &rval, SYS_getitimer, 2, &argd[0]); 76 77 if (error) { 78 errno = (error > 0)? error : ENOSYS; 79 return (-1); 80 } 81 #ifdef _LP64 82 if (victim32) { 83 ITIMERVAL32_TO_ITIMERVAL(itv, &itimerval32); 84 } 85 #endif /* _LP64 */ 86 return (rval.sys_rval1); 87 } 88 89 /* 90 * setitimer() system call -- executed by victim process. 91 */ 92 int 93 pr_setitimer(struct ps_prochandle *Pr, 94 int which, const struct itimerval *itv, struct itimerval *oitv) 95 { 96 sysret_t rval; /* return value from setitimer() */ 97 argdes_t argd[3]; /* arg descriptors for setitimer() */ 98 argdes_t *adp; 99 int error; 100 #ifdef _LP64 101 int victim32 = (Pstatus(Pr)->pr_dmodel == PR_MODEL_ILP32); 102 struct itimerval32 itimerval32; 103 struct itimerval32 oitimerval32; 104 #endif /* _LP64 */ 105 106 if (Pr == NULL) /* no victim process */ 107 return (setitimer(which, (struct itimerval *)itv, oitv)); 108 109 adp = &argd[0]; /* which argument */ 110 adp->arg_value = which; 111 adp->arg_type = AT_BYVAL; 112 adp->arg_inout = AI_INPUT; 113 adp->arg_object = NULL; 114 adp->arg_size = 0; 115 116 adp++; /* itv argument */ 117 adp->arg_value = 0; 118 adp->arg_type = AT_BYREF; 119 adp->arg_inout = AI_INPUT; 120 #ifdef _LP64 121 if (victim32) { 122 ITIMERVAL_TO_ITIMERVAL32(&itimerval32, itv); 123 adp->arg_object = (void *)&itimerval32; 124 adp->arg_size = sizeof (itimerval32); 125 } else { 126 adp->arg_object = (void *)itv; 127 adp->arg_size = sizeof (*itv); 128 } 129 #else /* _LP64 */ 130 adp->arg_object = (void *)itv; 131 adp->arg_size = sizeof (*itv); 132 #endif /* _LP64 */ 133 134 adp++; /* oitv argument */ 135 adp->arg_value = 0; 136 if (oitv == NULL) { 137 adp->arg_type = AT_BYVAL; 138 adp->arg_inout = AI_INPUT; 139 adp->arg_object = NULL; 140 adp->arg_size = 0; 141 } else { 142 adp->arg_type = AT_BYREF; 143 adp->arg_inout = AI_OUTPUT; 144 #ifdef _LP64 145 if (victim32) { 146 adp->arg_object = (void *)&oitimerval32; 147 adp->arg_size = sizeof (oitimerval32); 148 } else { 149 adp->arg_object = oitv; 150 adp->arg_size = sizeof (*oitv); 151 } 152 #else /* _LP64 */ 153 adp->arg_object = oitv; 154 adp->arg_size = sizeof (*oitv); 155 #endif /* _LP64 */ 156 } 157 158 error = Psyscall(Pr, &rval, SYS_setitimer, 3, &argd[0]); 159 160 if (error) { 161 errno = (error > 0)? error : ENOSYS; 162 return (-1); 163 } 164 #ifdef _LP64 165 if (victim32 && oitv != NULL) { 166 ITIMERVAL32_TO_ITIMERVAL(oitv, &oitimerval32); 167 } 168 #endif /* _LP64 */ 169 return (rval.sys_rval1); 170 } 171