]> granicus.if.org Git - strace/blob - resource.c
resource.c: make use of RVAL_DECODED
[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 #include "xlat/resources.h"
37
38 static const char *
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
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_or_printaddr(tcp, addr, &rlim)) {
62                 tprintf("{rlim_cur=%s,", sprint_rlim64(rlim.rlim_cur));
63                 tprintf(" rlim_max=%s}", sprint_rlim64(rlim.rlim_max));
64         }
65 }
66
67 #if !defined(current_wordsize) || current_wordsize == 4
68
69 static const char *
70 sprint_rlim32(uint32_t lim)
71 {
72         static char buf[sizeof(uint32_t)*3 + sizeof("*1024")];
73
74         if (lim == UINT32_MAX)
75                 return "RLIM_INFINITY";
76
77         if (lim > 1024 && lim % 1024 == 0)
78                 sprintf(buf, "%" PRIu32 "*1024", lim / 1024);
79         else
80                 sprintf(buf, "%" PRIu32, lim);
81         return buf;
82 }
83
84 static void
85 print_rlimit32(struct tcb *tcp, unsigned long addr)
86 {
87         struct rlimit_32 {
88                 uint32_t rlim_cur;
89                 uint32_t rlim_max;
90         } rlim;
91
92         if (!umove_or_printaddr(tcp, addr, &rlim)) {
93                 tprintf("{rlim_cur=%s,", sprint_rlim32(rlim.rlim_cur));
94                 tprintf(" rlim_max=%s}", sprint_rlim32(rlim.rlim_max));
95         }
96 }
97
98 static void
99 decode_rlimit(struct tcb *tcp, unsigned long addr)
100 {
101 # if defined(X86_64) || defined(X32)
102         /*
103          * i386 is the only personality on X86_64 and X32
104          * with 32-bit rlim_t.
105          * When current_personality is X32, current_wordsize
106          * equals to 4 but rlim_t is 64-bit.
107          */
108         if (current_personality == 1)
109 # else
110         if (current_wordsize == 4)
111 # endif
112                 print_rlimit32(tcp, addr);
113         else
114                 print_rlimit64(tcp, addr);
115 }
116
117 #else /* defined(current_wordsize) && current_wordsize != 4 */
118
119 # define decode_rlimit print_rlimit64
120
121 #endif
122
123 SYS_FUNC(getrlimit)
124 {
125         if (entering(tcp)) {
126                 printxval(resources, tcp->u_arg[0], "RLIMIT_???");
127                 tprints(", ");
128         }
129         else {
130                 decode_rlimit(tcp, tcp->u_arg[1]);
131         }
132         return 0;
133 }
134
135 SYS_FUNC(setrlimit)
136 {
137         printxval(resources, tcp->u_arg[0], "RLIMIT_???");
138         tprints(", ");
139         decode_rlimit(tcp, tcp->u_arg[1]);
140
141         return RVAL_DECODED;
142 }
143
144 SYS_FUNC(prlimit64)
145 {
146         if (entering(tcp)) {
147                 tprintf("%ld, ", tcp->u_arg[0]);
148                 printxval(resources, tcp->u_arg[1], "RLIMIT_???");
149                 tprints(", ");
150                 print_rlimit64(tcp, tcp->u_arg[2]);
151                 tprints(", ");
152         } else {
153                 print_rlimit64(tcp, tcp->u_arg[3]);
154         }
155         return 0;
156 }
157
158 #include "xlat/usagewho.h"
159
160 #ifdef ALPHA
161 void
162 printrusage32(struct tcb *tcp, long addr)
163 {
164         struct timeval32 {
165                 unsigned tv_sec;
166                 unsigned tv_usec;
167         };
168         struct rusage32 {
169                 struct timeval32 ru_utime;      /* user time used */
170                 struct timeval32 ru_stime;      /* system time used */
171                 long    ru_maxrss;              /* maximum resident set size */
172                 long    ru_ixrss;               /* integral shared memory size */
173                 long    ru_idrss;               /* integral unshared data size */
174                 long    ru_isrss;               /* integral unshared stack size */
175                 long    ru_minflt;              /* page reclaims */
176                 long    ru_majflt;              /* page faults */
177                 long    ru_nswap;               /* swaps */
178                 long    ru_inblock;             /* block input operations */
179                 long    ru_oublock;             /* block output operations */
180                 long    ru_msgsnd;              /* messages sent */
181                 long    ru_msgrcv;              /* messages received */
182                 long    ru_nsignals;            /* signals received */
183                 long    ru_nvcsw;               /* voluntary context switches */
184                 long    ru_nivcsw;              /* involuntary " */
185         } ru;
186
187         if (umove_or_printaddr(tcp, addr, &ru))
188                 return;
189         if (!abbrev(tcp)) {
190                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
191                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
192                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
193                 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
194                         ru.ru_maxrss, ru.ru_ixrss);
195                 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
196                         ru.ru_idrss, ru.ru_isrss);
197                 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
198                         ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
199                 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
200                         ru.ru_inblock, ru.ru_oublock);
201                 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
202                         ru.ru_msgsnd, ru.ru_msgrcv);
203                 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
204                         ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
205         }
206         else {
207                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
208                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
209                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
210         }
211 }
212 #endif
213
214 void
215 printrusage(struct tcb *tcp, long addr)
216 {
217         struct rusage ru;
218
219         if (umove_or_printaddr(tcp, addr, &ru))
220                 return;
221         if (!abbrev(tcp)) {
222                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ",
223                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
224                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
225                 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ",
226                         ru.ru_maxrss, ru.ru_ixrss);
227                 tprintf("ru_idrss=%lu, ru_isrss=%lu, ",
228                         ru.ru_idrss, ru.ru_isrss);
229                 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ",
230                         ru.ru_minflt, ru.ru_majflt, ru.ru_nswap);
231                 tprintf("ru_inblock=%lu, ru_oublock=%lu, ",
232                         ru.ru_inblock, ru.ru_oublock);
233                 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ",
234                         ru.ru_msgsnd, ru.ru_msgrcv);
235                 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}",
236                         ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw);
237         }
238         else {
239                 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}",
240                         (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec,
241                         (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec);
242         }
243 }
244
245 SYS_FUNC(getrusage)
246 {
247         if (entering(tcp)) {
248                 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
249                 tprints(", ");
250         }
251         else
252                 printrusage(tcp, tcp->u_arg[1]);
253         return 0;
254 }
255
256 #ifdef ALPHA
257 SYS_FUNC(osf_getrusage)
258 {
259         if (entering(tcp)) {
260                 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???");
261                 tprints(", ");
262         }
263         else
264                 printrusage32(tcp, tcp->u_arg[1]);
265         return 0;
266 }
267 #endif /* ALPHA */
268
269 #include "xlat/priorities.h"
270
271 SYS_FUNC(getpriority)
272 {
273         printxval(priorities, tcp->u_arg[0], "PRIO_???");
274         tprintf(", %lu", tcp->u_arg[1]);
275
276         return RVAL_DECODED;
277 }
278
279 SYS_FUNC(setpriority)
280 {
281         printxval(priorities, tcp->u_arg[0], "PRIO_???");
282         tprintf(", %lu, %d", tcp->u_arg[1], (int) tcp->u_arg[2]);
283
284         return RVAL_DECODED;
285 }
286
287 SYS_FUNC(times)
288 {
289         struct tms tbuf;
290
291         if (exiting(tcp)) {
292                 if (!umove_or_printaddr(tcp, tcp->u_arg[0], &tbuf)) {
293                         tprintf("{tms_utime=%llu, tms_stime=%llu, ",
294                                 (unsigned long long) tbuf.tms_utime,
295                                 (unsigned long long) tbuf.tms_stime);
296                         tprintf("tms_cutime=%llu, tms_cstime=%llu}",
297                                 (unsigned long long) tbuf.tms_cutime,
298                                 (unsigned long long) tbuf.tms_cstime);
299                 }
300         }
301         return 0;
302 }