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
pr_getitimer(struct ps_prochandle * Pr,int which,struct itimerval * itv)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
pr_setitimer(struct ps_prochandle * Pr,int which,const struct itimerval * itv,struct itimerval * oitv)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