]> granicus.if.org Git - strace/blob - resource.c
Use XLAT_END macro
[strace] / resource.c
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 static const struct xlat resources[] = {
37 #ifdef RLIMIT_AS
38         XLAT(RLIMIT_AS),
39 #endif
40 #ifdef RLIMIT_CORE
41         XLAT(RLIMIT_CORE),
42 #endif
43 #ifdef RLIMIT_CPU
44         XLAT(RLIMIT_CPU),
45 #endif
46 #ifdef RLIMIT_DATA
47         XLAT(RLIMIT_DATA),
48 #endif
49 #ifdef RLIMIT_FSIZE
50         XLAT(RLIMIT_FSIZE),
51 #endif
52 #ifdef RLIMIT_LOCKS
53         XLAT(RLIMIT_LOCKS),
54 #endif
55 #ifdef RLIMIT_MEMLOCK
56         XLAT(RLIMIT_MEMLOCK),
57 #endif
58 #ifdef RLIMIT_MSGQUEUE
59         XLAT(RLIMIT_MSGQUEUE),
60 #endif
61 #ifdef RLIMIT_NICE
62         XLAT(RLIMIT_NICE),
63 #endif
64 #ifdef RLIMIT_NOFILE
65         XLAT(RLIMIT_NOFILE),
66 #endif
67 #ifdef RLIMIT_NPROC
68         XLAT(RLIMIT_NPROC),
69 #endif
70 #ifdef RLIMIT_RSS
71         XLAT(RLIMIT_RSS),
72 #endif
73 #ifdef RLIMIT_RTPRIO
74         XLAT(RLIMIT_RTPRIO),
75 #endif
76 #ifdef RLIMIT_RTTIME
77         XLAT(RLIMIT_RTTIME),
78 #endif
79 #ifdef RLIMIT_SIGPENDING
80         XLAT(RLIMIT_SIGPENDING),
81 #endif
82 #ifdef RLIMIT_STACK
83         XLAT(RLIMIT_STACK),
84 #endif
85 #ifdef RLIMIT_VMEM
86         XLAT(RLIMIT_VMEM),
87 #endif
88         XLAT_END
89 };
90
91 #if !(SIZEOF_RLIM_T == 4 || SIZEOF_RLIM_T == 8)
92 # error "Unsupported SIZEOF_RLIM_T value"
93 #endif
94
95 static const char *
96 sprint_rlim64(uint64_t lim)
97 {
98         static char buf[sizeof(uint64_t)*3 + sizeof("*1024")];
99
100         if (lim == UINT64_MAX)
101                 return "RLIM64_INFINITY";
102
103         if (lim > 1024 && lim % 1024 == 0)
104                 sprintf(buf, "%" PRIu64 "*1024", lim / 1024);
105         else
106                 sprintf(buf, "%" PRIu64, lim);
107         return buf;
108 }
109
110 static void
111 print_rlimit64(struct tcb *tcp, unsigned long addr)
112 {
113         struct rlimit_64 {
114                 uint64_t rlim_cur;
115                 uint64_t rlim_max;
116         } rlim;
117
118         if (umove(tcp, addr, &rlim) < 0)
119                 tprintf("%#lx", addr);
120         else {
121                 tprintf("{rlim_cur=%s,", sprint_rlim64(rlim.rlim_cur));
122                 tprintf(" rlim_max=%s}", sprint_rlim64(rlim.rlim_max));
123         }
124 }
125
126 static void
127 decode_rlimit64(struct tcb *tcp, unsigned long addr)
128 {
129         if (!addr)
130                 tprints("NULL");
131         else if (!verbose(tcp) ||
132                  (exiting(tcp) && syserror(tcp)))
133                 tprintf("%#lx", addr);
134         else
135                 print_rlimit64(tcp, addr);
136 }
137
138 #if SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1
139
140 static const char *
141 sprint_rlim32(uint32_t lim)
142 {
143         static char buf[sizeof(uint32_t)*3 + sizeof("*1024")];
144
145         if (lim == UINT32_MAX)
146                 return "RLIM_INFINITY";
147
148         if (lim > 1024 && lim % 1024 == 0)
149                 sprintf(buf, "%" PRIu32 "*1024", lim / 1024);
150         else
151                 sprintf(buf, "%" PRIu32, lim);
152         return buf;
153 }
154
155 static void
156 print_rlimit32(struct tcb *tcp, unsigned long addr)
157 {
158         struct rlimit_32 {
159                 uint32_t rlim_cur;
160                 uint32_t rlim_max;
161         } rlim;
162
163         if (umove(tcp, addr, &rlim) < 0)
164                 tprintf("%#lx", addr);
165         else {
166                 tprintf("{rlim_cur=%s,", sprint_rlim32(rlim.rlim_cur));
167                 tprintf(" rlim_max=%s}", sprint_rlim32(rlim.rlim_max));
168         }
169 }
170
171 static void
172 decode_rlimit(struct tcb *tcp, unsigned long addr)
173 {
174         if (!addr)
175                 tprints("NULL");
176         else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)))
177                 tprintf("%#lx", addr);
178         else {
179 # if SIZEOF_RLIM_T == 4
180                 print_rlimit32(tcp, addr);
181 # else
182                 if (current_wordsize == 4)
183                         print_rlimit32(tcp, addr);
184                 else
185                         print_rlimit64(tcp, addr);
186 # endif
187         }
188 }
189
190 #else /* SIZEOF_RLIM_T == 8 && SUPPORTED_PERSONALITIES == 1 */
191
192 # define decode_rlimit decode_rlimit64
193
194 #endif /* SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1 */
195
196 int
197 sys_getrlimit(struct tcb *tcp)
198 {
199         if (entering(tcp)) {
200                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
201                 tprints(", ");
202         }
203         else {
204                 decode_rlimit(tcp, tcp->u_arg[1]);
205         }
206         return 0;
207 }
208
209 int
210 sys_setrlimit(struct tcb *tcp)
211 {
212         if (entering(tcp)) {
213                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
214                 tprints(", ");
215                 decode_rlimit(tcp, tcp->u_arg[1]);
216         }
217         return 0;
218 }
219
220 int
221 sys_prlimit64(struct tcb *tcp)
222 {
223         if (entering(tcp)) {
224                 tprintf("%ld, ", tcp->u_arg[0]);
225                 printxval(resources, tcp->u_arg[1], "RLIMIT_???");
226                 tprints(", ");
227                 decode_rlimit64(tcp, tcp->u_arg[2]);
228                 tprints(", ");
229         } else {
230                 decode_rlimit64(tcp, tcp->u_arg[3]);
231         }
232         return 0;
233 }
234
235 static const struct xlat usagewho[] = {
236         XLAT(RUSAGE_SELF),
237         XLAT(RUSAGE_CHILDREN),
238 #ifdef RUSAGE_BOTH
239         XLAT(RUSAGE_BOTH),
240 #endif
241         XLAT_END
242 };
243
244 #ifdef ALPHA
245 void
246 printrusage32(struct tcb *tcp, long addr)
247 {
248         struct timeval32 {
249                 unsigned tv_sec;
250                 unsigned tv_usec;
251         };
252         struct rusage32 {
253                 struct timeval32 ru_utime;      /* user time used */
254                 struct timeval32 ru_stime;      /* system time used */
255                 long    ru_maxrss;              /* maximum resident set size */
256                 long    ru_ixrss;               /* integral shared memory size */
257                 long    ru_idrss;               /* integral unshared data size */
258                 long    ru_isrss;               /* integral unshared stack size */
259                 long    ru_minflt;              /* page reclaims */
260                 long    ru_majflt;              /* page faults */
261                 long    ru_nswap;               /* swaps */
262                 long    ru_inblock;             /* block input operations */
263                 long    ru_oublock;             /* block output operations */
264                 long    ru_msgsnd;              /* messages sent */
265                 long    ru_msgrcv;              /* messages received */
266                 long    ru_nsignals;            /* signals received */
267                 long    ru_nvcsw;               /* voluntary context switches */
268                 long    ru_nivcsw;              /* involuntary " */
269         } ru;
270
271         if (!addr)
272                 tprints("NULL");
273         else if (syserror(tcp) || !verbose(tcp))
274                 tprintf("%#lx", addr);
275         else if (umove(tcp, addr, &ru) < 0)
276                 tprints("{...}");
277         else if (!abbrev(tcp)) {
278                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
279                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
280                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
281                 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
282                         ru.ru_maxrss, ru.ru_ixrss);
283                 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
284                         ru.ru_idrss, ru.ru_isrss);
285                 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
286                         ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
287                 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
288                         ru.ru_inblock, ru.ru_oublock);
289                 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
290                         ru.ru_msgsnd, ru.ru_msgrcv);
291                 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
292                         ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
293         }
294         else {
295                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
296                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
297                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
298         }
299 }
300 #endif
301
302 void
303 printrusage(struct tcb *tcp, long addr)
304 {
305         struct rusage ru;
306
307         if (!addr)
308                 tprints("NULL");
309         else if (syserror(tcp) || !verbose(tcp))
310                 tprintf("%#lx", addr);
311         else if (umove(tcp, addr, &ru) < 0)
312                 tprints("{...}");
313         else if (!abbrev(tcp)) {
314                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
315                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
316                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
317                 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
318                         ru.ru_maxrss, ru.ru_ixrss);
319                 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
320                         ru.ru_idrss, ru.ru_isrss);
321                 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
322                         ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
323                 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
324                         ru.ru_inblock, ru.ru_oublock);
325                 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
326                         ru.ru_msgsnd, ru.ru_msgrcv);
327                 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
328                         ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
329         }
330         else {
331                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
332                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
333                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
334         }
335 }
336
337 int
338 sys_getrusage(struct tcb *tcp)
339 {
340         if (entering(tcp)) {
341                 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
342                 tprints(", ");
343         }
344         else
345                 printrusage(tcp, tcp->u_arg[1]);
346         return 0;
347 }
348
349 #ifdef ALPHA
350 int
351 sys_osf_getrusage(struct tcb *tcp)
352 {
353         if (entering(tcp)) {
354                 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
355                 tprints(", ");
356         }
357         else
358                 printrusage32(tcp, tcp->u_arg[1]);
359         return 0;
360 }
361 #endif /* ALPHA */
362
363 int
364 sys_sysinfo(struct tcb *tcp)
365 {
366         struct sysinfo si;
367
368         if (exiting(tcp)) {
369                 if (syserror(tcp) || !verbose(tcp))
370                         tprintf("%#lx", tcp->u_arg[0]);
371                 else if (umove(tcp, tcp->u_arg[0], &si) < 0)
372                         tprints("{...}");
373                 else {
374                         tprintf("{uptime=%lu, loads=[%lu, %lu, %lu] ",
375                                 (long) si.uptime, (long) si.loads[0],
376                                 (long) si.loads[1], (long) si.loads[2]);
377                         tprintf("totalram=%lu, freeram=%lu, ",
378                                 (long) si.totalram, (long) si.freeram);
379                         tprintf("sharedram=%lu, bufferram=%lu} ",
380                                 (long) si.sharedram, (long) si.bufferram);
381                         tprintf("totalswap=%lu, freeswap=%lu, procs=%u}",
382                                 (long) si.totalswap, (long) si.freeswap,
383                                 (unsigned)si.procs);
384                 }
385         }
386         return 0;
387 }
388
389 static const struct xlat priorities[] = {
390         XLAT(PRIO_PROCESS),
391         XLAT(PRIO_PGRP),
392         XLAT(PRIO_USER),
393         XLAT_END
394 };
395
396 int
397 sys_getpriority(struct tcb *tcp)
398 {
399         if (entering(tcp)) {
400                 printxval(priorities, tcp->u_arg[0], "PRIO_???");
401                 tprintf(", %lu", tcp->u_arg[1]);
402         }
403         return 0;
404 }
405
406 int
407 sys_setpriority(struct tcb *tcp)
408 {
409         if (entering(tcp)) {
410                 printxval(priorities, tcp->u_arg[0], "PRIO_???");
411                 tprintf(", %lu, %ld", tcp->u_arg[1], tcp->u_arg[2]);
412         }
413         return 0;
414 }
415
416 int
417 sys_times(struct tcb *tcp)
418 {
419         struct tms tbuf;
420
421         if (exiting(tcp)) {
422                 if (tcp->u_arg[0] == 0)
423                         tprints("NULL");
424                 else if (syserror(tcp))
425                         tprintf("%#lx", tcp->u_arg[0]);
426                 else if (umove(tcp, tcp->u_arg[0], &tbuf) < 0)
427                         tprints("{...}");
428                 else {
429                         tprintf("{tms_utime=%llu, tms_stime=%llu, ",
430                                 (unsigned long long) tbuf.tms_utime,
431                                 (unsigned long long) tbuf.tms_stime);
432                         tprintf("tms_cutime=%llu, tms_cstime=%llu}",
433                                 (unsigned long long) tbuf.tms_cutime,
434                                 (unsigned long long) tbuf.tms_cstime);
435                 }
436         }
437         return 0;
438 }