1 /*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "defs.h"
32 #include <sys/resource.h>
33 #include <sys/times.h>
34 #include <linux/kernel.h>
35
36 #include "xlat/resources.h"
37
38 static const char *
sprint_rlim64(uint64_t lim)39 sprint_rlim64(uint64_t lim)
40 {
41 static char buf[sizeof(uint64_t)*3 + sizeof("*1024")];
42
43 if (lim == UINT64_MAX)
44 return "RLIM64_INFINITY";
45
46 if (lim > 1024 && lim % 1024 == 0)
47 sprintf(buf, "%" PRIu64 "*1024", lim / 1024);
48 else
49 sprintf(buf, "%" PRIu64, lim);
50 return buf;
51 }
52
53 static void
print_rlimit64(struct tcb * tcp,unsigned long addr)54 print_rlimit64(struct tcb *tcp, unsigned long addr)
55 {
56 struct rlimit_64 {
57 uint64_t rlim_cur;
58 uint64_t rlim_max;
59 } rlim;
60
61 if (umove(tcp, addr, &rlim) < 0)
62 tprintf("%#lx", addr);
63 else {
64 tprintf("{rlim_cur=%s,", sprint_rlim64(rlim.rlim_cur));
65 tprintf(" rlim_max=%s}", sprint_rlim64(rlim.rlim_max));
66 }
67 }
68
69 static void
decode_rlimit64(struct tcb * tcp,unsigned long addr)70 decode_rlimit64(struct tcb *tcp, unsigned long addr)
71 {
72 if (!addr)
73 tprints("NULL");
74 else if (!verbose(tcp) ||
75 (exiting(tcp) && syserror(tcp)))
76 tprintf("%#lx", addr);
77 else
78 print_rlimit64(tcp, addr);
79 }
80
81 #if !defined(current_wordsize) || current_wordsize == 4
82
83 static const char *
sprint_rlim32(uint32_t lim)84 sprint_rlim32(uint32_t lim)
85 {
86 static char buf[sizeof(uint32_t)*3 + sizeof("*1024")];
87
88 if (lim == UINT32_MAX)
89 return "RLIM_INFINITY";
90
91 if (lim > 1024 && lim % 1024 == 0)
92 sprintf(buf, "%" PRIu32 "*1024", lim / 1024);
93 else
94 sprintf(buf, "%" PRIu32, lim);
95 return buf;
96 }
97
98 static void
print_rlimit32(struct tcb * tcp,unsigned long addr)99 print_rlimit32(struct tcb *tcp, unsigned long addr)
100 {
101 struct rlimit_32 {
102 uint32_t rlim_cur;
103 uint32_t rlim_max;
104 } rlim;
105
106 if (umove(tcp, addr, &rlim) < 0)
107 tprintf("%#lx", addr);
108 else {
109 tprintf("{rlim_cur=%s,", sprint_rlim32(rlim.rlim_cur));
110 tprintf(" rlim_max=%s}", sprint_rlim32(rlim.rlim_max));
111 }
112 }
113
114 static void
decode_rlimit(struct tcb * tcp,unsigned long addr)115 decode_rlimit(struct tcb *tcp, unsigned long addr)
116 {
117 if (!addr)
118 tprints("NULL");
119 else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)))
120 tprintf("%#lx", addr);
121 else {
122 # if defined(X86_64) || defined(X32)
123 /*
124 * i386 is the only personality on X86_64 and X32
125 * with 32-bit rlim_t.
126 * When current_personality is X32, current_wordsize
127 * equals to 4 but rlim_t is 64-bit.
128 */
129 if (current_personality == 1)
130 # else
131 if (current_wordsize == 4)
132 # endif
133 print_rlimit32(tcp, addr);
134 else
135 print_rlimit64(tcp, addr);
136 }
137 }
138
139 #else /* defined(current_wordsize) && current_wordsize != 4 */
140
141 # define decode_rlimit decode_rlimit64
142
143 #endif
144
145 int
sys_getrlimit(struct tcb * tcp)146 sys_getrlimit(struct tcb *tcp)
147 {
148 if (entering(tcp)) {
149 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
150 tprints(", ");
151 }
152 else {
153 decode_rlimit(tcp, tcp->u_arg[1]);
154 }
155 return 0;
156 }
157
158 int
sys_setrlimit(struct tcb * tcp)159 sys_setrlimit(struct tcb *tcp)
160 {
161 if (entering(tcp)) {
162 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
163 tprints(", ");
164 decode_rlimit(tcp, tcp->u_arg[1]);
165 }
166 return 0;
167 }
168
169 int
sys_prlimit64(struct tcb * tcp)170 sys_prlimit64(struct tcb *tcp)
171 {
172 if (entering(tcp)) {
173 tprintf("%ld, ", tcp->u_arg[0]);
174 printxval(resources, tcp->u_arg[1], "RLIMIT_???");
175 tprints(", ");
176 decode_rlimit64(tcp, tcp->u_arg[2]);
177 tprints(", ");
178 } else {
179 decode_rlimit64(tcp, tcp->u_arg[3]);
180 }
181 return 0;
182 }
183
184 #include "xlat/usagewho.h"
185
186 #ifdef ALPHA
187 void
printrusage32(struct tcb * tcp,long addr)188 printrusage32(struct tcb *tcp, long addr)
189 {
190 struct timeval32 {
191 unsigned tv_sec;
192 unsigned tv_usec;
193 };
194 struct rusage32 {
195 struct timeval32 ru_utime; /* user time used */
196 struct timeval32 ru_stime; /* system time used */
197 long ru_maxrss; /* maximum resident set size */
198 long ru_ixrss; /* integral shared memory size */
199 long ru_idrss; /* integral unshared data size */
200 long ru_isrss; /* integral unshared stack size */
201 long ru_minflt; /* page reclaims */
202 long ru_majflt; /* page faults */
203 long ru_nswap; /* swaps */
204 long ru_inblock; /* block input operations */
205 long ru_oublock; /* block output operations */
206 long ru_msgsnd; /* messages sent */
207 long ru_msgrcv; /* messages received */
208 long ru_nsignals; /* signals received */
209 long ru_nvcsw; /* voluntary context switches */
210 long ru_nivcsw; /* involuntary " */
211 } ru;
212
213 if (!addr)
214 tprints("NULL");
215 else if (syserror(tcp) || !verbose(tcp))
216 tprintf("%#lx", addr);
217 else if (umove(tcp, addr, &ru) < 0)
218 tprints("{...}");
219 else if (!abbrev(tcp)) {
220 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
221 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
222 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
223 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
224 ru.ru_maxrss, ru.ru_ixrss);
225 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
226 ru.ru_idrss, ru.ru_isrss);
227 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
228 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
229 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
230 ru.ru_inblock, ru.ru_oublock);
231 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
232 ru.ru_msgsnd, ru.ru_msgrcv);
233 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
234 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
235 }
236 else {
237 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
238 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
239 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
240 }
241 }
242 #endif
243
244 void
printrusage(struct tcb * tcp,long addr)245 printrusage(struct tcb *tcp, long addr)
246 {
247 struct rusage ru;
248
249 if (!addr)
250 tprints("NULL");
251 else if (syserror(tcp) || !verbose(tcp))
252 tprintf("%#lx", addr);
253 else if (umove(tcp, addr, &ru) < 0)
254 tprints("{...}");
255 else if (!abbrev(tcp)) {
256 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
257 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
258 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
259 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
260 ru.ru_maxrss, ru.ru_ixrss);
261 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
262 ru.ru_idrss, ru.ru_isrss);
263 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
264 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
265 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
266 ru.ru_inblock, ru.ru_oublock);
267 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
268 ru.ru_msgsnd, ru.ru_msgrcv);
269 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
270 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
271 }
272 else {
273 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
274 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
275 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
276 }
277 }
278
279 int
sys_getrusage(struct tcb * tcp)280 sys_getrusage(struct tcb *tcp)
281 {
282 if (entering(tcp)) {
283 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
284 tprints(", ");
285 }
286 else
287 printrusage(tcp, tcp->u_arg[1]);
288 return 0;
289 }
290
291 #ifdef ALPHA
292 int
sys_osf_getrusage(struct tcb * tcp)293 sys_osf_getrusage(struct tcb *tcp)
294 {
295 if (entering(tcp)) {
296 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
297 tprints(", ");
298 }
299 else
300 printrusage32(tcp, tcp->u_arg[1]);
301 return 0;
302 }
303 #endif /* ALPHA */
304
305 int
sys_sysinfo(struct tcb * tcp)306 sys_sysinfo(struct tcb *tcp)
307 {
308 struct sysinfo si;
309
310 if (exiting(tcp)) {
311 if (syserror(tcp) || !verbose(tcp))
312 tprintf("%#lx", tcp->u_arg[0]);
313 else if (umove(tcp, tcp->u_arg[0], &si) < 0)
314 tprints("{...}");
315 else {
316 tprintf("{uptime=%lu, loads=[%lu, %lu, %lu] ",
317 (long) si.uptime, (long) si.loads[0],
318 (long) si.loads[1], (long) si.loads[2]);
319 tprintf("totalram=%lu, freeram=%lu, ",
320 (long) si.totalram, (long) si.freeram);
321 tprintf("sharedram=%lu, bufferram=%lu} ",
322 (long) si.sharedram, (long) si.bufferram);
323 tprintf("totalswap=%lu, freeswap=%lu, procs=%u}",
324 (long) si.totalswap, (long) si.freeswap,
325 (unsigned)si.procs);
326 }
327 }
328 return 0;
329 }
330
331 #include "xlat/priorities.h"
332
333 int
sys_getpriority(struct tcb * tcp)334 sys_getpriority(struct tcb *tcp)
335 {
336 if (entering(tcp)) {
337 printxval(priorities, tcp->u_arg[0], "PRIO_???");
338 tprintf(", %lu", tcp->u_arg[1]);
339 }
340 return 0;
341 }
342
343 int
sys_setpriority(struct tcb * tcp)344 sys_setpriority(struct tcb *tcp)
345 {
346 if (entering(tcp)) {
347 printxval(priorities, tcp->u_arg[0], "PRIO_???");
348 tprintf(", %lu, %ld", tcp->u_arg[1], tcp->u_arg[2]);
349 }
350 return 0;
351 }
352
353 int
sys_times(struct tcb * tcp)354 sys_times(struct tcb *tcp)
355 {
356 struct tms tbuf;
357
358 if (exiting(tcp)) {
359 if (tcp->u_arg[0] == 0)
360 tprints("NULL");
361 else if (syserror(tcp))
362 tprintf("%#lx", tcp->u_arg[0]);
363 else if (umove(tcp, tcp->u_arg[0], &tbuf) < 0)
364 tprints("{...}");
365 else {
366 tprintf("{tms_utime=%llu, tms_stime=%llu, ",
367 (unsigned long long) tbuf.tms_utime,
368 (unsigned long long) tbuf.tms_stime);
369 tprintf("tms_cutime=%llu, tms_cstime=%llu}",
370 (unsigned long long) tbuf.tms_cutime,
371 (unsigned long long) tbuf.tms_cstime);
372 }
373 }
374 return 0;
375 }
376